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 "fx_fpf.h" | 7 #include "fx_fpf.h" |
8 #if _FX_OS_ == _FX_ANDROID_ | 8 #if _FX_OS_ == _FX_ANDROID_ |
9 #define FPF_SKIAMATCHWEIGHT_NAME1» 62 | 9 #define FPF_SKIAMATCHWEIGHT_NAME1 62 |
10 #define FPF_SKIAMATCHWEIGHT_NAME2» 60 | 10 #define FPF_SKIAMATCHWEIGHT_NAME2 60 |
11 #define FPF_SKIAMATCHWEIGHT_1» » 16 | 11 #define FPF_SKIAMATCHWEIGHT_1 16 |
12 #define FPF_SKIAMATCHWEIGHT_2» » 8 | 12 #define FPF_SKIAMATCHWEIGHT_2 8 |
13 #include "fpf_skiafontmgr.h" | 13 #include "fpf_skiafontmgr.h" |
14 #include "fpf_skiafont.h" | 14 #include "fpf_skiafont.h" |
15 #ifdef __cplusplus | 15 #ifdef __cplusplus |
16 extern "C" { | 16 extern "C" { |
17 #endif | 17 #endif |
18 static unsigned long FPF_SkiaStream_Read(FXFT_Stream stream, unsigned long offse
t, unsigned char* buffer, unsigned long count) | 18 static unsigned long FPF_SkiaStream_Read(FXFT_Stream stream, |
19 { | 19 unsigned long offset, |
20 IFX_FileRead *pFileRead = (IFX_FileRead*)stream->descriptor.pointer; | 20 unsigned char* buffer, |
21 if (!pFileRead) { | 21 unsigned long count) { |
22 return 0; | 22 IFX_FileRead* pFileRead = (IFX_FileRead*)stream->descriptor.pointer; |
23 } | 23 if (!pFileRead) { |
24 if (count > 0) { | 24 return 0; |
25 if (pFileRead->ReadBlock(buffer, (FX_FILESIZE)offset, (size_t)count) !=
count) { | 25 } |
26 return 0; | 26 if (count > 0) { |
27 } | 27 if (pFileRead->ReadBlock(buffer, (FX_FILESIZE)offset, (size_t)count) != |
28 } | 28 count) { |
29 return count; | 29 return 0; |
30 } | 30 } |
31 static void FPF_SkiaStream_Close(FXFT_Stream stream) | 31 } |
32 { | 32 return count; |
| 33 } |
| 34 static void FPF_SkiaStream_Close(FXFT_Stream stream) { |
33 } | 35 } |
34 #ifdef __cplusplus | 36 #ifdef __cplusplus |
35 }; | 37 }; |
36 #endif | 38 #endif |
37 typedef struct _FPF_SKIAFONTMAP { | 39 typedef struct _FPF_SKIAFONTMAP { |
38 FX_DWORD» dwFamily; | 40 FX_DWORD dwFamily; |
39 FX_DWORD» dwSubSt; | 41 FX_DWORD dwSubSt; |
40 } FPF_SKIAFONTMAP, *FPF_LPSKIAFONTMAP; | 42 } FPF_SKIAFONTMAP, *FPF_LPSKIAFONTMAP; |
41 typedef FPF_SKIAFONTMAP const * FPF_LPCSKIAFONTMAP; | 43 typedef FPF_SKIAFONTMAP const* FPF_LPCSKIAFONTMAP; |
42 static const FPF_SKIAFONTMAP g_SkiaFontmap[] = { | 44 static const FPF_SKIAFONTMAP g_SkiaFontmap[] = { |
43 {0x58c5083,»» 0xc8d2e345}, | 45 { 0x58c5083, 0xc8d2e345 }, |
44 {0x5dfade2,»» 0xe1633081}, | 46 { 0x5dfade2, 0xe1633081 }, |
45 {0x684317d,»» 0xe1633081}, | 47 { 0x684317d, 0xe1633081 }, |
46 {0x14ee2d13,» 0xc8d2e345}, | 48 { 0x14ee2d13, 0xc8d2e345 }, |
47 {0x3918fe2d,» 0xbbeeec72}, | 49 { 0x3918fe2d, 0xbbeeec72 }, |
48 {0x3b98b31c,» 0xe1633081}, | 50 { 0x3b98b31c, 0xe1633081 }, |
49 {0x3d49f40e,» 0xe1633081}, | 51 { 0x3d49f40e, 0xe1633081 }, |
50 {0x432c41c5,» 0xe1633081}, | 52 { 0x432c41c5, 0xe1633081 }, |
51 {0x491b6ad0,» 0xe1633081}, | 53 { 0x491b6ad0, 0xe1633081 }, |
52 {0x5612cab1,» 0x59b9f8f1}, | 54 { 0x5612cab1, 0x59b9f8f1 }, |
53 {0x779ce19d,» 0xc8d2e345}, | 55 { 0x779ce19d, 0xc8d2e345 }, |
54 {0x7cc9510b,» 0x59b9f8f1}, | 56 { 0x7cc9510b, 0x59b9f8f1 }, |
55 {0x83746053,» 0xbbeeec72}, | 57 { 0x83746053, 0xbbeeec72 }, |
56 {0xaaa60c03,» 0xbbeeec72}, | 58 { 0xaaa60c03, 0xbbeeec72 }, |
57 {0xbf85ff26,» 0xe1633081}, | 59 { 0xbf85ff26, 0xe1633081 }, |
58 {0xc04fe601,» 0xbbeeec72}, | 60 { 0xc04fe601, 0xbbeeec72 }, |
59 {0xca3812d5,» 0x59b9f8f1}, | 61 { 0xca3812d5, 0x59b9f8f1 }, |
60 {0xca383e15,» 0x59b9f8f1}, | 62 { 0xca383e15, 0x59b9f8f1 }, |
61 {0xcad5eaf6,» 0x59b9f8f1}, | 63 { 0xcad5eaf6, 0x59b9f8f1 }, |
62 {0xcb7a04c8,» 0xc8d2e345}, | 64 { 0xcb7a04c8, 0xc8d2e345 }, |
63 {0xfb4ce0de,» 0xe1633081}, | 65 { 0xfb4ce0de, 0xe1633081 }, |
64 }; | 66 }; |
65 FX_DWORD FPF_SkiaGetSubstFont(FX_DWORD dwHash) | 67 FX_DWORD FPF_SkiaGetSubstFont(FX_DWORD dwHash) { |
66 { | 68 FX_INT32 iStart = 0; |
67 FX_INT32 iStart = 0; | 69 FX_INT32 iEnd = sizeof(g_SkiaFontmap) / sizeof(FPF_SKIAFONTMAP); |
68 FX_INT32 iEnd = sizeof(g_SkiaFontmap) / sizeof(FPF_SKIAFONTMAP); | 70 while (iStart <= iEnd) { |
69 while (iStart <= iEnd) { | 71 FX_INT32 iMid = (iStart + iEnd) / 2; |
70 FX_INT32 iMid = (iStart + iEnd) / 2; | 72 FPF_LPCSKIAFONTMAP pItem = &g_SkiaFontmap[iMid]; |
71 FPF_LPCSKIAFONTMAP pItem = &g_SkiaFontmap[iMid]; | 73 if (dwHash < pItem->dwFamily) { |
72 if (dwHash < pItem->dwFamily) { | 74 iEnd = iMid - 1; |
73 iEnd = iMid - 1; | 75 } else if (dwHash > pItem->dwFamily) { |
74 } else if (dwHash > pItem->dwFamily) { | 76 iStart = iMid + 1; |
75 iStart = iMid + 1; | 77 } else { |
76 } else { | 78 return pItem->dwSubSt; |
77 return pItem->dwSubSt; | 79 } |
78 } | 80 } |
79 } | 81 return NULL; |
80 return NULL; | |
81 } | 82 } |
82 static const FPF_SKIAFONTMAP g_SkiaSansFontMap[] = { | 83 static const FPF_SKIAFONTMAP g_SkiaSansFontMap[] = { |
83 {0x58c5083,»» 0xd5b8d10f}, | 84 { 0x58c5083, 0xd5b8d10f }, |
84 {0x14ee2d13,» 0xd5b8d10f}, | 85 { 0x14ee2d13, 0xd5b8d10f }, |
85 {0x779ce19d,» 0xd5b8d10f}, | 86 { 0x779ce19d, 0xd5b8d10f }, |
86 {0xcb7a04c8,» 0xd5b8d10f}, | 87 { 0xcb7a04c8, 0xd5b8d10f }, |
87 {0xfb4ce0de,» 0xd5b8d10f}, | 88 { 0xfb4ce0de, 0xd5b8d10f }, |
88 }; | 89 }; |
89 FX_DWORD FPF_SkiaGetSansFont(FX_DWORD dwHash) | 90 FX_DWORD FPF_SkiaGetSansFont(FX_DWORD dwHash) { |
90 { | 91 FX_INT32 iStart = 0; |
91 FX_INT32 iStart = 0; | 92 FX_INT32 iEnd = sizeof(g_SkiaSansFontMap) / sizeof(FPF_SKIAFONTMAP); |
92 FX_INT32 iEnd = sizeof(g_SkiaSansFontMap) / sizeof(FPF_SKIAFONTMAP); | 93 while (iStart <= iEnd) { |
93 while (iStart <= iEnd) { | 94 FX_INT32 iMid = (iStart + iEnd) / 2; |
94 FX_INT32 iMid = (iStart + iEnd) / 2; | 95 FPF_LPCSKIAFONTMAP pItem = &g_SkiaSansFontMap[iMid]; |
95 FPF_LPCSKIAFONTMAP pItem = &g_SkiaSansFontMap[iMid]; | 96 if (dwHash < pItem->dwFamily) { |
96 if (dwHash < pItem->dwFamily) { | 97 iEnd = iMid - 1; |
97 iEnd = iMid - 1; | 98 } else if (dwHash > pItem->dwFamily) { |
98 } else if (dwHash > pItem->dwFamily) { | 99 iStart = iMid + 1; |
99 iStart = iMid + 1; | 100 } else { |
100 } else { | 101 return pItem->dwSubSt; |
101 return pItem->dwSubSt; | 102 } |
102 } | 103 } |
103 } | 104 return 0; |
| 105 } |
| 106 static FX_UINT32 FPF_GetHashCode_StringA(FX_LPCSTR pStr, |
| 107 FX_INT32 iLength, |
| 108 FX_BOOL bIgnoreCase = FALSE) { |
| 109 if (!pStr) { |
104 return 0; | 110 return 0; |
105 } | 111 } |
106 static FX_UINT32 FPF_GetHashCode_StringA(FX_LPCSTR pStr, FX_INT32 iLength, FX_BO
OL bIgnoreCase = FALSE) | 112 if (iLength < 0) { |
107 { | 113 iLength = FXSYS_strlen(pStr); |
108 if (!pStr) { | 114 } |
109 return 0; | 115 FX_LPCSTR pStrEnd = pStr + iLength; |
110 } | 116 FX_UINT32 uHashCode = 0; |
111 if (iLength < 0) { | 117 if (bIgnoreCase) { |
112 iLength = FXSYS_strlen(pStr); | 118 while (pStr < pStrEnd) { |
113 } | 119 uHashCode = 31 * uHashCode + FXSYS_tolower(*pStr++); |
114 FX_LPCSTR pStrEnd = pStr + iLength; | 120 } |
115 FX_UINT32 uHashCode = 0; | 121 } else { |
116 if (bIgnoreCase) { | 122 while (pStr < pStrEnd) { |
117 while (pStr < pStrEnd) { | 123 uHashCode = 31 * uHashCode + *pStr++; |
118 uHashCode = 31 * uHashCode + FXSYS_tolower(*pStr++); | 124 } |
119 } | 125 } |
| 126 return uHashCode; |
| 127 } |
| 128 enum FPF_SKIACHARSET { |
| 129 FPF_SKIACHARSET_Ansi = 1 << 0, |
| 130 FPF_SKIACHARSET_Default = 1 << 1, |
| 131 FPF_SKIACHARSET_Symbol = 1 << 2, |
| 132 FPF_SKIACHARSET_ShiftJIS = 1 << 3, |
| 133 FPF_SKIACHARSET_Korean = 1 << 4, |
| 134 FPF_SKIACHARSET_Johab = 1 << 5, |
| 135 FPF_SKIACHARSET_GB2312 = 1 << 6, |
| 136 FPF_SKIACHARSET_BIG5 = 1 << 7, |
| 137 FPF_SKIACHARSET_Greek = 1 << 8, |
| 138 FPF_SKIACHARSET_Turkish = 1 << 9, |
| 139 FPF_SKIACHARSET_Vietnamese = 1 << 10, |
| 140 FPF_SKIACHARSET_Hebrew = 1 << 11, |
| 141 FPF_SKIACHARSET_Arabic = 1 << 12, |
| 142 FPF_SKIACHARSET_Baltic = 1 << 13, |
| 143 FPF_SKIACHARSET_Cyrillic = 1 << 14, |
| 144 FPF_SKIACHARSET_Thai = 1 << 15, |
| 145 FPF_SKIACHARSET_EeasternEuropean = 1 << 16, |
| 146 FPF_SKIACHARSET_PC = 1 << 17, |
| 147 FPF_SKIACHARSET_OEM = 1 << 18, |
| 148 }; |
| 149 static FX_DWORD FPF_SkiaGetCharset(FX_BYTE uCharset) { |
| 150 switch (uCharset) { |
| 151 case FXFONT_ANSI_CHARSET: |
| 152 return FPF_SKIACHARSET_Ansi; |
| 153 case FXFONT_DEFAULT_CHARSET: |
| 154 return FPF_SKIACHARSET_Default; |
| 155 case FXFONT_SYMBOL_CHARSET: |
| 156 return FPF_SKIACHARSET_Symbol; |
| 157 case FXFONT_SHIFTJIS_CHARSET: |
| 158 return FPF_SKIACHARSET_ShiftJIS; |
| 159 case FXFONT_HANGEUL_CHARSET: |
| 160 return FPF_SKIACHARSET_Korean; |
| 161 case FXFONT_GB2312_CHARSET: |
| 162 return FPF_SKIACHARSET_GB2312; |
| 163 case FXFONT_CHINESEBIG5_CHARSET: |
| 164 return FPF_SKIACHARSET_BIG5; |
| 165 case FXFONT_GREEK_CHARSET: |
| 166 return FPF_SKIACHARSET_Greek; |
| 167 case FXFONT_TURKISH_CHARSET: |
| 168 return FPF_SKIACHARSET_Turkish; |
| 169 case FXFONT_HEBREW_CHARSET: |
| 170 return FPF_SKIACHARSET_Hebrew; |
| 171 case FXFONT_ARABIC_CHARSET: |
| 172 return FPF_SKIACHARSET_Arabic; |
| 173 case FXFONT_BALTIC_CHARSET: |
| 174 return FPF_SKIACHARSET_Baltic; |
| 175 case FXFONT_RUSSIAN_CHARSET: |
| 176 return FPF_SKIACHARSET_Cyrillic; |
| 177 case FXFONT_THAI_CHARSET: |
| 178 return FPF_SKIACHARSET_Thai; |
| 179 case FXFONT_EASTEUROPE_CHARSET: |
| 180 return FPF_SKIACHARSET_EeasternEuropean; |
| 181 } |
| 182 return FPF_SKIACHARSET_Default; |
| 183 } |
| 184 static FX_DWORD FPF_SKIANormalizeFontName(FX_BSTR bsfamily) { |
| 185 FX_DWORD dwHash = 0; |
| 186 FX_INT32 iLength = bsfamily.GetLength(); |
| 187 FX_LPCSTR pBuffer = bsfamily.GetCStr(); |
| 188 for (FX_INT32 i = 0; i < iLength; i++) { |
| 189 FX_CHAR ch = pBuffer[i]; |
| 190 if (ch == ' ' || ch == '-' || ch == ',') { |
| 191 continue; |
| 192 } |
| 193 dwHash = 31 * dwHash + FXSYS_tolower(ch); |
| 194 } |
| 195 return dwHash; |
| 196 } |
| 197 static FX_DWORD FPF_SKIAGetFamilyHash(FX_BSTR bsFamily, |
| 198 FX_DWORD dwStyle, |
| 199 FX_BYTE uCharset) { |
| 200 CFX_ByteString bsFont(bsFamily); |
| 201 if (dwStyle & FXFONT_BOLD) { |
| 202 bsFont += "Bold"; |
| 203 } |
| 204 if (dwStyle & FXFONT_ITALIC) { |
| 205 bsFont += "Italic"; |
| 206 } |
| 207 if (dwStyle & FXFONT_SERIF) { |
| 208 bsFont += "Serif"; |
| 209 } |
| 210 bsFont += uCharset; |
| 211 return FPF_GetHashCode_StringA((FX_LPCSTR)bsFont, bsFont.GetLength(), TRUE); |
| 212 } |
| 213 static FX_BOOL FPF_SkiaIsCJK(FX_BYTE uCharset) { |
| 214 return (uCharset == FXFONT_GB2312_CHARSET) || |
| 215 (uCharset == FXFONT_CHINESEBIG5_CHARSET) || |
| 216 (uCharset == FXFONT_HANGEUL_CHARSET) || |
| 217 (uCharset == FXFONT_SHIFTJIS_CHARSET); |
| 218 } |
| 219 static FX_BOOL FPF_SkiaMaybeSymbol(FX_BSTR bsFacename) { |
| 220 CFX_ByteString bsName = bsFacename; |
| 221 bsName.MakeLower(); |
| 222 return bsName.Find("symbol") > -1; |
| 223 } |
| 224 static FX_BOOL FPF_SkiaMaybeArabic(FX_BSTR bsFacename) { |
| 225 CFX_ByteString bsName = bsFacename; |
| 226 bsName.MakeLower(); |
| 227 return bsName.Find("arabic") > -1; |
| 228 } |
| 229 CFPF_SkiaFontMgr::CFPF_SkiaFontMgr() : m_bLoaded(FALSE), m_FTLibrary(NULL) { |
| 230 } |
| 231 CFPF_SkiaFontMgr::~CFPF_SkiaFontMgr() { |
| 232 void* pkey = NULL; |
| 233 CFPF_SkiaFont* pValue = NULL; |
| 234 FX_POSITION pos = m_FamilyFonts.GetStartPosition(); |
| 235 while (pos) { |
| 236 m_FamilyFonts.GetNextAssoc(pos, pkey, (void*&)pValue); |
| 237 if (pValue) { |
| 238 pValue->Release(); |
| 239 } |
| 240 } |
| 241 m_FamilyFonts.RemoveAll(); |
| 242 for (FX_INT32 i = m_FontFaces.GetUpperBound(); i >= 0; i--) { |
| 243 CFPF_SkiaFontDescriptor* pFont = |
| 244 (CFPF_SkiaFontDescriptor*)m_FontFaces.ElementAt(i); |
| 245 if (pFont) { |
| 246 delete pFont; |
| 247 } |
| 248 } |
| 249 m_FontFaces.RemoveAll(); |
| 250 if (m_FTLibrary) { |
| 251 FXFT_Done_FreeType(m_FTLibrary); |
| 252 } |
| 253 } |
| 254 FX_BOOL CFPF_SkiaFontMgr::InitFTLibrary() { |
| 255 if (m_FTLibrary == NULL) { |
| 256 FXFT_Init_FreeType(&m_FTLibrary); |
| 257 } |
| 258 return m_FTLibrary != NULL; |
| 259 } |
| 260 void CFPF_SkiaFontMgr::LoadSystemFonts() { |
| 261 if (m_bLoaded) { |
| 262 return; |
| 263 } |
| 264 ScanPath(FX_BSTRC("/system/fonts")); |
| 265 OutputSystemFonts(); |
| 266 m_bLoaded = TRUE; |
| 267 } |
| 268 void CFPF_SkiaFontMgr::LoadPrivateFont(IFX_FileRead* pFontFile) { |
| 269 } |
| 270 void CFPF_SkiaFontMgr::LoadPrivateFont(FX_BSTR bsFileName) { |
| 271 } |
| 272 void CFPF_SkiaFontMgr::LoadPrivateFont(FX_LPVOID pBuffer, size_t szBuffer) { |
| 273 } |
| 274 IFPF_Font* CFPF_SkiaFontMgr::CreateFont(FX_BSTR bsFamilyname, |
| 275 FX_BYTE uCharset, |
| 276 FX_DWORD dwStyle, |
| 277 FX_DWORD dwMatch) { |
| 278 FX_DWORD dwHash = FPF_SKIAGetFamilyHash(bsFamilyname, dwStyle, uCharset); |
| 279 IFPF_Font* pFont = NULL; |
| 280 if (m_FamilyFonts.Lookup((void*)(FX_UINTPTR) dwHash, (void*&)pFont)) { |
| 281 if (pFont) { |
| 282 return pFont->Retain(); |
| 283 } |
| 284 } |
| 285 FX_DWORD dwFaceName = FPF_SKIANormalizeFontName(bsFamilyname); |
| 286 FX_DWORD dwSubst = FPF_SkiaGetSubstFont(dwFaceName); |
| 287 FX_DWORD dwSubstSans = FPF_SkiaGetSansFont(dwFaceName); |
| 288 FX_BOOL bMaybeSymbol = FPF_SkiaMaybeSymbol(bsFamilyname); |
| 289 if (uCharset != FXFONT_ARABIC_CHARSET && FPF_SkiaMaybeArabic(bsFamilyname)) { |
| 290 uCharset = FXFONT_ARABIC_CHARSET; |
| 291 } else if (uCharset == FXFONT_ANSI_CHARSET && |
| 292 (dwMatch & FPF_MATCHFONT_REPLACEANSI)) { |
| 293 uCharset = FXFONT_DEFAULT_CHARSET; |
| 294 } |
| 295 FX_INT32 nExpectVal = FPF_SKIAMATCHWEIGHT_NAME1 + FPF_SKIAMATCHWEIGHT_1 * 3 + |
| 296 FPF_SKIAMATCHWEIGHT_2 * 2; |
| 297 FX_INT32 nItem = -1; |
| 298 FX_INT32 nMax = -1; |
| 299 FX_INT32 nGlyphNum = 0; |
| 300 for (FX_INT32 i = m_FontFaces.GetUpperBound(); i >= 0; i--) { |
| 301 CFPF_SkiaPathFont* pFontDes = (CFPF_SkiaPathFont*)m_FontFaces.ElementAt(i); |
| 302 if (!(pFontDes->m_dwCharsets & FPF_SkiaGetCharset(uCharset))) { |
| 303 continue; |
| 304 } |
| 305 FX_INT32 nFind = 0; |
| 306 FX_DWORD dwSysFontName = FPF_SKIANormalizeFontName(pFontDes->m_pFamily); |
| 307 if (dwFaceName == dwSysFontName) { |
| 308 nFind += FPF_SKIAMATCHWEIGHT_NAME1; |
| 309 } |
| 310 FX_BOOL bMatchedName = (nFind == FPF_SKIAMATCHWEIGHT_NAME1); |
| 311 if ((dwStyle & FXFONT_BOLD) == (pFontDes->m_dwStyle & FXFONT_BOLD)) { |
| 312 nFind += FPF_SKIAMATCHWEIGHT_1; |
| 313 } |
| 314 if ((dwStyle & FXFONT_ITALIC) == (pFontDes->m_dwStyle & FXFONT_ITALIC)) { |
| 315 nFind += FPF_SKIAMATCHWEIGHT_1; |
| 316 } |
| 317 if ((dwStyle & FXFONT_FIXED_PITCH) == |
| 318 (pFontDes->m_dwStyle & FXFONT_FIXED_PITCH)) { |
| 319 nFind += FPF_SKIAMATCHWEIGHT_2; |
| 320 } |
| 321 if ((dwStyle & FXFONT_SERIF) == (pFontDes->m_dwStyle & FXFONT_SERIF)) { |
| 322 nFind += FPF_SKIAMATCHWEIGHT_1; |
| 323 } |
| 324 if ((dwStyle & FXFONT_SCRIPT) == (pFontDes->m_dwStyle & FXFONT_SCRIPT)) { |
| 325 nFind += FPF_SKIAMATCHWEIGHT_2; |
| 326 } |
| 327 if (dwSubst == dwSysFontName || dwSubstSans == dwSysFontName) { |
| 328 nFind += FPF_SKIAMATCHWEIGHT_NAME2; |
| 329 bMatchedName = TRUE; |
| 330 } |
| 331 if (uCharset == FXFONT_DEFAULT_CHARSET || bMaybeSymbol) { |
| 332 if (nFind > nMax && bMatchedName) { |
| 333 nMax = nFind; |
| 334 nItem = i; |
| 335 } |
| 336 } else if (FPF_SkiaIsCJK(uCharset)) { |
| 337 if (bMatchedName || pFontDes->m_iGlyphNum > nGlyphNum) { |
| 338 nItem = i; |
| 339 nGlyphNum = pFontDes->m_iGlyphNum; |
| 340 } |
| 341 } else if (nFind > nMax) { |
| 342 nMax = nFind; |
| 343 nItem = i; |
| 344 } |
| 345 if (nExpectVal <= nFind) { |
| 346 nItem = i; |
| 347 break; |
| 348 } |
| 349 } |
| 350 if (nItem > -1) { |
| 351 CFPF_SkiaFontDescriptor* pFontDes = |
| 352 (CFPF_SkiaFontDescriptor*)m_FontFaces.ElementAt(nItem); |
| 353 CFPF_SkiaFont* pFont = FX_NEW CFPF_SkiaFont; |
| 354 if (pFont) { |
| 355 if (pFont->InitFont(this, pFontDes, bsFamilyname, dwStyle, uCharset)) { |
| 356 m_FamilyFonts.SetAt((void*)(FX_UINTPTR) dwHash, (void*)pFont); |
| 357 return pFont->Retain(); |
| 358 } |
| 359 pFont->Release(); |
| 360 pFont = NULL; |
| 361 } |
| 362 return pFont; |
| 363 } |
| 364 return NULL; |
| 365 } |
| 366 FXFT_Face CFPF_SkiaFontMgr::GetFontFace(IFX_FileRead* pFileRead, |
| 367 FX_INT32 iFaceIndex) { |
| 368 if (!pFileRead) { |
| 369 return NULL; |
| 370 } |
| 371 if (pFileRead->GetSize() == 0) { |
| 372 return NULL; |
| 373 } |
| 374 if (iFaceIndex < 0) { |
| 375 return NULL; |
| 376 } |
| 377 FXFT_StreamRec streamRec; |
| 378 FXSYS_memset32(&streamRec, 0, sizeof(FXFT_StreamRec)); |
| 379 streamRec.size = pFileRead->GetSize(); |
| 380 streamRec.descriptor.pointer = pFileRead; |
| 381 streamRec.read = FPF_SkiaStream_Read; |
| 382 streamRec.close = FPF_SkiaStream_Close; |
| 383 FXFT_Open_Args args; |
| 384 args.flags = FT_OPEN_STREAM; |
| 385 args.stream = &streamRec; |
| 386 FXFT_Face face; |
| 387 if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face)) { |
| 388 return NULL; |
| 389 } |
| 390 FXFT_Set_Pixel_Sizes(face, 0, 64); |
| 391 return face; |
| 392 } |
| 393 FXFT_Face CFPF_SkiaFontMgr::GetFontFace(FX_BSTR bsFile, FX_INT32 iFaceIndex) { |
| 394 if (bsFile.IsEmpty()) { |
| 395 return NULL; |
| 396 } |
| 397 if (iFaceIndex < 0) { |
| 398 return NULL; |
| 399 } |
| 400 FXFT_Open_Args args; |
| 401 args.flags = FT_OPEN_PATHNAME; |
| 402 args.pathname = (FT_String*)bsFile.GetCStr(); |
| 403 FXFT_Face face; |
| 404 if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face)) { |
| 405 return FALSE; |
| 406 } |
| 407 FXFT_Set_Pixel_Sizes(face, 0, 64); |
| 408 return face; |
| 409 } |
| 410 FXFT_Face CFPF_SkiaFontMgr::GetFontFace(FX_LPCBYTE pBuffer, |
| 411 size_t szBuffer, |
| 412 FX_INT32 iFaceIndex) { |
| 413 if (!pBuffer || szBuffer < 1) { |
| 414 return NULL; |
| 415 } |
| 416 if (iFaceIndex < 0) { |
| 417 return NULL; |
| 418 } |
| 419 FXFT_Open_Args args; |
| 420 args.flags = FT_OPEN_MEMORY; |
| 421 args.memory_base = pBuffer; |
| 422 args.memory_size = szBuffer; |
| 423 FXFT_Face face; |
| 424 if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face)) { |
| 425 return FALSE; |
| 426 } |
| 427 FXFT_Set_Pixel_Sizes(face, 0, 64); |
| 428 return face; |
| 429 } |
| 430 void CFPF_SkiaFontMgr::ScanPath(FX_BSTR path) { |
| 431 void* handle = FX_OpenFolder(path.GetCStr()); |
| 432 if (!handle) { |
| 433 return; |
| 434 } |
| 435 CFX_ByteString filename; |
| 436 FX_BOOL bFolder = FALSE; |
| 437 while (FX_GetNextFile(handle, filename, bFolder)) { |
| 438 if (bFolder) { |
| 439 if (filename == FX_BSTRC(".") || filename == FX_BSTRC("..")) { |
| 440 continue; |
| 441 } |
120 } else { | 442 } else { |
121 while (pStr < pStrEnd) { | 443 CFX_ByteString ext = filename.Right(4); |
122 uHashCode = 31 * uHashCode + *pStr ++; | 444 ext.MakeLower(); |
123 } | 445 if (ext != FX_BSTRC(".ttf") && ext != FX_BSTRC(".ttc")) { |
124 } | 446 continue; |
125 return uHashCode; | 447 } |
126 } | 448 } |
127 enum FPF_SKIACHARSET { | 449 CFX_ByteString fullpath = path; |
128 FPF_SKIACHARSET_Ansi» » » = 1 << 0, | 450 fullpath += "/"; |
129 FPF_SKIACHARSET_Default» » » = 1 << 1, | 451 fullpath += filename; |
130 FPF_SKIACHARSET_Symbol» » » = 1 << 2, | 452 if (bFolder) { |
131 FPF_SKIACHARSET_ShiftJIS» » = 1 << 3, | 453 ScanPath(fullpath); |
132 FPF_SKIACHARSET_Korean» » » = 1 << 4, | 454 } else { |
133 FPF_SKIACHARSET_Johab» » » = 1 << 5, | 455 ScanFile(fullpath); |
134 FPF_SKIACHARSET_GB2312» » » = 1 << 6, | 456 } |
135 FPF_SKIACHARSET_BIG5» » » = 1 << 7, | 457 } |
136 FPF_SKIACHARSET_Greek» » » = 1 << 8, | 458 FX_CloseFolder(handle); |
137 FPF_SKIACHARSET_Turkish» » » = 1 << 9, | 459 } |
138 FPF_SKIACHARSET_Vietnamese» » = 1 << 10, | 460 void CFPF_SkiaFontMgr::ScanFile(FX_BSTR file) { |
139 FPF_SKIACHARSET_Hebrew» » » = 1 << 11, | 461 FXFT_Face face = GetFontFace(file); |
140 FPF_SKIACHARSET_Arabic» » » = 1 << 12, | 462 if (face) { |
141 FPF_SKIACHARSET_Baltic» » » = 1 << 13, | 463 CFPF_SkiaPathFont* pFontDesc = FX_NEW CFPF_SkiaPathFont; |
142 FPF_SKIACHARSET_Cyrillic» » = 1 << 14, | 464 if (!pFontDesc) { |
143 FPF_SKIACHARSET_Thai» » » = 1 << 15, | 465 return; |
144 FPF_SKIACHARSET_EeasternEuropean = 1 << 16, | 466 } |
145 FPF_SKIACHARSET_PC» » » » = 1 << 17, | 467 pFontDesc->SetPath(file.GetCStr()); |
146 FPF_SKIACHARSET_OEM»» » » = 1 << 18, | 468 ReportFace(face, pFontDesc); |
| 469 m_FontFaces.Add(pFontDesc); |
| 470 FXFT_Done_Face(face); |
| 471 } |
| 472 } |
| 473 static const FX_DWORD g_FPFSkiaFontCharsets[] = { |
| 474 FPF_SKIACHARSET_Ansi, FPF_SKIACHARSET_EeasternEuropean, |
| 475 FPF_SKIACHARSET_Cyrillic, FPF_SKIACHARSET_Greek, |
| 476 FPF_SKIACHARSET_Turkish, FPF_SKIACHARSET_Hebrew, |
| 477 FPF_SKIACHARSET_Arabic, FPF_SKIACHARSET_Baltic, |
| 478 0, 0, |
| 479 0, 0, |
| 480 0, 0, |
| 481 0, 0, |
| 482 FPF_SKIACHARSET_Thai, FPF_SKIACHARSET_ShiftJIS, |
| 483 FPF_SKIACHARSET_GB2312, FPF_SKIACHARSET_Korean, |
| 484 FPF_SKIACHARSET_BIG5, FPF_SKIACHARSET_Johab, |
| 485 0, 0, |
| 486 0, 0, |
| 487 0, 0, |
| 488 0, 0, |
| 489 FPF_SKIACHARSET_OEM, FPF_SKIACHARSET_Symbol, |
147 }; | 490 }; |
148 static FX_DWORD FPF_SkiaGetCharset(FX_BYTE uCharset) | 491 static FX_DWORD FPF_SkiaGetFaceCharset(TT_OS2* pOS2) { |
149 { | 492 FX_DWORD dwCharset = 0; |
150 switch (uCharset) { | 493 if (pOS2) { |
151 case FXFONT_ANSI_CHARSET: | 494 for (FX_INT32 i = 0; i < 32; i++) { |
152 return FPF_SKIACHARSET_Ansi; | 495 if (pOS2->ulCodePageRange1 & (1 << i)) { |
153 case FXFONT_DEFAULT_CHARSET: | 496 dwCharset |= g_FPFSkiaFontCharsets[i]; |
154 return FPF_SKIACHARSET_Default; | 497 } |
155 case FXFONT_SYMBOL_CHARSET: | 498 } |
156 return FPF_SKIACHARSET_Symbol; | 499 } |
157 case FXFONT_SHIFTJIS_CHARSET: | 500 dwCharset |= FPF_SKIACHARSET_Default; |
158 return FPF_SKIACHARSET_ShiftJIS; | 501 return dwCharset; |
159 case FXFONT_HANGEUL_CHARSET: | 502 } |
160 return FPF_SKIACHARSET_Korean; | 503 void CFPF_SkiaFontMgr::ReportFace(FXFT_Face face, |
161 case FXFONT_GB2312_CHARSET: | 504 CFPF_SkiaFontDescriptor* pFontDesc) { |
162 return FPF_SKIACHARSET_GB2312; | 505 if (!face || !pFontDesc) { |
163 case FXFONT_CHINESEBIG5_CHARSET: | 506 return; |
164 return FPF_SKIACHARSET_BIG5; | 507 } |
165 case FXFONT_GREEK_CHARSET: | 508 pFontDesc->SetFamily(FXFT_Get_Face_Family_Name(face)); |
166 return FPF_SKIACHARSET_Greek; | 509 if (FXFT_Is_Face_Bold(face)) { |
167 case FXFONT_TURKISH_CHARSET: | 510 pFontDesc->m_dwStyle |= FXFONT_BOLD; |
168 return FPF_SKIACHARSET_Turkish; | 511 } |
169 case FXFONT_HEBREW_CHARSET: | 512 if (FXFT_Is_Face_Italic(face)) { |
170 return FPF_SKIACHARSET_Hebrew; | 513 pFontDesc->m_dwStyle |= FXFONT_ITALIC; |
171 case FXFONT_ARABIC_CHARSET: | 514 } |
172 return FPF_SKIACHARSET_Arabic; | 515 if (FT_IS_FIXED_WIDTH(face)) { |
173 case FXFONT_BALTIC_CHARSET: | 516 pFontDesc->m_dwStyle |= FXFONT_FIXED_PITCH; |
174 return FPF_SKIACHARSET_Baltic; | 517 } |
175 case FXFONT_RUSSIAN_CHARSET: | 518 TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2); |
176 return FPF_SKIACHARSET_Cyrillic; | 519 if (pOS2) { |
177 case FXFONT_THAI_CHARSET: | 520 if (pOS2->ulCodePageRange1 & (1 << 31)) { |
178 return FPF_SKIACHARSET_Thai; | 521 pFontDesc->m_dwStyle |= FXFONT_SYMBOLIC; |
179 case FXFONT_EASTEUROPE_CHARSET: | 522 } |
180 return FPF_SKIACHARSET_EeasternEuropean; | 523 if (pOS2->panose[0] == 2) { |
181 } | 524 FX_BYTE uSerif = pOS2->panose[1]; |
182 return FPF_SKIACHARSET_Default; | 525 if ((uSerif > 1 && uSerif < 10) || uSerif > 13) { |
183 } | 526 pFontDesc->m_dwStyle |= FXFONT_SERIF; |
184 static FX_DWORD FPF_SKIANormalizeFontName(FX_BSTR bsfamily) | 527 } |
185 { | 528 } |
186 FX_DWORD dwHash = 0; | 529 } |
187 FX_INT32 iLength = bsfamily.GetLength(); | 530 if (pOS2 && (pOS2->ulCodePageRange1 & (1 << 31))) { |
188 FX_LPCSTR pBuffer = bsfamily.GetCStr(); | 531 pFontDesc->m_dwStyle |= FXFONT_SYMBOLIC; |
189 for (FX_INT32 i = 0; i < iLength; i++) { | 532 } |
190 FX_CHAR ch = pBuffer[i]; | 533 pFontDesc->m_dwCharsets = FPF_SkiaGetFaceCharset(pOS2); |
191 if (ch == ' ' || ch == '-' || ch == ',') { | 534 pFontDesc->m_iFaceIndex = face->face_index; |
192 continue; | 535 pFontDesc->m_iGlyphNum = face->num_glyphs; |
193 } | 536 } |
194 dwHash = 31 * dwHash + FXSYS_tolower(ch); | 537 void CFPF_SkiaFontMgr::OutputSystemFonts() { |
195 } | |
196 return dwHash; | |
197 } | |
198 static FX_DWORD FPF_SKIAGetFamilyHash(FX_BSTR bsFamily, FX_DWORD dwStyle, FX_BYT
E uCharset) | |
199 { | |
200 CFX_ByteString bsFont(bsFamily); | |
201 if (dwStyle & FXFONT_BOLD) { | |
202 bsFont += "Bold"; | |
203 } | |
204 if (dwStyle & FXFONT_ITALIC) { | |
205 bsFont += "Italic"; | |
206 } | |
207 if (dwStyle & FXFONT_SERIF) { | |
208 bsFont += "Serif"; | |
209 } | |
210 bsFont += uCharset; | |
211 return FPF_GetHashCode_StringA((FX_LPCSTR)bsFont, bsFont.GetLength(), TRUE); | |
212 } | |
213 static FX_BOOL FPF_SkiaIsCJK(FX_BYTE uCharset) | |
214 { | |
215 return (uCharset == FXFONT_GB2312_CHARSET) || (uCharset == FXFONT_CHINESEBIG
5_CHARSET) | |
216 || (uCharset == FXFONT_HANGEUL_CHARSET) || (uCharset == FXFONT_SHIFTJ
IS_CHARSET); | |
217 } | |
218 static FX_BOOL FPF_SkiaMaybeSymbol(FX_BSTR bsFacename) | |
219 { | |
220 CFX_ByteString bsName = bsFacename; | |
221 bsName.MakeLower(); | |
222 return bsName.Find("symbol") > -1; | |
223 } | |
224 static FX_BOOL FPF_SkiaMaybeArabic(FX_BSTR bsFacename) | |
225 { | |
226 CFX_ByteString bsName = bsFacename; | |
227 bsName.MakeLower(); | |
228 return bsName.Find("arabic") > -1; | |
229 } | |
230 CFPF_SkiaFontMgr::CFPF_SkiaFontMgr() | |
231 : m_bLoaded(FALSE), m_FTLibrary(NULL) | |
232 { | |
233 } | |
234 CFPF_SkiaFontMgr::~CFPF_SkiaFontMgr() | |
235 { | |
236 void *pkey = NULL; | |
237 CFPF_SkiaFont *pValue = NULL; | |
238 FX_POSITION pos = m_FamilyFonts.GetStartPosition(); | |
239 while (pos) { | |
240 m_FamilyFonts.GetNextAssoc(pos, pkey, (void*&)pValue); | |
241 if (pValue) { | |
242 pValue->Release(); | |
243 } | |
244 } | |
245 m_FamilyFonts.RemoveAll(); | |
246 for (FX_INT32 i = m_FontFaces.GetUpperBound(); i >= 0; i--) { | |
247 CFPF_SkiaFontDescriptor *pFont = (CFPF_SkiaFontDescriptor*)m_FontFaces.E
lementAt(i); | |
248 if (pFont) { | |
249 delete pFont; | |
250 } | |
251 } | |
252 m_FontFaces.RemoveAll(); | |
253 if (m_FTLibrary) { | |
254 FXFT_Done_FreeType(m_FTLibrary); | |
255 } | |
256 } | |
257 FX_BOOL CFPF_SkiaFontMgr::InitFTLibrary() | |
258 { | |
259 if (m_FTLibrary == NULL) { | |
260 FXFT_Init_FreeType(&m_FTLibrary); | |
261 } | |
262 return m_FTLibrary != NULL; | |
263 } | |
264 void CFPF_SkiaFontMgr::LoadSystemFonts() | |
265 { | |
266 if (m_bLoaded) { | |
267 return; | |
268 } | |
269 ScanPath(FX_BSTRC("/system/fonts")); | |
270 OutputSystemFonts(); | |
271 m_bLoaded = TRUE; | |
272 } | |
273 void CFPF_SkiaFontMgr::LoadPrivateFont(IFX_FileRead* pFontFile) | |
274 { | |
275 } | |
276 void CFPF_SkiaFontMgr::LoadPrivateFont(FX_BSTR bsFileName) | |
277 { | |
278 } | |
279 void CFPF_SkiaFontMgr::LoadPrivateFont(FX_LPVOID pBuffer, size_t szBuffer) | |
280 { | |
281 } | |
282 IFPF_Font* CFPF_SkiaFontMgr::CreateFont(FX_BSTR bsFamilyname, FX_BYTE uCharset,
FX_DWORD dwStyle, FX_DWORD dwMatch) | |
283 { | |
284 FX_DWORD dwHash = FPF_SKIAGetFamilyHash(bsFamilyname, dwStyle, uCharset); | |
285 IFPF_Font *pFont = NULL; | |
286 if (m_FamilyFonts.Lookup((void*)(FX_UINTPTR)dwHash, (void*&)pFont)) { | |
287 if (pFont) { | |
288 return pFont->Retain(); | |
289 } | |
290 } | |
291 FX_DWORD dwFaceName = FPF_SKIANormalizeFontName(bsFamilyname); | |
292 FX_DWORD dwSubst = FPF_SkiaGetSubstFont(dwFaceName); | |
293 FX_DWORD dwSubstSans = FPF_SkiaGetSansFont(dwFaceName); | |
294 FX_BOOL bMaybeSymbol = FPF_SkiaMaybeSymbol(bsFamilyname); | |
295 if (uCharset != FXFONT_ARABIC_CHARSET && FPF_SkiaMaybeArabic(bsFamilyname))
{ | |
296 uCharset = FXFONT_ARABIC_CHARSET; | |
297 } else if (uCharset == FXFONT_ANSI_CHARSET && (dwMatch & FPF_MATCHFONT_REPLA
CEANSI)) { | |
298 uCharset = FXFONT_DEFAULT_CHARSET; | |
299 } | |
300 FX_INT32 nExpectVal = FPF_SKIAMATCHWEIGHT_NAME1 + FPF_SKIAMATCHWEIGHT_1 * 3
+ FPF_SKIAMATCHWEIGHT_2 * 2; | |
301 FX_INT32 nItem = -1; | |
302 FX_INT32 nMax = -1; | |
303 FX_INT32 nGlyphNum = 0; | |
304 for (FX_INT32 i = m_FontFaces.GetUpperBound(); i >= 0; i--) { | |
305 CFPF_SkiaPathFont *pFontDes = (CFPF_SkiaPathFont*)m_FontFaces.ElementAt(
i); | |
306 if(!(pFontDes->m_dwCharsets & FPF_SkiaGetCharset(uCharset))) { | |
307 continue; | |
308 } | |
309 FX_INT32 nFind = 0; | |
310 FX_DWORD dwSysFontName = FPF_SKIANormalizeFontName(pFontDes->m_pFamily); | |
311 if (dwFaceName == dwSysFontName) { | |
312 nFind += FPF_SKIAMATCHWEIGHT_NAME1; | |
313 } | |
314 FX_BOOL bMatchedName = (nFind == FPF_SKIAMATCHWEIGHT_NAME1); | |
315 if ((dwStyle & FXFONT_BOLD) == (pFontDes->m_dwStyle & FXFONT_BOLD)) { | |
316 nFind += FPF_SKIAMATCHWEIGHT_1; | |
317 } | |
318 if ((dwStyle & FXFONT_ITALIC) == (pFontDes->m_dwStyle & FXFONT_ITALIC))
{ | |
319 nFind += FPF_SKIAMATCHWEIGHT_1; | |
320 } | |
321 if ((dwStyle & FXFONT_FIXED_PITCH) == (pFontDes->m_dwStyle & FXFONT_FIXE
D_PITCH)) { | |
322 nFind += FPF_SKIAMATCHWEIGHT_2; | |
323 } | |
324 if ((dwStyle & FXFONT_SERIF) == (pFontDes->m_dwStyle & FXFONT_SERIF)) { | |
325 nFind += FPF_SKIAMATCHWEIGHT_1; | |
326 } | |
327 if ((dwStyle & FXFONT_SCRIPT) == (pFontDes->m_dwStyle & FXFONT_SCRIPT))
{ | |
328 nFind += FPF_SKIAMATCHWEIGHT_2; | |
329 } | |
330 if (dwSubst == dwSysFontName || dwSubstSans == dwSysFontName) { | |
331 nFind += FPF_SKIAMATCHWEIGHT_NAME2; | |
332 bMatchedName = TRUE; | |
333 } | |
334 if (uCharset == FXFONT_DEFAULT_CHARSET || bMaybeSymbol) { | |
335 if (nFind > nMax && bMatchedName) { | |
336 nMax = nFind; | |
337 nItem = i; | |
338 } | |
339 } else if (FPF_SkiaIsCJK(uCharset)) { | |
340 if (bMatchedName || pFontDes->m_iGlyphNum > nGlyphNum) { | |
341 nItem = i; | |
342 nGlyphNum = pFontDes->m_iGlyphNum; | |
343 } | |
344 } else if (nFind > nMax) { | |
345 nMax = nFind; | |
346 nItem = i; | |
347 } | |
348 if (nExpectVal <= nFind) { | |
349 nItem = i; | |
350 break; | |
351 } | |
352 } | |
353 if (nItem > -1) { | |
354 CFPF_SkiaFontDescriptor *pFontDes = (CFPF_SkiaFontDescriptor*)m_FontFace
s.ElementAt(nItem); | |
355 CFPF_SkiaFont *pFont = FX_NEW CFPF_SkiaFont; | |
356 if (pFont) { | |
357 if (pFont->InitFont(this, pFontDes, bsFamilyname, dwStyle, uCharset)
) { | |
358 m_FamilyFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont); | |
359 return pFont->Retain(); | |
360 } | |
361 pFont->Release(); | |
362 pFont = NULL; | |
363 } | |
364 return pFont; | |
365 } | |
366 return NULL; | |
367 } | |
368 FXFT_Face CFPF_SkiaFontMgr::GetFontFace(IFX_FileRead *pFileRead, FX_INT32 iFaceI
ndex) | |
369 { | |
370 if (!pFileRead) { | |
371 return NULL; | |
372 } | |
373 if (pFileRead->GetSize() == 0) { | |
374 return NULL; | |
375 } | |
376 if (iFaceIndex < 0) { | |
377 return NULL; | |
378 } | |
379 FXFT_StreamRec streamRec; | |
380 FXSYS_memset32(&streamRec, 0, sizeof(FXFT_StreamRec)); | |
381 streamRec.size = pFileRead->GetSize(); | |
382 streamRec.descriptor.pointer = pFileRead; | |
383 streamRec.read = FPF_SkiaStream_Read; | |
384 streamRec.close = FPF_SkiaStream_Close; | |
385 FXFT_Open_Args args; | |
386 args.flags = FT_OPEN_STREAM; | |
387 args.stream = &streamRec; | |
388 FXFT_Face face; | |
389 if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face)) { | |
390 return NULL; | |
391 } | |
392 FXFT_Set_Pixel_Sizes(face, 0, 64); | |
393 return face; | |
394 } | |
395 FXFT_Face CFPF_SkiaFontMgr::GetFontFace(FX_BSTR bsFile, FX_INT32 iFaceIndex ) | |
396 { | |
397 if (bsFile.IsEmpty()) { | |
398 return NULL; | |
399 } | |
400 if (iFaceIndex < 0) { | |
401 return NULL; | |
402 } | |
403 FXFT_Open_Args args; | |
404 args.flags = FT_OPEN_PATHNAME; | |
405 args.pathname = (FT_String*)bsFile.GetCStr(); | |
406 FXFT_Face face; | |
407 if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face)) { | |
408 return FALSE; | |
409 } | |
410 FXFT_Set_Pixel_Sizes(face, 0, 64); | |
411 return face; | |
412 } | |
413 FXFT_Face CFPF_SkiaFontMgr::GetFontFace(FX_LPCBYTE pBuffer, size_t szBuffer, FX_
INT32 iFaceIndex ) | |
414 { | |
415 if (!pBuffer || szBuffer < 1) { | |
416 return NULL; | |
417 } | |
418 if (iFaceIndex < 0) { | |
419 return NULL; | |
420 } | |
421 FXFT_Open_Args args; | |
422 args.flags = FT_OPEN_MEMORY; | |
423 args.memory_base = pBuffer; | |
424 args.memory_size = szBuffer; | |
425 FXFT_Face face; | |
426 if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face)) { | |
427 return FALSE; | |
428 } | |
429 FXFT_Set_Pixel_Sizes(face, 0, 64); | |
430 return face; | |
431 } | |
432 void CFPF_SkiaFontMgr::ScanPath(FX_BSTR path) | |
433 { | |
434 void *handle = FX_OpenFolder(path.GetCStr()); | |
435 if (!handle) { | |
436 return; | |
437 } | |
438 CFX_ByteString filename; | |
439 FX_BOOL bFolder = FALSE; | |
440 while (FX_GetNextFile(handle, filename, bFolder)) { | |
441 if (bFolder) { | |
442 if (filename == FX_BSTRC(".") || filename == FX_BSTRC("..")) { | |
443 continue; | |
444 } | |
445 } else { | |
446 CFX_ByteString ext = filename.Right(4); | |
447 ext.MakeLower(); | |
448 if (ext != FX_BSTRC(".ttf") && ext != FX_BSTRC(".ttc")) { | |
449 continue; | |
450 } | |
451 } | |
452 CFX_ByteString fullpath = path; | |
453 fullpath += "/"; | |
454 fullpath += filename; | |
455 if (bFolder) { | |
456 ScanPath(fullpath); | |
457 } else { | |
458 ScanFile(fullpath); | |
459 } | |
460 } | |
461 FX_CloseFolder(handle); | |
462 } | |
463 void CFPF_SkiaFontMgr::ScanFile(FX_BSTR file) | |
464 { | |
465 FXFT_Face face = GetFontFace(file); | |
466 if (face) { | |
467 CFPF_SkiaPathFont *pFontDesc = FX_NEW CFPF_SkiaPathFont; | |
468 if (!pFontDesc) { | |
469 return; | |
470 } | |
471 pFontDesc->SetPath(file.GetCStr()); | |
472 ReportFace(face, pFontDesc); | |
473 m_FontFaces.Add(pFontDesc); | |
474 FXFT_Done_Face(face); | |
475 } | |
476 } | |
477 static const FX_DWORD g_FPFSkiaFontCharsets [] = { | |
478 FPF_SKIACHARSET_Ansi, | |
479 FPF_SKIACHARSET_EeasternEuropean, | |
480 FPF_SKIACHARSET_Cyrillic, | |
481 FPF_SKIACHARSET_Greek, | |
482 FPF_SKIACHARSET_Turkish, | |
483 FPF_SKIACHARSET_Hebrew, | |
484 FPF_SKIACHARSET_Arabic, | |
485 FPF_SKIACHARSET_Baltic, | |
486 0, | |
487 0, | |
488 0, | |
489 0, | |
490 0, | |
491 0, | |
492 0, | |
493 0, | |
494 FPF_SKIACHARSET_Thai, | |
495 FPF_SKIACHARSET_ShiftJIS, | |
496 FPF_SKIACHARSET_GB2312, | |
497 FPF_SKIACHARSET_Korean, | |
498 FPF_SKIACHARSET_BIG5, | |
499 FPF_SKIACHARSET_Johab, | |
500 0, | |
501 0, | |
502 0, | |
503 0, | |
504 0, | |
505 0, | |
506 0, | |
507 0, | |
508 FPF_SKIACHARSET_OEM, | |
509 FPF_SKIACHARSET_Symbol, | |
510 }; | |
511 static FX_DWORD FPF_SkiaGetFaceCharset(TT_OS2 *pOS2) | |
512 { | |
513 FX_DWORD dwCharset = 0; | |
514 if (pOS2) { | |
515 for (FX_INT32 i = 0; i < 32; i++) { | |
516 if (pOS2->ulCodePageRange1 & (1 << i)) { | |
517 dwCharset |= g_FPFSkiaFontCharsets[i]; | |
518 } | |
519 } | |
520 } | |
521 dwCharset |= FPF_SKIACHARSET_Default; | |
522 return dwCharset; | |
523 } | |
524 void CFPF_SkiaFontMgr::ReportFace(FXFT_Face face, CFPF_SkiaFontDescriptor *pFont
Desc) | |
525 { | |
526 if (!face || !pFontDesc) { | |
527 return; | |
528 } | |
529 pFontDesc->SetFamily(FXFT_Get_Face_Family_Name(face)); | |
530 if (FXFT_Is_Face_Bold(face)) { | |
531 pFontDesc->m_dwStyle |= FXFONT_BOLD; | |
532 } | |
533 if (FXFT_Is_Face_Italic(face)) { | |
534 pFontDesc->m_dwStyle |= FXFONT_ITALIC; | |
535 } | |
536 if (FT_IS_FIXED_WIDTH(face)) { | |
537 pFontDesc->m_dwStyle |= FXFONT_FIXED_PITCH; | |
538 } | |
539 TT_OS2 *pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2); | |
540 if (pOS2) { | |
541 if (pOS2->ulCodePageRange1 & (1 << 31)) { | |
542 pFontDesc->m_dwStyle |= FXFONT_SYMBOLIC; | |
543 } | |
544 if (pOS2->panose[0] == 2) { | |
545 FX_BYTE uSerif = pOS2->panose[1]; | |
546 if ((uSerif > 1 && uSerif < 10) || uSerif > 13) { | |
547 pFontDesc->m_dwStyle |= FXFONT_SERIF; | |
548 } | |
549 } | |
550 } | |
551 if (pOS2 && (pOS2->ulCodePageRange1 & (1 << 31))) { | |
552 pFontDesc->m_dwStyle |= FXFONT_SYMBOLIC; | |
553 } | |
554 pFontDesc->m_dwCharsets = FPF_SkiaGetFaceCharset(pOS2); | |
555 pFontDesc->m_iFaceIndex = face->face_index; | |
556 pFontDesc->m_iGlyphNum = face->num_glyphs; | |
557 } | |
558 void CFPF_SkiaFontMgr::OutputSystemFonts() | |
559 { | |
560 } | 538 } |
561 #endif | 539 #endif |
OLD | NEW |