From fdc00a7042d912aafaabddae4d9c84199921ef23 Mon Sep 17 00:00:00 2001 From: Bo Xu Date: Tue, 28 Oct 2014 23:03:33 -0700 Subject: Merge XFA to PDFium master at 4dc95e7 on 10/28/2014 --- core/src/fxge/ge/fx_ge_font.cpp | 231 +++++++++++++++++++++++++++++++++++-- core/src/fxge/ge/fx_ge_fontmap.cpp | 69 +++++++++++ core/src/fxge/ge/text_int.h | 21 +++- 3 files changed, 313 insertions(+), 8 deletions(-) (limited to 'core/src/fxge') diff --git a/core/src/fxge/ge/fx_ge_font.cpp b/core/src/fxge/ge/fx_ge_font.cpp index 817f3712d9..e3c68e0f65 100644 --- a/core/src/fxge/ge/fx_ge_font.cpp +++ b/core/src/fxge/ge/fx_ge_font.cpp @@ -25,6 +25,52 @@ CFX_Font::CFX_Font() m_pDwFont = NULL; m_hHandle = NULL; m_bDwLoaded = FALSE; + m_bLogic = FALSE; +} +FX_BOOL CFX_Font::LoadClone(const CFX_Font* pFont) +{ + if (pFont == NULL) { + return FALSE; + } + m_bLogic = TRUE; + if (pFont->m_pSubstFont) { + m_pSubstFont = FX_NEW CFX_SubstFont; + if (!m_pSubstFont) { + return FALSE; + } + m_pSubstFont->m_Charset = pFont->m_pSubstFont->m_Charset; + m_pSubstFont->m_ExtHandle = pFont->m_pSubstFont->m_ExtHandle; + m_pSubstFont->m_SubstFlags = pFont->m_pSubstFont->m_SubstFlags; + m_pSubstFont->m_Weight = pFont->m_pSubstFont->m_Weight; + m_pSubstFont->m_Family = pFont->m_pSubstFont->m_Family; + m_pSubstFont->m_ItalicAngle = pFont->m_pSubstFont->m_ItalicAngle; + } + if (pFont->m_OtfFontData.GetSize()) { + m_OtfFontData.AttachData(pFont->m_OtfFontData.GetBuffer(), pFont->m_OtfFontData.GetSize()); + } + m_Face = pFont->m_Face; + m_bEmbedded = pFont->m_bEmbedded; + m_bVertical = pFont->m_bVertical; + m_dwSize = pFont->m_dwSize; + m_pFontData = pFont->m_pFontData; + m_pGsubData = pFont->m_pGsubData; +#ifdef FOXIT_CHROME_BUILD + if (pFont->m_pFontDataAllocation) { + m_pFontDataAllocation = FX_Alloc(FX_BYTE, m_dwSize); + if (!m_pFontDataAllocation) { + return FALSE; + } + m_pFontData = m_pFontDataAllocation; + FXSYS_memcpy32(m_pFontDataAllocation, pFont->m_pFontDataAllocation, m_dwSize); + } +#endif + m_pPlatformFont = pFont->m_pPlatformFont; + m_pPlatformFontCollection = pFont->m_pPlatformFontCollection; + m_pDwFont = pFont->m_pDwFont; + m_hHandle = pFont->m_hHandle; + m_bDwLoaded = pFont->m_bDwLoaded; + m_pOwnedStream = pFont->m_pOwnedStream; + return TRUE; } CFX_Font::~CFX_Font() { @@ -38,6 +84,10 @@ CFX_Font::~CFX_Font() m_pFontDataAllocation = NULL; } #endif + if (m_bLogic) { + m_OtfFontData.DetachBuffer(); + return; + } 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) { 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)) { 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) { m_bEmbedded = FALSE; FXFT_Library library; - if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL) { + if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL) 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)) return FALSE; - } + if (pFaceCount) + *pFaceCount = (int)m_Face->num_faces; +#ifndef FOXIT_CHROME_BUILD m_pOwnedStream = stream; +#endif 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() +{ + m_pFont = NULL; + m_nEncodingID = FXFM_ENCODING_NONE; +} +FX_BOOL CFX_FontEncodingEX::Init(CFX_Font* pFont, FX_DWORD EncodingID) +{ + if (!pFont) { + return FALSE; + } + m_pFont = pFont; + m_nEncodingID = EncodingID; + return TRUE; +} +FX_DWORD CFX_FontEncodingEX::GlyphFromCharCode(FX_DWORD charcode) +{ + FXFT_Face face = m_pFont->m_Face; + FT_UInt nIndex = FXFT_Get_Char_Index(face, charcode); + if (nIndex > 0) { + return nIndex; + } + int nmaps = FXFT_Get_Face_CharmapCount(face); + int m = 0; + while (m < nmaps) { + int nEncodingID = FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[m++]); + if (m_nEncodingID == nEncodingID) { + continue; + } + int error = FXFT_Select_Charmap(face, nEncodingID); + if (error) { + continue; + } + nIndex = FXFT_Get_Char_Index(face, charcode); + if (nIndex > 0) { + m_nEncodingID = nEncodingID; + return nIndex; + } + } + FXFT_Select_Charmap(face, m_nEncodingID); + return 0; +} +CFX_WideString CFX_FontEncodingEX::UnicodeFromCharCode(FX_DWORD charcode) const +{ + if (m_nEncodingID == FXFM_ENCODING_UNICODE) { + return CFX_WideString((FX_WCHAR)charcode); + } + return CFX_WideString((FX_WCHAR)0); +} +FX_DWORD CFX_FontEncodingEX::CharCodeFromUnicode(FX_WCHAR Unicode) const +{ + if (m_nEncodingID == FXFM_ENCODING_UNICODE || m_nEncodingID == FXFM_ENCODING_MS_SYMBOL) { + return Unicode; + } + FXFT_Face face = m_pFont->m_Face; + int nmaps = FXFT_Get_Face_CharmapCount(face); + for (int i = 0; i < nmaps; i++) { + int nEncodingID = FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i]); + if (nEncodingID == FXFM_ENCODING_UNICODE || nEncodingID == FXFM_ENCODING_MS_SYMBOL) { + return Unicode; + } + } + return -1; +} +FX_BOOL CFX_FontEncodingEX::IsUnicodeCompatible() const +{ + return m_nEncodingID == FXFM_ENCODING_UNICODE; +} +FX_DWORD CFX_FontEncodingEX::GlyphIndexFromName(FX_LPCSTR pStrName) +{ + FXFT_Face face = m_pFont->m_Face; + return FT_Get_Name_Index(face, (FT_String*)pStrName); +} +CFX_ByteString CFX_FontEncodingEX::NameFromGlyphIndex(FX_DWORD dwGlyphIndex) +{ + FXFT_Face face = m_pFont->m_Face; + CFX_ByteString glyphName(" "); + if (FT_HAS_GLYPH_NAMES(((FT_Face)face))) { + if (FT_Get_Glyph_Name((FT_Face)face, dwGlyphIndex, (FT_Pointer)(FX_LPCSTR)glyphName, 16)) { + glyphName.Empty(); + return glyphName; + } + return glyphName; + } else { + return glyphName; + } +} +FX_DWORD CFX_FontEncodingEX::CharCodeFromGlyphIndex(FX_DWORD dwGlyphIndex) +{ + FXFT_Face face = m_pFont->GetFace(); + FX_DWORD charcode; + FT_UInt gid; + charcode = FT_Get_First_Char((FT_Face)face, &gid); + while (gid != 0) { + if (dwGlyphIndex == gid) { + return charcode; + } + charcode = FT_Get_Next_Char((FT_Face)face, charcode, &gid); + } + int nmaps = FXFT_Get_Face_CharmapCount(face); + int m = 0; + while (m < nmaps) { + int nEncodingID = FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[m++]); + if (m_nEncodingID == nEncodingID) { + continue; + } + int error = FXFT_Select_Charmap(face, nEncodingID); + if (error) { + continue; + } + charcode = FT_Get_First_Char((FT_Face)face, &gid); + while (gid != 0) { + if (dwGlyphIndex == gid) { + m_nEncodingID = nEncodingID; + return charcode; + } + charcode = FT_Get_Next_Char((FT_Face)face, charcode, &gid); + } + } + return (FX_DWORD) - 1; +} +static const FX_DWORD gs_EncodingID[] = { + FXFM_ENCODING_MS_SYMBOL, + FXFM_ENCODING_UNICODE, + FXFM_ENCODING_MS_SJIS, + FXFM_ENCODING_MS_GB2312, + FXFM_ENCODING_MS_BIG5, + FXFM_ENCODING_MS_WANSUNG, + FXFM_ENCODING_MS_JOHAB, + FXFM_ENCODING_ADOBE_STANDARD, + FXFM_ENCODING_ADOBE_EXPERT, + FXFM_ENCODING_ADOBE_CUSTOM, + FXFM_ENCODING_ADOBE_LATIN_1, + FXFM_ENCODING_OLD_LATIN_2, + FXFM_ENCODING_APPLE_ROMAN +}; +static IFX_FontEncodingEx* _FXFM_CreateFontEncoding(CFX_Font* pFont, FX_DWORD nEncodingID) +{ + int error = FXFT_Select_Charmap(pFont->m_Face, nEncodingID); + if (error) { + return NULL; + } + CFX_FontEncodingEX* pFontEncoding = FX_NEW CFX_FontEncodingEX; + if (pFontEncoding && !pFontEncoding->Init(pFont, nEncodingID)) { + delete pFontEncoding; + pFontEncoding = NULL; + } + return pFontEncoding; +} +IFX_FontEncodingEx* FX_CreateFontEncodingEx(CFX_Font* pFont, FX_DWORD nEncodingID) +{ + if (!pFont || !pFont->m_Face) { + return NULL; + } + if (nEncodingID != FXFM_ENCODING_NONE) { + return _FXFM_CreateFontEncoding(pFont, nEncodingID); + } + static int s_count = sizeof(gs_EncodingID) / sizeof(FX_DWORD); + for (int i = 0; i < s_count; i++) { + IFX_FontEncodingEx* pFontEncoding = _FXFM_CreateFontEncoding(pFont, gs_EncodingID[i]); + if (pFontEncoding) { + return pFontEncoding; + } + } + return NULL; +} diff --git a/core/src/fxge/ge/fx_ge_fontmap.cpp b/core/src/fxge/ge/fx_ge_fontmap.cpp index a5fa6443a8..fe790d8664 100644 --- a/core/src/fxge/ge/fx_ge_fontmap.cpp +++ b/core/src/fxge/ge/fx_ge_fontmap.cpp @@ -1156,6 +1156,9 @@ FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name, FX_BOOL bTru pSubstFont->m_SubstFlags |= FXFONT_SUBST_EXACT; } if (hFont == NULL) { + if (flags & FXFONT_EXACTMATCH) { + return NULL; + } if (bCJK) { if (italic_angle != 0) { bItalic = TRUE; @@ -1284,6 +1287,68 @@ FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name, FX_BOOL bTru m_pFontInfo->DeleteFont(hFont); return face; } +FXFT_Face CFX_FontMapper::FindSubstFontByUnicode(FX_DWORD dwUnicode, FX_DWORD flags, int weight, int italic_angle) +{ + if (m_pFontInfo == NULL) { + return NULL; + } + FX_BOOL bItalic = (flags & FXFONT_ITALIC) != 0; + int PitchFamily = 0; + if (flags & FXFONT_SERIF) { + PitchFamily |= FXFONT_FF_ROMAN; + } + if (flags & FXFONT_SCRIPT) { + PitchFamily |= FXFONT_FF_SCRIPT; + } + if (flags & FXFONT_FIXED_PITCH) { + PitchFamily |= FXFONT_FF_FIXEDPITCH; + } + void* hFont = m_pFontInfo->MapFontByUnicode(dwUnicode, weight, bItalic, PitchFamily); + if (hFont == NULL) { + return NULL; + } + FX_DWORD ttc_size = m_pFontInfo->GetFontData(hFont, 0x74746366, NULL, 0); + FX_DWORD font_size = m_pFontInfo->GetFontData(hFont, 0, NULL, 0); + if(font_size == 0 && ttc_size == 0) { + m_pFontInfo->DeleteFont(hFont); + return NULL; + } + FXFT_Face face = NULL; + if (ttc_size) { + FX_BYTE temp[1024]; + m_pFontInfo->GetFontData(hFont, 0x74746366, temp, 1024); + FX_DWORD checksum = 0; + for (int i = 0; i < 256; i ++) { + checksum += ((FX_DWORD*)temp)[i]; + } + FX_LPBYTE pFontData; + face = m_pFontMgr->GetCachedTTCFace(ttc_size, checksum, ttc_size - font_size, pFontData); + if (face == NULL) { + pFontData = FX_Alloc(FX_BYTE, ttc_size); + if (pFontData) { + m_pFontInfo->GetFontData(hFont, 0x74746366, pFontData, ttc_size); + face = m_pFontMgr->AddCachedTTCFace(ttc_size, checksum, pFontData, ttc_size, + ttc_size - font_size); + } + } + } else { + CFX_ByteString SubstName; + m_pFontInfo->GetFaceName(hFont, SubstName); + FX_LPBYTE pFontData; + face = m_pFontMgr->GetCachedFace(SubstName, weight, bItalic, pFontData); + if (face == NULL) { + pFontData = FX_Alloc(FX_BYTE, font_size); + if (!pFontData) { + m_pFontInfo->DeleteFont(hFont); + return NULL; + } + m_pFontInfo->GetFontData(hFont, 0, pFontData, font_size); + face = m_pFontMgr->AddCachedFace(SubstName, weight, bItalic, pFontData, font_size, m_pFontInfo->GetFaceIndex(hFont)); + } + } + m_pFontInfo->DeleteFont(hFont); + return face; +} extern "C" { unsigned long _FTStreamRead(FXFT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count); @@ -1483,6 +1548,10 @@ void* CFX_FolderFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int { return NULL; } +void* CFX_FolderFontInfo::MapFontByUnicode(FX_DWORD dwUnicode, int weight, FX_BOOL bItalic, int pitch_family) +{ + return NULL; +} void* CFX_FolderFontInfo::GetFont(FX_LPCSTR face) { FX_LPVOID p; diff --git a/core/src/fxge/ge/text_int.h b/core/src/fxge/ge/text_int.h index c8d55965e3..e51976f172 100644 --- a/core/src/fxge/ge/text_int.h +++ b/core/src/fxge/ge/text_int.h @@ -101,5 +101,24 @@ public: int m_PitchFamily; CFX_ByteString m_FontTables; }; - +class CFX_FontEncodingEX : public IFX_FontEncodingEx +{ +public: + CFX_FontEncodingEX(); + FX_BOOL Init(CFX_Font* pFont, FX_DWORD EncodingID); + virtual FX_DWORD GlyphIndexFromName(FX_LPCSTR pStrName); + virtual CFX_ByteString NameFromGlyphIndex(FX_DWORD dwGlyphIndex); + virtual FX_DWORD CharCodeFromGlyphIndex(FX_DWORD dwGlyphIndex); + virtual FX_DWORD GlyphFromCharCode(FX_DWORD charcode); + virtual CFX_WideString UnicodeFromCharCode(FX_DWORD charcode) const; + virtual FX_DWORD CharCodeFromUnicode(FX_WCHAR Unicode) const; + virtual FX_BOOL IsUnicodeCompatible() const; + virtual FX_DWORD GlyphFromCharCodeEx(FX_DWORD charcode, int encoding = ENCODING_UNICODE) + { + return GlyphFromCharCode(charcode); + } +private: + CFX_Font* m_pFont; + FX_DWORD m_nEncodingID; +}; #endif // _TEXT_INT_H_ -- cgit v1.2.3