summaryrefslogtreecommitdiff
path: root/Build/source/libs/gd/libgd-src/src/gdft.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/gd/libgd-src/src/gdft.c')
-rw-r--r--Build/source/libs/gd/libgd-src/src/gdft.c272
1 files changed, 186 insertions, 86 deletions
diff --git a/Build/source/libs/gd/libgd-src/src/gdft.c b/Build/source/libs/gd/libgd-src/src/gdft.c
index d989ecc3873..98e74fa346c 100644
--- a/Build/source/libs/gd/libgd-src/src/gdft.c
+++ b/Build/source/libs/gd/libgd-src/src/gdft.c
@@ -1,4 +1,3 @@
-
/********************************************/
/* gd interface to freetype library */
/* */
@@ -72,9 +71,7 @@ static char *font_path(char **fontpath, char *name_list);
*/
#ifndef DEFAULT_FONTPATH
-# ifdef NETWARE
-# define DEFAULT_FONTPATH "sys:/java/nwgfx/lib/x11/fonts/ttf;."
-# elif defined(_WIN32)
+# if defined(_WIN32)
# define DEFAULT_FONTPATH "C:\\WINDOWS\\FONTS;C:\\WINNT\\FONTS"
# elif defined(__APPLE__) || (defined(__MWERKS__) && defined(macintosh))
# define DEFAULT_FONTPATH "/usr/share/fonts/truetype:/System/Library/Fonts:/Library/Fonts"
@@ -85,7 +82,7 @@ static char *font_path(char **fontpath, char *name_list);
#endif
#ifndef PATHSEPARATOR
-# if defined(NETWARE) || defined(_WIN32)
+# if defined(_WIN32)
# define PATHSEPARATOR ";"
# else
# define PATHSEPARATOR ":"
@@ -103,8 +100,8 @@ static char *font_path(char **fontpath, char *name_list);
*
* Alias of <gdImageStringFT>.
*/
-BGD_DECLARE(char *) gdImageStringTTF (gdImage * im, int *brect, int fg, char *fontlist,
- double ptsize, double angle, int x, int y, char *string)
+BGD_DECLARE(char *) gdImageStringTTF (gdImage * im, int *brect, int fg, const char *fontlist,
+ double ptsize, double angle, int x, int y, const char *string)
{
/* 2.0.6: valid return */
return gdImageStringFT (im, brect, fg, fontlist, ptsize,
@@ -112,8 +109,8 @@ BGD_DECLARE(char *) gdImageStringTTF (gdImage * im, int *brect, int fg, char *fo
}
#ifndef HAVE_LIBFREETYPE
-BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist,
- double ptsize, double angle, int x, int y, char *string,
+BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, const char *fontlist,
+ double ptsize, double angle, int x, int y, const char *string,
gdFTStringExtraPtr strex)
{
(void)im;
@@ -130,8 +127,8 @@ BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, char *f
return "libgd was not built with FreeType font support\n";
}
-BGD_DECLARE(char *) gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist,
- double ptsize, double angle, int x, int y, char *string)
+BGD_DECLARE(char *) gdImageStringFT (gdImage * im, int *brect, int fg, const char *fontlist,
+ double ptsize, double angle, int x, int y, const char *string)
{
(void)im;
(void)brect;
@@ -184,7 +181,7 @@ typedef struct {
font_t;
typedef struct {
- char *fontlist; /* key */
+ const char *fontlist; /* key */
int flags; /* key */
FT_Library *library;
}
@@ -260,7 +257,7 @@ static int comp_entities(const void *e1, const void *e2)
return strcmp(en1->name, en2->name);
}
-extern int any2eucjp (char *, char *, unsigned int);
+extern int any2eucjp (char *, const char *, unsigned int);
/* Persistent font cache until explicitly cleared */
/* Fonts can be used across multiple images */
@@ -273,7 +270,7 @@ static FT_Library library;
#define Tcl_UniChar int
#define TCL_UTF_MAX 3
static int
-gdTcl_UtfToUniChar (char *str, Tcl_UniChar * chPtr)
+gdTcl_UtfToUniChar (const char *str, Tcl_UniChar * chPtr)
/* str is the UTF8 next character pointer */
/* chPtr is the int for the result */
{
@@ -432,6 +429,107 @@ gdTcl_UtfToUniChar (char *str, Tcl_UniChar * chPtr)
return 1;
}
+#ifdef HAVE_LIBRAQM
+#include <raqm.h>
+#endif
+
+typedef struct {
+ unsigned int index;
+ FT_Pos x_advance;
+ FT_Pos x_offset;
+ FT_Pos y_offset;
+ uint32_t cluster;
+} glyphInfo;
+
+static size_t
+textLayout(uint32_t *text, int len,
+ FT_Face face, gdFTStringExtraPtr strex,
+ glyphInfo **glyph_info)
+{
+ size_t count;
+ glyphInfo *info;
+
+#ifdef HAVE_LIBRAQM
+ size_t i;
+ raqm_glyph_t *glyphs;
+ raqm_t *rq = raqm_create ();
+
+ if (!rq || !raqm_set_text (rq, text, len) ||
+ !raqm_set_freetype_face (rq, face) ||
+ !raqm_set_par_direction (rq, RAQM_DIRECTION_DEFAULT) ||
+ !raqm_layout (rq)) {
+ raqm_destroy (rq);
+ return 0;
+ }
+
+ glyphs = raqm_get_glyphs (rq, &count);
+ if (!glyphs) {
+ raqm_destroy (rq);
+ return 0;
+ }
+
+ info = (glyphInfo*) gdMalloc (sizeof (glyphInfo) * count);
+ if (!info) {
+ raqm_destroy (rq);
+ return 0;
+ }
+
+ for (i = 0; i < count; i++) {
+ info[i].index = glyphs[i].index;
+ info[i].x_offset = glyphs[i].x_offset;
+ info[i].y_offset = glyphs[i].y_offset;
+ info[i].x_advance = glyphs[i].x_advance;
+ info[i].cluster = glyphs[i].cluster;
+ }
+
+ raqm_destroy (rq);
+#else
+ FT_UInt glyph_index = 0, previous = 0;
+ FT_Vector delta;
+ FT_Error err;
+ info = (glyphInfo*) gdMalloc (sizeof (glyphInfo) * len);
+ if (!info) {
+ return 0;
+ }
+ for (count = 0; count < len; count++) {
+ /* Convert character code to glyph index */
+ glyph_index = FT_Get_Char_Index (face, text[count]);
+
+ /* retrieve kerning distance */
+ if (! (strex && (strex->flags & gdFTEX_DISABLE_KERNING))
+ && ! FT_IS_FIXED_WIDTH(face)
+ && FT_HAS_KERNING(face)
+ && previous
+ && glyph_index)
+ FT_Get_Kerning (face, previous, glyph_index, ft_kerning_default, &delta);
+ else
+ delta.x = delta.y = 0;
+
+ err = FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT);
+ if (err) {
+ gdFree (info);
+ return 0;
+ }
+ info[count].index = glyph_index;
+ info[count].x_offset = 0;
+ info[count].y_offset = 0;
+ if (delta.x != 0)
+ info[count - 1].x_advance += delta.x;
+ info[count].x_advance = face->glyph->metrics.horiAdvance;
+ info[count].cluster = count;
+
+ /* carriage returns or newlines */
+ if (text[count] == '\r' || text[count] == '\n')
+ previous = 0; /* clear kerning flag */
+ else
+ previous = glyph_index;
+ }
+#endif
+
+ *glyph_info = info;
+ return count;
+}
+
/********************************************************************/
/* font cache functions */
@@ -475,7 +573,7 @@ fontFetch (char **error, void *key)
gdFree(a);
return "could not alloc full list of fonts";
}
- strncpy(a->fontlist, b->fontlist, b_font_list_len);
+ memcpy(a->fontlist, b->fontlist, b_font_list_len);
a->fontlist[b_font_list_len] = 0;
a->flags = b->flags;
@@ -824,8 +922,8 @@ BGD_DECLARE(void) gdFontCacheShutdown ()
* See also:
* - <gdImageString>
*/
-BGD_DECLARE(char *) gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist,
- double ptsize, double angle, int x, int y, char *string)
+BGD_DECLARE(char *) gdImageStringFT (gdImage * im, int *brect, int fg, const char *fontlist,
+ double ptsize, double angle, int x, int y, const char *string)
{
return gdImageStringFTEx (im, brect, fg, fontlist,
ptsize, angle, x, y, string, 0);
@@ -872,13 +970,13 @@ BGD_DECLARE(int) gdFontCacheSetup (void)
typedef struct {
// logical OR of gdFTEX_ values
int flags;
-
+
// fine tune line spacing for '\n'
double linespacing;
-
+
// Preferred character mapping
int charmap;
-
+
// Rendering resolution
int hdpi;
int vdpi;
@@ -982,32 +1080,35 @@ BGD_DECLARE(int) gdFontCacheSetup (void)
> flags | gdFTEX_FONTPATHNAME;
- For more information, see <gdImageStringFT>.
+ For more information, see <gdImageStringFT>.
*/
/* the platform-independent resolution used for size and position calculations */
/* the size of the error introduced by rounding is affected by this number */
#define METRIC_RES 300
-BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist,
- double ptsize, double angle, int x, int y, char *string,
+BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, const char *fontlist,
+ double ptsize, double angle, int x, int y, const char *string,
gdFTStringExtraPtr strex)
{
FT_Matrix matrix;
- FT_Vector penf, oldpenf, delta, total_min = {0,0}, total_max = {0,0}, glyph_min, glyph_max;
+ FT_Vector penf, oldpenf, total_min = {0,0}, total_max = {0,0}, glyph_min, glyph_max;
FT_Face face;
FT_CharMap charmap = NULL;
FT_Glyph image;
FT_GlyphSlot slot;
FT_Error err;
- FT_UInt glyph_index, previous;
+ FT_UInt glyph_index;
double sin_a = sin (angle);
double cos_a = cos (angle);
- int len, i, ch;
+ int i, ch;
font_t *font;
fontkey_t fontkey;
- char *next;
+ const char *next;
char *tmpstr = 0;
+ uint32_t *text;
+ glyphInfo *info = NULL;
+ size_t count;
int render = (im && (im->trueColor || (fg <= 255 && fg >= -255)));
FT_BitmapGlyph bm;
/* 2.0.13: Bob Ostermann: don't force autohint, that's just for testing
@@ -1100,7 +1201,7 @@ BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, char *f
gdMutexUnlock(gdFontCacheMutex);
return "could not alloc full list of fonts";
}
- strncpy(strex->fontpath, font->fontpath, fontpath_len);
+ memcpy(strex->fontpath, font->fontpath, fontpath_len);
strex->fontpath[fontpath_len] = 0;
}
}
@@ -1220,31 +1321,11 @@ BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, char *f
oldpenf.x = oldpenf.y = 0; /* for postscript xshow operator */
penf.x = penf.y = 0; /* running position of non-rotated glyphs */
- previous = 0; /* index of previous glyph for kerning calculations */
- for (i=0; *next; i++) {
- FT_Activate_Size (platform_independent);
-
+ text = (uint32_t*) gdCalloc (sizeof (uint32_t), strlen(next));
+ i = 0;
+ while (*next) {
+ int len;
ch = *next;
-
- /* carriage returns */
- if (ch == '\r') {
- penf.x = 0;
- previous = 0; /* clear kerning flag */
- next++;
- continue;
- }
- /* newlines */
- if (ch == '\n') {
- /* 2.0.13: reset penf.x. Christopher J. Grayce */
- penf.x = 0;
- penf.y += linespace * ptsize * 64 * METRIC_RES / 72;
- penf.y &= ~63; /* round down to 1/METRIC_RES */
- previous = 0; /* clear kerning flag */
- next++;
- continue;
- }
-
-
switch (encoding) {
case gdFTEX_Unicode: {
/* use UTF-8 mapping from ASCII */
@@ -1320,22 +1401,43 @@ BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, char *f
next++;
break;
}
+ text[i] = ch;
+ i++;
+ }
- /* Convert character code to glyph index */
- glyph_index = FT_Get_Char_Index (face, ch);
+ FT_Activate_Size (platform_independent);
- /* retrieve kerning distance */
- if ( ! (strex && (strex->flags & gdFTEX_DISABLE_KERNING))
- && ! FT_IS_FIXED_WIDTH(face)
- && FT_HAS_KERNING(face)
- && previous
- && glyph_index)
- FT_Get_Kerning (face, previous, glyph_index, ft_kerning_default, &delta);
- else
- delta.x = delta.y = 0;
+ count = textLayout (text , i, face, strex, &info);
- penf.x += delta.x;
+ if (!count) {
+ gdFree (text);
+ gdFree (tmpstr);
+ gdCacheDelete (tc_cache);
+ gdMutexUnlock (gdFontCacheMutex);
+ return "Problem doing text layout";
+ }
+ for (i = 0; i < count; i++) {
+ FT_Activate_Size (platform_independent);
+
+ ch = text[info[i].cluster];
+
+ /* carriage returns */
+ if (ch == '\r') {
+ penf.x = 0;
+ continue;
+ }
+
+ /* newlines */
+ if (ch == '\n') {
+ /* 2.0.13: reset penf.x. Christopher J. Grayce */
+ penf.x = 0;
+ penf.y += linespace * ptsize * 64 * METRIC_RES / 72;
+ penf.y &= ~63; /* round down to 1/METRIC_RES */
+ continue;
+ }
+
+ glyph_index = info[i].index;
/* When we know the position of the second or subsequent character,
save the (kerned) advance from the preceeding character in the
xshow vector */
@@ -1348,6 +1450,7 @@ BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, char *f
if (!strex->xshow) {
if (tmpstr)
gdFree (tmpstr);
+ gdFree(text);
gdCacheDelete (tc_cache);
gdMutexUnlock (gdFontCacheMutex);
return "Problem allocating memory";
@@ -1359,6 +1462,7 @@ BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, char *f
if (!strex->xshow) {
if (tmpstr)
gdFree (tmpstr);
+ gdFree(text);
gdCacheDelete (tc_cache);
gdMutexUnlock (gdFontCacheMutex);
return "Problem allocating memory";
@@ -1374,12 +1478,13 @@ BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, char *f
if (err) {
if (tmpstr)
gdFree (tmpstr);
+ gdFree(text);
gdCacheDelete (tc_cache);
gdMutexUnlock (gdFontCacheMutex);
return "Problem loading glyph";
}
- horiAdvance = slot->metrics.horiAdvance;
+ horiAdvance = info[i].x_advance;
if (brect) {
/* only if need brect */
@@ -1414,6 +1519,8 @@ BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, char *f
}
if (render) {
+ FT_Pos pen_x;
+ FT_Pos pen_y;
FT_Activate_Size (platform_specific);
/* load glyph again into the slot (erase previous one) - this time with scaling */
@@ -1421,6 +1528,7 @@ BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, char *f
if (err) {
if (tmpstr)
gdFree (tmpstr);
+ gdFree(text);
gdCacheDelete (tc_cache);
gdMutexUnlock (gdFontCacheMutex);
return "Problem loading glyph";
@@ -1435,6 +1543,7 @@ BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, char *f
FT_Done_Glyph(image);
if (tmpstr)
gdFree (tmpstr);
+ gdFree(text);
gdCacheDelete (tc_cache);
gdMutexUnlock (gdFontCacheMutex);
return "Problem rendering glyph";
@@ -1445,19 +1554,22 @@ BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, char *f
bm = (FT_BitmapGlyph) image;
/* position rounded down to nearest pixel at current dpi
(the estimate was rounded up to next 1/METRIC_RES, so this should fit) */
+ pen_x = penf.x + info[i].x_offset;
+ pen_y = penf.y - info[i].y_offset;
gdft_draw_bitmap (tc_cache, im, fg, bm->bitmap,
- (int)(x + (penf.x * cos_a + penf.y * sin_a)*hdpi/(METRIC_RES*64) + bm->left),
- (int)(y - (penf.x * sin_a - penf.y * cos_a)*vdpi/(METRIC_RES*64) - bm->top));
+ (int)(x + (pen_x * cos_a + pen_y * sin_a)*hdpi/(METRIC_RES*64) + bm->left),
+ (int)(y - (pen_x * sin_a - pen_y * cos_a)*vdpi/(METRIC_RES*64) - bm->top));
FT_Done_Glyph (image);
}
- /* record current glyph index for kerning */
- previous = glyph_index;
penf.x += horiAdvance;
}
+ gdFree(text);
+ gdFree(info);
+
/* Save the (unkerned) advance from the last character in the xshow vector */
if (strex && (strex->flags & gdFTEX_XSHOW) && strex->xshow) {
sprintf(strex->xshow + xshow_pos, "%g",
@@ -1469,12 +1581,6 @@ BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, char *f
double scalex = (double)hdpi / (64 * METRIC_RES);
double scaley = (double)vdpi / (64 * METRIC_RES);
- /* increase by 1 pixel to allow for rounding */
- total_min.x -= METRIC_RES;
- total_min.y -= METRIC_RES;
- total_max.x += METRIC_RES;
- total_max.y += METRIC_RES;
-
/* rotate bounding rectangle, scale and round to int pixels, and translate */
brect[0] = x + (total_min.x * cos_a + total_max.y * sin_a)*scalex;
brect[1] = y - (total_min.x * sin_a - total_max.y * cos_a)*scaley;
@@ -1656,7 +1762,7 @@ static char * font_pattern(char **fontpath, char *fontpattern)
if (*fontpath == NULL) {
return "could not alloc font path";
}
- strncpy(*fontpath, (const char *)file, file_len);
+ memcpy(*fontpath, (const char *)file, file_len);
(*fontpath)[file_len] = 0;
}
FcPatternDestroy(font);
@@ -1685,11 +1791,11 @@ static char * font_path(char **fontpath, char *name_list)
fontsearchpath = getenv ("GDFONTPATH");
#ifdef _WIN32
if (!fontsearchpath) {
- char *ffptr = getenv ("SYSTEMROOT");
+ char *ffptr = getenv ("WINDIR");
if (ffptr) {
- fontsearchpath = malloc (strlen(ffptr) + strlen("\\fonts") + 1);
+ fontsearchpath = malloc (strlen(ffptr) + strlen("\\Fonts") + 1);
strcpy(fontsearchpath, ffptr);
- strcat(fontsearchpath, "\\fonts");
+ strcat(fontsearchpath, "\\Fonts");
}
}
#endif
@@ -1706,7 +1812,7 @@ static char * font_path(char **fontpath, char *name_list)
gdFree(path);
return "could not alloc full list of fonts";
}
- strncpy(fontlist, name_list, name_list_len);
+ memcpy(fontlist, name_list, name_list_len);
fontlist[name_list_len] = 0;
/*
@@ -1731,14 +1837,9 @@ static char * font_path(char **fontpath, char *name_list)
return "could not alloc full path of font";
}
/* if name is an absolute or relative pathname then test directly */
-#ifdef NETWARE
- /* netware uses the format "volume:/path" or the standard "/path" */
- if (name[0] != 0 && (strstr(name, ":/") || name[0] == '/'))
-#else
if (strchr (name, '/')
|| (name[0] != 0 && name[1] == ':'
&& (name[2] == '/' || name[2] == '\\')))
-#endif
{
sprintf (fullname, "%s", name);
if (access (fullname, R_OK) == 0) {
@@ -1820,4 +1921,3 @@ BGD_DECLARE(int) gdFTUseFontConfig(int flag)
return 0;
#endif /* HAVE_LIBFONTCONFIG */
}
-