summaryrefslogtreecommitdiff
path: root/core/src/fxge/ge
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/fxge/ge')
-rw-r--r--core/src/fxge/ge/fx_ge_font.cpp231
-rw-r--r--core/src/fxge/ge/fx_ge_fontmap.cpp69
-rw-r--r--core/src/fxge/ge/text_int.h21
3 files changed, 313 insertions, 8 deletions
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_