summaryrefslogtreecommitdiff
path: root/core/fpdfdoc/doc_utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/fpdfdoc/doc_utils.cpp')
-rw-r--r--core/fpdfdoc/doc_utils.cpp753
1 files changed, 753 insertions, 0 deletions
diff --git a/core/fpdfdoc/doc_utils.cpp b/core/fpdfdoc/doc_utils.cpp
new file mode 100644
index 0000000000..5160c1115c
--- /dev/null
+++ b/core/fpdfdoc/doc_utils.cpp
@@ -0,0 +1,753 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include <algorithm>
+#include <vector>
+
+#include "core/fpdfdoc/doc_utils.h"
+#include "core/include/fpdfapi/cpdf_array.h"
+#include "core/include/fpdfapi/cpdf_document.h"
+#include "core/include/fpdfapi/cpdf_simple_parser.h"
+#include "core/include/fpdfdoc/fpdf_doc.h"
+
+namespace {
+
+const int FPDFDOC_UTILS_MAXRECURSION = 32;
+
+CPDF_Object* SearchNumberNode(const CPDF_Dictionary* pNode, int num) {
+ CPDF_Array* pLimits = pNode->GetArrayBy("Limits");
+ if (pLimits &&
+ (num < pLimits->GetIntegerAt(0) || num > pLimits->GetIntegerAt(1))) {
+ return NULL;
+ }
+ CPDF_Array* pNumbers = pNode->GetArrayBy("Nums");
+ if (pNumbers) {
+ FX_DWORD dwCount = pNumbers->GetCount() / 2;
+ for (FX_DWORD i = 0; i < dwCount; i++) {
+ int index = pNumbers->GetIntegerAt(i * 2);
+ if (num == index) {
+ return pNumbers->GetElementValue(i * 2 + 1);
+ }
+ if (index > num) {
+ break;
+ }
+ }
+ return NULL;
+ }
+ CPDF_Array* pKids = pNode->GetArrayBy("Kids");
+ if (!pKids) {
+ return NULL;
+ }
+ for (FX_DWORD i = 0; i < pKids->GetCount(); i++) {
+ CPDF_Dictionary* pKid = pKids->GetDictAt(i);
+ if (!pKid) {
+ continue;
+ }
+ CPDF_Object* pFound = SearchNumberNode(pKid, num);
+ if (pFound) {
+ return pFound;
+ }
+ }
+ return NULL;
+}
+
+} // namespace
+
+CPDF_Object* CPDF_NumberTree::LookupValue(int num) const {
+ return SearchNumberNode(m_pRoot, num);
+}
+
+CFX_WideString GetFullName(CPDF_Dictionary* pFieldDict) {
+ CFX_WideString full_name;
+ CPDF_Dictionary* pLevel = pFieldDict;
+ while (pLevel) {
+ CFX_WideString short_name = pLevel->GetUnicodeTextBy("T");
+ if (short_name != L"") {
+ if (full_name == L"") {
+ full_name = short_name;
+ } else {
+ full_name = short_name + L"." + full_name;
+ }
+ }
+ pLevel = pLevel->GetDictBy("Parent");
+ }
+ return full_name;
+}
+FX_BOOL CPDF_DefaultAppearance::HasFont() {
+ if (m_csDA.IsEmpty()) {
+ return FALSE;
+ }
+ CPDF_SimpleParser syntax(m_csDA);
+ return syntax.FindTagParamFromStart("Tf", 2);
+}
+CFX_ByteString CPDF_DefaultAppearance::GetFontString() {
+ CFX_ByteString csFont;
+ if (m_csDA.IsEmpty()) {
+ return csFont;
+ }
+ CPDF_SimpleParser syntax(m_csDA);
+ if (syntax.FindTagParamFromStart("Tf", 2)) {
+ csFont += (CFX_ByteString)syntax.GetWord();
+ csFont += " ";
+ csFont += (CFX_ByteString)syntax.GetWord();
+ csFont += " ";
+ csFont += (CFX_ByteString)syntax.GetWord();
+ }
+ return csFont;
+}
+void CPDF_DefaultAppearance::GetFont(CFX_ByteString& csFontNameTag,
+ FX_FLOAT& fFontSize) {
+ csFontNameTag = "";
+ fFontSize = 0;
+ if (m_csDA.IsEmpty()) {
+ return;
+ }
+ CPDF_SimpleParser syntax(m_csDA);
+ if (syntax.FindTagParamFromStart("Tf", 2)) {
+ csFontNameTag = (CFX_ByteString)syntax.GetWord();
+ csFontNameTag.Delete(0, 1);
+ fFontSize = FX_atof((CFX_ByteString)syntax.GetWord());
+ }
+ csFontNameTag = PDF_NameDecode(csFontNameTag);
+}
+FX_BOOL CPDF_DefaultAppearance::HasColor(FX_BOOL bStrokingOperation) {
+ if (m_csDA.IsEmpty()) {
+ return FALSE;
+ }
+ CPDF_SimpleParser syntax(m_csDA);
+ if (syntax.FindTagParamFromStart(bStrokingOperation ? "G" : "g", 1)) {
+ return TRUE;
+ }
+ if (syntax.FindTagParamFromStart(bStrokingOperation ? "RG" : "rg", 3)) {
+ return TRUE;
+ }
+ return syntax.FindTagParamFromStart(bStrokingOperation ? "K" : "k", 4);
+}
+CFX_ByteString CPDF_DefaultAppearance::GetColorString(
+ FX_BOOL bStrokingOperation) {
+ CFX_ByteString csColor;
+ if (m_csDA.IsEmpty()) {
+ return csColor;
+ }
+ CPDF_SimpleParser syntax(m_csDA);
+ if (syntax.FindTagParamFromStart(bStrokingOperation ? "G" : "g", 1)) {
+ csColor += (CFX_ByteString)syntax.GetWord();
+ csColor += " ";
+ csColor += (CFX_ByteString)syntax.GetWord();
+ return csColor;
+ }
+ if (syntax.FindTagParamFromStart(bStrokingOperation ? "RG" : "rg", 3)) {
+ csColor += (CFX_ByteString)syntax.GetWord();
+ csColor += " ";
+ csColor += (CFX_ByteString)syntax.GetWord();
+ csColor += " ";
+ csColor += (CFX_ByteString)syntax.GetWord();
+ csColor += " ";
+ csColor += (CFX_ByteString)syntax.GetWord();
+ return csColor;
+ }
+ if (syntax.FindTagParamFromStart(bStrokingOperation ? "K" : "k", 4)) {
+ csColor += (CFX_ByteString)syntax.GetWord();
+ csColor += " ";
+ csColor += (CFX_ByteString)syntax.GetWord();
+ csColor += " ";
+ csColor += (CFX_ByteString)syntax.GetWord();
+ csColor += " ";
+ csColor += (CFX_ByteString)syntax.GetWord();
+ csColor += " ";
+ csColor += (CFX_ByteString)syntax.GetWord();
+ }
+ return csColor;
+}
+void CPDF_DefaultAppearance::GetColor(int& iColorType,
+ FX_FLOAT fc[4],
+ FX_BOOL bStrokingOperation) {
+ iColorType = COLORTYPE_TRANSPARENT;
+ for (int c = 0; c < 4; c++) {
+ fc[c] = 0;
+ }
+ if (m_csDA.IsEmpty()) {
+ return;
+ }
+ CPDF_SimpleParser syntax(m_csDA);
+ if (syntax.FindTagParamFromStart(bStrokingOperation ? "G" : "g", 1)) {
+ iColorType = COLORTYPE_GRAY;
+ fc[0] = FX_atof((CFX_ByteString)syntax.GetWord());
+ return;
+ }
+ if (syntax.FindTagParamFromStart(bStrokingOperation ? "RG" : "rg", 3)) {
+ iColorType = COLORTYPE_RGB;
+ fc[0] = FX_atof((CFX_ByteString)syntax.GetWord());
+ fc[1] = FX_atof((CFX_ByteString)syntax.GetWord());
+ fc[2] = FX_atof((CFX_ByteString)syntax.GetWord());
+ return;
+ }
+ if (syntax.FindTagParamFromStart(bStrokingOperation ? "K" : "k", 4)) {
+ iColorType = COLORTYPE_CMYK;
+ fc[0] = FX_atof((CFX_ByteString)syntax.GetWord());
+ fc[1] = FX_atof((CFX_ByteString)syntax.GetWord());
+ fc[2] = FX_atof((CFX_ByteString)syntax.GetWord());
+ fc[3] = FX_atof((CFX_ByteString)syntax.GetWord());
+ }
+}
+void CPDF_DefaultAppearance::GetColor(FX_ARGB& color,
+ int& iColorType,
+ FX_BOOL bStrokingOperation) {
+ color = 0;
+ iColorType = COLORTYPE_TRANSPARENT;
+ if (m_csDA.IsEmpty()) {
+ return;
+ }
+ CPDF_SimpleParser syntax(m_csDA);
+ if (syntax.FindTagParamFromStart(bStrokingOperation ? "G" : "g", 1)) {
+ iColorType = COLORTYPE_GRAY;
+ FX_FLOAT g = FX_atof((CFX_ByteString)syntax.GetWord()) * 255 + 0.5f;
+ color = ArgbEncode(255, (int)g, (int)g, (int)g);
+ return;
+ }
+ if (syntax.FindTagParamFromStart(bStrokingOperation ? "RG" : "rg", 3)) {
+ iColorType = COLORTYPE_RGB;
+ FX_FLOAT r = FX_atof((CFX_ByteString)syntax.GetWord()) * 255 + 0.5f;
+ FX_FLOAT g = FX_atof((CFX_ByteString)syntax.GetWord()) * 255 + 0.5f;
+ FX_FLOAT b = FX_atof((CFX_ByteString)syntax.GetWord()) * 255 + 0.5f;
+ color = ArgbEncode(255, (int)r, (int)g, (int)b);
+ return;
+ }
+ if (syntax.FindTagParamFromStart(bStrokingOperation ? "K" : "k", 4)) {
+ iColorType = COLORTYPE_CMYK;
+ FX_FLOAT c = FX_atof((CFX_ByteString)syntax.GetWord());
+ FX_FLOAT m = FX_atof((CFX_ByteString)syntax.GetWord());
+ FX_FLOAT y = FX_atof((CFX_ByteString)syntax.GetWord());
+ FX_FLOAT k = FX_atof((CFX_ByteString)syntax.GetWord());
+ FX_FLOAT r = 1.0f - std::min(1.0f, c + k);
+ FX_FLOAT g = 1.0f - std::min(1.0f, m + k);
+ FX_FLOAT b = 1.0f - std::min(1.0f, y + k);
+ color = ArgbEncode(255, (int)(r * 255 + 0.5f), (int)(g * 255 + 0.5f),
+ (int)(b * 255 + 0.5f));
+ }
+}
+FX_BOOL CPDF_DefaultAppearance::HasTextMatrix() {
+ if (m_csDA.IsEmpty()) {
+ return FALSE;
+ }
+ CPDF_SimpleParser syntax(m_csDA);
+ return syntax.FindTagParamFromStart("Tm", 6);
+}
+CFX_ByteString CPDF_DefaultAppearance::GetTextMatrixString() {
+ CFX_ByteString csTM;
+ if (m_csDA.IsEmpty()) {
+ return csTM;
+ }
+ CPDF_SimpleParser syntax(m_csDA);
+ if (syntax.FindTagParamFromStart("Tm", 6)) {
+ for (int i = 0; i < 6; i++) {
+ csTM += (CFX_ByteString)syntax.GetWord();
+ csTM += " ";
+ }
+ csTM += (CFX_ByteString)syntax.GetWord();
+ }
+ return csTM;
+}
+CFX_Matrix CPDF_DefaultAppearance::GetTextMatrix() {
+ CFX_Matrix tm;
+ if (m_csDA.IsEmpty()) {
+ return tm;
+ }
+ CPDF_SimpleParser syntax(m_csDA);
+ if (syntax.FindTagParamFromStart("Tm", 6)) {
+ FX_FLOAT f[6];
+ for (int i = 0; i < 6; i++) {
+ f[i] = FX_atof((CFX_ByteString)syntax.GetWord());
+ }
+ tm.Set(f[0], f[1], f[2], f[3], f[4], f[5]);
+ }
+ return tm;
+}
+void InitInterFormDict(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument) {
+ if (!pDocument) {
+ return;
+ }
+ if (!pFormDict) {
+ pFormDict = new CPDF_Dictionary;
+ FX_DWORD dwObjNum = pDocument->AddIndirectObject(pFormDict);
+ CPDF_Dictionary* pRoot = pDocument->GetRoot();
+ pRoot->SetAtReference("AcroForm", pDocument, dwObjNum);
+ }
+ CFX_ByteString csDA;
+ if (!pFormDict->KeyExist("DR")) {
+ CPDF_Font* pFont = NULL;
+ CFX_ByteString csBaseName, csDefault;
+ uint8_t charSet = CPDF_InterForm::GetNativeCharSet();
+ pFont = CPDF_InterForm::AddStandardFont(pDocument, "Helvetica");
+ if (pFont) {
+ AddInterFormFont(pFormDict, pDocument, pFont, csBaseName);
+ csDefault = csBaseName;
+ }
+ if (charSet != 0) {
+ CFX_ByteString csFontName = CPDF_InterForm::GetNativeFont(charSet, NULL);
+ if (!pFont || csFontName != "Helvetica") {
+ pFont = CPDF_InterForm::AddNativeFont(pDocument);
+ if (pFont) {
+ csBaseName = "";
+ AddInterFormFont(pFormDict, pDocument, pFont, csBaseName);
+ csDefault = csBaseName;
+ }
+ }
+ }
+ if (pFont) {
+ csDA = "/" + PDF_NameEncode(csDefault) + " 0 Tf";
+ }
+ }
+ if (!csDA.IsEmpty()) {
+ csDA += " ";
+ }
+ csDA += "0 g";
+ if (!pFormDict->KeyExist("DA")) {
+ pFormDict->SetAtString("DA", csDA);
+ }
+}
+FX_DWORD CountInterFormFonts(CPDF_Dictionary* pFormDict) {
+ if (!pFormDict) {
+ return 0;
+ }
+ CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR");
+ if (!pDR) {
+ return 0;
+ }
+ CPDF_Dictionary* pFonts = pDR->GetDictBy("Font");
+ if (!pFonts) {
+ return 0;
+ }
+ FX_DWORD dwCount = 0;
+ for (const auto& it : *pFonts) {
+ CPDF_Object* pObj = it.second;
+ if (!pObj) {
+ continue;
+ }
+ if (CPDF_Dictionary* pDirect = ToDictionary(pObj->GetDirect())) {
+ if (pDirect->GetStringBy("Type") == "Font") {
+ dwCount++;
+ }
+ }
+ }
+ return dwCount;
+}
+CPDF_Font* GetInterFormFont(CPDF_Dictionary* pFormDict,
+ CPDF_Document* pDocument,
+ FX_DWORD index,
+ CFX_ByteString& csNameTag) {
+ if (!pFormDict) {
+ return NULL;
+ }
+ CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR");
+ if (!pDR) {
+ return NULL;
+ }
+ CPDF_Dictionary* pFonts = pDR->GetDictBy("Font");
+ if (!pFonts) {
+ return NULL;
+ }
+ FX_DWORD dwCount = 0;
+ for (const auto& it : *pFonts) {
+ const CFX_ByteString& csKey = it.first;
+ CPDF_Object* pObj = it.second;
+ if (!pObj) {
+ continue;
+ }
+ CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect());
+ if (!pElement)
+ continue;
+ if (pElement->GetStringBy("Type") != "Font")
+ continue;
+ if (dwCount == index) {
+ csNameTag = csKey;
+ return pDocument->LoadFont(pElement);
+ }
+ dwCount++;
+ }
+ return NULL;
+}
+CPDF_Font* GetInterFormFont(CPDF_Dictionary* pFormDict,
+ CPDF_Document* pDocument,
+ CFX_ByteString csNameTag) {
+ CFX_ByteString csAlias = PDF_NameDecode(csNameTag);
+ if (!pFormDict || csAlias.IsEmpty()) {
+ return NULL;
+ }
+ CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR");
+ if (!pDR) {
+ return NULL;
+ }
+ CPDF_Dictionary* pFonts = pDR->GetDictBy("Font");
+ if (!pFonts) {
+ return NULL;
+ }
+ CPDF_Dictionary* pElement = pFonts->GetDictBy(csAlias);
+ if (!pElement) {
+ return NULL;
+ }
+ if (pElement->GetStringBy("Type") == "Font") {
+ return pDocument->LoadFont(pElement);
+ }
+ return NULL;
+}
+CPDF_Font* GetInterFormFont(CPDF_Dictionary* pFormDict,
+ CPDF_Document* pDocument,
+ CFX_ByteString csFontName,
+ CFX_ByteString& csNameTag) {
+ if (!pFormDict || csFontName.IsEmpty()) {
+ return NULL;
+ }
+ CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR");
+ if (!pDR) {
+ return NULL;
+ }
+ CPDF_Dictionary* pFonts = pDR->GetDictBy("Font");
+ if (!pFonts) {
+ return NULL;
+ }
+ for (const auto& it : *pFonts) {
+ const CFX_ByteString& csKey = it.first;
+ CPDF_Object* pObj = it.second;
+ if (!pObj) {
+ continue;
+ }
+ CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect());
+ if (!pElement)
+ continue;
+ if (pElement->GetStringBy("Type") != "Font")
+ continue;
+
+ CPDF_Font* pFind = pDocument->LoadFont(pElement);
+ if (!pFind)
+ continue;
+
+ CFX_ByteString csBaseFont;
+ csBaseFont = pFind->GetBaseFont();
+ csBaseFont.Remove(' ');
+ if (csBaseFont == csFontName) {
+ csNameTag = csKey;
+ return pFind;
+ }
+ }
+ return NULL;
+}
+CPDF_Font* GetNativeInterFormFont(CPDF_Dictionary* pFormDict,
+ CPDF_Document* pDocument,
+ uint8_t charSet,
+ CFX_ByteString& csNameTag) {
+ if (!pFormDict) {
+ return NULL;
+ }
+ CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR");
+ if (!pDR) {
+ return NULL;
+ }
+ CPDF_Dictionary* pFonts = pDR->GetDictBy("Font");
+ if (!pFonts) {
+ return NULL;
+ }
+ for (const auto& it : *pFonts) {
+ const CFX_ByteString& csKey = it.first;
+ CPDF_Object* pObj = it.second;
+ if (!pObj) {
+ continue;
+ }
+ CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect());
+ if (!pElement)
+ continue;
+ if (pElement->GetStringBy("Type") != "Font")
+ continue;
+ CPDF_Font* pFind = pDocument->LoadFont(pElement);
+ if (!pFind) {
+ continue;
+ }
+ CFX_SubstFont* pSubst = (CFX_SubstFont*)pFind->GetSubstFont();
+ if (!pSubst) {
+ continue;
+ }
+ if (pSubst->m_Charset == (int)charSet) {
+ csNameTag = csKey;
+ return pFind;
+ }
+ }
+ return NULL;
+}
+CPDF_Font* GetNativeInterFormFont(CPDF_Dictionary* pFormDict,
+ CPDF_Document* pDocument,
+ CFX_ByteString& csNameTag) {
+ csNameTag = "";
+ uint8_t charSet = CPDF_InterForm::GetNativeCharSet();
+ CFX_SubstFont* pSubst;
+ CPDF_Font* pFont = GetDefaultInterFormFont(pFormDict, pDocument);
+ if (pFont) {
+ pSubst = (CFX_SubstFont*)pFont->GetSubstFont();
+ if (pSubst && pSubst->m_Charset == (int)charSet) {
+ FindInterFormFont(pFormDict, pFont, csNameTag);
+ return pFont;
+ }
+ }
+ return GetNativeInterFormFont(pFormDict, pDocument, charSet, csNameTag);
+}
+FX_BOOL FindInterFormFont(CPDF_Dictionary* pFormDict,
+ const CPDF_Font* pFont,
+ CFX_ByteString& csNameTag) {
+ if (!pFormDict || !pFont) {
+ return FALSE;
+ }
+ CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR");
+ if (!pDR) {
+ return FALSE;
+ }
+ CPDF_Dictionary* pFonts = pDR->GetDictBy("Font");
+ if (!pFonts) {
+ return FALSE;
+ }
+ for (const auto& it : *pFonts) {
+ const CFX_ByteString& csKey = it.first;
+ CPDF_Object* pObj = it.second;
+ if (!pObj) {
+ continue;
+ }
+ CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect());
+ if (!pElement)
+ continue;
+ if (pElement->GetStringBy("Type") != "Font") {
+ continue;
+ }
+ if (pFont->GetFontDict() == pElement) {
+ csNameTag = csKey;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+FX_BOOL FindInterFormFont(CPDF_Dictionary* pFormDict,
+ CPDF_Document* pDocument,
+ CFX_ByteString csFontName,
+ CPDF_Font*& pFont,
+ CFX_ByteString& csNameTag) {
+ if (!pFormDict) {
+ return FALSE;
+ }
+ CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR");
+ if (!pDR) {
+ return FALSE;
+ }
+ CPDF_Dictionary* pFonts = pDR->GetDictBy("Font");
+ if (!pFonts) {
+ return FALSE;
+ }
+ if (csFontName.GetLength() > 0) {
+ csFontName.Remove(' ');
+ }
+ for (const auto& it : *pFonts) {
+ const CFX_ByteString& csKey = it.first;
+ CPDF_Object* pObj = it.second;
+ if (!pObj) {
+ continue;
+ }
+ CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect());
+ if (!pElement)
+ continue;
+ if (pElement->GetStringBy("Type") != "Font") {
+ continue;
+ }
+ pFont = pDocument->LoadFont(pElement);
+ if (!pFont) {
+ continue;
+ }
+ CFX_ByteString csBaseFont;
+ csBaseFont = pFont->GetBaseFont();
+ csBaseFont.Remove(' ');
+ if (csBaseFont == csFontName) {
+ csNameTag = csKey;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+void AddInterFormFont(CPDF_Dictionary*& pFormDict,
+ CPDF_Document* pDocument,
+ const CPDF_Font* pFont,
+ CFX_ByteString& csNameTag) {
+ if (!pFont) {
+ return;
+ }
+ if (!pFormDict) {
+ InitInterFormDict(pFormDict, pDocument);
+ }
+ CFX_ByteString csTag;
+ if (FindInterFormFont(pFormDict, pFont, csTag)) {
+ csNameTag = csTag;
+ return;
+ }
+ if (!pFormDict) {
+ InitInterFormDict(pFormDict, pDocument);
+ }
+ CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR");
+ if (!pDR) {
+ pDR = new CPDF_Dictionary;
+ pFormDict->SetAt("DR", pDR);
+ }
+ CPDF_Dictionary* pFonts = pDR->GetDictBy("Font");
+ if (!pFonts) {
+ pFonts = new CPDF_Dictionary;
+ pDR->SetAt("Font", pFonts);
+ }
+ if (csNameTag.IsEmpty()) {
+ csNameTag = pFont->GetBaseFont();
+ }
+ csNameTag.Remove(' ');
+ csNameTag =
+ CPDF_InterForm::GenerateNewResourceName(pDR, "Font", 4, csNameTag);
+ pFonts->SetAtReference(csNameTag, pDocument, pFont->GetFontDict());
+}
+CPDF_Font* AddNativeInterFormFont(CPDF_Dictionary*& pFormDict,
+ CPDF_Document* pDocument,
+ uint8_t charSet,
+ CFX_ByteString& csNameTag) {
+ if (!pFormDict) {
+ InitInterFormDict(pFormDict, pDocument);
+ }
+ CFX_ByteString csTemp;
+ CPDF_Font* pFont =
+ GetNativeInterFormFont(pFormDict, pDocument, charSet, csTemp);
+ if (pFont) {
+ csNameTag = csTemp;
+ return pFont;
+ }
+ CFX_ByteString csFontName = CPDF_InterForm::GetNativeFont(charSet);
+ if (!csFontName.IsEmpty()) {
+ if (FindInterFormFont(pFormDict, pDocument, csFontName, pFont, csNameTag)) {
+ return pFont;
+ }
+ }
+ pFont = CPDF_InterForm::AddNativeFont(charSet, pDocument);
+ if (pFont) {
+ AddInterFormFont(pFormDict, pDocument, pFont, csNameTag);
+ }
+ return pFont;
+}
+CPDF_Font* AddNativeInterFormFont(CPDF_Dictionary*& pFormDict,
+ CPDF_Document* pDocument,
+ CFX_ByteString& csNameTag) {
+ uint8_t charSet = CPDF_InterForm::GetNativeCharSet();
+ return AddNativeInterFormFont(pFormDict, pDocument, charSet, csNameTag);
+}
+void RemoveInterFormFont(CPDF_Dictionary* pFormDict, const CPDF_Font* pFont) {
+ if (!pFormDict || !pFont) {
+ return;
+ }
+ CFX_ByteString csTag;
+ if (!FindInterFormFont(pFormDict, pFont, csTag)) {
+ return;
+ }
+ CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR");
+ CPDF_Dictionary* pFonts = pDR->GetDictBy("Font");
+ pFonts->RemoveAt(csTag);
+}
+void RemoveInterFormFont(CPDF_Dictionary* pFormDict, CFX_ByteString csNameTag) {
+ if (!pFormDict || csNameTag.IsEmpty()) {
+ return;
+ }
+ CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR");
+ if (!pDR) {
+ return;
+ }
+ CPDF_Dictionary* pFonts = pDR->GetDictBy("Font");
+ if (!pFonts) {
+ return;
+ }
+ pFonts->RemoveAt(csNameTag);
+}
+
+CPDF_Font* GetDefaultInterFormFont(CPDF_Dictionary* pFormDict,
+ CPDF_Document* pDocument) {
+ if (!pFormDict) {
+ return NULL;
+ }
+ CPDF_DefaultAppearance cDA(pFormDict->GetStringBy("DA"));
+ CFX_ByteString csFontNameTag;
+ FX_FLOAT fFontSize;
+ cDA.GetFont(csFontNameTag, fFontSize);
+ return GetInterFormFont(pFormDict, pDocument, csFontNameTag);
+}
+
+CPDF_IconFit::ScaleMethod CPDF_IconFit::GetScaleMethod() {
+ if (!m_pDict) {
+ return Always;
+ }
+ CFX_ByteString csSW = m_pDict->GetStringBy("SW", "A");
+ if (csSW == "B") {
+ return Bigger;
+ }
+ if (csSW == "S") {
+ return Smaller;
+ }
+ if (csSW == "N") {
+ return Never;
+ }
+ return Always;
+}
+FX_BOOL CPDF_IconFit::IsProportionalScale() {
+ if (!m_pDict) {
+ return TRUE;
+ }
+ return m_pDict->GetStringBy("S", "P") != "A";
+}
+void CPDF_IconFit::GetIconPosition(FX_FLOAT& fLeft, FX_FLOAT& fBottom) {
+ fLeft = fBottom = 0.5;
+ if (!m_pDict) {
+ return;
+ }
+ CPDF_Array* pA = m_pDict->GetArrayBy("A");
+ if (pA) {
+ FX_DWORD dwCount = pA->GetCount();
+ if (dwCount > 0) {
+ fLeft = pA->GetNumberAt(0);
+ }
+ if (dwCount > 1) {
+ fBottom = pA->GetNumberAt(1);
+ }
+ }
+}
+FX_BOOL CPDF_IconFit::GetFittingBounds() {
+ if (!m_pDict) {
+ return FALSE;
+ }
+ return m_pDict->GetBooleanBy("FB");
+}
+
+std::vector<bool> SaveCheckedFieldStatus(CPDF_FormField* pField) {
+ std::vector<bool> result;
+ int iCount = pField->CountControls();
+ for (int i = 0; i < iCount; ++i) {
+ if (CPDF_FormControl* pControl = pField->GetControl(i))
+ result.push_back(pControl->IsChecked());
+ }
+ return result;
+}
+
+CPDF_Object* FPDF_GetFieldAttr(CPDF_Dictionary* pFieldDict,
+ const FX_CHAR* name,
+ int nLevel) {
+ if (nLevel > FPDFDOC_UTILS_MAXRECURSION) {
+ return NULL;
+ }
+ if (!pFieldDict) {
+ return NULL;
+ }
+ CPDF_Object* pAttr = pFieldDict->GetElementValue(name);
+ if (pAttr) {
+ return pAttr;
+ }
+ CPDF_Dictionary* pParent = pFieldDict->GetDictBy("Parent");
+ if (!pParent) {
+ return NULL;
+ }
+ return FPDF_GetFieldAttr(pParent, name, nLevel + 1);
+}