Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / core / src / fxge / ge / fx_ge_font.cpp
index 817f371..e3c68e0 100644 (file)
@@ -25,6 +25,52 @@ CFX_Font::CFX_Font()
     m_pDwFont = NULL;
     m_hHandle = NULL;
     m_bDwLoaded = FALSE;
+    m_bLogic = FALSE;\r
+}\r
+FX_BOOL CFX_Font::LoadClone(const CFX_Font* pFont)\r
+{\r
+    if (pFont == NULL) {\r
+        return FALSE;\r
+    }\r
+    m_bLogic = TRUE;\r
+    if (pFont->m_pSubstFont) {\r
+        m_pSubstFont = FX_NEW CFX_SubstFont;\r
+        if (!m_pSubstFont) {\r
+            return FALSE;\r
+        }\r
+        m_pSubstFont->m_Charset = pFont->m_pSubstFont->m_Charset;\r
+        m_pSubstFont->m_ExtHandle = pFont->m_pSubstFont->m_ExtHandle;\r
+        m_pSubstFont->m_SubstFlags = pFont->m_pSubstFont->m_SubstFlags;\r
+        m_pSubstFont->m_Weight = pFont->m_pSubstFont->m_Weight;\r
+        m_pSubstFont->m_Family = pFont->m_pSubstFont->m_Family;\r
+        m_pSubstFont->m_ItalicAngle = pFont->m_pSubstFont->m_ItalicAngle;\r
+    }\r
+    if (pFont->m_OtfFontData.GetSize()) {\r
+        m_OtfFontData.AttachData(pFont->m_OtfFontData.GetBuffer(), pFont->m_OtfFontData.GetSize());\r
+    }\r
+    m_Face = pFont->m_Face;\r
+    m_bEmbedded = pFont->m_bEmbedded;\r
+    m_bVertical = pFont->m_bVertical;\r
+    m_dwSize = pFont->m_dwSize;\r
+    m_pFontData = pFont->m_pFontData;\r
+    m_pGsubData = pFont->m_pGsubData;\r
+#ifdef FOXIT_CHROME_BUILD\r
+    if (pFont->m_pFontDataAllocation) {\r
+        m_pFontDataAllocation = FX_Alloc(FX_BYTE, m_dwSize);\r
+        if (!m_pFontDataAllocation) {\r
+            return FALSE;\r
+        }\r
+        m_pFontData = m_pFontDataAllocation;\r
+        FXSYS_memcpy32(m_pFontDataAllocation, pFont->m_pFontDataAllocation, m_dwSize);\r
+    }\r
+#endif\r
+    m_pPlatformFont = pFont->m_pPlatformFont;\r
+    m_pPlatformFontCollection = pFont->m_pPlatformFontCollection;\r
+    m_pDwFont = pFont->m_pDwFont;\r
+    m_hHandle = pFont->m_hHandle;\r
+    m_bDwLoaded = pFont->m_bDwLoaded;\r
+    m_pOwnedStream = pFont->m_pOwnedStream;\r
+    return TRUE;\r
 }
 CFX_Font::~CFX_Font()
 {
@@ -38,6 +84,10 @@ CFX_Font::~CFX_Font()
         m_pFontDataAllocation = NULL;
     }
 #endif
+    if (m_bLogic) {\r
+        m_OtfFontData.DetachBuffer();\r
+        return;\r
+    }\r
     if (m_Face) {
 #ifdef FOXIT_CHROME_BUILD
         if (FXFT_Get_Face_External_Stream(m_Face)) {
@@ -108,7 +158,7 @@ extern "C" {
     {
     }
 };
-FX_BOOL _LoadFile(FXFT_Library library, FXFT_Face* Face, IFX_FileRead* pFile, FXFT_Stream* stream)
+FX_BOOL _LoadFile(FXFT_Library library, FXFT_Face* Face, IFX_FileRead* pFile, FXFT_Stream* stream, FX_INT32 faceIndex = 0)\r
 {
     FXFT_Stream stream1 = (FXFT_Stream)FX_Alloc(FX_BYTE, sizeof (FXFT_StreamRec));
     if (!stream1) {
@@ -123,7 +173,7 @@ FX_BOOL _LoadFile(FXFT_Library library, FXFT_Face* Face, IFX_FileRead* pFile, FX
     FXFT_Open_Args args;
     args.flags = FT_OPEN_STREAM;
     args.stream = stream1;
-    if (FXFT_Open_Face(library, &args, 0, Face)) {
+    if (FXFT_Open_Face(library, &args, faceIndex, Face)) {\r
         FX_Free(stream1);
         return FALSE;
     }
@@ -132,19 +182,21 @@ FX_BOOL _LoadFile(FXFT_Library library, FXFT_Face* Face, IFX_FileRead* pFile, FX
     }
     return TRUE;
 }
-FX_BOOL CFX_Font::LoadFile(IFX_FileRead* pFile)
+FX_BOOL CFX_Font::LoadFile(IFX_FileRead* pFile, int nFaceIndex, int* pFaceCount)\r
 {
     m_bEmbedded = FALSE;
     FXFT_Library library;
-    if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL) {
+    if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL)\r
         FXFT_Init_FreeType(&CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary);
-    }
     library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary;
     FXFT_Stream stream = NULL;
-    if (!_LoadFile(library, &m_Face, pFile, &stream)) {
+    if (!_LoadFile(library, &m_Face, pFile, &stream, nFaceIndex))\r
         return FALSE;
-    }
+    if (pFaceCount)\r
+        *pFaceCount = (int)m_Face->num_faces;\r
+#ifndef FOXIT_CHROME_BUILD\r
     m_pOwnedStream = stream;
+#endif\r
     FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
     return TRUE;
 }
@@ -455,3 +507,168 @@ IFX_FontEncoding* FXGE_CreateUnicodeEncoding(CFX_Font* pFont)
     pEncoding = FX_NEW CFX_UnicodeEncoding(pFont);
     return pEncoding;
 }
+CFX_FontEncodingEX::CFX_FontEncodingEX()\r
+{\r
+    m_pFont = NULL;\r
+    m_nEncodingID = FXFM_ENCODING_NONE;\r
+}\r
+FX_BOOL CFX_FontEncodingEX::Init(CFX_Font* pFont, FX_DWORD EncodingID)\r
+{\r
+    if (!pFont) {\r
+        return FALSE;\r
+    }\r
+    m_pFont = pFont;\r
+    m_nEncodingID = EncodingID;\r
+    return TRUE;\r
+}\r
+FX_DWORD CFX_FontEncodingEX::GlyphFromCharCode(FX_DWORD charcode)\r
+{\r
+    FXFT_Face face = m_pFont->m_Face;\r
+    FT_UInt nIndex = FXFT_Get_Char_Index(face, charcode);\r
+    if (nIndex > 0) {\r
+        return nIndex;\r
+    }\r
+    int nmaps = FXFT_Get_Face_CharmapCount(face);\r
+    int m = 0;\r
+    while (m < nmaps) {\r
+        int nEncodingID = FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[m++]);\r
+        if (m_nEncodingID == nEncodingID) {\r
+            continue;\r
+        }\r
+        int error = FXFT_Select_Charmap(face, nEncodingID);\r
+        if (error) {\r
+            continue;\r
+        }\r
+        nIndex = FXFT_Get_Char_Index(face, charcode);\r
+        if (nIndex > 0) {\r
+            m_nEncodingID = nEncodingID;\r
+            return nIndex;\r
+        }\r
+    }\r
+    FXFT_Select_Charmap(face, m_nEncodingID);\r
+    return 0;\r
+}\r
+CFX_WideString CFX_FontEncodingEX::UnicodeFromCharCode(FX_DWORD charcode) const\r
+{\r
+    if (m_nEncodingID == FXFM_ENCODING_UNICODE) {\r
+        return CFX_WideString((FX_WCHAR)charcode);\r
+    }\r
+    return CFX_WideString((FX_WCHAR)0);\r
+}\r
+FX_DWORD CFX_FontEncodingEX::CharCodeFromUnicode(FX_WCHAR Unicode) const\r
+{\r
+    if (m_nEncodingID == FXFM_ENCODING_UNICODE || m_nEncodingID == FXFM_ENCODING_MS_SYMBOL) {\r
+        return Unicode;\r
+    }\r
+    FXFT_Face face = m_pFont->m_Face;\r
+    int nmaps = FXFT_Get_Face_CharmapCount(face);\r
+    for (int i = 0; i < nmaps; i++) {\r
+        int nEncodingID = FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i]);\r
+        if (nEncodingID == FXFM_ENCODING_UNICODE || nEncodingID == FXFM_ENCODING_MS_SYMBOL) {\r
+            return Unicode;\r
+        }\r
+    }\r
+    return -1;\r
+}\r
+FX_BOOL CFX_FontEncodingEX::IsUnicodeCompatible() const\r
+{\r
+    return m_nEncodingID == FXFM_ENCODING_UNICODE;\r
+}\r
+FX_DWORD CFX_FontEncodingEX::GlyphIndexFromName(FX_LPCSTR pStrName)\r
+{\r
+    FXFT_Face face = m_pFont->m_Face;\r
+    return FT_Get_Name_Index(face, (FT_String*)pStrName);\r
+}\r
+CFX_ByteString CFX_FontEncodingEX::NameFromGlyphIndex(FX_DWORD dwGlyphIndex)\r
+{\r
+    FXFT_Face face = m_pFont->m_Face;\r
+    CFX_ByteString glyphName("                ");\r
+    if (FT_HAS_GLYPH_NAMES(((FT_Face)face))) {\r
+        if (FT_Get_Glyph_Name((FT_Face)face, dwGlyphIndex, (FT_Pointer)(FX_LPCSTR)glyphName, 16)) {\r
+            glyphName.Empty();\r
+            return glyphName;\r
+        }\r
+        return glyphName;\r
+    } else {\r
+        return glyphName;\r
+    }\r
+}\r
+FX_DWORD CFX_FontEncodingEX::CharCodeFromGlyphIndex(FX_DWORD dwGlyphIndex)\r
+{\r
+    FXFT_Face face = m_pFont->GetFace();\r
+    FX_DWORD  charcode;\r
+    FT_UInt  gid;\r
+    charcode = FT_Get_First_Char((FT_Face)face, &gid);\r
+    while (gid != 0) {\r
+        if (dwGlyphIndex == gid) {\r
+            return charcode;\r
+        }\r
+        charcode = FT_Get_Next_Char((FT_Face)face, charcode, &gid);\r
+    }\r
+    int nmaps = FXFT_Get_Face_CharmapCount(face);\r
+    int m = 0;\r
+    while (m < nmaps) {\r
+        int nEncodingID = FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[m++]);\r
+        if (m_nEncodingID == nEncodingID) {\r
+            continue;\r
+        }\r
+        int error = FXFT_Select_Charmap(face, nEncodingID);\r
+        if (error) {\r
+            continue;\r
+        }\r
+        charcode = FT_Get_First_Char((FT_Face)face, &gid);\r
+        while (gid != 0) {\r
+            if (dwGlyphIndex == gid) {\r
+                m_nEncodingID = nEncodingID;\r
+                return charcode;\r
+            }\r
+            charcode = FT_Get_Next_Char((FT_Face)face, charcode, &gid);\r
+        }\r
+    }\r
+    return (FX_DWORD) - 1;\r
+}\r
+static const FX_DWORD gs_EncodingID[] = {\r
+    FXFM_ENCODING_MS_SYMBOL,\r
+    FXFM_ENCODING_UNICODE,\r
+    FXFM_ENCODING_MS_SJIS,\r
+    FXFM_ENCODING_MS_GB2312,\r
+    FXFM_ENCODING_MS_BIG5,\r
+    FXFM_ENCODING_MS_WANSUNG,\r
+    FXFM_ENCODING_MS_JOHAB,\r
+    FXFM_ENCODING_ADOBE_STANDARD,\r
+    FXFM_ENCODING_ADOBE_EXPERT,\r
+    FXFM_ENCODING_ADOBE_CUSTOM,\r
+    FXFM_ENCODING_ADOBE_LATIN_1,\r
+    FXFM_ENCODING_OLD_LATIN_2,\r
+    FXFM_ENCODING_APPLE_ROMAN\r
+};\r
+static IFX_FontEncodingEx* _FXFM_CreateFontEncoding(CFX_Font* pFont, FX_DWORD nEncodingID)\r
+{\r
+    int error = FXFT_Select_Charmap(pFont->m_Face, nEncodingID);\r
+    if (error) {\r
+        return NULL;\r
+    }\r
+    CFX_FontEncodingEX* pFontEncoding = FX_NEW CFX_FontEncodingEX;\r
+    if (pFontEncoding && !pFontEncoding->Init(pFont, nEncodingID)) {\r
+        delete pFontEncoding;\r
+        pFontEncoding = NULL;\r
+    }\r
+    return pFontEncoding;\r
+}\r
+IFX_FontEncodingEx* FX_CreateFontEncodingEx(CFX_Font* pFont, FX_DWORD nEncodingID)\r
+{\r
+    if (!pFont || !pFont->m_Face) {\r
+        return NULL;\r
+    }\r
+    if (nEncodingID != FXFM_ENCODING_NONE) {\r
+        return _FXFM_CreateFontEncoding(pFont, nEncodingID);\r
+    }\r
+    static int s_count = sizeof(gs_EncodingID) / sizeof(FX_DWORD);\r
+    for (int i = 0; i < s_count; i++) {\r
+        IFX_FontEncodingEx* pFontEncoding = _FXFM_CreateFontEncoding(pFont, gs_EncodingID[i]);\r
+        if (pFontEncoding) {\r
+            return pFontEncoding;\r
+        }\r
+    }\r
+    return NULL;\r
+}\r