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