diff options
author | John Abd-El-Malek <jabdelmalek@google.com> | 2014-05-23 17:28:10 -0700 |
---|---|---|
committer | John Abd-El-Malek <jabdelmalek@google.com> | 2014-05-23 17:41:56 -0700 |
commit | 3f3b45cc74b0499912409f766a595945dbbfc4c5 (patch) | |
tree | ec400b6965477b88ea7f0d335f7e5c52044c346c /core/src/fpdfapi/fpdf_font/fpdf_font.cpp | |
parent | 6fe4aed948337175f6f7f81bb03c37b9c7f535da (diff) | |
download | pdfium-3f3b45cc74b0499912409f766a595945dbbfc4c5.tar.xz |
Convert all line endings to LF.
Diffstat (limited to 'core/src/fpdfapi/fpdf_font/fpdf_font.cpp')
-rw-r--r-- | core/src/fpdfapi/fpdf_font/fpdf_font.cpp | 3526 |
1 files changed, 1763 insertions, 1763 deletions
diff --git a/core/src/fpdfapi/fpdf_font/fpdf_font.cpp b/core/src/fpdfapi/fpdf_font/fpdf_font.cpp index 886199b120..4bec3337b1 100644 --- a/core/src/fpdfapi/fpdf_font/fpdf_font.cpp +++ b/core/src/fpdfapi/fpdf_font/fpdf_font.cpp @@ -1,1763 +1,1763 @@ -// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fpdfapi/fpdf_page.h"
-#include "../../../include/fpdfapi/fpdf_module.h"
-#include "../../../include/fpdfapi/fpdf_pageobj.h"
-#include "font_int.h"
-#include "../fpdf_page/pageint.h"
-#include "../../../include/fxge/fx_freetype.h"
-FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id)
-{
- for (int i = 0; i < FXFT_Get_Face_CharmapCount(face); i ++) {
- if (FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(face)[i]) == platform_id &&
- FXFT_Get_Charmap_EncodingID(FXFT_Get_Face_Charmaps(face)[i]) == encoding_id) {
- FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]);
- return TRUE;
- }
- }
- return FALSE;
-}
-extern const FX_WORD* PDF_UnicodesForPredefinedCharSet(int);
-CPDF_FontGlobals::CPDF_FontGlobals()
-{
- FXSYS_memset32(m_EmbeddedCharsets, 0, sizeof m_EmbeddedCharsets);
- FXSYS_memset32(m_EmbeddedToUnicodes, 0, sizeof m_EmbeddedToUnicodes);
- m_pContrastRamps = NULL;
-}
-CPDF_FontGlobals::~CPDF_FontGlobals()
-{
- ClearAll();
- if (m_pContrastRamps) {
- FX_Free(m_pContrastRamps);
- }
-}
-class CFX_StockFontArray : public CFX_Object
-{
-public:
- CFX_StockFontArray()
- {
- FXSYS_memset32(m_pStockFonts, 0, sizeof(CPDF_Font*) * 14);
- }
- CPDF_Font* m_pStockFonts[14];
-};
-CPDF_Font* CPDF_FontGlobals::Find(void* key, int index)
-{
- void* value = NULL;
- if (!m_pStockMap.Lookup(key, value)) {
- return NULL;
- }
- if (!value) {
- return NULL;
- }
- return ((CFX_StockFontArray*)value)->m_pStockFonts[index];
-}
-void CPDF_FontGlobals::Set(void* key, int index, CPDF_Font* pFont)
-{
- void* value = NULL;
- if (m_pStockMap.Lookup(key, value)) {
- ((CFX_StockFontArray*)value)->m_pStockFonts[index] = pFont;
- return;
- }
- CFX_StockFontArray* pFonts = FX_NEW CFX_StockFontArray();
- if (pFonts) {
- pFonts->m_pStockFonts[index] = pFont;
- }
- m_pStockMap.SetAt(key, pFonts);
-}
-void CPDF_FontGlobals::Clear(void* key)
-{
- void* value = NULL;
- if (!m_pStockMap.Lookup(key, value)) {
- return;
- }
- if (value) {
- CFX_StockFontArray* pStockFonts = (CFX_StockFontArray*)value;
- for (int i = 0; i < 14; i ++) {
- if (pStockFonts->m_pStockFonts[i]) {
- pStockFonts->m_pStockFonts[i]->GetFontDict()->Release();
- delete pStockFonts->m_pStockFonts[i];
- }
- }
- delete pStockFonts;
- }
- m_pStockMap.RemoveKey(key);
-}
-void CPDF_FontGlobals::ClearAll()
-{
- FX_POSITION pos = m_pStockMap.GetStartPosition();
- while (pos) {
- void *key = NULL;
- void* value = NULL;
- m_pStockMap.GetNextAssoc(pos, key, value);
- if (value) {
- CFX_StockFontArray* pStockFonts = (CFX_StockFontArray*)value;
- for (int i = 0; i < 14; i ++) {
- if (pStockFonts->m_pStockFonts[i]) {
- pStockFonts->m_pStockFonts[i]->GetFontDict()->Release();
- delete pStockFonts->m_pStockFonts[i];
- }
- }
- delete pStockFonts;
- }
- m_pStockMap.RemoveKey(key);
- }
-}
-CPDF_Font::CPDF_Font()
-{
- m_FontType = 0;
- m_FontBBox.left = m_FontBBox.right = m_FontBBox.top = m_FontBBox.bottom = 0;
- m_StemV = m_Ascent = m_Descent = m_ItalicAngle = 0;
- m_pFontFile = NULL;
- m_Flags = 0;
- m_pToUnicodeMap = NULL;
- m_bToUnicodeLoaded = FALSE;
- m_pCharMap = NULL;
-}
-FX_BOOL CPDF_Font::Initialize()
-{
- m_pCharMap = FX_NEW CPDF_FontCharMap(this);
- return TRUE;
-}
-CPDF_Font::~CPDF_Font()
-{
- if (m_pCharMap) {
- FX_Free(m_pCharMap);
- m_pCharMap = NULL;
- }
- if (m_pToUnicodeMap) {
- delete m_pToUnicodeMap;
- m_pToUnicodeMap = NULL;
- }
- if (m_pFontFile) {
- m_pDocument->GetPageData()->ReleaseFontFileStreamAcc((CPDF_Stream*)m_pFontFile->GetStream());
- }
-}
-FX_BOOL CPDF_Font::IsVertWriting() const
-{
- FX_BOOL bVertWriting = FALSE;
- CPDF_CIDFont* pCIDFont = GetCIDFont();
- if (pCIDFont) {
- bVertWriting = pCIDFont->IsVertWriting();
- } else {
- bVertWriting = m_Font.IsVertical();
- }
- return bVertWriting;
-}
-CFX_ByteString CPDF_Font::GetFontTypeName() const
-{
- switch (m_FontType) {
- case PDFFONT_TYPE1:
- return FX_BSTRC("Type1");
- case PDFFONT_TRUETYPE:
- return FX_BSTRC("TrueType");
- case PDFFONT_TYPE3:
- return FX_BSTRC("Type3");
- case PDFFONT_CIDFONT:
- return FX_BSTRC("Type0");
- }
- return CFX_ByteString();
-}
-void CPDF_Font::AppendChar(CFX_ByteString& str, FX_DWORD charcode) const
-{
- char buf[4];
- int len = AppendChar(buf, charcode);
- if (len == 1) {
- str += buf[0];
- } else {
- str += CFX_ByteString(buf, len);
- }
-}
-CFX_WideString CPDF_Font::UnicodeFromCharCode(FX_DWORD charcode) const
-{
- if (!m_bToUnicodeLoaded) {
- ((CPDF_Font*)this)->LoadUnicodeMap();
- }
- if (m_pToUnicodeMap) {
- CFX_WideString wsRet = m_pToUnicodeMap->Lookup(charcode);
- if (!wsRet.IsEmpty()) {
- return wsRet;
- }
- }
- FX_WCHAR unicode = _UnicodeFromCharCode(charcode);
- if (unicode == 0) {
- return CFX_WideString();
- }
- return unicode;
-}
-FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const
-{
- if (!m_bToUnicodeLoaded) {
- ((CPDF_Font*)this)->LoadUnicodeMap();
- }
- if (m_pToUnicodeMap) {
- FX_DWORD charcode = m_pToUnicodeMap->ReverseLookup(unicode);
- if (charcode) {
- return charcode;
- }
- }
- return _CharCodeFromUnicode(unicode);
-}
-CFX_WideString CPDF_Font::DecodeString(const CFX_ByteString& str) const
-{
- CFX_WideString result;
- int src_len = str.GetLength();
- result.Reserve(src_len);
- FX_LPCSTR src_buf = str;
- int src_pos = 0;
- while (src_pos < src_len) {
- FX_DWORD charcode = GetNextChar(src_buf, src_pos);
- CFX_WideString unicode = UnicodeFromCharCode(charcode);
- if (!unicode.IsEmpty()) {
- result += unicode;
- } else {
- result += (FX_WCHAR)charcode;
- }
- }
- return result;
-}
-CFX_ByteString CPDF_Font::EncodeString(const CFX_WideString& str) const
-{
- CFX_ByteString result;
- int src_len = str.GetLength();
- FX_LPSTR dest_buf = result.GetBuffer(src_len * 2);
- FX_LPCWSTR src_buf = str;
- int dest_pos = 0;
- for (int src_pos = 0; src_pos < src_len; src_pos ++) {
- FX_DWORD charcode = CharCodeFromUnicode(src_buf[src_pos]);
- dest_pos += AppendChar(dest_buf + dest_pos, charcode);
- }
- result.ReleaseBuffer(dest_pos);
- return result;
-}
-void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc)
-{
- m_Flags = pFontDesc->GetInteger(FX_BSTRC("Flags"), PDFFONT_NONSYMBOLIC);
- int ItalicAngle = 0;
- FX_BOOL bExistItalicAngle = FALSE;
- if (pFontDesc->KeyExist(FX_BSTRC("ItalicAngle"))) {
- ItalicAngle = pFontDesc->GetInteger(FX_BSTRC("ItalicAngle"));
- bExistItalicAngle = TRUE;
- }
- if (ItalicAngle < 0) {
- m_Flags |= PDFFONT_ITALIC;
- m_ItalicAngle = ItalicAngle;
- }
- FX_BOOL bExistStemV = FALSE;
- if (pFontDesc->KeyExist(FX_BSTRC("StemV"))) {
- m_StemV = pFontDesc->GetInteger(FX_BSTRC("StemV"));
- bExistStemV = TRUE;
- }
- FX_BOOL bExistAscent = FALSE;
- if (pFontDesc->KeyExist(FX_BSTRC("Ascent"))) {
- m_Ascent = pFontDesc->GetInteger(FX_BSTRC("Ascent"));
- bExistAscent = TRUE;
- }
- FX_BOOL bExistDescent = FALSE;
- if (pFontDesc->KeyExist(FX_BSTRC("Descent"))) {
- m_Descent = pFontDesc->GetInteger(FX_BSTRC("Descent"));
- bExistDescent = TRUE;
- }
- FX_BOOL bExistCapHeight = FALSE;
- if (pFontDesc->KeyExist(FX_BSTRC("CapHeight"))) {
- bExistCapHeight = TRUE;
- }
- if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent && bExistStemV) {
- m_Flags |= PDFFONT_USEEXTERNATTR;
- }
- if (m_Descent > 10) {
- m_Descent = -m_Descent;
- }
- CPDF_Array* pBBox = pFontDesc->GetArray(FX_BSTRC("FontBBox"));
- if (pBBox) {
- m_FontBBox.left = pBBox->GetInteger(0);
- m_FontBBox.bottom = pBBox->GetInteger(1);
- m_FontBBox.right = pBBox->GetInteger(2);
- m_FontBBox.top = pBBox->GetInteger(3);
- }
- CPDF_Stream* pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile"));
- if (pFontFile == NULL) {
- pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile2"));
- }
- if (pFontFile == NULL) {
- pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile3"));
- }
- if (pFontFile) {
- m_pFontFile = m_pDocument->LoadFontFile(pFontFile);
- if (m_pFontFile == NULL) {
- return;
- }
- FX_LPCBYTE pFontData = m_pFontFile->GetData();
- FX_DWORD dwFontSize = m_pFontFile->GetSize();
- m_Font.LoadEmbedded(pFontData, dwFontSize);
- if (m_Font.m_Face == NULL) {
- m_pFontFile = NULL;
- }
- }
-}
-short TT2PDF(int m, FXFT_Face face)
-{
- int upm = FXFT_Get_Face_UnitsPerEM(face);
- if (upm == 0) {
- return (short)m;
- }
- return (m * 1000 + upm / 2) / upm;
-}
-void CPDF_Font::CheckFontMetrics()
-{
- if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 && m_FontBBox.right == 0) {
- if (m_Font.m_Face) {
- m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(m_Font.m_Face), m_Font.m_Face);
- m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(m_Font.m_Face), m_Font.m_Face);
- m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(m_Font.m_Face), m_Font.m_Face);
- m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(m_Font.m_Face), m_Font.m_Face);
- m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(m_Font.m_Face), m_Font.m_Face);
- m_Descent = TT2PDF(FXFT_Get_Face_Descender(m_Font.m_Face), m_Font.m_Face);
- } else {
- FX_BOOL bFirst = TRUE;
- for (int i = 0; i < 256; i ++) {
- FX_RECT rect;
- GetCharBBox(i, rect);
- if (rect.left == rect.right) {
- continue;
- }
- if (bFirst) {
- m_FontBBox = rect;
- bFirst = FALSE;
- } else {
- if (m_FontBBox.top < rect.top) {
- m_FontBBox.top = rect.top;
- }
- if (m_FontBBox.right < rect.right) {
- m_FontBBox.right = rect.right;
- }
- if (m_FontBBox.left > rect.left) {
- m_FontBBox.left = rect.left;
- }
- if (m_FontBBox.bottom > rect.bottom) {
- m_FontBBox.bottom = rect.bottom;
- }
- }
- }
- }
- }
- if (m_Ascent == 0 && m_Descent == 0) {
- FX_RECT rect;
- GetCharBBox('A', rect);
- if (rect.bottom == rect.top) {
- m_Ascent = m_FontBBox.top;
- } else {
- m_Ascent = rect.top;
- }
- GetCharBBox('g', rect);
- if (rect.bottom == rect.top) {
- m_Descent = m_FontBBox.bottom;
- } else {
- m_Descent = rect.bottom;
- }
- }
-}
-void CPDF_Font::LoadUnicodeMap()
-{
- m_bToUnicodeLoaded = TRUE;
- CPDF_Stream* pStream = m_pFontDict->GetStream(FX_BSTRC("ToUnicode"));
- if (pStream == NULL) {
- return;
- }
- m_pToUnicodeMap = FX_NEW CPDF_ToUnicodeMap;
- m_pToUnicodeMap->Load(pStream);
-}
-int CPDF_Font::GetStringWidth(FX_LPCSTR pString, int size)
-{
- int offset = 0;
- int width = 0;
- while (offset < size) {
- FX_DWORD charcode = GetNextChar(pString, offset);
- width += GetCharWidthF(charcode);
- }
- return width;
-}
-int CPDF_Font::GetCharTypeWidth(FX_DWORD charcode)
-{
- if (m_Font.m_Face == NULL) {
- return 0;
- }
- int glyph_index = GlyphFromCharCode(charcode);
- if (glyph_index == 0xffff) {
- return 0;
- }
- return m_Font.GetGlyphWidth(glyph_index);
-}
-int _PDF_GetStandardFontName(CFX_ByteString& name);
-CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc, FX_BSTR name)
-{
- CFX_ByteString fontname(name);
- int font_id = _PDF_GetStandardFontName(fontname);
- if (font_id < 0) {
- return NULL;
- }
- CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
- CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id);
- if (pFont) {
- return pFont;
- }
- CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
- pDict->SetAtName(FX_BSTRC("Type"), FX_BSTRC("Font"));
- pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Type1"));
- pDict->SetAtName(FX_BSTRC("BaseFont"), fontname);
- pDict->SetAtName(FX_BSTRC("Encoding"), FX_BSTRC("WinAnsiEncoding"));
- pFont = CPDF_Font::CreateFontF(NULL, pDict);
- pFontGlobals->Set(pDoc, font_id, pFont);
- return pFont;
-}
-const FX_BYTE ChineseFontNames[][5] = {
- {0xCB, 0xCE, 0xCC, 0xE5, 0x00},
- {0xBF, 0xAC, 0xCC, 0xE5, 0x00},
- {0xBA, 0xDA, 0xCC, 0xE5, 0x00},
- {0xB7, 0xC2, 0xCB, 0xCE, 0x00},
- {0xD0, 0xC2, 0xCB, 0xCE, 0x00}
-};
-CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc, CPDF_Dictionary* pFontDict)
-{
- CFX_ByteString type = pFontDict->GetString(FX_BSTRC("Subtype"));
- CPDF_Font* pFont;
- if (type == FX_BSTRC("TrueType")) {
- {
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ || _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- CFX_ByteString basefont = pFontDict->GetString(FX_BSTRC("BaseFont"));
- CFX_ByteString tag = basefont.Left(4);
- int i;
- int count = sizeof(ChineseFontNames) / sizeof(ChineseFontNames[0]);
- for (i = 0; i < count; ++i) {
- if (tag == CFX_ByteString((FX_LPCSTR)ChineseFontNames[i])) {
- break;
- }
- }
- if (i < count) {
- CPDF_Dictionary* pFontDesc = pFontDict->GetDict(FX_BSTRC("FontDescriptor"));
- if (pFontDesc == NULL || !pFontDesc->KeyExist(FX_BSTRC("FontFile2"))) {
- pFont = FX_NEW CPDF_CIDFont;
- pFont->Initialize();
- pFont->m_FontType = PDFFONT_CIDFONT;
- pFont->m_pFontDict = pFontDict;
- pFont->m_pDocument = pDoc;
- if (!pFont->Load()) {
- delete pFont;
- return NULL;
- }
- return pFont;
- }
- }
-#endif
- }
- pFont = FX_NEW CPDF_TrueTypeFont;
- pFont->Initialize();
- pFont->m_FontType = PDFFONT_TRUETYPE;
- } else if (type == FX_BSTRC("Type3")) {
- pFont = FX_NEW CPDF_Type3Font;
- pFont->Initialize();
- pFont->m_FontType = PDFFONT_TYPE3;
- } else if (type == FX_BSTRC("Type0")) {
- pFont = FX_NEW CPDF_CIDFont;
- pFont->Initialize();
- pFont->m_FontType = PDFFONT_CIDFONT;
- } else {
- pFont = FX_NEW CPDF_Type1Font;
- pFont->Initialize();
- pFont->m_FontType = PDFFONT_TYPE1;
- }
- pFont->m_pFontDict = pFontDict;
- pFont->m_pDocument = pDoc;
- if (!pFont->Load()) {
- delete pFont;
- return NULL;
- }
- return pFont;
-}
-FX_BOOL CPDF_Font::Load()
-{
- if (m_pFontDict == NULL) {
- return FALSE;
- }
- CFX_ByteString type = m_pFontDict->GetString(FX_BSTRC("Subtype"));
- m_BaseFont = m_pFontDict->GetString(FX_BSTRC("BaseFont"));
- if (type == FX_BSTRC("MMType1")) {
- type = FX_BSTRC("Type1");
- }
- return _Load();
-}
-static CFX_WideString _FontMap_GetWideString(CFX_CharMap* pMap, const CFX_ByteString& bytestr)
-{
- return ((CPDF_FontCharMap*)pMap)->m_pFont->DecodeString(bytestr);
-}
-static CFX_ByteString _FontMap_GetByteString(CFX_CharMap* pMap, const CFX_WideString& widestr)
-{
- return ((CPDF_FontCharMap*)pMap)->m_pFont->EncodeString(widestr);
-}
-CPDF_FontCharMap::CPDF_FontCharMap(CPDF_Font* pFont)
-{
- m_GetByteString = _FontMap_GetByteString;
- m_GetWideString = _FontMap_GetWideString;
- m_pFont = pFont;
-}
-CFX_WideString CPDF_ToUnicodeMap::Lookup(FX_DWORD charcode)
-{
- FX_DWORD value;
- if (m_Map.Lookup(charcode, value)) {
- FX_WCHAR unicode = (FX_WCHAR)(value & 0xffff);
- if (unicode != 0xffff) {
- return unicode;
- }
- FX_LPCWSTR buf = m_MultiCharBuf.GetBuffer();
- FX_DWORD buf_len = m_MultiCharBuf.GetLength();
- if (buf == NULL || buf_len == 0) {
- return CFX_WideString();
- }
- FX_DWORD index = value >> 16;
- if (index >= buf_len) {
- return CFX_WideString();
- }
- FX_DWORD len = buf[index];
- if (index + len < index || index + len >= buf_len) {
- return CFX_WideString();
- }
- return CFX_WideString(buf + index + 1, len);
- }
- if (m_pBaseMap) {
- return m_pBaseMap->UnicodeFromCID((FX_WORD)charcode);
- }
- return CFX_WideString();
-}
-FX_DWORD CPDF_ToUnicodeMap::ReverseLookup(FX_WCHAR unicode)
-{
- FX_POSITION pos = m_Map.GetStartPosition();
- while (pos) {
- FX_DWORD key, value;
- m_Map.GetNextAssoc(pos, key, value);
- if ((FX_WCHAR)value == unicode) {
- return key;
- }
- }
- return 0;
-}
-static FX_DWORD _StringToCode(FX_BSTR str)
-{
- FX_LPCSTR buf = str.GetCStr();
- int len = str.GetLength();
- if (len == 0) {
- return 0;
- }
- int result = 0;
- if (buf[0] == '<') {
- for (int i = 1; i < len; i ++) {
- int digit;
- if (buf[i] >= '0' && buf[i] <= '9') {
- digit = buf[i] - '0';
- } else if (buf[i] >= 'a' && buf[i] <= 'f') {
- digit = buf[i] - 'a' + 10;
- } else if (buf[i] >= 'A' && buf[i] <= 'F') {
- digit = buf[i] - 'A' + 10;
- } else {
- break;
- }
- result = result * 16 + digit;
- }
- return result;
- } else {
- for (int i = 0; i < len; i ++) {
- if (buf[i] < '0' || buf[i] > '9') {
- break;
- }
- result = result * 10 + buf[i] - '0';
- }
- }
- return result;
-}
-static CFX_WideString _StringDataAdd(CFX_WideString str)
-{
- CFX_WideString ret;
- int len = str.GetLength();
- FX_WCHAR value = 1;
- for (int i = len - 1; i >= 0 ; --i) {
- FX_WCHAR ch = str[i] + value;
- if (ch < str[i]) {
- ret.Insert(0, 0);
- } else {
- ret.Insert(0, ch);
- value = 0;
- }
- }
- if (value) {
- ret.Insert(0, value);
- }
- return ret;
-}
-static CFX_WideString _StringToWideString(FX_BSTR str)
-{
- FX_LPCSTR buf = str.GetCStr();
- int len = str.GetLength();
- if (len == 0) {
- return CFX_WideString();
- }
- CFX_WideString result;
- if (buf[0] == '<') {
- int byte_pos = 0;
- FX_WCHAR ch = 0;
- for (int i = 1; i < len; i ++) {
- int digit;
- if (buf[i] >= '0' && buf[i] <= '9') {
- digit = buf[i] - '0';
- } else if (buf[i] >= 'a' && buf[i] <= 'f') {
- digit = buf[i] - 'a' + 10;
- } else if (buf[i] >= 'A' && buf[i] <= 'F') {
- digit = buf[i] - 'A' + 10;
- } else {
- break;
- }
- ch = ch * 16 + digit;
- byte_pos ++;
- if (byte_pos == 4) {
- result += ch;
- byte_pos = 0;
- ch = 0;
- }
- }
- return result;
- }
- if (buf[0] == '(') {
- }
- return result;
-}
-void CPDF_ToUnicodeMap::Load(CPDF_Stream* pStream)
-{
- int CIDSet = 0;
- CPDF_StreamAcc stream;
- stream.LoadAllData(pStream, FALSE);
- CPDF_SimpleParser parser(stream.GetData(), stream.GetSize());
- m_Map.EstimateSize(stream.GetSize() / 8, 1024);
- while (1) {
- CFX_ByteStringC word = parser.GetWord();
- if (word.IsEmpty()) {
- break;
- }
- if (word == FX_BSTRC("beginbfchar")) {
- while (1) {
- word = parser.GetWord();
- if (word.IsEmpty() || word == FX_BSTRC("endbfchar")) {
- break;
- }
- FX_DWORD srccode = _StringToCode(word);
- word = parser.GetWord();
- CFX_WideString destcode = _StringToWideString(word);
- int len = destcode.GetLength();
- if (len == 0) {
- continue;
- }
- if (len == 1) {
- m_Map.SetAt(srccode, destcode.GetAt(0));
- } else {
- m_Map.SetAt(srccode, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff);
- m_MultiCharBuf.AppendChar(destcode.GetLength());
- m_MultiCharBuf << destcode;
- }
- }
- } else if (word == FX_BSTRC("beginbfrange")) {
- while (1) {
- CFX_ByteString low, high;
- low = parser.GetWord();
- if (low.IsEmpty() || low == FX_BSTRC("endbfrange")) {
- break;
- }
- high = parser.GetWord();
- FX_DWORD lowcode = _StringToCode(low);
- FX_DWORD highcode = (lowcode & 0xffffff00) | (_StringToCode(high) & 0xff);
- if (highcode == (FX_DWORD) - 1) {
- break;
- }
- CFX_ByteString start = parser.GetWord();
- if (start == FX_BSTRC("[")) {
- for (FX_DWORD code = lowcode; code <= highcode; code ++) {
- CFX_ByteString dest = parser.GetWord();
- CFX_WideString destcode = _StringToWideString(dest);
- int len = destcode.GetLength();
- if (len == 0) {
- continue;
- }
- if (len == 1) {
- m_Map.SetAt(code, destcode.GetAt(0));
- } else {
- m_Map.SetAt(code, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff);
- m_MultiCharBuf.AppendChar(destcode.GetLength());
- m_MultiCharBuf << destcode;
- }
- }
- parser.GetWord();
- } else {
- CFX_WideString destcode = _StringToWideString(start);
- int len = destcode.GetLength();
- FX_DWORD value = 0;
- if (len == 1) {
- value = _StringToCode(start);
- for (FX_DWORD code = lowcode; code <= highcode; code ++) {
- m_Map.SetAt(code, value++);
- }
- } else {
- for (FX_DWORD code = lowcode; code <= highcode; code ++) {
- CFX_WideString retcode;
- if (code == lowcode) {
- retcode = destcode;
- } else {
- retcode = _StringDataAdd(destcode);
- }
- m_Map.SetAt(code, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff);
- m_MultiCharBuf.AppendChar(retcode.GetLength());
- m_MultiCharBuf << retcode;
- destcode = retcode;
- }
- }
- }
- }
- } else if (word == FX_BSTRC("/Adobe-Korea1-UCS2")) {
- CIDSet = CIDSET_KOREA1;
- } else if (word == FX_BSTRC("/Adobe-Japan1-UCS2")) {
- CIDSet = CIDSET_JAPAN1;
- } else if (word == FX_BSTRC("/Adobe-CNS1-UCS2")) {
- CIDSet = CIDSET_CNS1;
- } else if (word == FX_BSTRC("/Adobe-GB1-UCS2")) {
- CIDSet = CIDSET_GB1;
- }
- }
- if (CIDSet) {
- m_pBaseMap = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals()->m_CMapManager.GetCID2UnicodeMap(CIDSet, FALSE);
- } else {
- m_pBaseMap = NULL;
- }
-}
-static FX_BOOL GetPredefinedEncoding(int& basemap, const CFX_ByteString& value)
-{
- if (value == FX_BSTRC("WinAnsiEncoding")) {
- basemap = PDFFONT_ENCODING_WINANSI;
- } else if (value == FX_BSTRC("MacRomanEncoding")) {
- basemap = PDFFONT_ENCODING_MACROMAN;
- } else if (value == FX_BSTRC("MacExpertEncoding")) {
- basemap = PDFFONT_ENCODING_MACEXPERT;
- } else if (value == FX_BSTRC("PDFDocEncoding")) {
- basemap = PDFFONT_ENCODING_PDFDOC;
- } else {
- return FALSE;
- }
- return TRUE;
-}
-void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding, int& iBaseEncoding, CFX_ByteString*& pCharNames,
- FX_BOOL bEmbedded, FX_BOOL bTrueType)
-{
- if (pEncoding == NULL) {
- if (m_BaseFont == FX_BSTRC("Symbol")) {
- iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL : PDFFONT_ENCODING_ADOBE_SYMBOL;
- } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
- iBaseEncoding = PDFFONT_ENCODING_WINANSI;
- }
- return;
- }
- if (pEncoding->GetType() == PDFOBJ_NAME) {
- if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL || iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) {
- return;
- }
- if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == FX_BSTRC("Symbol")) {
- if (!bTrueType) {
- iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
- }
- return;
- }
- CFX_ByteString bsEncoding = pEncoding->GetString();
- if (bsEncoding.Compare(FX_BSTRC("MacExpertEncoding")) == 0) {
- bsEncoding = FX_BSTRC("WinAnsiEncoding");
- }
- GetPredefinedEncoding(iBaseEncoding, bsEncoding);
- return;
- }
- if (pEncoding->GetType() != PDFOBJ_DICTIONARY) {
- return;
- }
- CPDF_Dictionary* pDict = (CPDF_Dictionary*)pEncoding;
- if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL && iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) {
- CFX_ByteString bsEncoding = pDict->GetString(FX_BSTRC("BaseEncoding"));
- if (bsEncoding.Compare(FX_BSTRC("MacExpertEncoding")) == 0 && bTrueType) {
- bsEncoding = FX_BSTRC("WinAnsiEncoding");
- }
- GetPredefinedEncoding(iBaseEncoding, bsEncoding);
- }
- if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
- iBaseEncoding = PDFFONT_ENCODING_STANDARD;
- }
- CPDF_Array* pDiffs = pDict->GetArray(FX_BSTRC("Differences"));
- if (pDiffs == NULL) {
- return;
- }
- FX_NEW_VECTOR(pCharNames, CFX_ByteString, 256);
- FX_DWORD cur_code = 0;
- for (FX_DWORD i = 0; i < pDiffs->GetCount(); i ++) {
- CPDF_Object* pElement = pDiffs->GetElementValue(i);
- if (pElement == NULL) {
- continue;
- }
- if (pElement->GetType() == PDFOBJ_NAME) {
- if (cur_code < 256) {
- pCharNames[cur_code] = ((CPDF_Name*)pElement)->GetString();
- }
- cur_code ++;
- } else {
- cur_code = pElement->GetInteger();
- }
- }
-}
-FX_BOOL CPDF_Font::IsStandardFont() const
-{
- if (m_FontType != PDFFONT_TYPE1) {
- return FALSE;
- }
- if (m_pFontFile != NULL) {
- return FALSE;
- }
- if (((CPDF_Type1Font*)this)->GetBase14Font() < 0) {
- return FALSE;
- }
- return TRUE;
-}
-extern FX_LPCSTR PDF_CharNameFromPredefinedCharSet(int encoding, FX_BYTE charcode);
-CPDF_SimpleFont::CPDF_SimpleFont()
-{
- FXSYS_memset8(m_CharBBox, 0xff, sizeof m_CharBBox);
- FXSYS_memset8(m_CharWidth, 0xff, sizeof m_CharWidth);
- FXSYS_memset8(m_GlyphIndex, 0xff, sizeof m_GlyphIndex);
- FXSYS_memset8(m_ExtGID, 0xff, sizeof m_ExtGID);
- m_pCharNames = NULL;
- m_BaseEncoding = PDFFONT_ENCODING_BUILTIN;
-}
-CPDF_SimpleFont::~CPDF_SimpleFont()
-{
- if (m_pCharNames) {
- FX_DELETE_VECTOR(m_pCharNames, CFX_ByteString, 256);
- }
-}
-int CPDF_SimpleFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL *pVertGlyph)
-{
- if (pVertGlyph) {
- *pVertGlyph = FALSE;
- }
- if (charcode > 0xff) {
- return -1;
- }
- int index = m_GlyphIndex[(FX_BYTE)charcode];
- if (index == 0xffff) {
- return -1;
- }
- return index;
-}
-void CPDF_SimpleFont::LoadCharMetrics(int charcode)
-{
- if (m_Font.m_Face == NULL) {
- return;
- }
- if (charcode < 0 || charcode > 0xff) {
- return;
- }
- int glyph_index = m_GlyphIndex[charcode];
- if (glyph_index == 0xffff) {
- if (m_pFontFile == NULL && charcode != 32) {
- LoadCharMetrics(32);
- m_CharBBox[charcode] = m_CharBBox[32];
- if (m_bUseFontWidth) {
- m_CharWidth[charcode] = m_CharWidth[32];
- }
- }
- return;
- }
- int err = FXFT_Load_Glyph(m_Font.m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
- if (err) {
- return;
- }
- m_CharBBox[charcode].Left = TT2PDF(FXFT_Get_Glyph_HoriBearingX(m_Font.m_Face), m_Font.m_Face);
- m_CharBBox[charcode].Right = TT2PDF(FXFT_Get_Glyph_HoriBearingX(m_Font.m_Face) + FXFT_Get_Glyph_Width(m_Font.m_Face), m_Font.m_Face);
- m_CharBBox[charcode].Top = TT2PDF(FXFT_Get_Glyph_HoriBearingY(m_Font.m_Face), m_Font.m_Face);
- m_CharBBox[charcode].Bottom = TT2PDF(FXFT_Get_Glyph_HoriBearingY(m_Font.m_Face) - FXFT_Get_Glyph_Height(m_Font.m_Face), m_Font.m_Face);
- if (m_bUseFontWidth) {
- int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(m_Font.m_Face), m_Font.m_Face);
- if (m_CharWidth[charcode] == 0xffff) {
- m_CharWidth[charcode] = TT_Width;
- } else if (TT_Width && !IsEmbedded()) {
- m_CharBBox[charcode].Right = m_CharBBox[charcode].Right * m_CharWidth[charcode] / TT_Width;
- m_CharBBox[charcode].Left = m_CharBBox[charcode].Left * m_CharWidth[charcode] / TT_Width;
- }
- }
-}
-int CPDF_SimpleFont::GetCharWidthF(FX_DWORD charcode, int level)
-{
- if (charcode > 0xff) {
- charcode = 0;
- }
- if (m_CharWidth[charcode] == 0xffff) {
- LoadCharMetrics(charcode);
- if (m_CharWidth[charcode] == 0xffff) {
- m_CharWidth[charcode] = 0;
- }
- }
- return (FX_INT16)m_CharWidth[charcode];
-}
-void CPDF_SimpleFont::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level)
-{
- if (charcode > 0xff) {
- charcode = 0;
- }
- if (m_CharBBox[charcode].Left == (FX_SHORT)0xffff) {
- LoadCharMetrics(charcode);
- }
- rect.left = m_CharBBox[charcode].Left;
- rect.right = m_CharBBox[charcode].Right;
- rect.bottom = m_CharBBox[charcode].Bottom;
- rect.top = m_CharBBox[charcode].Top;
-}
-FX_LPCSTR GetAdobeCharName(int iBaseEncoding, const CFX_ByteString* pCharNames, int charcode)
-{
- ASSERT(charcode >= 0 && charcode < 256);
- if (charcode < 0 || charcode >= 256) {
- return NULL;
- }
- FX_LPCSTR name = NULL;
- if (pCharNames) {
- name = pCharNames[charcode];
- }
- if ((name == NULL || name[0] == 0) && iBaseEncoding) {
- name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode);
- }
- if (name == NULL || name[0] == 0) {
- return NULL;
- }
- return name;
-}
-FX_BOOL CPDF_SimpleFont::LoadCommon()
-{
- CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict(FX_BSTRC("FontDescriptor"));
- if (pFontDesc) {
- LoadFontDescriptor(pFontDesc);
- }
- CPDF_Array* pWidthArray = m_pFontDict->GetArray(FX_BSTRC("Widths"));
- int width_start = 0, width_end = -1;
- m_bUseFontWidth = TRUE;
- if (pWidthArray) {
- m_bUseFontWidth = FALSE;
- if (pFontDesc && pFontDesc->KeyExist(FX_BSTRC("MissingWidth"))) {
- int MissingWidth = pFontDesc->GetInteger(FX_BSTRC("MissingWidth"));
- for (int i = 0; i < 256; i ++) {
- m_CharWidth[i] = MissingWidth;
- }
- }
- width_start = m_pFontDict->GetInteger(FX_BSTRC("FirstChar"), 0);
- width_end = m_pFontDict->GetInteger(FX_BSTRC("LastChar"), 0);
- if (width_start >= 0 && width_start <= 255) {
- if (width_end <= 0 || width_end >= width_start + (int)pWidthArray->GetCount()) {
- width_end = width_start + pWidthArray->GetCount() - 1;
- }
- if (width_end > 255) {
- width_end = 255;
- }
- for (int i = width_start; i <= width_end; i ++) {
- m_CharWidth[i] = pWidthArray->GetInteger(i - width_start);
- }
- }
- }
- if (m_pFontFile == NULL) {
- LoadSubstFont();
- } else {
- if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') {
- m_BaseFont = m_BaseFont.Mid(8);
- }
- }
- if (!(m_Flags & PDFFONT_SYMBOLIC)) {
- m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
- }
- CPDF_Object* pEncoding = m_pFontDict->GetElementValue(FX_BSTRC("Encoding"));
- LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, m_pFontFile != NULL, m_Font.IsTTFont());
- LoadGlyphMap();
- if (m_pCharNames) {
- FX_DELETE_VECTOR(m_pCharNames, CFX_ByteString, 256);
- m_pCharNames = NULL;
- }
- if (m_Font.m_Face == NULL) {
- return TRUE;
- }
- if (m_Flags & PDFFONT_ALLCAP) {
- unsigned char lowercases[] = {'a', 'z', 0xe0, 0xf6, 0xf8, 0xfd};
- for (int range = 0; range < sizeof lowercases / 2; range ++) {
- for (int i = lowercases[range * 2]; i <= lowercases[range * 2 + 1]; i ++) {
- if (m_GlyphIndex[i] != 0xffff && m_pFontFile != NULL) {
- continue;
- }
- m_GlyphIndex[i] = m_GlyphIndex[i - 32];
- if (m_CharWidth[i - 32]) {
- m_CharWidth[i] = m_CharWidth[i - 32];
- m_CharBBox[i] = m_CharBBox[i - 32];
- }
- }
- }
- }
- CheckFontMetrics();
- return TRUE;
-}
-void CPDF_SimpleFont::LoadSubstFont()
-{
- if (!m_bUseFontWidth && !(m_Flags & PDFFONT_FIXEDPITCH)) {
- int width = 0, i;
- for (i = 0; i < 256; i ++) {
- if (m_CharWidth[i] == 0 || m_CharWidth[i] == 0xffff) {
- continue;
- }
- if (width == 0) {
- width = m_CharWidth[i];
- } else if (width != m_CharWidth[i]) {
- break;
- }
- }
- if (i == 256 && width) {
- m_Flags |= PDFFONT_FIXEDPITCH;
- }
- }
- int weight = m_StemV < 140 ? m_StemV * 5 : (m_StemV * 4 + 140);
- m_Font.LoadSubst(m_BaseFont, m_FontType == PDFFONT_TRUETYPE, m_Flags, weight, m_ItalicAngle, 0);
- if (m_Font.m_pSubstFont->m_SubstFlags & FXFONT_SUBST_NONSYMBOL) {
- }
-}
-FX_BOOL CPDF_SimpleFont::IsUnicodeCompatible() const
-{
- return m_BaseEncoding != PDFFONT_ENCODING_BUILTIN && m_BaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
- m_BaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS;
-}
-CPDF_Type1Font::CPDF_Type1Font()
-{
- m_Base14Font = -1;
-}
-FX_BOOL CPDF_Type1Font::_Load()
-{
- m_Base14Font = _PDF_GetStandardFontName(m_BaseFont);
- if (m_Base14Font >= 0) {
- CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict(FX_BSTRC("FontDescriptor"));
- if (pFontDesc && pFontDesc->KeyExist(FX_BSTRC("Flags"))) {
- m_Flags = pFontDesc->GetInteger(FX_BSTRC("Flags"));
- } else {
- m_Flags = m_Base14Font >= 12 ? PDFFONT_SYMBOLIC : PDFFONT_NONSYMBOLIC;
- }
- if (m_Base14Font < 4)
- for (int i = 0; i < 256; i ++) {
- m_CharWidth[i] = 600;
- }
- if (m_Base14Font == 12) {
- m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
- } else if (m_Base14Font == 13) {
- m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS;
- } else if (m_Flags & PDFFONT_NONSYMBOLIC) {
- m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
- }
- }
- return LoadCommon();
-}
-static FX_BOOL FT_UseType1Charmap(FXFT_Face face)
-{
- if (FXFT_Get_Face_CharmapCount(face) == 0) {
- return FALSE;
- }
- if (FXFT_Get_Face_CharmapCount(face) == 1 &&
- FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == FXFT_ENCODING_UNICODE) {
- return FALSE;
- }
- if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == FXFT_ENCODING_UNICODE) {
- FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[1]);
- } else {
- FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);
- }
- return TRUE;
-}
-extern FX_WCHAR FT_UnicodeFromCharCode(int encoding, FX_DWORD charcode);
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
-#include "../../fxge/apple/apple_int.h"
-#endif
-int CPDF_Type1Font::GlyphFromCharCodeExt(FX_DWORD charcode)
-{
- if (charcode > 0xff) {
- return -1;
- }
- int index = m_ExtGID[(FX_BYTE)charcode];
- if (index == 0xffff) {
- return -1;
- }
- return index;
-}
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
-struct _GlyphNameMap {
- FX_LPCSTR m_pStrAdobe;
- FX_LPCSTR m_pStrUnicode;
-};
-static const _GlyphNameMap g_GlyphNameSubsts[] = {
- {"ff", "uniFB00"},
- {"fi", "uniFB01"},
- {"fl", "uniFB02"},
- {"ffi", "uniFB03"},
- {"ffl", "uniFB04"}
-};
-extern "C" {
- static int compareString(const void* key, const void* element)
- {
- return FXSYS_stricmp((FX_LPCSTR)key, ((_GlyphNameMap*)element)->m_pStrAdobe);
- }
-}
-static FX_LPCSTR _GlyphNameRemap(FX_LPCSTR pStrAdobe)
-{
- _GlyphNameMap* found = (_GlyphNameMap*)FXSYS_bsearch(pStrAdobe, g_GlyphNameSubsts,
- sizeof g_GlyphNameSubsts / sizeof(_GlyphNameMap), sizeof(_GlyphNameMap),
- compareString);
- if (found) {
- return found->m_pStrUnicode;
- }
- return NULL;
-}
-#endif
-void CPDF_Type1Font::LoadGlyphMap()
-{
- if (m_Font.m_Face == NULL) {
- return;
- }
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- FX_BOOL bCoreText = TRUE;
- CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
- if (!m_Font.m_pPlatformFont) {
- if (m_Font.GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) {
- bCoreText = FALSE;
- }
- m_Font.m_pPlatformFont = quartz2d.CreateFont(m_Font.m_pFontData, m_Font.m_dwSize);
- if (NULL == m_Font.m_pPlatformFont) {
- bCoreText = FALSE;
- }
- }
-#endif
- if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) {
- if (FT_UseTTCharmap(m_Font.m_Face, 3, 0)) {
- FX_BOOL bGotOne = FALSE;
- for (int charcode = 0; charcode < 256; charcode ++) {
- const FX_BYTE prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
- for (int j = 0; j < 4; j ++) {
- FX_WORD unicode = prefix[j] * 256 + charcode;
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode);
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- FX_CHAR name_glyph[256];
- FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
- name_glyph[255] = 0;
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
- if (name_ct) {
- CFRelease(name_ct);
- }
-#endif
- if (m_GlyphIndex[charcode]) {
- bGotOne = TRUE;
- break;
- }
- }
- }
- if (bGotOne) {
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- if (!bCoreText) {
- FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256);
- }
-#endif
- return;
- }
- }
- FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE);
- if (m_BaseEncoding == 0) {
- m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
- }
- for (int charcode = 0; charcode < 256; charcode ++) {
- FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
- if (name == NULL) {
- continue;
- }
- m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, m_Encoding.m_Unicodes[charcode]);
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- FX_CHAR name_glyph[256];
- FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
- name_glyph[255] = 0;
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
- if (name_ct) {
- CFRelease(name_ct);
- }
-#endif
- if (m_GlyphIndex[charcode] == 0 && FXSYS_strcmp(name, ".notdef") == 0) {
- m_Encoding.m_Unicodes[charcode] = 0x20;
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, 0x20);
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- FX_CHAR name_glyph[256];
- FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
- name_glyph[255] = 0;
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
- if (name_ct) {
- CFRelease(name_ct);
- }
-#endif
- }
- }
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- if (!bCoreText) {
- FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256);
- }
-#endif
- return;
- }
- FT_UseType1Charmap(m_Font.m_Face);
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- if (bCoreText) {
- if (m_Flags & PDFFONT_SYMBOLIC) {
- for (int charcode = 0; charcode < 256; charcode ++) {
- FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
- if (name) {
- m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
- m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull);
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
- if (name_ct) {
- CFRelease(name_ct);
- }
- } else {
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode);
- FX_WCHAR unicode = 0;
- if (m_GlyphIndex[charcode]) {
- unicode = FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
- }
- FX_CHAR name_glyph[256];
- FXSYS_memset32(name_glyph, 0, sizeof(name_glyph));
- FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
- name_glyph[255] = 0;
- if (unicode == 0 && name_glyph[0] != 0) {
- unicode = PDF_UnicodeFromAdobeName(name_glyph);
- }
- m_Encoding.m_Unicodes[charcode] = unicode;
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
- if (name_ct) {
- CFRelease(name_ct);
- }
- }
- }
- return;
- }
- FX_BOOL bUnicode = FALSE;
- if (0 == FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE)) {
- bUnicode = TRUE;
- }
- for (int charcode = 0; charcode < 256; charcode ++) {
- FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
- if (name == NULL) {
- continue;
- }
- m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
- FX_LPCSTR pStrUnicode = _GlyphNameRemap(name);
- if (pStrUnicode && 0 == FXFT_Get_Name_Index(m_Font.m_Face, (char*)name)) {
- name = pStrUnicode;
- }
- m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull);
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
- if (name_ct) {
- CFRelease(name_ct);
- }
- if (m_GlyphIndex[charcode] == 0) {
- if (FXSYS_strcmp(name, ".notdef") != 0 && FXSYS_strcmp(name, "space") != 0) {
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
- FX_CHAR name_glyph[256];
- FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
- name_glyph[255] = 0;
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
- if (name_ct) {
- CFRelease(name_ct);
- }
- } else {
- m_Encoding.m_Unicodes[charcode] = 0x20;
- m_GlyphIndex[charcode] = bUnicode ? FXFT_Get_Char_Index(m_Font.m_Face, 0x20) : 0xffff;
- FX_CHAR name_glyph[256];
- FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
- name_glyph[255] = 0;
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
- if (name_ct) {
- CFRelease(name_ct);
- }
- }
- }
- }
- return;
- }
-#endif
- if (m_Flags & PDFFONT_SYMBOLIC) {
- for (int charcode = 0; charcode < 256; charcode ++) {
- FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
- if (name) {
- m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
- m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);
- } else {
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode);
- if (m_GlyphIndex[charcode]) {
- FX_WCHAR unicode = FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
- if (unicode == 0) {
- FX_CHAR name_glyph[256];
- FXSYS_memset32(name_glyph, 0, sizeof(name_glyph));
- FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
- name_glyph[255] = 0;
- if (name_glyph[0] != 0) {
- unicode = PDF_UnicodeFromAdobeName(name_glyph);
- }
- }
- m_Encoding.m_Unicodes[charcode] = unicode;
- }
- }
- }
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- if (!bCoreText) {
- FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256);
- }
-#endif
- return;
- }
- FX_BOOL bUnicode = FALSE;
- if (0 == FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE)) {
- bUnicode = TRUE;
- }
- for (int charcode = 0; charcode < 256; charcode ++) {
- FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
- if (name == NULL) {
- continue;
- }
- m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
- m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);
- if (m_GlyphIndex[charcode] == 0) {
- if (FXSYS_strcmp(name, ".notdef") != 0 && FXSYS_strcmp(name, "space") != 0) {
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
- } else {
- m_Encoding.m_Unicodes[charcode] = 0x20;
- m_GlyphIndex[charcode] = 0xffff;
- }
- }
- }
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- if (!bCoreText) {
- FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256);
- }
-#endif
-}
-CPDF_FontEncoding::CPDF_FontEncoding()
-{
- FXSYS_memset32(m_Unicodes, 0, sizeof(m_Unicodes));
-}
-int CPDF_FontEncoding::CharCodeFromUnicode(FX_WCHAR unicode) const
-{
- for (int i = 0; i < 256; i ++)
- if (m_Unicodes[i] == unicode) {
- return i;
- }
- return -1;
-}
-CPDF_FontEncoding::CPDF_FontEncoding(int PredefinedEncoding)
-{
- const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(PredefinedEncoding);
- if (!pSrc) {
- FXSYS_memset32(m_Unicodes, 0, sizeof(m_Unicodes));
- } else
- for (int i = 0; i < 256; i++) {
- m_Unicodes[i] = pSrc[i];
- }
-}
-FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const
-{
- return FXSYS_memcmp32(m_Unicodes, pAnother->m_Unicodes, sizeof(m_Unicodes)) == 0;
-}
-CPDF_Object* CPDF_FontEncoding::Realize()
-{
- int predefined = 0;
- for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS; cs ++) {
- const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(cs);
- FX_BOOL match = TRUE;
- for (int i = 0; i < 256; ++i) {
- if (m_Unicodes[i] != pSrc[i]) {
- match = FALSE;
- break;
- }
- }
- if (match) {
- predefined = cs;
- break;
- }
- }
- if (predefined) {
- if (predefined == PDFFONT_ENCODING_WINANSI) {
- return CPDF_Name::Create("WinAnsiEncoding");
- }
- if (predefined == PDFFONT_ENCODING_MACROMAN) {
- return CPDF_Name::Create("MacRomanEncoding");
- }
- if (predefined == PDFFONT_ENCODING_MACEXPERT) {
- return CPDF_Name::Create("MacExpertEncoding");
- }
- return NULL;
- }
- CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
- pDict->SetAtName(FX_BSTRC("BaseEncoding"), FX_BSTRC("WinAnsiEncoding"));
- const FX_WORD* pStandard = PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI);
- CPDF_Array* pDiff = CPDF_Array::Create();
- for (int i = 0; i < 256; i ++) {
- if (pStandard[i] == m_Unicodes[i]) {
- continue;
- }
- pDiff->Add(CPDF_Number::Create(i));
- pDiff->Add(CPDF_Name::Create(PDF_AdobeNameFromUnicode(m_Unicodes[i])));
- }
- pDict->SetAt(FX_BSTRC("Differences"), pDiff);
- return pDict;
-}
-CPDF_TrueTypeFont::CPDF_TrueTypeFont()
-{
-}
-FX_BOOL CPDF_TrueTypeFont::_Load()
-{
- return LoadCommon();
-}
-extern FX_DWORD FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode);
-void CPDF_TrueTypeFont::LoadGlyphMap()
-{
- if (m_Font.m_Face == NULL) {
- return;
- }
- int baseEncoding = m_BaseEncoding;
- if (m_pFontFile && m_Font.m_Face->num_charmaps > 0
- && (baseEncoding == PDFFONT_ENCODING_MACROMAN || baseEncoding == PDFFONT_ENCODING_WINANSI)
- && (m_Flags & PDFFONT_SYMBOLIC)) {
- FX_BOOL bSupportWin = FALSE;
- FX_BOOL bSupportMac = FALSE;
- for (int i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.m_Face); i++) {
- int platform_id = FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(m_Font.m_Face)[i]);
- if (platform_id == 0 || platform_id == 3) {
- bSupportWin = TRUE;
- } else if (platform_id == 0 || platform_id == 1) {
- bSupportMac = TRUE;
- }
- }
- if (baseEncoding == PDFFONT_ENCODING_WINANSI && !bSupportWin) {
- baseEncoding = bSupportMac ? PDFFONT_ENCODING_MACROMAN : PDFFONT_ENCODING_BUILTIN;
- } else if (baseEncoding == PDFFONT_ENCODING_MACROMAN && !bSupportMac) {
- baseEncoding = bSupportWin ? PDFFONT_ENCODING_WINANSI : PDFFONT_ENCODING_BUILTIN;
- }
- }
- if (((baseEncoding == PDFFONT_ENCODING_MACROMAN || baseEncoding == PDFFONT_ENCODING_WINANSI)
- && m_pCharNames == NULL) || (m_Flags & PDFFONT_NONSYMBOLIC)) {
- if (!FXFT_Has_Glyph_Names(m_Font.m_Face) && (!m_Font.m_Face->num_charmaps || !m_Font.m_Face->charmaps)) {
- int nStartChar = m_pFontDict->GetInteger(FX_BSTRC("FirstChar"));
- int charcode = 0;
- for (; charcode < nStartChar; charcode ++) {
- m_GlyphIndex[charcode] = 0;
- }
- FX_WORD nGlyph = charcode - nStartChar + 3;
- for (; charcode < 256; charcode ++, nGlyph ++) {
- m_GlyphIndex[charcode] = nGlyph;
- }
- return;
- }
- FX_BOOL bMSUnicode = FT_UseTTCharmap(m_Font.m_Face, 3, 1);
- FX_BOOL bMacRoman = FALSE, bMSSymbol = FALSE;
- if (!bMSUnicode) {
- if (m_Flags & PDFFONT_NONSYMBOLIC) {
- bMacRoman = FT_UseTTCharmap(m_Font.m_Face, 1, 0);
- bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.m_Face, 3, 0);
- } else {
- bMSSymbol = FT_UseTTCharmap(m_Font.m_Face, 3, 0);
- bMacRoman = !bMSSymbol && FT_UseTTCharmap(m_Font.m_Face, 1, 0);
- }
- }
- FX_BOOL bToUnicode = m_pFontDict->KeyExist(FX_BSTRC("ToUnicode"));
- for (int charcode = 0; charcode < 256; charcode ++) {
- FX_LPCSTR name = GetAdobeCharName(baseEncoding, m_pCharNames, charcode);
- if (name == NULL) {
- m_GlyphIndex[charcode] = m_pFontFile ? FXFT_Get_Char_Index(m_Font.m_Face, charcode) : -1;
- continue;
- }
- m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
- if (bMSSymbol) {
- const FX_BYTE prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
- for (int j = 0; j < 4; j ++) {
- FX_WORD unicode = prefix[j] * 256 + charcode;
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode);
- if (m_GlyphIndex[charcode]) {
- break;
- }
- }
- } else if (m_Encoding.m_Unicodes[charcode]) {
- if (bMSUnicode) {
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, m_Encoding.m_Unicodes[charcode]);
- } else if (bMacRoman) {
- FX_DWORD maccode = FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, m_Encoding.m_Unicodes[charcode]);
- if (!maccode) {
- m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char *)name);
- } else {
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, maccode);
- }
- }
- }
- if ((m_GlyphIndex[charcode] == 0 || m_GlyphIndex[charcode] == 0xffff) && name != NULL) {
- if (name[0] == '.' && FXSYS_strcmp(name, ".notdef") == 0) {
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, 32);
- } else {
- m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);
- if (m_GlyphIndex[charcode] == 0) {
- if (bToUnicode) {
- CFX_WideString wsUnicode = UnicodeFromCharCode(charcode);
- if (!wsUnicode.IsEmpty()) {
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, wsUnicode[0]);
- m_Encoding.m_Unicodes[charcode] = wsUnicode[0];
- }
- }
- if (m_GlyphIndex[charcode] == 0) {
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode);
- }
- }
- }
- }
- }
- return;
- }
- if (FT_UseTTCharmap(m_Font.m_Face, 3, 0)) {
- const FX_BYTE prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
- FX_BOOL bGotOne = FALSE;
- for (int charcode = 0; charcode < 256; charcode ++) {
- for (int j = 0; j < 4; j ++) {
- FX_WORD unicode = prefix[j] * 256 + charcode;
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode);
- if (m_GlyphIndex[charcode]) {
- bGotOne = TRUE;
- break;
- }
- }
- }
- if (bGotOne) {
- if (baseEncoding != PDFFONT_ENCODING_BUILTIN) {
- for (int charcode = 0; charcode < 256; charcode ++) {
- FX_LPCSTR name = GetAdobeCharName(baseEncoding, m_pCharNames, charcode);
- if (name == NULL) {
- continue;
- }
- m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
- }
- } else if (FT_UseTTCharmap(m_Font.m_Face, 1, 0)) {
- for (int charcode = 0; charcode < 256; charcode ++) {
- m_Encoding.m_Unicodes[charcode] = FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode);
- }
- }
- return;
- }
- }
- if (FT_UseTTCharmap(m_Font.m_Face, 1, 0)) {
- FX_BOOL bGotOne = FALSE;
- for (int charcode = 0; charcode < 256; charcode ++) {
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode);
- m_Encoding.m_Unicodes[charcode] = FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode);
- if (m_GlyphIndex[charcode]) {
- bGotOne = TRUE;
- }
- }
- if (m_pFontFile || bGotOne) {
- return;
- }
- }
- if (FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE) == 0) {
- FX_BOOL bGotOne = FALSE;
- const FX_WORD* pUnicodes = PDF_UnicodesForPredefinedCharSet(baseEncoding);
- for (int charcode = 0; charcode < 256; charcode ++) {
- if (m_pFontFile == NULL) {
- FX_LPCSTR name = GetAdobeCharName(0, m_pCharNames, charcode);
- if (name != NULL) {
- m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
- } else if (pUnicodes) {
- m_Encoding.m_Unicodes[charcode] = pUnicodes[charcode];
- }
- } else {
- m_Encoding.m_Unicodes[charcode] = charcode;
- }
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, m_Encoding.m_Unicodes[charcode]);
- if (m_GlyphIndex[charcode]) {
- bGotOne = TRUE;
- }
- }
- if (bGotOne) {
- return;
- }
- }
- for (int charcode = 0; charcode < 256; charcode ++) {
- m_GlyphIndex[charcode] = charcode;
- }
-}
-CPDF_Type3Font::CPDF_Type3Font()
-{
- m_pPageResources = NULL;
- FXSYS_memset32(m_CharWidthL, 0, sizeof m_CharWidthL);
-}
-CPDF_Type3Font::~CPDF_Type3Font()
-{
- FX_POSITION pos = m_CacheMap.GetStartPosition();
- while (pos) {
- FX_LPVOID key, value;
- m_CacheMap.GetNextAssoc(pos, key, value);
- delete (CPDF_Type3Char*)value;
- }
- m_CacheMap.RemoveAll();
- pos = m_DeletedMap.GetStartPosition();
- while (pos) {
- FX_LPVOID key, value;
- m_DeletedMap.GetNextAssoc(pos, key, value);
- delete (CPDF_Type3Char*)key;
- }
-}
-FX_BOOL CPDF_Type3Font::_Load()
-{
- m_pFontResources = m_pFontDict->GetDict(FX_BSTRC("Resources"));
- CPDF_Array* pMatrix = m_pFontDict->GetArray(FX_BSTRC("FontMatrix"));
- FX_FLOAT xscale = 1.0f, yscale = 1.0f;
- if (pMatrix) {
- m_FontMatrix = pMatrix->GetMatrix();
- xscale = m_FontMatrix.a;
- yscale = m_FontMatrix.d;
- }
- CPDF_Array* pBBox = m_pFontDict->GetArray(FX_BSTRC("FontBBox"));
- if (pBBox) {
- m_FontBBox.left = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(0), xscale) * 1000);
- m_FontBBox.bottom = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(1), yscale) * 1000);
- m_FontBBox.right = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(2), xscale) * 1000);
- m_FontBBox.top = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(3), yscale) * 1000);
- }
- int StartChar = m_pFontDict->GetInteger(FX_BSTRC("FirstChar"));
- CPDF_Array* pWidthArray = m_pFontDict->GetArray(FX_BSTRC("Widths"));
- if (pWidthArray && (StartChar >= 0 && StartChar < 256)) {
- FX_DWORD count = pWidthArray->GetCount();
- if (count > 256) {
- count = 256;
- }
- if (StartChar + count > 256) {
- count = 256 - StartChar;
- }
- for (FX_DWORD i = 0; i < count; i ++) {
- m_CharWidthL[StartChar + i] = FXSYS_round(FXSYS_Mul(pWidthArray->GetNumber(i), xscale) * 1000);
- }
- }
- m_pCharProcs = m_pFontDict->GetDict(FX_BSTRC("CharProcs"));
- CPDF_Object* pEncoding = m_pFontDict->GetElementValue(FX_BSTRC("Encoding"));
- if (pEncoding) {
- LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, FALSE, FALSE);
- if (m_pCharNames) {
- for (int i = 0; i < 256; i ++) {
- m_Encoding.m_Unicodes[i] = PDF_UnicodeFromAdobeName(m_pCharNames[i]);
- if (m_Encoding.m_Unicodes[i] == 0) {
- m_Encoding.m_Unicodes[i] = i;
- }
- }
- }
- }
- return TRUE;
-}
-void CPDF_Type3Font::CheckType3FontMetrics()
-{
- CheckFontMetrics();
-}
-CPDF_Type3Char* CPDF_Type3Font::LoadChar(FX_DWORD charcode, int level)
-{
- if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_) {
- return NULL;
- }
- CPDF_Type3Char* pChar = NULL;
- if (m_CacheMap.Lookup((FX_LPVOID)(FX_UINTPTR)charcode, (FX_LPVOID&)pChar)) {
- if (pChar->m_bPageRequired && m_pPageResources) {
- delete pChar;
- m_CacheMap.RemoveKey((FX_LPVOID)(FX_UINTPTR)charcode);
- return LoadChar(charcode, level + 1);
- }
- return pChar;
- }
- FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
- if (name == NULL) {
- return NULL;
- }
- CPDF_Stream* pStream = (CPDF_Stream*)m_pCharProcs->GetElementValue(name);
- if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) {
- return NULL;
- }
- pChar = FX_NEW CPDF_Type3Char;
- pChar->m_pForm = FX_NEW CPDF_Form(m_pDocument, m_pFontResources ? m_pFontResources : m_pPageResources, pStream, NULL);
- pChar->m_pForm->ParseContent(NULL, NULL, pChar, NULL, level + 1);
- FX_FLOAT scale = m_FontMatrix.GetXUnit();
- pChar->m_Width = (FX_INT32)(pChar->m_Width * scale + 0.5f);
- FX_RECT &rcBBox = pChar->m_BBox;
- CFX_FloatRect char_rect((FX_FLOAT)rcBBox.left / 1000.0f, (FX_FLOAT)rcBBox.bottom / 1000.0f,
- (FX_FLOAT)rcBBox.right / 1000.0f, (FX_FLOAT)rcBBox.top / 1000.0f);
- if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top) {
- char_rect = pChar->m_pForm->CalcBoundingBox();
- }
- char_rect.Transform(&m_FontMatrix);
- rcBBox.left = FXSYS_round(char_rect.left * 1000);
- rcBBox.right = FXSYS_round(char_rect.right * 1000);
- rcBBox.top = FXSYS_round(char_rect.top * 1000);
- rcBBox.bottom = FXSYS_round(char_rect.bottom * 1000);
- m_CacheMap.SetAt((FX_LPVOID)(FX_UINTPTR)charcode, pChar);
- if (pChar->m_pForm->CountObjects() == 0) {
- delete pChar->m_pForm;
- pChar->m_pForm = NULL;
- }
- return pChar;
-}
-int CPDF_Type3Font::GetCharWidthF(FX_DWORD charcode, int level)
-{
- if (charcode > 0xff) {
- charcode = 0;
- }
- if (m_CharWidthL[charcode]) {
- return m_CharWidthL[charcode];
- }
- CPDF_Type3Char* pChar = LoadChar(charcode, level);
- if (pChar == NULL) {
- return 0;
- }
- return pChar->m_Width;
-}
-void CPDF_Type3Font::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level)
-{
- CPDF_Type3Char* pChar = LoadChar(charcode, level);
- if (pChar == NULL) {
- rect.left = rect.right = rect.top = rect.bottom = 0;
- return;
- }
- rect = pChar->m_BBox;
-}
-CPDF_Type3Char::CPDF_Type3Char()
-{
- m_pForm = NULL;
- m_pBitmap = NULL;
- m_bPageRequired = FALSE;
- m_bColored = FALSE;
-}
-CPDF_Type3Char::~CPDF_Type3Char()
-{
- if (m_pForm) {
- delete m_pForm;
- }
- if (m_pBitmap) {
- delete m_pBitmap;
- }
-}
+// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "../../../include/fpdfapi/fpdf_page.h" +#include "../../../include/fpdfapi/fpdf_module.h" +#include "../../../include/fpdfapi/fpdf_pageobj.h" +#include "font_int.h" +#include "../fpdf_page/pageint.h" +#include "../../../include/fxge/fx_freetype.h" +FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id) +{ + for (int i = 0; i < FXFT_Get_Face_CharmapCount(face); i ++) { + if (FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(face)[i]) == platform_id && + FXFT_Get_Charmap_EncodingID(FXFT_Get_Face_Charmaps(face)[i]) == encoding_id) { + FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]); + return TRUE; + } + } + return FALSE; +} +extern const FX_WORD* PDF_UnicodesForPredefinedCharSet(int); +CPDF_FontGlobals::CPDF_FontGlobals() +{ + FXSYS_memset32(m_EmbeddedCharsets, 0, sizeof m_EmbeddedCharsets); + FXSYS_memset32(m_EmbeddedToUnicodes, 0, sizeof m_EmbeddedToUnicodes); + m_pContrastRamps = NULL; +} +CPDF_FontGlobals::~CPDF_FontGlobals() +{ + ClearAll(); + if (m_pContrastRamps) { + FX_Free(m_pContrastRamps); + } +} +class CFX_StockFontArray : public CFX_Object +{ +public: + CFX_StockFontArray() + { + FXSYS_memset32(m_pStockFonts, 0, sizeof(CPDF_Font*) * 14); + } + CPDF_Font* m_pStockFonts[14]; +}; +CPDF_Font* CPDF_FontGlobals::Find(void* key, int index) +{ + void* value = NULL; + if (!m_pStockMap.Lookup(key, value)) { + return NULL; + } + if (!value) { + return NULL; + } + return ((CFX_StockFontArray*)value)->m_pStockFonts[index]; +} +void CPDF_FontGlobals::Set(void* key, int index, CPDF_Font* pFont) +{ + void* value = NULL; + if (m_pStockMap.Lookup(key, value)) { + ((CFX_StockFontArray*)value)->m_pStockFonts[index] = pFont; + return; + } + CFX_StockFontArray* pFonts = FX_NEW CFX_StockFontArray(); + if (pFonts) { + pFonts->m_pStockFonts[index] = pFont; + } + m_pStockMap.SetAt(key, pFonts); +} +void CPDF_FontGlobals::Clear(void* key) +{ + void* value = NULL; + if (!m_pStockMap.Lookup(key, value)) { + return; + } + if (value) { + CFX_StockFontArray* pStockFonts = (CFX_StockFontArray*)value; + for (int i = 0; i < 14; i ++) { + if (pStockFonts->m_pStockFonts[i]) { + pStockFonts->m_pStockFonts[i]->GetFontDict()->Release(); + delete pStockFonts->m_pStockFonts[i]; + } + } + delete pStockFonts; + } + m_pStockMap.RemoveKey(key); +} +void CPDF_FontGlobals::ClearAll() +{ + FX_POSITION pos = m_pStockMap.GetStartPosition(); + while (pos) { + void *key = NULL; + void* value = NULL; + m_pStockMap.GetNextAssoc(pos, key, value); + if (value) { + CFX_StockFontArray* pStockFonts = (CFX_StockFontArray*)value; + for (int i = 0; i < 14; i ++) { + if (pStockFonts->m_pStockFonts[i]) { + pStockFonts->m_pStockFonts[i]->GetFontDict()->Release(); + delete pStockFonts->m_pStockFonts[i]; + } + } + delete pStockFonts; + } + m_pStockMap.RemoveKey(key); + } +} +CPDF_Font::CPDF_Font() +{ + m_FontType = 0; + m_FontBBox.left = m_FontBBox.right = m_FontBBox.top = m_FontBBox.bottom = 0; + m_StemV = m_Ascent = m_Descent = m_ItalicAngle = 0; + m_pFontFile = NULL; + m_Flags = 0; + m_pToUnicodeMap = NULL; + m_bToUnicodeLoaded = FALSE; + m_pCharMap = NULL; +} +FX_BOOL CPDF_Font::Initialize() +{ + m_pCharMap = FX_NEW CPDF_FontCharMap(this); + return TRUE; +} +CPDF_Font::~CPDF_Font() +{ + if (m_pCharMap) { + FX_Free(m_pCharMap); + m_pCharMap = NULL; + } + if (m_pToUnicodeMap) { + delete m_pToUnicodeMap; + m_pToUnicodeMap = NULL; + } + if (m_pFontFile) { + m_pDocument->GetPageData()->ReleaseFontFileStreamAcc((CPDF_Stream*)m_pFontFile->GetStream()); + } +} +FX_BOOL CPDF_Font::IsVertWriting() const +{ + FX_BOOL bVertWriting = FALSE; + CPDF_CIDFont* pCIDFont = GetCIDFont(); + if (pCIDFont) { + bVertWriting = pCIDFont->IsVertWriting(); + } else { + bVertWriting = m_Font.IsVertical(); + } + return bVertWriting; +} +CFX_ByteString CPDF_Font::GetFontTypeName() const +{ + switch (m_FontType) { + case PDFFONT_TYPE1: + return FX_BSTRC("Type1"); + case PDFFONT_TRUETYPE: + return FX_BSTRC("TrueType"); + case PDFFONT_TYPE3: + return FX_BSTRC("Type3"); + case PDFFONT_CIDFONT: + return FX_BSTRC("Type0"); + } + return CFX_ByteString(); +} +void CPDF_Font::AppendChar(CFX_ByteString& str, FX_DWORD charcode) const +{ + char buf[4]; + int len = AppendChar(buf, charcode); + if (len == 1) { + str += buf[0]; + } else { + str += CFX_ByteString(buf, len); + } +} +CFX_WideString CPDF_Font::UnicodeFromCharCode(FX_DWORD charcode) const +{ + if (!m_bToUnicodeLoaded) { + ((CPDF_Font*)this)->LoadUnicodeMap(); + } + if (m_pToUnicodeMap) { + CFX_WideString wsRet = m_pToUnicodeMap->Lookup(charcode); + if (!wsRet.IsEmpty()) { + return wsRet; + } + } + FX_WCHAR unicode = _UnicodeFromCharCode(charcode); + if (unicode == 0) { + return CFX_WideString(); + } + return unicode; +} +FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const +{ + if (!m_bToUnicodeLoaded) { + ((CPDF_Font*)this)->LoadUnicodeMap(); + } + if (m_pToUnicodeMap) { + FX_DWORD charcode = m_pToUnicodeMap->ReverseLookup(unicode); + if (charcode) { + return charcode; + } + } + return _CharCodeFromUnicode(unicode); +} +CFX_WideString CPDF_Font::DecodeString(const CFX_ByteString& str) const +{ + CFX_WideString result; + int src_len = str.GetLength(); + result.Reserve(src_len); + FX_LPCSTR src_buf = str; + int src_pos = 0; + while (src_pos < src_len) { + FX_DWORD charcode = GetNextChar(src_buf, src_pos); + CFX_WideString unicode = UnicodeFromCharCode(charcode); + if (!unicode.IsEmpty()) { + result += unicode; + } else { + result += (FX_WCHAR)charcode; + } + } + return result; +} +CFX_ByteString CPDF_Font::EncodeString(const CFX_WideString& str) const +{ + CFX_ByteString result; + int src_len = str.GetLength(); + FX_LPSTR dest_buf = result.GetBuffer(src_len * 2); + FX_LPCWSTR src_buf = str; + int dest_pos = 0; + for (int src_pos = 0; src_pos < src_len; src_pos ++) { + FX_DWORD charcode = CharCodeFromUnicode(src_buf[src_pos]); + dest_pos += AppendChar(dest_buf + dest_pos, charcode); + } + result.ReleaseBuffer(dest_pos); + return result; +} +void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) +{ + m_Flags = pFontDesc->GetInteger(FX_BSTRC("Flags"), PDFFONT_NONSYMBOLIC); + int ItalicAngle = 0; + FX_BOOL bExistItalicAngle = FALSE; + if (pFontDesc->KeyExist(FX_BSTRC("ItalicAngle"))) { + ItalicAngle = pFontDesc->GetInteger(FX_BSTRC("ItalicAngle")); + bExistItalicAngle = TRUE; + } + if (ItalicAngle < 0) { + m_Flags |= PDFFONT_ITALIC; + m_ItalicAngle = ItalicAngle; + } + FX_BOOL bExistStemV = FALSE; + if (pFontDesc->KeyExist(FX_BSTRC("StemV"))) { + m_StemV = pFontDesc->GetInteger(FX_BSTRC("StemV")); + bExistStemV = TRUE; + } + FX_BOOL bExistAscent = FALSE; + if (pFontDesc->KeyExist(FX_BSTRC("Ascent"))) { + m_Ascent = pFontDesc->GetInteger(FX_BSTRC("Ascent")); + bExistAscent = TRUE; + } + FX_BOOL bExistDescent = FALSE; + if (pFontDesc->KeyExist(FX_BSTRC("Descent"))) { + m_Descent = pFontDesc->GetInteger(FX_BSTRC("Descent")); + bExistDescent = TRUE; + } + FX_BOOL bExistCapHeight = FALSE; + if (pFontDesc->KeyExist(FX_BSTRC("CapHeight"))) { + bExistCapHeight = TRUE; + } + if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent && bExistStemV) { + m_Flags |= PDFFONT_USEEXTERNATTR; + } + if (m_Descent > 10) { + m_Descent = -m_Descent; + } + CPDF_Array* pBBox = pFontDesc->GetArray(FX_BSTRC("FontBBox")); + if (pBBox) { + m_FontBBox.left = pBBox->GetInteger(0); + m_FontBBox.bottom = pBBox->GetInteger(1); + m_FontBBox.right = pBBox->GetInteger(2); + m_FontBBox.top = pBBox->GetInteger(3); + } + CPDF_Stream* pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile")); + if (pFontFile == NULL) { + pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile2")); + } + if (pFontFile == NULL) { + pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile3")); + } + if (pFontFile) { + m_pFontFile = m_pDocument->LoadFontFile(pFontFile); + if (m_pFontFile == NULL) { + return; + } + FX_LPCBYTE pFontData = m_pFontFile->GetData(); + FX_DWORD dwFontSize = m_pFontFile->GetSize(); + m_Font.LoadEmbedded(pFontData, dwFontSize); + if (m_Font.m_Face == NULL) { + m_pFontFile = NULL; + } + } +} +short TT2PDF(int m, FXFT_Face face) +{ + int upm = FXFT_Get_Face_UnitsPerEM(face); + if (upm == 0) { + return (short)m; + } + return (m * 1000 + upm / 2) / upm; +} +void CPDF_Font::CheckFontMetrics() +{ + if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 && m_FontBBox.right == 0) { + if (m_Font.m_Face) { + m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(m_Font.m_Face), m_Font.m_Face); + m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(m_Font.m_Face), m_Font.m_Face); + m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(m_Font.m_Face), m_Font.m_Face); + m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(m_Font.m_Face), m_Font.m_Face); + m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(m_Font.m_Face), m_Font.m_Face); + m_Descent = TT2PDF(FXFT_Get_Face_Descender(m_Font.m_Face), m_Font.m_Face); + } else { + FX_BOOL bFirst = TRUE; + for (int i = 0; i < 256; i ++) { + FX_RECT rect; + GetCharBBox(i, rect); + if (rect.left == rect.right) { + continue; + } + if (bFirst) { + m_FontBBox = rect; + bFirst = FALSE; + } else { + if (m_FontBBox.top < rect.top) { + m_FontBBox.top = rect.top; + } + if (m_FontBBox.right < rect.right) { + m_FontBBox.right = rect.right; + } + if (m_FontBBox.left > rect.left) { + m_FontBBox.left = rect.left; + } + if (m_FontBBox.bottom > rect.bottom) { + m_FontBBox.bottom = rect.bottom; + } + } + } + } + } + if (m_Ascent == 0 && m_Descent == 0) { + FX_RECT rect; + GetCharBBox('A', rect); + if (rect.bottom == rect.top) { + m_Ascent = m_FontBBox.top; + } else { + m_Ascent = rect.top; + } + GetCharBBox('g', rect); + if (rect.bottom == rect.top) { + m_Descent = m_FontBBox.bottom; + } else { + m_Descent = rect.bottom; + } + } +} +void CPDF_Font::LoadUnicodeMap() +{ + m_bToUnicodeLoaded = TRUE; + CPDF_Stream* pStream = m_pFontDict->GetStream(FX_BSTRC("ToUnicode")); + if (pStream == NULL) { + return; + } + m_pToUnicodeMap = FX_NEW CPDF_ToUnicodeMap; + m_pToUnicodeMap->Load(pStream); +} +int CPDF_Font::GetStringWidth(FX_LPCSTR pString, int size) +{ + int offset = 0; + int width = 0; + while (offset < size) { + FX_DWORD charcode = GetNextChar(pString, offset); + width += GetCharWidthF(charcode); + } + return width; +} +int CPDF_Font::GetCharTypeWidth(FX_DWORD charcode) +{ + if (m_Font.m_Face == NULL) { + return 0; + } + int glyph_index = GlyphFromCharCode(charcode); + if (glyph_index == 0xffff) { + return 0; + } + return m_Font.GetGlyphWidth(glyph_index); +} +int _PDF_GetStandardFontName(CFX_ByteString& name); +CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc, FX_BSTR name) +{ + CFX_ByteString fontname(name); + int font_id = _PDF_GetStandardFontName(fontname); + if (font_id < 0) { + return NULL; + } + CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); + CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id); + if (pFont) { + return pFont; + } + CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); + pDict->SetAtName(FX_BSTRC("Type"), FX_BSTRC("Font")); + pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Type1")); + pDict->SetAtName(FX_BSTRC("BaseFont"), fontname); + pDict->SetAtName(FX_BSTRC("Encoding"), FX_BSTRC("WinAnsiEncoding")); + pFont = CPDF_Font::CreateFontF(NULL, pDict); + pFontGlobals->Set(pDoc, font_id, pFont); + return pFont; +} +const FX_BYTE ChineseFontNames[][5] = { + {0xCB, 0xCE, 0xCC, 0xE5, 0x00}, + {0xBF, 0xAC, 0xCC, 0xE5, 0x00}, + {0xBA, 0xDA, 0xCC, 0xE5, 0x00}, + {0xB7, 0xC2, 0xCB, 0xCE, 0x00}, + {0xD0, 0xC2, 0xCB, 0xCE, 0x00} +}; +CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc, CPDF_Dictionary* pFontDict) +{ + CFX_ByteString type = pFontDict->GetString(FX_BSTRC("Subtype")); + CPDF_Font* pFont; + if (type == FX_BSTRC("TrueType")) { + { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ || _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + CFX_ByteString basefont = pFontDict->GetString(FX_BSTRC("BaseFont")); + CFX_ByteString tag = basefont.Left(4); + int i; + int count = sizeof(ChineseFontNames) / sizeof(ChineseFontNames[0]); + for (i = 0; i < count; ++i) { + if (tag == CFX_ByteString((FX_LPCSTR)ChineseFontNames[i])) { + break; + } + } + if (i < count) { + CPDF_Dictionary* pFontDesc = pFontDict->GetDict(FX_BSTRC("FontDescriptor")); + if (pFontDesc == NULL || !pFontDesc->KeyExist(FX_BSTRC("FontFile2"))) { + pFont = FX_NEW CPDF_CIDFont; + pFont->Initialize(); + pFont->m_FontType = PDFFONT_CIDFONT; + pFont->m_pFontDict = pFontDict; + pFont->m_pDocument = pDoc; + if (!pFont->Load()) { + delete pFont; + return NULL; + } + return pFont; + } + } +#endif + } + pFont = FX_NEW CPDF_TrueTypeFont; + pFont->Initialize(); + pFont->m_FontType = PDFFONT_TRUETYPE; + } else if (type == FX_BSTRC("Type3")) { + pFont = FX_NEW CPDF_Type3Font; + pFont->Initialize(); + pFont->m_FontType = PDFFONT_TYPE3; + } else if (type == FX_BSTRC("Type0")) { + pFont = FX_NEW CPDF_CIDFont; + pFont->Initialize(); + pFont->m_FontType = PDFFONT_CIDFONT; + } else { + pFont = FX_NEW CPDF_Type1Font; + pFont->Initialize(); + pFont->m_FontType = PDFFONT_TYPE1; + } + pFont->m_pFontDict = pFontDict; + pFont->m_pDocument = pDoc; + if (!pFont->Load()) { + delete pFont; + return NULL; + } + return pFont; +} +FX_BOOL CPDF_Font::Load() +{ + if (m_pFontDict == NULL) { + return FALSE; + } + CFX_ByteString type = m_pFontDict->GetString(FX_BSTRC("Subtype")); + m_BaseFont = m_pFontDict->GetString(FX_BSTRC("BaseFont")); + if (type == FX_BSTRC("MMType1")) { + type = FX_BSTRC("Type1"); + } + return _Load(); +} +static CFX_WideString _FontMap_GetWideString(CFX_CharMap* pMap, const CFX_ByteString& bytestr) +{ + return ((CPDF_FontCharMap*)pMap)->m_pFont->DecodeString(bytestr); +} +static CFX_ByteString _FontMap_GetByteString(CFX_CharMap* pMap, const CFX_WideString& widestr) +{ + return ((CPDF_FontCharMap*)pMap)->m_pFont->EncodeString(widestr); +} +CPDF_FontCharMap::CPDF_FontCharMap(CPDF_Font* pFont) +{ + m_GetByteString = _FontMap_GetByteString; + m_GetWideString = _FontMap_GetWideString; + m_pFont = pFont; +} +CFX_WideString CPDF_ToUnicodeMap::Lookup(FX_DWORD charcode) +{ + FX_DWORD value; + if (m_Map.Lookup(charcode, value)) { + FX_WCHAR unicode = (FX_WCHAR)(value & 0xffff); + if (unicode != 0xffff) { + return unicode; + } + FX_LPCWSTR buf = m_MultiCharBuf.GetBuffer(); + FX_DWORD buf_len = m_MultiCharBuf.GetLength(); + if (buf == NULL || buf_len == 0) { + return CFX_WideString(); + } + FX_DWORD index = value >> 16; + if (index >= buf_len) { + return CFX_WideString(); + } + FX_DWORD len = buf[index]; + if (index + len < index || index + len >= buf_len) { + return CFX_WideString(); + } + return CFX_WideString(buf + index + 1, len); + } + if (m_pBaseMap) { + return m_pBaseMap->UnicodeFromCID((FX_WORD)charcode); + } + return CFX_WideString(); +} +FX_DWORD CPDF_ToUnicodeMap::ReverseLookup(FX_WCHAR unicode) +{ + FX_POSITION pos = m_Map.GetStartPosition(); + while (pos) { + FX_DWORD key, value; + m_Map.GetNextAssoc(pos, key, value); + if ((FX_WCHAR)value == unicode) { + return key; + } + } + return 0; +} +static FX_DWORD _StringToCode(FX_BSTR str) +{ + FX_LPCSTR buf = str.GetCStr(); + int len = str.GetLength(); + if (len == 0) { + return 0; + } + int result = 0; + if (buf[0] == '<') { + for (int i = 1; i < len; i ++) { + int digit; + if (buf[i] >= '0' && buf[i] <= '9') { + digit = buf[i] - '0'; + } else if (buf[i] >= 'a' && buf[i] <= 'f') { + digit = buf[i] - 'a' + 10; + } else if (buf[i] >= 'A' && buf[i] <= 'F') { + digit = buf[i] - 'A' + 10; + } else { + break; + } + result = result * 16 + digit; + } + return result; + } else { + for (int i = 0; i < len; i ++) { + if (buf[i] < '0' || buf[i] > '9') { + break; + } + result = result * 10 + buf[i] - '0'; + } + } + return result; +} +static CFX_WideString _StringDataAdd(CFX_WideString str) +{ + CFX_WideString ret; + int len = str.GetLength(); + FX_WCHAR value = 1; + for (int i = len - 1; i >= 0 ; --i) { + FX_WCHAR ch = str[i] + value; + if (ch < str[i]) { + ret.Insert(0, 0); + } else { + ret.Insert(0, ch); + value = 0; + } + } + if (value) { + ret.Insert(0, value); + } + return ret; +} +static CFX_WideString _StringToWideString(FX_BSTR str) +{ + FX_LPCSTR buf = str.GetCStr(); + int len = str.GetLength(); + if (len == 0) { + return CFX_WideString(); + } + CFX_WideString result; + if (buf[0] == '<') { + int byte_pos = 0; + FX_WCHAR ch = 0; + for (int i = 1; i < len; i ++) { + int digit; + if (buf[i] >= '0' && buf[i] <= '9') { + digit = buf[i] - '0'; + } else if (buf[i] >= 'a' && buf[i] <= 'f') { + digit = buf[i] - 'a' + 10; + } else if (buf[i] >= 'A' && buf[i] <= 'F') { + digit = buf[i] - 'A' + 10; + } else { + break; + } + ch = ch * 16 + digit; + byte_pos ++; + if (byte_pos == 4) { + result += ch; + byte_pos = 0; + ch = 0; + } + } + return result; + } + if (buf[0] == '(') { + } + return result; +} +void CPDF_ToUnicodeMap::Load(CPDF_Stream* pStream) +{ + int CIDSet = 0; + CPDF_StreamAcc stream; + stream.LoadAllData(pStream, FALSE); + CPDF_SimpleParser parser(stream.GetData(), stream.GetSize()); + m_Map.EstimateSize(stream.GetSize() / 8, 1024); + while (1) { + CFX_ByteStringC word = parser.GetWord(); + if (word.IsEmpty()) { + break; + } + if (word == FX_BSTRC("beginbfchar")) { + while (1) { + word = parser.GetWord(); + if (word.IsEmpty() || word == FX_BSTRC("endbfchar")) { + break; + } + FX_DWORD srccode = _StringToCode(word); + word = parser.GetWord(); + CFX_WideString destcode = _StringToWideString(word); + int len = destcode.GetLength(); + if (len == 0) { + continue; + } + if (len == 1) { + m_Map.SetAt(srccode, destcode.GetAt(0)); + } else { + m_Map.SetAt(srccode, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff); + m_MultiCharBuf.AppendChar(destcode.GetLength()); + m_MultiCharBuf << destcode; + } + } + } else if (word == FX_BSTRC("beginbfrange")) { + while (1) { + CFX_ByteString low, high; + low = parser.GetWord(); + if (low.IsEmpty() || low == FX_BSTRC("endbfrange")) { + break; + } + high = parser.GetWord(); + FX_DWORD lowcode = _StringToCode(low); + FX_DWORD highcode = (lowcode & 0xffffff00) | (_StringToCode(high) & 0xff); + if (highcode == (FX_DWORD) - 1) { + break; + } + CFX_ByteString start = parser.GetWord(); + if (start == FX_BSTRC("[")) { + for (FX_DWORD code = lowcode; code <= highcode; code ++) { + CFX_ByteString dest = parser.GetWord(); + CFX_WideString destcode = _StringToWideString(dest); + int len = destcode.GetLength(); + if (len == 0) { + continue; + } + if (len == 1) { + m_Map.SetAt(code, destcode.GetAt(0)); + } else { + m_Map.SetAt(code, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff); + m_MultiCharBuf.AppendChar(destcode.GetLength()); + m_MultiCharBuf << destcode; + } + } + parser.GetWord(); + } else { + CFX_WideString destcode = _StringToWideString(start); + int len = destcode.GetLength(); + FX_DWORD value = 0; + if (len == 1) { + value = _StringToCode(start); + for (FX_DWORD code = lowcode; code <= highcode; code ++) { + m_Map.SetAt(code, value++); + } + } else { + for (FX_DWORD code = lowcode; code <= highcode; code ++) { + CFX_WideString retcode; + if (code == lowcode) { + retcode = destcode; + } else { + retcode = _StringDataAdd(destcode); + } + m_Map.SetAt(code, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff); + m_MultiCharBuf.AppendChar(retcode.GetLength()); + m_MultiCharBuf << retcode; + destcode = retcode; + } + } + } + } + } else if (word == FX_BSTRC("/Adobe-Korea1-UCS2")) { + CIDSet = CIDSET_KOREA1; + } else if (word == FX_BSTRC("/Adobe-Japan1-UCS2")) { + CIDSet = CIDSET_JAPAN1; + } else if (word == FX_BSTRC("/Adobe-CNS1-UCS2")) { + CIDSet = CIDSET_CNS1; + } else if (word == FX_BSTRC("/Adobe-GB1-UCS2")) { + CIDSet = CIDSET_GB1; + } + } + if (CIDSet) { + m_pBaseMap = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals()->m_CMapManager.GetCID2UnicodeMap(CIDSet, FALSE); + } else { + m_pBaseMap = NULL; + } +} +static FX_BOOL GetPredefinedEncoding(int& basemap, const CFX_ByteString& value) +{ + if (value == FX_BSTRC("WinAnsiEncoding")) { + basemap = PDFFONT_ENCODING_WINANSI; + } else if (value == FX_BSTRC("MacRomanEncoding")) { + basemap = PDFFONT_ENCODING_MACROMAN; + } else if (value == FX_BSTRC("MacExpertEncoding")) { + basemap = PDFFONT_ENCODING_MACEXPERT; + } else if (value == FX_BSTRC("PDFDocEncoding")) { + basemap = PDFFONT_ENCODING_PDFDOC; + } else { + return FALSE; + } + return TRUE; +} +void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding, int& iBaseEncoding, CFX_ByteString*& pCharNames, + FX_BOOL bEmbedded, FX_BOOL bTrueType) +{ + if (pEncoding == NULL) { + if (m_BaseFont == FX_BSTRC("Symbol")) { + iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL : PDFFONT_ENCODING_ADOBE_SYMBOL; + } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) { + iBaseEncoding = PDFFONT_ENCODING_WINANSI; + } + return; + } + if (pEncoding->GetType() == PDFOBJ_NAME) { + if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL || iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) { + return; + } + if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == FX_BSTRC("Symbol")) { + if (!bTrueType) { + iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL; + } + return; + } + CFX_ByteString bsEncoding = pEncoding->GetString(); + if (bsEncoding.Compare(FX_BSTRC("MacExpertEncoding")) == 0) { + bsEncoding = FX_BSTRC("WinAnsiEncoding"); + } + GetPredefinedEncoding(iBaseEncoding, bsEncoding); + return; + } + if (pEncoding->GetType() != PDFOBJ_DICTIONARY) { + return; + } + CPDF_Dictionary* pDict = (CPDF_Dictionary*)pEncoding; + if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL && iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) { + CFX_ByteString bsEncoding = pDict->GetString(FX_BSTRC("BaseEncoding")); + if (bsEncoding.Compare(FX_BSTRC("MacExpertEncoding")) == 0 && bTrueType) { + bsEncoding = FX_BSTRC("WinAnsiEncoding"); + } + GetPredefinedEncoding(iBaseEncoding, bsEncoding); + } + if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) { + iBaseEncoding = PDFFONT_ENCODING_STANDARD; + } + CPDF_Array* pDiffs = pDict->GetArray(FX_BSTRC("Differences")); + if (pDiffs == NULL) { + return; + } + FX_NEW_VECTOR(pCharNames, CFX_ByteString, 256); + FX_DWORD cur_code = 0; + for (FX_DWORD i = 0; i < pDiffs->GetCount(); i ++) { + CPDF_Object* pElement = pDiffs->GetElementValue(i); + if (pElement == NULL) { + continue; + } + if (pElement->GetType() == PDFOBJ_NAME) { + if (cur_code < 256) { + pCharNames[cur_code] = ((CPDF_Name*)pElement)->GetString(); + } + cur_code ++; + } else { + cur_code = pElement->GetInteger(); + } + } +} +FX_BOOL CPDF_Font::IsStandardFont() const +{ + if (m_FontType != PDFFONT_TYPE1) { + return FALSE; + } + if (m_pFontFile != NULL) { + return FALSE; + } + if (((CPDF_Type1Font*)this)->GetBase14Font() < 0) { + return FALSE; + } + return TRUE; +} +extern FX_LPCSTR PDF_CharNameFromPredefinedCharSet(int encoding, FX_BYTE charcode); +CPDF_SimpleFont::CPDF_SimpleFont() +{ + FXSYS_memset8(m_CharBBox, 0xff, sizeof m_CharBBox); + FXSYS_memset8(m_CharWidth, 0xff, sizeof m_CharWidth); + FXSYS_memset8(m_GlyphIndex, 0xff, sizeof m_GlyphIndex); + FXSYS_memset8(m_ExtGID, 0xff, sizeof m_ExtGID); + m_pCharNames = NULL; + m_BaseEncoding = PDFFONT_ENCODING_BUILTIN; +} +CPDF_SimpleFont::~CPDF_SimpleFont() +{ + if (m_pCharNames) { + FX_DELETE_VECTOR(m_pCharNames, CFX_ByteString, 256); + } +} +int CPDF_SimpleFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL *pVertGlyph) +{ + if (pVertGlyph) { + *pVertGlyph = FALSE; + } + if (charcode > 0xff) { + return -1; + } + int index = m_GlyphIndex[(FX_BYTE)charcode]; + if (index == 0xffff) { + return -1; + } + return index; +} +void CPDF_SimpleFont::LoadCharMetrics(int charcode) +{ + if (m_Font.m_Face == NULL) { + return; + } + if (charcode < 0 || charcode > 0xff) { + return; + } + int glyph_index = m_GlyphIndex[charcode]; + if (glyph_index == 0xffff) { + if (m_pFontFile == NULL && charcode != 32) { + LoadCharMetrics(32); + m_CharBBox[charcode] = m_CharBBox[32]; + if (m_bUseFontWidth) { + m_CharWidth[charcode] = m_CharWidth[32]; + } + } + return; + } + int err = FXFT_Load_Glyph(m_Font.m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); + if (err) { + return; + } + m_CharBBox[charcode].Left = TT2PDF(FXFT_Get_Glyph_HoriBearingX(m_Font.m_Face), m_Font.m_Face); + m_CharBBox[charcode].Right = TT2PDF(FXFT_Get_Glyph_HoriBearingX(m_Font.m_Face) + FXFT_Get_Glyph_Width(m_Font.m_Face), m_Font.m_Face); + m_CharBBox[charcode].Top = TT2PDF(FXFT_Get_Glyph_HoriBearingY(m_Font.m_Face), m_Font.m_Face); + m_CharBBox[charcode].Bottom = TT2PDF(FXFT_Get_Glyph_HoriBearingY(m_Font.m_Face) - FXFT_Get_Glyph_Height(m_Font.m_Face), m_Font.m_Face); + if (m_bUseFontWidth) { + int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(m_Font.m_Face), m_Font.m_Face); + if (m_CharWidth[charcode] == 0xffff) { + m_CharWidth[charcode] = TT_Width; + } else if (TT_Width && !IsEmbedded()) { + m_CharBBox[charcode].Right = m_CharBBox[charcode].Right * m_CharWidth[charcode] / TT_Width; + m_CharBBox[charcode].Left = m_CharBBox[charcode].Left * m_CharWidth[charcode] / TT_Width; + } + } +} +int CPDF_SimpleFont::GetCharWidthF(FX_DWORD charcode, int level) +{ + if (charcode > 0xff) { + charcode = 0; + } + if (m_CharWidth[charcode] == 0xffff) { + LoadCharMetrics(charcode); + if (m_CharWidth[charcode] == 0xffff) { + m_CharWidth[charcode] = 0; + } + } + return (FX_INT16)m_CharWidth[charcode]; +} +void CPDF_SimpleFont::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level) +{ + if (charcode > 0xff) { + charcode = 0; + } + if (m_CharBBox[charcode].Left == (FX_SHORT)0xffff) { + LoadCharMetrics(charcode); + } + rect.left = m_CharBBox[charcode].Left; + rect.right = m_CharBBox[charcode].Right; + rect.bottom = m_CharBBox[charcode].Bottom; + rect.top = m_CharBBox[charcode].Top; +} +FX_LPCSTR GetAdobeCharName(int iBaseEncoding, const CFX_ByteString* pCharNames, int charcode) +{ + ASSERT(charcode >= 0 && charcode < 256); + if (charcode < 0 || charcode >= 256) { + return NULL; + } + FX_LPCSTR name = NULL; + if (pCharNames) { + name = pCharNames[charcode]; + } + if ((name == NULL || name[0] == 0) && iBaseEncoding) { + name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode); + } + if (name == NULL || name[0] == 0) { + return NULL; + } + return name; +} +FX_BOOL CPDF_SimpleFont::LoadCommon() +{ + CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict(FX_BSTRC("FontDescriptor")); + if (pFontDesc) { + LoadFontDescriptor(pFontDesc); + } + CPDF_Array* pWidthArray = m_pFontDict->GetArray(FX_BSTRC("Widths")); + int width_start = 0, width_end = -1; + m_bUseFontWidth = TRUE; + if (pWidthArray) { + m_bUseFontWidth = FALSE; + if (pFontDesc && pFontDesc->KeyExist(FX_BSTRC("MissingWidth"))) { + int MissingWidth = pFontDesc->GetInteger(FX_BSTRC("MissingWidth")); + for (int i = 0; i < 256; i ++) { + m_CharWidth[i] = MissingWidth; + } + } + width_start = m_pFontDict->GetInteger(FX_BSTRC("FirstChar"), 0); + width_end = m_pFontDict->GetInteger(FX_BSTRC("LastChar"), 0); + if (width_start >= 0 && width_start <= 255) { + if (width_end <= 0 || width_end >= width_start + (int)pWidthArray->GetCount()) { + width_end = width_start + pWidthArray->GetCount() - 1; + } + if (width_end > 255) { + width_end = 255; + } + for (int i = width_start; i <= width_end; i ++) { + m_CharWidth[i] = pWidthArray->GetInteger(i - width_start); + } + } + } + if (m_pFontFile == NULL) { + LoadSubstFont(); + } else { + if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') { + m_BaseFont = m_BaseFont.Mid(8); + } + } + if (!(m_Flags & PDFFONT_SYMBOLIC)) { + m_BaseEncoding = PDFFONT_ENCODING_STANDARD; + } + CPDF_Object* pEncoding = m_pFontDict->GetElementValue(FX_BSTRC("Encoding")); + LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, m_pFontFile != NULL, m_Font.IsTTFont()); + LoadGlyphMap(); + if (m_pCharNames) { + FX_DELETE_VECTOR(m_pCharNames, CFX_ByteString, 256); + m_pCharNames = NULL; + } + if (m_Font.m_Face == NULL) { + return TRUE; + } + if (m_Flags & PDFFONT_ALLCAP) { + unsigned char lowercases[] = {'a', 'z', 0xe0, 0xf6, 0xf8, 0xfd}; + for (int range = 0; range < sizeof lowercases / 2; range ++) { + for (int i = lowercases[range * 2]; i <= lowercases[range * 2 + 1]; i ++) { + if (m_GlyphIndex[i] != 0xffff && m_pFontFile != NULL) { + continue; + } + m_GlyphIndex[i] = m_GlyphIndex[i - 32]; + if (m_CharWidth[i - 32]) { + m_CharWidth[i] = m_CharWidth[i - 32]; + m_CharBBox[i] = m_CharBBox[i - 32]; + } + } + } + } + CheckFontMetrics(); + return TRUE; +} +void CPDF_SimpleFont::LoadSubstFont() +{ + if (!m_bUseFontWidth && !(m_Flags & PDFFONT_FIXEDPITCH)) { + int width = 0, i; + for (i = 0; i < 256; i ++) { + if (m_CharWidth[i] == 0 || m_CharWidth[i] == 0xffff) { + continue; + } + if (width == 0) { + width = m_CharWidth[i]; + } else if (width != m_CharWidth[i]) { + break; + } + } + if (i == 256 && width) { + m_Flags |= PDFFONT_FIXEDPITCH; + } + } + int weight = m_StemV < 140 ? m_StemV * 5 : (m_StemV * 4 + 140); + m_Font.LoadSubst(m_BaseFont, m_FontType == PDFFONT_TRUETYPE, m_Flags, weight, m_ItalicAngle, 0); + if (m_Font.m_pSubstFont->m_SubstFlags & FXFONT_SUBST_NONSYMBOL) { + } +} +FX_BOOL CPDF_SimpleFont::IsUnicodeCompatible() const +{ + return m_BaseEncoding != PDFFONT_ENCODING_BUILTIN && m_BaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL && + m_BaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS; +} +CPDF_Type1Font::CPDF_Type1Font() +{ + m_Base14Font = -1; +} +FX_BOOL CPDF_Type1Font::_Load() +{ + m_Base14Font = _PDF_GetStandardFontName(m_BaseFont); + if (m_Base14Font >= 0) { + CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict(FX_BSTRC("FontDescriptor")); + if (pFontDesc && pFontDesc->KeyExist(FX_BSTRC("Flags"))) { + m_Flags = pFontDesc->GetInteger(FX_BSTRC("Flags")); + } else { + m_Flags = m_Base14Font >= 12 ? PDFFONT_SYMBOLIC : PDFFONT_NONSYMBOLIC; + } + if (m_Base14Font < 4) + for (int i = 0; i < 256; i ++) { + m_CharWidth[i] = 600; + } + if (m_Base14Font == 12) { + m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL; + } else if (m_Base14Font == 13) { + m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS; + } else if (m_Flags & PDFFONT_NONSYMBOLIC) { + m_BaseEncoding = PDFFONT_ENCODING_STANDARD; + } + } + return LoadCommon(); +} +static FX_BOOL FT_UseType1Charmap(FXFT_Face face) +{ + if (FXFT_Get_Face_CharmapCount(face) == 0) { + return FALSE; + } + if (FXFT_Get_Face_CharmapCount(face) == 1 && + FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == FXFT_ENCODING_UNICODE) { + return FALSE; + } + if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == FXFT_ENCODING_UNICODE) { + FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[1]); + } else { + FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]); + } + return TRUE; +} +extern FX_WCHAR FT_UnicodeFromCharCode(int encoding, FX_DWORD charcode); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ +#include "../../fxge/apple/apple_int.h" +#endif +int CPDF_Type1Font::GlyphFromCharCodeExt(FX_DWORD charcode) +{ + if (charcode > 0xff) { + return -1; + } + int index = m_ExtGID[(FX_BYTE)charcode]; + if (index == 0xffff) { + return -1; + } + return index; +} +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ +struct _GlyphNameMap { + FX_LPCSTR m_pStrAdobe; + FX_LPCSTR m_pStrUnicode; +}; +static const _GlyphNameMap g_GlyphNameSubsts[] = { + {"ff", "uniFB00"}, + {"fi", "uniFB01"}, + {"fl", "uniFB02"}, + {"ffi", "uniFB03"}, + {"ffl", "uniFB04"} +}; +extern "C" { + static int compareString(const void* key, const void* element) + { + return FXSYS_stricmp((FX_LPCSTR)key, ((_GlyphNameMap*)element)->m_pStrAdobe); + } +} +static FX_LPCSTR _GlyphNameRemap(FX_LPCSTR pStrAdobe) +{ + _GlyphNameMap* found = (_GlyphNameMap*)FXSYS_bsearch(pStrAdobe, g_GlyphNameSubsts, + sizeof g_GlyphNameSubsts / sizeof(_GlyphNameMap), sizeof(_GlyphNameMap), + compareString); + if (found) { + return found->m_pStrUnicode; + } + return NULL; +} +#endif +void CPDF_Type1Font::LoadGlyphMap() +{ + if (m_Font.m_Face == NULL) { + return; + } +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + FX_BOOL bCoreText = TRUE; + CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d; + if (!m_Font.m_pPlatformFont) { + if (m_Font.GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) { + bCoreText = FALSE; + } + m_Font.m_pPlatformFont = quartz2d.CreateFont(m_Font.m_pFontData, m_Font.m_dwSize); + if (NULL == m_Font.m_pPlatformFont) { + bCoreText = FALSE; + } + } +#endif + if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) { + if (FT_UseTTCharmap(m_Font.m_Face, 3, 0)) { + FX_BOOL bGotOne = FALSE; + for (int charcode = 0; charcode < 256; charcode ++) { + const FX_BYTE prefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; + for (int j = 0; j < 4; j ++) { + FX_WORD unicode = prefix[j] * 256 + charcode; + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + FX_CHAR name_glyph[256]; + FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256); + name_glyph[255] = 0; + CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull); + m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct); + if (name_ct) { + CFRelease(name_ct); + } +#endif + if (m_GlyphIndex[charcode]) { + bGotOne = TRUE; + break; + } + } + } + if (bGotOne) { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (!bCoreText) { + FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256); + } +#endif + return; + } + } + FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE); + if (m_BaseEncoding == 0) { + m_BaseEncoding = PDFFONT_ENCODING_STANDARD; + } + for (int charcode = 0; charcode < 256; charcode ++) { + FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); + if (name == NULL) { + continue; + } + m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, m_Encoding.m_Unicodes[charcode]); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + FX_CHAR name_glyph[256]; + FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256); + name_glyph[255] = 0; + CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull); + m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct); + if (name_ct) { + CFRelease(name_ct); + } +#endif + if (m_GlyphIndex[charcode] == 0 && FXSYS_strcmp(name, ".notdef") == 0) { + m_Encoding.m_Unicodes[charcode] = 0x20; + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, 0x20); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + FX_CHAR name_glyph[256]; + FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256); + name_glyph[255] = 0; + CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull); + m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct); + if (name_ct) { + CFRelease(name_ct); + } +#endif + } + } +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (!bCoreText) { + FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256); + } +#endif + return; + } + FT_UseType1Charmap(m_Font.m_Face); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (bCoreText) { + if (m_Flags & PDFFONT_SYMBOLIC) { + for (int charcode = 0; charcode < 256; charcode ++) { + FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); + if (name) { + m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); + m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name); + CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull); + m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct); + if (name_ct) { + CFRelease(name_ct); + } + } else { + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode); + FX_WCHAR unicode = 0; + if (m_GlyphIndex[charcode]) { + unicode = FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode); + } + FX_CHAR name_glyph[256]; + FXSYS_memset32(name_glyph, 0, sizeof(name_glyph)); + FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256); + name_glyph[255] = 0; + if (unicode == 0 && name_glyph[0] != 0) { + unicode = PDF_UnicodeFromAdobeName(name_glyph); + } + m_Encoding.m_Unicodes[charcode] = unicode; + CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull); + m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct); + if (name_ct) { + CFRelease(name_ct); + } + } + } + return; + } + FX_BOOL bUnicode = FALSE; + if (0 == FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE)) { + bUnicode = TRUE; + } + for (int charcode = 0; charcode < 256; charcode ++) { + FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); + if (name == NULL) { + continue; + } + m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); + FX_LPCSTR pStrUnicode = _GlyphNameRemap(name); + if (pStrUnicode && 0 == FXFT_Get_Name_Index(m_Font.m_Face, (char*)name)) { + name = pStrUnicode; + } + m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name); + CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull); + m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct); + if (name_ct) { + CFRelease(name_ct); + } + if (m_GlyphIndex[charcode] == 0) { + if (FXSYS_strcmp(name, ".notdef") != 0 && FXSYS_strcmp(name, "space") != 0) { + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode); + FX_CHAR name_glyph[256]; + FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256); + name_glyph[255] = 0; + CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull); + m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct); + if (name_ct) { + CFRelease(name_ct); + } + } else { + m_Encoding.m_Unicodes[charcode] = 0x20; + m_GlyphIndex[charcode] = bUnicode ? FXFT_Get_Char_Index(m_Font.m_Face, 0x20) : 0xffff; + FX_CHAR name_glyph[256]; + FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256); + name_glyph[255] = 0; + CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull); + m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct); + if (name_ct) { + CFRelease(name_ct); + } + } + } + } + return; + } +#endif + if (m_Flags & PDFFONT_SYMBOLIC) { + for (int charcode = 0; charcode < 256; charcode ++) { + FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); + if (name) { + m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); + m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name); + } else { + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode); + if (m_GlyphIndex[charcode]) { + FX_WCHAR unicode = FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode); + if (unicode == 0) { + FX_CHAR name_glyph[256]; + FXSYS_memset32(name_glyph, 0, sizeof(name_glyph)); + FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256); + name_glyph[255] = 0; + if (name_glyph[0] != 0) { + unicode = PDF_UnicodeFromAdobeName(name_glyph); + } + } + m_Encoding.m_Unicodes[charcode] = unicode; + } + } + } +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (!bCoreText) { + FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256); + } +#endif + return; + } + FX_BOOL bUnicode = FALSE; + if (0 == FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE)) { + bUnicode = TRUE; + } + for (int charcode = 0; charcode < 256; charcode ++) { + FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); + if (name == NULL) { + continue; + } + m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); + m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name); + if (m_GlyphIndex[charcode] == 0) { + if (FXSYS_strcmp(name, ".notdef") != 0 && FXSYS_strcmp(name, "space") != 0) { + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode); + } else { + m_Encoding.m_Unicodes[charcode] = 0x20; + m_GlyphIndex[charcode] = 0xffff; + } + } + } +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (!bCoreText) { + FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256); + } +#endif +} +CPDF_FontEncoding::CPDF_FontEncoding() +{ + FXSYS_memset32(m_Unicodes, 0, sizeof(m_Unicodes)); +} +int CPDF_FontEncoding::CharCodeFromUnicode(FX_WCHAR unicode) const +{ + for (int i = 0; i < 256; i ++) + if (m_Unicodes[i] == unicode) { + return i; + } + return -1; +} +CPDF_FontEncoding::CPDF_FontEncoding(int PredefinedEncoding) +{ + const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(PredefinedEncoding); + if (!pSrc) { + FXSYS_memset32(m_Unicodes, 0, sizeof(m_Unicodes)); + } else + for (int i = 0; i < 256; i++) { + m_Unicodes[i] = pSrc[i]; + } +} +FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const +{ + return FXSYS_memcmp32(m_Unicodes, pAnother->m_Unicodes, sizeof(m_Unicodes)) == 0; +} +CPDF_Object* CPDF_FontEncoding::Realize() +{ + int predefined = 0; + for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS; cs ++) { + const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(cs); + FX_BOOL match = TRUE; + for (int i = 0; i < 256; ++i) { + if (m_Unicodes[i] != pSrc[i]) { + match = FALSE; + break; + } + } + if (match) { + predefined = cs; + break; + } + } + if (predefined) { + if (predefined == PDFFONT_ENCODING_WINANSI) { + return CPDF_Name::Create("WinAnsiEncoding"); + } + if (predefined == PDFFONT_ENCODING_MACROMAN) { + return CPDF_Name::Create("MacRomanEncoding"); + } + if (predefined == PDFFONT_ENCODING_MACEXPERT) { + return CPDF_Name::Create("MacExpertEncoding"); + } + return NULL; + } + CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); + pDict->SetAtName(FX_BSTRC("BaseEncoding"), FX_BSTRC("WinAnsiEncoding")); + const FX_WORD* pStandard = PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI); + CPDF_Array* pDiff = CPDF_Array::Create(); + for (int i = 0; i < 256; i ++) { + if (pStandard[i] == m_Unicodes[i]) { + continue; + } + pDiff->Add(CPDF_Number::Create(i)); + pDiff->Add(CPDF_Name::Create(PDF_AdobeNameFromUnicode(m_Unicodes[i]))); + } + pDict->SetAt(FX_BSTRC("Differences"), pDiff); + return pDict; +} +CPDF_TrueTypeFont::CPDF_TrueTypeFont() +{ +} +FX_BOOL CPDF_TrueTypeFont::_Load() +{ + return LoadCommon(); +} +extern FX_DWORD FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode); +void CPDF_TrueTypeFont::LoadGlyphMap() +{ + if (m_Font.m_Face == NULL) { + return; + } + int baseEncoding = m_BaseEncoding; + if (m_pFontFile && m_Font.m_Face->num_charmaps > 0 + && (baseEncoding == PDFFONT_ENCODING_MACROMAN || baseEncoding == PDFFONT_ENCODING_WINANSI) + && (m_Flags & PDFFONT_SYMBOLIC)) { + FX_BOOL bSupportWin = FALSE; + FX_BOOL bSupportMac = FALSE; + for (int i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.m_Face); i++) { + int platform_id = FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(m_Font.m_Face)[i]); + if (platform_id == 0 || platform_id == 3) { + bSupportWin = TRUE; + } else if (platform_id == 0 || platform_id == 1) { + bSupportMac = TRUE; + } + } + if (baseEncoding == PDFFONT_ENCODING_WINANSI && !bSupportWin) { + baseEncoding = bSupportMac ? PDFFONT_ENCODING_MACROMAN : PDFFONT_ENCODING_BUILTIN; + } else if (baseEncoding == PDFFONT_ENCODING_MACROMAN && !bSupportMac) { + baseEncoding = bSupportWin ? PDFFONT_ENCODING_WINANSI : PDFFONT_ENCODING_BUILTIN; + } + } + if (((baseEncoding == PDFFONT_ENCODING_MACROMAN || baseEncoding == PDFFONT_ENCODING_WINANSI) + && m_pCharNames == NULL) || (m_Flags & PDFFONT_NONSYMBOLIC)) { + if (!FXFT_Has_Glyph_Names(m_Font.m_Face) && (!m_Font.m_Face->num_charmaps || !m_Font.m_Face->charmaps)) { + int nStartChar = m_pFontDict->GetInteger(FX_BSTRC("FirstChar")); + int charcode = 0; + for (; charcode < nStartChar; charcode ++) { + m_GlyphIndex[charcode] = 0; + } + FX_WORD nGlyph = charcode - nStartChar + 3; + for (; charcode < 256; charcode ++, nGlyph ++) { + m_GlyphIndex[charcode] = nGlyph; + } + return; + } + FX_BOOL bMSUnicode = FT_UseTTCharmap(m_Font.m_Face, 3, 1); + FX_BOOL bMacRoman = FALSE, bMSSymbol = FALSE; + if (!bMSUnicode) { + if (m_Flags & PDFFONT_NONSYMBOLIC) { + bMacRoman = FT_UseTTCharmap(m_Font.m_Face, 1, 0); + bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.m_Face, 3, 0); + } else { + bMSSymbol = FT_UseTTCharmap(m_Font.m_Face, 3, 0); + bMacRoman = !bMSSymbol && FT_UseTTCharmap(m_Font.m_Face, 1, 0); + } + } + FX_BOOL bToUnicode = m_pFontDict->KeyExist(FX_BSTRC("ToUnicode")); + for (int charcode = 0; charcode < 256; charcode ++) { + FX_LPCSTR name = GetAdobeCharName(baseEncoding, m_pCharNames, charcode); + if (name == NULL) { + m_GlyphIndex[charcode] = m_pFontFile ? FXFT_Get_Char_Index(m_Font.m_Face, charcode) : -1; + continue; + } + m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); + if (bMSSymbol) { + const FX_BYTE prefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; + for (int j = 0; j < 4; j ++) { + FX_WORD unicode = prefix[j] * 256 + charcode; + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode); + if (m_GlyphIndex[charcode]) { + break; + } + } + } else if (m_Encoding.m_Unicodes[charcode]) { + if (bMSUnicode) { + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, m_Encoding.m_Unicodes[charcode]); + } else if (bMacRoman) { + FX_DWORD maccode = FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, m_Encoding.m_Unicodes[charcode]); + if (!maccode) { + m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char *)name); + } else { + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, maccode); + } + } + } + if ((m_GlyphIndex[charcode] == 0 || m_GlyphIndex[charcode] == 0xffff) && name != NULL) { + if (name[0] == '.' && FXSYS_strcmp(name, ".notdef") == 0) { + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, 32); + } else { + m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name); + if (m_GlyphIndex[charcode] == 0) { + if (bToUnicode) { + CFX_WideString wsUnicode = UnicodeFromCharCode(charcode); + if (!wsUnicode.IsEmpty()) { + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, wsUnicode[0]); + m_Encoding.m_Unicodes[charcode] = wsUnicode[0]; + } + } + if (m_GlyphIndex[charcode] == 0) { + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode); + } + } + } + } + } + return; + } + if (FT_UseTTCharmap(m_Font.m_Face, 3, 0)) { + const FX_BYTE prefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; + FX_BOOL bGotOne = FALSE; + for (int charcode = 0; charcode < 256; charcode ++) { + for (int j = 0; j < 4; j ++) { + FX_WORD unicode = prefix[j] * 256 + charcode; + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode); + if (m_GlyphIndex[charcode]) { + bGotOne = TRUE; + break; + } + } + } + if (bGotOne) { + if (baseEncoding != PDFFONT_ENCODING_BUILTIN) { + for (int charcode = 0; charcode < 256; charcode ++) { + FX_LPCSTR name = GetAdobeCharName(baseEncoding, m_pCharNames, charcode); + if (name == NULL) { + continue; + } + m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); + } + } else if (FT_UseTTCharmap(m_Font.m_Face, 1, 0)) { + for (int charcode = 0; charcode < 256; charcode ++) { + m_Encoding.m_Unicodes[charcode] = FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode); + } + } + return; + } + } + if (FT_UseTTCharmap(m_Font.m_Face, 1, 0)) { + FX_BOOL bGotOne = FALSE; + for (int charcode = 0; charcode < 256; charcode ++) { + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode); + m_Encoding.m_Unicodes[charcode] = FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode); + if (m_GlyphIndex[charcode]) { + bGotOne = TRUE; + } + } + if (m_pFontFile || bGotOne) { + return; + } + } + if (FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE) == 0) { + FX_BOOL bGotOne = FALSE; + const FX_WORD* pUnicodes = PDF_UnicodesForPredefinedCharSet(baseEncoding); + for (int charcode = 0; charcode < 256; charcode ++) { + if (m_pFontFile == NULL) { + FX_LPCSTR name = GetAdobeCharName(0, m_pCharNames, charcode); + if (name != NULL) { + m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); + } else if (pUnicodes) { + m_Encoding.m_Unicodes[charcode] = pUnicodes[charcode]; + } + } else { + m_Encoding.m_Unicodes[charcode] = charcode; + } + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, m_Encoding.m_Unicodes[charcode]); + if (m_GlyphIndex[charcode]) { + bGotOne = TRUE; + } + } + if (bGotOne) { + return; + } + } + for (int charcode = 0; charcode < 256; charcode ++) { + m_GlyphIndex[charcode] = charcode; + } +} +CPDF_Type3Font::CPDF_Type3Font() +{ + m_pPageResources = NULL; + FXSYS_memset32(m_CharWidthL, 0, sizeof m_CharWidthL); +} +CPDF_Type3Font::~CPDF_Type3Font() +{ + FX_POSITION pos = m_CacheMap.GetStartPosition(); + while (pos) { + FX_LPVOID key, value; + m_CacheMap.GetNextAssoc(pos, key, value); + delete (CPDF_Type3Char*)value; + } + m_CacheMap.RemoveAll(); + pos = m_DeletedMap.GetStartPosition(); + while (pos) { + FX_LPVOID key, value; + m_DeletedMap.GetNextAssoc(pos, key, value); + delete (CPDF_Type3Char*)key; + } +} +FX_BOOL CPDF_Type3Font::_Load() +{ + m_pFontResources = m_pFontDict->GetDict(FX_BSTRC("Resources")); + CPDF_Array* pMatrix = m_pFontDict->GetArray(FX_BSTRC("FontMatrix")); + FX_FLOAT xscale = 1.0f, yscale = 1.0f; + if (pMatrix) { + m_FontMatrix = pMatrix->GetMatrix(); + xscale = m_FontMatrix.a; + yscale = m_FontMatrix.d; + } + CPDF_Array* pBBox = m_pFontDict->GetArray(FX_BSTRC("FontBBox")); + if (pBBox) { + m_FontBBox.left = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(0), xscale) * 1000); + m_FontBBox.bottom = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(1), yscale) * 1000); + m_FontBBox.right = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(2), xscale) * 1000); + m_FontBBox.top = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(3), yscale) * 1000); + } + int StartChar = m_pFontDict->GetInteger(FX_BSTRC("FirstChar")); + CPDF_Array* pWidthArray = m_pFontDict->GetArray(FX_BSTRC("Widths")); + if (pWidthArray && (StartChar >= 0 && StartChar < 256)) { + FX_DWORD count = pWidthArray->GetCount(); + if (count > 256) { + count = 256; + } + if (StartChar + count > 256) { + count = 256 - StartChar; + } + for (FX_DWORD i = 0; i < count; i ++) { + m_CharWidthL[StartChar + i] = FXSYS_round(FXSYS_Mul(pWidthArray->GetNumber(i), xscale) * 1000); + } + } + m_pCharProcs = m_pFontDict->GetDict(FX_BSTRC("CharProcs")); + CPDF_Object* pEncoding = m_pFontDict->GetElementValue(FX_BSTRC("Encoding")); + if (pEncoding) { + LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, FALSE, FALSE); + if (m_pCharNames) { + for (int i = 0; i < 256; i ++) { + m_Encoding.m_Unicodes[i] = PDF_UnicodeFromAdobeName(m_pCharNames[i]); + if (m_Encoding.m_Unicodes[i] == 0) { + m_Encoding.m_Unicodes[i] = i; + } + } + } + } + return TRUE; +} +void CPDF_Type3Font::CheckType3FontMetrics() +{ + CheckFontMetrics(); +} +CPDF_Type3Char* CPDF_Type3Font::LoadChar(FX_DWORD charcode, int level) +{ + if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_) { + return NULL; + } + CPDF_Type3Char* pChar = NULL; + if (m_CacheMap.Lookup((FX_LPVOID)(FX_UINTPTR)charcode, (FX_LPVOID&)pChar)) { + if (pChar->m_bPageRequired && m_pPageResources) { + delete pChar; + m_CacheMap.RemoveKey((FX_LPVOID)(FX_UINTPTR)charcode); + return LoadChar(charcode, level + 1); + } + return pChar; + } + FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); + if (name == NULL) { + return NULL; + } + CPDF_Stream* pStream = (CPDF_Stream*)m_pCharProcs->GetElementValue(name); + if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) { + return NULL; + } + pChar = FX_NEW CPDF_Type3Char; + pChar->m_pForm = FX_NEW CPDF_Form(m_pDocument, m_pFontResources ? m_pFontResources : m_pPageResources, pStream, NULL); + pChar->m_pForm->ParseContent(NULL, NULL, pChar, NULL, level + 1); + FX_FLOAT scale = m_FontMatrix.GetXUnit(); + pChar->m_Width = (FX_INT32)(pChar->m_Width * scale + 0.5f); + FX_RECT &rcBBox = pChar->m_BBox; + CFX_FloatRect char_rect((FX_FLOAT)rcBBox.left / 1000.0f, (FX_FLOAT)rcBBox.bottom / 1000.0f, + (FX_FLOAT)rcBBox.right / 1000.0f, (FX_FLOAT)rcBBox.top / 1000.0f); + if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top) { + char_rect = pChar->m_pForm->CalcBoundingBox(); + } + char_rect.Transform(&m_FontMatrix); + rcBBox.left = FXSYS_round(char_rect.left * 1000); + rcBBox.right = FXSYS_round(char_rect.right * 1000); + rcBBox.top = FXSYS_round(char_rect.top * 1000); + rcBBox.bottom = FXSYS_round(char_rect.bottom * 1000); + m_CacheMap.SetAt((FX_LPVOID)(FX_UINTPTR)charcode, pChar); + if (pChar->m_pForm->CountObjects() == 0) { + delete pChar->m_pForm; + pChar->m_pForm = NULL; + } + return pChar; +} +int CPDF_Type3Font::GetCharWidthF(FX_DWORD charcode, int level) +{ + if (charcode > 0xff) { + charcode = 0; + } + if (m_CharWidthL[charcode]) { + return m_CharWidthL[charcode]; + } + CPDF_Type3Char* pChar = LoadChar(charcode, level); + if (pChar == NULL) { + return 0; + } + return pChar->m_Width; +} +void CPDF_Type3Font::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level) +{ + CPDF_Type3Char* pChar = LoadChar(charcode, level); + if (pChar == NULL) { + rect.left = rect.right = rect.top = rect.bottom = 0; + return; + } + rect = pChar->m_BBox; +} +CPDF_Type3Char::CPDF_Type3Char() +{ + m_pForm = NULL; + m_pBitmap = NULL; + m_bPageRequired = FALSE; + m_bColored = FALSE; +} +CPDF_Type3Char::~CPDF_Type3Char() +{ + if (m_pForm) { + delete m_pForm; + } + if (m_pBitmap) { + delete m_pBitmap; + } +} |