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)  

FontEngine.cpp
Go to the documentation of this file.
1 /*************************************************************************
2 ** FontEngine.cpp **
3 ** **
4 ** This file is part of dvisvgm -- a fast DVI to SVG converter **
5 ** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> **
6 ** **
7 ** This program is free software; you can redistribute it and/or **
8 ** modify it under the terms of the GNU General Public License as **
9 ** published by the Free Software Foundation; either version 3 of **
10 ** the License, or (at your option) any later version. **
11 ** **
12 ** This program is distributed in the hope that it will be useful, but **
13 ** WITHOUT ANY WARRANTY; without even the implied warranty of **
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the **
15 ** GNU General Public License for more details. **
16 ** **
17 ** You should have received a copy of the GNU General Public License **
18 ** along with this program; if not, see <http://www.gnu.org/licenses/>. **
19 *************************************************************************/
20 
21 #include <cmath>
22 #include <sstream>
23 #include <ft2build.h>
24 #include FT_ADVANCES_H
25 #include FT_GLYPH_H
26 #include FT_OUTLINE_H
27 #include FT_TRUETYPE_TABLES_H
28 #include FT_TYPES_H
29 #include "Font.hpp"
30 #include "FontEngine.hpp"
31 #include "FontStyle.hpp"
32 #include "Message.hpp"
33 #include "utility.hpp"
34 
35 using namespace std;
36 
37 
38 /** Converts a floating point value to a 16.16 fixed point value. */
39 static inline FT_Fixed to_16dot16 (double val) {
40  return static_cast<FT_Fixed>(lround(val*65536.0));
41 }
42 
43 
44 /** Converts an integer to a 16.16 fixed point value. */
45 static inline FT_Fixed to_16dot16 (int val) {
46  return static_cast<FT_Fixed>(val) << 16;
47 }
48 
49 
50 ///////////////////////////////////////////////////////////////////////////
51 
52 
55  Message::estream(true) << "failed to initialize FreeType library\n";
56 }
57 
58 
61  Message::estream(true) << "failed to release font\n";
63  Message::estream(true) << "failed to release FreeType library\n";
64 }
65 
66 
67 /** Returns the singleton instance of this class. */
69  static FontEngine engine;
70  return engine;
71 }
72 
73 
75  FT_Int major, minor, patch;
76  FT_Library &lib = instance()._library;
77  FT_Library_Version(lib, &major, &minor, &patch);
78  ostringstream oss;
79  oss << major << '.' << minor << '.' << patch;
80  return oss.str();
81 }
82 
83 
84 /** Sets the font to be used.
85  * @param[in] fname path to font file
86  * @param[in] fontindex index of font in font collection (multi-font files, like TTC)
87  * @return true on success */
88 bool FontEngine::setFont (const string &fname, int fontindex, const CharMapID &charMapID) {
90  Message::estream(true) << "failed to release font\n";
91  if (FT_New_Face(_library, fname.c_str(), fontindex, &_currentFace)) {
92  Message::estream(true) << "can't read font file " << fname << '\n';
93  return false;
94  }
95  if (charMapID.valid())
96  setCharMap(charMapID);
97  return true;
98 }
99 
100 
102  if (_currentFont && _currentFont->name() == font.name())
103  return true;
104 
105  if (const char *path=font.path()) {
106  auto pf = dynamic_cast<const PhysicalFont*>(&font);
107  if (setFont(path, font.fontIndex(), pf ? pf->getCharMapID() : CharMapID())) {
108  _currentFont = &font;
109  return true;
110  }
111  }
112  return false;
113 }
114 
115 
116 bool FontEngine::isCIDFont() const {
117  FT_Bool cid_keyed;
118  return FT_Get_CID_Is_Internally_CID_Keyed(_currentFace, &cid_keyed) == 0 && cid_keyed;
119 }
120 
121 
122 bool FontEngine::setCharMap (const CharMapID &charMapID) {
123  for (int i=0; i < _currentFace->num_charmaps; i++) {
124  FT_CharMap ft_cmap = _currentFace->charmaps[i];
125  if (ft_cmap->platform_id == charMapID.platform_id && ft_cmap->encoding_id == charMapID.encoding_id) {
126  FT_Set_Charmap(_currentFace, ft_cmap);
127  return true;
128  }
129  }
130  return false;
131 }
132 
133 
134 /** Returns a character map that maps from glyph indexes to character codes
135  * of the current encoding.
136  * @param[out] charmap the resulting charmap */
138  charmap.clear();
139  FT_UInt gid; // index of current glyph
140  uint32_t charcode = FT_Get_First_Char(_currentFace, &gid);
141  while (gid) {
142  if (!charmap.valueAt(gid))
143  charmap.addRange(gid, gid, charcode);
144  charcode = FT_Get_Next_Char(_currentFace, charcode, &gid);
145  }
146 }
147 
148 
149 /** Creates a charmap that maps from the custom character encoding to Unicode.
150  * @return pointer to charmap if it could be created, 0 otherwise */
151 unique_ptr<const RangeMap> FontEngine::createCustomToUnicodeMap () {
152  FT_CharMap ftcharmap = _currentFace->charmap;
154  return nullptr;
155  RangeMap gidToCharCodeMap;
156  buildGidToCharCodeMap(gidToCharCodeMap);
158  return nullptr;
159  auto charmap = util::make_unique<RangeMap>();
160  FT_UInt gid; // index of current glyph
161  uint32_t ucCharcode = FT_Get_First_Char(_currentFace, &gid); // Unicode code point
162  while (gid) {
163  uint32_t customCharcode = gidToCharCodeMap.valueAt(gid);
164  charmap->addRange(customCharcode, customCharcode, ucCharcode);
165  ucCharcode = FT_Get_Next_Char(_currentFace, ucCharcode, &gid);
166  }
167  FT_Set_Charmap(_currentFace, ftcharmap);
168  return std::move(charmap);
169 }
170 
171 
172 const char* FontEngine::getFamilyName () const {
173  return _currentFace ? _currentFace->family_name : nullptr;
174 }
175 
176 
177 const char* FontEngine::getStyleName () const {
178  return _currentFace ? _currentFace->style_name : nullptr;
179 }
180 
181 
183  return _currentFace ? _currentFace->units_per_EM : 0;
184 }
185 
186 
187 /** Returns the ascender of the current font in font units.
188  * The (usually) positive value denotes the maximum height
189  * (extent above the baseline) of the font. */
191  return _currentFace ? _currentFace->ascender : 0;
192 }
193 
194 
195 /** Returns the descender of the current font in font units.
196  * The (usually) positive value denotes the maximum depth
197  * (extent below the baseline) of the font. */
199  return _currentFace ? -_currentFace->descender : 0;
200 }
201 
202 
203 int FontEngine::getAdvance (int c) const {
204  if (_currentFace) {
205  FT_Fixed adv=0;
207  return adv;
208  }
209  return 0;
210 }
211 
212 
214  if (_currentFace) {
215  auto table = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(_currentFace, ft_sfnt_os2));
216  return table ? table->xAvgCharWidth : 0;
217  }
218  return 0;
219 }
220 
221 
222 int FontEngine::getHAdvance (const Character &c) const {
223  if (_currentFace) {
226  }
227  return 0;
228 }
229 
230 
231 int FontEngine::getVAdvance (const Character &c) const {
232  if (_currentFace) {
237  }
238  return 0;
239 }
240 
241 
242 int FontEngine::charIndex (const Character &c) const {
244  return c.type() == Character::NAME ? 0 : c.number();
245  switch (c.type()) {
246  case Character::CHRCODE:
247  return FT_Get_Char_Index(_currentFace, (FT_ULong)c.number());
248  case Character::NAME:
249  return FT_Get_Name_Index(_currentFace, const_cast<FT_String*>(c.name()));
250  default:
251  return c.number();
252  }
253 }
254 
255 
256 /** Get first available character of the current font face. */
258  if (_currentFace)
260  return 0;
261 }
262 
263 
264 /** Get the next available character of the current font face. */
268  return getFirstChar();
269 }
270 
271 
272 /** Returns the number of glyphs present in the current font face. */
274  return _currentFace ? _currentFace->num_glyphs : 0;
275 }
276 
277 
278 /** Returns the glyph name for a given charater code.
279  * @param[in] c char code
280  * @return glyph name */
281 string FontEngine::getGlyphName (const Character &c) const {
282  if (c.type() == Character::NAME)
283  return c.name();
284 
286  char buf[256];
288  return string(buf);
289  }
290  return "";
291 }
292 
293 
294 vector<int> FontEngine::getPanose () const {
295  vector<int> panose(10);
296  if (_currentFace) {
297  auto table = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(_currentFace, ft_sfnt_os2));
298  if (table)
299  for (int i=0; i < 10; i++)
300  panose[i] = table->panose[i];
301  }
302  return panose;
303 }
304 
305 
306 int FontEngine::getCharMapIDs (vector<CharMapID> &charmapIDs) const {
307  charmapIDs.clear();
308  if (_currentFace) {
309  for (int i=0; i < _currentFace->num_charmaps; i++) {
311  charmapIDs.emplace_back(CharMapID(charmap->platform_id, charmap->encoding_id));
312  }
313  }
314  return charmapIDs.size();
315 }
316 
317 
321  return CharMapID();
322 }
323 
324 
328  return CharMapID();
329 }
330 
331 
332 // handle API change in freetype version 2.2.1
333 #if FREETYPE_MAJOR > 2 || (FREETYPE_MAJOR == 2 && (FREETYPE_MINOR > 2 || (FREETYPE_MINOR == 2 && FREETYPE_PATCH >= 1)))
334  using FTVectorPtr = const FT_Vector*;
335 #else
337 #endif
338 
339 
340 // Callback functions used by trace_outline/FT_Outline_Decompose
341 static int moveto (FTVectorPtr to, void *user) {
342  auto glyph = static_cast<Glyph*>(user);
343  glyph->moveto(to->x, to->y);
344  return 0;
345 }
346 
347 
348 static int lineto (FTVectorPtr to, void *user) {
349  auto glyph = static_cast<Glyph*>(user);
350  glyph->lineto(to->x, to->y);
351  return 0;
352 }
353 
354 
355 static int quadto (FTVectorPtr control, FTVectorPtr to, void *user) {
356  auto glyph = static_cast<Glyph*>(user);
357  glyph->quadto(control->x, control->y, to->x, to->y);
358  return 0;
359 }
360 
361 
362 static int cubicto (FTVectorPtr control1, FTVectorPtr control2, FTVectorPtr to, void *user) {
363  auto glyph = static_cast<Glyph*>(user);
364  glyph->cubicto(control1->x, control1->y, control2->x, control2->y, to->x, to->y);
365  return 0;
366 }
367 
368 
369 /** Traces the outline of a glyph by calling the corresponding "drawing" functions.
370  * Each glyph is composed of straight lines, quadratic or cubic Bézier curves.
371  * This function creates a Glyph object representing these graphics segments.
372  * @param[in] face FreeType object representing the font to scan
373  * @param[in] font corresponding Font object providing additional data
374  * @param[in] index index of the glyph to be traced
375  * @param[out] glyph resulting Glyph object containing the graphics segments
376  * @param[in] scale if true the current pt size will be considered otherwise the plain TrueType units are used.
377  * @return false on errors */
378 static bool trace_outline (FT_Face face, const Font *font, int index, Glyph &glyph, bool scale) {
379  if (face) {
381  Message::estream(true) << "can't load glyph " << int(index) << '\n';
382  return false;
383  }
385  Message::estream(true) << "no outlines found in glyph " << int(index) << '\n';
386  return false;
387  }
389  // apply style parameters if set
390  if (const FontStyle *style = font->style()) {
391  FT_Matrix matrix = {to_16dot16(style->extend), to_16dot16(style->slant), 0, to_16dot16(1)};
393  if (style->bold != 0)
394  FT_Outline_Embolden(&outline, style->bold/font->scaledSize()*face->units_per_EM);
395  }
396  const FT_Outline_Funcs funcs = {moveto, lineto, quadto, cubicto, 0, 0};
398  return true;
399  }
400  Message::wstream(true) << "can't trace outline (no font selected)\n";
401  return false;
402 }
403 
404 
405 /** Traces the outline of a glyph by calling the corresponding "drawing" functions.
406  * Each glyph is composed of straight lines, quadratic or cubic Bézier curves.
407  * This function creates a Glyph object representing these graphics segments.
408  * @param[in] c the glyph of this character will be traced
409  * @param[out] glyph resulting Glyph object containing the graphics segments
410  * @param[in] scale if true the current pt size will be considered otherwise the plain TrueType units are used.
411  * @return false on errors */
412 bool FontEngine::traceOutline (const Character &c, Glyph &glyph, bool scale) const {
414 }
long __cdecl lround(double _X)
static int lineto(FTVectorPtr to, void *user)
Definition: FontEngine.cpp:348
static int cubicto(FTVectorPtr control1, FTVectorPtr control2, FTVectorPtr to, void *user)
Definition: FontEngine.cpp:362
static FT_Fixed to_16dot16(double val)
Definition: FontEngine.cpp:39
static bool trace_outline(FT_Face face, const Font *font, int index, Glyph &glyph, bool scale)
Definition: FontEngine.cpp:378
static int quadto(FTVectorPtr control, FTVectorPtr to, void *user)
Definition: FontEngine.cpp:355
static int moveto(FTVectorPtr to, void *user)
Definition: FontEngine.cpp:341
static int pf(int(*writeFunc)(void *stream, const char *data, int size), void *stream, const char *fmt,...)
Definition: HTMLGen.cc:254
#define font
Definition: aptex-macros.h:175
unsigned long Glyph
const char * getFamilyName() const
Definition: FontEngine.cpp:172
FT_Library _library
Definition: FontEngine.hpp:78
int getUnitsPerEM() const
Definition: FontEngine.cpp:182
FT_Face _currentFace
Definition: FontEngine.hpp:77
int getFirstChar() const
Definition: FontEngine.cpp:257
unsigned int _currentChar
Definition: FontEngine.hpp:76
bool setCharMap(const CharMapID &charMapID)
Definition: FontEngine.cpp:122
CharMapID setUnicodeCharMap()
Definition: FontEngine.cpp:318
int getDescender() const
Definition: FontEngine.cpp:198
int getNumGlyphs() const
Definition: FontEngine.cpp:273
int getVAdvance(const Character &c) const
Definition: FontEngine.cpp:231
CharMapID setCustomCharMap()
Definition: FontEngine.cpp:325
static FontEngine & instance()
Definition: FontEngine.cpp:68
const char * getStyleName() const
Definition: FontEngine.cpp:177
std::vector< int > getPanose() const
Definition: FontEngine.cpp:294
int charIndex(const Character &c) const
Definition: FontEngine.cpp:242
int getNextChar() const
Definition: FontEngine.cpp:265
static std::string version()
Definition: FontEngine.cpp:74
int getAdvance(int c) const
Definition: FontEngine.cpp:203
void buildGidToCharCodeMap(RangeMap &charmap)
Definition: FontEngine.cpp:137
std::string getGlyphName(const Character &c) const
Definition: FontEngine.cpp:281
unsigned int _currentGlyphIndex
Definition: FontEngine.hpp:76
std::unique_ptr< const RangeMap > createCustomToUnicodeMap()
Definition: FontEngine.cpp:151
bool traceOutline(const Character &c, Glyph &glyph, bool scale=true) const
Definition: FontEngine.cpp:412
bool setFont(const Font &font)
Definition: FontEngine.cpp:101
int getCharMapIDs(std::vector< CharMapID > &charmapIDs) const
Definition: FontEngine.cpp:306
const Font * _currentFont
Definition: FontEngine.hpp:79
int getHAdvance() const
Definition: FontEngine.cpp:213
int getAscender() const
Definition: FontEngine.cpp:190
bool isCIDFont() const
Definition: FontEngine.cpp:116
Definition: Font.hpp:55
virtual std::string name() const =0
static MessageStream & wstream(bool prefix=false)
Definition: Message.cpp:165
static MessageStream & estream(bool prefix=false)
Definition: Message.cpp:179
uint32_t valueAt(uint32_t c) const
Definition: RangeMap.cpp:174
#define control
Definition: devnag.c:323
#define FT_ENCODING_ADOBE_CUSTOM
struct move_struct move
#define c(n)
Definition: gpos-common.c:150
FT_Load_Glyph(FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags)
Definition: ftobjs.c:796
FT_New_Face(FT_Library library, const char *filepathname, FT_Long face_index, FT_Face *aface)
Definition: ftobjs.c:1468
#define FT_LOAD_NO_SCALE
Definition: freetype.h:3022
FT_Library_Version(FT_Library library, FT_Int *amajor, FT_Int *aminor, FT_Int *apatch)
Definition: ftobjs.c:5322
FT_Done_Face(FT_Face face)
Definition: ftobjs.c:2783
FT_Get_First_Char(FT_Face face, FT_UInt *agindex)
Definition: ftobjs.c:3760
FT_Get_Char_Index(FT_Face face, FT_ULong charcode)
Definition: ftobjs.c:3731
FT_Select_Charmap(FT_Face face, FT_Encoding encoding)
Definition: ftobjs.c:3521
#define FT_HAS_VERTICAL(face)
Definition: freetype.h:1242
#define FT_LOAD_DEFAULT
Definition: freetype.h:3021
@ FT_ENCODING_UNICODE
Definition: freetype.h:745
FT_Get_Next_Char(FT_Face face, FT_ULong char_code, FT_UInt *agindex)
Definition: ftobjs.c:3785
FT_Set_Charmap(FT_Face face, FT_CharMap charmap)
Definition: ftobjs.c:3564
FT_Get_Glyph_Name(FT_Face face, FT_UInt glyph_index, FT_Pointer buffer, FT_UInt buffer_max)
Definition: ftobjs.c:4110
#define FT_HAS_GLYPH_NAMES(face)
Definition: freetype.h:1346
FT_Get_Name_Index(FT_Face face, const FT_String *glyph_name)
Definition: ftobjs.c:4082
FT_Done_FreeType(FT_Library library)
Definition: ftinit.c:235
FT_Init_FreeType(FT_Library *alibrary)
Definition: ftinit.c:199
FT_Get_Advance(FT_Face face, FT_UInt gindex, FT_Int32 load_flags, FT_Fixed *padvance)
Definition: ftadvanc.c:74
FT_Get_CID_Is_Internally_CID_Keyed(FT_Face face, FT_Bool *is_cid)
Definition: ftcid.c:65
@ FT_GLYPH_FORMAT_OUTLINE
Definition: ftimage.h:749
FT_Outline_Embolden(FT_Outline *outline, FT_Pos strength)
Definition: ftoutln.c:894
FT_Outline_Transform(const FT_Outline *outline, const FT_Matrix *matrix)
Definition: ftoutln.c:706
FT_BEGIN_HEADER FT_Outline_Decompose(FT_Outline *outline, const FT_Outline_Funcs *func_interface, void *user)
Definition: ftoutln.c:43
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
unsigned long FT_ULong
Definition: fttypes.h:253
signed long FT_Fixed
Definition: fttypes.h:287
char FT_String
Definition: fttypes.h:187
unsigned int FT_UInt
Definition: fttypes.h:231
signed int FT_Int
Definition: fttypes.h:220
FT_Get_Sfnt_Table(FT_Face face, FT_Sfnt_Tag tag)
Definition: ftobjs.c:4176
#define ft_sfnt_os2
Definition: tttables.h:638
small capitals from c petite p scientific i
Definition: afcover.h:80
Arabic default style
Definition: afstyles.h:94
FT_Face face
Definition: cffdrivr.c:659
unsigned int uint32_t
Definition: stdint.h:80
#define buf
int major
Definition: pdfcolor.c:526
int minor
Definition: pdfcolor.c:527
string engine
Definition: kpsewhich.c:51
#define string
Definition: ctangleboot.c:111
STL namespace.
float ** matrix()
char * fname
Definition: plain2.c:121
real to[600]
Definition: pmxab.c:87
double scale
Definition: pnmhistmap.c:38
static const luaL_Reg funcs[]
Definition: lutf8lib.c:238
uint8_t encoding_id
Definition: CharMapID.hpp:56
bool valid() const
Definition: CharMapID.hpp:39
uint8_t platform_id
Definition: CharMapID.hpp:55
FT_UShort platform_id
Definition: freetype.h:821
FT_UShort encoding_id
Definition: freetype.h:822
FT_String * family_name
Definition: freetype.h:1038
FT_String * style_name
Definition: freetype.h:1039
FT_CharMap * charmaps
Definition: freetype.h:1045
FT_Long num_glyphs
Definition: freetype.h:1036
FT_Int num_charmaps
Definition: freetype.h:1044
FT_Short descender
Definition: freetype.h:1056
FT_UShort units_per_EM
Definition: freetype.h:1054
FT_CharMap charmap
Definition: freetype.h:1067
FT_GlyphSlot glyph
Definition: freetype.h:1065
FT_Short ascender
Definition: freetype.h:1055
FT_Outline outline
Definition: freetype.h:1890
FT_Glyph_Metrics metrics
Definition: freetype.h:1879
FT_Glyph_Format format
Definition: freetype.h:1884
FT_Pos vertAdvance
Definition: freetype.h:311
FT_Pos horiAdvance
Definition: freetype.h:307
FT_Pos x
Definition: ftimage.h:77
FT_Pos y
Definition: ftimage.h:78
Definition: pbmfont.h:11
Definition: pbmfont.h:4
Definition: mendex.h:20
Definition: table.h:30
Definition: strexpr.c:21
pointer path
Definition: t1imager.h:36
val
Definition: tex4ht.c:3227
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_Outline outline
Definition: ttf2pfb.c:167