w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

SplashFTFont.cc
Go to the documentation of this file.
1 //========================================================================
2 //
3 // SplashFTFont.cc
4 //
5 //========================================================================
6 
7 //========================================================================
8 //
9 // Modified under the Poppler project - http://poppler.freedesktop.org
10 //
11 // All changes made under the Poppler project to this file are licensed
12 // under GPL version 2 or later
13 //
14 // Copyright (C) 2005, 2007-2011, 2014, 2018, 2020 Albert Astals Cid <aacid@kde.org>
15 // Copyright (C) 2006 Kristian Høgsberg <krh@bitplanet.net>
16 // Copyright (C) 2009 Petr Gajdos <pgajdos@novell.com>
17 // Copyright (C) 2010 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
18 // Copyright (C) 2011 Andreas Hartmetz <ahartmetz@gmail.com>
19 // Copyright (C) 2012 Thomas Freitag <Thomas.Freitag@alfa.de>
20 // Copyright (C) 2017 Adrian Johnson <ajohnson@redneon.com>
21 // Copyright (C) 2018 Oliver Sander <oliver.sander@tu-dresden.de>
22 //
23 // To see a description of the changes please see the Changelog file that
24 // came with your tarball or type make ChangeLog if you are building from git
25 //
26 //========================================================================
27 
28 #include <config.h>
29 
30 #include <ft2build.h>
31 #include FT_OUTLINE_H
32 #include FT_SIZES_H
33 #include FT_GLYPH_H
34 #include "goo/gmem.h"
35 #include "SplashMath.h"
36 #include "SplashGlyphBitmap.h"
37 #include "SplashPath.h"
38 #include "SplashFTFontEngine.h"
39 #include "SplashFTFontFile.h"
40 #include "SplashFTFont.h"
41 
42 #include "goo/GooLikely.h"
43 
44 //------------------------------------------------------------------------
45 
46 static int glyphPathMoveTo(const FT_Vector *pt, void *path);
47 static int glyphPathLineTo(const FT_Vector *pt, void *path);
48 static int glyphPathConicTo(const FT_Vector *ctrl, const FT_Vector *pt, void *path);
49 static int glyphPathCubicTo(const FT_Vector *ctrl1, const FT_Vector *ctrl2, const FT_Vector *pt, void *path);
50 
51 //------------------------------------------------------------------------
52 // SplashFTFont
53 //------------------------------------------------------------------------
54 
56  : SplashFont(fontFileA, matA, textMatA, fontFileA->engine->aa), textScale(0), enableFreeTypeHinting(fontFileA->engine->enableFreeTypeHinting), enableSlightHinting(fontFileA->engine->enableSlightHinting), isOk(false)
57 {
58  FT_Face face;
59  int div;
60  int x, y;
61 
62  face = fontFileA->face;
63  if (FT_New_Size(face, &sizeObj)) {
64  return;
65  }
66  face->size = sizeObj;
67  size = splashRound(splashDist(0, 0, mat[2], mat[3]));
68  if (size < 1) {
69  size = 1;
70  }
71  if (FT_Set_Pixel_Sizes(face, 0, size)) {
72  return;
73  }
74  // if the textMat values are too small, FreeType's fixed point
75  // arithmetic doesn't work so well
76  textScale = splashDist(0, 0, textMat[2], textMat[3]) / size;
77 
78  if (unlikely(textScale == 0 || face->units_per_EM == 0)) {
79  return;
80  }
81 
82  div = face->bbox.xMax > 20000 ? 65536 : 1;
83 
84  // transform the four corners of the font bounding box -- the min
85  // and max values form the bounding box of the transformed font
86  x = (int)((mat[0] * face->bbox.xMin + mat[2] * face->bbox.yMin) / (div * face->units_per_EM));
87  xMin = xMax = x;
88  y = (int)((mat[1] * face->bbox.xMin + mat[3] * face->bbox.yMin) / (div * face->units_per_EM));
89  yMin = yMax = y;
90  x = (int)((mat[0] * face->bbox.xMin + mat[2] * face->bbox.yMax) / (div * face->units_per_EM));
91  if (x < xMin) {
92  xMin = x;
93  } else if (x > xMax) {
94  xMax = x;
95  }
96  y = (int)((mat[1] * face->bbox.xMin + mat[3] * face->bbox.yMax) / (div * face->units_per_EM));
97  if (y < yMin) {
98  yMin = y;
99  } else if (y > yMax) {
100  yMax = y;
101  }
102  x = (int)((mat[0] * face->bbox.xMax + mat[2] * face->bbox.yMin) / (div * face->units_per_EM));
103  if (x < xMin) {
104  xMin = x;
105  } else if (x > xMax) {
106  xMax = x;
107  }
108  y = (int)((mat[1] * face->bbox.xMax + mat[3] * face->bbox.yMin) / (div * face->units_per_EM));
109  if (y < yMin) {
110  yMin = y;
111  } else if (y > yMax) {
112  yMax = y;
113  }
114  x = (int)((mat[0] * face->bbox.xMax + mat[2] * face->bbox.yMax) / (div * face->units_per_EM));
115  if (x < xMin) {
116  xMin = x;
117  } else if (x > xMax) {
118  xMax = x;
119  }
120  y = (int)((mat[1] * face->bbox.xMax + mat[3] * face->bbox.yMax) / (div * face->units_per_EM));
121  if (y < yMin) {
122  yMin = y;
123  } else if (y > yMax) {
124  yMax = y;
125  }
126  // This is a kludge: some buggy PDF generators embed fonts with
127  // zero bounding boxes.
128  if (xMax == xMin) {
129  xMin = 0;
130  xMax = size;
131  }
132  if (yMax == yMin) {
133  yMin = 0;
134  yMax = (int)((SplashCoord)1.2 * size);
135  }
136 
137  // compute the transform matrix
138  matrix.xx = (FT_Fixed)((mat[0] / size) * 65536);
139  matrix.yx = (FT_Fixed)((mat[1] / size) * 65536);
140  matrix.xy = (FT_Fixed)((mat[2] / size) * 65536);
141  matrix.yy = (FT_Fixed)((mat[3] / size) * 65536);
142  textMatrix.xx = (FT_Fixed)((textMat[0] / (textScale * size)) * 65536);
143  textMatrix.yx = (FT_Fixed)((textMat[1] / (textScale * size)) * 65536);
144  textMatrix.xy = (FT_Fixed)((textMat[2] / (textScale * size)) * 65536);
145  textMatrix.yy = (FT_Fixed)((textMat[3] / (textScale * size)) * 65536);
146 
147  isOk = true;
148 }
149 
151 
152 bool SplashFTFont::getGlyph(int c, int xFrac, int yFrac, SplashGlyphBitmap *bitmap, int x0, int y0, SplashClip *clip, SplashClipResult *clipRes)
153 {
154  return SplashFont::getGlyph(c, xFrac, 0, bitmap, x0, y0, clip, clipRes);
155 }
156 
157 static FT_Int32 getFTLoadFlags(bool type1, bool trueType, bool aa, bool enableFreeTypeHinting, bool enableSlightHinting)
158 {
159  int ret = FT_LOAD_DEFAULT;
160  if (aa)
162 
163  if (enableFreeTypeHinting) {
164  if (enableSlightHinting) {
166  } else {
167  if (trueType) {
168  // FT2's autohinting doesn't always work very well (especially with
169  // font subsets), so turn it off if anti-aliasing is enabled; if
170  // anti-aliasing is disabled, this seems to be a tossup - some fonts
171  // look better with hinting, some without, so leave hinting on
172  if (aa) {
174  }
175  } else if (type1) {
176  // Type 1 fonts seem to look better with 'light' hinting mode
178  }
179  }
180  } else {
182  }
183  return ret;
184 }
185 
186 bool SplashFTFont::makeGlyph(int c, int xFrac, int yFrac, SplashGlyphBitmap *bitmap, int x0, int y0, SplashClip *clip, SplashClipResult *clipRes)
187 {
188  SplashFTFontFile *ff;
191  FT_UInt gid;
192  int rowSize;
193  unsigned char *p, *q;
194  int i;
195 
196  if (unlikely(!isOk)) {
197  return false;
198  }
199 
200  ff = (SplashFTFontFile *)fontFile;
201 
202  ff->face->size = sizeObj;
203  offset.x = (FT_Pos)(int)((SplashCoord)xFrac * splashFontFractionMul * 64);
204  offset.y = 0;
206  slot = ff->face->glyph;
207 
208  if (ff->codeToGID && c < ff->codeToGIDLen && c >= 0) {
209  gid = (FT_UInt)ff->codeToGID[c];
210  } else {
211  gid = (FT_UInt)c;
212  }
213 
215  return false;
216  }
217 
218  // prelimirary values based on FT_Outline_Get_CBox
219  // we add two pixels to each side to be in the safe side
220  FT_BBox cbox;
221  FT_Outline_Get_CBox(&ff->face->glyph->outline, &cbox);
222  bitmap->x = -(cbox.xMin / 64) + 2;
223  bitmap->y = (cbox.yMax / 64) + 2;
224  bitmap->w = ((cbox.xMax - cbox.xMin) / 64) + 4;
225  bitmap->h = ((cbox.yMax - cbox.yMin) / 64) + 4;
226 
227  *clipRes = clip->testRect(x0 - bitmap->x, y0 - bitmap->y, x0 - bitmap->x + bitmap->w, y0 - bitmap->y + bitmap->h);
228  if (*clipRes == splashClipAllOutside) {
229  bitmap->freeData = false;
230  return true;
231  }
232 
234  return false;
235  }
236 
237  if (slot->bitmap.width == 0 || slot->bitmap.rows == 0) {
238  // this can happen if (a) the glyph is really tiny or (b) the
239  // metrics in the TrueType file are broken
240  return false;
241  }
242 
243  bitmap->x = -slot->bitmap_left;
244  bitmap->y = slot->bitmap_top;
245  bitmap->w = slot->bitmap.width;
246  bitmap->h = slot->bitmap.rows;
247  bitmap->aa = aa;
248  if (aa) {
249  rowSize = bitmap->w;
250  } else {
251  rowSize = (bitmap->w + 7) >> 3;
252  }
253  bitmap->data = (unsigned char *)gmallocn_checkoverflow(rowSize, bitmap->h);
254  if (!bitmap->data) {
255  return false;
256  }
257  bitmap->freeData = true;
258  for (i = 0, p = bitmap->data, q = slot->bitmap.buffer; i < bitmap->h; ++i, p += rowSize, q += slot->bitmap.pitch) {
259  memcpy(p, q, rowSize);
260  }
261 
262  return true;
263 }
264 
266 {
267  SplashFTFontFile *ff;
269  FT_UInt gid;
270  FT_Matrix identityMatrix;
271 
272  ff = (SplashFTFontFile *)fontFile;
273 
274  // init the matrix
275  identityMatrix.xx = 65536; // 1 in 16.16 format
276  identityMatrix.xy = 0;
277  identityMatrix.yx = 0;
278  identityMatrix.yy = 65536; // 1 in 16.16 format
279 
280  // init the offset
281  offset.x = 0;
282  offset.y = 0;
283 
284  ff->face->size = sizeObj;
285  FT_Set_Transform(ff->face, &identityMatrix, &offset);
286 
287  if (ff->codeToGID && c < ff->codeToGIDLen) {
288  gid = (FT_UInt)ff->codeToGID[c];
289  } else {
290  gid = (FT_UInt)c;
291  }
292 
294  return -1;
295  }
296 
297  // 64.0 is 1 in 26.6 format
298  return ff->face->glyph->metrics.horiAdvance / 64.0 / size;
299 }
300 
302 {
305  bool needClose;
306 };
307 
309 {
310  static const FT_Outline_Funcs outlineFuncs = {
311 #if FREETYPE_MINOR <= 1
312  (int (*)(FT_Vector *, void *)) & glyphPathMoveTo,
313  (int (*)(FT_Vector *, void *)) & glyphPathLineTo,
314  (int (*)(FT_Vector *, FT_Vector *, void *)) & glyphPathConicTo,
315  (int (*)(FT_Vector *, FT_Vector *, FT_Vector *, void *)) & glyphPathCubicTo,
316 #else
321 #endif
322  0,
323  0
324  };
325  SplashFTFontFile *ff;
328  FT_UInt gid;
329  FT_Glyph glyph;
330 
331  if (unlikely(textScale == 0)) {
332  return nullptr;
333  }
334 
335  ff = (SplashFTFontFile *)fontFile;
336  ff->face->size = sizeObj;
337  FT_Set_Transform(ff->face, &textMatrix, nullptr);
338  slot = ff->face->glyph;
339  if (ff->codeToGID && c < ff->codeToGIDLen && c >= 0) {
340  gid = ff->codeToGID[c];
341  } else {
342  gid = (FT_UInt)c;
343  }
345  return nullptr;
346  }
347  if (FT_Get_Glyph(slot, &glyph)) {
348  return nullptr;
349  }
351  return nullptr;
352  }
353  path.path = new SplashPath();
354  path.textScale = textScale;
355  path.needClose = false;
356  FT_Outline_Decompose(&((FT_OutlineGlyph)glyph)->outline, &outlineFuncs, &path);
357  if (path.needClose) {
358  path.path->close();
359  }
361  return path.path;
362 }
363 
364 static int glyphPathMoveTo(const FT_Vector *pt, void *path)
365 {
367 
368  if (p->needClose) {
369  p->path->close();
370  p->needClose = false;
371  }
372  p->path->moveTo((SplashCoord)pt->x * p->textScale / 64.0, (SplashCoord)pt->y * p->textScale / 64.0);
373  return 0;
374 }
375 
376 static int glyphPathLineTo(const FT_Vector *pt, void *path)
377 {
379 
380  p->path->lineTo((SplashCoord)pt->x * p->textScale / 64.0, (SplashCoord)pt->y * p->textScale / 64.0);
381  p->needClose = true;
382  return 0;
383 }
384 
385 static int glyphPathConicTo(const FT_Vector *ctrl, const FT_Vector *pt, void *path)
386 {
388  SplashCoord x0, y0, x1, y1, x2, y2, x3, y3, xc, yc;
389 
390  if (!p->path->getCurPt(&x0, &y0)) {
391  return 0;
392  }
393  xc = (SplashCoord)ctrl->x * p->textScale / 64.0;
394  yc = (SplashCoord)ctrl->y * p->textScale / 64.0;
395  x3 = (SplashCoord)pt->x * p->textScale / 64.0;
396  y3 = (SplashCoord)pt->y * p->textScale / 64.0;
397 
398  // A second-order Bezier curve is defined by two endpoints, p0 and
399  // p3, and one control point, pc:
400  //
401  // p(t) = (1-t)^2*p0 + t*(1-t)*pc + t^2*p3
402  //
403  // A third-order Bezier curve is defined by the same two endpoints,
404  // p0 and p3, and two control points, p1 and p2:
405  //
406  // p(t) = (1-t)^3*p0 + 3t*(1-t)^2*p1 + 3t^2*(1-t)*p2 + t^3*p3
407  //
408  // Applying some algebra, we can convert a second-order curve to a
409  // third-order curve:
410  //
411  // p1 = (1/3) * (p0 + 2pc)
412  // p2 = (1/3) * (2pc + p3)
413 
414  x1 = (SplashCoord)(1.0 / 3.0) * (x0 + (SplashCoord)2 * xc);
415  y1 = (SplashCoord)(1.0 / 3.0) * (y0 + (SplashCoord)2 * yc);
416  x2 = (SplashCoord)(1.0 / 3.0) * ((SplashCoord)2 * xc + x3);
417  y2 = (SplashCoord)(1.0 / 3.0) * ((SplashCoord)2 * yc + y3);
418 
419  p->path->curveTo(x1, y1, x2, y2, x3, y3);
420  p->needClose = true;
421  return 0;
422 }
423 
424 static int glyphPathCubicTo(const FT_Vector *ctrl1, const FT_Vector *ctrl2, const FT_Vector *pt, void *path)
425 {
427 
428  p->path->curveTo((SplashCoord)ctrl1->x * p->textScale / 64.0, (SplashCoord)ctrl1->y * p->textScale / 64.0, (SplashCoord)ctrl2->x * p->textScale / 64.0, (SplashCoord)ctrl2->y * p->textScale / 64.0,
429  (SplashCoord)pt->x * p->textScale / 64.0, (SplashCoord)pt->y * p->textScale / 64.0);
430  p->needClose = true;
431  return 0;
432 }
div_t __cdecl div(int _Numerator, int _Denominator)
q
Definition: afm2pl.c:2287
#define y0
#define x3
#define x0
#define y3
bool getGlyph(int c, int xFrac, int yFrac, SplashGlyphBitmap *bitmap, int x0, int y0, SplashClip *clip, SplashClipResult *clipRes) override
bool makeGlyph(int c, int xFrac, int yFrac, SplashGlyphBitmap *bitmap, int x0, int y0, SplashClip *clip, SplashClipResult *clipRes) override
FT_Matrix matrix
Definition: SplashFTFont.h:62
SplashFTFont(SplashFTFontFile *fontFileA, SplashCoord *matA, const SplashCoord *textMatA)
Definition: SplashFTFont.cc:55
bool enableFreeTypeHinting
Definition: SplashFTFont.h:66
bool enableSlightHinting
Definition: SplashFTFont.h:67
~SplashFTFont() override
FT_Matrix textMatrix
Definition: SplashFTFont.h:63
SplashPath * getGlyphPath(int c) override
SplashCoord textScale
Definition: SplashFTFont.h:64
double getGlyphAdvance(int c) override
FT_Size sizeObj
Definition: SplashFTFont.h:61
GBool aa
Definition: SplashFont.h:100
SplashCoord textMat[4]
Definition: SplashFont.h:98
SplashCoord mat[4]
Definition: SplashFont.h:96
virtual GBool getGlyph(int c, int xFrac, int yFrac, SplashGlyphBitmap *bitmap)
Definition: SplashFont.cc:110
SplashFontFile * fontFile
Definition: SplashFont.h:95
int h
Definition: dviconv.c:9
#define c(n)
Definition: gpos-common.c:150
#define memcpy(d, s, n)
Definition: gsftopk.c:64
#define unlikely(x)
Definition: jbig2arith.cc:116
FT_Load_Glyph(FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags)
Definition: ftobjs.c:796
#define FT_LOAD_NO_BITMAP
Definition: freetype.h:3025
FT_Set_Transform(FT_Face face, FT_Matrix *matrix, FT_Vector *delta)
Definition: ftobjs.c:689
FT_Set_Pixel_Sizes(FT_Face face, FT_UInt pixel_width, FT_UInt pixel_height)
Definition: ftobjs.c:3373
#define ft_render_mode_mono
Definition: freetype.h:3263
#define FT_LOAD_NO_HINTING
Definition: freetype.h:3023
#define FT_LOAD_DEFAULT
Definition: freetype.h:3021
FT_Render_Glyph(FT_GlyphSlot slot, FT_Render_Mode render_mode)
Definition: ftobjs.c:4796
#define FT_LOAD_NO_AUTOHINT
Definition: freetype.h:3035
#define FT_LOAD_TARGET_LIGHT
Definition: freetype.h:3138
#define ft_render_mode_normal
Definition: freetype.h:3262
FT_Done_Glyph(FT_Glyph glyph)
Definition: ftglyph.c:641
FT_Get_Glyph(FT_GlyphSlot slot, FT_Glyph *aglyph)
Definition: ftglyph.c:401
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:57
FT_Outline_Check(FT_Outline *outline)
Definition: ftoutln.c:341
FT_BEGIN_HEADER FT_Outline_Decompose(FT_Outline *outline, const FT_Outline_Funcs *func_interface, void *user)
Definition: ftoutln.c:43
FT_Outline_Get_CBox(const FT_Outline *outline, FT_BBox *acbox)
Definition: ftoutln.c:457
FT_BEGIN_HEADER FT_New_Size(FT_Face face, FT_Size *size)
Definition: ftobjs.c:2824
signed long FT_Fixed
Definition: fttypes.h:287
unsigned int FT_UInt
Definition: fttypes.h:231
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
FT_Face face
Definition: cffdrivr.c:659
#define false
Definition: ftrandom.c:52
kerning y
Definition: ttdriver.c:212
SplashClipResult
Definition: SplashClip.h:28
@ splashClipAllOutside
Definition: SplashClip.h:30
#define splashFontFractionMul
Definition: SplashFont.h:33
static int splashRound(SplashCoord x)
Definition: SplashMath.h:180
static SplashCoord splashDist(SplashCoord x0, SplashCoord y0, SplashCoord x1, SplashCoord y1)
Definition: SplashMath.h:220
double SplashCoord
Definition: SplashTypes.h:23
string engine
Definition: kpsewhich.c:51
static int ret
Definition: convert.c:72
float x
Definition: cordic.py:15
static int offset
Definition: ppmtogif.c:642
#define x1
#define y1
#define y2
#define x2
slotref slot
Definition: opcodes.h:237
void * gmallocn_checkoverflow(int count, int size)
Definition: gmem.h:122
static int glyphPathMoveTo(const FT_Vector *pt, void *path)
static int glyphPathLineTo(const FT_Vector *pt, void *path)
static int glyphPathConicTo(const FT_Vector *ctrl, const FT_Vector *pt, void *path)
static int glyphPathCubicTo(const FT_Vector *ctrl1, const FT_Vector *ctrl2, const FT_Vector *pt, void *path)
static FT_Int32 getFTLoadFlags(bool type1, bool trueType, bool aa, bool enableFreeTypeHinting, bool enableSlightHinting)
FT_Pos xMin
Definition: ftimage.h:120
FT_Pos yMax
Definition: ftimage.h:121
FT_Pos yMin
Definition: ftimage.h:120
FT_Pos xMax
Definition: ftimage.h:121
FT_Size size
Definition: freetype.h:1066
FT_BBox bbox
Definition: freetype.h:1052
FT_UShort units_per_EM
Definition: freetype.h:1054
FT_GlyphSlot glyph
Definition: freetype.h:1065
FT_Outline outline
Definition: freetype.h:1890
FT_Glyph_Metrics metrics
Definition: freetype.h:1879
FT_Pos horiAdvance
Definition: freetype.h:307
FT_Fixed xx
Definition: fttypes.h:392
FT_Fixed yx
Definition: fttypes.h:393
FT_Fixed yy
Definition: fttypes.h:393
FT_Fixed xy
Definition: fttypes.h:392
FT_Pos x
Definition: ftimage.h:77
FT_Pos y
Definition: ftimage.h:78
SplashCoord textScale
SplashPath * path
Definition: gf2pbm.c:137
unsigned short w
Definition: gf2pbm.c:138
unsigned short h
Definition: gf2pbm.c:138
Definition: pbmfont.h:4
Definition: tpic.c:45
pointer path
Definition: t1imager.h:36
return() int(((double) *(font_tbl[cur_fnt].wtbl+(int)(*(font_tbl[cur_fnt].char_wi+(int)(ch - font_tbl[cur_fnt].char_f)% 256)))/(double)(1L<< 20)) *(double) font_tbl[cur_fnt].scale)
TT_Glyph glyph
Definition: ttf2pfb.c:162
TT_Outline outline
Definition: ttf2pfb.c:167
PATTERN * pt
Definition: vlna.c:74