clang-format all pdfium code.
[pdfium.git] / core / src / fxge / ge / fx_ge_font.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "../../../include/fxge/fx_ge.h"
8 #include "../../../include/fxge/fx_freetype.h"
9 #include "text_int.h"
10 #define EM_ADJUST(em, a) (em == 0 ? (a) : (a)*1000 / em)
11 extern void _FPDFAPI_GetInternalFontData(int id1,
12                                          const uint8_t*& data,
13                                          FX_DWORD& size);
14 CFX_Font::CFX_Font() {
15   m_pSubstFont = NULL;
16   m_Face = NULL;
17   m_bEmbedded = FALSE;
18   m_bVertical = FALSE;
19   m_pFontData = NULL;
20   m_pFontDataAllocation = NULL;
21   m_dwSize = 0;
22   m_pOwnedStream = NULL;
23   m_pGsubData = NULL;
24   m_pPlatformFont = NULL;
25   m_pPlatformFontCollection = NULL;
26   m_pDwFont = NULL;
27   m_hHandle = NULL;
28   m_bDwLoaded = FALSE;
29 }
30 CFX_Font::~CFX_Font() {
31   delete m_pSubstFont;
32   m_pSubstFont = NULL;
33   if (m_pFontDataAllocation) {
34     FX_Free(m_pFontDataAllocation);
35     m_pFontDataAllocation = NULL;
36   }
37   if (m_Face) {
38     if (FXFT_Get_Face_External_Stream(m_Face)) {
39       FXFT_Clear_Face_External_Stream(m_Face);
40     }
41     if (m_bEmbedded) {
42       DeleteFace();
43     } else {
44       CFX_GEModule::Get()->GetFontMgr()->ReleaseFace(m_Face);
45     }
46   }
47   if (m_pOwnedStream) {
48     FX_Free(m_pOwnedStream);
49     m_pOwnedStream = NULL;
50   }
51   if (m_pGsubData) {
52     FX_Free(m_pGsubData);
53     m_pGsubData = NULL;
54   }
55 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
56   ReleasePlatformResource();
57 #endif
58 }
59 void CFX_Font::DeleteFace() {
60   FXFT_Done_Face(m_Face);
61   m_Face = NULL;
62 }
63 FX_BOOL CFX_Font::LoadSubst(const CFX_ByteString& face_name,
64                             FX_BOOL bTrueType,
65                             FX_DWORD flags,
66                             int weight,
67                             int italic_angle,
68                             int CharsetCP,
69                             FX_BOOL bVertical) {
70   m_bEmbedded = FALSE;
71   m_bVertical = bVertical;
72   m_pSubstFont = new CFX_SubstFont;
73   m_Face = CFX_GEModule::Get()->GetFontMgr()->FindSubstFont(
74       face_name, bTrueType, flags, weight, italic_angle, CharsetCP,
75       m_pSubstFont);
76 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
77   if (m_pSubstFont->m_ExtHandle) {
78     m_pPlatformFont = m_pSubstFont->m_ExtHandle;
79     m_pSubstFont->m_ExtHandle = NULL;
80   }
81 #endif
82   if (m_Face) {
83     m_pFontData = FXFT_Get_Face_Stream_Base(m_Face);
84     m_dwSize = FXFT_Get_Face_Stream_Size(m_Face);
85   }
86   return TRUE;
87 }
88 extern "C" {
89 unsigned long _FTStreamRead(FXFT_Stream stream,
90                             unsigned long offset,
91                             unsigned char* buffer,
92                             unsigned long count) {
93   if (count == 0) {
94     return 0;
95   }
96   IFX_FileRead* pFile = (IFX_FileRead*)stream->descriptor.pointer;
97   int res = pFile->ReadBlock(buffer, offset, count);
98   if (res) {
99     return count;
100   }
101   return 0;
102 }
103 void _FTStreamClose(FXFT_Stream stream) {}
104 };
105 FX_BOOL _LoadFile(FXFT_Library library,
106                   FXFT_Face* Face,
107                   IFX_FileRead* pFile,
108                   FXFT_Stream* stream) {
109   FXFT_Stream stream1 = (FXFT_Stream)FX_Alloc(uint8_t, sizeof(FXFT_StreamRec));
110   stream1->base = NULL;
111   stream1->size = (unsigned long)pFile->GetSize();
112   stream1->pos = 0;
113   stream1->descriptor.pointer = pFile;
114   stream1->close = _FTStreamClose;
115   stream1->read = _FTStreamRead;
116   FXFT_Open_Args args;
117   args.flags = FT_OPEN_STREAM;
118   args.stream = stream1;
119   if (FXFT_Open_Face(library, &args, 0, Face)) {
120     FX_Free(stream1);
121     return FALSE;
122   }
123   if (stream) {
124     *stream = stream1;
125   }
126   return TRUE;
127 }
128 FX_BOOL CFX_Font::LoadFile(IFX_FileRead* pFile) {
129   m_bEmbedded = FALSE;
130   FXFT_Library library;
131   if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL) {
132     FXFT_Init_FreeType(&CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary);
133   }
134   library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary;
135   FXFT_Stream stream = NULL;
136   if (!_LoadFile(library, &m_Face, pFile, &stream)) {
137     return FALSE;
138   }
139   m_pOwnedStream = stream;
140   FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
141   return TRUE;
142 }
143 int CFX_Font::GetGlyphWidth(FX_DWORD glyph_index) {
144   if (!m_Face) {
145     return 0;
146   }
147   if (m_pSubstFont && (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM)) {
148     AdjustMMParams(glyph_index, 0, 0);
149   }
150   int err = FXFT_Load_Glyph(
151       m_Face, glyph_index,
152       FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
153   if (err) {
154     return 0;
155   }
156   int width = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
157                         FXFT_Get_Glyph_HoriAdvance(m_Face));
158   return width;
159 }
160 static FXFT_Face FT_LoadFont(uint8_t* pData, int size) {
161   FXFT_Library library;
162   if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL) {
163     FXFT_Init_FreeType(&CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary);
164   }
165   library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary;
166   FXFT_Face face = NULL;
167   int error = FXFT_New_Memory_Face(library, pData, size, 0, &face);
168   if (error) {
169     return NULL;
170   }
171   error = FXFT_Set_Pixel_Sizes(face, 64, 64);
172   if (error) {
173     return NULL;
174   }
175   return face;
176 }
177 FX_BOOL CFX_Font::LoadEmbedded(const uint8_t* data, FX_DWORD size) {
178   m_pFontDataAllocation = FX_Alloc(uint8_t, size);
179   FXSYS_memcpy(m_pFontDataAllocation, data, size);
180   m_Face = FT_LoadFont((uint8_t*)m_pFontDataAllocation, size);
181   m_pFontData = (uint8_t*)m_pFontDataAllocation;
182   m_bEmbedded = TRUE;
183   m_dwSize = size;
184   return m_Face != NULL;
185 }
186 FX_BOOL CFX_Font::IsTTFont() {
187   if (m_Face == NULL) {
188     return FALSE;
189   }
190   return FXFT_Is_Face_TT_OT(m_Face) == FXFT_FACE_FLAG_SFNT;
191 }
192 int CFX_Font::GetAscent() const {
193   if (m_Face == NULL) {
194     return 0;
195   }
196   int ascent = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
197                          FXFT_Get_Face_Ascender(m_Face));
198   return ascent;
199 }
200 int CFX_Font::GetDescent() const {
201   if (m_Face == NULL) {
202     return 0;
203   }
204   int descent = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
205                           FXFT_Get_Face_Descender(m_Face));
206   return descent;
207 }
208 FX_BOOL CFX_Font::GetGlyphBBox(FX_DWORD glyph_index, FX_RECT& bbox) {
209   if (m_Face == NULL) {
210     return FALSE;
211   }
212   if (FXFT_Is_Face_Tricky(m_Face)) {
213     int error = FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72);
214     if (error) {
215       return FALSE;
216     }
217     error = FXFT_Load_Glyph(m_Face, glyph_index,
218                             FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
219     if (error) {
220       return FALSE;
221     }
222     FXFT_BBox cbox;
223     FT_Glyph glyph;
224     error = FXFT_Get_Glyph(((FXFT_Face)m_Face)->glyph, &glyph);
225     if (error) {
226       return FALSE;
227     }
228     FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox);
229     int pixel_size_x = ((FXFT_Face)m_Face)->size->metrics.x_ppem,
230         pixel_size_y = ((FXFT_Face)m_Face)->size->metrics.y_ppem;
231     if (pixel_size_x == 0 || pixel_size_y == 0) {
232       bbox.left = cbox.xMin;
233       bbox.right = cbox.xMax;
234       bbox.top = cbox.yMax;
235       bbox.bottom = cbox.yMin;
236     } else {
237       bbox.left = cbox.xMin * 1000 / pixel_size_x;
238       bbox.right = cbox.xMax * 1000 / pixel_size_x;
239       bbox.top = cbox.yMax * 1000 / pixel_size_y;
240       bbox.bottom = cbox.yMin * 1000 / pixel_size_y;
241     }
242     if (bbox.top > FXFT_Get_Face_Ascender(m_Face)) {
243       bbox.top = FXFT_Get_Face_Ascender(m_Face);
244     }
245     if (bbox.bottom < FXFT_Get_Face_Descender(m_Face)) {
246       bbox.bottom = FXFT_Get_Face_Descender(m_Face);
247     }
248     FT_Done_Glyph(glyph);
249     return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0;
250   }
251   if (FXFT_Load_Glyph(
252           m_Face, glyph_index,
253           FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) {
254     return FALSE;
255   }
256   int em = FXFT_Get_Face_UnitsPerEM(m_Face);
257   if (em == 0) {
258     bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face);
259     bbox.bottom = FXFT_Get_Glyph_HoriBearingY(m_Face);
260     bbox.top = bbox.bottom - FXFT_Get_Glyph_Height(m_Face);
261     bbox.right = bbox.left + FXFT_Get_Glyph_Width(m_Face);
262   } else {
263     bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face) * 1000 / em;
264     bbox.top =
265         (FXFT_Get_Glyph_HoriBearingY(m_Face) - FXFT_Get_Glyph_Height(m_Face)) *
266         1000 / em;
267     bbox.right =
268         (FXFT_Get_Glyph_HoriBearingX(m_Face) + FXFT_Get_Glyph_Width(m_Face)) *
269         1000 / em;
270     bbox.bottom = (FXFT_Get_Glyph_HoriBearingY(m_Face)) * 1000 / em;
271   }
272   return TRUE;
273 }
274 FX_BOOL CFX_Font::IsItalic() {
275   if (m_Face == NULL) {
276     return FALSE;
277   }
278   FX_BOOL ret = FXFT_Is_Face_Italic(m_Face) == FXFT_STYLE_FLAG_ITALIC;
279   if (!ret) {
280     CFX_ByteString str(FXFT_Get_Face_Style_Name(m_Face));
281     str.MakeLower();
282     if (str.Find("italic") != -1) {
283       ret = TRUE;
284     }
285   }
286   return ret;
287 }
288 FX_BOOL CFX_Font::IsBold() {
289   if (m_Face == NULL) {
290     return FALSE;
291   }
292   return FXFT_Is_Face_Bold(m_Face) == FXFT_STYLE_FLAG_BOLD;
293 }
294 FX_BOOL CFX_Font::IsFixedWidth() {
295   if (m_Face == NULL) {
296     return FALSE;
297   }
298   return FXFT_Is_Face_fixedwidth(m_Face);
299 }
300 CFX_WideString CFX_Font::GetPsName() const {
301   if (m_Face == NULL) {
302     return CFX_WideString();
303   }
304   CFX_WideString psName =
305       CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(m_Face));
306   if (psName.IsEmpty()) {
307     psName = CFX_WideString::FromLocal("Untitled");
308   }
309   return psName;
310 }
311 CFX_ByteString CFX_Font::GetFamilyName() const {
312   if (m_Face == NULL && m_pSubstFont == NULL) {
313     return CFX_ByteString();
314   }
315   if (m_Face) {
316     return CFX_ByteString(FXFT_Get_Face_Family_Name(m_Face));
317   }
318   return m_pSubstFont->m_Family;
319 }
320 CFX_ByteString CFX_Font::GetFaceName() const {
321   if (m_Face == NULL && m_pSubstFont == NULL) {
322     return CFX_ByteString();
323   }
324   if (m_Face) {
325     CFX_ByteString facename;
326     CFX_ByteString style = CFX_ByteString(FXFT_Get_Face_Style_Name(m_Face));
327     facename = GetFamilyName();
328     if (facename.IsEmpty()) {
329       facename = "Untitled";
330     }
331     if (!style.IsEmpty() && style != "Regular") {
332       facename += " " + style;
333     }
334     return facename;
335   }
336   return m_pSubstFont->m_Family;
337 }
338 FX_BOOL CFX_Font::GetBBox(FX_RECT& bbox) {
339   if (m_Face == NULL) {
340     return FALSE;
341   }
342   int em = FXFT_Get_Face_UnitsPerEM(m_Face);
343   if (em == 0) {
344     bbox.left = FXFT_Get_Face_xMin(m_Face);
345     bbox.bottom = FXFT_Get_Face_yMax(m_Face);
346     bbox.top = FXFT_Get_Face_yMin(m_Face);
347     bbox.right = FXFT_Get_Face_xMax(m_Face);
348   } else {
349     bbox.left = FXFT_Get_Face_xMin(m_Face) * 1000 / em;
350     bbox.top = FXFT_Get_Face_yMin(m_Face) * 1000 / em;
351     bbox.right = FXFT_Get_Face_xMax(m_Face) * 1000 / em;
352     bbox.bottom = FXFT_Get_Face_yMax(m_Face) * 1000 / em;
353   }
354   return TRUE;
355 }
356 int CFX_Font::GetHeight() {
357   if (m_Face == NULL) {
358     return 0;
359   }
360   int height =
361       EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Height(m_Face));
362   return height;
363 }
364 int CFX_Font::GetMaxAdvanceWidth() {
365   if (m_Face == NULL) {
366     return 0;
367   }
368   int width = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
369                         FXFT_Get_Face_MaxAdvanceWidth(m_Face));
370   return width;
371 }
372 int CFX_Font::GetULPos() {
373   if (m_Face == NULL) {
374     return 0;
375   }
376   int pos = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
377                       FXFT_Get_Face_UnderLinePosition(m_Face));
378   return pos;
379 }
380 int CFX_Font::GetULthickness() {
381   if (m_Face == NULL) {
382     return 0;
383   }
384   int thickness = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
385                             FXFT_Get_Face_UnderLineThickness(m_Face));
386   return thickness;
387 }
388 CFX_UnicodeEncoding::CFX_UnicodeEncoding(CFX_Font* pFont) {
389   m_pFont = pFont;
390 }
391 FX_DWORD CFX_UnicodeEncoding::GlyphFromCharCode(FX_DWORD charcode) {
392   FXFT_Face face = m_pFont->GetFace();
393   if (!face) {
394     return charcode;
395   }
396   if (FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE) == 0) {
397     return FXFT_Get_Char_Index(face, charcode);
398   }
399   if (m_pFont->m_pSubstFont && m_pFont->m_pSubstFont->m_Charset == 2) {
400     FX_DWORD index = 0;
401     if (FXFT_Select_Charmap(face, FXFT_ENCODING_MS_SYMBOL) == 0) {
402       index = FXFT_Get_Char_Index(face, charcode);
403     }
404     if (!index && !FXFT_Select_Charmap(face, FXFT_ENCODING_APPLE_ROMAN)) {
405       return FXFT_Get_Char_Index(face, charcode);
406     }
407   }
408   return charcode;
409 }
410 FX_DWORD CFX_UnicodeEncoding::GlyphFromCharCodeEx(FX_DWORD charcode,
411                                                   int encoding) {
412   FXFT_Face face = m_pFont->GetFace();
413   if (!face) {
414     return charcode;
415   }
416   if (encoding == ENCODING_UNICODE) {
417     return GlyphFromCharCode(charcode);
418   }
419   int nmaps = FXFT_Get_Face_CharmapCount(m_pFont->m_Face);
420   int i = 0;
421   while (i < nmaps) {
422     int encoding = FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i++]);
423     if (encoding != FXFT_ENCODING_UNICODE) {
424       FXFT_Select_Charmap(face, encoding);
425       break;
426     }
427   }
428   return FXFT_Get_Char_Index(face, charcode);
429 }
430 IFX_FontEncoding* FXGE_CreateUnicodeEncoding(CFX_Font* pFont) {
431   return new CFX_UnicodeEncoding(pFont);
432 }