|
Link Here
|
| 1 |
diff --git a/ext/gd/gd.c ./gd.c |
| 2 |
--- a/ext/gd/gd.c |
| 3 |
+++ ./gd.c |
| 4 |
@@ -88,6 +88,9 @@ |
| 5 |
# include "gdttf.h" |
| 6 |
#endif |
| 7 |
|
| 8 |
+/* Need access to some freetype constants */ |
| 9 |
+#include <freetype/freetype.h> |
| 10 |
+ |
| 11 |
#ifndef M_PI |
| 12 |
#define M_PI 3.14159265358979323846 |
| 13 |
#endif |
| 14 |
@@ -4264,6 +4267,14 @@ |
| 15 |
angle = angle * (M_PI/180); |
| 16 |
|
| 17 |
#if HAVE_GD_STRINGFTEX |
| 18 |
+ if (extended) { |
| 19 |
+ /* Sensible defaults */ |
| 20 |
+ strex.slant_angle = 0.; |
| 21 |
+ strex.width_mult = 1.; |
| 22 |
+ strex.height_mult = 1.; |
| 23 |
+ strex.advance_mult = 1.; |
| 24 |
+ } |
| 25 |
+ |
| 26 |
if (extended && EXT) { /* parse extended info */ |
| 27 |
HashPosition pos; |
| 28 |
|
| 29 |
@@ -4286,6 +4297,49 @@ |
| 30 |
convert_to_double_ex(item); |
| 31 |
strex.flags |= gdFTEX_LINESPACE; |
| 32 |
strex.linespacing = Z_DVAL_PP(item); |
| 33 |
+ } else if (strcmp("load_no_scale", key) == 0) { |
| 34 |
+ strex.loadFlags |= FT_LOAD_NO_SCALE; |
| 35 |
+ } else if (strcmp("load_no_hinting", key) == 0) { |
| 36 |
+ strex.loadFlags |= FT_LOAD_NO_HINTING; |
| 37 |
+ } else if (strcmp("load_no_bitmap", key) == 0) { |
| 38 |
+ strex.loadFlags |= FT_LOAD_NO_BITMAP; |
| 39 |
+ } else if (strcmp("load_force_autohint", key) == 0) { |
| 40 |
+ strex.loadFlags |= FT_LOAD_FORCE_AUTOHINT; |
| 41 |
+ } else if (strcmp("load_ignore_transform", key) == 0) { |
| 42 |
+ strex.loadFlags |= FT_LOAD_IGNORE_TRANSFORM; |
| 43 |
+ } else if (strcmp("load_monochrome", key) == 0) { |
| 44 |
+ strex.loadFlags |= FT_LOAD_MONOCHROME; |
| 45 |
+ } else if (strcmp("load_linear_design", key) == 0) { |
| 46 |
+ strex.loadFlags |= FT_LOAD_LINEAR_DESIGN; |
| 47 |
+ } else if (strcmp("load_no_autohint", key) == 0) { |
| 48 |
+ strex.loadFlags |= FT_LOAD_NO_AUTOHINT; |
| 49 |
+ } else if (strcmp("hdpi", key) == 0) { |
| 50 |
+ convert_to_long_ex(item); |
| 51 |
+ strex.hdpi = Z_LVAL_PP(item); |
| 52 |
+ if (!strex.vdpi) strex.vdpi = strex.hdpi; |
| 53 |
+ strex.flags |= gdFTEX_RESOLUTION; |
| 54 |
+ } else if (strcmp("vdpi", key) == 0) { |
| 55 |
+ convert_to_long_ex(item); |
| 56 |
+ strex.vdpi = Z_LVAL_PP(item); |
| 57 |
+ if (!strex.hdpi) strex.hdpi = strex.vdpi; |
| 58 |
+ strex.flags |= gdFTEX_RESOLUTION; |
| 59 |
+ } else if (strcmp("screenres", key) == 0) { |
| 60 |
+ convert_to_long_ex(item); |
| 61 |
+ strex.hdpi = Z_LVAL_PP(item); |
| 62 |
+ strex.vdpi = strex.hdpi; |
| 63 |
+ strex.flags |= gdFTEX_RESOLUTION; |
| 64 |
+ } else if (strcmp("slant_angle", key) == 0) { |
| 65 |
+ convert_to_double_ex(item); |
| 66 |
+ strex.slant_angle = Z_DVAL_PP(item); |
| 67 |
+ } else if (strcmp("advance_mult", key) == 0) { |
| 68 |
+ convert_to_double_ex(item); |
| 69 |
+ strex.advance_mult = Z_DVAL_PP(item); |
| 70 |
+ } else if (strcmp("width_mult", key) == 0) { |
| 71 |
+ convert_to_double_ex(item); |
| 72 |
+ strex.width_mult = Z_DVAL_PP(item); |
| 73 |
+ } else if (strcmp("height_mult", key) == 0) { |
| 74 |
+ convert_to_double_ex(item); |
| 75 |
+ strex.height_mult = Z_DVAL_PP(item); |
| 76 |
} |
| 77 |
|
| 78 |
} while (zend_hash_move_forward_ex(HASH_OF(EXT), &pos) == SUCCESS); |
| 79 |
diff --git a/ext/gd/libgd/gd.h ./libgd/gd.h |
| 80 |
--- a/ext/gd/libgd/gd.h |
| 81 |
+++ ./libgd/gd.h |
| 82 |
@@ -347,6 +347,12 @@ |
| 83 |
for in the above order. */ |
| 84 |
int hdpi; |
| 85 |
int vdpi; |
| 86 |
+ |
| 87 |
+ int loadFlags; /* Freetype's FT_LOAD_* constants */ |
| 88 |
+ double slant_angle; /* Slant angle, in radians */ |
| 89 |
+ double advance_mult; /* Advange multiplier (letter spacing) */ |
| 90 |
+ double width_mult; /* Font's width multiplier */ |
| 91 |
+ double height_mult; /* Font's height multiplier */ |
| 92 |
} |
| 93 |
gdFTStringExtra, *gdFTStringExtraPtr; |
| 94 |
|
| 95 |
diff --git a/ext/gd/libgd/gdft.c ./libgd/gdft.c |
| 96 |
--- a/ext/gd/libgd/gdft.c |
| 97 |
+++ ./libgd/gdft.c |
| 98 |
@@ -773,7 +773,7 @@ |
| 99 |
gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsize, double angle, int x, int y, char *string, gdFTStringExtraPtr strex) |
| 100 |
{ |
| 101 |
FT_BBox bbox, glyph_bbox; |
| 102 |
- FT_Matrix matrix; |
| 103 |
+ FT_Matrix matrix, matrix_a, matrix_b; |
| 104 |
FT_Vector pen, delta, penf; |
| 105 |
FT_Face face; |
| 106 |
FT_Glyph image; |
| 107 |
@@ -790,8 +790,8 @@ |
| 108 |
char *tmpstr = NULL; |
| 109 |
int render = (im && (im->trueColor || (fg <= 255 && fg >= -255))); |
| 110 |
FT_BitmapGlyph bm; |
| 111 |
- /* 2.0.13: Bob Ostermann: don't force autohint, that's just for testing freetype and doesn't look as good */ |
| 112 |
- int render_mode = FT_LOAD_DEFAULT; |
| 113 |
+ /* Render to bitmap by default */ |
| 114 |
+ int render_mode = FT_LOAD_RENDER; |
| 115 |
int m, mfound; |
| 116 |
/* Now tuneable thanks to Wez Furlong */ |
| 117 |
double linespace = LINESPACE; |
| 118 |
@@ -807,9 +807,14 @@ |
| 119 |
/* Tuneable horizontal and vertical resolution in dots per inch */ |
| 120 |
int hdpi, vdpi; |
| 121 |
|
| 122 |
- if (strex && ((strex->flags & gdFTEX_LINESPACE) == gdFTEX_LINESPACE)) { |
| 123 |
- linespace = strex->linespacing; |
| 124 |
+ if (strex) { |
| 125 |
+ if (strex && ((strex->flags & gdFTEX_LINESPACE) == gdFTEX_LINESPACE)) { |
| 126 |
+ linespace = strex->linespacing; |
| 127 |
+ } |
| 128 |
+ /* Add additional FT_LOAD_* values */ |
| 129 |
+ render_mode |= strex->loadFlags; |
| 130 |
} |
| 131 |
+ |
| 132 |
tc_cache = gdCacheCreate(TWEENCOLORCACHESIZE, tweenColorTest, tweenColorFetch, tweenColorRelease); |
| 133 |
|
| 134 |
/***** initialize font library and font cache on first call ******/ |
| 135 |
@@ -854,10 +859,10 @@ |
| 136 |
return "Could not set character size"; |
| 137 |
} |
| 138 |
|
| 139 |
- matrix.xx = (FT_Fixed) (cos_a * (1 << 16)); |
| 140 |
- matrix.yx = (FT_Fixed) (sin_a * (1 << 16)); |
| 141 |
- matrix.xy = -matrix.yx; |
| 142 |
- matrix.yy = matrix.xx; |
| 143 |
+ matrix.xx = (FT_Fixed) ((strex->width_mult * cos_a + strex->width_mult * strex->slant_angle * sin_a) * (1 << 16)); |
| 144 |
+ matrix.xy = (FT_Fixed) ((strex->width_mult * -sin_a + strex->width_mult * strex->slant_angle * cos_a) * (1 << 16)); |
| 145 |
+ matrix.yx = (FT_Fixed) ((strex->height_mult * sin_a) * (1 << 16)); |
| 146 |
+ matrix.yy = (FT_Fixed) ((strex->height_mult * cos_a) * (1 << 16)); |
| 147 |
|
| 148 |
penf.x = penf.y = 0; /* running position of non-rotated string */ |
| 149 |
pen.x = pen.y = 0; /* running position of rotated string */ |
| 150 |
@@ -1095,8 +1100,8 @@ |
| 151 |
previous = glyph_index; |
| 152 |
|
| 153 |
/* increment pen position */ |
| 154 |
- pen.x += image->advance.x >> 10; |
| 155 |
- pen.y -= image->advance.y >> 10; |
| 156 |
+ pen.x += (image->advance.x >> 10) * strex->advance_mult; |
| 157 |
+ pen.y -= (image->advance.y >> 10) * strex->advance_mult; |
| 158 |
|
| 159 |
penf.x += slot->metrics.horiAdvance; |
| 160 |
|