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 "xfa/src/fgas/src/fgas_base.h"
8 #include "fx_gefont.h"
9 #include "fx_fontutils.h"
10 #ifndef _FXPLUS
LoadFont(const FX_WCHAR * pszFontFamily,FX_DWORD dwFontStyles,FX_WORD wCodePage,IFX_FontMgr * pFontMgr)11 IFX_Font* IFX_Font::LoadFont(const FX_WCHAR* pszFontFamily,
12 FX_DWORD dwFontStyles,
13 FX_WORD wCodePage,
14 IFX_FontMgr* pFontMgr) {
15 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
16 if (NULL != pFontMgr) {
17 return pFontMgr->GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily);
18 }
19 return NULL;
20 #else
21 CFX_GEFont* pFont = new CFX_GEFont(pFontMgr);
22 if (!pFont->LoadFont(pszFontFamily, dwFontStyles, wCodePage)) {
23 pFont->Release();
24 return NULL;
25 }
26 return pFont;
27 #endif
28 }
LoadFont(const uint8_t * pBuffer,int32_t iLength,IFX_FontMgr * pFontMgr)29 IFX_Font* IFX_Font::LoadFont(const uint8_t* pBuffer,
30 int32_t iLength,
31 IFX_FontMgr* pFontMgr) {
32 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
33 if (NULL != pFontMgr) {
34 return pFontMgr->LoadFont(pBuffer, iLength, 0, NULL);
35 }
36 return NULL;
37 #else
38 CFX_GEFont* pFont = new CFX_GEFont(pFontMgr);
39 if (!pFont->LoadFont(pBuffer, iLength)) {
40 pFont->Release();
41 return NULL;
42 }
43 return pFont;
44 #endif
45 }
LoadFont(const FX_WCHAR * pszFileName,IFX_FontMgr * pFontMgr)46 IFX_Font* IFX_Font::LoadFont(const FX_WCHAR* pszFileName,
47 IFX_FontMgr* pFontMgr) {
48 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
49 if (NULL != pFontMgr) {
50 return pFontMgr->LoadFont(pszFileName, 0, NULL);
51 }
52 return NULL;
53 #else
54 CFX_GEFont* pFont = new CFX_GEFont(pFontMgr);
55 if (!pFont->LoadFont(pszFileName)) {
56 pFont->Release();
57 return NULL;
58 }
59 return pFont;
60 #endif
61 }
LoadFont(IFX_Stream * pFontStream,IFX_FontMgr * pFontMgr,FX_BOOL bSaveStream)62 IFX_Font* IFX_Font::LoadFont(IFX_Stream* pFontStream,
63 IFX_FontMgr* pFontMgr,
64 FX_BOOL bSaveStream) {
65 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
66 if (NULL != pFontMgr) {
67 return pFontMgr->LoadFont(pFontStream, 0, NULL);
68 }
69 return NULL;
70 #else
71 CFX_GEFont* pFont = new CFX_GEFont(pFontMgr);
72 if (!pFont->LoadFont(pFontStream, bSaveStream)) {
73 pFont->Release();
74 return NULL;
75 }
76 return pFont;
77 #endif
78 }
LoadFont(CFX_Font * pExtFont,IFX_FontMgr * pFontMgr,FX_BOOL bTakeOver)79 IFX_Font* IFX_Font::LoadFont(CFX_Font* pExtFont,
80 IFX_FontMgr* pFontMgr,
81 FX_BOOL bTakeOver) {
82 CFX_GEFont* pFont = new CFX_GEFont(pFontMgr);
83 if (!pFont->LoadFont(pExtFont, bTakeOver)) {
84 pFont->Release();
85 return NULL;
86 }
87 return pFont;
88 }
CFX_GEFont(IFX_FontMgr * pFontMgr)89 CFX_GEFont::CFX_GEFont(IFX_FontMgr* pFontMgr)
90 : CFX_ThreadLock(),
91 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
92 m_bUseLogFontStyle(FALSE),
93 m_dwLogFontStyle(0),
94 #endif
95 m_pFont(NULL),
96 m_pFontMgr(pFontMgr),
97 m_iRefCount(1),
98 m_bExtFont(FALSE),
99 m_pStream(NULL),
100 m_pFileRead(NULL),
101 m_pFontEncoding(NULL),
102 m_pCharWidthMap(NULL),
103 m_pRectArray(NULL),
104 m_pBBoxMap(NULL),
105 m_pProvider(NULL),
106 m_wCharSet(0xFFFF),
107 m_SubstFonts(),
108 m_FontMapper(16) {
109 }
110
CFX_GEFont(const CFX_GEFont & src,FX_DWORD dwFontStyles)111 CFX_GEFont::CFX_GEFont(const CFX_GEFont& src, FX_DWORD dwFontStyles)
112 : CFX_ThreadLock(),
113 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
114 m_bUseLogFontStyle(FALSE),
115 m_dwLogFontStyle(0),
116 #endif
117 m_pFont(NULL),
118 m_pFontMgr(src.m_pFontMgr),
119 m_iRefCount(1),
120 m_bExtFont(FALSE),
121 m_pStream(NULL),
122 m_pFileRead(NULL),
123 m_pFontEncoding(NULL),
124 m_pCharWidthMap(NULL),
125 m_pRectArray(NULL),
126 m_pBBoxMap(NULL),
127 m_pProvider(NULL),
128 m_wCharSet(0xFFFF),
129 m_SubstFonts(),
130 m_FontMapper(16) {
131 m_pFont = new CFX_Font;
132 FXSYS_assert(m_pFont != NULL);
133 FXSYS_assert(src.m_pFont != NULL);
134 m_pFont->LoadClone(src.m_pFont);
135 CFX_SubstFont* pSubst = m_pFont->GetSubstFont();
136 if (!pSubst) {
137 pSubst = new CFX_SubstFont;
138 m_pFont->SetSubstFont(pSubst);
139 }
140 pSubst->m_Weight =
141 (dwFontStyles & FX_FONTSTYLE_Bold) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL;
142 if (dwFontStyles & FX_FONTSTYLE_Italic) {
143 pSubst->m_SubstFlags |= FXFONT_SUBST_ITALIC;
144 }
145 InitFont();
146 }
~CFX_GEFont()147 CFX_GEFont::~CFX_GEFont() {
148 int32_t iCount = m_SubstFonts.GetSize();
149 for (int32_t i = 0; i < iCount; i++) {
150 IFX_Font* pFont = (IFX_Font*)m_SubstFonts[i];
151 pFont->Release();
152 }
153 m_SubstFonts.RemoveAll();
154 m_FontMapper.RemoveAll();
155 if (m_pFileRead != NULL) {
156 m_pFileRead->Release();
157 }
158 if (m_pStream != NULL) {
159 m_pStream->Release();
160 }
161 if (m_pFontEncoding != NULL) {
162 delete m_pFontEncoding;
163 }
164 if (m_pCharWidthMap != NULL) {
165 delete m_pCharWidthMap;
166 }
167 if (m_pRectArray != NULL) {
168 delete m_pRectArray;
169 }
170 if (m_pBBoxMap != NULL) {
171 delete m_pBBoxMap;
172 }
173 if (m_pFont != NULL && !m_bExtFont) {
174 delete m_pFont;
175 }
176 }
Release()177 void CFX_GEFont::Release() {
178 if (--m_iRefCount < 1) {
179 if (m_pFontMgr != NULL) {
180 m_pFontMgr->RemoveFont(this);
181 }
182 delete this;
183 }
184 }
Retain()185 IFX_Font* CFX_GEFont::Retain() {
186 ++m_iRefCount;
187 return this;
188 }
LoadFont(const FX_WCHAR * pszFontFamily,FX_DWORD dwFontStyles,FX_WORD wCodePage)189 FX_BOOL CFX_GEFont::LoadFont(const FX_WCHAR* pszFontFamily,
190 FX_DWORD dwFontStyles,
191 FX_WORD wCodePage) {
192 if (m_pFont) {
193 return FALSE;
194 }
195 Lock();
196 CFX_ByteString csFontFamily;
197 if (pszFontFamily != NULL) {
198 csFontFamily = CFX_ByteString::FromUnicode(pszFontFamily);
199 }
200 FX_DWORD dwFlags = 0;
201 if (dwFontStyles & FX_FONTSTYLE_FixedPitch) {
202 dwFlags |= FXFONT_FIXED_PITCH;
203 }
204 if (dwFontStyles & FX_FONTSTYLE_Serif) {
205 dwFlags |= FXFONT_SERIF;
206 }
207 if (dwFontStyles & FX_FONTSTYLE_Symbolic) {
208 dwFlags |= FXFONT_SYMBOLIC;
209 }
210 if (dwFontStyles & FX_FONTSTYLE_Script) {
211 dwFlags |= FXFONT_SCRIPT;
212 }
213 if (dwFontStyles & FX_FONTSTYLE_Italic) {
214 dwFlags |= FXFONT_ITALIC;
215 }
216 if (dwFontStyles & FX_FONTSTYLE_Bold) {
217 dwFlags |= FXFONT_BOLD;
218 }
219 if (dwFontStyles & FX_FONTSTYLE_ExactMatch) {
220 dwFlags |= FXFONT_EXACTMATCH;
221 }
222 int32_t iWeight =
223 (dwFontStyles & FX_FONTSTYLE_Bold) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL;
224 FX_WORD wCharSet = FX_GetCharsetFromCodePage(wCodePage);
225 if (wCharSet == 0xFFFF) {
226 wCharSet = FXSYS_GetACP();
227 }
228 m_wCharSet = wCharSet;
229 m_pFont = new CFX_Font;
230 if ((dwFlags & FXFONT_ITALIC) && (dwFlags & FXFONT_BOLD)) {
231 csFontFamily += ",BoldItalic";
232 } else if (dwFlags & FXFONT_BOLD) {
233 csFontFamily += ",Bold";
234 } else if (dwFlags & FXFONT_ITALIC) {
235 csFontFamily += ",Italic";
236 }
237 m_pFont->LoadSubst(csFontFamily, TRUE, dwFlags, iWeight, 0, wCodePage);
238 FX_BOOL bRet = m_pFont->GetFace() != nullptr;
239 if (bRet) {
240 bRet = InitFont();
241 }
242 Unlock();
243 return bRet;
244 }
LoadFont(const uint8_t * pBuffer,int32_t length)245 FX_BOOL CFX_GEFont::LoadFont(const uint8_t* pBuffer, int32_t length) {
246 if (m_pFont) {
247 return FALSE;
248 }
249 Lock();
250 m_pFont = new CFX_Font;
251 FX_BOOL bRet = m_pFont->LoadEmbedded(pBuffer, length);
252 if (bRet) {
253 bRet = InitFont();
254 }
255 m_wCharSet = 0xFFFF;
256 Unlock();
257 return bRet;
258 }
LoadFont(const FX_WCHAR * pszFileName)259 FX_BOOL CFX_GEFont::LoadFont(const FX_WCHAR* pszFileName) {
260 if (m_pFont || m_pStream || m_pFileRead) {
261 return FALSE;
262 }
263 Lock();
264 m_pStream = IFX_Stream::CreateStream(
265 pszFileName, FX_STREAMACCESS_Binary | FX_STREAMACCESS_Read);
266 m_pFileRead = FX_CreateFileRead(m_pStream);
267 FX_BOOL bRet = FALSE;
268 if (m_pStream && m_pFileRead) {
269 m_pFont = new CFX_Font;
270 bRet = m_pFont->LoadFile(m_pFileRead);
271 if (bRet) {
272 bRet = InitFont();
273 } else {
274 m_pFileRead->Release();
275 m_pFileRead = nullptr;
276 }
277 }
278 m_wCharSet = 0xFFFF;
279 Unlock();
280 return bRet;
281 }
LoadFont(IFX_Stream * pFontStream,FX_BOOL bSaveStream)282 FX_BOOL CFX_GEFont::LoadFont(IFX_Stream* pFontStream, FX_BOOL bSaveStream) {
283 if (m_pFont || m_pFileRead || !pFontStream || pFontStream->GetLength() < 1) {
284 return FALSE;
285 }
286 Lock();
287 if (bSaveStream) {
288 m_pStream = pFontStream;
289 }
290 m_pFileRead = FX_CreateFileRead(pFontStream);
291 m_pFont = new CFX_Font;
292 FX_BOOL bRet = m_pFont->LoadFile(m_pFileRead);
293 if (bRet) {
294 bRet = InitFont();
295 } else {
296 m_pFileRead->Release();
297 m_pFileRead = nullptr;
298 }
299 m_wCharSet = 0xFFFF;
300 Unlock();
301 return bRet;
302 }
LoadFont(CFX_Font * pExtFont,FX_BOOL bTakeOver)303 FX_BOOL CFX_GEFont::LoadFont(CFX_Font* pExtFont, FX_BOOL bTakeOver) {
304 if (m_pFont || !pExtFont) {
305 return FALSE;
306 }
307 Lock();
308 m_pFont = pExtFont;
309 FX_BOOL bRet = !!m_pFont;
310 if (bRet) {
311 m_bExtFont = !bTakeOver;
312 bRet = InitFont();
313 } else {
314 m_bExtFont = TRUE;
315 }
316 m_wCharSet = 0xFFFF;
317 Unlock();
318 return bRet;
319 }
InitFont()320 FX_BOOL CFX_GEFont::InitFont() {
321 if (!m_pFont) {
322 return FALSE;
323 }
324 if (!m_pFontEncoding) {
325 m_pFontEncoding = FX_CreateFontEncodingEx(m_pFont);
326 if (!m_pFontEncoding) {
327 return FALSE;
328 }
329 }
330 if (!m_pCharWidthMap) {
331 m_pCharWidthMap = new CFX_WordDiscreteArray(1024);
332 }
333 if (!m_pRectArray) {
334 m_pRectArray = new CFX_RectMassArray(16);
335 }
336 if (!m_pBBoxMap) {
337 m_pBBoxMap = new CFX_MapPtrToPtr(16);
338 }
339 return TRUE;
340 }
Derive(FX_DWORD dwFontStyles,FX_WORD wCodePage)341 IFX_Font* CFX_GEFont::Derive(FX_DWORD dwFontStyles, FX_WORD wCodePage) {
342 if (GetFontStyles() == dwFontStyles) {
343 return Retain();
344 }
345 return new CFX_GEFont(*this, dwFontStyles);
346 }
GetCharSet() const347 uint8_t CFX_GEFont::GetCharSet() const {
348 if (m_wCharSet != 0xFFFF) {
349 return (uint8_t)m_wCharSet;
350 }
351 if (!m_pFont->GetSubstFont()) {
352 return FX_CHARSET_Default;
353 }
354 return m_pFont->GetSubstFont()->m_Charset;
355 }
GetFamilyName(CFX_WideString & wsFamily) const356 void CFX_GEFont::GetFamilyName(CFX_WideString& wsFamily) const {
357 if (!m_pFont->GetSubstFont() ||
358 m_pFont->GetSubstFont()->m_Family.GetLength() == 0) {
359 wsFamily = CFX_WideString::FromLocal(m_pFont->GetFamilyName());
360 } else {
361 wsFamily = CFX_WideString::FromLocal(m_pFont->GetSubstFont()->m_Family);
362 }
363 }
GetPsName(CFX_WideString & wsName) const364 void CFX_GEFont::GetPsName(CFX_WideString& wsName) const {
365 wsName = m_pFont->GetPsName();
366 }
GetFontStyles() const367 FX_DWORD CFX_GEFont::GetFontStyles() const {
368 FXSYS_assert(m_pFont != NULL);
369 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
370 if (m_bUseLogFontStyle) {
371 return m_dwLogFontStyle;
372 }
373 #endif
374 FX_DWORD dwStyles = 0;
375 if (!m_pFont->GetSubstFont()) {
376 if (m_pFont->IsBold()) {
377 dwStyles |= FX_FONTSTYLE_Bold;
378 }
379 if (m_pFont->IsItalic()) {
380 dwStyles |= FX_FONTSTYLE_Italic;
381 }
382 } else {
383 if (m_pFont->GetSubstFont()->m_Weight == FXFONT_FW_BOLD) {
384 dwStyles |= FX_FONTSTYLE_Bold;
385 }
386 if (m_pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_ITALIC) {
387 dwStyles |= FX_FONTSTYLE_Italic;
388 }
389 }
390 return dwStyles;
391 }
GetCharWidth(FX_WCHAR wUnicode,int32_t & iWidth,FX_BOOL bCharCode)392 FX_BOOL CFX_GEFont::GetCharWidth(FX_WCHAR wUnicode,
393 int32_t& iWidth,
394 FX_BOOL bCharCode) {
395 return GetCharWidth(wUnicode, iWidth, TRUE, bCharCode);
396 }
GetCharWidth(FX_WCHAR wUnicode,int32_t & iWidth,FX_BOOL bRecursive,FX_BOOL bCharCode)397 FX_BOOL CFX_GEFont::GetCharWidth(FX_WCHAR wUnicode,
398 int32_t& iWidth,
399 FX_BOOL bRecursive,
400 FX_BOOL bCharCode) {
401 FXSYS_assert(m_pCharWidthMap != NULL);
402 iWidth = m_pCharWidthMap->GetAt(wUnicode, 0);
403 if (iWidth < 1) {
404 if (!m_pProvider ||
405 !m_pProvider->GetCharWidth(this, wUnicode, iWidth, bCharCode)) {
406 IFX_Font* pFont = NULL;
407 int32_t iGlyph = GetGlyphIndex(wUnicode, TRUE, &pFont, bCharCode);
408 if (iGlyph != 0xFFFF && pFont != NULL) {
409 if (pFont == (IFX_Font*)this) {
410 iWidth = m_pFont->GetGlyphWidth(iGlyph);
411 if (iWidth < 0) {
412 iWidth = -1;
413 }
414 } else if (((CFX_GEFont*)pFont)
415 ->GetCharWidth(wUnicode, iWidth, FALSE, bCharCode)) {
416 return TRUE;
417 }
418 } else {
419 iWidth = -1;
420 }
421 }
422 Lock();
423 m_pCharWidthMap->SetAtGrow(wUnicode, (int16_t)iWidth);
424 Unlock();
425 } else if (iWidth == 65535) {
426 iWidth = -1;
427 }
428 return iWidth > 0;
429 }
GetCharBBox(FX_WCHAR wUnicode,CFX_Rect & bbox,FX_BOOL bCharCode)430 FX_BOOL CFX_GEFont::GetCharBBox(FX_WCHAR wUnicode,
431 CFX_Rect& bbox,
432 FX_BOOL bCharCode) {
433 return GetCharBBox(wUnicode, bbox, TRUE, bCharCode);
434 }
GetCharBBox(FX_WCHAR wUnicode,CFX_Rect & bbox,FX_BOOL bRecursive,FX_BOOL bCharCode)435 FX_BOOL CFX_GEFont::GetCharBBox(FX_WCHAR wUnicode,
436 CFX_Rect& bbox,
437 FX_BOOL bRecursive,
438 FX_BOOL bCharCode) {
439 FXSYS_assert(m_pRectArray != NULL);
440 FXSYS_assert(m_pBBoxMap != NULL);
441 void* pRect = NULL;
442 if (!m_pBBoxMap->Lookup((void*)(uintptr_t)wUnicode, pRect)) {
443 IFX_Font* pFont = NULL;
444 int32_t iGlyph = GetGlyphIndex(wUnicode, TRUE, &pFont, bCharCode);
445 if (iGlyph != 0xFFFF && pFont != NULL) {
446 if (pFont == (IFX_Font*)this) {
447 FX_RECT rtBBox;
448 if (m_pFont->GetGlyphBBox(iGlyph, rtBBox)) {
449 Lock();
450 CFX_Rect rt;
451 rt.Set(rtBBox.left, rtBBox.top, rtBBox.Width(), rtBBox.Height());
452 int32_t index = m_pRectArray->Add(rt);
453 pRect = m_pRectArray->GetPtrAt(index);
454 m_pBBoxMap->SetAt((void*)(uintptr_t)wUnicode, pRect);
455 Unlock();
456 }
457 } else if (((CFX_GEFont*)pFont)
458 ->GetCharBBox(wUnicode, bbox, FALSE, bCharCode)) {
459 return TRUE;
460 }
461 }
462 }
463 if (pRect == NULL) {
464 return FALSE;
465 }
466 bbox = *(FX_LPCRECT)pRect;
467 return TRUE;
468 }
GetBBox(CFX_Rect & bbox)469 FX_BOOL CFX_GEFont::GetBBox(CFX_Rect& bbox) {
470 FX_RECT rt(0, 0, 0, 0);
471 FX_BOOL bRet = m_pFont->GetBBox(rt);
472 if (bRet) {
473 bbox.left = rt.left;
474 bbox.width = rt.Width();
475 bbox.top = rt.bottom;
476 bbox.height = -rt.Height();
477 }
478 return bRet;
479 }
GetItalicAngle() const480 int32_t CFX_GEFont::GetItalicAngle() const {
481 if (!m_pFont->GetSubstFont()) {
482 return 0;
483 }
484 return m_pFont->GetSubstFont()->m_ItalicAngle;
485 }
GetGlyphIndex(FX_WCHAR wUnicode,FX_BOOL bCharCode)486 int32_t CFX_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode) {
487 return GetGlyphIndex(wUnicode, TRUE, NULL, bCharCode);
488 }
GetGlyphIndex(FX_WCHAR wUnicode,FX_BOOL bRecursive,IFX_Font ** ppFont,FX_BOOL bCharCode)489 int32_t CFX_GEFont::GetGlyphIndex(FX_WCHAR wUnicode,
490 FX_BOOL bRecursive,
491 IFX_Font** ppFont,
492 FX_BOOL bCharCode) {
493 FXSYS_assert(m_pFontEncoding != NULL);
494 int32_t iGlyphIndex = m_pFontEncoding->GlyphFromCharCode(wUnicode);
495 if (iGlyphIndex > 0) {
496 if (ppFont != NULL) {
497 *ppFont = (IFX_Font*)this;
498 }
499 return iGlyphIndex;
500 }
501 FGAS_LPCFONTUSB pFontUSB = FGAS_GetUnicodeBitField(wUnicode);
502 if (pFontUSB == NULL) {
503 return 0xFFFF;
504 }
505 FX_WORD wBitField = pFontUSB->wBitField;
506 if (wBitField >= 128) {
507 return 0xFFFF;
508 }
509 IFX_Font* pFont = NULL;
510 m_FontMapper.Lookup((void*)(uintptr_t)wUnicode, (void*&)pFont);
511 if (pFont != NULL && pFont != (IFX_Font*)this) {
512 iGlyphIndex =
513 ((CFX_GEFont*)pFont)->GetGlyphIndex(wUnicode, FALSE, NULL, bCharCode);
514 if (iGlyphIndex != 0xFFFF) {
515 int32_t i = m_SubstFonts.Find(pFont);
516 if (i > -1) {
517 iGlyphIndex |= ((i + 1) << 24);
518 if (ppFont != NULL) {
519 *ppFont = pFont;
520 }
521 return iGlyphIndex;
522 }
523 }
524 }
525 if (m_pFontMgr != NULL && bRecursive) {
526 CFX_WideString wsFamily;
527 GetFamilyName(wsFamily);
528 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
529 IFX_Font* pFont = m_pFontMgr->GetDefFontByUnicode(
530 wUnicode, GetFontStyles(), (const FX_WCHAR*)wsFamily);
531 #else
532 IFX_Font* pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(),
533 (const FX_WCHAR*)wsFamily);
534 if (NULL == pFont) {
535 pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), NULL);
536 }
537 #endif
538 if (pFont != NULL) {
539 if (pFont == (IFX_Font*)this) {
540 pFont->Release();
541 return 0xFFFF;
542 }
543 m_FontMapper.SetAt((void*)(uintptr_t)wUnicode, (void*)pFont);
544 int32_t i = m_SubstFonts.GetSize();
545 m_SubstFonts.Add(pFont);
546 iGlyphIndex =
547 ((CFX_GEFont*)pFont)->GetGlyphIndex(wUnicode, FALSE, NULL, bCharCode);
548 if (iGlyphIndex != 0xFFFF) {
549 iGlyphIndex |= ((i + 1) << 24);
550 if (ppFont != NULL) {
551 *ppFont = pFont;
552 }
553 return iGlyphIndex;
554 }
555 }
556 }
557 return 0xFFFF;
558 }
GetAscent() const559 int32_t CFX_GEFont::GetAscent() const {
560 return m_pFont->GetAscent();
561 }
GetDescent() const562 int32_t CFX_GEFont::GetDescent() const {
563 return m_pFont->GetDescent();
564 }
Reset()565 void CFX_GEFont::Reset() {
566 Lock();
567 int32_t iCount = m_SubstFonts.GetSize();
568 for (int32_t i = 0; i < iCount; i++) {
569 IFX_Font* pFont = (IFX_Font*)m_SubstFonts[i];
570 ((CFX_GEFont*)pFont)->Reset();
571 }
572 if (m_pCharWidthMap != NULL) {
573 m_pCharWidthMap->RemoveAll();
574 }
575 if (m_pBBoxMap != NULL) {
576 m_pBBoxMap->RemoveAll();
577 }
578 if (m_pRectArray != NULL) {
579 m_pRectArray->RemoveAll();
580 }
581 Unlock();
582 }
GetSubstFont(int32_t iGlyphIndex) const583 IFX_Font* CFX_GEFont::GetSubstFont(int32_t iGlyphIndex) const {
584 iGlyphIndex = ((FX_DWORD)iGlyphIndex) >> 24;
585 return iGlyphIndex == 0 ? (IFX_Font*)this
586 : (IFX_Font*)m_SubstFonts[iGlyphIndex - 1];
587 }
588 #endif
589