summaryrefslogtreecommitdiff
path: root/xfa/fxfa/cxfa_pdffontmgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/fxfa/cxfa_pdffontmgr.cpp')
-rw-r--r--xfa/fxfa/cxfa_pdffontmgr.cpp208
1 files changed, 208 insertions, 0 deletions
diff --git a/xfa/fxfa/cxfa_pdffontmgr.cpp b/xfa/fxfa/cxfa_pdffontmgr.cpp
new file mode 100644
index 0000000000..cadb7cbab5
--- /dev/null
+++ b/xfa/fxfa/cxfa_pdffontmgr.cpp
@@ -0,0 +1,208 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/cxfa_pdffontmgr.h"
+
+#include <algorithm>
+
+#include "core/fpdfapi/font/cpdf_font.h"
+#include "xfa/fxfa/cxfa_ffapp.h"
+
+namespace {
+
+// The 5 names per entry are: PsName, Normal, Bold, Italic, BoldItalic.
+const char* const g_XFAPDFFontName[][5] = {
+ {"Adobe PI Std", "AdobePIStd", "AdobePIStd", "AdobePIStd", "AdobePIStd"},
+ {"Myriad Pro Light", "MyriadPro-Light", "MyriadPro-Semibold",
+ "MyriadPro-LightIt", "MyriadPro-SemiboldIt"},
+};
+
+} // namespace
+
+CXFA_PDFFontMgr::CXFA_PDFFontMgr(CXFA_FFDoc* pDoc) : m_pDoc(pDoc) {}
+
+CXFA_PDFFontMgr::~CXFA_PDFFontMgr() {}
+
+CFX_RetainPtr<CFGAS_GEFont> CXFA_PDFFontMgr::FindFont(
+ const CFX_ByteString& strPsName,
+ bool bBold,
+ bool bItalic,
+ CPDF_Font** pDstPDFFont,
+ bool bStrictMatch) {
+ CPDF_Document* pDoc = m_pDoc->GetPDFDoc();
+ if (!pDoc)
+ return nullptr;
+
+ CPDF_Dictionary* pFontSetDict =
+ pDoc->GetRoot()->GetDictFor("AcroForm")->GetDictFor("DR");
+ if (!pFontSetDict)
+ return nullptr;
+
+ pFontSetDict = pFontSetDict->GetDictFor("Font");
+ if (!pFontSetDict)
+ return nullptr;
+
+ CFX_ByteString name = strPsName;
+ name.Remove(' ');
+ CFGAS_FontMgr* pFDEFontMgr = m_pDoc->GetApp()->GetFDEFontMgr();
+ for (const auto& it : *pFontSetDict) {
+ const CFX_ByteString& key = it.first;
+ CPDF_Object* pObj = it.second.get();
+ if (!PsNameMatchDRFontName(name.AsStringC(), bBold, bItalic, key,
+ bStrictMatch)) {
+ continue;
+ }
+ CPDF_Dictionary* pFontDict = ToDictionary(pObj->GetDirect());
+ if (!pFontDict || pFontDict->GetStringFor("Type") != "Font") {
+ return nullptr;
+ }
+ CPDF_Font* pPDFFont = pDoc->LoadFont(pFontDict);
+ if (!pPDFFont) {
+ return nullptr;
+ }
+ if (!pPDFFont->IsEmbedded()) {
+ *pDstPDFFont = pPDFFont;
+ return nullptr;
+ }
+ return CFGAS_GEFont::LoadFont(&pPDFFont->m_Font, pFDEFontMgr);
+ }
+ return nullptr;
+}
+
+CFX_RetainPtr<CFGAS_GEFont> CXFA_PDFFontMgr::GetFont(
+ const CFX_WideStringC& wsFontFamily,
+ uint32_t dwFontStyles,
+ CPDF_Font** pPDFFont,
+ bool bStrictMatch) {
+ uint32_t dwHashCode = FX_HashCode_GetW(wsFontFamily, false);
+ CFX_ByteString strKey;
+ strKey.Format("%u%u", dwHashCode, dwFontStyles);
+ auto it = m_FontMap.find(strKey);
+ if (it != m_FontMap.end())
+ return it->second;
+ CFX_ByteString bsPsName =
+ CFX_ByteString::FromUnicode(CFX_WideString(wsFontFamily));
+ bool bBold = (dwFontStyles & FX_FONTSTYLE_Bold) == FX_FONTSTYLE_Bold;
+ bool bItalic = (dwFontStyles & FX_FONTSTYLE_Italic) == FX_FONTSTYLE_Italic;
+ CFX_ByteString strFontName = PsNameToFontName(bsPsName, bBold, bItalic);
+ CFX_RetainPtr<CFGAS_GEFont> pFont =
+ FindFont(strFontName, bBold, bItalic, pPDFFont, bStrictMatch);
+ if (pFont)
+ m_FontMap[strKey] = pFont;
+ return pFont;
+}
+
+CFX_ByteString CXFA_PDFFontMgr::PsNameToFontName(
+ const CFX_ByteString& strPsName,
+ bool bBold,
+ bool bItalic) {
+ for (size_t i = 0; i < FX_ArraySize(g_XFAPDFFontName); ++i) {
+ if (strPsName == g_XFAPDFFontName[i][0]) {
+ size_t index = 1;
+ if (bBold)
+ ++index;
+ if (bItalic)
+ index += 2;
+ return g_XFAPDFFontName[i][index];
+ }
+ }
+ return strPsName;
+}
+
+bool CXFA_PDFFontMgr::PsNameMatchDRFontName(const CFX_ByteStringC& bsPsName,
+ bool bBold,
+ bool bItalic,
+ const CFX_ByteString& bsDRFontName,
+ bool bStrictMatch) {
+ CFX_ByteString bsDRName = bsDRFontName;
+ bsDRName.Remove('-');
+ int32_t iPsLen = bsPsName.GetLength();
+ int32_t nIndex = bsDRName.Find(bsPsName);
+ if (nIndex != -1 && !bStrictMatch)
+ return true;
+
+ if (nIndex != 0)
+ return false;
+
+ int32_t iDifferLength = bsDRName.GetLength() - iPsLen;
+ if (iDifferLength > 1 || (bBold || bItalic)) {
+ int32_t iBoldIndex = bsDRName.Find("Bold");
+ bool bBoldFont = iBoldIndex > 0;
+ if (bBold != bBoldFont)
+ return false;
+
+ if (bBoldFont) {
+ iDifferLength =
+ std::min(iDifferLength - 4, bsDRName.GetLength() - iBoldIndex - 4);
+ }
+ bool bItalicFont = true;
+ if (bsDRName.Find("Italic") > 0) {
+ iDifferLength -= 6;
+ } else if (bsDRName.Find("It") > 0) {
+ iDifferLength -= 2;
+ } else if (bsDRName.Find("Oblique") > 0) {
+ iDifferLength -= 7;
+ } else {
+ bItalicFont = false;
+ }
+ if (bItalic != bItalicFont)
+ return false;
+
+ if (iDifferLength > 1) {
+ CFX_ByteString bsDRTailer = bsDRName.Right(iDifferLength);
+ if (bsDRTailer == "MT" || bsDRTailer == "PSMT" ||
+ bsDRTailer == "Regular" || bsDRTailer == "Reg") {
+ return true;
+ }
+ if (bBoldFont || bItalicFont)
+ return false;
+
+ bool bMatch = false;
+ switch (bsPsName.GetAt(iPsLen - 1)) {
+ case 'L': {
+ if (bsDRName.Right(5) == "Light") {
+ bMatch = true;
+ }
+ } break;
+ case 'R': {
+ if (bsDRName.Right(7) == "Regular" || bsDRName.Right(3) == "Reg") {
+ bMatch = true;
+ }
+ } break;
+ case 'M': {
+ if (bsDRName.Right(5) == "Medium") {
+ bMatch = true;
+ }
+ } break;
+ default:
+ break;
+ }
+ return bMatch;
+ }
+ }
+ return true;
+}
+
+bool CXFA_PDFFontMgr::GetCharWidth(const CFX_RetainPtr<CFGAS_GEFont>& pFont,
+ wchar_t wUnicode,
+ bool bCharCode,
+ int32_t* pWidth) {
+ if (wUnicode != 0x20 || bCharCode)
+ return false;
+
+ auto it = m_FDE2PDFFont.find(pFont);
+ if (it == m_FDE2PDFFont.end())
+ return false;
+
+ CPDF_Font* pPDFFont = it->second;
+ *pWidth = pPDFFont->GetCharWidthF(pPDFFont->CharCodeFromUnicode(wUnicode));
+ return true;
+}
+
+void CXFA_PDFFontMgr::SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont,
+ CPDF_Font* pPDFFont) {
+ m_FDE2PDFFont[pFont] = pPDFFont;
+}