| 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 "../fontdata/chromefontdata/chromefontdata.h" | 11 #include "../fontdata/chromefontdata/chromefontdata.h" |
| 12 #include "text_int.h" | 12 #include "text_int.h" |
| 13 | 13 |
| 14 #define GET_TT_SHORT(w) (FX_WORD)(((w)[0] << 8) | (w)[1]) | 14 #define GET_TT_SHORT(w) (FX_WORD)(((w)[0] << 8) | (w)[1]) |
| 15 #define GET_TT_LONG(w) \ | 15 #define GET_TT_LONG(w) \ |
| 16 (FX_DWORD)(((w)[0] << 24) | ((w)[1] << 16) | ((w)[2] << 8) | (w)[3]) | 16 (FX_DWORD)(((w)[0] << 24) | ((w)[1] << 16) | ((w)[2] << 8) | (w)[3]) |
| 17 | 17 |
| 18 #define FX_FONT_STYLE_None 0x00 |
| 19 #define FX_FONT_STYLE_Bold 0x01 |
| 20 #define FX_FONT_STYLE_Italic 0x02 |
| 21 #define FX_FONT_STYLE_BoldBold 0x04 |
| 22 |
| 18 namespace { | 23 namespace { |
| 19 | 24 |
| 20 struct BuiltinFont { | 25 struct BuiltinFont { |
| 21 const uint8_t* m_pFontData; | 26 const uint8_t* m_pFontData; |
| 22 FX_DWORD m_dwSize; | 27 FX_DWORD m_dwSize; |
| 23 }; | 28 }; |
| 24 | 29 |
| 25 const BuiltinFont g_FoxitFonts[14] = { | 30 const BuiltinFont g_FoxitFonts[14] = { |
| 26 {g_FoxitFixedFontData, 17597}, | 31 {g_FoxitFixedFontData, 17597}, |
| 27 {g_FoxitFixedBoldFontData, 18055}, | 32 {g_FoxitFixedBoldFontData, 18055}, |
| 28 {g_FoxitFixedBoldItalicFontData, 19151}, | 33 {g_FoxitFixedBoldItalicFontData, 19151}, |
| 29 {g_FoxitFixedItalicFontData, 18746}, | 34 {g_FoxitFixedItalicFontData, 18746}, |
| 30 {g_FoxitSansFontData, 15025}, | 35 {g_FoxitSansFontData, 15025}, |
| 31 {g_FoxitSansBoldFontData, 16344}, | 36 {g_FoxitSansBoldFontData, 16344}, |
| 32 {g_FoxitSansBoldItalicFontData, 16418}, | 37 {g_FoxitSansBoldItalicFontData, 16418}, |
| 33 {g_FoxitSansItalicFontData, 16339}, | 38 {g_FoxitSansItalicFontData, 16339}, |
| 34 {g_FoxitSerifFontData, 19469}, | 39 {g_FoxitSerifFontData, 19469}, |
| 35 {g_FoxitSerifBoldFontData, 19395}, | 40 {g_FoxitSerifBoldFontData, 19395}, |
| 36 {g_FoxitSerifBoldItalicFontData, 20733}, | 41 {g_FoxitSerifBoldItalicFontData, 20733}, |
| 37 {g_FoxitSerifItalicFontData, 21227}, | 42 {g_FoxitSerifItalicFontData, 21227}, |
| 38 {g_FoxitSymbolFontData, 16729}, | 43 {g_FoxitSymbolFontData, 16729}, |
| 39 {g_FoxitDingbatsFontData, 29513}, | 44 {g_FoxitDingbatsFontData, 29513}, |
| 40 }; | 45 }; |
| 41 | 46 |
| 42 const BuiltinFont g_MMFonts[2] = { | 47 const BuiltinFont g_MMFonts[2] = { |
| 43 {g_FoxitSerifMMFontData, 113417}, | 48 {g_FoxitSerifMMFontData, 113417}, |
| 44 {g_FoxitSansMMFontData, 66919}, | 49 {g_FoxitSansMMFontData, 66919}, |
| 45 }; | 50 }; |
| 46 | 51 |
| 47 CFX_ByteString KeyNameFromFace(const CFX_ByteString& face_name, | |
| 48 int weight, | |
| 49 FX_BOOL bItalic) { | |
| 50 CFX_ByteString key(face_name); | |
| 51 key += ','; | |
| 52 key += CFX_ByteString::FormatInteger(weight); | |
| 53 key += bItalic ? 'I' : 'N'; | |
| 54 return key; | |
| 55 } | |
| 56 | |
| 57 CFX_ByteString KeyNameFromSize(int ttc_size, FX_DWORD checksum) { | |
| 58 CFX_ByteString key; | |
| 59 key.Format("%d:%d", ttc_size, checksum); | |
| 60 return key; | |
| 61 } | |
| 62 | |
| 63 } // namespace | |
| 64 | |
| 65 CFX_SubstFont::CFX_SubstFont() { | |
| 66 m_ExtHandle = NULL; | |
| 67 m_Charset = 0; | |
| 68 m_SubstFlags = 0; | |
| 69 m_Weight = 0; | |
| 70 m_ItalicAngle = 0; | |
| 71 m_bSubstOfCJK = FALSE; | |
| 72 m_WeightCJK = 0; | |
| 73 m_bItlicCJK = FALSE; | |
| 74 } | |
| 75 CTTFontDesc::~CTTFontDesc() { | |
| 76 if (m_Type == 1) { | |
| 77 if (m_SingleFace.m_pFace) { | |
| 78 FXFT_Done_Face(m_SingleFace.m_pFace); | |
| 79 } | |
| 80 } else if (m_Type == 2) { | |
| 81 for (int i = 0; i < 16; i++) | |
| 82 if (m_TTCFace.m_pFaces[i]) { | |
| 83 FXFT_Done_Face(m_TTCFace.m_pFaces[i]); | |
| 84 } | |
| 85 } | |
| 86 FX_Free(m_pFontData); | |
| 87 } | |
| 88 FX_BOOL CTTFontDesc::ReleaseFace(FXFT_Face face) { | |
| 89 if (m_Type == 1) { | |
| 90 if (m_SingleFace.m_pFace != face) { | |
| 91 return FALSE; | |
| 92 } | |
| 93 } else if (m_Type == 2) { | |
| 94 int i; | |
| 95 for (i = 0; i < 16; i++) | |
| 96 if (m_TTCFace.m_pFaces[i] == face) { | |
| 97 break; | |
| 98 } | |
| 99 if (i == 16) { | |
| 100 return FALSE; | |
| 101 } | |
| 102 } | |
| 103 m_RefCount--; | |
| 104 if (m_RefCount) { | |
| 105 return FALSE; | |
| 106 } | |
| 107 delete this; | |
| 108 return TRUE; | |
| 109 } | |
| 110 | |
| 111 CFX_FontMgr::CFX_FontMgr() : m_FTLibrary(nullptr) { | |
| 112 m_pBuiltinMapper.reset(new CFX_FontMapper(this)); | |
| 113 } | |
| 114 | |
| 115 CFX_FontMgr::~CFX_FontMgr() { | |
| 116 for (const auto& pair : m_FaceMap) | |
| 117 delete pair.second; | |
| 118 | |
| 119 // |m_pBuiltinMapper| references |m_FTLibrary|, so it has to be destroyed | |
| 120 // first. | |
| 121 m_pBuiltinMapper.reset(); | |
| 122 FXFT_Done_FreeType(m_FTLibrary); | |
| 123 } | |
| 124 | |
| 125 void CFX_FontMgr::InitFTLibrary() { | |
| 126 if (m_FTLibrary) | |
| 127 return; | |
| 128 FXFT_Init_FreeType(&m_FTLibrary); | |
| 129 } | |
| 130 | |
| 131 void CFX_FontMgr::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo) { | |
| 132 m_pBuiltinMapper->SetSystemFontInfo(pFontInfo); | |
| 133 } | |
| 134 | |
| 135 FXFT_Face CFX_FontMgr::FindSubstFont(const CFX_ByteString& face_name, | |
| 136 FX_BOOL bTrueType, | |
| 137 FX_DWORD flags, | |
| 138 int weight, | |
| 139 int italic_angle, | |
| 140 int CharsetCP, | |
| 141 CFX_SubstFont* pSubstFont) { | |
| 142 InitFTLibrary(); | |
| 143 return m_pBuiltinMapper->FindSubstFont(face_name, bTrueType, flags, weight, | |
| 144 italic_angle, CharsetCP, pSubstFont); | |
| 145 } | |
| 146 | |
| 147 FXFT_Face CFX_FontMgr::GetCachedFace(const CFX_ByteString& face_name, | |
| 148 int weight, | |
| 149 FX_BOOL bItalic, | |
| 150 uint8_t*& pFontData) { | |
| 151 auto it = m_FaceMap.find(KeyNameFromFace(face_name, weight, bItalic)); | |
| 152 if (it == m_FaceMap.end()) | |
| 153 return nullptr; | |
| 154 | |
| 155 CTTFontDesc* pFontDesc = it->second; | |
| 156 pFontData = pFontDesc->m_pFontData; | |
| 157 pFontDesc->m_RefCount++; | |
| 158 return pFontDesc->m_SingleFace.m_pFace; | |
| 159 } | |
| 160 FXFT_Face CFX_FontMgr::AddCachedFace(const CFX_ByteString& face_name, | |
| 161 int weight, | |
| 162 FX_BOOL bItalic, | |
| 163 uint8_t* pData, | |
| 164 FX_DWORD size, | |
| 165 int face_index) { | |
| 166 CTTFontDesc* pFontDesc = new CTTFontDesc; | |
| 167 pFontDesc->m_Type = 1; | |
| 168 pFontDesc->m_SingleFace.m_pFace = NULL; | |
| 169 pFontDesc->m_SingleFace.m_bBold = weight; | |
| 170 pFontDesc->m_SingleFace.m_bItalic = bItalic; | |
| 171 pFontDesc->m_pFontData = pData; | |
| 172 pFontDesc->m_RefCount = 1; | |
| 173 | |
| 174 InitFTLibrary(); | |
| 175 FXFT_Library library = m_FTLibrary; | |
| 176 int ret = FXFT_New_Memory_Face(library, pData, size, face_index, | |
| 177 &pFontDesc->m_SingleFace.m_pFace); | |
| 178 if (ret) { | |
| 179 delete pFontDesc; | |
| 180 return NULL; | |
| 181 } | |
| 182 ret = FXFT_Set_Pixel_Sizes(pFontDesc->m_SingleFace.m_pFace, 64, 64); | |
| 183 if (ret) { | |
| 184 delete pFontDesc; | |
| 185 return NULL; | |
| 186 } | |
| 187 m_FaceMap[KeyNameFromFace(face_name, weight, bItalic)] = pFontDesc; | |
| 188 return pFontDesc->m_SingleFace.m_pFace; | |
| 189 } | |
| 190 const FX_CHAR* const g_Base14FontNames[14] = { | 52 const FX_CHAR* const g_Base14FontNames[14] = { |
| 191 "Courier", | 53 "Courier", |
| 192 "Courier-Bold", | 54 "Courier-Bold", |
| 193 "Courier-BoldOblique", | 55 "Courier-BoldOblique", |
| 194 "Courier-Oblique", | 56 "Courier-Oblique", |
| 195 "Helvetica", | 57 "Helvetica", |
| 196 "Helvetica-Bold", | 58 "Helvetica-Bold", |
| 197 "Helvetica-BoldOblique", | 59 "Helvetica-BoldOblique", |
| 198 "Helvetica-Oblique", | 60 "Helvetica-Oblique", |
| 199 "Times-Roman", | 61 "Times-Roman", |
| 200 "Times-Bold", | 62 "Times-Bold", |
| 201 "Times-BoldItalic", | 63 "Times-BoldItalic", |
| 202 "Times-Italic", | 64 "Times-Italic", |
| 203 "Symbol", | 65 "Symbol", |
| 204 "ZapfDingbats", | 66 "ZapfDingbats", |
| 205 }; | 67 }; |
| 68 |
| 206 const struct AltFontName { | 69 const struct AltFontName { |
| 207 const FX_CHAR* m_pName; | 70 const FX_CHAR* m_pName; |
| 208 int m_Index; | 71 int m_Index; |
| 209 } g_AltFontNames[] = { | 72 } g_AltFontNames[] = { |
| 210 {"Arial", 4}, | 73 {"Arial", 4}, |
| 211 {"Arial,Bold", 5}, | 74 {"Arial,Bold", 5}, |
| 212 {"Arial,BoldItalic", 6}, | 75 {"Arial,BoldItalic", 6}, |
| 213 {"Arial,Italic", 7}, | 76 {"Arial,Italic", 7}, |
| 214 {"Arial-Bold", 5}, | 77 {"Arial-Bold", 5}, |
| 215 {"Arial-BoldItalic", 6}, | 78 {"Arial-BoldItalic", 6}, |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 {"TimesNewRomanPS-BoldItalicMT", 10}, | 153 {"TimesNewRomanPS-BoldItalicMT", 10}, |
| 291 {"TimesNewRomanPS-BoldMT", 9}, | 154 {"TimesNewRomanPS-BoldMT", 9}, |
| 292 {"TimesNewRomanPS-Italic", 11}, | 155 {"TimesNewRomanPS-Italic", 11}, |
| 293 {"TimesNewRomanPS-ItalicMT", 11}, | 156 {"TimesNewRomanPS-ItalicMT", 11}, |
| 294 {"TimesNewRomanPSMT", 8}, | 157 {"TimesNewRomanPSMT", 8}, |
| 295 {"TimesNewRomanPSMT,Bold", 9}, | 158 {"TimesNewRomanPSMT,Bold", 9}, |
| 296 {"TimesNewRomanPSMT,BoldItalic", 10}, | 159 {"TimesNewRomanPSMT,BoldItalic", 10}, |
| 297 {"TimesNewRomanPSMT,Italic", 11}, | 160 {"TimesNewRomanPSMT,Italic", 11}, |
| 298 {"ZapfDingbats", 13}, | 161 {"ZapfDingbats", 13}, |
| 299 }; | 162 }; |
| 300 extern "C" { | 163 |
| 301 static int compareString(const void* key, const void* element) { | 164 const struct { |
| 165 const FX_CHAR* m_pName; |
| 166 const FX_CHAR* m_pSubstName; |
| 167 } Base14Substs[] = { |
| 168 {"Courier", "Courier New"}, |
| 169 {"Courier-Bold", "Courier New Bold"}, |
| 170 {"Courier-BoldOblique", "Courier New Bold Italic"}, |
| 171 {"Courier-Oblique", "Courier New Italic"}, |
| 172 {"Helvetica", "Arial"}, |
| 173 {"Helvetica-Bold", "Arial Bold"}, |
| 174 {"Helvetica-BoldOblique", "Arial Bold Italic"}, |
| 175 {"Helvetica-Oblique", "Arial Italic"}, |
| 176 {"Times-Roman", "Times New Roman"}, |
| 177 {"Times-Bold", "Times New Roman Bold"}, |
| 178 {"Times-BoldItalic", "Times New Roman Bold Italic"}, |
| 179 {"Times-Italic", "Times New Roman Italic"}, |
| 180 }; |
| 181 |
| 182 const struct AltFontFamily { |
| 183 const FX_CHAR* m_pFontName; |
| 184 const FX_CHAR* m_pFontFamily; |
| 185 } g_AltFontFamilies[] = { |
| 186 {"AGaramondPro", "Adobe Garamond Pro"}, |
| 187 {"BankGothicBT-Medium", "BankGothic Md BT"}, |
| 188 {"ForteMT", "Forte"}, |
| 189 }; |
| 190 |
| 191 const struct FX_FontStyle { |
| 192 const FX_CHAR* style; |
| 193 int32_t len; |
| 194 } g_FontStyles[] = { |
| 195 {"Bold", 4}, {"Italic", 6}, {"BoldItalic", 10}, {"Reg", 3}, {"Regular", 7}, |
| 196 }; |
| 197 |
| 198 const struct CHARSET_MAP { |
| 199 uint8_t charset; |
| 200 FX_WORD codepage; |
| 201 } g_Codepage2CharsetTable[] = { |
| 202 {1, 0}, {2, 42}, {254, 437}, {255, 850}, {222, 874}, |
| 203 {128, 932}, {134, 936}, {129, 949}, {136, 950}, {238, 1250}, |
| 204 {204, 1251}, {0, 1252}, {161, 1253}, {162, 1254}, {177, 1255}, |
| 205 {178, 1256}, {186, 1257}, {163, 1258}, {130, 1361}, {77, 10000}, |
| 206 {78, 10001}, {79, 10003}, {80, 10008}, {81, 10002}, {83, 10005}, |
| 207 {84, 10004}, {85, 10006}, {86, 10081}, {87, 10021}, {88, 10029}, |
| 208 {89, 10007}, |
| 209 }; |
| 210 |
| 211 int CompareFontFamilyString(const void* key, const void* element) { |
| 212 CFX_ByteString str_key((const FX_CHAR*)key); |
| 213 if (str_key.Find(((AltFontFamily*)element)->m_pFontName) != -1) { |
| 214 return 0; |
| 215 } |
| 216 return FXSYS_stricmp((const FX_CHAR*)key, |
| 217 ((AltFontFamily*)element)->m_pFontName); |
| 218 } |
| 219 |
| 220 int CompareString(const void* key, const void* element) { |
| 302 return FXSYS_stricmp((const FX_CHAR*)key, ((AltFontName*)element)->m_pName); | 221 return FXSYS_stricmp((const FX_CHAR*)key, ((AltFontName*)element)->m_pName); |
| 303 } | 222 } |
| 223 |
| 224 CFX_ByteString KeyNameFromFace(const CFX_ByteString& face_name, |
| 225 int weight, |
| 226 FX_BOOL bItalic) { |
| 227 CFX_ByteString key(face_name); |
| 228 key += ','; |
| 229 key += CFX_ByteString::FormatInteger(weight); |
| 230 key += bItalic ? 'I' : 'N'; |
| 231 return key; |
| 232 } |
| 233 |
| 234 CFX_ByteString KeyNameFromSize(int ttc_size, FX_DWORD checksum) { |
| 235 CFX_ByteString key; |
| 236 key.Format("%d:%d", ttc_size, checksum); |
| 237 return key; |
| 238 } |
| 239 |
| 240 CFX_ByteString TT_NormalizeName(const FX_CHAR* family) { |
| 241 CFX_ByteString norm(family); |
| 242 norm.Remove(' '); |
| 243 norm.Remove('-'); |
| 244 norm.Remove(','); |
| 245 int pos = norm.Find('+'); |
| 246 if (pos > 0) { |
| 247 norm = norm.Left(pos); |
| 248 } |
| 249 norm.MakeLower(); |
| 250 return norm; |
| 251 } |
| 252 |
| 253 CFX_ByteString FPDF_ReadStringFromFile(FXSYS_FILE* pFile, FX_DWORD size) { |
| 254 CFX_ByteString buffer; |
| 255 if (!FXSYS_fread(buffer.GetBuffer(size), size, 1, pFile)) { |
| 256 return CFX_ByteString(); |
| 257 } |
| 258 buffer.ReleaseBuffer(size); |
| 259 return buffer; |
| 260 } |
| 261 |
| 262 CFX_ByteString FPDF_LoadTableFromTT(FXSYS_FILE* pFile, |
| 263 const uint8_t* pTables, |
| 264 FX_DWORD nTables, |
| 265 FX_DWORD tag) { |
| 266 for (FX_DWORD i = 0; i < nTables; i++) { |
| 267 const uint8_t* p = pTables + i * 16; |
| 268 if (GET_TT_LONG(p) == tag) { |
| 269 FX_DWORD offset = GET_TT_LONG(p + 8); |
| 270 FX_DWORD size = GET_TT_LONG(p + 12); |
| 271 FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); |
| 272 return FPDF_ReadStringFromFile(pFile, size); |
| 273 } |
| 274 } |
| 275 return CFX_ByteString(); |
| 276 } |
| 277 |
| 278 uint8_t GetCharsetFromCodePage(FX_WORD codepage) { |
| 279 int32_t iEnd = sizeof(g_Codepage2CharsetTable) / sizeof(CHARSET_MAP) - 1; |
| 280 FXSYS_assert(iEnd >= 0); |
| 281 int32_t iStart = 0, iMid; |
| 282 do { |
| 283 iMid = (iStart + iEnd) / 2; |
| 284 const CHARSET_MAP& cp = g_Codepage2CharsetTable[iMid]; |
| 285 if (codepage == cp.codepage) { |
| 286 return cp.charset; |
| 287 } |
| 288 if (codepage < cp.codepage) { |
| 289 iEnd = iMid - 1; |
| 290 } else { |
| 291 iStart = iMid + 1; |
| 292 } |
| 293 } while (iStart <= iEnd); |
| 294 return 1; |
| 295 } |
| 296 |
| 297 CFX_ByteString GetFontFamily(CFX_ByteString fontName, int nStyle) { |
| 298 if (fontName.Find("Script") >= 0) { |
| 299 if ((nStyle & FX_FONT_STYLE_Bold) == FX_FONT_STYLE_Bold) { |
| 300 fontName = "ScriptMTBold"; |
| 301 } else if (fontName.Find("Palace") >= 0) { |
| 302 fontName = "PalaceScriptMT"; |
| 303 } else if (fontName.Find("French") >= 0) { |
| 304 fontName = "FrenchScriptMT"; |
| 305 } else if (fontName.Find("FreeStyle") >= 0) { |
| 306 fontName = "FreeStyleScript"; |
| 307 } |
| 308 return fontName; |
| 309 } |
| 310 AltFontFamily* found = (AltFontFamily*)FXSYS_bsearch( |
| 311 fontName.c_str(), g_AltFontFamilies, |
| 312 sizeof g_AltFontFamilies / sizeof(AltFontFamily), sizeof(AltFontFamily), |
| 313 CompareFontFamilyString); |
| 314 if (found == NULL) { |
| 315 return fontName; |
| 316 } |
| 317 return found->m_pFontFamily; |
| 318 } |
| 319 |
| 320 CFX_ByteString ParseStyle(const FX_CHAR* pStyle, int iLen, int iIndex) { |
| 321 CFX_ByteTextBuf buf; |
| 322 if (!iLen || iLen <= iIndex) { |
| 323 return buf.GetByteString(); |
| 324 } |
| 325 while (iIndex < iLen) { |
| 326 if (pStyle[iIndex] == ',') { |
| 327 break; |
| 328 } |
| 329 buf.AppendChar(pStyle[iIndex]); |
| 330 ++iIndex; |
| 331 } |
| 332 return buf.GetByteString(); |
| 333 } |
| 334 |
| 335 int32_t GetStyleType(const CFX_ByteString& bsStyle, FX_BOOL bRevert) { |
| 336 int32_t iLen = bsStyle.GetLength(); |
| 337 if (!iLen) { |
| 338 return -1; |
| 339 } |
| 340 int iSize = sizeof(g_FontStyles) / sizeof(FX_FontStyle); |
| 341 const FX_FontStyle* pStyle = NULL; |
| 342 for (int i = iSize - 1; i >= 0; --i) { |
| 343 pStyle = g_FontStyles + i; |
| 344 if (!pStyle || pStyle->len > iLen) { |
| 345 continue; |
| 346 } |
| 347 if (!bRevert) { |
| 348 if (bsStyle.Left(pStyle->len).Compare(pStyle->style) == 0) { |
| 349 return i; |
| 350 } |
| 351 } else { |
| 352 if (bsStyle.Right(pStyle->len).Compare(pStyle->style) == 0) { |
| 353 return i; |
| 354 } |
| 355 } |
| 356 } |
| 357 return -1; |
| 358 } |
| 359 |
| 360 FX_BOOL CheckSupportThirdPartFont(CFX_ByteString name, int& PitchFamily) { |
| 361 if (name == FX_BSTRC("MyriadPro")) { |
| 362 PitchFamily &= ~FXFONT_FF_ROMAN; |
| 363 return TRUE; |
| 364 } |
| 365 return FALSE; |
| 366 } |
| 367 |
| 368 FX_DWORD GetCharset(int charset) { |
| 369 switch (charset) { |
| 370 case FXFONT_SHIFTJIS_CHARSET: |
| 371 return CHARSET_FLAG_SHIFTJIS; |
| 372 case FXFONT_GB2312_CHARSET: |
| 373 return CHARSET_FLAG_GB; |
| 374 case FXFONT_CHINESEBIG5_CHARSET: |
| 375 return CHARSET_FLAG_BIG5; |
| 376 case FXFONT_HANGEUL_CHARSET: |
| 377 return CHARSET_FLAG_KOREAN; |
| 378 case FXFONT_SYMBOL_CHARSET: |
| 379 return CHARSET_FLAG_SYMBOL; |
| 380 case FXFONT_ANSI_CHARSET: |
| 381 return CHARSET_FLAG_ANSI; |
| 382 default: |
| 383 break; |
| 384 } |
| 385 return 0; |
| 386 } |
| 387 |
| 388 int32_t GetSimilarValue(int weight, |
| 389 FX_BOOL bItalic, |
| 390 int pitch_family, |
| 391 FX_DWORD style) { |
| 392 int32_t iSimilarValue = 0; |
| 393 if ((style & FXFONT_BOLD) == (weight > 400)) { |
| 394 iSimilarValue += 16; |
| 395 } |
| 396 if ((style & FXFONT_ITALIC) == bItalic) { |
| 397 iSimilarValue += 16; |
| 398 } |
| 399 if ((style & FXFONT_SERIF) == (pitch_family & FXFONT_FF_ROMAN)) { |
| 400 iSimilarValue += 16; |
| 401 } |
| 402 if ((style & FXFONT_SCRIPT) == (pitch_family & FXFONT_FF_SCRIPT)) { |
| 403 iSimilarValue += 8; |
| 404 } |
| 405 if ((style & FXFONT_FIXED_PITCH) == (pitch_family & FXFONT_FF_FIXEDPITCH)) { |
| 406 iSimilarValue += 8; |
| 407 } |
| 408 return iSimilarValue; |
| 409 } |
| 410 |
| 411 } // namespace |
| 412 |
| 413 CFX_SubstFont::CFX_SubstFont() { |
| 414 m_ExtHandle = NULL; |
| 415 m_Charset = 0; |
| 416 m_SubstFlags = 0; |
| 417 m_Weight = 0; |
| 418 m_ItalicAngle = 0; |
| 419 m_bSubstOfCJK = FALSE; |
| 420 m_WeightCJK = 0; |
| 421 m_bItlicCJK = FALSE; |
| 422 } |
| 423 CTTFontDesc::~CTTFontDesc() { |
| 424 if (m_Type == 1) { |
| 425 if (m_SingleFace.m_pFace) { |
| 426 FXFT_Done_Face(m_SingleFace.m_pFace); |
| 427 } |
| 428 } else if (m_Type == 2) { |
| 429 for (int i = 0; i < 16; i++) |
| 430 if (m_TTCFace.m_pFaces[i]) { |
| 431 FXFT_Done_Face(m_TTCFace.m_pFaces[i]); |
| 432 } |
| 433 } |
| 434 FX_Free(m_pFontData); |
| 435 } |
| 436 FX_BOOL CTTFontDesc::ReleaseFace(FXFT_Face face) { |
| 437 if (m_Type == 1) { |
| 438 if (m_SingleFace.m_pFace != face) { |
| 439 return FALSE; |
| 440 } |
| 441 } else if (m_Type == 2) { |
| 442 int i; |
| 443 for (i = 0; i < 16; i++) |
| 444 if (m_TTCFace.m_pFaces[i] == face) { |
| 445 break; |
| 446 } |
| 447 if (i == 16) { |
| 448 return FALSE; |
| 449 } |
| 450 } |
| 451 m_RefCount--; |
| 452 if (m_RefCount) { |
| 453 return FALSE; |
| 454 } |
| 455 delete this; |
| 456 return TRUE; |
| 457 } |
| 458 |
| 459 CFX_FontMgr::CFX_FontMgr() : m_FTLibrary(nullptr) { |
| 460 m_pBuiltinMapper.reset(new CFX_FontMapper(this)); |
| 461 } |
| 462 |
| 463 CFX_FontMgr::~CFX_FontMgr() { |
| 464 for (const auto& pair : m_FaceMap) |
| 465 delete pair.second; |
| 466 |
| 467 // |m_pBuiltinMapper| references |m_FTLibrary|, so it has to be destroyed |
| 468 // first. |
| 469 m_pBuiltinMapper.reset(); |
| 470 FXFT_Done_FreeType(m_FTLibrary); |
| 471 } |
| 472 |
| 473 void CFX_FontMgr::InitFTLibrary() { |
| 474 if (m_FTLibrary) |
| 475 return; |
| 476 FXFT_Init_FreeType(&m_FTLibrary); |
| 477 } |
| 478 |
| 479 void CFX_FontMgr::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo) { |
| 480 m_pBuiltinMapper->SetSystemFontInfo(pFontInfo); |
| 481 } |
| 482 |
| 483 FXFT_Face CFX_FontMgr::FindSubstFont(const CFX_ByteString& face_name, |
| 484 FX_BOOL bTrueType, |
| 485 FX_DWORD flags, |
| 486 int weight, |
| 487 int italic_angle, |
| 488 int CharsetCP, |
| 489 CFX_SubstFont* pSubstFont) { |
| 490 InitFTLibrary(); |
| 491 return m_pBuiltinMapper->FindSubstFont(face_name, bTrueType, flags, weight, |
| 492 italic_angle, CharsetCP, pSubstFont); |
| 493 } |
| 494 |
| 495 FXFT_Face CFX_FontMgr::GetCachedFace(const CFX_ByteString& face_name, |
| 496 int weight, |
| 497 FX_BOOL bItalic, |
| 498 uint8_t*& pFontData) { |
| 499 auto it = m_FaceMap.find(KeyNameFromFace(face_name, weight, bItalic)); |
| 500 if (it == m_FaceMap.end()) |
| 501 return nullptr; |
| 502 |
| 503 CTTFontDesc* pFontDesc = it->second; |
| 504 pFontData = pFontDesc->m_pFontData; |
| 505 pFontDesc->m_RefCount++; |
| 506 return pFontDesc->m_SingleFace.m_pFace; |
| 507 } |
| 508 FXFT_Face CFX_FontMgr::AddCachedFace(const CFX_ByteString& face_name, |
| 509 int weight, |
| 510 FX_BOOL bItalic, |
| 511 uint8_t* pData, |
| 512 FX_DWORD size, |
| 513 int face_index) { |
| 514 CTTFontDesc* pFontDesc = new CTTFontDesc; |
| 515 pFontDesc->m_Type = 1; |
| 516 pFontDesc->m_SingleFace.m_pFace = NULL; |
| 517 pFontDesc->m_SingleFace.m_bBold = weight; |
| 518 pFontDesc->m_SingleFace.m_bItalic = bItalic; |
| 519 pFontDesc->m_pFontData = pData; |
| 520 pFontDesc->m_RefCount = 1; |
| 521 |
| 522 InitFTLibrary(); |
| 523 FXFT_Library library = m_FTLibrary; |
| 524 int ret = FXFT_New_Memory_Face(library, pData, size, face_index, |
| 525 &pFontDesc->m_SingleFace.m_pFace); |
| 526 if (ret) { |
| 527 delete pFontDesc; |
| 528 return NULL; |
| 529 } |
| 530 ret = FXFT_Set_Pixel_Sizes(pFontDesc->m_SingleFace.m_pFace, 64, 64); |
| 531 if (ret) { |
| 532 delete pFontDesc; |
| 533 return NULL; |
| 534 } |
| 535 m_FaceMap[KeyNameFromFace(face_name, weight, bItalic)] = pFontDesc; |
| 536 return pFontDesc->m_SingleFace.m_pFace; |
| 304 } | 537 } |
| 305 | 538 |
| 306 int GetTTCIndex(const uint8_t* pFontData, | 539 int GetTTCIndex(const uint8_t* pFontData, |
| 307 FX_DWORD ttc_size, | 540 FX_DWORD ttc_size, |
| 308 FX_DWORD font_offset) { | 541 FX_DWORD font_offset) { |
| 309 int face_index = 0; | 542 int face_index = 0; |
| 310 const uint8_t* p = pFontData + 8; | 543 const uint8_t* p = pFontData + 8; |
| 311 FX_DWORD nfont = GET_TT_LONG(p); | 544 FX_DWORD nfont = GET_TT_LONG(p); |
| 312 FX_DWORD index; | 545 FX_DWORD index; |
| 313 for (index = 0; index < nfont; index++) { | 546 for (index = 0; index < nfont; index++) { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 } | 669 } |
| 437 void CFX_FontMapper::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo) { | 670 void CFX_FontMapper::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo) { |
| 438 if (pFontInfo == NULL) { | 671 if (pFontInfo == NULL) { |
| 439 return; | 672 return; |
| 440 } | 673 } |
| 441 if (m_pFontInfo) { | 674 if (m_pFontInfo) { |
| 442 m_pFontInfo->Release(); | 675 m_pFontInfo->Release(); |
| 443 } | 676 } |
| 444 m_pFontInfo = pFontInfo; | 677 m_pFontInfo = pFontInfo; |
| 445 } | 678 } |
| 446 static CFX_ByteString _TT_NormalizeName(const FX_CHAR* family) { | 679 |
| 447 CFX_ByteString norm(family); | |
| 448 norm.Remove(' '); | |
| 449 norm.Remove('-'); | |
| 450 norm.Remove(','); | |
| 451 int pos = norm.Find('+'); | |
| 452 if (pos > 0) { | |
| 453 norm = norm.Left(pos); | |
| 454 } | |
| 455 norm.MakeLower(); | |
| 456 return norm; | |
| 457 } | |
| 458 CFX_ByteString GetNameFromTT(const uint8_t* name_table, FX_DWORD name_id) { | 680 CFX_ByteString GetNameFromTT(const uint8_t* name_table, FX_DWORD name_id) { |
| 459 const uint8_t* ptr = name_table + 2; | 681 const uint8_t* ptr = name_table + 2; |
| 460 int name_count = GET_TT_SHORT(ptr); | 682 int name_count = GET_TT_SHORT(ptr); |
| 461 int string_offset = GET_TT_SHORT(ptr + 2); | 683 int string_offset = GET_TT_SHORT(ptr + 2); |
| 462 const uint8_t* string_ptr = name_table + string_offset; | 684 const uint8_t* string_ptr = name_table + string_offset; |
| 463 ptr += 4; | 685 ptr += 4; |
| 464 for (int i = 0; i < name_count; i++) { | 686 for (int i = 0; i < name_count; i++) { |
| 465 if (GET_TT_SHORT(ptr + 6) == name_id && GET_TT_SHORT(ptr) == 1 && | 687 if (GET_TT_SHORT(ptr + 6) == name_id && GET_TT_SHORT(ptr) == 1 && |
| 466 GET_TT_SHORT(ptr + 2) == 0) { | 688 GET_TT_SHORT(ptr + 2) == 0) { |
| 467 return CFX_ByteStringC(string_ptr + GET_TT_SHORT(ptr + 10), | 689 return CFX_ByteStringC(string_ptr + GET_TT_SHORT(ptr + 10), |
| 468 GET_TT_SHORT(ptr + 8)); | 690 GET_TT_SHORT(ptr + 8)); |
| 469 } | 691 } |
| 470 ptr += 12; | 692 ptr += 12; |
| 471 } | 693 } |
| 472 return CFX_ByteString(); | 694 return CFX_ByteString(); |
| 473 } | 695 } |
| 474 static CFX_ByteString _FPDF_ReadStringFromFile(FXSYS_FILE* pFile, | 696 |
| 475 FX_DWORD size) { | |
| 476 CFX_ByteString buffer; | |
| 477 if (!FXSYS_fread(buffer.GetBuffer(size), size, 1, pFile)) { | |
| 478 return CFX_ByteString(); | |
| 479 } | |
| 480 buffer.ReleaseBuffer(size); | |
| 481 return buffer; | |
| 482 } | |
| 483 CFX_ByteString _FPDF_LoadTableFromTT(FXSYS_FILE* pFile, | |
| 484 const uint8_t* pTables, | |
| 485 FX_DWORD nTables, | |
| 486 FX_DWORD tag) { | |
| 487 for (FX_DWORD i = 0; i < nTables; i++) { | |
| 488 const uint8_t* p = pTables + i * 16; | |
| 489 if (GET_TT_LONG(p) == tag) { | |
| 490 FX_DWORD offset = GET_TT_LONG(p + 8); | |
| 491 FX_DWORD size = GET_TT_LONG(p + 12); | |
| 492 FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); | |
| 493 return _FPDF_ReadStringFromFile(pFile, size); | |
| 494 } | |
| 495 } | |
| 496 return CFX_ByteString(); | |
| 497 } | |
| 498 CFX_ByteString _FPDF_LoadTableFromTTStreamFile(IFX_FileStream* pFile, | |
| 499 const uint8_t* pTables, | |
| 500 FX_DWORD nTables, | |
| 501 FX_DWORD tag) { | |
| 502 for (FX_DWORD i = 0; i < nTables; i++) { | |
| 503 const uint8_t* p = pTables + i * 16; | |
| 504 if (GET_TT_LONG(p) == tag) { | |
| 505 FX_DWORD offset = GET_TT_LONG(p + 8); | |
| 506 FX_DWORD size = GET_TT_LONG(p + 12); | |
| 507 CFX_ByteString buffer; | |
| 508 if (!pFile->ReadBlock(buffer.GetBuffer(size), offset, size)) { | |
| 509 return CFX_ByteString(); | |
| 510 } | |
| 511 buffer.ReleaseBuffer(size); | |
| 512 return buffer; | |
| 513 } | |
| 514 } | |
| 515 return CFX_ByteString(); | |
| 516 } | |
| 517 CFX_ByteString CFX_FontMapper::GetPSNameFromTT(void* hFont) { | 697 CFX_ByteString CFX_FontMapper::GetPSNameFromTT(void* hFont) { |
| 518 if (m_pFontInfo == NULL) { | 698 if (m_pFontInfo == NULL) { |
| 519 return CFX_ByteString(); | 699 return CFX_ByteString(); |
| 520 } | 700 } |
| 521 CFX_ByteString result; | 701 CFX_ByteString result; |
| 522 FX_DWORD size = m_pFontInfo->GetFontData(hFont, 0x6e616d65, NULL, 0); | 702 FX_DWORD size = m_pFontInfo->GetFontData(hFont, 0x6e616d65, NULL, 0); |
| 523 if (size) { | 703 if (size) { |
| 524 uint8_t* buffer = FX_Alloc(uint8_t, size); | 704 uint8_t* buffer = FX_Alloc(uint8_t, size); |
| 525 m_pFontInfo->GetFontData(hFont, 0x6e616d65, buffer, size); | 705 m_pFontInfo->GetFontData(hFont, 0x6e616d65, buffer, size); |
| 526 result = GetNameFromTT(buffer, 6); | 706 result = GetNameFromTT(buffer, 6); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 return; | 757 return; |
| 578 } | 758 } |
| 579 m_pFontInfo->EnumFontList(this); | 759 m_pFontInfo->EnumFontList(this); |
| 580 m_bListLoaded = TRUE; | 760 m_bListLoaded = TRUE; |
| 581 } | 761 } |
| 582 CFX_ByteString CFX_FontMapper::MatchInstalledFonts( | 762 CFX_ByteString CFX_FontMapper::MatchInstalledFonts( |
| 583 const CFX_ByteString& norm_name) { | 763 const CFX_ByteString& norm_name) { |
| 584 LoadInstalledFonts(); | 764 LoadInstalledFonts(); |
| 585 int i; | 765 int i; |
| 586 for (i = m_InstalledTTFonts.GetSize() - 1; i >= 0; i--) { | 766 for (i = m_InstalledTTFonts.GetSize() - 1; i >= 0; i--) { |
| 587 CFX_ByteString norm1 = _TT_NormalizeName(m_InstalledTTFonts[i]); | 767 CFX_ByteString norm1 = TT_NormalizeName(m_InstalledTTFonts[i]); |
| 588 if (norm1 == norm_name) { | 768 if (norm1 == norm_name) { |
| 589 break; | 769 break; |
| 590 } | 770 } |
| 591 } | 771 } |
| 592 if (i < 0) { | 772 if (i < 0) { |
| 593 return CFX_ByteString(); | 773 return CFX_ByteString(); |
| 594 } | 774 } |
| 595 CFX_ByteString match = m_InstalledTTFonts[i]; | 775 CFX_ByteString match = m_InstalledTTFonts[i]; |
| 596 if (match[0] == ' ') { | 776 if (match[0] == ' ') { |
| 597 match = m_InstalledTTFonts[i + 1]; | 777 match = m_InstalledTTFonts[i + 1]; |
| 598 } | 778 } |
| 599 return match; | 779 return match; |
| 600 } | 780 } |
| 601 typedef struct _CHARSET_MAP_ { | 781 |
| 602 uint8_t charset; | |
| 603 FX_WORD codepage; | |
| 604 } CHARSET_MAP; | |
| 605 static const CHARSET_MAP g_Codepage2CharsetTable[] = { | |
| 606 {1, 0}, {2, 42}, {254, 437}, {255, 850}, {222, 874}, | |
| 607 {128, 932}, {134, 936}, {129, 949}, {136, 950}, {238, 1250}, | |
| 608 {204, 1251}, {0, 1252}, {161, 1253}, {162, 1254}, {177, 1255}, | |
| 609 {178, 1256}, {186, 1257}, {163, 1258}, {130, 1361}, {77, 10000}, | |
| 610 {78, 10001}, {79, 10003}, {80, 10008}, {81, 10002}, {83, 10005}, | |
| 611 {84, 10004}, {85, 10006}, {86, 10081}, {87, 10021}, {88, 10029}, | |
| 612 {89, 10007}, | |
| 613 }; | |
| 614 uint8_t _GetCharsetFromCodePage(FX_WORD codepage) { | |
| 615 int32_t iEnd = sizeof(g_Codepage2CharsetTable) / sizeof(CHARSET_MAP) - 1; | |
| 616 FXSYS_assert(iEnd >= 0); | |
| 617 int32_t iStart = 0, iMid; | |
| 618 do { | |
| 619 iMid = (iStart + iEnd) / 2; | |
| 620 const CHARSET_MAP& cp = g_Codepage2CharsetTable[iMid]; | |
| 621 if (codepage == cp.codepage) { | |
| 622 return cp.charset; | |
| 623 } | |
| 624 if (codepage < cp.codepage) { | |
| 625 iEnd = iMid - 1; | |
| 626 } else { | |
| 627 iStart = iMid + 1; | |
| 628 } | |
| 629 } while (iStart <= iEnd); | |
| 630 return 1; | |
| 631 } | |
| 632 FX_DWORD _GetCodePageRangeFromCharset(int charset) { | |
| 633 if (charset == FXFONT_EASTEUROPE_CHARSET) { | |
| 634 return 1 << 1; | |
| 635 } | |
| 636 if (charset == FXFONT_GREEK_CHARSET) { | |
| 637 return 1 << 3; | |
| 638 } | |
| 639 if (charset == FXFONT_TURKISH_CHARSET) { | |
| 640 return 1 << 4; | |
| 641 } | |
| 642 if (charset == FXFONT_HEBREW_CHARSET) { | |
| 643 return 1 << 5; | |
| 644 } | |
| 645 if (charset == FXFONT_ARABIC_CHARSET) { | |
| 646 return 1 << 6; | |
| 647 } | |
| 648 if (charset == FXFONT_BALTIC_CHARSET) { | |
| 649 return 1 << 7; | |
| 650 } | |
| 651 if (charset == FXFONT_THAI_CHARSET) { | |
| 652 return 1 << 16; | |
| 653 } | |
| 654 if (charset == FXFONT_SHIFTJIS_CHARSET) { | |
| 655 return 1 << 17; | |
| 656 } | |
| 657 if (charset == FXFONT_GB2312_CHARSET) { | |
| 658 return 1 << 18; | |
| 659 } | |
| 660 if (charset == FXFONT_CHINESEBIG5_CHARSET) { | |
| 661 return 1 << 20; | |
| 662 } | |
| 663 if (charset == FXFONT_HANGEUL_CHARSET) { | |
| 664 return 1 << 19; | |
| 665 } | |
| 666 if (charset == FXFONT_SYMBOL_CHARSET) { | |
| 667 return 1 << 31; | |
| 668 } | |
| 669 return 1 << 21; | |
| 670 } | |
| 671 FXFT_Face CFX_FontMapper::UseInternalSubst(CFX_SubstFont* pSubstFont, | 782 FXFT_Face CFX_FontMapper::UseInternalSubst(CFX_SubstFont* pSubstFont, |
| 672 int iBaseFont, | 783 int iBaseFont, |
| 673 int italic_angle, | 784 int italic_angle, |
| 674 int weight, | 785 int weight, |
| 675 int picthfamily) { | 786 int picthfamily) { |
| 676 if (iBaseFont < 12) { | 787 if (iBaseFont < 12) { |
| 677 if (m_FoxitFaces[iBaseFont]) { | 788 if (m_FoxitFaces[iBaseFont]) { |
| 678 return m_FoxitFaces[iBaseFont]; | 789 return m_FoxitFaces[iBaseFont]; |
| 679 } | 790 } |
| 680 const uint8_t* pFontData = NULL; | 791 const uint8_t* pFontData = NULL; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 704 pSubstFont->m_Family = "Chrome Sans"; | 815 pSubstFont->m_Family = "Chrome Sans"; |
| 705 if (m_MMFaces[0]) { | 816 if (m_MMFaces[0]) { |
| 706 return m_MMFaces[0]; | 817 return m_MMFaces[0]; |
| 707 } | 818 } |
| 708 const uint8_t* pFontData = NULL; | 819 const uint8_t* pFontData = NULL; |
| 709 FX_DWORD size = 0; | 820 FX_DWORD size = 0; |
| 710 m_pFontMgr->GetBuiltinFont(15, &pFontData, &size); | 821 m_pFontMgr->GetBuiltinFont(15, &pFontData, &size); |
| 711 m_MMFaces[0] = m_pFontMgr->GetFixedFace(pFontData, size, 0); | 822 m_MMFaces[0] = m_pFontMgr->GetFixedFace(pFontData, size, 0); |
| 712 return m_MMFaces[0]; | 823 return m_MMFaces[0]; |
| 713 } | 824 } |
| 714 const struct _AltFontFamily { | 825 |
| 715 const FX_CHAR* m_pFontName; | |
| 716 const FX_CHAR* m_pFontFamily; | |
| 717 } g_AltFontFamilies[] = { | |
| 718 {"AGaramondPro", "Adobe Garamond Pro"}, | |
| 719 {"BankGothicBT-Medium", "BankGothic Md BT"}, | |
| 720 {"ForteMT", "Forte"}, | |
| 721 }; | |
| 722 extern "C" { | |
| 723 static int compareFontFamilyString(const void* key, const void* element) { | |
| 724 CFX_ByteString str_key((const FX_CHAR*)key); | |
| 725 if (str_key.Find(((_AltFontFamily*)element)->m_pFontName) != -1) { | |
| 726 return 0; | |
| 727 } | |
| 728 return FXSYS_stricmp((const FX_CHAR*)key, | |
| 729 ((_AltFontFamily*)element)->m_pFontName); | |
| 730 } | |
| 731 } | |
| 732 #define FX_FONT_STYLE_None 0x00 | |
| 733 #define FX_FONT_STYLE_Bold 0x01 | |
| 734 #define FX_FONT_STYLE_Italic 0x02 | |
| 735 #define FX_FONT_STYLE_BoldBold 0x04 | |
| 736 static CFX_ByteString _GetFontFamily(CFX_ByteString fontName, int nStyle) { | |
| 737 if (fontName.Find("Script") >= 0) { | |
| 738 if ((nStyle & FX_FONT_STYLE_Bold) == FX_FONT_STYLE_Bold) { | |
| 739 fontName = "ScriptMTBold"; | |
| 740 } else if (fontName.Find("Palace") >= 0) { | |
| 741 fontName = "PalaceScriptMT"; | |
| 742 } else if (fontName.Find("French") >= 0) { | |
| 743 fontName = "FrenchScriptMT"; | |
| 744 } else if (fontName.Find("FreeStyle") >= 0) { | |
| 745 fontName = "FreeStyleScript"; | |
| 746 } | |
| 747 return fontName; | |
| 748 } | |
| 749 _AltFontFamily* found = (_AltFontFamily*)FXSYS_bsearch( | |
| 750 fontName.c_str(), g_AltFontFamilies, | |
| 751 sizeof g_AltFontFamilies / sizeof(_AltFontFamily), sizeof(_AltFontFamily), | |
| 752 compareFontFamilyString); | |
| 753 if (found == NULL) { | |
| 754 return fontName; | |
| 755 } | |
| 756 return found->m_pFontFamily; | |
| 757 }; | |
| 758 typedef struct _FX_FontStyle { | |
| 759 const FX_CHAR* style; | |
| 760 int32_t len; | |
| 761 } FX_FontStyle; | |
| 762 const FX_FontStyle g_FontStyles[] = { | |
| 763 {"Bold", 4}, {"Italic", 6}, {"BoldItalic", 10}, {"Reg", 3}, {"Regular", 7}, | |
| 764 }; | |
| 765 CFX_ByteString ParseStyle(const FX_CHAR* pStyle, int iLen, int iIndex) { | |
| 766 CFX_ByteTextBuf buf; | |
| 767 if (!iLen || iLen <= iIndex) { | |
| 768 return buf.GetByteString(); | |
| 769 } | |
| 770 while (iIndex < iLen) { | |
| 771 if (pStyle[iIndex] == ',') { | |
| 772 break; | |
| 773 } | |
| 774 buf.AppendChar(pStyle[iIndex]); | |
| 775 ++iIndex; | |
| 776 } | |
| 777 return buf.GetByteString(); | |
| 778 } | |
| 779 int32_t GetStyleType(const CFX_ByteString& bsStyle, FX_BOOL bRevert) { | |
| 780 int32_t iLen = bsStyle.GetLength(); | |
| 781 if (!iLen) { | |
| 782 return -1; | |
| 783 } | |
| 784 int iSize = sizeof(g_FontStyles) / sizeof(FX_FontStyle); | |
| 785 const FX_FontStyle* pStyle = NULL; | |
| 786 for (int i = iSize - 1; i >= 0; --i) { | |
| 787 pStyle = g_FontStyles + i; | |
| 788 if (!pStyle || pStyle->len > iLen) { | |
| 789 continue; | |
| 790 } | |
| 791 if (!bRevert) { | |
| 792 if (bsStyle.Left(pStyle->len).Compare(pStyle->style) == 0) { | |
| 793 return i; | |
| 794 } | |
| 795 } else { | |
| 796 if (bsStyle.Right(pStyle->len).Compare(pStyle->style) == 0) { | |
| 797 return i; | |
| 798 } | |
| 799 } | |
| 800 } | |
| 801 return -1; | |
| 802 } | |
| 803 FX_BOOL CheckSupportThirdPartFont(CFX_ByteString name, int& PitchFamily) { | |
| 804 if (name == FX_BSTRC("MyriadPro")) { | |
| 805 PitchFamily &= ~FXFONT_FF_ROMAN; | |
| 806 return TRUE; | |
| 807 } | |
| 808 return FALSE; | |
| 809 } | |
| 810 FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name, | 826 FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name, |
| 811 FX_BOOL bTrueType, | 827 FX_BOOL bTrueType, |
| 812 FX_DWORD flags, | 828 FX_DWORD flags, |
| 813 int weight, | 829 int weight, |
| 814 int italic_angle, | 830 int italic_angle, |
| 815 int WindowCP, | 831 int WindowCP, |
| 816 CFX_SubstFont* pSubstFont) { | 832 CFX_SubstFont* pSubstFont) { |
| 817 if (!(flags & FXFONT_USEEXTERNATTR)) { | 833 if (!(flags & FXFONT_USEEXTERNATTR)) { |
| 818 weight = FXFONT_FW_NORMAL; | 834 weight = FXFONT_FW_NORMAL; |
| 819 italic_angle = 0; | 835 italic_angle = 0; |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 ? 900 | 991 ? 900 |
| 976 : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL); | 992 : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL); |
| 977 } | 993 } |
| 978 if (nStyle & FX_FONT_STYLE_Italic) { | 994 if (nStyle & FX_FONT_STYLE_Italic) { |
| 979 bItalic = TRUE; | 995 bItalic = TRUE; |
| 980 } | 996 } |
| 981 FX_BOOL bCJK = FALSE; | 997 FX_BOOL bCJK = FALSE; |
| 982 int iExact = 0; | 998 int iExact = 0; |
| 983 int Charset = FXFONT_ANSI_CHARSET; | 999 int Charset = FXFONT_ANSI_CHARSET; |
| 984 if (WindowCP) { | 1000 if (WindowCP) { |
| 985 Charset = _GetCharsetFromCodePage(WindowCP); | 1001 Charset = GetCharsetFromCodePage(WindowCP); |
| 986 } else if (iBaseFont == 12 && (flags & FXFONT_SYMBOLIC)) { | 1002 } else if (iBaseFont == 12 && (flags & FXFONT_SYMBOLIC)) { |
| 987 Charset = FXFONT_SYMBOL_CHARSET; | 1003 Charset = FXFONT_SYMBOL_CHARSET; |
| 988 } | 1004 } |
| 989 if (Charset == FXFONT_SHIFTJIS_CHARSET || Charset == FXFONT_GB2312_CHARSET || | 1005 if (Charset == FXFONT_SHIFTJIS_CHARSET || Charset == FXFONT_GB2312_CHARSET || |
| 990 Charset == FXFONT_HANGEUL_CHARSET || | 1006 Charset == FXFONT_HANGEUL_CHARSET || |
| 991 Charset == FXFONT_CHINESEBIG5_CHARSET) { | 1007 Charset == FXFONT_CHINESEBIG5_CHARSET) { |
| 992 bCJK = TRUE; | 1008 bCJK = TRUE; |
| 993 } | 1009 } |
| 994 if (m_pFontInfo == NULL) { | 1010 if (m_pFontInfo == NULL) { |
| 995 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; | 1011 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; |
| 996 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, | 1012 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, |
| 997 PitchFamily); | 1013 PitchFamily); |
| 998 } | 1014 } |
| 999 family = _GetFontFamily(family, nStyle); | 1015 family = GetFontFamily(family, nStyle); |
| 1000 CFX_ByteString match = MatchInstalledFonts(_TT_NormalizeName(family)); | 1016 CFX_ByteString match = MatchInstalledFonts(TT_NormalizeName(family)); |
| 1001 if (match.IsEmpty() && family != SubstName && | 1017 if (match.IsEmpty() && family != SubstName && |
| 1002 (!bHasComma && (!bHasHypen || (bHasHypen && !bStyleAvail)))) { | 1018 (!bHasComma && (!bHasHypen || (bHasHypen && !bStyleAvail)))) { |
| 1003 match = MatchInstalledFonts(_TT_NormalizeName(SubstName)); | 1019 match = MatchInstalledFonts(TT_NormalizeName(SubstName)); |
| 1004 } | 1020 } |
| 1005 if (match.IsEmpty() && iBaseFont >= 12) { | 1021 if (match.IsEmpty() && iBaseFont >= 12) { |
| 1006 if (!bCJK) { | 1022 if (!bCJK) { |
| 1007 if (!CheckSupportThirdPartFont(family, PitchFamily)) { | 1023 if (!CheckSupportThirdPartFont(family, PitchFamily)) { |
| 1008 if (italic_angle != 0) { | 1024 if (italic_angle != 0) { |
| 1009 bItalic = TRUE; | 1025 bItalic = TRUE; |
| 1010 } else { | 1026 } else { |
| 1011 bItalic = FALSE; | 1027 bItalic = FALSE; |
| 1012 } | 1028 } |
| 1013 weight = old_weight; | 1029 weight = old_weight; |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1294 void CFX_FolderFontInfo::ReportFace(CFX_ByteString& path, | 1310 void CFX_FolderFontInfo::ReportFace(CFX_ByteString& path, |
| 1295 FXSYS_FILE* pFile, | 1311 FXSYS_FILE* pFile, |
| 1296 FX_DWORD filesize, | 1312 FX_DWORD filesize, |
| 1297 FX_DWORD offset) { | 1313 FX_DWORD offset) { |
| 1298 FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); | 1314 FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); |
| 1299 char buffer[16]; | 1315 char buffer[16]; |
| 1300 if (!FXSYS_fread(buffer, 12, 1, pFile)) { | 1316 if (!FXSYS_fread(buffer, 12, 1, pFile)) { |
| 1301 return; | 1317 return; |
| 1302 } | 1318 } |
| 1303 FX_DWORD nTables = GET_TT_SHORT(buffer + 4); | 1319 FX_DWORD nTables = GET_TT_SHORT(buffer + 4); |
| 1304 CFX_ByteString tables = _FPDF_ReadStringFromFile(pFile, nTables * 16); | 1320 CFX_ByteString tables = FPDF_ReadStringFromFile(pFile, nTables * 16); |
| 1305 if (tables.IsEmpty()) { | 1321 if (tables.IsEmpty()) { |
| 1306 return; | 1322 return; |
| 1307 } | 1323 } |
| 1308 CFX_ByteString names = | 1324 CFX_ByteString names = |
| 1309 _FPDF_LoadTableFromTT(pFile, tables, nTables, 0x6e616d65); | 1325 FPDF_LoadTableFromTT(pFile, tables, nTables, 0x6e616d65); |
| 1310 CFX_ByteString facename = GetNameFromTT(names, 1); | 1326 CFX_ByteString facename = GetNameFromTT(names, 1); |
| 1311 CFX_ByteString style = GetNameFromTT(names, 2); | 1327 CFX_ByteString style = GetNameFromTT(names, 2); |
| 1312 if (style != "Regular") { | 1328 if (style != "Regular") { |
| 1313 facename += " " + style; | 1329 facename += " " + style; |
| 1314 } | 1330 } |
| 1315 if (m_FontList.find(facename) != m_FontList.end()) { | 1331 if (m_FontList.find(facename) != m_FontList.end()) { |
| 1316 return; | 1332 return; |
| 1317 } | 1333 } |
| 1318 CFX_FontFaceInfo* pInfo = | 1334 CFX_FontFaceInfo* pInfo = |
| 1319 new CFX_FontFaceInfo(path, facename, tables, offset, filesize); | 1335 new CFX_FontFaceInfo(path, facename, tables, offset, filesize); |
| 1320 CFX_ByteString os2 = | 1336 CFX_ByteString os2 = FPDF_LoadTableFromTT(pFile, tables, nTables, 0x4f532f32); |
| 1321 _FPDF_LoadTableFromTT(pFile, tables, nTables, 0x4f532f32); | |
| 1322 if (os2.GetLength() >= 86) { | 1337 if (os2.GetLength() >= 86) { |
| 1323 const uint8_t* p = (const uint8_t*)os2 + 78; | 1338 const uint8_t* p = (const uint8_t*)os2 + 78; |
| 1324 FX_DWORD codepages = GET_TT_LONG(p); | 1339 FX_DWORD codepages = GET_TT_LONG(p); |
| 1325 if (codepages & (1 << 17)) { | 1340 if (codepages & (1 << 17)) { |
| 1326 m_pMapper->AddInstalledFont(facename, FXFONT_SHIFTJIS_CHARSET); | 1341 m_pMapper->AddInstalledFont(facename, FXFONT_SHIFTJIS_CHARSET); |
| 1327 pInfo->m_Charsets |= CHARSET_FLAG_SHIFTJIS; | 1342 pInfo->m_Charsets |= CHARSET_FLAG_SHIFTJIS; |
| 1328 } | 1343 } |
| 1329 if (codepages & (1 << 18)) { | 1344 if (codepages & (1 << 18)) { |
| 1330 m_pMapper->AddInstalledFont(facename, FXFONT_GB2312_CHARSET); | 1345 m_pMapper->AddInstalledFont(facename, FXFONT_GB2312_CHARSET); |
| 1331 pInfo->m_Charsets |= CHARSET_FLAG_GB; | 1346 pInfo->m_Charsets |= CHARSET_FLAG_GB; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1351 } | 1366 } |
| 1352 if (style.Find(FX_BSTRC("Italic")) > -1 || | 1367 if (style.Find(FX_BSTRC("Italic")) > -1 || |
| 1353 style.Find(FX_BSTRC("Oblique")) > -1) { | 1368 style.Find(FX_BSTRC("Oblique")) > -1) { |
| 1354 pInfo->m_Styles |= FXFONT_ITALIC; | 1369 pInfo->m_Styles |= FXFONT_ITALIC; |
| 1355 } | 1370 } |
| 1356 if (facename.Find(FX_BSTRC("Serif")) > -1) { | 1371 if (facename.Find(FX_BSTRC("Serif")) > -1) { |
| 1357 pInfo->m_Styles |= FXFONT_SERIF; | 1372 pInfo->m_Styles |= FXFONT_SERIF; |
| 1358 } | 1373 } |
| 1359 m_FontList[facename] = pInfo; | 1374 m_FontList[facename] = pInfo; |
| 1360 } | 1375 } |
| 1361 static const struct { | 1376 |
| 1362 const FX_CHAR* m_pName; | |
| 1363 const FX_CHAR* m_pSubstName; | |
| 1364 } Base14Substs[] = { | |
| 1365 {"Courier", "Courier New"}, | |
| 1366 {"Courier-Bold", "Courier New Bold"}, | |
| 1367 {"Courier-BoldOblique", "Courier New Bold Italic"}, | |
| 1368 {"Courier-Oblique", "Courier New Italic"}, | |
| 1369 {"Helvetica", "Arial"}, | |
| 1370 {"Helvetica-Bold", "Arial Bold"}, | |
| 1371 {"Helvetica-BoldOblique", "Arial Bold Italic"}, | |
| 1372 {"Helvetica-Oblique", "Arial Italic"}, | |
| 1373 {"Times-Roman", "Times New Roman"}, | |
| 1374 {"Times-Bold", "Times New Roman Bold"}, | |
| 1375 {"Times-BoldItalic", "Times New Roman Bold Italic"}, | |
| 1376 {"Times-Italic", "Times New Roman Italic"}, | |
| 1377 }; | |
| 1378 void* CFX_FolderFontInfo::GetSubstFont(const CFX_ByteString& face) { | 1377 void* CFX_FolderFontInfo::GetSubstFont(const CFX_ByteString& face) { |
| 1379 for (size_t iBaseFont = 0; iBaseFont < FX_ArraySize(Base14Substs); | 1378 for (size_t iBaseFont = 0; iBaseFont < FX_ArraySize(Base14Substs); |
| 1380 iBaseFont++) { | 1379 iBaseFont++) { |
| 1381 if (face == Base14Substs[iBaseFont].m_pName) { | 1380 if (face == Base14Substs[iBaseFont].m_pName) { |
| 1382 return GetFont(Base14Substs[iBaseFont].m_pSubstName); | 1381 return GetFont(Base14Substs[iBaseFont].m_pSubstName); |
| 1383 } | 1382 } |
| 1384 } | 1383 } |
| 1385 return nullptr; | 1384 return nullptr; |
| 1386 } | 1385 } |
| 1387 static FX_DWORD _GetCharset(int charset) { | 1386 |
| 1388 switch (charset) { | |
| 1389 case FXFONT_SHIFTJIS_CHARSET: | |
| 1390 return CHARSET_FLAG_SHIFTJIS; | |
| 1391 case FXFONT_GB2312_CHARSET: | |
| 1392 return CHARSET_FLAG_GB; | |
| 1393 case FXFONT_CHINESEBIG5_CHARSET: | |
| 1394 return CHARSET_FLAG_BIG5; | |
| 1395 case FXFONT_HANGEUL_CHARSET: | |
| 1396 return CHARSET_FLAG_KOREAN; | |
| 1397 case FXFONT_SYMBOL_CHARSET: | |
| 1398 return CHARSET_FLAG_SYMBOL; | |
| 1399 case FXFONT_ANSI_CHARSET: | |
| 1400 return CHARSET_FLAG_ANSI; | |
| 1401 default: | |
| 1402 break; | |
| 1403 } | |
| 1404 return 0; | |
| 1405 } | |
| 1406 static int32_t _GetSimilarValue(int weight, | |
| 1407 FX_BOOL bItalic, | |
| 1408 int pitch_family, | |
| 1409 FX_DWORD style) { | |
| 1410 int32_t iSimilarValue = 0; | |
| 1411 if ((style & FXFONT_BOLD) == (weight > 400)) { | |
| 1412 iSimilarValue += 16; | |
| 1413 } | |
| 1414 if ((style & FXFONT_ITALIC) == bItalic) { | |
| 1415 iSimilarValue += 16; | |
| 1416 } | |
| 1417 if ((style & FXFONT_SERIF) == (pitch_family & FXFONT_FF_ROMAN)) { | |
| 1418 iSimilarValue += 16; | |
| 1419 } | |
| 1420 if ((style & FXFONT_SCRIPT) == (pitch_family & FXFONT_FF_SCRIPT)) { | |
| 1421 iSimilarValue += 8; | |
| 1422 } | |
| 1423 if ((style & FXFONT_FIXED_PITCH) == (pitch_family & FXFONT_FF_FIXEDPITCH)) { | |
| 1424 iSimilarValue += 8; | |
| 1425 } | |
| 1426 return iSimilarValue; | |
| 1427 } | |
| 1428 void* CFX_FolderFontInfo::FindFont(int weight, | 1387 void* CFX_FolderFontInfo::FindFont(int weight, |
| 1429 FX_BOOL bItalic, | 1388 FX_BOOL bItalic, |
| 1430 int charset, | 1389 int charset, |
| 1431 int pitch_family, | 1390 int pitch_family, |
| 1432 const FX_CHAR* family, | 1391 const FX_CHAR* family, |
| 1433 FX_BOOL bMatchName) { | 1392 FX_BOOL bMatchName) { |
| 1434 CFX_FontFaceInfo* pFind = nullptr; | 1393 CFX_FontFaceInfo* pFind = nullptr; |
| 1435 if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) { | 1394 if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) { |
| 1436 return GetFont("Courier New"); | 1395 return GetFont("Courier New"); |
| 1437 } | 1396 } |
| 1438 FX_DWORD charset_flag = _GetCharset(charset); | 1397 FX_DWORD charset_flag = GetCharset(charset); |
| 1439 int32_t iBestSimilar = 0; | 1398 int32_t iBestSimilar = 0; |
| 1440 for (const auto& it : m_FontList) { | 1399 for (const auto& it : m_FontList) { |
| 1441 const CFX_ByteString& bsName = it.first; | 1400 const CFX_ByteString& bsName = it.first; |
| 1442 CFX_FontFaceInfo* pFont = it.second; | 1401 CFX_FontFaceInfo* pFont = it.second; |
| 1443 if (!(pFont->m_Charsets & charset_flag) && | 1402 if (!(pFont->m_Charsets & charset_flag) && |
| 1444 charset != FXFONT_DEFAULT_CHARSET) { | 1403 charset != FXFONT_DEFAULT_CHARSET) { |
| 1445 continue; | 1404 continue; |
| 1446 } | 1405 } |
| 1447 int32_t index = bsName.Find(family); | 1406 int32_t index = bsName.Find(family); |
| 1448 if (bMatchName && index < 0) { | 1407 if (bMatchName && index < 0) { |
| 1449 continue; | 1408 continue; |
| 1450 } | 1409 } |
| 1451 int32_t iSimilarValue = | 1410 int32_t iSimilarValue = |
| 1452 _GetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles); | 1411 GetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles); |
| 1453 if (iSimilarValue > iBestSimilar) { | 1412 if (iSimilarValue > iBestSimilar) { |
| 1454 iBestSimilar = iSimilarValue; | 1413 iBestSimilar = iSimilarValue; |
| 1455 pFind = pFont; | 1414 pFind = pFont; |
| 1456 } | 1415 } |
| 1457 } | 1416 } |
| 1458 return pFind; | 1417 return pFind; |
| 1459 } | 1418 } |
| 1460 void* CFX_FolderFontInfo::MapFont(int weight, | 1419 void* CFX_FolderFontInfo::MapFont(int weight, |
| 1461 FX_BOOL bItalic, | 1420 FX_BOOL bItalic, |
| 1462 int charset, | 1421 int charset, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1520 name = pFont->m_FaceName; | 1479 name = pFont->m_FaceName; |
| 1521 return TRUE; | 1480 return TRUE; |
| 1522 } | 1481 } |
| 1523 FX_BOOL CFX_FolderFontInfo::GetFontCharset(void* hFont, int& charset) { | 1482 FX_BOOL CFX_FolderFontInfo::GetFontCharset(void* hFont, int& charset) { |
| 1524 return FALSE; | 1483 return FALSE; |
| 1525 } | 1484 } |
| 1526 | 1485 |
| 1527 int PDF_GetStandardFontName(CFX_ByteString* name) { | 1486 int PDF_GetStandardFontName(CFX_ByteString* name) { |
| 1528 AltFontName* found = static_cast<AltFontName*>( | 1487 AltFontName* found = static_cast<AltFontName*>( |
| 1529 FXSYS_bsearch(name->c_str(), g_AltFontNames, FX_ArraySize(g_AltFontNames), | 1488 FXSYS_bsearch(name->c_str(), g_AltFontNames, FX_ArraySize(g_AltFontNames), |
| 1530 sizeof(AltFontName), compareString)); | 1489 sizeof(AltFontName), CompareString)); |
| 1531 if (!found) | 1490 if (!found) |
| 1532 return -1; | 1491 return -1; |
| 1533 | 1492 |
| 1534 *name = g_Base14FontNames[found->m_Index]; | 1493 *name = g_Base14FontNames[found->m_Index]; |
| 1535 return found->m_Index; | 1494 return found->m_Index; |
| 1536 } | 1495 } |
| OLD | NEW |