a6ababf572b96bdc69f3027f7e26c784091f1712
[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 CFX_Font::CFX_Font() {
12   m_pSubstFont = NULL;
13   m_Face = NULL;
14   m_bEmbedded = FALSE;
15   m_bVertical = FALSE;
16   m_pFontData = NULL;
17   m_pFontDataAllocation = NULL;
18   m_dwSize = 0;
19   m_pGsubData = NULL;
20   m_pPlatformFont = NULL;
21   m_pPlatformFontCollection = NULL;
22   m_pDwFont = NULL;
23   m_hHandle = NULL;
24   m_bDwLoaded = FALSE;
25 }
26 CFX_Font::~CFX_Font() {
27   delete m_pSubstFont;
28   m_pSubstFont = NULL;
29   FX_Free(m_pFontDataAllocation);
30   m_pFontDataAllocation = NULL;
31   if (m_Face) {
32     if (FXFT_Get_Face_External_Stream(m_Face)) {
33       FXFT_Clear_Face_External_Stream(m_Face);
34     }
35     if (m_bEmbedded) {
36       DeleteFace();
37     } else {
38       CFX_GEModule::Get()->GetFontMgr()->ReleaseFace(m_Face);
39     }
40   }
41   FX_Free(m_pGsubData);
42   m_pGsubData = NULL;
43 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
44   ReleasePlatformResource();
45 #endif
46 }
47 void CFX_Font::DeleteFace() {
48   FXFT_Done_Face(m_Face);
49   m_Face = NULL;
50 }
51 void CFX_Font::LoadSubst(const CFX_ByteString& face_name,
52                          FX_BOOL bTrueType,
53                          FX_DWORD flags,
54                          int weight,
55                          int italic_angle,
56                          int CharsetCP,
57                          FX_BOOL bVertical) {
58   m_bEmbedded = FALSE;
59   m_bVertical = bVertical;
60   m_pSubstFont = new CFX_SubstFont;
61   m_Face = CFX_GEModule::Get()->GetFontMgr()->FindSubstFont(
62       face_name, bTrueType, flags, weight, italic_angle, CharsetCP,
63       m_pSubstFont);
64 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
65   if (m_pSubstFont->m_ExtHandle) {
66     m_pPlatformFont = m_pSubstFont->m_ExtHandle;
67     m_pSubstFont->m_ExtHandle = NULL;
68   }
69 #endif
70   if (m_Face) {
71     m_pFontData = FXFT_Get_Face_Stream_Base(m_Face);
72     m_dwSize = FXFT_Get_Face_Stream_Size(m_Face);
73   }
74 }
75
76 int CFX_Font::GetGlyphWidth(FX_DWORD glyph_index) {
77   if (!m_Face) {
78     return 0;
79   }
80   if (m_pSubstFont && (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM)) {
81     AdjustMMParams(glyph_index, 0, 0);
82   }
83   int err = FXFT_Load_Glyph(
84       m_Face, glyph_index,
85       FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
86   if (err) {
87     return 0;
88   }
89   int width = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
90                         FXFT_Get_Glyph_HoriAdvance(m_Face));
91   return width;
92 }
93 static FXFT_Face FT_LoadFont(uint8_t* pData, int size) {
94   FXFT_Library library;
95   if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL) {
96     FXFT_Init_FreeType(&CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary);
97   }
98   library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary;
99   FXFT_Face face = NULL;
100   int error = FXFT_New_Memory_Face(library, pData, size, 0, &face);
101   if (error) {
102     return NULL;
103   }
104   error = FXFT_Set_Pixel_Sizes(face, 64, 64);
105   if (error) {
106     return NULL;
107   }
108   return face;
109 }
110 FX_BOOL CFX_Font::LoadEmbedded(const uint8_t* data, FX_DWORD size) {
111   m_pFontDataAllocation = FX_Alloc(uint8_t, size);
112   FXSYS_memcpy(m_pFontDataAllocation, data, size);
113   m_Face = FT_LoadFont((uint8_t*)m_pFontDataAllocation, size);
114   m_pFontData = (uint8_t*)m_pFontDataAllocation;
115   m_bEmbedded = TRUE;
116   m_dwSize = size;
117   return m_Face != NULL;
118 }
119
120 FX_BOOL CFX_Font::IsTTFont() const {
121   if (!m_Face)
122     return FALSE;
123   return FXFT_Is_Face_TT_OT(m_Face) == FXFT_FACE_FLAG_SFNT;
124 }
125
126 int CFX_Font::GetAscent() const {
127   if (!m_Face)
128     return 0;
129   return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
130                    FXFT_Get_Face_Ascender(m_Face));
131 }
132
133 int CFX_Font::GetDescent() const {
134   if (!m_Face)
135     return 0;
136   return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
137                    FXFT_Get_Face_Descender(m_Face));
138 }
139
140 FX_BOOL CFX_Font::GetGlyphBBox(FX_DWORD glyph_index, FX_RECT& bbox) {
141   if (!m_Face)
142     return FALSE;
143
144   if (FXFT_Is_Face_Tricky(m_Face)) {
145     int error = FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72);
146     if (error) {
147       return FALSE;
148     }
149     error = FXFT_Load_Glyph(m_Face, glyph_index,
150                             FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
151     if (error) {
152       return FALSE;
153     }
154     FXFT_BBox cbox;
155     FT_Glyph glyph;
156     error = FXFT_Get_Glyph(((FXFT_Face)m_Face)->glyph, &glyph);
157     if (error) {
158       return FALSE;
159     }
160     FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox);
161     int pixel_size_x = ((FXFT_Face)m_Face)->size->metrics.x_ppem,
162         pixel_size_y = ((FXFT_Face)m_Face)->size->metrics.y_ppem;
163     if (pixel_size_x == 0 || pixel_size_y == 0) {
164       bbox.left = cbox.xMin;
165       bbox.right = cbox.xMax;
166       bbox.top = cbox.yMax;
167       bbox.bottom = cbox.yMin;
168     } else {
169       bbox.left = cbox.xMin * 1000 / pixel_size_x;
170       bbox.right = cbox.xMax * 1000 / pixel_size_x;
171       bbox.top = cbox.yMax * 1000 / pixel_size_y;
172       bbox.bottom = cbox.yMin * 1000 / pixel_size_y;
173     }
174     if (bbox.top > FXFT_Get_Face_Ascender(m_Face)) {
175       bbox.top = FXFT_Get_Face_Ascender(m_Face);
176     }
177     if (bbox.bottom < FXFT_Get_Face_Descender(m_Face)) {
178       bbox.bottom = FXFT_Get_Face_Descender(m_Face);
179     }
180     FT_Done_Glyph(glyph);
181     return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0;
182   }
183   if (FXFT_Load_Glyph(
184           m_Face, glyph_index,
185           FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) {
186     return FALSE;
187   }
188   int em = FXFT_Get_Face_UnitsPerEM(m_Face);
189   if (em == 0) {
190     bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face);
191     bbox.bottom = FXFT_Get_Glyph_HoriBearingY(m_Face);
192     bbox.top = bbox.bottom - FXFT_Get_Glyph_Height(m_Face);
193     bbox.right = bbox.left + FXFT_Get_Glyph_Width(m_Face);
194   } else {
195     bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face) * 1000 / em;
196     bbox.top =
197         (FXFT_Get_Glyph_HoriBearingY(m_Face) - FXFT_Get_Glyph_Height(m_Face)) *
198         1000 / em;
199     bbox.right =
200         (FXFT_Get_Glyph_HoriBearingX(m_Face) + FXFT_Get_Glyph_Width(m_Face)) *
201         1000 / em;
202     bbox.bottom = (FXFT_Get_Glyph_HoriBearingY(m_Face)) * 1000 / em;
203   }
204   return TRUE;
205 }
206
207 FX_BOOL CFX_Font::IsItalic() const {
208   if (!m_Face)
209     return FALSE;
210
211   FX_BOOL ret = FXFT_Is_Face_Italic(m_Face) == FXFT_STYLE_FLAG_ITALIC;
212   if (!ret) {
213     CFX_ByteString str(FXFT_Get_Face_Style_Name(m_Face));
214     str.MakeLower();
215     if (str.Find("italic") != -1) {
216       ret = TRUE;
217     }
218   }
219   return ret;
220 }
221
222 FX_BOOL CFX_Font::IsBold() const {
223   if (!m_Face)
224     return FALSE;
225   return FXFT_Is_Face_Bold(m_Face) == FXFT_STYLE_FLAG_BOLD;
226 }
227
228 FX_BOOL CFX_Font::IsFixedWidth() const {
229   if (!m_Face)
230     return FALSE;
231   return FXFT_Is_Face_fixedwidth(m_Face);
232 }
233
234 CFX_WideString CFX_Font::GetPsName() const {
235   if (m_Face == NULL) {
236     return CFX_WideString();
237   }
238   CFX_WideString psName =
239       CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(m_Face));
240   if (psName.IsEmpty()) {
241     psName = CFX_WideString::FromLocal("Untitled");
242   }
243   return psName;
244 }
245 CFX_ByteString CFX_Font::GetFamilyName() const {
246   if (m_Face == NULL && m_pSubstFont == NULL) {
247     return CFX_ByteString();
248   }
249   if (m_Face) {
250     return CFX_ByteString(FXFT_Get_Face_Family_Name(m_Face));
251   }
252   return m_pSubstFont->m_Family;
253 }
254 CFX_ByteString CFX_Font::GetFaceName() const {
255   if (m_Face == NULL && m_pSubstFont == NULL) {
256     return CFX_ByteString();
257   }
258   if (m_Face) {
259     CFX_ByteString facename;
260     CFX_ByteString style = CFX_ByteString(FXFT_Get_Face_Style_Name(m_Face));
261     facename = GetFamilyName();
262     if (facename.IsEmpty()) {
263       facename = "Untitled";
264     }
265     if (!style.IsEmpty() && style != "Regular") {
266       facename += " " + style;
267     }
268     return facename;
269   }
270   return m_pSubstFont->m_Family;
271 }
272 FX_BOOL CFX_Font::GetBBox(FX_RECT& bbox) {
273   if (m_Face == NULL) {
274     return FALSE;
275   }
276   int em = FXFT_Get_Face_UnitsPerEM(m_Face);
277   if (em == 0) {
278     bbox.left = FXFT_Get_Face_xMin(m_Face);
279     bbox.bottom = FXFT_Get_Face_yMax(m_Face);
280     bbox.top = FXFT_Get_Face_yMin(m_Face);
281     bbox.right = FXFT_Get_Face_xMax(m_Face);
282   } else {
283     bbox.left = FXFT_Get_Face_xMin(m_Face) * 1000 / em;
284     bbox.top = FXFT_Get_Face_yMin(m_Face) * 1000 / em;
285     bbox.right = FXFT_Get_Face_xMax(m_Face) * 1000 / em;
286     bbox.bottom = FXFT_Get_Face_yMax(m_Face) * 1000 / em;
287   }
288   return TRUE;
289 }
290
291 int CFX_Font::GetHeight() const {
292   if (!m_Face)
293     return 0;
294
295   return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
296                    FXFT_Get_Face_Height(m_Face));
297 }
298
299 int CFX_Font::GetMaxAdvanceWidth() const {
300   if (!m_Face)
301     return 0;
302
303   return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
304                    FXFT_Get_Face_MaxAdvanceWidth(m_Face));
305 }
306
307 int CFX_Font::GetULPos() const {
308   if (!m_Face)
309     return 0;
310
311   return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
312                    FXFT_Get_Face_UnderLinePosition(m_Face));
313 }
314
315 int CFX_Font::GetULthickness() const {
316   if (!m_Face)
317     return 0;
318
319   return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
320                    FXFT_Get_Face_UnderLineThickness(m_Face));
321 }
322
323 CFX_UnicodeEncoding::CFX_UnicodeEncoding(CFX_Font* pFont) : m_pFont(pFont) {
324 }
325
326 CFX_UnicodeEncoding::~CFX_UnicodeEncoding() {
327 }
328
329 FX_DWORD CFX_UnicodeEncoding::GlyphFromCharCode(FX_DWORD charcode) {
330   FXFT_Face face = m_pFont->GetFace();
331   if (!face)
332     return charcode;
333
334   if (FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE) == 0)
335     return FXFT_Get_Char_Index(face, charcode);
336
337   if (m_pFont->GetSubstFont() && m_pFont->GetSubstFont()->m_Charset == 2) {
338     FX_DWORD index = 0;
339     if (FXFT_Select_Charmap(face, FXFT_ENCODING_MS_SYMBOL) == 0)
340       index = FXFT_Get_Char_Index(face, charcode);
341     if (!index && !FXFT_Select_Charmap(face, FXFT_ENCODING_APPLE_ROMAN))
342       return FXFT_Get_Char_Index(face, charcode);
343   }
344   return charcode;
345 }