| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "../../../include/fxge/fx_ge.h" | 9 #include "../../../include/fxge/fx_ge.h" |
| 10 #include "../../../include/fxge/fx_freetype.h" | 10 #include "../../../include/fxge/fx_freetype.h" |
| 11 #include "text_int.h" | 11 #include "text_int.h" |
| 12 #define GET_TT_SHORT(w) (FX_WORD)(((w)[0] << 8) | (w)[1]) | 12 #define GET_TT_SHORT(w) (FX_WORD)(((w)[0] << 8) | (w)[1]) |
| 13 #define GET_TT_LONG(w) (FX_DWORD)(((w)[0] << 24) | ((w)[1] << 16) | ((w)[2] << 8
) | (w)[3]) | 13 #define GET_TT_LONG(w) \ |
| 14 CFX_SubstFont::CFX_SubstFont() | 14 (FX_DWORD)(((w)[0] << 24) | ((w)[1] << 16) | ((w)[2] << 8) | (w)[3]) |
| 15 { | 15 CFX_SubstFont::CFX_SubstFont() { |
| 16 m_ExtHandle = NULL; | 16 m_ExtHandle = NULL; |
| 17 m_Charset = 0; | 17 m_Charset = 0; |
| 18 m_SubstFlags = 0; | 18 m_SubstFlags = 0; |
| 19 m_Weight = 0; | 19 m_Weight = 0; |
| 20 m_ItalicAngle = 0; | 20 m_ItalicAngle = 0; |
| 21 m_bSubstOfCJK = FALSE; | 21 m_bSubstOfCJK = FALSE; |
| 22 m_WeightCJK = 0; | 22 m_WeightCJK = 0; |
| 23 m_bItlicCJK = FALSE; | 23 m_bItlicCJK = FALSE; |
| 24 } | 24 } |
| 25 CTTFontDesc::~CTTFontDesc() | 25 CTTFontDesc::~CTTFontDesc() { |
| 26 { | 26 if (m_Type == 1) { |
| 27 if (m_Type == 1) { | 27 if (m_SingleFace.m_pFace) { |
| 28 if (m_SingleFace.m_pFace) { | 28 FXFT_Done_Face(m_SingleFace.m_pFace); |
| 29 FXFT_Done_Face(m_SingleFace.m_pFace); | |
| 30 } | |
| 31 } else if (m_Type == 2) { | |
| 32 for (int i = 0; i < 16; i ++) | |
| 33 if (m_TTCFace.m_pFaces[i]) { | |
| 34 FXFT_Done_Face(m_TTCFace.m_pFaces[i]); | |
| 35 } | |
| 36 } | 29 } |
| 37 if (m_pFontData) { | 30 } else if (m_Type == 2) { |
| 38 FX_Free(m_pFontData); | 31 for (int i = 0; i < 16; i++) |
| 32 if (m_TTCFace.m_pFaces[i]) { |
| 33 FXFT_Done_Face(m_TTCFace.m_pFaces[i]); |
| 34 } |
| 35 } |
| 36 if (m_pFontData) { |
| 37 FX_Free(m_pFontData); |
| 38 } |
| 39 } |
| 40 FX_BOOL CTTFontDesc::ReleaseFace(FXFT_Face face) { |
| 41 if (m_Type == 1) { |
| 42 if (m_SingleFace.m_pFace != face) { |
| 43 return FALSE; |
| 39 } | 44 } |
| 45 } else if (m_Type == 2) { |
| 46 int i; |
| 47 for (i = 0; i < 16; i++) |
| 48 if (m_TTCFace.m_pFaces[i] == face) { |
| 49 break; |
| 50 } |
| 51 if (i == 16) { |
| 52 return FALSE; |
| 53 } |
| 54 } |
| 55 m_RefCount--; |
| 56 if (m_RefCount) { |
| 57 return FALSE; |
| 58 } |
| 59 delete this; |
| 60 return TRUE; |
| 40 } | 61 } |
| 41 FX_BOOL CTTFontDesc::ReleaseFace(FXFT_Face face) | 62 CFX_FontMgr::CFX_FontMgr() : m_FTLibrary(nullptr) { |
| 42 { | 63 m_pBuiltinMapper = new CFX_FontMapper(this); |
| 43 if (m_Type == 1) { | 64 FXSYS_memset(m_ExternalFonts, 0, sizeof m_ExternalFonts); |
| 44 if (m_SingleFace.m_pFace != face) { | |
| 45 return FALSE; | |
| 46 } | |
| 47 } else if (m_Type == 2) { | |
| 48 int i; | |
| 49 for (i = 0; i < 16; i ++) | |
| 50 if (m_TTCFace.m_pFaces[i] == face) { | |
| 51 break; | |
| 52 } | |
| 53 if (i == 16) { | |
| 54 return FALSE; | |
| 55 } | |
| 56 } | |
| 57 m_RefCount --; | |
| 58 if (m_RefCount) { | |
| 59 return FALSE; | |
| 60 } | |
| 61 delete this; | |
| 62 return TRUE; | |
| 63 } | 65 } |
| 64 CFX_FontMgr::CFX_FontMgr() : m_FTLibrary(nullptr) | 66 CFX_FontMgr::~CFX_FontMgr() { |
| 65 { | 67 delete m_pBuiltinMapper; |
| 66 m_pBuiltinMapper = new CFX_FontMapper(this); | 68 FreeCache(); |
| 67 FXSYS_memset(m_ExternalFonts, 0, sizeof m_ExternalFonts); | 69 if (m_FTLibrary) { |
| 70 FXFT_Done_FreeType(m_FTLibrary); |
| 71 } |
| 68 } | 72 } |
| 69 CFX_FontMgr::~CFX_FontMgr() | 73 void CFX_FontMgr::InitFTLibrary() { |
| 70 { | 74 if (m_FTLibrary == NULL) { |
| 71 delete m_pBuiltinMapper; | 75 FXFT_Init_FreeType(&m_FTLibrary); |
| 72 FreeCache(); | 76 } |
| 73 if (m_FTLibrary) { | |
| 74 FXFT_Done_FreeType(m_FTLibrary); | |
| 75 } | |
| 76 } | 77 } |
| 77 void CFX_FontMgr::InitFTLibrary() | 78 void CFX_FontMgr::FreeCache() { |
| 78 { | 79 FX_POSITION pos = m_FaceMap.GetStartPosition(); |
| 79 if (m_FTLibrary == NULL) { | 80 while (pos) { |
| 80 FXFT_Init_FreeType(&m_FTLibrary); | 81 CFX_ByteString Key; |
| 81 } | 82 CTTFontDesc* face; |
| 83 m_FaceMap.GetNextAssoc(pos, Key, (void*&)face); |
| 84 delete face; |
| 85 } |
| 86 m_FaceMap.RemoveAll(); |
| 82 } | 87 } |
| 83 void CFX_FontMgr::FreeCache() | 88 void CFX_FontMgr::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo) { |
| 84 { | 89 m_pBuiltinMapper->SetSystemFontInfo(pFontInfo); |
| 85 FX_POSITION pos = m_FaceMap.GetStartPosition(); | |
| 86 while(pos) { | |
| 87 CFX_ByteString Key; | |
| 88 CTTFontDesc* face; | |
| 89 m_FaceMap.GetNextAssoc(pos, Key, (void*&)face); | |
| 90 delete face; | |
| 91 } | |
| 92 m_FaceMap.RemoveAll(); | |
| 93 } | 90 } |
| 94 void CFX_FontMgr::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo) | 91 FXFT_Face CFX_FontMgr::FindSubstFont(const CFX_ByteString& face_name, |
| 95 { | 92 FX_BOOL bTrueType, |
| 96 m_pBuiltinMapper->SetSystemFontInfo(pFontInfo); | 93 FX_DWORD flags, |
| 97 } | 94 int weight, |
| 98 FXFT_Face CFX_FontMgr::FindSubstFont(const CFX_ByteString& face_name, FX_BOOL bT
rueType, | 95 int italic_angle, |
| 99 FX_DWORD flags, int weight, int italic_angl
e, int CharsetCP, CFX_SubstFont* pSubstFont) | 96 int CharsetCP, |
| 100 { | 97 CFX_SubstFont* pSubstFont) { |
| 101 if (!m_FTLibrary) { | 98 if (!m_FTLibrary) { |
| 102 FXFT_Init_FreeType(&m_FTLibrary); | 99 FXFT_Init_FreeType(&m_FTLibrary); |
| 103 } | 100 } |
| 104 return m_pBuiltinMapper->FindSubstFont(face_name, bTrueType, flags, weight,
italic_angle, CharsetCP, pSubstFont); | 101 return m_pBuiltinMapper->FindSubstFont(face_name, bTrueType, flags, weight, |
| 102 italic_angle, CharsetCP, pSubstFont); |
| 105 } | 103 } |
| 106 FXFT_Face CFX_FontMgr::GetCachedFace(const CFX_ByteString& face_name, | 104 FXFT_Face CFX_FontMgr::GetCachedFace(const CFX_ByteString& face_name, |
| 107 int weight, FX_BOOL bItalic, uint8_t*& pFon
tData) | 105 int weight, |
| 108 { | 106 FX_BOOL bItalic, |
| 109 CFX_ByteString key(face_name); | 107 uint8_t*& pFontData) { |
| 110 key += ','; | 108 CFX_ByteString key(face_name); |
| 111 key += CFX_ByteString::FormatInteger(weight); | 109 key += ','; |
| 112 key += bItalic ? 'I' : 'N'; | 110 key += CFX_ByteString::FormatInteger(weight); |
| 113 CTTFontDesc* pFontDesc = NULL; | 111 key += bItalic ? 'I' : 'N'; |
| 114 m_FaceMap.Lookup(key, (void*&)pFontDesc); | 112 CTTFontDesc* pFontDesc = NULL; |
| 115 if(pFontDesc) { | 113 m_FaceMap.Lookup(key, (void*&)pFontDesc); |
| 116 pFontData = pFontDesc->m_pFontData; | 114 if (pFontDesc) { |
| 117 pFontDesc->m_RefCount ++; | 115 pFontData = pFontDesc->m_pFontData; |
| 118 return pFontDesc->m_SingleFace.m_pFace; | 116 pFontDesc->m_RefCount++; |
| 119 } | 117 return pFontDesc->m_SingleFace.m_pFace; |
| 120 return NULL; | 118 } |
| 119 return NULL; |
| 121 } | 120 } |
| 122 FXFT_Face CFX_FontMgr::AddCachedFace(const CFX_ByteString& face_name, | 121 FXFT_Face CFX_FontMgr::AddCachedFace(const CFX_ByteString& face_name, |
| 123 int weight, FX_BOOL bItalic, uint8_t* pData
, FX_DWORD size, int face_index) | 122 int weight, |
| 124 { | 123 FX_BOOL bItalic, |
| 125 CTTFontDesc* pFontDesc = new CTTFontDesc; | 124 uint8_t* pData, |
| 126 pFontDesc->m_Type = 1; | 125 FX_DWORD size, |
| 127 pFontDesc->m_SingleFace.m_pFace = NULL; | 126 int face_index) { |
| 128 pFontDesc->m_SingleFace.m_bBold = weight; | 127 CTTFontDesc* pFontDesc = new CTTFontDesc; |
| 129 pFontDesc->m_SingleFace.m_bItalic = bItalic; | 128 pFontDesc->m_Type = 1; |
| 130 pFontDesc->m_pFontData = pData; | 129 pFontDesc->m_SingleFace.m_pFace = NULL; |
| 131 pFontDesc->m_RefCount = 1; | 130 pFontDesc->m_SingleFace.m_bBold = weight; |
| 132 FXFT_Library library; | 131 pFontDesc->m_SingleFace.m_bItalic = bItalic; |
| 133 if (m_FTLibrary == NULL) { | 132 pFontDesc->m_pFontData = pData; |
| 134 FXFT_Init_FreeType(&m_FTLibrary); | 133 pFontDesc->m_RefCount = 1; |
| 135 } | 134 FXFT_Library library; |
| 136 library = m_FTLibrary; | 135 if (m_FTLibrary == NULL) { |
| 137 int ret = FXFT_New_Memory_Face(library, pData, size, face_index, &pFontDesc-
>m_SingleFace.m_pFace); | 136 FXFT_Init_FreeType(&m_FTLibrary); |
| 138 if (ret) { | 137 } |
| 139 delete pFontDesc; | 138 library = m_FTLibrary; |
| 140 return NULL; | 139 int ret = FXFT_New_Memory_Face(library, pData, size, face_index, |
| 141 } | 140 &pFontDesc->m_SingleFace.m_pFace); |
| 142 ret = FXFT_Set_Pixel_Sizes(pFontDesc->m_SingleFace.m_pFace, 64, 64); | 141 if (ret) { |
| 143 if (ret) { | 142 delete pFontDesc; |
| 144 delete pFontDesc; | 143 return NULL; |
| 145 return NULL; | 144 } |
| 146 } | 145 ret = FXFT_Set_Pixel_Sizes(pFontDesc->m_SingleFace.m_pFace, 64, 64); |
| 147 CFX_ByteString key(face_name); | 146 if (ret) { |
| 148 key += ','; | 147 delete pFontDesc; |
| 149 key += CFX_ByteString::FormatInteger(weight); | 148 return NULL; |
| 150 key += bItalic ? 'I' : 'N'; | 149 } |
| 151 m_FaceMap.SetAt(key, pFontDesc); | 150 CFX_ByteString key(face_name); |
| 152 return pFontDesc->m_SingleFace.m_pFace; | 151 key += ','; |
| 152 key += CFX_ByteString::FormatInteger(weight); |
| 153 key += bItalic ? 'I' : 'N'; |
| 154 m_FaceMap.SetAt(key, pFontDesc); |
| 155 return pFontDesc->m_SingleFace.m_pFace; |
| 153 } | 156 } |
| 154 const FX_CHAR* const g_Base14FontNames[14] = { | 157 const FX_CHAR* const g_Base14FontNames[14] = { |
| 155 "Courier", | 158 "Courier", |
| 156 "Courier-Bold", | 159 "Courier-Bold", |
| 157 "Courier-BoldOblique", | 160 "Courier-BoldOblique", |
| 158 "Courier-Oblique", | 161 "Courier-Oblique", |
| 159 "Helvetica", | 162 "Helvetica", |
| 160 "Helvetica-Bold", | 163 "Helvetica-Bold", |
| 161 "Helvetica-BoldOblique", | 164 "Helvetica-BoldOblique", |
| 162 "Helvetica-Oblique", | 165 "Helvetica-Oblique", |
| 163 "Times-Roman", | 166 "Times-Roman", |
| 164 "Times-Bold", | 167 "Times-Bold", |
| 165 "Times-BoldItalic", | 168 "Times-BoldItalic", |
| 166 "Times-Italic", | 169 "Times-Italic", |
| 167 "Symbol", | 170 "Symbol", |
| 168 "ZapfDingbats", | 171 "ZapfDingbats", |
| 169 }; | 172 }; |
| 170 const struct _AltFontName { | 173 const struct _AltFontName { |
| 171 const FX_CHAR*» m_pName; | 174 const FX_CHAR* m_pName; |
| 172 int»» m_Index; | 175 int m_Index; |
| 173 } | 176 } g_AltFontNames[] = { |
| 174 g_AltFontNames[] = { | |
| 175 {"Arial", 4}, | 177 {"Arial", 4}, |
| 176 {"Arial,Bold", 5}, | 178 {"Arial,Bold", 5}, |
| 177 {"Arial,BoldItalic", 6}, | 179 {"Arial,BoldItalic", 6}, |
| 178 {"Arial,Italic", 7}, | 180 {"Arial,Italic", 7}, |
| 179 {"Arial-Bold", 5}, | 181 {"Arial-Bold", 5}, |
| 180 {"Arial-BoldItalic", 6}, | 182 {"Arial-BoldItalic", 6}, |
| 181 {"Arial-BoldItalicMT", 6}, | 183 {"Arial-BoldItalicMT", 6}, |
| 182 {"Arial-BoldMT", 5}, | 184 {"Arial-BoldMT", 5}, |
| 183 {"Arial-Italic", 7}, | 185 {"Arial-Italic", 7}, |
| 184 {"Arial-ItalicMT", 7}, | 186 {"Arial-ItalicMT", 7}, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 {"TimesNewRomanPS-BoldMT", 9}, | 258 {"TimesNewRomanPS-BoldMT", 9}, |
| 257 {"TimesNewRomanPS-Italic", 11}, | 259 {"TimesNewRomanPS-Italic", 11}, |
| 258 {"TimesNewRomanPS-ItalicMT", 11}, | 260 {"TimesNewRomanPS-ItalicMT", 11}, |
| 259 {"TimesNewRomanPSMT", 8}, | 261 {"TimesNewRomanPSMT", 8}, |
| 260 {"TimesNewRomanPSMT,Bold", 9}, | 262 {"TimesNewRomanPSMT,Bold", 9}, |
| 261 {"TimesNewRomanPSMT,BoldItalic", 10}, | 263 {"TimesNewRomanPSMT,BoldItalic", 10}, |
| 262 {"TimesNewRomanPSMT,Italic", 11}, | 264 {"TimesNewRomanPSMT,Italic", 11}, |
| 263 {"ZapfDingbats", 13}, | 265 {"ZapfDingbats", 13}, |
| 264 }; | 266 }; |
| 265 extern "C" { | 267 extern "C" { |
| 266 static int compareString(const void* key, const void* element) | 268 static int compareString(const void* key, const void* element) { |
| 267 { | 269 return FXSYS_stricmp((const FX_CHAR*)key, ((_AltFontName*)element)->m_pName); |
| 268 return FXSYS_stricmp((const FX_CHAR*)key, ((_AltFontName*)element)->m_pN
ame); | 270 } |
| 271 } |
| 272 int _PDF_GetStandardFontName(CFX_ByteString& name) { |
| 273 _AltFontName* found = |
| 274 (_AltFontName*)FXSYS_bsearch(name.c_str(), g_AltFontNames, |
| 275 sizeof g_AltFontNames / sizeof(_AltFontName), |
| 276 sizeof(_AltFontName), compareString); |
| 277 if (found == NULL) { |
| 278 return -1; |
| 279 } |
| 280 name = g_Base14FontNames[found->m_Index]; |
| 281 return found->m_Index; |
| 282 } |
| 283 int GetTTCIndex(const uint8_t* pFontData, |
| 284 FX_DWORD ttc_size, |
| 285 FX_DWORD font_offset) { |
| 286 int face_index = 0; |
| 287 const uint8_t* p = pFontData + 8; |
| 288 FX_DWORD nfont = GET_TT_LONG(p); |
| 289 FX_DWORD index; |
| 290 for (index = 0; index < nfont; index++) { |
| 291 p = pFontData + 12 + index * 4; |
| 292 if (GET_TT_LONG(p) == font_offset) { |
| 293 break; |
| 269 } | 294 } |
| 295 } |
| 296 if (index >= nfont) { |
| 297 face_index = 0; |
| 298 } else { |
| 299 face_index = index; |
| 300 } |
| 301 return face_index; |
| 270 } | 302 } |
| 271 int _PDF_GetStandardFontName(CFX_ByteString& name) | 303 FXFT_Face CFX_FontMgr::GetCachedTTCFace(int ttc_size, |
| 272 { | 304 FX_DWORD checksum, |
| 273 _AltFontName* found = (_AltFontName*)FXSYS_bsearch(name.c_str(), g_AltFontNa
mes, | 305 int font_offset, |
| 274 sizeof g_AltFontNames / sizeof (_AltFontName), sizeof
(_AltFontName), compareString); | 306 uint8_t*& pFontData) { |
| 275 if (found == NULL) { | 307 CFX_ByteString key; |
| 276 return -1; | 308 key.Format("%d:%d", ttc_size, checksum); |
| 309 CTTFontDesc* pFontDesc = NULL; |
| 310 m_FaceMap.Lookup(key, (void*&)pFontDesc); |
| 311 if (pFontDesc == NULL) { |
| 312 return NULL; |
| 313 } |
| 314 pFontData = pFontDesc->m_pFontData; |
| 315 pFontDesc->m_RefCount++; |
| 316 int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset); |
| 317 if (pFontDesc->m_TTCFace.m_pFaces[face_index] == NULL) { |
| 318 pFontDesc->m_TTCFace.m_pFaces[face_index] = |
| 319 GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index); |
| 320 } |
| 321 return pFontDesc->m_TTCFace.m_pFaces[face_index]; |
| 322 } |
| 323 FXFT_Face CFX_FontMgr::AddCachedTTCFace(int ttc_size, |
| 324 FX_DWORD checksum, |
| 325 uint8_t* pData, |
| 326 FX_DWORD size, |
| 327 int font_offset) { |
| 328 CFX_ByteString key; |
| 329 key.Format("%d:%d", ttc_size, checksum); |
| 330 CTTFontDesc* pFontDesc = new CTTFontDesc; |
| 331 pFontDesc->m_Type = 2; |
| 332 pFontDesc->m_pFontData = pData; |
| 333 for (int i = 0; i < 16; i++) { |
| 334 pFontDesc->m_TTCFace.m_pFaces[i] = NULL; |
| 335 } |
| 336 pFontDesc->m_RefCount++; |
| 337 key.Format("%d:%d", ttc_size, checksum); |
| 338 m_FaceMap.SetAt(key, pFontDesc); |
| 339 int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset); |
| 340 pFontDesc->m_TTCFace.m_pFaces[face_index] = |
| 341 GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index); |
| 342 return pFontDesc->m_TTCFace.m_pFaces[face_index]; |
| 343 } |
| 344 FXFT_Face CFX_FontMgr::GetFixedFace(const uint8_t* pData, |
| 345 FX_DWORD size, |
| 346 int face_index) { |
| 347 FXFT_Library library; |
| 348 if (m_FTLibrary == NULL) { |
| 349 FXFT_Init_FreeType(&m_FTLibrary); |
| 350 } |
| 351 library = m_FTLibrary; |
| 352 FXFT_Face face = NULL; |
| 353 int ret = FXFT_New_Memory_Face(library, pData, size, face_index, &face); |
| 354 if (ret) { |
| 355 return NULL; |
| 356 } |
| 357 ret = FXFT_Set_Pixel_Sizes(face, 64, 64); |
| 358 if (ret) { |
| 359 return NULL; |
| 360 } |
| 361 return face; |
| 362 } |
| 363 FXFT_Face CFX_FontMgr::GetFileFace(const FX_CHAR* filename, int face_index) { |
| 364 FXFT_Library library; |
| 365 if (m_FTLibrary == NULL) { |
| 366 FXFT_Init_FreeType(&m_FTLibrary); |
| 367 } |
| 368 library = m_FTLibrary; |
| 369 FXFT_Face face = NULL; |
| 370 int ret = FXFT_New_Face(library, filename, face_index, &face); |
| 371 if (ret) { |
| 372 return NULL; |
| 373 } |
| 374 ret = FXFT_Set_Pixel_Sizes(face, 64, 64); |
| 375 if (ret) { |
| 376 return NULL; |
| 377 } |
| 378 return face; |
| 379 } |
| 380 void CFX_FontMgr::ReleaseFace(FXFT_Face face) { |
| 381 if (face == NULL) { |
| 382 return; |
| 383 } |
| 384 FX_POSITION pos = m_FaceMap.GetStartPosition(); |
| 385 while (pos) { |
| 386 CFX_ByteString Key; |
| 387 CTTFontDesc* ttface; |
| 388 m_FaceMap.GetNextAssoc(pos, Key, (void*&)ttface); |
| 389 if (ttface->ReleaseFace(face)) { |
| 390 m_FaceMap.RemoveKey(Key); |
| 277 } | 391 } |
| 278 name = g_Base14FontNames[found->m_Index]; | 392 } |
| 279 return found->m_Index; | |
| 280 } | |
| 281 int GetTTCIndex(const uint8_t* pFontData, FX_DWORD ttc_size, FX_DWORD font_offse
t) | |
| 282 { | |
| 283 int face_index = 0; | |
| 284 const uint8_t* p = pFontData + 8; | |
| 285 FX_DWORD nfont = GET_TT_LONG(p); | |
| 286 FX_DWORD index; | |
| 287 for (index = 0; index < nfont; index ++) { | |
| 288 p = pFontData + 12 + index * 4; | |
| 289 if (GET_TT_LONG(p) == font_offset) { | |
| 290 break; | |
| 291 } | |
| 292 } | |
| 293 if(index >= nfont) { | |
| 294 face_index = 0; | |
| 295 } else { | |
| 296 face_index = index; | |
| 297 } | |
| 298 return face_index; | |
| 299 } | |
| 300 FXFT_Face CFX_FontMgr::GetCachedTTCFace(int ttc_size, FX_DWORD checksum, | |
| 301 int font_offset, uint8_t*& pFontData) | |
| 302 { | |
| 303 CFX_ByteString key; | |
| 304 key.Format("%d:%d", ttc_size, checksum); | |
| 305 CTTFontDesc* pFontDesc = NULL; | |
| 306 m_FaceMap.Lookup(key, (void*&)pFontDesc); | |
| 307 if (pFontDesc == NULL) { | |
| 308 return NULL; | |
| 309 } | |
| 310 pFontData = pFontDesc->m_pFontData; | |
| 311 pFontDesc->m_RefCount ++; | |
| 312 int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset); | |
| 313 if (pFontDesc->m_TTCFace.m_pFaces[face_index] == NULL) { | |
| 314 pFontDesc->m_TTCFace.m_pFaces[face_index] = GetFixedFace(pFontDesc->m_pF
ontData, ttc_size, face_index); | |
| 315 } | |
| 316 return pFontDesc->m_TTCFace.m_pFaces[face_index]; | |
| 317 } | |
| 318 FXFT_Face CFX_FontMgr::AddCachedTTCFace(int ttc_size, FX_DWORD checksum, | |
| 319 uint8_t* pData, FX_DWORD size, int font_
offset) | |
| 320 { | |
| 321 CFX_ByteString key; | |
| 322 key.Format("%d:%d", ttc_size, checksum); | |
| 323 CTTFontDesc* pFontDesc = new CTTFontDesc; | |
| 324 pFontDesc->m_Type = 2; | |
| 325 pFontDesc->m_pFontData = pData; | |
| 326 for (int i = 0; i < 16; i ++) { | |
| 327 pFontDesc->m_TTCFace.m_pFaces[i] = NULL; | |
| 328 } | |
| 329 pFontDesc->m_RefCount ++; | |
| 330 key.Format("%d:%d", ttc_size, checksum); | |
| 331 m_FaceMap.SetAt(key, pFontDesc); | |
| 332 int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset); | |
| 333 pFontDesc->m_TTCFace.m_pFaces[face_index] = GetFixedFace(pFontDesc->m_pFontD
ata, ttc_size, face_index); | |
| 334 return pFontDesc->m_TTCFace.m_pFaces[face_index]; | |
| 335 } | |
| 336 FXFT_Face CFX_FontMgr::GetFixedFace(const uint8_t* pData, FX_DWORD size, int fac
e_index) | |
| 337 { | |
| 338 FXFT_Library library; | |
| 339 if (m_FTLibrary == NULL) { | |
| 340 FXFT_Init_FreeType(&m_FTLibrary); | |
| 341 } | |
| 342 library = m_FTLibrary; | |
| 343 FXFT_Face face = NULL; | |
| 344 int ret = FXFT_New_Memory_Face(library, pData, size, face_index, &face); | |
| 345 if (ret) { | |
| 346 return NULL; | |
| 347 } | |
| 348 ret = FXFT_Set_Pixel_Sizes(face, 64, 64); | |
| 349 if (ret) { | |
| 350 return NULL; | |
| 351 } | |
| 352 return face; | |
| 353 } | |
| 354 FXFT_Face CFX_FontMgr::GetFileFace(const FX_CHAR* filename, int face_index) | |
| 355 { | |
| 356 FXFT_Library library; | |
| 357 if (m_FTLibrary == NULL) { | |
| 358 FXFT_Init_FreeType(&m_FTLibrary); | |
| 359 } | |
| 360 library = m_FTLibrary; | |
| 361 FXFT_Face face = NULL; | |
| 362 int ret = FXFT_New_Face(library, filename, face_index, &face); | |
| 363 if (ret) { | |
| 364 return NULL; | |
| 365 } | |
| 366 ret = FXFT_Set_Pixel_Sizes(face, 64, 64); | |
| 367 if (ret) { | |
| 368 return NULL; | |
| 369 } | |
| 370 return face; | |
| 371 } | |
| 372 void CFX_FontMgr::ReleaseFace(FXFT_Face face) | |
| 373 { | |
| 374 if (face == NULL) { | |
| 375 return; | |
| 376 } | |
| 377 FX_POSITION pos = m_FaceMap.GetStartPosition(); | |
| 378 while(pos) { | |
| 379 CFX_ByteString Key; | |
| 380 CTTFontDesc* ttface; | |
| 381 m_FaceMap.GetNextAssoc(pos, Key, (void*&)ttface); | |
| 382 if (ttface->ReleaseFace(face)) { | |
| 383 m_FaceMap.RemoveKey(Key); | |
| 384 } | |
| 385 } | |
| 386 } | 393 } |
| 387 extern "C" { | 394 extern "C" { |
| 388 extern const unsigned char g_FoxitFixedItalicFontData [18746]; | 395 extern const unsigned char g_FoxitFixedItalicFontData[18746]; |
| 389 extern const unsigned char g_FoxitFixedFontData [17597]; | 396 extern const unsigned char g_FoxitFixedFontData[17597]; |
| 390 extern const unsigned char g_FoxitSansItalicFontData [16339]; | 397 extern const unsigned char g_FoxitSansItalicFontData[16339]; |
| 391 extern const unsigned char g_FoxitSansFontData [15025]; | 398 extern const unsigned char g_FoxitSansFontData[15025]; |
| 392 extern const unsigned char g_FoxitSerifItalicFontData [21227]; | 399 extern const unsigned char g_FoxitSerifItalicFontData[21227]; |
| 393 extern const unsigned char g_FoxitSerifFontData [19469]; | 400 extern const unsigned char g_FoxitSerifFontData[19469]; |
| 394 extern const unsigned char g_FoxitFixedBoldItalicFontData [19151]; | 401 extern const unsigned char g_FoxitFixedBoldItalicFontData[19151]; |
| 395 extern const unsigned char g_FoxitFixedBoldFontData [18055]; | 402 extern const unsigned char g_FoxitFixedBoldFontData[18055]; |
| 396 extern const unsigned char g_FoxitSansBoldItalicFontData [16418]; | 403 extern const unsigned char g_FoxitSansBoldItalicFontData[16418]; |
| 397 extern const unsigned char g_FoxitSansBoldFontData [16344]; | 404 extern const unsigned char g_FoxitSansBoldFontData[16344]; |
| 398 extern const unsigned char g_FoxitSerifBoldItalicFontData [20733]; | 405 extern const unsigned char g_FoxitSerifBoldItalicFontData[20733]; |
| 399 extern const unsigned char g_FoxitSerifBoldFontData [19395]; | 406 extern const unsigned char g_FoxitSerifBoldFontData[19395]; |
| 400 extern const unsigned char g_FoxitSymbolFontData[16729]; | 407 extern const unsigned char g_FoxitSymbolFontData[16729]; |
| 401 extern const unsigned char g_FoxitDingbatsFontData[29513]; | 408 extern const unsigned char g_FoxitDingbatsFontData[29513]; |
| 402 extern const unsigned char g_FoxitSerifMMFontData[113417]; | 409 extern const unsigned char g_FoxitSerifMMFontData[113417]; |
| 403 extern const unsigned char g_FoxitSansMMFontData[66919]; | 410 extern const unsigned char g_FoxitSansMMFontData[66919]; |
| 404 }; | 411 }; |
| 405 const FoxitFonts g_FoxitFonts[14] = { | 412 const FoxitFonts g_FoxitFonts[14] = { |
| 406 {g_FoxitFixedFontData, 17597}, | 413 {g_FoxitFixedFontData, 17597}, |
| 407 {g_FoxitFixedBoldFontData, 18055}, | 414 {g_FoxitFixedBoldFontData, 18055}, |
| 408 {g_FoxitFixedBoldItalicFontData, 19151}, | 415 {g_FoxitFixedBoldItalicFontData, 19151}, |
| 409 {g_FoxitFixedItalicFontData, 18746}, | 416 {g_FoxitFixedItalicFontData, 18746}, |
| 410 {g_FoxitSansFontData, 15025}, | 417 {g_FoxitSansFontData, 15025}, |
| 411 {g_FoxitSansBoldFontData, 16344}, | 418 {g_FoxitSansBoldFontData, 16344}, |
| 412 {g_FoxitSansBoldItalicFontData, 16418}, | 419 {g_FoxitSansBoldItalicFontData, 16418}, |
| 413 {g_FoxitSansItalicFontData, 16339}, | 420 {g_FoxitSansItalicFontData, 16339}, |
| 414 {g_FoxitSerifFontData, 19469}, | 421 {g_FoxitSerifFontData, 19469}, |
| 415 {g_FoxitSerifBoldFontData, 19395}, | 422 {g_FoxitSerifBoldFontData, 19395}, |
| 416 {g_FoxitSerifBoldItalicFontData, 20733}, | 423 {g_FoxitSerifBoldItalicFontData, 20733}, |
| 417 {g_FoxitSerifItalicFontData, 21227}, | 424 {g_FoxitSerifItalicFontData, 21227}, |
| 418 {g_FoxitSymbolFontData, 16729}, | 425 {g_FoxitSymbolFontData, 16729}, |
| 419 {g_FoxitDingbatsFontData, 29513}, | 426 {g_FoxitDingbatsFontData, 29513}, |
| 420 }; | 427 }; |
| 421 void _FPDFAPI_GetInternalFontData(int id, const uint8_t*& data, FX_DWORD& size) | 428 void _FPDFAPI_GetInternalFontData(int id, |
| 422 { | 429 const uint8_t*& data, |
| 423 CFX_GEModule::Get()->GetFontMgr()->GetStandardFont(data, size, id); | 430 FX_DWORD& size) { |
| 424 } | 431 CFX_GEModule::Get()->GetFontMgr()->GetStandardFont(data, size, id); |
| 425 FX_BOOL CFX_FontMgr::GetStandardFont(const uint8_t*& pFontData, FX_DWORD& size,
int index) | 432 } |
| 426 { | 433 FX_BOOL CFX_FontMgr::GetStandardFont(const uint8_t*& pFontData, |
| 427 if (index > 15 || index < 0) { | 434 FX_DWORD& size, |
| 428 return FALSE; | 435 int index) { |
| 429 } | 436 if (index > 15 || index < 0) { |
| 430 { | 437 return FALSE; |
| 431 if (index >= 14) { | 438 } |
| 432 if (index == 14) { | 439 { |
| 433 pFontData = g_FoxitSerifMMFontData; | 440 if (index >= 14) { |
| 434 size = 113417; | 441 if (index == 14) { |
| 435 } else { | 442 pFontData = g_FoxitSerifMMFontData; |
| 436 pFontData = g_FoxitSansMMFontData; | 443 size = 113417; |
| 437 size = 66919; | 444 } else { |
| 438 } | 445 pFontData = g_FoxitSansMMFontData; |
| 439 } else { | 446 size = 66919; |
| 440 pFontData = g_FoxitFonts[index].m_pFontData; | 447 } |
| 441 size = g_FoxitFonts[index].m_dwSize; | 448 } else { |
| 442 } | 449 pFontData = g_FoxitFonts[index].m_pFontData; |
| 443 } | 450 size = g_FoxitFonts[index].m_dwSize; |
| 444 return TRUE; | 451 } |
| 452 } |
| 453 return TRUE; |
| 445 } | 454 } |
| 446 CFX_FontMapper::CFX_FontMapper(CFX_FontMgr* mgr) | 455 CFX_FontMapper::CFX_FontMapper(CFX_FontMgr* mgr) |
| 447 : m_pFontInfo(nullptr), | 456 : m_pFontInfo(nullptr), |
| 448 m_bListLoaded(FALSE), | 457 m_bListLoaded(FALSE), |
| 449 m_pFontEnumerator(nullptr), | 458 m_pFontEnumerator(nullptr), |
| 450 m_pFontMgr(mgr) | 459 m_pFontMgr(mgr) { |
| 451 { | 460 FXSYS_memset(m_FoxitFaces, 0, sizeof m_FoxitFaces); |
| 452 FXSYS_memset(m_FoxitFaces, 0, sizeof m_FoxitFaces); | 461 m_MMFaces[0] = m_MMFaces[1] = NULL; |
| 453 m_MMFaces[0] = m_MMFaces[1] = NULL; | 462 } |
| 454 } | 463 CFX_FontMapper::~CFX_FontMapper() { |
| 455 CFX_FontMapper::~CFX_FontMapper() | 464 for (int i = 0; i < 14; i++) |
| 456 { | 465 if (m_FoxitFaces[i]) { |
| 457 for (int i = 0; i < 14; i ++) | 466 FXFT_Done_Face(m_FoxitFaces[i]); |
| 458 if (m_FoxitFaces[i]) { | 467 } |
| 459 FXFT_Done_Face(m_FoxitFaces[i]); | 468 if (m_MMFaces[0]) { |
| 460 } | 469 FXFT_Done_Face(m_MMFaces[0]); |
| 461 if (m_MMFaces[0]) { | 470 } |
| 462 FXFT_Done_Face(m_MMFaces[0]); | 471 if (m_MMFaces[1]) { |
| 463 } | 472 FXFT_Done_Face(m_MMFaces[1]); |
| 464 if (m_MMFaces[1]) { | 473 } |
| 465 FXFT_Done_Face(m_MMFaces[1]); | 474 if (m_pFontInfo) { |
| 466 } | 475 m_pFontInfo->Release(); |
| 467 if (m_pFontInfo) { | 476 } |
| 468 m_pFontInfo->Release(); | 477 } |
| 469 } | 478 void CFX_FontMapper::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo) { |
| 470 } | 479 if (pFontInfo == NULL) { |
| 471 void CFX_FontMapper::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo) | 480 return; |
| 472 { | 481 } |
| 473 if (pFontInfo == NULL) { | 482 if (m_pFontInfo) { |
| 483 m_pFontInfo->Release(); |
| 484 } |
| 485 m_pFontInfo = pFontInfo; |
| 486 } |
| 487 static CFX_ByteString _TT_NormalizeName(const FX_CHAR* family) { |
| 488 CFX_ByteString norm(family, -1); |
| 489 norm.Remove(' '); |
| 490 norm.Remove('-'); |
| 491 norm.Remove(','); |
| 492 int pos = norm.Find('+'); |
| 493 if (pos > 0) { |
| 494 norm = norm.Left(pos); |
| 495 } |
| 496 norm.MakeLower(); |
| 497 return norm; |
| 498 } |
| 499 CFX_ByteString _FPDF_GetNameFromTT(const uint8_t* name_table, |
| 500 FX_DWORD name_id) { |
| 501 const uint8_t* ptr = name_table + 2; |
| 502 int name_count = GET_TT_SHORT(ptr); |
| 503 int string_offset = GET_TT_SHORT(ptr + 2); |
| 504 const uint8_t* string_ptr = name_table + string_offset; |
| 505 ptr += 4; |
| 506 for (int i = 0; i < name_count; i++) { |
| 507 if (GET_TT_SHORT(ptr + 6) == name_id && GET_TT_SHORT(ptr) == 1 && |
| 508 GET_TT_SHORT(ptr + 2) == 0) { |
| 509 return CFX_ByteStringC(string_ptr + GET_TT_SHORT(ptr + 10), |
| 510 GET_TT_SHORT(ptr + 8)); |
| 511 } |
| 512 ptr += 12; |
| 513 } |
| 514 return CFX_ByteString(); |
| 515 } |
| 516 static CFX_ByteString _FPDF_ReadStringFromFile(FXSYS_FILE* pFile, |
| 517 FX_DWORD size) { |
| 518 CFX_ByteString buffer; |
| 519 if (!FXSYS_fread(buffer.GetBuffer(size), size, 1, pFile)) { |
| 520 return CFX_ByteString(); |
| 521 } |
| 522 buffer.ReleaseBuffer(size); |
| 523 return buffer; |
| 524 } |
| 525 CFX_ByteString _FPDF_LoadTableFromTT(FXSYS_FILE* pFile, |
| 526 const uint8_t* pTables, |
| 527 FX_DWORD nTables, |
| 528 FX_DWORD tag) { |
| 529 for (FX_DWORD i = 0; i < nTables; i++) { |
| 530 const uint8_t* p = pTables + i * 16; |
| 531 if (GET_TT_LONG(p) == tag) { |
| 532 FX_DWORD offset = GET_TT_LONG(p + 8); |
| 533 FX_DWORD size = GET_TT_LONG(p + 12); |
| 534 FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); |
| 535 return _FPDF_ReadStringFromFile(pFile, size); |
| 536 } |
| 537 } |
| 538 return CFX_ByteString(); |
| 539 } |
| 540 CFX_ByteString _FPDF_LoadTableFromTTStreamFile(IFX_FileStream* pFile, |
| 541 const uint8_t* pTables, |
| 542 FX_DWORD nTables, |
| 543 FX_DWORD tag) { |
| 544 for (FX_DWORD i = 0; i < nTables; i++) { |
| 545 const uint8_t* p = pTables + i * 16; |
| 546 if (GET_TT_LONG(p) == tag) { |
| 547 FX_DWORD offset = GET_TT_LONG(p + 8); |
| 548 FX_DWORD size = GET_TT_LONG(p + 12); |
| 549 CFX_ByteString buffer; |
| 550 if (!pFile->ReadBlock(buffer.GetBuffer(size), offset, size)) { |
| 551 return CFX_ByteString(); |
| 552 } |
| 553 buffer.ReleaseBuffer(size); |
| 554 return buffer; |
| 555 } |
| 556 } |
| 557 return CFX_ByteString(); |
| 558 } |
| 559 CFX_ByteString CFX_FontMapper::GetPSNameFromTT(void* hFont) { |
| 560 if (m_pFontInfo == NULL) { |
| 561 CFX_ByteString(); |
| 562 } |
| 563 CFX_ByteString result; |
| 564 FX_DWORD size = m_pFontInfo->GetFontData(hFont, 0x6e616d65, NULL, 0); |
| 565 if (size) { |
| 566 uint8_t* buffer = FX_Alloc(uint8_t, size); |
| 567 m_pFontInfo->GetFontData(hFont, 0x6e616d65, buffer, size); |
| 568 result = _FPDF_GetNameFromTT(buffer, 6); |
| 569 FX_Free(buffer); |
| 570 } |
| 571 return result; |
| 572 } |
| 573 void CFX_FontMapper::AddInstalledFont(const CFX_ByteString& name, int charset) { |
| 574 if (m_pFontInfo == NULL) { |
| 575 return; |
| 576 } |
| 577 if (m_CharsetArray.Find((FX_DWORD)charset) == -1) { |
| 578 m_CharsetArray.Add((FX_DWORD)charset); |
| 579 m_FaceArray.Add(name); |
| 580 } |
| 581 if (name == m_LastFamily) { |
| 582 return; |
| 583 } |
| 584 const uint8_t* ptr = name; |
| 585 FX_BOOL bLocalized = FALSE; |
| 586 for (int i = 0; i < name.GetLength(); i++) |
| 587 if (ptr[i] > 0x80) { |
| 588 bLocalized = TRUE; |
| 589 break; |
| 590 } |
| 591 if (bLocalized) { |
| 592 void* hFont = m_pFontInfo->GetFont(name); |
| 593 if (hFont == NULL) { |
| 594 int iExact; |
| 595 hFont = |
| 596 m_pFontInfo->MapFont(0, 0, FXFONT_DEFAULT_CHARSET, 0, name, iExact); |
| 597 if (hFont == NULL) { |
| 474 return; | 598 return; |
| 475 } | 599 } |
| 476 if (m_pFontInfo) { | 600 } |
| 477 m_pFontInfo->Release(); | 601 CFX_ByteString new_name = GetPSNameFromTT(hFont); |
| 478 } | 602 if (!new_name.IsEmpty()) { |
| 479 m_pFontInfo = pFontInfo; | 603 new_name.Insert(0, ' '); |
| 480 } | 604 m_InstalledTTFonts.Add(new_name); |
| 481 static CFX_ByteString _TT_NormalizeName(const FX_CHAR* family) | 605 } |
| 482 { | 606 m_pFontInfo->DeleteFont(hFont); |
| 483 CFX_ByteString norm(family, -1); | 607 } |
| 484 norm.Remove(' '); | 608 m_InstalledTTFonts.Add(name); |
| 485 norm.Remove('-'); | 609 m_LastFamily = name; |
| 486 norm.Remove(','); | 610 } |
| 487 int pos = norm.Find('+'); | 611 void CFX_FontMapper::LoadInstalledFonts() { |
| 488 if (pos > 0) { | 612 if (m_pFontInfo == NULL) { |
| 489 norm = norm.Left(pos); | 613 return; |
| 490 } | 614 } |
| 491 norm.MakeLower(); | 615 if (m_bListLoaded) { |
| 492 return norm; | 616 return; |
| 493 } | 617 } |
| 494 CFX_ByteString _FPDF_GetNameFromTT(const uint8_t* name_table, FX_DWORD name_id) | 618 if (m_bListLoaded) { |
| 495 { | 619 return; |
| 496 const uint8_t* ptr = name_table + 2; | 620 } |
| 497 int name_count = GET_TT_SHORT(ptr); | 621 m_pFontInfo->EnumFontList(this); |
| 498 int string_offset = GET_TT_SHORT(ptr + 2); | 622 m_bListLoaded = TRUE; |
| 499 const uint8_t* string_ptr = name_table + string_offset; | 623 } |
| 500 ptr += 4; | 624 CFX_ByteString CFX_FontMapper::MatchInstalledFonts( |
| 501 for (int i = 0; i < name_count; i ++) { | 625 const CFX_ByteString& norm_name) { |
| 502 if (GET_TT_SHORT(ptr + 6) == name_id && GET_TT_SHORT(ptr) == 1 && GET_TT
_SHORT(ptr + 2) == 0) { | 626 LoadInstalledFonts(); |
| 503 return CFX_ByteStringC(string_ptr + GET_TT_SHORT(ptr + 10), GET_TT_S
HORT(ptr + 8)); | 627 int i; |
| 504 } | 628 for (i = m_InstalledTTFonts.GetSize() - 1; i >= 0; i--) { |
| 505 ptr += 12; | 629 CFX_ByteString norm1 = _TT_NormalizeName(m_InstalledTTFonts[i]); |
| 506 } | 630 if (norm1 == norm_name) { |
| 631 break; |
| 632 } |
| 633 } |
| 634 if (i < 0) { |
| 507 return CFX_ByteString(); | 635 return CFX_ByteString(); |
| 508 } | 636 } |
| 509 static CFX_ByteString _FPDF_ReadStringFromFile(FXSYS_FILE* pFile, FX_DWORD size) | 637 CFX_ByteString match = m_InstalledTTFonts[i]; |
| 510 { | 638 if (match[0] == ' ') { |
| 511 CFX_ByteString buffer; | 639 match = m_InstalledTTFonts[i + 1]; |
| 512 if (!FXSYS_fread(buffer.GetBuffer(size), size, 1, pFile)) { | 640 } |
| 513 return CFX_ByteString(); | 641 return match; |
| 514 } | |
| 515 buffer.ReleaseBuffer(size); | |
| 516 return buffer; | |
| 517 } | |
| 518 CFX_ByteString _FPDF_LoadTableFromTT(FXSYS_FILE* pFile, const uint8_t* pTables,
FX_DWORD nTables, FX_DWORD tag) | |
| 519 { | |
| 520 for (FX_DWORD i = 0; i < nTables; i ++) { | |
| 521 const uint8_t* p = pTables + i * 16; | |
| 522 if (GET_TT_LONG(p) == tag) { | |
| 523 FX_DWORD offset = GET_TT_LONG(p + 8); | |
| 524 FX_DWORD size = GET_TT_LONG(p + 12); | |
| 525 FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); | |
| 526 return _FPDF_ReadStringFromFile(pFile, size); | |
| 527 } | |
| 528 } | |
| 529 return CFX_ByteString(); | |
| 530 } | |
| 531 CFX_ByteString _FPDF_LoadTableFromTTStreamFile(IFX_FileStream* pFile, const uint
8_t* pTables, FX_DWORD nTables, FX_DWORD tag) | |
| 532 { | |
| 533 for (FX_DWORD i = 0; i < nTables; i ++) { | |
| 534 const uint8_t* p = pTables + i * 16; | |
| 535 if (GET_TT_LONG(p) == tag) { | |
| 536 FX_DWORD offset = GET_TT_LONG(p + 8); | |
| 537 FX_DWORD size = GET_TT_LONG(p + 12); | |
| 538 CFX_ByteString buffer; | |
| 539 if (!pFile->ReadBlock(buffer.GetBuffer(size), offset, size)) { | |
| 540 return CFX_ByteString(); | |
| 541 } | |
| 542 buffer.ReleaseBuffer(size); | |
| 543 return buffer; | |
| 544 } | |
| 545 } | |
| 546 return CFX_ByteString(); | |
| 547 } | |
| 548 CFX_ByteString CFX_FontMapper::GetPSNameFromTT(void* hFont) | |
| 549 { | |
| 550 if (m_pFontInfo == NULL) { | |
| 551 CFX_ByteString(); | |
| 552 } | |
| 553 CFX_ByteString result; | |
| 554 FX_DWORD size = m_pFontInfo->GetFontData(hFont, 0x6e616d65, NULL, 0); | |
| 555 if (size) { | |
| 556 uint8_t* buffer = FX_Alloc(uint8_t, size); | |
| 557 m_pFontInfo->GetFontData(hFont, 0x6e616d65, buffer, size); | |
| 558 result = _FPDF_GetNameFromTT(buffer, 6); | |
| 559 FX_Free(buffer); | |
| 560 } | |
| 561 return result; | |
| 562 } | |
| 563 void CFX_FontMapper::AddInstalledFont(const CFX_ByteString& name, int charset) | |
| 564 { | |
| 565 if (m_pFontInfo == NULL) { | |
| 566 return; | |
| 567 } | |
| 568 if (m_CharsetArray.Find((FX_DWORD)charset) == -1) { | |
| 569 m_CharsetArray.Add((FX_DWORD)charset); | |
| 570 m_FaceArray.Add(name); | |
| 571 } | |
| 572 if (name == m_LastFamily) { | |
| 573 return; | |
| 574 } | |
| 575 const uint8_t* ptr = name; | |
| 576 FX_BOOL bLocalized = FALSE; | |
| 577 for (int i = 0; i < name.GetLength(); i ++) | |
| 578 if (ptr[i] > 0x80) { | |
| 579 bLocalized = TRUE; | |
| 580 break; | |
| 581 } | |
| 582 if (bLocalized) { | |
| 583 void* hFont = m_pFontInfo->GetFont(name); | |
| 584 if (hFont == NULL) { | |
| 585 int iExact; | |
| 586 hFont = m_pFontInfo->MapFont(0, 0, FXFONT_DEFAULT_CHARSET, 0, name,
iExact); | |
| 587 if (hFont == NULL) { | |
| 588 return; | |
| 589 } | |
| 590 } | |
| 591 CFX_ByteString new_name = GetPSNameFromTT(hFont); | |
| 592 if (!new_name.IsEmpty()) { | |
| 593 new_name.Insert(0, ' '); | |
| 594 m_InstalledTTFonts.Add(new_name); | |
| 595 } | |
| 596 m_pFontInfo->DeleteFont(hFont); | |
| 597 } | |
| 598 m_InstalledTTFonts.Add(name); | |
| 599 m_LastFamily = name; | |
| 600 } | |
| 601 void CFX_FontMapper::LoadInstalledFonts() | |
| 602 { | |
| 603 if (m_pFontInfo == NULL) { | |
| 604 return; | |
| 605 } | |
| 606 if (m_bListLoaded) { | |
| 607 return; | |
| 608 } | |
| 609 if (m_bListLoaded) { | |
| 610 return; | |
| 611 } | |
| 612 m_pFontInfo->EnumFontList(this); | |
| 613 m_bListLoaded = TRUE; | |
| 614 } | |
| 615 CFX_ByteString CFX_FontMapper::MatchInstalledFonts(const CFX_ByteString& norm_na
me) | |
| 616 { | |
| 617 LoadInstalledFonts(); | |
| 618 int i; | |
| 619 for (i = m_InstalledTTFonts.GetSize() - 1; i >= 0; i --) { | |
| 620 CFX_ByteString norm1 = _TT_NormalizeName(m_InstalledTTFonts[i]); | |
| 621 if (norm1 == norm_name) { | |
| 622 break; | |
| 623 } | |
| 624 } | |
| 625 if (i < 0) { | |
| 626 return CFX_ByteString(); | |
| 627 } | |
| 628 CFX_ByteString match = m_InstalledTTFonts[i]; | |
| 629 if (match[0] == ' ') { | |
| 630 match = m_InstalledTTFonts[i + 1]; | |
| 631 } | |
| 632 return match; | |
| 633 } | 642 } |
| 634 typedef struct _CHARSET_MAP_ { | 643 typedef struct _CHARSET_MAP_ { |
| 635 uint8_t charset; | 644 uint8_t charset; |
| 636 FX_WORD codepage; | 645 FX_WORD codepage; |
| 637 } CHARSET_MAP; | 646 } CHARSET_MAP; |
| 638 static const CHARSET_MAP g_Codepage2CharsetTable[] = { | 647 static const CHARSET_MAP g_Codepage2CharsetTable[] = { |
| 639 { 1» , 0» }, | 648 {1, 0}, {2, 42}, {254, 437}, {255, 850}, {222, 874}, |
| 640 { 2» , 42» }, | 649 {128, 932}, {134, 936}, {129, 949}, {136, 950}, {238, 1250}, |
| 641 { 254, 437» }, | 650 {204, 1251}, {0, 1252}, {161, 1253}, {162, 1254}, {177, 1255}, |
| 642 { 255, 850» }, | 651 {178, 1256}, {186, 1257}, {163, 1258}, {130, 1361}, {77, 10000}, |
| 643 { 222, 874» }, | 652 {78, 10001}, {79, 10003}, {80, 10008}, {81, 10002}, {83, 10005}, |
| 644 { 128, 932» }, | 653 {84, 10004}, {85, 10006}, {86, 10081}, {87, 10021}, {88, 10029}, |
| 645 { 134, 936» }, | 654 {89, 10007}, |
| 646 { 129, 949» }, | |
| 647 { 136, 950» }, | |
| 648 { 238, 1250»}, | |
| 649 { 204, 1251»}, | |
| 650 { 0, 1252»}, | |
| 651 { 161, 1253»}, | |
| 652 { 162, 1254»}, | |
| 653 { 177, 1255»}, | |
| 654 { 178, 1256»}, | |
| 655 { 186, 1257»}, | |
| 656 { 163, 1258 }, | |
| 657 { 130, 1361 }, | |
| 658 { 77, 10000 }, | |
| 659 { 78, 10001 }, | |
| 660 { 79, 10003 }, | |
| 661 { 80, 10008 }, | |
| 662 { 81, 10002 }, | |
| 663 { 83, 10005 }, | |
| 664 { 84, 10004 }, | |
| 665 { 85, 10006 }, | |
| 666 { 86, 10081 }, | |
| 667 { 87, 10021 }, | |
| 668 { 88, 10029 }, | |
| 669 { 89, 10007 }, | |
| 670 }; | 655 }; |
| 671 uint8_t _GetCharsetFromCodePage(FX_WORD codepage) | 656 uint8_t _GetCharsetFromCodePage(FX_WORD codepage) { |
| 672 { | 657 int32_t iEnd = sizeof(g_Codepage2CharsetTable) / sizeof(CHARSET_MAP) - 1; |
| 673 int32_t iEnd = sizeof(g_Codepage2CharsetTable) / sizeof(CHARSET_MAP) - 1; | 658 FXSYS_assert(iEnd >= 0); |
| 674 FXSYS_assert(iEnd >= 0); | 659 int32_t iStart = 0, iMid; |
| 675 int32_t iStart = 0, iMid; | 660 do { |
| 676 do { | 661 iMid = (iStart + iEnd) / 2; |
| 677 iMid = (iStart + iEnd) / 2; | 662 const CHARSET_MAP& cp = g_Codepage2CharsetTable[iMid]; |
| 678 const CHARSET_MAP & cp = g_Codepage2CharsetTable[iMid]; | 663 if (codepage == cp.codepage) { |
| 679 if (codepage == cp.codepage) { | 664 return cp.charset; |
| 680 return cp.charset; | 665 } |
| 681 } | 666 if (codepage < cp.codepage) { |
| 682 if (codepage < cp.codepage) { | 667 iEnd = iMid - 1; |
| 683 iEnd = iMid - 1; | 668 } else { |
| 684 } else { | 669 iStart = iMid + 1; |
| 685 iStart = iMid + 1; | 670 } |
| 686 } | 671 } while (iStart <= iEnd); |
| 687 } while (iStart <= iEnd); | 672 return 1; |
| 688 return 1; | 673 } |
| 689 } | 674 FX_DWORD _GetCodePageRangeFromCharset(int charset) { |
| 690 FX_DWORD _GetCodePageRangeFromCharset(int charset) | 675 if (charset == FXFONT_EASTEUROPE_CHARSET) { |
| 691 { | 676 return 1 << 1; |
| 692 if (charset == FXFONT_EASTEUROPE_CHARSET) { | 677 } |
| 693 return 1 << 1; | 678 if (charset == FXFONT_GREEK_CHARSET) { |
| 694 } | 679 return 1 << 3; |
| 695 if (charset == FXFONT_GREEK_CHARSET) { | 680 } |
| 696 return 1 << 3; | 681 if (charset == FXFONT_TURKISH_CHARSET) { |
| 697 } | 682 return 1 << 4; |
| 698 if (charset == FXFONT_TURKISH_CHARSET) { | 683 } |
| 699 return 1 << 4; | 684 if (charset == FXFONT_HEBREW_CHARSET) { |
| 700 } | 685 return 1 << 5; |
| 701 if (charset == FXFONT_HEBREW_CHARSET) { | 686 } |
| 702 return 1 << 5; | 687 if (charset == FXFONT_ARABIC_CHARSET) { |
| 703 } | 688 return 1 << 6; |
| 704 if (charset == FXFONT_ARABIC_CHARSET) { | 689 } |
| 705 return 1 << 6; | 690 if (charset == FXFONT_BALTIC_CHARSET) { |
| 706 } | 691 return 1 << 7; |
| 707 if (charset == FXFONT_BALTIC_CHARSET) { | 692 } |
| 708 return 1 << 7; | 693 if (charset == FXFONT_THAI_CHARSET) { |
| 709 } | 694 return 1 << 16; |
| 710 if (charset == FXFONT_THAI_CHARSET) { | 695 } |
| 711 return 1 << 16; | 696 if (charset == FXFONT_SHIFTJIS_CHARSET) { |
| 712 } | 697 return 1 << 17; |
| 713 if (charset == FXFONT_SHIFTJIS_CHARSET) { | 698 } |
| 714 return 1 << 17; | 699 if (charset == FXFONT_GB2312_CHARSET) { |
| 715 } | 700 return 1 << 18; |
| 716 if (charset == FXFONT_GB2312_CHARSET) { | 701 } |
| 717 return 1 << 18; | 702 if (charset == FXFONT_CHINESEBIG5_CHARSET) { |
| 718 } | 703 return 1 << 20; |
| 719 if (charset == FXFONT_CHINESEBIG5_CHARSET) { | 704 } |
| 720 return 1 << 20; | 705 if (charset == FXFONT_HANGEUL_CHARSET) { |
| 721 } | 706 return 1 << 19; |
| 722 if (charset == FXFONT_HANGEUL_CHARSET) { | 707 } |
| 723 return 1 << 19; | 708 if (charset == FXFONT_SYMBOL_CHARSET) { |
| 724 } | 709 return 1 << 31; |
| 725 if (charset == FXFONT_SYMBOL_CHARSET) { | 710 } |
| 726 return 1 << 31; | 711 return 1 << 21; |
| 727 } | 712 } |
| 728 return 1 << 21; | 713 FXFT_Face CFX_FontMapper::UseInternalSubst(CFX_SubstFont* pSubstFont, |
| 729 } | 714 int iBaseFont, |
| 730 FXFT_Face CFX_FontMapper::UseInternalSubst(CFX_SubstFont* pSubstFont, int iBaseF
ont, int italic_angle, int weight, int picthfamily) | 715 int italic_angle, |
| 731 { | 716 int weight, |
| 732 if (iBaseFont < 12) { | 717 int picthfamily) { |
| 733 if (m_FoxitFaces[iBaseFont]) { | 718 if (iBaseFont < 12) { |
| 734 return m_FoxitFaces[iBaseFont]; | 719 if (m_FoxitFaces[iBaseFont]) { |
| 735 } | 720 return m_FoxitFaces[iBaseFont]; |
| 736 const uint8_t* pFontData = NULL; | |
| 737 FX_DWORD size = 0; | |
| 738 if (m_pFontMgr->GetStandardFont(pFontData, size, iBaseFont)) { | |
| 739 m_FoxitFaces[iBaseFont] = m_pFontMgr->GetFixedFace(pFontData, size,
0); | |
| 740 return m_FoxitFaces[iBaseFont]; | |
| 741 } | |
| 742 } | |
| 743 pSubstFont->m_SubstFlags |= FXFONT_SUBST_MM; | |
| 744 pSubstFont->m_ItalicAngle = italic_angle; | |
| 745 if (weight) { | |
| 746 pSubstFont->m_Weight = weight; | |
| 747 } | |
| 748 if (picthfamily & FXFONT_FF_ROMAN) { | |
| 749 pSubstFont->m_Weight = pSubstFont->m_Weight * 4 / 5; | |
| 750 pSubstFont->m_Family = "Chrome Serif"; | |
| 751 if (m_MMFaces[1]) { | |
| 752 return m_MMFaces[1]; | |
| 753 } | |
| 754 const uint8_t* pFontData = NULL; | |
| 755 FX_DWORD size; | |
| 756 m_pFontMgr->GetStandardFont(pFontData, size, 14); | |
| 757 m_MMFaces[1] = m_pFontMgr->GetFixedFace(pFontData, size, 0); | |
| 758 return m_MMFaces[1]; | |
| 759 } | |
| 760 pSubstFont->m_Family = "Chrome Sans"; | |
| 761 if (m_MMFaces[0]) { | |
| 762 return m_MMFaces[0]; | |
| 763 } | 721 } |
| 764 const uint8_t* pFontData = NULL; | 722 const uint8_t* pFontData = NULL; |
| 765 FX_DWORD size = 0; | 723 FX_DWORD size = 0; |
| 766 m_pFontMgr->GetStandardFont(pFontData, size, 15); | 724 if (m_pFontMgr->GetStandardFont(pFontData, size, iBaseFont)) { |
| 767 m_MMFaces[0] = m_pFontMgr->GetFixedFace(pFontData, size, 0); | 725 m_FoxitFaces[iBaseFont] = m_pFontMgr->GetFixedFace(pFontData, size, 0); |
| 726 return m_FoxitFaces[iBaseFont]; |
| 727 } |
| 728 } |
| 729 pSubstFont->m_SubstFlags |= FXFONT_SUBST_MM; |
| 730 pSubstFont->m_ItalicAngle = italic_angle; |
| 731 if (weight) { |
| 732 pSubstFont->m_Weight = weight; |
| 733 } |
| 734 if (picthfamily & FXFONT_FF_ROMAN) { |
| 735 pSubstFont->m_Weight = pSubstFont->m_Weight * 4 / 5; |
| 736 pSubstFont->m_Family = "Chrome Serif"; |
| 737 if (m_MMFaces[1]) { |
| 738 return m_MMFaces[1]; |
| 739 } |
| 740 const uint8_t* pFontData = NULL; |
| 741 FX_DWORD size; |
| 742 m_pFontMgr->GetStandardFont(pFontData, size, 14); |
| 743 m_MMFaces[1] = m_pFontMgr->GetFixedFace(pFontData, size, 0); |
| 744 return m_MMFaces[1]; |
| 745 } |
| 746 pSubstFont->m_Family = "Chrome Sans"; |
| 747 if (m_MMFaces[0]) { |
| 768 return m_MMFaces[0]; | 748 return m_MMFaces[0]; |
| 749 } |
| 750 const uint8_t* pFontData = NULL; |
| 751 FX_DWORD size = 0; |
| 752 m_pFontMgr->GetStandardFont(pFontData, size, 15); |
| 753 m_MMFaces[0] = m_pFontMgr->GetFixedFace(pFontData, size, 0); |
| 754 return m_MMFaces[0]; |
| 769 } | 755 } |
| 770 const struct _AltFontFamily { | 756 const struct _AltFontFamily { |
| 771 const FX_CHAR* m_pFontName; | 757 const FX_CHAR* m_pFontName; |
| 772 const FX_CHAR* m_pFontFamily; | 758 const FX_CHAR* m_pFontFamily; |
| 773 } | 759 } g_AltFontFamilies[] = { |
| 774 g_AltFontFamilies[] = { | |
| 775 {"AGaramondPro", "Adobe Garamond Pro"}, | 760 {"AGaramondPro", "Adobe Garamond Pro"}, |
| 776 {"BankGothicBT-Medium", "BankGothic Md BT"}, | 761 {"BankGothicBT-Medium", "BankGothic Md BT"}, |
| 777 {"ForteMT", "Forte"}, | 762 {"ForteMT", "Forte"}, |
| 778 }; | 763 }; |
| 779 extern "C" { | 764 extern "C" { |
| 780 static int compareFontFamilyString(const void* key, const void* element) | 765 static int compareFontFamilyString(const void* key, const void* element) { |
| 781 { | 766 CFX_ByteString str_key((const FX_CHAR*)key); |
| 782 CFX_ByteString str_key((const FX_CHAR*)key); | 767 if (str_key.Find(((_AltFontFamily*)element)->m_pFontName) != -1) { |
| 783 if (str_key.Find(((_AltFontFamily*)element)->m_pFontName) != -1) { | 768 return 0; |
| 784 return 0; | 769 } |
| 785 } | 770 return FXSYS_stricmp((const FX_CHAR*)key, |
| 786 return FXSYS_stricmp((const FX_CHAR*)key, ((_AltFontFamily*)element)->m_
pFontName); | 771 ((_AltFontFamily*)element)->m_pFontName); |
| 787 } | 772 } |
| 788 } | 773 } |
| 789 #define FX_FONT_STYLE_None» » 0x00 | 774 #define FX_FONT_STYLE_None 0x00 |
| 790 #define FX_FONT_STYLE_Bold» » 0x01 | 775 #define FX_FONT_STYLE_Bold 0x01 |
| 791 #define FX_FONT_STYLE_Italic» 0x02 | 776 #define FX_FONT_STYLE_Italic 0x02 |
| 792 #define FX_FONT_STYLE_BoldBold» 0x04 | 777 #define FX_FONT_STYLE_BoldBold 0x04 |
| 793 static CFX_ByteString _GetFontFamily(CFX_ByteString fontName, int nStyle) | 778 static CFX_ByteString _GetFontFamily(CFX_ByteString fontName, int nStyle) { |
| 794 { | 779 if (fontName.Find("Script") >= 0) { |
| 795 if (fontName.Find("Script") >= 0) { | 780 if ((nStyle & FX_FONT_STYLE_Bold) == FX_FONT_STYLE_Bold) { |
| 796 if ((nStyle & FX_FONT_STYLE_Bold) == FX_FONT_STYLE_Bold) { | 781 fontName = "ScriptMTBold"; |
| 797 fontName = "ScriptMTBold"; | 782 } else if (fontName.Find("Palace") >= 0) { |
| 798 } else if (fontName.Find("Palace") >= 0) { | 783 fontName = "PalaceScriptMT"; |
| 799 fontName = "PalaceScriptMT"; | 784 } else if (fontName.Find("French") >= 0) { |
| 800 } else if (fontName.Find("French") >= 0) { | 785 fontName = "FrenchScriptMT"; |
| 801 fontName = "FrenchScriptMT"; | 786 } else if (fontName.Find("FreeStyle") >= 0) { |
| 802 } else if (fontName.Find("FreeStyle") >= 0) { | 787 fontName = "FreeStyleScript"; |
| 803 fontName = "FreeStyleScript"; | 788 } |
| 804 } | 789 return fontName; |
| 805 return fontName; | 790 } |
| 806 } | 791 _AltFontFamily* found = (_AltFontFamily*)FXSYS_bsearch( |
| 807 _AltFontFamily* found = (_AltFontFamily*)FXSYS_bsearch(fontName.c_str(), g_A
ltFontFamilies, | 792 fontName.c_str(), g_AltFontFamilies, |
| 808 sizeof g_AltFontFamilies / sizeof (_AltFontFamily),
sizeof (_AltFontFamily), compareFontFamilyString); | 793 sizeof g_AltFontFamilies / sizeof(_AltFontFamily), sizeof(_AltFontFamily), |
| 809 if (found == NULL) { | 794 compareFontFamilyString); |
| 810 return fontName; | 795 if (found == NULL) { |
| 811 } | 796 return fontName; |
| 812 return found->m_pFontFamily; | 797 } |
| 798 return found->m_pFontFamily; |
| 813 }; | 799 }; |
| 814 typedef struct _FX_FontStyle { | 800 typedef struct _FX_FontStyle { |
| 815 const FX_CHAR* style; | 801 const FX_CHAR* style; |
| 816 int32_t len; | 802 int32_t len; |
| 817 } FX_FontStyle; | 803 } FX_FontStyle; |
| 818 const FX_FontStyle g_FontStyles[] = { | 804 const FX_FontStyle g_FontStyles[] = { |
| 819 { "Bold", 4 }, | 805 {"Bold", 4}, {"Italic", 6}, {"BoldItalic", 10}, {"Reg", 3}, {"Regular", 7}, |
| 820 { "Italic", 6 }, | |
| 821 { "BoldItalic", 10 }, | |
| 822 { "Reg", 3 }, | |
| 823 { "Regular", 7 }, | |
| 824 }; | 806 }; |
| 825 CFX_ByteString ParseStyle(const FX_CHAR* pStyle, int iLen, int iIndex) | 807 CFX_ByteString ParseStyle(const FX_CHAR* pStyle, int iLen, int iIndex) { |
| 826 { | 808 CFX_ByteTextBuf buf; |
| 827 CFX_ByteTextBuf buf; | 809 if (!iLen || iLen <= iIndex) { |
| 828 if (!iLen || iLen <= iIndex) { | |
| 829 return buf.GetByteString(); | |
| 830 } | |
| 831 while (iIndex < iLen) { | |
| 832 if (pStyle[iIndex] == ',') { | |
| 833 break; | |
| 834 } | |
| 835 buf.AppendChar(pStyle[iIndex]); | |
| 836 ++iIndex; | |
| 837 } | |
| 838 return buf.GetByteString(); | 810 return buf.GetByteString(); |
| 839 } | 811 } |
| 840 int32_t GetStyleType(const CFX_ByteString &bsStyle, FX_BOOL bRevert) | 812 while (iIndex < iLen) { |
| 841 { | 813 if (pStyle[iIndex] == ',') { |
| 842 int32_t iLen = bsStyle.GetLength(); | 814 break; |
| 843 if (!iLen) { | 815 } |
| 844 return -1; | 816 buf.AppendChar(pStyle[iIndex]); |
| 845 } | 817 ++iIndex; |
| 846 int iSize = sizeof(g_FontStyles) / sizeof(FX_FontStyle); | 818 } |
| 847 const FX_FontStyle *pStyle = NULL; | 819 return buf.GetByteString(); |
| 848 for (int i = iSize - 1; i >= 0; --i) { | 820 } |
| 849 pStyle = g_FontStyles + i; | 821 int32_t GetStyleType(const CFX_ByteString& bsStyle, FX_BOOL bRevert) { |
| 850 if (!pStyle || pStyle->len > iLen) { | 822 int32_t iLen = bsStyle.GetLength(); |
| 851 continue; | 823 if (!iLen) { |
| 852 } | 824 return -1; |
| 853 if (!bRevert) { | 825 } |
| 854 if (bsStyle.Left(pStyle->len).Compare(pStyle->style) == 0) { | 826 int iSize = sizeof(g_FontStyles) / sizeof(FX_FontStyle); |
| 855 return i; | 827 const FX_FontStyle* pStyle = NULL; |
| 856 } | 828 for (int i = iSize - 1; i >= 0; --i) { |
| 829 pStyle = g_FontStyles + i; |
| 830 if (!pStyle || pStyle->len > iLen) { |
| 831 continue; |
| 832 } |
| 833 if (!bRevert) { |
| 834 if (bsStyle.Left(pStyle->len).Compare(pStyle->style) == 0) { |
| 835 return i; |
| 836 } |
| 837 } else { |
| 838 if (bsStyle.Right(pStyle->len).Compare(pStyle->style) == 0) { |
| 839 return i; |
| 840 } |
| 841 } |
| 842 } |
| 843 return -1; |
| 844 } |
| 845 FX_BOOL CheckSupportThirdPartFont(CFX_ByteString name, int& PitchFamily) { |
| 846 if (name == FX_BSTRC("MyriadPro")) { |
| 847 PitchFamily &= ~FXFONT_FF_ROMAN; |
| 848 return TRUE; |
| 849 } |
| 850 return FALSE; |
| 851 } |
| 852 FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name, |
| 853 FX_BOOL bTrueType, |
| 854 FX_DWORD flags, |
| 855 int weight, |
| 856 int italic_angle, |
| 857 int WindowCP, |
| 858 CFX_SubstFont* pSubstFont) { |
| 859 if (!(flags & FXFONT_USEEXTERNATTR)) { |
| 860 weight = FXFONT_FW_NORMAL; |
| 861 italic_angle = 0; |
| 862 } |
| 863 CFX_ByteString SubstName = name; |
| 864 SubstName.Remove(0x20); |
| 865 if (bTrueType) { |
| 866 if (name[0] == '@') { |
| 867 SubstName = name.Mid(1); |
| 868 } |
| 869 } |
| 870 _PDF_GetStandardFontName(SubstName); |
| 871 if (SubstName == FX_BSTRC("Symbol") && !bTrueType) { |
| 872 pSubstFont->m_Family = "Chrome Symbol"; |
| 873 pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; |
| 874 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; |
| 875 if (m_FoxitFaces[12]) { |
| 876 return m_FoxitFaces[12]; |
| 877 } |
| 878 const uint8_t* pFontData = NULL; |
| 879 FX_DWORD size = 0; |
| 880 m_pFontMgr->GetStandardFont(pFontData, size, 12); |
| 881 m_FoxitFaces[12] = m_pFontMgr->GetFixedFace(pFontData, size, 0); |
| 882 return m_FoxitFaces[12]; |
| 883 } |
| 884 if (SubstName == FX_BSTRC("ZapfDingbats")) { |
| 885 pSubstFont->m_Family = "Chrome Dingbats"; |
| 886 pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; |
| 887 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; |
| 888 if (m_FoxitFaces[13]) { |
| 889 return m_FoxitFaces[13]; |
| 890 } |
| 891 const uint8_t* pFontData = NULL; |
| 892 FX_DWORD size = 0; |
| 893 m_pFontMgr->GetStandardFont(pFontData, size, 13); |
| 894 m_FoxitFaces[13] = m_pFontMgr->GetFixedFace(pFontData, size, 0); |
| 895 return m_FoxitFaces[13]; |
| 896 } |
| 897 int iBaseFont = 0; |
| 898 CFX_ByteString family, style; |
| 899 FX_BOOL bHasComma = FALSE; |
| 900 FX_BOOL bHasHypen = FALSE; |
| 901 int find = SubstName.Find(FX_BSTRC(","), 0); |
| 902 if (find >= 0) { |
| 903 family = SubstName.Left(find); |
| 904 _PDF_GetStandardFontName(family); |
| 905 style = SubstName.Mid(find + 1); |
| 906 bHasComma = TRUE; |
| 907 } else { |
| 908 family = SubstName; |
| 909 } |
| 910 for (; iBaseFont < 12; iBaseFont++) |
| 911 if (family == CFX_ByteStringC(g_Base14FontNames[iBaseFont])) { |
| 912 break; |
| 913 } |
| 914 int PitchFamily = 0; |
| 915 FX_BOOL bItalic = FALSE; |
| 916 FX_DWORD nStyle = 0; |
| 917 FX_BOOL bStyleAvail = FALSE; |
| 918 if (iBaseFont < 12) { |
| 919 family = g_Base14FontNames[iBaseFont]; |
| 920 if ((iBaseFont % 4) == 1 || (iBaseFont % 4) == 2) { |
| 921 nStyle |= FX_FONT_STYLE_Bold; |
| 922 } |
| 923 if ((iBaseFont % 4) / 2) { |
| 924 nStyle |= FX_FONT_STYLE_Italic; |
| 925 } |
| 926 if (iBaseFont < 4) { |
| 927 PitchFamily |= FXFONT_FF_FIXEDPITCH; |
| 928 } |
| 929 if (iBaseFont >= 8) { |
| 930 PitchFamily |= FXFONT_FF_ROMAN; |
| 931 } |
| 932 } else { |
| 933 if (!bHasComma) { |
| 934 find = family.ReverseFind('-'); |
| 935 if (find >= 0) { |
| 936 style = family.Mid(find + 1); |
| 937 family = family.Left(find); |
| 938 bHasHypen = TRUE; |
| 939 } |
| 940 } |
| 941 if (!bHasHypen) { |
| 942 int nLen = family.GetLength(); |
| 943 int32_t nRet = GetStyleType(family, TRUE); |
| 944 if (nRet > -1) { |
| 945 family = family.Left(nLen - g_FontStyles[nRet].len); |
| 946 if (nRet == 0) { |
| 947 nStyle |= FX_FONT_STYLE_Bold; |
| 948 } |
| 949 if (nRet == 1) { |
| 950 nStyle |= FX_FONT_STYLE_Italic; |
| 951 } |
| 952 if (nRet == 2) { |
| 953 nStyle |= (FX_FONT_STYLE_Bold | FX_FONT_STYLE_Italic); |
| 954 } |
| 955 } |
| 956 } |
| 957 if (flags & FXFONT_SERIF) { |
| 958 PitchFamily |= FXFONT_FF_ROMAN; |
| 959 } |
| 960 if (flags & FXFONT_SCRIPT) { |
| 961 PitchFamily |= FXFONT_FF_SCRIPT; |
| 962 } |
| 963 if (flags & FXFONT_FIXED_PITCH) { |
| 964 PitchFamily |= FXFONT_FF_FIXEDPITCH; |
| 965 } |
| 966 } |
| 967 if (!style.IsEmpty()) { |
| 968 int nLen = style.GetLength(); |
| 969 const FX_CHAR* pStyle = style; |
| 970 int i = 0; |
| 971 FX_BOOL bFirstItem = TRUE; |
| 972 CFX_ByteString buf; |
| 973 while (i < nLen) { |
| 974 buf = ParseStyle(pStyle, nLen, i); |
| 975 int32_t nRet = GetStyleType(buf, FALSE); |
| 976 if ((i && !bStyleAvail) || (!i && nRet < 0)) { |
| 977 family = SubstName; |
| 978 iBaseFont = 12; |
| 979 break; |
| 980 } else if (nRet >= 0) { |
| 981 bStyleAvail = TRUE; |
| 982 } |
| 983 if (nRet == 0) { |
| 984 if (nStyle & FX_FONT_STYLE_Bold) { |
| 985 nStyle |= FX_FONT_STYLE_BoldBold; |
| 857 } else { | 986 } else { |
| 858 if (bsStyle.Right(pStyle->len).Compare(pStyle->style) == 0) { | 987 nStyle |= FX_FONT_STYLE_Bold; |
| 859 return i; | 988 } |
| 860 } | 989 bFirstItem = FALSE; |
| 861 } | 990 } |
| 862 } | 991 if (nRet == 1) { |
| 863 return -1; | 992 if (bFirstItem) { |
| 864 } | 993 nStyle |= FX_FONT_STYLE_Italic; |
| 865 FX_BOOL CheckSupportThirdPartFont(CFX_ByteString name, int &PitchFamily) | 994 } else { |
| 866 { | 995 family = SubstName; |
| 867 if (name == FX_BSTRC("MyriadPro")) { | 996 iBaseFont = 12; |
| 868 PitchFamily &= ~FXFONT_FF_ROMAN; | 997 } |
| 869 return TRUE; | 998 break; |
| 870 } | 999 } |
| 1000 if (nRet == 2) { |
| 1001 nStyle |= FX_FONT_STYLE_Italic; |
| 1002 if (nStyle & FX_FONT_STYLE_Bold) { |
| 1003 nStyle |= FX_FONT_STYLE_BoldBold; |
| 1004 } else { |
| 1005 nStyle |= FX_FONT_STYLE_Bold; |
| 1006 } |
| 1007 bFirstItem = FALSE; |
| 1008 } |
| 1009 i += buf.GetLength() + 1; |
| 1010 } |
| 1011 } |
| 1012 weight = weight ? weight : FXFONT_FW_NORMAL; |
| 1013 int old_weight = weight; |
| 1014 if (nStyle) { |
| 1015 weight = |
| 1016 nStyle & FX_FONT_STYLE_BoldBold |
| 1017 ? 900 |
| 1018 : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL); |
| 1019 } |
| 1020 if (nStyle & FX_FONT_STYLE_Italic) { |
| 1021 bItalic = TRUE; |
| 1022 } |
| 1023 FX_BOOL bCJK = FALSE; |
| 1024 int iExact = 0; |
| 1025 int Charset = FXFONT_ANSI_CHARSET; |
| 1026 if (WindowCP) { |
| 1027 Charset = _GetCharsetFromCodePage(WindowCP); |
| 1028 } else if (iBaseFont == 12 && (flags & FXFONT_SYMBOLIC)) { |
| 1029 Charset = FXFONT_SYMBOL_CHARSET; |
| 1030 } |
| 1031 if (Charset == FXFONT_SHIFTJIS_CHARSET || Charset == FXFONT_GB2312_CHARSET || |
| 1032 Charset == FXFONT_HANGEUL_CHARSET || |
| 1033 Charset == FXFONT_CHINESEBIG5_CHARSET) { |
| 1034 bCJK = TRUE; |
| 1035 } |
| 1036 if (m_pFontInfo == NULL) { |
| 1037 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; |
| 1038 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, |
| 1039 PitchFamily); |
| 1040 } |
| 1041 family = _GetFontFamily(family, nStyle); |
| 1042 CFX_ByteString match = MatchInstalledFonts(_TT_NormalizeName(family)); |
| 1043 if (match.IsEmpty() && family != SubstName && |
| 1044 (!bHasComma && (!bHasHypen || (bHasHypen && !bStyleAvail)))) { |
| 1045 match = MatchInstalledFonts(_TT_NormalizeName(SubstName)); |
| 1046 } |
| 1047 if (match.IsEmpty() && iBaseFont >= 12) { |
| 1048 if (!bCJK) { |
| 1049 if (!CheckSupportThirdPartFont(family, PitchFamily)) { |
| 1050 if (italic_angle != 0) { |
| 1051 bItalic = TRUE; |
| 1052 } else { |
| 1053 bItalic = FALSE; |
| 1054 } |
| 1055 weight = old_weight; |
| 1056 } |
| 1057 } else { |
| 1058 pSubstFont->m_bSubstOfCJK = TRUE; |
| 1059 if (nStyle) { |
| 1060 pSubstFont->m_WeightCJK = weight; |
| 1061 } else { |
| 1062 pSubstFont->m_WeightCJK = FXFONT_FW_NORMAL; |
| 1063 } |
| 1064 if (nStyle & FX_FONT_STYLE_Italic) { |
| 1065 pSubstFont->m_bItlicCJK = TRUE; |
| 1066 } |
| 1067 } |
| 1068 } else { |
| 1069 italic_angle = 0; |
| 1070 weight = |
| 1071 nStyle & FX_FONT_STYLE_BoldBold |
| 1072 ? 900 |
| 1073 : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL); |
| 1074 } |
| 1075 if (!match.IsEmpty() || iBaseFont < 12) { |
| 1076 pSubstFont->m_SubstFlags |= FXFONT_SUBST_EXACT; |
| 1077 if (!match.IsEmpty()) { |
| 1078 family = match; |
| 1079 } |
| 1080 if (iBaseFont < 12) { |
| 1081 if (nStyle && !(iBaseFont % 4)) { |
| 1082 if ((nStyle & 0x3) == 1) { |
| 1083 iBaseFont += 1; |
| 1084 } |
| 1085 if ((nStyle & 0x3) == 2) { |
| 1086 iBaseFont += 3; |
| 1087 } |
| 1088 if ((nStyle & 0x3) == 3) { |
| 1089 iBaseFont += 2; |
| 1090 } |
| 1091 } |
| 1092 if (m_pFontMgr->m_ExternalFonts[iBaseFont].m_pFontData) { |
| 1093 if (m_FoxitFaces[iBaseFont]) { |
| 1094 return m_FoxitFaces[iBaseFont]; |
| 1095 } |
| 1096 m_FoxitFaces[iBaseFont] = m_pFontMgr->GetFixedFace( |
| 1097 m_pFontMgr->m_ExternalFonts[iBaseFont].m_pFontData, |
| 1098 m_pFontMgr->m_ExternalFonts[iBaseFont].m_dwSize, 0); |
| 1099 if (m_FoxitFaces[iBaseFont]) { |
| 1100 return m_FoxitFaces[iBaseFont]; |
| 1101 } |
| 1102 } else { |
| 1103 family = g_Base14FontNames[iBaseFont]; |
| 1104 } |
| 1105 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; |
| 1106 } |
| 1107 } else { |
| 1108 if (flags & FXFONT_ITALIC) { |
| 1109 bItalic = TRUE; |
| 1110 } |
| 1111 } |
| 1112 iExact = !match.IsEmpty(); |
| 1113 void* hFont = m_pFontInfo->MapFont(weight, bItalic, Charset, PitchFamily, |
| 1114 family, iExact); |
| 1115 if (iExact) { |
| 1116 pSubstFont->m_SubstFlags |= FXFONT_SUBST_EXACT; |
| 1117 } |
| 1118 if (hFont == NULL) { |
| 1119 if (bCJK) { |
| 1120 if (italic_angle != 0) { |
| 1121 bItalic = TRUE; |
| 1122 } else { |
| 1123 bItalic = FALSE; |
| 1124 } |
| 1125 weight = old_weight; |
| 1126 } |
| 1127 if (!match.IsEmpty()) { |
| 1128 hFont = m_pFontInfo->GetFont(match); |
| 1129 if (hFont == NULL) { |
| 1130 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, |
| 1131 PitchFamily); |
| 1132 } |
| 1133 } else { |
| 1134 if (Charset == FXFONT_SYMBOL_CHARSET) { |
| 1135 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || \ |
| 1136 _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ |
| 1137 if (SubstName == FX_BSTRC("Symbol")) { |
| 1138 pSubstFont->m_Family = "Chrome Symbol"; |
| 1139 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; |
| 1140 pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; |
| 1141 if (m_FoxitFaces[12]) { |
| 1142 return m_FoxitFaces[12]; |
| 1143 } |
| 1144 const uint8_t* pFontData = NULL; |
| 1145 FX_DWORD size = 0; |
| 1146 m_pFontMgr->GetStandardFont(pFontData, size, 12); |
| 1147 m_FoxitFaces[12] = m_pFontMgr->GetFixedFace(pFontData, size, 0); |
| 1148 return m_FoxitFaces[12]; |
| 1149 } |
| 1150 #endif |
| 1151 pSubstFont->m_SubstFlags |= FXFONT_SUBST_NONSYMBOL; |
| 1152 return FindSubstFont(family, bTrueType, flags & ~FXFONT_SYMBOLIC, |
| 1153 weight, italic_angle, 0, pSubstFont); |
| 1154 } |
| 1155 if (Charset == FXFONT_ANSI_CHARSET) { |
| 1156 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; |
| 1157 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, |
| 1158 PitchFamily); |
| 1159 } |
| 1160 int index = m_CharsetArray.Find(Charset); |
| 1161 if (index < 0) { |
| 1162 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, |
| 1163 PitchFamily); |
| 1164 } |
| 1165 hFont = m_pFontInfo->GetFont(m_FaceArray[index]); |
| 1166 } |
| 1167 } |
| 1168 pSubstFont->m_ExtHandle = m_pFontInfo->RetainFont(hFont); |
| 1169 if (hFont == NULL) { |
| 1170 return NULL; |
| 1171 } |
| 1172 m_pFontInfo->GetFaceName(hFont, SubstName); |
| 1173 if (Charset == FXFONT_DEFAULT_CHARSET) { |
| 1174 m_pFontInfo->GetFontCharset(hFont, Charset); |
| 1175 } |
| 1176 FX_DWORD ttc_size = m_pFontInfo->GetFontData(hFont, 0x74746366, NULL, 0); |
| 1177 FX_DWORD font_size = m_pFontInfo->GetFontData(hFont, 0, NULL, 0); |
| 1178 if (font_size == 0 && ttc_size == 0) { |
| 1179 m_pFontInfo->DeleteFont(hFont); |
| 1180 return NULL; |
| 1181 } |
| 1182 FXFT_Face face = NULL; |
| 1183 if (ttc_size) { |
| 1184 uint8_t temp[1024]; |
| 1185 m_pFontInfo->GetFontData(hFont, 0x74746366, temp, 1024); |
| 1186 FX_DWORD checksum = 0; |
| 1187 for (int i = 0; i < 256; i++) { |
| 1188 checksum += ((FX_DWORD*)temp)[i]; |
| 1189 } |
| 1190 uint8_t* pFontData; |
| 1191 face = m_pFontMgr->GetCachedTTCFace(ttc_size, checksum, |
| 1192 ttc_size - font_size, pFontData); |
| 1193 if (face == NULL) { |
| 1194 pFontData = FX_Alloc(uint8_t, ttc_size); |
| 1195 m_pFontInfo->GetFontData(hFont, 0x74746366, pFontData, ttc_size); |
| 1196 face = m_pFontMgr->AddCachedTTCFace(ttc_size, checksum, pFontData, |
| 1197 ttc_size, ttc_size - font_size); |
| 1198 } |
| 1199 } else { |
| 1200 uint8_t* pFontData; |
| 1201 face = m_pFontMgr->GetCachedFace(SubstName, weight, bItalic, pFontData); |
| 1202 if (face == NULL) { |
| 1203 pFontData = FX_Alloc(uint8_t, font_size); |
| 1204 m_pFontInfo->GetFontData(hFont, 0, pFontData, font_size); |
| 1205 face = m_pFontMgr->AddCachedFace(SubstName, weight, bItalic, pFontData, |
| 1206 font_size, |
| 1207 m_pFontInfo->GetFaceIndex(hFont)); |
| 1208 } |
| 1209 } |
| 1210 if (face == NULL) { |
| 1211 m_pFontInfo->DeleteFont(hFont); |
| 1212 return NULL; |
| 1213 } |
| 1214 pSubstFont->m_Family = SubstName; |
| 1215 pSubstFont->m_Charset = Charset; |
| 1216 FX_BOOL bNeedUpdateWeight = FALSE; |
| 1217 if (FXFT_Is_Face_Bold(face)) { |
| 1218 if (weight == FXFONT_FW_BOLD) { |
| 1219 bNeedUpdateWeight = FALSE; |
| 1220 } else { |
| 1221 bNeedUpdateWeight = TRUE; |
| 1222 } |
| 1223 } else { |
| 1224 if (weight == FXFONT_FW_NORMAL) { |
| 1225 bNeedUpdateWeight = FALSE; |
| 1226 } else { |
| 1227 bNeedUpdateWeight = TRUE; |
| 1228 } |
| 1229 } |
| 1230 if (bNeedUpdateWeight) { |
| 1231 pSubstFont->m_Weight = weight; |
| 1232 } |
| 1233 if (bItalic && !FXFT_Is_Face_Italic(face)) { |
| 1234 if (italic_angle == 0) { |
| 1235 italic_angle = -12; |
| 1236 } else if (FXSYS_abs(italic_angle) < 5) { |
| 1237 italic_angle = 0; |
| 1238 } |
| 1239 pSubstFont->m_ItalicAngle = italic_angle; |
| 1240 } |
| 1241 m_pFontInfo->DeleteFont(hFont); |
| 1242 return face; |
| 1243 } |
| 1244 extern "C" { |
| 1245 unsigned long _FTStreamRead(FXFT_Stream stream, |
| 1246 unsigned long offset, |
| 1247 unsigned char* buffer, |
| 1248 unsigned long count); |
| 1249 void _FTStreamClose(FXFT_Stream stream); |
| 1250 }; |
| 1251 CFontFileFaceInfo::CFontFileFaceInfo() { |
| 1252 m_pFile = NULL; |
| 1253 m_Face = NULL; |
| 1254 m_Charsets = 0; |
| 1255 m_FileSize = 0; |
| 1256 m_FontOffset = 0; |
| 1257 m_Weight = 0; |
| 1258 m_bItalic = FALSE; |
| 1259 m_PitchFamily = 0; |
| 1260 } |
| 1261 CFontFileFaceInfo::~CFontFileFaceInfo() { |
| 1262 if (m_Face) { |
| 1263 FXFT_Done_Face(m_Face); |
| 1264 } |
| 1265 m_Face = NULL; |
| 1266 } |
| 1267 extern FX_BOOL _LoadFile(FXFT_Library library, |
| 1268 FXFT_Face* Face, |
| 1269 IFX_FileRead* pFile, |
| 1270 FXFT_Stream* stream); |
| 1271 #if _FX_OS_ == _FX_ANDROID_ |
| 1272 IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() { |
| 1273 return NULL; |
| 1274 } |
| 1275 #endif |
| 1276 CFX_FolderFontInfo::CFX_FolderFontInfo() {} |
| 1277 CFX_FolderFontInfo::~CFX_FolderFontInfo() { |
| 1278 FX_POSITION pos = m_FontList.GetStartPosition(); |
| 1279 while (pos) { |
| 1280 CFX_ByteString key; |
| 1281 void* value; |
| 1282 m_FontList.GetNextAssoc(pos, key, value); |
| 1283 delete (CFontFaceInfo*)value; |
| 1284 } |
| 1285 } |
| 1286 void CFX_FolderFontInfo::AddPath(const CFX_ByteStringC& path) { |
| 1287 m_PathList.Add(path); |
| 1288 } |
| 1289 void CFX_FolderFontInfo::Release() { |
| 1290 delete this; |
| 1291 } |
| 1292 FX_BOOL CFX_FolderFontInfo::EnumFontList(CFX_FontMapper* pMapper) { |
| 1293 m_pMapper = pMapper; |
| 1294 for (int i = 0; i < m_PathList.GetSize(); i++) { |
| 1295 ScanPath(m_PathList[i]); |
| 1296 } |
| 1297 return TRUE; |
| 1298 } |
| 1299 void CFX_FolderFontInfo::ScanPath(CFX_ByteString& path) { |
| 1300 void* handle = FX_OpenFolder(path); |
| 1301 if (handle == NULL) { |
| 1302 return; |
| 1303 } |
| 1304 CFX_ByteString filename; |
| 1305 FX_BOOL bFolder; |
| 1306 while (FX_GetNextFile(handle, filename, bFolder)) { |
| 1307 if (bFolder) { |
| 1308 if (filename == "." || filename == "..") { |
| 1309 continue; |
| 1310 } |
| 1311 } else { |
| 1312 CFX_ByteString ext = filename.Right(4); |
| 1313 ext.MakeUpper(); |
| 1314 if (ext != ".TTF" && ext != ".OTF" && ext != ".TTC") { |
| 1315 continue; |
| 1316 } |
| 1317 } |
| 1318 CFX_ByteString fullpath = path; |
| 1319 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ |
| 1320 fullpath += "\\"; |
| 1321 #else |
| 1322 fullpath += "/"; |
| 1323 #endif |
| 1324 fullpath += filename; |
| 1325 if (bFolder) { |
| 1326 ScanPath(fullpath); |
| 1327 } else { |
| 1328 ScanFile(fullpath); |
| 1329 } |
| 1330 } |
| 1331 FX_CloseFolder(handle); |
| 1332 } |
| 1333 void CFX_FolderFontInfo::ScanFile(CFX_ByteString& path) { |
| 1334 FXSYS_FILE* pFile = FXSYS_fopen(path, "rb"); |
| 1335 if (pFile == NULL) { |
| 1336 return; |
| 1337 } |
| 1338 FXSYS_fseek(pFile, 0, FXSYS_SEEK_END); |
| 1339 FX_DWORD filesize = FXSYS_ftell(pFile); |
| 1340 uint8_t buffer[16]; |
| 1341 FXSYS_fseek(pFile, 0, FXSYS_SEEK_SET); |
| 1342 size_t readCnt = FXSYS_fread(buffer, 12, 1, pFile); |
| 1343 if (readCnt != 1) { |
| 1344 FXSYS_fclose(pFile); |
| 1345 return; |
| 1346 } |
| 1347 |
| 1348 if (GET_TT_LONG(buffer) == 0x74746366) { |
| 1349 FX_DWORD nFaces = GET_TT_LONG(buffer + 8); |
| 1350 if (nFaces > std::numeric_limits<FX_DWORD>::max() / 4) { |
| 1351 FXSYS_fclose(pFile); |
| 1352 return; |
| 1353 } |
| 1354 FX_DWORD face_bytes = nFaces * 4; |
| 1355 uint8_t* offsets = FX_Alloc(uint8_t, face_bytes); |
| 1356 readCnt = FXSYS_fread(offsets, 1, face_bytes, pFile); |
| 1357 if (readCnt != face_bytes) { |
| 1358 FX_Free(offsets); |
| 1359 FXSYS_fclose(pFile); |
| 1360 return; |
| 1361 } |
| 1362 for (FX_DWORD i = 0; i < nFaces; i++) { |
| 1363 uint8_t* p = offsets + i * 4; |
| 1364 ReportFace(path, pFile, filesize, GET_TT_LONG(p)); |
| 1365 } |
| 1366 FX_Free(offsets); |
| 1367 } else { |
| 1368 ReportFace(path, pFile, filesize, 0); |
| 1369 } |
| 1370 FXSYS_fclose(pFile); |
| 1371 } |
| 1372 void CFX_FolderFontInfo::ReportFace(CFX_ByteString& path, |
| 1373 FXSYS_FILE* pFile, |
| 1374 FX_DWORD filesize, |
| 1375 FX_DWORD offset) { |
| 1376 FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); |
| 1377 char buffer[16]; |
| 1378 if (!FXSYS_fread(buffer, 12, 1, pFile)) { |
| 1379 return; |
| 1380 } |
| 1381 FX_DWORD nTables = GET_TT_SHORT(buffer + 4); |
| 1382 CFX_ByteString tables = _FPDF_ReadStringFromFile(pFile, nTables * 16); |
| 1383 if (tables.IsEmpty()) { |
| 1384 return; |
| 1385 } |
| 1386 CFX_ByteString names = |
| 1387 _FPDF_LoadTableFromTT(pFile, tables, nTables, 0x6e616d65); |
| 1388 CFX_ByteString facename = _FPDF_GetNameFromTT(names, 1); |
| 1389 CFX_ByteString style = _FPDF_GetNameFromTT(names, 2); |
| 1390 if (style != "Regular") { |
| 1391 facename += " " + style; |
| 1392 } |
| 1393 void* p; |
| 1394 if (m_FontList.Lookup(facename, p)) { |
| 1395 return; |
| 1396 } |
| 1397 CFontFaceInfo* pInfo = new CFontFaceInfo; |
| 1398 pInfo->m_FilePath = path; |
| 1399 pInfo->m_FaceName = facename; |
| 1400 pInfo->m_FontTables = tables; |
| 1401 pInfo->m_FontOffset = offset; |
| 1402 pInfo->m_FileSize = filesize; |
| 1403 pInfo->m_Charsets = 0; |
| 1404 CFX_ByteString os2 = |
| 1405 _FPDF_LoadTableFromTT(pFile, tables, nTables, 0x4f532f32); |
| 1406 if (os2.GetLength() >= 86) { |
| 1407 const uint8_t* p = (const uint8_t*)os2 + 78; |
| 1408 FX_DWORD codepages = GET_TT_LONG(p); |
| 1409 if (codepages & (1 << 17)) { |
| 1410 m_pMapper->AddInstalledFont(facename, FXFONT_SHIFTJIS_CHARSET); |
| 1411 pInfo->m_Charsets |= CHARSET_FLAG_SHIFTJIS; |
| 1412 } |
| 1413 if (codepages & (1 << 18)) { |
| 1414 m_pMapper->AddInstalledFont(facename, FXFONT_GB2312_CHARSET); |
| 1415 pInfo->m_Charsets |= CHARSET_FLAG_GB; |
| 1416 } |
| 1417 if (codepages & (1 << 20)) { |
| 1418 m_pMapper->AddInstalledFont(facename, FXFONT_CHINESEBIG5_CHARSET); |
| 1419 pInfo->m_Charsets |= CHARSET_FLAG_BIG5; |
| 1420 } |
| 1421 if ((codepages & (1 << 19)) || (codepages & (1 << 21))) { |
| 1422 m_pMapper->AddInstalledFont(facename, FXFONT_HANGEUL_CHARSET); |
| 1423 pInfo->m_Charsets |= CHARSET_FLAG_KOREAN; |
| 1424 } |
| 1425 if (codepages & (1 << 31)) { |
| 1426 m_pMapper->AddInstalledFont(facename, FXFONT_SYMBOL_CHARSET); |
| 1427 pInfo->m_Charsets |= CHARSET_FLAG_SYMBOL; |
| 1428 } |
| 1429 } |
| 1430 m_pMapper->AddInstalledFont(facename, FXFONT_ANSI_CHARSET); |
| 1431 pInfo->m_Charsets |= CHARSET_FLAG_ANSI; |
| 1432 pInfo->m_Styles = 0; |
| 1433 if (style.Find(FX_BSTRC("Bold")) > -1) { |
| 1434 pInfo->m_Styles |= FXFONT_BOLD; |
| 1435 } |
| 1436 if (style.Find(FX_BSTRC("Italic")) > -1 || |
| 1437 style.Find(FX_BSTRC("Oblique")) > -1) { |
| 1438 pInfo->m_Styles |= FXFONT_ITALIC; |
| 1439 } |
| 1440 if (facename.Find(FX_BSTRC("Serif")) > -1) { |
| 1441 pInfo->m_Styles |= FXFONT_SERIF; |
| 1442 } |
| 1443 m_FontList.SetAt(facename, pInfo); |
| 1444 } |
| 1445 void* CFX_FolderFontInfo::MapFont(int weight, |
| 1446 FX_BOOL bItalic, |
| 1447 int charset, |
| 1448 int pitch_family, |
| 1449 const FX_CHAR* family, |
| 1450 int& iExact) { |
| 1451 return NULL; |
| 1452 } |
| 1453 void* CFX_FolderFontInfo::GetFont(const FX_CHAR* face) { |
| 1454 void* p; |
| 1455 if (!m_FontList.Lookup(face, p)) { |
| 1456 return NULL; |
| 1457 } |
| 1458 return p; |
| 1459 } |
| 1460 FX_DWORD CFX_FolderFontInfo::GetFontData(void* hFont, |
| 1461 FX_DWORD table, |
| 1462 uint8_t* buffer, |
| 1463 FX_DWORD size) { |
| 1464 if (hFont == NULL) { |
| 1465 return 0; |
| 1466 } |
| 1467 CFontFaceInfo* pFont = (CFontFaceInfo*)hFont; |
| 1468 FXSYS_FILE* pFile = NULL; |
| 1469 if (size > 0) { |
| 1470 pFile = FXSYS_fopen(pFont->m_FilePath, "rb"); |
| 1471 if (pFile == NULL) { |
| 1472 return 0; |
| 1473 } |
| 1474 } |
| 1475 FX_DWORD datasize = 0; |
| 1476 FX_DWORD offset; |
| 1477 if (table == 0) { |
| 1478 datasize = pFont->m_FontOffset ? 0 : pFont->m_FileSize; |
| 1479 offset = 0; |
| 1480 } else if (table == 0x74746366) { |
| 1481 datasize = pFont->m_FontOffset ? pFont->m_FileSize : 0; |
| 1482 offset = 0; |
| 1483 } else { |
| 1484 FX_DWORD nTables = pFont->m_FontTables.GetLength() / 16; |
| 1485 for (FX_DWORD i = 0; i < nTables; i++) { |
| 1486 const uint8_t* p = (const uint8_t*)pFont->m_FontTables + i * 16; |
| 1487 if (GET_TT_LONG(p) == table) { |
| 1488 offset = GET_TT_LONG(p + 8); |
| 1489 datasize = GET_TT_LONG(p + 12); |
| 1490 } |
| 1491 } |
| 1492 } |
| 1493 if (datasize && size >= datasize && pFile) { |
| 1494 FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); |
| 1495 FXSYS_fread(buffer, datasize, 1, pFile); |
| 1496 } |
| 1497 if (pFile) { |
| 1498 FXSYS_fclose(pFile); |
| 1499 } |
| 1500 return datasize; |
| 1501 } |
| 1502 void CFX_FolderFontInfo::DeleteFont(void* hFont) {} |
| 1503 FX_BOOL CFX_FolderFontInfo::GetFaceName(void* hFont, CFX_ByteString& name) { |
| 1504 if (hFont == NULL) { |
| 871 return FALSE; | 1505 return FALSE; |
| 872 } | 1506 } |
| 873 FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name, FX_BOOL bTru
eType, FX_DWORD flags, | 1507 CFontFaceInfo* pFont = (CFontFaceInfo*)hFont; |
| 874 int weight, int italic_angle, int Window
CP, CFX_SubstFont* pSubstFont) | 1508 name = pFont->m_FaceName; |
| 875 { | 1509 return TRUE; |
| 876 if (!(flags & FXFONT_USEEXTERNATTR)) { | 1510 } |
| 877 weight = FXFONT_FW_NORMAL; | 1511 FX_BOOL CFX_FolderFontInfo::GetFontCharset(void* hFont, int& charset) { |
| 878 italic_angle = 0; | 1512 return FALSE; |
| 879 } | 1513 } |
| 880 CFX_ByteString SubstName = name; | |
| 881 SubstName.Remove(0x20); | |
| 882 if (bTrueType) { | |
| 883 if (name[0] == '@') { | |
| 884 SubstName = name.Mid(1); | |
| 885 } | |
| 886 } | |
| 887 _PDF_GetStandardFontName(SubstName); | |
| 888 if (SubstName == FX_BSTRC("Symbol") && !bTrueType) { | |
| 889 pSubstFont->m_Family = "Chrome Symbol"; | |
| 890 pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; | |
| 891 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; | |
| 892 if (m_FoxitFaces[12]) { | |
| 893 return m_FoxitFaces[12]; | |
| 894 } | |
| 895 const uint8_t* pFontData = NULL; | |
| 896 FX_DWORD size = 0; | |
| 897 m_pFontMgr->GetStandardFont(pFontData, size, 12); | |
| 898 m_FoxitFaces[12] = m_pFontMgr->GetFixedFace(pFontData, size, 0); | |
| 899 return m_FoxitFaces[12]; | |
| 900 } | |
| 901 if (SubstName == FX_BSTRC("ZapfDingbats")) { | |
| 902 pSubstFont->m_Family = "Chrome Dingbats"; | |
| 903 pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; | |
| 904 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; | |
| 905 if (m_FoxitFaces[13]) { | |
| 906 return m_FoxitFaces[13]; | |
| 907 } | |
| 908 const uint8_t* pFontData = NULL; | |
| 909 FX_DWORD size = 0; | |
| 910 m_pFontMgr->GetStandardFont(pFontData, size, 13); | |
| 911 m_FoxitFaces[13] = m_pFontMgr->GetFixedFace(pFontData, size, 0); | |
| 912 return m_FoxitFaces[13]; | |
| 913 } | |
| 914 int iBaseFont = 0; | |
| 915 CFX_ByteString family, style; | |
| 916 FX_BOOL bHasComma = FALSE; | |
| 917 FX_BOOL bHasHypen = FALSE; | |
| 918 int find = SubstName.Find(FX_BSTRC(","), 0); | |
| 919 if (find >= 0) { | |
| 920 family = SubstName.Left(find); | |
| 921 _PDF_GetStandardFontName(family); | |
| 922 style = SubstName.Mid(find + 1); | |
| 923 bHasComma = TRUE; | |
| 924 } else { | |
| 925 family = SubstName; | |
| 926 } | |
| 927 for (; iBaseFont < 12; iBaseFont ++) | |
| 928 if (family == CFX_ByteStringC(g_Base14FontNames[iBaseFont])) { | |
| 929 break; | |
| 930 } | |
| 931 int PitchFamily = 0; | |
| 932 FX_BOOL bItalic = FALSE; | |
| 933 FX_DWORD nStyle = 0; | |
| 934 FX_BOOL bStyleAvail = FALSE; | |
| 935 if (iBaseFont < 12) { | |
| 936 family = g_Base14FontNames[iBaseFont]; | |
| 937 if ((iBaseFont % 4) == 1 || (iBaseFont % 4) == 2) { | |
| 938 nStyle |= FX_FONT_STYLE_Bold; | |
| 939 } | |
| 940 if ((iBaseFont % 4) / 2) { | |
| 941 nStyle |= FX_FONT_STYLE_Italic; | |
| 942 } | |
| 943 if (iBaseFont < 4) { | |
| 944 PitchFamily |= FXFONT_FF_FIXEDPITCH; | |
| 945 } | |
| 946 if (iBaseFont >= 8) { | |
| 947 PitchFamily |= FXFONT_FF_ROMAN; | |
| 948 } | |
| 949 } else { | |
| 950 if (!bHasComma) { | |
| 951 find = family.ReverseFind('-'); | |
| 952 if (find >= 0) { | |
| 953 style = family.Mid(find + 1); | |
| 954 family = family.Left(find); | |
| 955 bHasHypen = TRUE; | |
| 956 } | |
| 957 } | |
| 958 if (!bHasHypen) { | |
| 959 int nLen = family.GetLength(); | |
| 960 int32_t nRet = GetStyleType(family, TRUE); | |
| 961 if (nRet > -1) { | |
| 962 family = family.Left(nLen - g_FontStyles[nRet].len); | |
| 963 if (nRet == 0) { | |
| 964 nStyle |= FX_FONT_STYLE_Bold; | |
| 965 } | |
| 966 if (nRet == 1) { | |
| 967 nStyle |= FX_FONT_STYLE_Italic; | |
| 968 } | |
| 969 if (nRet == 2) { | |
| 970 nStyle |= (FX_FONT_STYLE_Bold | FX_FONT_STYLE_Italic); | |
| 971 } | |
| 972 } | |
| 973 } | |
| 974 if (flags & FXFONT_SERIF) { | |
| 975 PitchFamily |= FXFONT_FF_ROMAN; | |
| 976 } | |
| 977 if (flags & FXFONT_SCRIPT) { | |
| 978 PitchFamily |= FXFONT_FF_SCRIPT; | |
| 979 } | |
| 980 if (flags & FXFONT_FIXED_PITCH) { | |
| 981 PitchFamily |= FXFONT_FF_FIXEDPITCH; | |
| 982 } | |
| 983 } | |
| 984 if (!style.IsEmpty()) { | |
| 985 int nLen = style.GetLength(); | |
| 986 const FX_CHAR* pStyle = style; | |
| 987 int i = 0; | |
| 988 FX_BOOL bFirstItem = TRUE; | |
| 989 CFX_ByteString buf; | |
| 990 while (i < nLen) { | |
| 991 buf = ParseStyle(pStyle, nLen, i); | |
| 992 int32_t nRet = GetStyleType(buf, FALSE); | |
| 993 if ((i && !bStyleAvail) || (!i && nRet < 0)) { | |
| 994 family = SubstName; | |
| 995 iBaseFont = 12; | |
| 996 break; | |
| 997 } else if (nRet >= 0) { | |
| 998 bStyleAvail = TRUE; | |
| 999 } | |
| 1000 if (nRet == 0) { | |
| 1001 if (nStyle & FX_FONT_STYLE_Bold) { | |
| 1002 nStyle |= FX_FONT_STYLE_BoldBold; | |
| 1003 } else { | |
| 1004 nStyle |= FX_FONT_STYLE_Bold; | |
| 1005 } | |
| 1006 bFirstItem = FALSE; | |
| 1007 } | |
| 1008 if (nRet == 1) { | |
| 1009 if (bFirstItem) { | |
| 1010 nStyle |= FX_FONT_STYLE_Italic; | |
| 1011 } else { | |
| 1012 family = SubstName; | |
| 1013 iBaseFont = 12; | |
| 1014 } | |
| 1015 break; | |
| 1016 } | |
| 1017 if (nRet == 2) { | |
| 1018 nStyle |= FX_FONT_STYLE_Italic; | |
| 1019 if (nStyle & FX_FONT_STYLE_Bold) { | |
| 1020 nStyle |= FX_FONT_STYLE_BoldBold; | |
| 1021 } else { | |
| 1022 nStyle |= FX_FONT_STYLE_Bold; | |
| 1023 } | |
| 1024 bFirstItem = FALSE; | |
| 1025 } | |
| 1026 i += buf.GetLength() + 1; | |
| 1027 } | |
| 1028 } | |
| 1029 weight = weight ? weight : FXFONT_FW_NORMAL; | |
| 1030 int old_weight = weight; | |
| 1031 if (nStyle) { | |
| 1032 weight = nStyle & FX_FONT_STYLE_BoldBold ? 900 : (nStyle & FX_FONT_STYLE
_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL); | |
| 1033 } | |
| 1034 if (nStyle & FX_FONT_STYLE_Italic) { | |
| 1035 bItalic = TRUE; | |
| 1036 } | |
| 1037 FX_BOOL bCJK = FALSE; | |
| 1038 int iExact = 0; | |
| 1039 int Charset = FXFONT_ANSI_CHARSET; | |
| 1040 if (WindowCP) { | |
| 1041 Charset = _GetCharsetFromCodePage(WindowCP); | |
| 1042 } else if (iBaseFont == 12 && (flags & FXFONT_SYMBOLIC)) { | |
| 1043 Charset = FXFONT_SYMBOL_CHARSET; | |
| 1044 } | |
| 1045 if (Charset == FXFONT_SHIFTJIS_CHARSET || Charset == FXFONT_GB2312_CHARSET |
| | |
| 1046 Charset == FXFONT_HANGEUL_CHARSET || Charset == FXFONT_CHINESEBIG5_C
HARSET) { | |
| 1047 bCJK = TRUE; | |
| 1048 } | |
| 1049 if (m_pFontInfo == NULL) { | |
| 1050 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; | |
| 1051 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight,
PitchFamily); | |
| 1052 } | |
| 1053 family = _GetFontFamily(family, nStyle); | |
| 1054 CFX_ByteString match = MatchInstalledFonts(_TT_NormalizeName(family)); | |
| 1055 if (match.IsEmpty() && family != SubstName && (!bHasComma && (!bHasHypen ||
(bHasHypen && !bStyleAvail)))) { | |
| 1056 match = MatchInstalledFonts(_TT_NormalizeName(SubstName)); | |
| 1057 } | |
| 1058 if (match.IsEmpty() && iBaseFont >= 12) { | |
| 1059 if (!bCJK) { | |
| 1060 if (!CheckSupportThirdPartFont(family, PitchFamily)) { | |
| 1061 if (italic_angle != 0) { | |
| 1062 bItalic = TRUE; | |
| 1063 } else { | |
| 1064 bItalic = FALSE; | |
| 1065 } | |
| 1066 weight = old_weight; | |
| 1067 } | |
| 1068 } else { | |
| 1069 pSubstFont->m_bSubstOfCJK = TRUE; | |
| 1070 if (nStyle) { | |
| 1071 pSubstFont->m_WeightCJK = weight; | |
| 1072 } else { | |
| 1073 pSubstFont->m_WeightCJK = FXFONT_FW_NORMAL; | |
| 1074 } | |
| 1075 if (nStyle & FX_FONT_STYLE_Italic) { | |
| 1076 pSubstFont->m_bItlicCJK = TRUE; | |
| 1077 } | |
| 1078 } | |
| 1079 } else { | |
| 1080 italic_angle = 0; | |
| 1081 weight = nStyle & FX_FONT_STYLE_BoldBold ? 900 : (nStyle & FX_FONT_STYLE
_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL); | |
| 1082 } | |
| 1083 if (!match.IsEmpty() || iBaseFont < 12) { | |
| 1084 pSubstFont->m_SubstFlags |= FXFONT_SUBST_EXACT; | |
| 1085 if (!match.IsEmpty()) { | |
| 1086 family = match; | |
| 1087 } | |
| 1088 if (iBaseFont < 12) { | |
| 1089 if (nStyle && !(iBaseFont % 4)) { | |
| 1090 if ((nStyle & 0x3) == 1) { | |
| 1091 iBaseFont += 1; | |
| 1092 } | |
| 1093 if ((nStyle & 0x3) == 2) { | |
| 1094 iBaseFont += 3; | |
| 1095 } | |
| 1096 if ((nStyle & 0x3) == 3) { | |
| 1097 iBaseFont += 2; | |
| 1098 } | |
| 1099 } | |
| 1100 if (m_pFontMgr->m_ExternalFonts[iBaseFont].m_pFontData) { | |
| 1101 if (m_FoxitFaces[iBaseFont]) { | |
| 1102 return m_FoxitFaces[iBaseFont]; | |
| 1103 } | |
| 1104 m_FoxitFaces[iBaseFont] = m_pFontMgr->GetFixedFace(m_pFontMgr->m
_ExternalFonts[iBaseFont].m_pFontData, | |
| 1105 m_pFontMgr->m_ExternalFonts[iBaseFont]
.m_dwSize, 0); | |
| 1106 if (m_FoxitFaces[iBaseFont]) { | |
| 1107 return m_FoxitFaces[iBaseFont]; | |
| 1108 } | |
| 1109 } else { | |
| 1110 family = g_Base14FontNames[iBaseFont]; | |
| 1111 } | |
| 1112 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; | |
| 1113 } | |
| 1114 } else { | |
| 1115 if (flags & FXFONT_ITALIC) { | |
| 1116 bItalic = TRUE; | |
| 1117 } | |
| 1118 } | |
| 1119 iExact = !match.IsEmpty(); | |
| 1120 void* hFont = m_pFontInfo->MapFont(weight, bItalic, Charset, PitchFamily, fa
mily, iExact); | |
| 1121 if (iExact) { | |
| 1122 pSubstFont->m_SubstFlags |= FXFONT_SUBST_EXACT; | |
| 1123 } | |
| 1124 if (hFont == NULL) { | |
| 1125 if (bCJK) { | |
| 1126 if (italic_angle != 0) { | |
| 1127 bItalic = TRUE; | |
| 1128 } else { | |
| 1129 bItalic = FALSE; | |
| 1130 } | |
| 1131 weight = old_weight; | |
| 1132 } | |
| 1133 if (!match.IsEmpty()) { | |
| 1134 hFont = m_pFontInfo->GetFont(match); | |
| 1135 if (hFont == NULL) { | |
| 1136 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old
_weight, PitchFamily); | |
| 1137 } | |
| 1138 } else { | |
| 1139 if (Charset == FXFONT_SYMBOL_CHARSET) { | |
| 1140 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || _FXM_PLATFORM_ == _FXM_PLATFORM_
ANDROID_ | |
| 1141 if (SubstName == FX_BSTRC("Symbol")) { | |
| 1142 pSubstFont->m_Family = "Chrome Symbol"; | |
| 1143 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; | |
| 1144 pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; | |
| 1145 if (m_FoxitFaces[12]) { | |
| 1146 return m_FoxitFaces[12]; | |
| 1147 } | |
| 1148 const uint8_t* pFontData = NULL; | |
| 1149 FX_DWORD size = 0; | |
| 1150 m_pFontMgr->GetStandardFont(pFontData, size, 12); | |
| 1151 m_FoxitFaces[12] = m_pFontMgr->GetFixedFace(pFontData, size,
0); | |
| 1152 return m_FoxitFaces[12]; | |
| 1153 } | |
| 1154 #endif | |
| 1155 pSubstFont->m_SubstFlags |= FXFONT_SUBST_NONSYMBOL; | |
| 1156 return FindSubstFont(family, bTrueType, flags & ~FXFONT_SYMBOLIC
, weight, italic_angle, 0, pSubstFont); | |
| 1157 } | |
| 1158 if (Charset == FXFONT_ANSI_CHARSET) { | |
| 1159 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; | |
| 1160 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old
_weight, PitchFamily); | |
| 1161 } | |
| 1162 int index = m_CharsetArray.Find(Charset); | |
| 1163 if (index < 0) { | |
| 1164 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old
_weight, PitchFamily); | |
| 1165 } | |
| 1166 hFont = m_pFontInfo->GetFont(m_FaceArray[index]); | |
| 1167 } | |
| 1168 } | |
| 1169 pSubstFont->m_ExtHandle = m_pFontInfo->RetainFont(hFont); | |
| 1170 if (hFont == NULL) { | |
| 1171 return NULL; | |
| 1172 } | |
| 1173 m_pFontInfo->GetFaceName(hFont, SubstName); | |
| 1174 if (Charset == FXFONT_DEFAULT_CHARSET) { | |
| 1175 m_pFontInfo->GetFontCharset(hFont, Charset); | |
| 1176 } | |
| 1177 FX_DWORD ttc_size = m_pFontInfo->GetFontData(hFont, 0x74746366, NULL, 0); | |
| 1178 FX_DWORD font_size = m_pFontInfo->GetFontData(hFont, 0, NULL, 0); | |
| 1179 if(font_size == 0 && ttc_size == 0) { | |
| 1180 m_pFontInfo->DeleteFont(hFont); | |
| 1181 return NULL; | |
| 1182 } | |
| 1183 FXFT_Face face = NULL; | |
| 1184 if (ttc_size) { | |
| 1185 uint8_t temp[1024]; | |
| 1186 m_pFontInfo->GetFontData(hFont, 0x74746366, temp, 1024); | |
| 1187 FX_DWORD checksum = 0; | |
| 1188 for (int i = 0; i < 256; i ++) { | |
| 1189 checksum += ((FX_DWORD*)temp)[i]; | |
| 1190 } | |
| 1191 uint8_t* pFontData; | |
| 1192 face = m_pFontMgr->GetCachedTTCFace(ttc_size, checksum, ttc_size - font_
size, pFontData); | |
| 1193 if (face == NULL) { | |
| 1194 pFontData = FX_Alloc(uint8_t, ttc_size); | |
| 1195 m_pFontInfo->GetFontData(hFont, 0x74746366, pFontData, ttc_size); | |
| 1196 face = m_pFontMgr->AddCachedTTCFace(ttc_size, checksum, pFontData, t
tc_size, | |
| 1197 ttc_size - font_size); | |
| 1198 } | |
| 1199 } else { | |
| 1200 uint8_t* pFontData; | |
| 1201 face = m_pFontMgr->GetCachedFace(SubstName, weight, bItalic, pFontData); | |
| 1202 if (face == NULL) { | |
| 1203 pFontData = FX_Alloc(uint8_t, font_size); | |
| 1204 m_pFontInfo->GetFontData(hFont, 0, pFontData, font_size); | |
| 1205 face = m_pFontMgr->AddCachedFace(SubstName, weight, bItalic, pFontDa
ta, font_size, m_pFontInfo->GetFaceIndex(hFont)); | |
| 1206 } | |
| 1207 } | |
| 1208 if (face == NULL) { | |
| 1209 m_pFontInfo->DeleteFont(hFont); | |
| 1210 return NULL; | |
| 1211 } | |
| 1212 pSubstFont->m_Family = SubstName; | |
| 1213 pSubstFont->m_Charset = Charset; | |
| 1214 FX_BOOL bNeedUpdateWeight = FALSE; | |
| 1215 if (FXFT_Is_Face_Bold(face)) { | |
| 1216 if (weight == FXFONT_FW_BOLD) { | |
| 1217 bNeedUpdateWeight = FALSE; | |
| 1218 } else { | |
| 1219 bNeedUpdateWeight = TRUE; | |
| 1220 } | |
| 1221 } else { | |
| 1222 if (weight == FXFONT_FW_NORMAL) { | |
| 1223 bNeedUpdateWeight = FALSE; | |
| 1224 } else { | |
| 1225 bNeedUpdateWeight = TRUE; | |
| 1226 } | |
| 1227 } | |
| 1228 if (bNeedUpdateWeight) { | |
| 1229 pSubstFont->m_Weight = weight; | |
| 1230 } | |
| 1231 if (bItalic && !FXFT_Is_Face_Italic(face)) { | |
| 1232 if (italic_angle == 0) { | |
| 1233 italic_angle = -12; | |
| 1234 } else if (FXSYS_abs(italic_angle) < 5) { | |
| 1235 italic_angle = 0; | |
| 1236 } | |
| 1237 pSubstFont->m_ItalicAngle = italic_angle; | |
| 1238 } | |
| 1239 m_pFontInfo->DeleteFont(hFont); | |
| 1240 return face; | |
| 1241 } | |
| 1242 extern "C" { | |
| 1243 unsigned long _FTStreamRead(FXFT_Stream stream, unsigned long offset, | |
| 1244 unsigned char* buffer, unsigned long count); | |
| 1245 void _FTStreamClose(FXFT_Stream stream); | |
| 1246 }; | |
| 1247 CFontFileFaceInfo::CFontFileFaceInfo() | |
| 1248 { | |
| 1249 m_pFile = NULL; | |
| 1250 m_Face = NULL; | |
| 1251 m_Charsets = 0; | |
| 1252 m_FileSize = 0; | |
| 1253 m_FontOffset = 0; | |
| 1254 m_Weight = 0; | |
| 1255 m_bItalic = FALSE; | |
| 1256 m_PitchFamily = 0; | |
| 1257 } | |
| 1258 CFontFileFaceInfo::~CFontFileFaceInfo() | |
| 1259 { | |
| 1260 if (m_Face) { | |
| 1261 FXFT_Done_Face(m_Face); | |
| 1262 } | |
| 1263 m_Face = NULL; | |
| 1264 } | |
| 1265 extern FX_BOOL _LoadFile(FXFT_Library library, FXFT_Face* Face, IFX_FileRead* pF
ile, FXFT_Stream* stream); | |
| 1266 #if _FX_OS_ == _FX_ANDROID_ | |
| 1267 IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() | |
| 1268 { | |
| 1269 return NULL; | |
| 1270 } | |
| 1271 #endif | |
| 1272 CFX_FolderFontInfo::CFX_FolderFontInfo() | |
| 1273 { | |
| 1274 } | |
| 1275 CFX_FolderFontInfo::~CFX_FolderFontInfo() | |
| 1276 { | |
| 1277 FX_POSITION pos = m_FontList.GetStartPosition(); | |
| 1278 while (pos) { | |
| 1279 CFX_ByteString key; | |
| 1280 void* value; | |
| 1281 m_FontList.GetNextAssoc(pos, key, value); | |
| 1282 delete (CFontFaceInfo*)value; | |
| 1283 } | |
| 1284 } | |
| 1285 void CFX_FolderFontInfo::AddPath(const CFX_ByteStringC& path) | |
| 1286 { | |
| 1287 m_PathList.Add(path); | |
| 1288 } | |
| 1289 void CFX_FolderFontInfo::Release() | |
| 1290 { | |
| 1291 delete this; | |
| 1292 } | |
| 1293 FX_BOOL CFX_FolderFontInfo::EnumFontList(CFX_FontMapper* pMapper) | |
| 1294 { | |
| 1295 m_pMapper = pMapper; | |
| 1296 for (int i = 0; i < m_PathList.GetSize(); i ++) { | |
| 1297 ScanPath(m_PathList[i]); | |
| 1298 } | |
| 1299 return TRUE; | |
| 1300 } | |
| 1301 void CFX_FolderFontInfo::ScanPath(CFX_ByteString& path) | |
| 1302 { | |
| 1303 void* handle = FX_OpenFolder(path); | |
| 1304 if (handle == NULL) { | |
| 1305 return; | |
| 1306 } | |
| 1307 CFX_ByteString filename; | |
| 1308 FX_BOOL bFolder; | |
| 1309 while (FX_GetNextFile(handle, filename, bFolder)) { | |
| 1310 if (bFolder) { | |
| 1311 if (filename == "." || filename == "..") { | |
| 1312 continue; | |
| 1313 } | |
| 1314 } else { | |
| 1315 CFX_ByteString ext = filename.Right(4); | |
| 1316 ext.MakeUpper(); | |
| 1317 if (ext != ".TTF" && ext != ".OTF" && ext != ".TTC") { | |
| 1318 continue; | |
| 1319 } | |
| 1320 } | |
| 1321 CFX_ByteString fullpath = path; | |
| 1322 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ | |
| 1323 fullpath += "\\"; | |
| 1324 #else | |
| 1325 fullpath += "/"; | |
| 1326 #endif | |
| 1327 fullpath += filename; | |
| 1328 if (bFolder) { | |
| 1329 ScanPath(fullpath); | |
| 1330 } else { | |
| 1331 ScanFile(fullpath); | |
| 1332 } | |
| 1333 } | |
| 1334 FX_CloseFolder(handle); | |
| 1335 } | |
| 1336 void CFX_FolderFontInfo::ScanFile(CFX_ByteString& path) | |
| 1337 { | |
| 1338 FXSYS_FILE* pFile = FXSYS_fopen(path, "rb"); | |
| 1339 if (pFile == NULL) { | |
| 1340 return; | |
| 1341 } | |
| 1342 FXSYS_fseek(pFile, 0, FXSYS_SEEK_END); | |
| 1343 FX_DWORD filesize = FXSYS_ftell(pFile); | |
| 1344 uint8_t buffer[16]; | |
| 1345 FXSYS_fseek(pFile, 0, FXSYS_SEEK_SET); | |
| 1346 size_t readCnt = FXSYS_fread(buffer, 12, 1, pFile); | |
| 1347 if (readCnt != 1) { | |
| 1348 FXSYS_fclose(pFile); | |
| 1349 return; | |
| 1350 } | |
| 1351 | |
| 1352 if (GET_TT_LONG(buffer) == 0x74746366) { | |
| 1353 FX_DWORD nFaces = GET_TT_LONG(buffer + 8); | |
| 1354 if (nFaces > std::numeric_limits<FX_DWORD>::max() / 4) { | |
| 1355 FXSYS_fclose(pFile); | |
| 1356 return; | |
| 1357 } | |
| 1358 FX_DWORD face_bytes = nFaces * 4; | |
| 1359 uint8_t* offsets = FX_Alloc(uint8_t, face_bytes); | |
| 1360 readCnt = FXSYS_fread(offsets, 1, face_bytes, pFile); | |
| 1361 if (readCnt != face_bytes) { | |
| 1362 FX_Free(offsets); | |
| 1363 FXSYS_fclose(pFile); | |
| 1364 return; | |
| 1365 } | |
| 1366 for (FX_DWORD i = 0; i < nFaces; i ++) { | |
| 1367 uint8_t* p = offsets + i * 4; | |
| 1368 ReportFace(path, pFile, filesize, GET_TT_LONG(p)); | |
| 1369 } | |
| 1370 FX_Free(offsets); | |
| 1371 } else { | |
| 1372 ReportFace(path, pFile, filesize, 0); | |
| 1373 } | |
| 1374 FXSYS_fclose(pFile); | |
| 1375 } | |
| 1376 void CFX_FolderFontInfo::ReportFace(CFX_ByteString& path, FXSYS_FILE* pFile, FX_
DWORD filesize, FX_DWORD offset) | |
| 1377 { | |
| 1378 FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); | |
| 1379 char buffer[16]; | |
| 1380 if (!FXSYS_fread(buffer, 12, 1, pFile)) { | |
| 1381 return; | |
| 1382 } | |
| 1383 FX_DWORD nTables = GET_TT_SHORT(buffer + 4); | |
| 1384 CFX_ByteString tables = _FPDF_ReadStringFromFile(pFile, nTables * 16); | |
| 1385 if (tables.IsEmpty()) { | |
| 1386 return; | |
| 1387 } | |
| 1388 CFX_ByteString names = _FPDF_LoadTableFromTT(pFile, tables, nTables, 0x6e616
d65); | |
| 1389 CFX_ByteString facename = _FPDF_GetNameFromTT(names, 1); | |
| 1390 CFX_ByteString style = _FPDF_GetNameFromTT(names, 2); | |
| 1391 if (style != "Regular") { | |
| 1392 facename += " " + style; | |
| 1393 } | |
| 1394 void* p; | |
| 1395 if (m_FontList.Lookup(facename, p)) { | |
| 1396 return; | |
| 1397 } | |
| 1398 CFontFaceInfo* pInfo = new CFontFaceInfo; | |
| 1399 pInfo->m_FilePath = path; | |
| 1400 pInfo->m_FaceName = facename; | |
| 1401 pInfo->m_FontTables = tables; | |
| 1402 pInfo->m_FontOffset = offset; | |
| 1403 pInfo->m_FileSize = filesize; | |
| 1404 pInfo->m_Charsets = 0; | |
| 1405 CFX_ByteString os2 = _FPDF_LoadTableFromTT(pFile, tables, nTables, 0x4f532f3
2); | |
| 1406 if (os2.GetLength() >= 86) { | |
| 1407 const uint8_t* p = (const uint8_t*)os2 + 78; | |
| 1408 FX_DWORD codepages = GET_TT_LONG(p); | |
| 1409 if (codepages & (1 << 17)) { | |
| 1410 m_pMapper->AddInstalledFont(facename, FXFONT_SHIFTJIS_CHARSET); | |
| 1411 pInfo->m_Charsets |= CHARSET_FLAG_SHIFTJIS; | |
| 1412 } | |
| 1413 if (codepages & (1 << 18)) { | |
| 1414 m_pMapper->AddInstalledFont(facename, FXFONT_GB2312_CHARSET); | |
| 1415 pInfo->m_Charsets |= CHARSET_FLAG_GB; | |
| 1416 } | |
| 1417 if (codepages & (1 << 20)) { | |
| 1418 m_pMapper->AddInstalledFont(facename, FXFONT_CHINESEBIG5_CHARSET); | |
| 1419 pInfo->m_Charsets |= CHARSET_FLAG_BIG5; | |
| 1420 } | |
| 1421 if ((codepages & (1 << 19)) || (codepages & (1 << 21))) { | |
| 1422 m_pMapper->AddInstalledFont(facename, FXFONT_HANGEUL_CHARSET); | |
| 1423 pInfo->m_Charsets |= CHARSET_FLAG_KOREAN; | |
| 1424 } | |
| 1425 if (codepages & (1 << 31)) { | |
| 1426 m_pMapper->AddInstalledFont(facename, FXFONT_SYMBOL_CHARSET); | |
| 1427 pInfo->m_Charsets |= CHARSET_FLAG_SYMBOL; | |
| 1428 } | |
| 1429 } | |
| 1430 m_pMapper->AddInstalledFont(facename, FXFONT_ANSI_CHARSET); | |
| 1431 pInfo->m_Charsets |= CHARSET_FLAG_ANSI; | |
| 1432 pInfo->m_Styles = 0; | |
| 1433 if (style.Find(FX_BSTRC("Bold")) > -1) { | |
| 1434 pInfo->m_Styles |= FXFONT_BOLD; | |
| 1435 } | |
| 1436 if (style.Find(FX_BSTRC("Italic")) > -1 || style.Find(FX_BSTRC("Oblique")) >
-1) { | |
| 1437 pInfo->m_Styles |= FXFONT_ITALIC; | |
| 1438 } | |
| 1439 if (facename.Find(FX_BSTRC("Serif")) > -1) { | |
| 1440 pInfo->m_Styles |= FXFONT_SERIF; | |
| 1441 } | |
| 1442 m_FontList.SetAt(facename, pInfo); | |
| 1443 } | |
| 1444 void* CFX_FolderFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int
pitch_family, const FX_CHAR* family, int& iExact) | |
| 1445 { | |
| 1446 return NULL; | |
| 1447 } | |
| 1448 void* CFX_FolderFontInfo::GetFont(const FX_CHAR* face) | |
| 1449 { | |
| 1450 void* p; | |
| 1451 if (!m_FontList.Lookup(face, p)) { | |
| 1452 return NULL; | |
| 1453 } | |
| 1454 return p; | |
| 1455 } | |
| 1456 FX_DWORD CFX_FolderFontInfo::GetFontData(void* hFont, FX_DWORD table, uint8_t* b
uffer, FX_DWORD size) | |
| 1457 { | |
| 1458 if (hFont == NULL) { | |
| 1459 return 0; | |
| 1460 } | |
| 1461 CFontFaceInfo* pFont = (CFontFaceInfo*)hFont; | |
| 1462 FXSYS_FILE* pFile = NULL; | |
| 1463 if (size > 0) { | |
| 1464 pFile = FXSYS_fopen(pFont->m_FilePath, "rb"); | |
| 1465 if (pFile == NULL) { | |
| 1466 return 0; | |
| 1467 } | |
| 1468 } | |
| 1469 FX_DWORD datasize = 0; | |
| 1470 FX_DWORD offset; | |
| 1471 if (table == 0) { | |
| 1472 datasize = pFont->m_FontOffset ? 0 : pFont->m_FileSize; | |
| 1473 offset = 0; | |
| 1474 } else if (table == 0x74746366) { | |
| 1475 datasize = pFont->m_FontOffset ? pFont->m_FileSize : 0; | |
| 1476 offset = 0; | |
| 1477 } else { | |
| 1478 FX_DWORD nTables = pFont->m_FontTables.GetLength() / 16; | |
| 1479 for (FX_DWORD i = 0; i < nTables; i ++) { | |
| 1480 const uint8_t* p = (const uint8_t*)pFont->m_FontTables + i * 16; | |
| 1481 if (GET_TT_LONG(p) == table) { | |
| 1482 offset = GET_TT_LONG(p + 8); | |
| 1483 datasize = GET_TT_LONG(p + 12); | |
| 1484 } | |
| 1485 } | |
| 1486 } | |
| 1487 if (datasize && size >= datasize && pFile) { | |
| 1488 FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); | |
| 1489 FXSYS_fread(buffer, datasize, 1, pFile); | |
| 1490 } | |
| 1491 if (pFile) { | |
| 1492 FXSYS_fclose(pFile); | |
| 1493 } | |
| 1494 return datasize; | |
| 1495 } | |
| 1496 void CFX_FolderFontInfo::DeleteFont(void* hFont) | |
| 1497 { | |
| 1498 } | |
| 1499 FX_BOOL CFX_FolderFontInfo::GetFaceName(void* hFont, CFX_ByteString& name) | |
| 1500 { | |
| 1501 if (hFont == NULL) { | |
| 1502 return FALSE; | |
| 1503 } | |
| 1504 CFontFaceInfo* pFont = (CFontFaceInfo*)hFont; | |
| 1505 name = pFont->m_FaceName; | |
| 1506 return TRUE; | |
| 1507 } | |
| 1508 FX_BOOL CFX_FolderFontInfo::GetFontCharset(void* hFont, int& charset) | |
| 1509 { | |
| 1510 return FALSE; | |
| 1511 } | |
| OLD | NEW |