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