| Index: core/src/fpdfapi/fpdf_font/fpdf_font.cpp
|
| diff --git a/core/src/fpdfapi/fpdf_font/fpdf_font.cpp b/core/src/fpdfapi/fpdf_font/fpdf_font.cpp
|
| index 8037a8c674e811202d43d3c91bcff16a5e1df452..0107000dd9725f91c5587694f7135d5965fd48f2 100644
|
| --- a/core/src/fpdfapi/fpdf_font/fpdf_font.cpp
|
| +++ b/core/src/fpdfapi/fpdf_font/fpdf_font.cpp
|
| @@ -12,1735 +12,1786 @@
|
| #include "../fpdf_page/pageint.h"
|
| #include "font_int.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;
|
| -}
|
| -CPDF_FontGlobals::CPDF_FontGlobals()
|
| - : m_pContrastRamps(NULL)
|
| -{
|
| - FXSYS_memset(m_EmbeddedCharsets, 0, sizeof(m_EmbeddedCharsets));
|
| - FXSYS_memset(m_EmbeddedToUnicodes, 0, sizeof(m_EmbeddedToUnicodes));
|
| -}
|
| -CPDF_FontGlobals::~CPDF_FontGlobals()
|
| -{
|
| - ClearAll();
|
| - if (m_pContrastRamps) {
|
| - FX_Free(m_pContrastRamps);
|
| - }
|
| -}
|
| -class CFX_StockFontArray
|
| -{
|
| -public:
|
| - CFX_StockFontArray()
|
| - {
|
| - FXSYS_memset(m_pStockFonts, 0, sizeof(m_pStockFonts));
|
| - }
|
| - ~CFX_StockFontArray()
|
| - {
|
| - for (int i = 0; i < FX_ArraySize(m_pStockFonts); i++) {
|
| - if (!m_pStockFonts[i])
|
| - continue;
|
| - CPDF_Dictionary* pFontDict = m_pStockFonts[i]->GetFontDict();
|
| - if (pFontDict)
|
| - pFontDict->Release();
|
| - delete m_pStockFonts[i];
|
| - }
|
| - }
|
| - CPDF_Font* GetFont(int index) const
|
| - {
|
| - if (index < 0 || index >= FX_ArraySize(m_pStockFonts))
|
| - return NULL;
|
| - return m_pStockFonts[index];
|
| - }
|
| - void SetFont(int index, CPDF_Font* font)
|
| - {
|
| - if (index < 0 || index >= FX_ArraySize(m_pStockFonts))
|
| - return;
|
| - delete m_pStockFonts[index];
|
| - m_pStockFonts[index] = font;
|
| - }
|
| -private:
|
| - CPDF_Font* m_pStockFonts[14];
|
| +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;
|
| +}
|
| +CPDF_FontGlobals::CPDF_FontGlobals() : m_pContrastRamps(NULL) {
|
| + FXSYS_memset(m_EmbeddedCharsets, 0, sizeof(m_EmbeddedCharsets));
|
| + FXSYS_memset(m_EmbeddedToUnicodes, 0, sizeof(m_EmbeddedToUnicodes));
|
| +}
|
| +CPDF_FontGlobals::~CPDF_FontGlobals() {
|
| + ClearAll();
|
| + if (m_pContrastRamps) {
|
| + FX_Free(m_pContrastRamps);
|
| + }
|
| +}
|
| +class CFX_StockFontArray {
|
| + public:
|
| + CFX_StockFontArray() {
|
| + FXSYS_memset(m_pStockFonts, 0, sizeof(m_pStockFonts));
|
| + }
|
| + ~CFX_StockFontArray() {
|
| + for (int i = 0; i < FX_ArraySize(m_pStockFonts); i++) {
|
| + if (!m_pStockFonts[i])
|
| + continue;
|
| + CPDF_Dictionary* pFontDict = m_pStockFonts[i]->GetFontDict();
|
| + if (pFontDict)
|
| + pFontDict->Release();
|
| + delete m_pStockFonts[i];
|
| + }
|
| + }
|
| + CPDF_Font* GetFont(int index) const {
|
| + if (index < 0 || index >= FX_ArraySize(m_pStockFonts))
|
| + return NULL;
|
| + return m_pStockFonts[index];
|
| + }
|
| + void SetFont(int index, CPDF_Font* font) {
|
| + if (index < 0 || index >= FX_ArraySize(m_pStockFonts))
|
| + return;
|
| + delete m_pStockFonts[index];
|
| + m_pStockFonts[index] = font;
|
| + }
|
| +
|
| + private:
|
| + 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 static_cast<CFX_StockFontArray*>(value)->GetFont(index);
|
| -}
|
| -void CPDF_FontGlobals::Set(void* key, int index, CPDF_Font* pFont)
|
| -{
|
| - void* value = NULL;
|
| - CFX_StockFontArray* font_array = NULL;
|
| - if (m_pStockMap.Lookup(key, value)) {
|
| - font_array = static_cast<CFX_StockFontArray*>(value);
|
| - } else {
|
| - font_array = new CFX_StockFontArray();
|
| - m_pStockMap.SetAt(key, font_array);
|
| - }
|
| - font_array->SetFont(index, pFont);
|
| -}
|
| -void CPDF_FontGlobals::Clear(void* key)
|
| -{
|
| +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 static_cast<CFX_StockFontArray*>(value)->GetFont(index);
|
| +}
|
| +void CPDF_FontGlobals::Set(void* key, int index, CPDF_Font* pFont) {
|
| + void* value = NULL;
|
| + CFX_StockFontArray* font_array = NULL;
|
| + if (m_pStockMap.Lookup(key, value)) {
|
| + font_array = static_cast<CFX_StockFontArray*>(value);
|
| + } else {
|
| + font_array = new CFX_StockFontArray();
|
| + m_pStockMap.SetAt(key, font_array);
|
| + }
|
| + font_array->SetFont(index, pFont);
|
| +}
|
| +void CPDF_FontGlobals::Clear(void* key) {
|
| + void* value = NULL;
|
| + if (!m_pStockMap.Lookup(key, value)) {
|
| + return;
|
| + }
|
| + delete static_cast<CFX_StockFontArray*>(value);
|
| + m_pStockMap.RemoveKey(key);
|
| +}
|
| +void CPDF_FontGlobals::ClearAll() {
|
| + FX_POSITION pos = m_pStockMap.GetStartPosition();
|
| + while (pos) {
|
| + void* key = NULL;
|
| void* value = NULL;
|
| - if (!m_pStockMap.Lookup(key, value)) {
|
| - return;
|
| - }
|
| + m_pStockMap.GetNextAssoc(pos, key, value);
|
| delete static_cast<CFX_StockFontArray*>(value);
|
| 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);
|
| - delete static_cast<CFX_StockFontArray*>(value);
|
| - m_pStockMap.RemoveKey(key);
|
| - }
|
| -}
|
| -CPDF_Font::CPDF_Font(int fonttype) : m_FontType(fonttype)
|
| -{
|
| - 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 = new CPDF_FontCharMap(this);
|
| -}
|
| -CPDF_Font::~CPDF_Font()
|
| -{
|
| - delete m_pCharMap;
|
| - m_pCharMap = NULL;
|
| + }
|
| +}
|
| +CPDF_Font::CPDF_Font(int fonttype) : m_FontType(fonttype) {
|
| + 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 = new CPDF_FontCharMap(this);
|
| +}
|
| +CPDF_Font::~CPDF_Font() {
|
| + delete m_pCharMap;
|
| + m_pCharMap = NULL;
|
|
|
| - delete m_pToUnicodeMap;
|
| - m_pToUnicodeMap = NULL;
|
| + 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];
|
| + 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);
|
| + const FX_CHAR* src_buf = str;
|
| + int src_pos = 0;
|
| + while (src_pos < src_len) {
|
| + FX_DWORD charcode = GetNextChar(src_buf, src_len, src_pos);
|
| + CFX_WideString unicode = UnicodeFromCharCode(charcode);
|
| + if (!unicode.IsEmpty()) {
|
| + result += unicode;
|
| } 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);
|
| - const FX_CHAR* src_buf = str;
|
| - int src_pos = 0;
|
| - while (src_pos < src_len) {
|
| - FX_DWORD charcode = GetNextChar(src_buf, src_len, 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_CHAR* dest_buf = result.GetBuffer(src_len * 2);
|
| - const FX_WCHAR* src_buf = str.c_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;
|
| - }
|
| - const uint8_t* 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;
|
| - }
|
| - }
|
| - }
|
| - }
|
| + 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_CHAR* dest_buf = result.GetBuffer(src_len * 2);
|
| + const FX_WCHAR* src_buf = str.c_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;
|
| }
|
| - if (m_Ascent == 0 && m_Descent == 0) {
|
| + const uint8_t* 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('A', rect);
|
| - if (rect.bottom == rect.top) {
|
| - m_Ascent = m_FontBBox.top;
|
| - } else {
|
| - m_Ascent = rect.top;
|
| + GetCharBBox(i, rect);
|
| + if (rect.left == rect.right) {
|
| + continue;
|
| }
|
| - GetCharBBox('g', rect);
|
| - if (rect.bottom == rect.top) {
|
| - m_Descent = m_FontBBox.bottom;
|
| + if (bFirst) {
|
| + m_FontBBox = rect;
|
| + bFirst = FALSE;
|
| } 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 = new CPDF_ToUnicodeMap;
|
| - m_pToUnicodeMap->Load(pStream);
|
| -}
|
| -int CPDF_Font::GetStringWidth(const FX_CHAR* pString, int size)
|
| -{
|
| - int offset = 0;
|
| - int width = 0;
|
| - while (offset < size) {
|
| - FX_DWORD charcode = GetNextChar(pString, size, 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;
|
| + 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;
|
| }
|
| - return m_Font.GetGlyphWidth(glyph_index);
|
| + 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 = new CPDF_ToUnicodeMap;
|
| + m_pToUnicodeMap->Load(pStream);
|
| +}
|
| +int CPDF_Font::GetStringWidth(const FX_CHAR* pString, int size) {
|
| + int offset = 0;
|
| + int width = 0;
|
| + while (offset < size) {
|
| + FX_DWORD charcode = GetNextChar(pString, size, 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, const CFX_ByteStringC& 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 uint8_t 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((const FX_CHAR*)ChineseFontNames[i])) {
|
| - break;
|
| - }
|
| - }
|
| - if (i < count) {
|
| - CPDF_Dictionary* pFontDesc = pFontDict->GetDict(FX_BSTRC("FontDescriptor"));
|
| - if (pFontDesc == NULL || !pFontDesc->KeyExist(FX_BSTRC("FontFile2"))) {
|
| - pFont = new CPDF_CIDFont;
|
| - pFont->m_pFontDict = pFontDict;
|
| - pFont->m_pDocument = pDoc;
|
| - if (!pFont->Load()) {
|
| - delete pFont;
|
| - return NULL;
|
| - }
|
| - return pFont;
|
| - }
|
| - }
|
| -#endif
|
| - }
|
| - pFont = new CPDF_TrueTypeFont;
|
| - } else if (type == FX_BSTRC("Type3")) {
|
| - pFont = new CPDF_Type3Font;
|
| - } else if (type == FX_BSTRC("Type0")) {
|
| - pFont = new CPDF_CIDFont;
|
| - } else {
|
| - pFont = new CPDF_Type1Font;
|
| - }
|
| - pFont->m_pFontDict = pFontDict;
|
| - pFont->m_pDocument = pDoc;
|
| - if (!pFont->Load()) {
|
| - delete pFont;
|
| - return NULL;
|
| - }
|
| +CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc,
|
| + const CFX_ByteStringC& 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;
|
| -}
|
| -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;
|
| - }
|
| - const FX_WCHAR* 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();
|
| + }
|
| + 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 uint8_t 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((const FX_CHAR*)ChineseFontNames[i])) {
|
| + break;
|
| + }
|
| + }
|
| + if (i < count) {
|
| + CPDF_Dictionary* pFontDesc =
|
| + pFontDict->GetDict(FX_BSTRC("FontDescriptor"));
|
| + if (pFontDesc == NULL || !pFontDesc->KeyExist(FX_BSTRC("FontFile2"))) {
|
| + pFont = new CPDF_CIDFont;
|
| + pFont->m_pFontDict = pFontDict;
|
| + pFont->m_pDocument = pDoc;
|
| + if (!pFont->Load()) {
|
| + delete pFont;
|
| + return NULL;
|
| + }
|
| + return pFont;
|
| }
|
| - return CFX_WideString(buf + index + 1, len);
|
| - }
|
| - if (m_pBaseMap) {
|
| - return m_pBaseMap->UnicodeFromCID((FX_WORD)charcode);
|
| + }
|
| +#endif
|
| }
|
| - return CFX_WideString();
|
| + pFont = new CPDF_TrueTypeFont;
|
| + } else if (type == FX_BSTRC("Type3")) {
|
| + pFont = new CPDF_Type3Font;
|
| + } else if (type == FX_BSTRC("Type0")) {
|
| + pFont = new CPDF_CIDFont;
|
| + } else {
|
| + pFont = new CPDF_Type1Font;
|
| + }
|
| + pFont->m_pFontDict = pFontDict;
|
| + pFont->m_pDocument = pDoc;
|
| + if (!pFont->Load()) {
|
| + delete pFont;
|
| + return NULL;
|
| + }
|
| + return pFont;
|
| }
|
| -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;
|
| - }
|
| - }
|
| +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;
|
| + }
|
| + const FX_WCHAR* 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(const CFX_ByteStringC& str) {
|
| + const FX_CHAR* buf = str.GetCStr();
|
| + int len = str.GetLength();
|
| + if (len == 0) {
|
| return 0;
|
| -}
|
| -static FX_DWORD _StringToCode(const CFX_ByteStringC& str)
|
| -{
|
| - const FX_CHAR* 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;
|
| + }
|
| + 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;
|
| }
|
| - for (int i = 0; i < len; i ++) {
|
| - if (buf[i] < '0' || buf[i] > '9') {
|
| - break;
|
| - }
|
| - result = result * 10 + buf[i] - '0';
|
| + return result;
|
| + }
|
| + 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(const CFX_ByteStringC& str) {
|
| + const FX_CHAR* 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;
|
| -}
|
| -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);
|
| + }
|
| + 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 {
|
| - ret.Insert(0, ch);
|
| - value = 0;
|
| - }
|
| - }
|
| - if (value) {
|
| - ret.Insert(0, value);
|
| - }
|
| - return ret;
|
| -}
|
| -static CFX_WideString _StringToWideString(const CFX_ByteStringC& str)
|
| -{
|
| - const FX_CHAR* 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;
|
| + 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;
|
| }
|
| - ch = ch * 16 + digit;
|
| - byte_pos ++;
|
| - if (byte_pos == 4) {
|
| - result += ch;
|
| - byte_pos = 0;
|
| - ch = 0;
|
| + 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;
|
| }
|
| - }
|
| - 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;
|
| - }
|
| + }
|
| + 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 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 {
|
| + 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 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;
|
| + }
|
| + pCharNames = new 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 {
|
| - 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;
|
| + cur_code = pElement->GetInteger();
|
| }
|
| - 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;
|
| - }
|
| - pCharNames = new 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;
|
| -}
|
| -CPDF_SimpleFont::CPDF_SimpleFont(int fonttype) : CPDF_Font(fonttype)
|
| -{
|
| - FXSYS_memset(m_CharBBox, 0xff, sizeof m_CharBBox);
|
| - FXSYS_memset(m_CharWidth, 0xff, sizeof m_CharWidth);
|
| - FXSYS_memset(m_GlyphIndex, 0xff, sizeof m_GlyphIndex);
|
| - FXSYS_memset(m_ExtGID, 0xff, sizeof m_ExtGID);
|
| - m_pCharNames = NULL;
|
| - m_BaseEncoding = PDFFONT_ENCODING_BUILTIN;
|
| -}
|
| -CPDF_SimpleFont::~CPDF_SimpleFont()
|
| -{
|
| - delete[] m_pCharNames;
|
| -}
|
| -int CPDF_SimpleFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL *pVertGlyph)
|
| -{
|
| - if (pVertGlyph) {
|
| - *pVertGlyph = FALSE;
|
| - }
|
| - if (charcode > 0xff) {
|
| - return -1;
|
| - }
|
| - int index = m_GlyphIndex[(uint8_t)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;
|
| - }
|
| +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;
|
| +}
|
| +CPDF_SimpleFont::CPDF_SimpleFont(int fonttype) : CPDF_Font(fonttype) {
|
| + FXSYS_memset(m_CharBBox, 0xff, sizeof m_CharBBox);
|
| + FXSYS_memset(m_CharWidth, 0xff, sizeof m_CharWidth);
|
| + FXSYS_memset(m_GlyphIndex, 0xff, sizeof m_GlyphIndex);
|
| + FXSYS_memset(m_ExtGID, 0xff, sizeof m_ExtGID);
|
| + m_pCharNames = NULL;
|
| + m_BaseEncoding = PDFFONT_ENCODING_BUILTIN;
|
| +}
|
| +CPDF_SimpleFont::~CPDF_SimpleFont() {
|
| + delete[] m_pCharNames;
|
| +}
|
| +int CPDF_SimpleFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
|
| + if (pVertGlyph) {
|
| + *pVertGlyph = FALSE;
|
| + }
|
| + if (charcode > 0xff) {
|
| + return -1;
|
| + }
|
| + int index = m_GlyphIndex[(uint8_t)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) {
|
| - LoadCharMetrics(charcode);
|
| - if (m_CharWidth[charcode] == 0xffff) {
|
| - m_CharWidth[charcode] = 0;
|
| - }
|
| - }
|
| - return (int16_t)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 == (int16_t)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;
|
| -}
|
| -const FX_CHAR* GetAdobeCharName(int iBaseEncoding, const CFX_ByteString* pCharNames, int charcode)
|
| -{
|
| - ASSERT(charcode >= 0 && charcode < 256);
|
| - if (charcode < 0 || charcode >= 256) {
|
| - return NULL;
|
| - }
|
| - const FX_CHAR* 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();
|
| - delete[] m_pCharNames;
|
| - 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 (size_t 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();
|
| + 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 (int16_t)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 == (int16_t)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;
|
| +}
|
| +const FX_CHAR* GetAdobeCharName(int iBaseEncoding,
|
| + const CFX_ByteString* pCharNames,
|
| + int charcode) {
|
| + ASSERT(charcode >= 0 && charcode < 256);
|
| + if (charcode < 0 || charcode >= 256) {
|
| + return NULL;
|
| + }
|
| + const FX_CHAR* 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();
|
| + delete[] m_pCharNames;
|
| + m_pCharNames = NULL;
|
| + if (m_Font.m_Face == NULL) {
|
| 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, IsFontType(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() : CPDF_SimpleFont(PDFFONT_TYPE1)
|
| -{
|
| - 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]);
|
| + }
|
| + if (m_Flags & PDFFONT_ALLCAP) {
|
| + unsigned char lowercases[] = {'a', 'z', 0xe0, 0xf6, 0xf8, 0xfd};
|
| + for (size_t 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, IsFontType(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() : CPDF_SimpleFont(PDFFONT_TYPE1) {
|
| + 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 {
|
| - FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);
|
| - }
|
| - return TRUE;
|
| + 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_
|
| +#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[(uint8_t)charcode];
|
| - if (index == 0xffff) {
|
| - return -1;
|
| - }
|
| - return index;
|
| +int CPDF_Type1Font::GlyphFromCharCodeExt(FX_DWORD charcode) {
|
| + if (charcode > 0xff) {
|
| + return -1;
|
| + }
|
| + int index = m_ExtGID[(uint8_t)charcode];
|
| + if (index == 0xffff) {
|
| + return -1;
|
| + }
|
| + return index;
|
| }
|
| -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
|
| +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
|
| struct _GlyphNameMap {
|
| - const FX_CHAR* m_pStrAdobe;
|
| - const FX_CHAR* m_pStrUnicode;
|
| -};
|
| -static const _GlyphNameMap g_GlyphNameSubsts[] = {
|
| - {"ff", "uniFB00"},
|
| - {"fi", "uniFB01"},
|
| - {"fl", "uniFB02"},
|
| - {"ffi", "uniFB03"},
|
| - {"ffl", "uniFB04"}
|
| + const FX_CHAR* m_pStrAdobe;
|
| + const FX_CHAR* 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((const FX_CHAR*)key, ((_GlyphNameMap*)element)->m_pStrAdobe);
|
| - }
|
| +static int compareString(const void* key, const void* element) {
|
| + return FXSYS_stricmp((const FX_CHAR*)key,
|
| + ((_GlyphNameMap*)element)->m_pStrAdobe);
|
| }
|
| -static const FX_CHAR* _GlyphNameRemap(const FX_CHAR* 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;
|
| +}
|
| +static const FX_CHAR* _GlyphNameRemap(const FX_CHAR* 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 uint8_t 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);
|
| - }
|
| +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 (m_GlyphIndex[charcode]) {
|
| - bGotOne = TRUE;
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - if (bGotOne) {
|
| -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
|
| - if (!bCoreText) {
|
| - FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
|
| - }
|
| + 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 uint8_t 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
|
| - return;
|
| - }
|
| + if (m_GlyphIndex[charcode]) {
|
| + bGotOne = TRUE;
|
| + break;
|
| + }
|
| }
|
| - FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE);
|
| - if (m_BaseEncoding == 0) {
|
| - m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
|
| + }
|
| + if (bGotOne) {
|
| +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
|
| + if (!bCoreText) {
|
| + FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
|
| }
|
| - for (int charcode = 0; charcode < 256; charcode ++) {
|
| - const FX_CHAR* 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);
|
| - }
|
| + 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++) {
|
| + const FX_CHAR* 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 _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
|
| - if (!bCoreText) {
|
| - FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
|
| + 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
|
| - 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 ++) {
|
| - const FX_CHAR* 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_memset(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 ++) {
|
| - const FX_CHAR* name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
|
| - if (name == NULL) {
|
| - continue;
|
| - }
|
| - m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
|
| - const FX_CHAR* 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;
|
| +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
|
| + if (!bCoreText) {
|
| + FXSYS_memcpy(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 ++) {
|
| - const FX_CHAR* 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_memset(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_memcpy(m_ExtGID, m_GlyphIndex, 256);
|
| - }
|
| -#endif
|
| - return;
|
| + for (int charcode = 0; charcode < 256; charcode++) {
|
| + const FX_CHAR* 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_memset(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 ++) {
|
| - const FX_CHAR* name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
|
| - if (name == NULL) {
|
| - continue;
|
| - }
|
| + bUnicode = TRUE;
|
| + }
|
| + for (int charcode = 0; charcode < 256; charcode++) {
|
| + const FX_CHAR* name =
|
| + GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
|
| + if (name == NULL) {
|
| + continue;
|
| + }
|
| + m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
|
| + const FX_CHAR* 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++) {
|
| + const FX_CHAR* 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);
|
| - 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;
|
| + 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_memset(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 _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
|
| if (!bCoreText) {
|
| - FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
|
| + FXSYS_memcpy(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++) {
|
| + const FX_CHAR* 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_memcpy(m_ExtGID, m_GlyphIndex, 256);
|
| + }
|
| +#endif
|
| }
|
| -CPDF_FontEncoding::CPDF_FontEncoding()
|
| -{
|
| - FXSYS_memset(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_memset(m_Unicodes, 0, sizeof(m_Unicodes));
|
| - } else
|
| - for (int i = 0; i < 256; i++) {
|
| - m_Unicodes[i] = pSrc[i];
|
| - }
|
| +CPDF_FontEncoding::CPDF_FontEncoding() {
|
| + FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes));
|
| }
|
| -FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const
|
| -{
|
| - return FXSYS_memcmp(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])));
|
| +int CPDF_FontEncoding::CharCodeFromUnicode(FX_WCHAR unicode) const {
|
| + for (int i = 0; i < 256; i++)
|
| + if (m_Unicodes[i] == unicode) {
|
| + return i;
|
| }
|
| - pDict->SetAt(FX_BSTRC("Differences"), pDiff);
|
| - return pDict;
|
| + return -1;
|
| }
|
| -CPDF_TrueTypeFont::CPDF_TrueTypeFont() : CPDF_SimpleFont(PDFFONT_TRUETYPE)
|
| -{
|
| -}
|
| -FX_BOOL CPDF_TrueTypeFont::_Load()
|
| -{
|
| - return LoadCommon();
|
| -}
|
| -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;
|
| - }
|
| +CPDF_FontEncoding::CPDF_FontEncoding(int PredefinedEncoding) {
|
| + const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(PredefinedEncoding);
|
| + if (!pSrc) {
|
| + FXSYS_memset(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_memcmp(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");
|
| }
|
| - 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"));
|
| - if(nStartChar < 0 || nStartChar > 255)
|
| - return;
|
| -
|
| - 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 ++) {
|
| - const FX_CHAR* 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 uint8_t 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 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() : CPDF_SimpleFont(PDFFONT_TRUETYPE) {}
|
| +FX_BOOL CPDF_TrueTypeFont::_Load() {
|
| + return LoadCommon();
|
| +}
|
| +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"));
|
| + if (nStartChar < 0 || nStartChar > 255)
|
| return;
|
| - }
|
| - if (FT_UseTTCharmap(m_Font.m_Face, 3, 0)) {
|
| +
|
| + 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++) {
|
| + const FX_CHAR* 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 uint8_t 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 ++) {
|
| - const FX_CHAR* 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) {
|
| - const FX_CHAR* 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;
|
| + 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 (bGotOne) {
|
| - return;
|
| - }
|
| - }
|
| - for (int charcode = 0; charcode < 256; charcode ++) {
|
| - m_GlyphIndex[charcode] = charcode;
|
| - }
|
| -}
|
| -CPDF_Type3Font::CPDF_Type3Font() : CPDF_SimpleFont(PDFFONT_TYPE3)
|
| -{
|
| - m_pPageResources = NULL;
|
| - FXSYS_memset(m_CharWidthL, 0, sizeof m_CharWidthL);
|
| -}
|
| -CPDF_Type3Font::~CPDF_Type3Font()
|
| -{
|
| - FX_POSITION pos = m_CacheMap.GetStartPosition();
|
| - while (pos) {
|
| - void* key;
|
| - void* value;
|
| - m_CacheMap.GetNextAssoc(pos, key, value);
|
| - delete (CPDF_Type3Char*)value;
|
| - }
|
| - m_CacheMap.RemoveAll();
|
| - pos = m_DeletedMap.GetStartPosition();
|
| - while (pos) {
|
| - void* key;
|
| - void* 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 = (int32_t)(FXSYS_Mul(pBBox->GetNumber(0), xscale) * 1000);
|
| - m_FontBBox.bottom = (int32_t)(FXSYS_Mul(pBBox->GetNumber(1), yscale) * 1000);
|
| - m_FontBBox.right = (int32_t)(FXSYS_Mul(pBBox->GetNumber(2), xscale) * 1000);
|
| - m_FontBBox.top = (int32_t)(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;
|
| - }
|
| + if (m_GlyphIndex[charcode] == 0) {
|
| + m_GlyphIndex[charcode] =
|
| + FXFT_Get_Char_Index(m_Font.m_Face, charcode);
|
| }
|
| - }
|
| - }
|
| - 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((void*)(uintptr_t)charcode, (void*&)pChar)) {
|
| - if (pChar->m_bPageRequired && m_pPageResources) {
|
| - delete pChar;
|
| - m_CacheMap.RemoveKey((void*)(uintptr_t)charcode);
|
| - return LoadChar(charcode, level + 1);
|
| - }
|
| - return pChar;
|
| - }
|
| - const FX_CHAR* name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
|
| - if (name == NULL) {
|
| - return NULL;
|
| - }
|
| - CPDF_Stream* pStream = (CPDF_Stream*)(m_pCharProcs ? m_pCharProcs->GetElementValue(name) : NULL);
|
| - if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) {
|
| - return NULL;
|
| - }
|
| - pChar = new CPDF_Type3Char;
|
| - pChar->m_pForm = 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 = (int32_t)(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((void*)(uintptr_t)charcode, pChar);
|
| - if (pChar->m_pForm->CountObjects() == 0) {
|
| - delete pChar->m_pForm;
|
| - pChar->m_pForm = NULL;
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return;
|
| + }
|
| + if (FT_UseTTCharmap(m_Font.m_Face, 3, 0)) {
|
| + const uint8_t 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++) {
|
| + const FX_CHAR* 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) {
|
| + const FX_CHAR* 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() : CPDF_SimpleFont(PDFFONT_TYPE3) {
|
| + m_pPageResources = NULL;
|
| + FXSYS_memset(m_CharWidthL, 0, sizeof m_CharWidthL);
|
| +}
|
| +CPDF_Type3Font::~CPDF_Type3Font() {
|
| + FX_POSITION pos = m_CacheMap.GetStartPosition();
|
| + while (pos) {
|
| + void* key;
|
| + void* value;
|
| + m_CacheMap.GetNextAssoc(pos, key, value);
|
| + delete (CPDF_Type3Char*)value;
|
| + }
|
| + m_CacheMap.RemoveAll();
|
| + pos = m_DeletedMap.GetStartPosition();
|
| + while (pos) {
|
| + void* key;
|
| + void* 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 = (int32_t)(FXSYS_Mul(pBBox->GetNumber(0), xscale) * 1000);
|
| + m_FontBBox.bottom =
|
| + (int32_t)(FXSYS_Mul(pBBox->GetNumber(1), yscale) * 1000);
|
| + m_FontBBox.right = (int32_t)(FXSYS_Mul(pBBox->GetNumber(2), xscale) * 1000);
|
| + m_FontBBox.top = (int32_t)(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((void*)(uintptr_t)charcode, (void*&)pChar)) {
|
| + if (pChar->m_bPageRequired && m_pPageResources) {
|
| + delete pChar;
|
| + m_CacheMap.RemoveKey((void*)(uintptr_t)charcode);
|
| + return LoadChar(charcode, level + 1);
|
| }
|
| 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()
|
| -{
|
| - delete m_pForm;
|
| - delete m_pBitmap;
|
| + }
|
| + const FX_CHAR* name =
|
| + GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
|
| + if (name == NULL) {
|
| + return NULL;
|
| + }
|
| + CPDF_Stream* pStream =
|
| + (CPDF_Stream*)(m_pCharProcs ? m_pCharProcs->GetElementValue(name) : NULL);
|
| + if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) {
|
| + return NULL;
|
| + }
|
| + pChar = new CPDF_Type3Char;
|
| + pChar->m_pForm = 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 = (int32_t)(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((void*)(uintptr_t)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() {
|
| + delete m_pForm;
|
| + delete m_pBitmap;
|
| }
|
|
|