diff options
-rw-r--r-- | BUILD.gn | 13 | ||||
-rw-r--r-- | core/fpdfdoc/cpdf_apsettings.cpp | 119 | ||||
-rw-r--r-- | core/fpdfdoc/cpdf_defaultappearance.cpp | 222 | ||||
-rw-r--r-- | core/fpdfdoc/cpdf_formcontrol.cpp (renamed from core/fpdfdoc/doc_formcontrol.cpp) | 149 | ||||
-rw-r--r-- | core/fpdfdoc/cpdf_formfield.cpp (renamed from core/fpdfdoc/doc_formfield.cpp) | 178 | ||||
-rw-r--r-- | core/fpdfdoc/cpdf_iconfit.cpp | 48 | ||||
-rw-r--r-- | core/fpdfdoc/cpdf_interform.cpp (renamed from core/fpdfdoc/doc_form.cpp) | 1064 | ||||
-rw-r--r-- | core/fpdfdoc/cpdf_numbertree.cpp | 52 | ||||
-rw-r--r-- | core/fpdfdoc/cpdf_numbertree.h | 23 | ||||
-rw-r--r-- | core/fpdfdoc/cpdf_pagelabel.cpp | 2 | ||||
-rw-r--r-- | core/fpdfdoc/cpvt_fontmap.cpp | 2 | ||||
-rw-r--r-- | core/fpdfdoc/doc_utils.cpp | 770 | ||||
-rw-r--r-- | core/fpdfdoc/doc_utils.h | 79 | ||||
-rw-r--r-- | core/fpdfdoc/include/cpdf_formfield.h | 1 | ||||
-rw-r--r-- | core/fpdfdoc/include/cpdf_interform.h | 4 | ||||
-rw-r--r-- | pdfium.gyp | 13 |
16 files changed, 1349 insertions, 1390 deletions
@@ -209,16 +209,24 @@ static_library("fpdfdoc") { "core/fpdfdoc/cpdf_actionfields.cpp", "core/fpdfdoc/cpdf_annot.cpp", "core/fpdfdoc/cpdf_annotlist.cpp", + "core/fpdfdoc/cpdf_apsettings.cpp", "core/fpdfdoc/cpdf_apsettings.h", "core/fpdfdoc/cpdf_bookmark.cpp", "core/fpdfdoc/cpdf_bookmarktree.cpp", + "core/fpdfdoc/cpdf_defaultappearance.cpp", "core/fpdfdoc/cpdf_dest.cpp", "core/fpdfdoc/cpdf_docjsactions.cpp", "core/fpdfdoc/cpdf_filespec.cpp", + "core/fpdfdoc/cpdf_formcontrol.cpp", + "core/fpdfdoc/cpdf_formfield.cpp", + "core/fpdfdoc/cpdf_iconfit.cpp", + "core/fpdfdoc/cpdf_interform.cpp", "core/fpdfdoc/cpdf_link.cpp", "core/fpdfdoc/cpdf_linklist.cpp", "core/fpdfdoc/cpdf_metadata.cpp", "core/fpdfdoc/cpdf_nametree.cpp", + "core/fpdfdoc/cpdf_numbertree.cpp", + "core/fpdfdoc/cpdf_numbertree.h", "core/fpdfdoc/cpdf_occontext.cpp", "core/fpdfdoc/cpdf_pagelabel.cpp", "core/fpdfdoc/cpdf_pagelabel.h", @@ -242,11 +250,6 @@ static_library("fpdfdoc") { "core/fpdfdoc/csection.h", "core/fpdfdoc/ctypeset.cpp", "core/fpdfdoc/ctypeset.h", - "core/fpdfdoc/doc_form.cpp", - "core/fpdfdoc/doc_formcontrol.cpp", - "core/fpdfdoc/doc_formfield.cpp", - "core/fpdfdoc/doc_utils.cpp", - "core/fpdfdoc/doc_utils.h", "core/fpdfdoc/include/cpdf_aaction.h", "core/fpdfdoc/include/cpdf_action.h", "core/fpdfdoc/include/cpdf_actionfields.h", diff --git a/core/fpdfdoc/cpdf_apsettings.cpp b/core/fpdfdoc/cpdf_apsettings.cpp new file mode 100644 index 0000000000..f2a802b445 --- /dev/null +++ b/core/fpdfdoc/cpdf_apsettings.cpp @@ -0,0 +1,119 @@ +// Copyright 2016 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 "core/fpdfdoc/cpdf_apsettings.h" + +#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" +#include "core/fpdfdoc/include/cpdf_formcontrol.h" + +CPDF_ApSettings::CPDF_ApSettings(CPDF_Dictionary* pDict) : m_pDict(pDict) {} + +bool CPDF_ApSettings::HasMKEntry(const CFX_ByteString& csEntry) const { + return m_pDict && m_pDict->KeyExist(csEntry); +} + +int CPDF_ApSettings::GetRotation() const { + return m_pDict ? m_pDict->GetIntegerBy("R") : 0; +} + +FX_ARGB CPDF_ApSettings::GetColor(int& iColorType, + const CFX_ByteString& csEntry) const { + iColorType = COLORTYPE_TRANSPARENT; + if (!m_pDict) + return 0; + + CPDF_Array* pEntry = m_pDict->GetArrayBy(csEntry); + if (!pEntry) + return 0; + + FX_ARGB color = 0; + size_t dwCount = pEntry->GetCount(); + if (dwCount == 1) { + iColorType = COLORTYPE_GRAY; + FX_FLOAT g = pEntry->GetNumberAt(0) * 255; + return ArgbEncode(255, (int)g, (int)g, (int)g); + } + if (dwCount == 3) { + iColorType = COLORTYPE_RGB; + FX_FLOAT r = pEntry->GetNumberAt(0) * 255; + FX_FLOAT g = pEntry->GetNumberAt(1) * 255; + FX_FLOAT b = pEntry->GetNumberAt(2) * 255; + return ArgbEncode(255, (int)r, (int)g, (int)b); + } + if (dwCount == 4) { + iColorType = COLORTYPE_CMYK; + FX_FLOAT c = pEntry->GetNumberAt(0); + FX_FLOAT m = pEntry->GetNumberAt(1); + FX_FLOAT y = pEntry->GetNumberAt(2); + FX_FLOAT k = pEntry->GetNumberAt(3); + 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); + return ArgbEncode(255, (int)(r * 255), (int)(g * 255), (int)(b * 255)); + } + return color; +} + +FX_FLOAT CPDF_ApSettings::GetOriginalColor( + int index, + const CFX_ByteString& csEntry) const { + if (!m_pDict) + return 0; + + CPDF_Array* pEntry = m_pDict->GetArrayBy(csEntry); + return pEntry ? pEntry->GetNumberAt(index) : 0; +} + +void CPDF_ApSettings::GetOriginalColor(int& iColorType, + FX_FLOAT fc[4], + const CFX_ByteString& csEntry) const { + iColorType = COLORTYPE_TRANSPARENT; + for (int i = 0; i < 4; i++) + fc[i] = 0; + + if (!m_pDict) + return; + + CPDF_Array* pEntry = m_pDict->GetArrayBy(csEntry); + if (!pEntry) + return; + + size_t dwCount = pEntry->GetCount(); + if (dwCount == 1) { + iColorType = COLORTYPE_GRAY; + fc[0] = pEntry->GetNumberAt(0); + } else if (dwCount == 3) { + iColorType = COLORTYPE_RGB; + fc[0] = pEntry->GetNumberAt(0); + fc[1] = pEntry->GetNumberAt(1); + fc[2] = pEntry->GetNumberAt(2); + } else if (dwCount == 4) { + iColorType = COLORTYPE_CMYK; + fc[0] = pEntry->GetNumberAt(0); + fc[1] = pEntry->GetNumberAt(1); + fc[2] = pEntry->GetNumberAt(2); + fc[3] = pEntry->GetNumberAt(3); + } +} + +CFX_WideString CPDF_ApSettings::GetCaption( + const CFX_ByteString& csEntry) const { + return m_pDict ? m_pDict->GetUnicodeTextBy(csEntry) : CFX_WideString(); +} + +CPDF_Stream* CPDF_ApSettings::GetIcon(const CFX_ByteString& csEntry) const { + return m_pDict ? m_pDict->GetStreamBy(csEntry) : nullptr; +} + +CPDF_IconFit CPDF_ApSettings::GetIconFit() const { + return CPDF_IconFit(m_pDict ? m_pDict->GetDictBy("IF") : nullptr); +} + +int CPDF_ApSettings::GetTextPosition() const { + return m_pDict ? m_pDict->GetIntegerBy("TP", TEXTPOS_CAPTION) + : TEXTPOS_CAPTION; +} diff --git a/core/fpdfdoc/cpdf_defaultappearance.cpp b/core/fpdfdoc/cpdf_defaultappearance.cpp new file mode 100644 index 0000000000..1c71ae5826 --- /dev/null +++ b/core/fpdfdoc/cpdf_defaultappearance.cpp @@ -0,0 +1,222 @@ +// Copyright 2016 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 "core/fpdfdoc/include/cpdf_defaultappearance.h" + +#include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h" +#include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h" +#include "core/fpdfdoc/include/cpdf_formcontrol.h" + +FX_BOOL CPDF_DefaultAppearance::HasFont() { + if (m_csDA.IsEmpty()) + return FALSE; + + CPDF_SimpleParser syntax(m_csDA.AsStringC()); + return syntax.FindTagParamFromStart("Tf", 2); +} + +CFX_ByteString CPDF_DefaultAppearance::GetFontString() { + CFX_ByteString csFont; + if (m_csDA.IsEmpty()) + return csFont; + + CPDF_SimpleParser syntax(m_csDA.AsStringC()); + if (syntax.FindTagParamFromStart("Tf", 2)) { + csFont += syntax.GetWord(); + csFont += " "; + csFont += syntax.GetWord(); + csFont += " "; + csFont += 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.AsStringC()); + if (syntax.FindTagParamFromStart("Tf", 2)) { + csFontNameTag = CFX_ByteString(syntax.GetWord()); + csFontNameTag.Delete(0, 1); + fFontSize = FX_atof(syntax.GetWord()); + } + csFontNameTag = PDF_NameDecode(csFontNameTag); +} + +FX_BOOL CPDF_DefaultAppearance::HasColor(PaintOperation nOperation) { + if (m_csDA.IsEmpty()) + return FALSE; + + CPDF_SimpleParser syntax(m_csDA.AsStringC()); + if (syntax.FindTagParamFromStart( + (nOperation == PaintOperation::STROKE ? "G" : "g"), 1)) { + return TRUE; + } + if (syntax.FindTagParamFromStart( + (nOperation == PaintOperation::STROKE ? "RG" : "rg"), 3)) { + return TRUE; + } + return syntax.FindTagParamFromStart( + (nOperation == PaintOperation::STROKE ? "K" : "k"), 4); +} + +CFX_ByteString CPDF_DefaultAppearance::GetColorString( + PaintOperation nOperation) { + CFX_ByteString csColor; + if (m_csDA.IsEmpty()) + return csColor; + + CPDF_SimpleParser syntax(m_csDA.AsStringC()); + if (syntax.FindTagParamFromStart( + (nOperation == PaintOperation::STROKE ? "G" : "g"), 1)) { + csColor += syntax.GetWord(); + csColor += " "; + csColor += syntax.GetWord(); + return csColor; + } + if (syntax.FindTagParamFromStart( + (nOperation == PaintOperation::STROKE ? "RG" : "rg"), 3)) { + csColor += syntax.GetWord(); + csColor += " "; + csColor += syntax.GetWord(); + csColor += " "; + csColor += syntax.GetWord(); + csColor += " "; + csColor += syntax.GetWord(); + return csColor; + } + if (syntax.FindTagParamFromStart( + (nOperation == PaintOperation::STROKE ? "K" : "k"), 4)) { + csColor += syntax.GetWord(); + csColor += " "; + csColor += syntax.GetWord(); + csColor += " "; + csColor += syntax.GetWord(); + csColor += " "; + csColor += syntax.GetWord(); + csColor += " "; + csColor += syntax.GetWord(); + } + return csColor; +} + +void CPDF_DefaultAppearance::GetColor(int& iColorType, + FX_FLOAT fc[4], + PaintOperation nOperation) { + iColorType = COLORTYPE_TRANSPARENT; + for (int c = 0; c < 4; c++) + fc[c] = 0; + + if (m_csDA.IsEmpty()) + return; + + CPDF_SimpleParser syntax(m_csDA.AsStringC()); + if (syntax.FindTagParamFromStart( + (nOperation == PaintOperation::STROKE ? "G" : "g"), 1)) { + iColorType = COLORTYPE_GRAY; + fc[0] = FX_atof(syntax.GetWord()); + return; + } + if (syntax.FindTagParamFromStart( + (nOperation == PaintOperation::STROKE ? "RG" : "rg"), 3)) { + iColorType = COLORTYPE_RGB; + fc[0] = FX_atof(syntax.GetWord()); + fc[1] = FX_atof(syntax.GetWord()); + fc[2] = FX_atof(syntax.GetWord()); + return; + } + if (syntax.FindTagParamFromStart( + (nOperation == PaintOperation::STROKE ? "K" : "k"), 4)) { + iColorType = COLORTYPE_CMYK; + fc[0] = FX_atof(syntax.GetWord()); + fc[1] = FX_atof(syntax.GetWord()); + fc[2] = FX_atof(syntax.GetWord()); + fc[3] = FX_atof(syntax.GetWord()); + } +} + +void CPDF_DefaultAppearance::GetColor(FX_ARGB& color, + int& iColorType, + PaintOperation nOperation) { + color = 0; + iColorType = COLORTYPE_TRANSPARENT; + if (m_csDA.IsEmpty()) + return; + + CPDF_SimpleParser syntax(m_csDA.AsStringC()); + if (syntax.FindTagParamFromStart( + (nOperation == PaintOperation::STROKE ? "G" : "g"), 1)) { + iColorType = COLORTYPE_GRAY; + FX_FLOAT g = FX_atof(syntax.GetWord()) * 255 + 0.5f; + color = ArgbEncode(255, (int)g, (int)g, (int)g); + return; + } + if (syntax.FindTagParamFromStart( + (nOperation == PaintOperation::STROKE ? "RG" : "rg"), 3)) { + iColorType = COLORTYPE_RGB; + FX_FLOAT r = FX_atof(syntax.GetWord()) * 255 + 0.5f; + FX_FLOAT g = FX_atof(syntax.GetWord()) * 255 + 0.5f; + FX_FLOAT b = FX_atof(syntax.GetWord()) * 255 + 0.5f; + color = ArgbEncode(255, (int)r, (int)g, (int)b); + return; + } + if (syntax.FindTagParamFromStart( + (nOperation == PaintOperation::STROKE ? "K" : "k"), 4)) { + iColorType = COLORTYPE_CMYK; + FX_FLOAT c = FX_atof(syntax.GetWord()); + FX_FLOAT m = FX_atof(syntax.GetWord()); + FX_FLOAT y = FX_atof(syntax.GetWord()); + FX_FLOAT k = FX_atof(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.AsStringC()); + return syntax.FindTagParamFromStart("Tm", 6); +} + +CFX_ByteString CPDF_DefaultAppearance::GetTextMatrixString() { + CFX_ByteString csTM; + if (m_csDA.IsEmpty()) + return csTM; + + CPDF_SimpleParser syntax(m_csDA.AsStringC()); + if (syntax.FindTagParamFromStart("Tm", 6)) { + for (int i = 0; i < 6; i++) { + csTM += syntax.GetWord(); + csTM += " "; + } + csTM += syntax.GetWord(); + } + return csTM; +} + +CFX_Matrix CPDF_DefaultAppearance::GetTextMatrix() { + CFX_Matrix tm; + if (m_csDA.IsEmpty()) + return tm; + + CPDF_SimpleParser syntax(m_csDA.AsStringC()); + if (syntax.FindTagParamFromStart("Tm", 6)) { + FX_FLOAT f[6]; + for (int i = 0; i < 6; i++) + f[i] = FX_atof(syntax.GetWord()); + tm.Set(f[0], f[1], f[2], f[3], f[4], f[5]); + } + return tm; +} diff --git a/core/fpdfdoc/doc_formcontrol.cpp b/core/fpdfdoc/cpdf_formcontrol.cpp index 932a006be5..e6c505869c 100644 --- a/core/fpdfdoc/doc_formcontrol.cpp +++ b/core/fpdfdoc/cpdf_formcontrol.cpp @@ -1,4 +1,4 @@ -// Copyright 2014 PDFium Authors. All rights reserved. +// Copyright 2016 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. @@ -53,25 +53,24 @@ void CPDF_FormControl::SetOnStateName(const CFX_ByteString& csOn) { ASSERT(GetType() == CPDF_FormField::CheckBox || GetType() == CPDF_FormField::RadioButton); CFX_ByteString csValue = csOn; - if (csValue.IsEmpty()) { + if (csValue.IsEmpty()) csValue = "Yes"; - } - if (csValue == "Off") { + else if (csValue == "Off") csValue = "Yes"; - } + CFX_ByteString csAS = m_pWidgetDict->GetStringBy("AS", "Off"); - if (csAS != "Off") { + if (csAS != "Off") m_pWidgetDict->SetAtName("AS", csValue); - } + CPDF_Dictionary* pAP = m_pWidgetDict->GetDictBy("AP"); - if (!pAP) { + if (!pAP) return; - } + for (const auto& it : *pAP) { CPDF_Object* pObj1 = it.second; - if (!pObj1) { + if (!pObj1) continue; - } + CPDF_Object* pObjDirect1 = pObj1->GetDirect(); CPDF_Dictionary* pSubDict = pObjDirect1->AsDictionary(); if (!pSubDict) @@ -82,9 +81,8 @@ void CPDF_FormControl::SetOnStateName(const CFX_ByteString& csOn) { const CFX_ByteString& csKey2 = subdict_it->first; CPDF_Object* pObj2 = subdict_it->second; ++subdict_it; - if (!pObj2) { + if (!pObj2) continue; - } if (csKey2 != "Off") { pSubDict->ReplaceKey(csKey2, csValue); break; @@ -92,6 +90,7 @@ void CPDF_FormControl::SetOnStateName(const CFX_ByteString& csOn) { } } } + CFX_ByteString CPDF_FormControl::GetCheckedAPState() { ASSERT(GetType() == CPDF_FormField::CheckBox || GetType() == CPDF_FormField::RadioButton); @@ -137,9 +136,9 @@ bool CPDF_FormControl::IsDefaultChecked() const { ASSERT(GetType() == CPDF_FormField::CheckBox || GetType() == CPDF_FormField::RadioButton); CPDF_Object* pDV = FPDF_GetFieldAttr(m_pField->m_pDict, "DV"); - if (!pDV) { + if (!pDV) return FALSE; - } + CFX_ByteString csDV = pDV->GetString(); CFX_ByteString csOn = GetOnStateName(); return (csDV == csOn); @@ -225,6 +224,7 @@ void CPDF_FormControl::GetOriginalColor(int& iColorType, const CFX_ByteString& csEntry) { GetMK().GetOriginalColor(iColorType, fc, csEntry); } + CFX_WideString CPDF_FormControl::GetCaption(const CFX_ByteString& csEntry) { return GetMK().GetCaption(csEntry); } @@ -292,9 +292,8 @@ CPDF_Font* CPDF_FormControl::GetDefaultControlFont() { CPDF_Dictionary* pElement = pFonts->GetDictBy(csFontNameTag); if (pElement) { CPDF_Font* pFont = m_pField->m_pForm->m_pDocument->LoadFont(pElement); - if (pFont) { + if (pFont) return pFont; - } } } } @@ -309,9 +308,8 @@ CPDF_Font* CPDF_FormControl::GetDefaultControlFont() { CPDF_Dictionary* pElement = pFonts->GetDictBy(csFontNameTag); if (pElement) { CPDF_Font* pFont = m_pField->m_pForm->m_pDocument->LoadFont(pElement); - if (pFont) { + if (pFont) return pFont; - } } } } @@ -319,120 +317,13 @@ CPDF_Font* CPDF_FormControl::GetDefaultControlFont() { } int CPDF_FormControl::GetControlAlignment() { - if (!m_pWidgetDict) { + if (!m_pWidgetDict) return 0; - } - if (m_pWidgetDict->KeyExist("Q")) { + if (m_pWidgetDict->KeyExist("Q")) return m_pWidgetDict->GetIntegerBy("Q", 0); - } + CPDF_Object* pObj = FPDF_GetFieldAttr(m_pField->m_pDict, "Q"); if (pObj) return pObj->GetInteger(); return m_pField->m_pForm->GetFormAlignment(); } - -CPDF_ApSettings::CPDF_ApSettings(CPDF_Dictionary* pDict) : m_pDict(pDict) {} - -bool CPDF_ApSettings::HasMKEntry(const CFX_ByteString& csEntry) const { - return m_pDict && m_pDict->KeyExist(csEntry); -} - -int CPDF_ApSettings::GetRotation() const { - return m_pDict ? m_pDict->GetIntegerBy("R") : 0; -} - -FX_ARGB CPDF_ApSettings::GetColor(int& iColorType, - const CFX_ByteString& csEntry) const { - iColorType = COLORTYPE_TRANSPARENT; - if (!m_pDict) - return 0; - - CPDF_Array* pEntry = m_pDict->GetArrayBy(csEntry); - if (!pEntry) - return 0; - - FX_ARGB color = 0; - size_t dwCount = pEntry->GetCount(); - if (dwCount == 1) { - iColorType = COLORTYPE_GRAY; - FX_FLOAT g = pEntry->GetNumberAt(0) * 255; - color = ArgbEncode(255, (int)g, (int)g, (int)g); - } else if (dwCount == 3) { - iColorType = COLORTYPE_RGB; - FX_FLOAT r = pEntry->GetNumberAt(0) * 255; - FX_FLOAT g = pEntry->GetNumberAt(1) * 255; - FX_FLOAT b = pEntry->GetNumberAt(2) * 255; - color = ArgbEncode(255, (int)r, (int)g, (int)b); - } else if (dwCount == 4) { - iColorType = COLORTYPE_CMYK; - FX_FLOAT c = pEntry->GetNumberAt(0); - FX_FLOAT m = pEntry->GetNumberAt(1); - FX_FLOAT y = pEntry->GetNumberAt(2); - FX_FLOAT k = pEntry->GetNumberAt(3); - 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), (int)(g * 255), (int)(b * 255)); - } - return color; -} - -FX_FLOAT CPDF_ApSettings::GetOriginalColor( - int index, - const CFX_ByteString& csEntry) const { - if (!m_pDict) - return 0; - - CPDF_Array* pEntry = m_pDict->GetArrayBy(csEntry); - return pEntry ? pEntry->GetNumberAt(index) : 0; -} - -void CPDF_ApSettings::GetOriginalColor(int& iColorType, - FX_FLOAT fc[4], - const CFX_ByteString& csEntry) const { - iColorType = COLORTYPE_TRANSPARENT; - for (int i = 0; i < 4; i++) { - fc[i] = 0; - } - if (!m_pDict) { - return; - } - CPDF_Array* pEntry = m_pDict->GetArrayBy(csEntry); - if (!pEntry) { - return; - } - size_t dwCount = pEntry->GetCount(); - if (dwCount == 1) { - iColorType = COLORTYPE_GRAY; - fc[0] = pEntry->GetNumberAt(0); - } else if (dwCount == 3) { - iColorType = COLORTYPE_RGB; - fc[0] = pEntry->GetNumberAt(0); - fc[1] = pEntry->GetNumberAt(1); - fc[2] = pEntry->GetNumberAt(2); - } else if (dwCount == 4) { - iColorType = COLORTYPE_CMYK; - fc[0] = pEntry->GetNumberAt(0); - fc[1] = pEntry->GetNumberAt(1); - fc[2] = pEntry->GetNumberAt(2); - fc[3] = pEntry->GetNumberAt(3); - } -} - -CFX_WideString CPDF_ApSettings::GetCaption( - const CFX_ByteString& csEntry) const { - return m_pDict ? m_pDict->GetUnicodeTextBy(csEntry) : CFX_WideString(); -} - -CPDF_Stream* CPDF_ApSettings::GetIcon(const CFX_ByteString& csEntry) const { - return m_pDict ? m_pDict->GetStreamBy(csEntry) : nullptr; -} - -CPDF_IconFit CPDF_ApSettings::GetIconFit() const { - return CPDF_IconFit(m_pDict ? m_pDict->GetDictBy("IF") : nullptr); -} - -int CPDF_ApSettings::GetTextPosition() const { - return m_pDict ? m_pDict->GetIntegerBy("TP", TEXTPOS_CAPTION) - : TEXTPOS_CAPTION; -} diff --git a/core/fpdfdoc/doc_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp index cb1b0a4566..81d2178820 100644 --- a/core/fpdfdoc/doc_formfield.cpp +++ b/core/fpdfdoc/cpdf_formfield.cpp @@ -14,12 +14,13 @@ #include "core/fpdfapi/fpdf_parser/include/cpdf_string.h" #include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h" #include "core/fpdfdoc/cpvt_generateap.h" -#include "core/fpdfdoc/doc_utils.h" #include "core/fpdfdoc/include/cpdf_formcontrol.h" #include "core/fpdfdoc/include/cpdf_interform.h" namespace { +const int kMaxRecursion = 32; + const int kFormListMultiSelect = 0x100; const int kFormComboEdit = 0x100; @@ -36,15 +37,48 @@ const int kFormTextPassword = 0x200; const int kFormTextNoScroll = 0x400; const int kFormTextComb = 0x800; -bool PDF_FormField_IsUnison(CPDF_FormField* pField) { +bool IsUnison(CPDF_FormField* pField) { if (pField->GetType() == CPDF_FormField::CheckBox) return true; - return (pField->GetFieldFlags() & 0x2000000) != 0; } } // namespace +CPDF_Object* FPDF_GetFieldAttr(CPDF_Dictionary* pFieldDict, + const FX_CHAR* name, + int nLevel) { + if (nLevel > kMaxRecursion) + return nullptr; + if (!pFieldDict) + return nullptr; + + CPDF_Object* pAttr = pFieldDict->GetDirectObjectBy(name); + if (pAttr) + return pAttr; + + CPDF_Dictionary* pParent = pFieldDict->GetDictBy("Parent"); + if (!pParent) + return nullptr; + return FPDF_GetFieldAttr(pParent, name, nLevel + 1); +} + +CFX_WideString FPDF_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; +} + CPDF_FormField::CPDF_FormField(CPDF_InterForm* pForm, CPDF_Dictionary* pDict) : m_Type(Unknown), m_pForm(pForm), @@ -64,24 +98,20 @@ void CPDF_FormField::SyncFieldFlags() { ? FPDF_GetFieldAttr(m_pDict, "Ff")->GetInteger() : 0; m_Flags = 0; - if (flags & 1) { + if (flags & 1) m_Flags |= kFormFieldReadOnly; - } - if (flags & 2) { + if (flags & 2) m_Flags |= kFormFieldRequired; - } - if (flags & 4) { + if (flags & 4) m_Flags |= kFormFieldNoExport; - } + if (type_name == "Btn") { if (flags & 0x8000) { m_Type = RadioButton; - if (flags & 0x4000) { + if (flags & 0x4000) m_Flags |= kFormRadioNoToggleOff; - } - if (flags & 0x2000000) { + if (flags & 0x2000000) m_Flags |= kFormRadioUnison; - } } else if (flags & 0x10000) { m_Type = PushButton; } else { @@ -94,39 +124,34 @@ void CPDF_FormField::SyncFieldFlags() { m_Type = RichText; } else { m_Type = Text; - if (flags & 0x1000) { + if (flags & 0x1000) m_Flags |= kFormTextMultiLine; - } - if (flags & 0x2000) { + if (flags & 0x2000) m_Flags |= kFormTextPassword; - } - if (flags & 0x800000) { + if (flags & 0x800000) m_Flags |= kFormTextNoScroll; - } - if (flags & 0x100000) { + if (flags & 0x100000) m_Flags |= kFormTextComb; - } } LoadDA(); } else if (type_name == "Ch") { if (flags & 0x20000) { m_Type = ComboBox; - if (flags & 0x40000) { + if (flags & 0x40000) m_Flags |= kFormComboEdit; - } } else { m_Type = ListBox; - if (flags & 0x200000) { + if (flags & 0x200000) m_Flags |= kFormListMultiSelect; - } } LoadDA(); } else if (type_name == "Sig") { m_Type = Sign; } } + CFX_WideString CPDF_FormField::GetFullName() const { - return ::GetFullName(m_pDict); + return FPDF_GetFullName(m_pDict); } FX_BOOL CPDF_FormField::ResetField(FX_BOOL bNotify) { @@ -137,20 +162,18 @@ FX_BOOL CPDF_FormField::ResetField(FX_BOOL bNotify) { if (iCount) { // TODO(weili): Check whether anything special needs to be done for // unison field. Otherwise, merge these branches. - if (PDF_FormField_IsUnison(this)) { - for (int i = 0; i < iCount; i++) { + if (IsUnison(this)) { + for (int i = 0; i < iCount; i++) CheckControl(i, GetControl(i)->IsDefaultChecked(), FALSE); - } } else { - for (int i = 0; i < iCount; i++) { + for (int i = 0; i < iCount; i++) CheckControl(i, GetControl(i)->IsDefaultChecked(), FALSE); - } } } - if (bNotify && m_pForm->m_pFormNotify) { + if (bNotify && m_pForm->m_pFormNotify) m_pForm->m_pFormNotify->AfterCheckedStatusChange(this); - } - } break; + break; + } case CPDF_FormField::ComboBox: case CPDF_FormField::ListBox: { CFX_WideString csValue; @@ -165,7 +188,8 @@ FX_BOOL CPDF_FormField::ResetField(FX_BOOL bNotify) { SetItemSelection(iIndex, TRUE); if (bNotify) NotifyListOrComboBoxAfterChange(); - } break; + break; + } case CPDF_FormField::Text: case CPDF_FormField::RichText: case CPDF_FormField::File: @@ -203,7 +227,8 @@ FX_BOOL CPDF_FormField::ResetField(FX_BOOL bNotify) { } if (bNotify) NotifyAfterValueChange(); - } break; + break; + } } return TRUE; } @@ -250,39 +275,29 @@ CPDF_AAction CPDF_FormField::GetAdditionalAction() const { CFX_WideString CPDF_FormField::GetAlternateName() const { CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "TU"); - if (!pObj) { - return L""; - } - return pObj->GetUnicodeText(); + return pObj ? pObj->GetUnicodeText() : L""; } + CFX_WideString CPDF_FormField::GetMappingName() const { CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "TM"); - if (!pObj) { - return L""; - } - return pObj->GetUnicodeText(); + return pObj ? pObj->GetUnicodeText() : L""; } + uint32_t CPDF_FormField::GetFieldFlags() const { CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "Ff"); - if (!pObj) { - return 0; - } - return pObj->GetInteger(); + return pObj ? pObj->GetInteger() : 0; } + CFX_ByteString CPDF_FormField::GetDefaultStyle() const { CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "DS"); - if (!pObj) { - return ""; - } - return pObj->GetString(); + return pObj ? pObj->GetString() : ""; } + CFX_WideString CPDF_FormField::GetRichTextString() const { CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "RV"); - if (!pObj) { - return L""; - } - return pObj->GetUnicodeText(); + return pObj ? pObj->GetUnicodeText() : L""; } + CFX_WideString CPDF_FormField::GetValue(FX_BOOL bDefault) const { if (GetType() == CheckBox || GetType() == RadioButton) return GetCheckValue(bDefault); @@ -290,16 +305,15 @@ CFX_WideString CPDF_FormField::GetValue(FX_BOOL bDefault) const { CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, bDefault ? "DV" : "V"); if (!pValue) { if (!bDefault) { - if (m_Type == RichText) { + if (m_Type == RichText) pValue = FPDF_GetFieldAttr(m_pDict, "V"); - } - if (!pValue && m_Type != Text) { + if (!pValue && m_Type != Text) pValue = FPDF_GetFieldAttr(m_pDict, "DV"); - } } if (!pValue) return CFX_WideString(); } + switch (pValue->GetType()) { case CPDF_Object::STRING: case CPDF_Object::STREAM: @@ -356,7 +370,8 @@ FX_BOOL CPDF_FormField::SetValue(const CFX_WideString& value, } if (bNotify) NotifyAfterValueChange(); - } break; + break; + } case ListBox: { int iIndex = FindOptionValue(value); if (iIndex < 0) @@ -444,9 +459,8 @@ int CPDF_FormField::GetSelectedIndex(int index) const { if (index < CountSelectedOptions()) { int iOptIndex = GetSelectedOptionIndex(index); CFX_WideString csOpt = GetOptionValue(iOptIndex); - if (csOpt == sel_value) { + if (csOpt == sel_value) return iOptIndex; - } } for (int i = 0; i < CountOptions(); i++) { if (sel_value == GetOptionValue(i)) @@ -474,19 +488,17 @@ FX_BOOL CPDF_FormField::ClearSelection(FX_BOOL bNotify) { FX_BOOL CPDF_FormField::IsItemSelected(int index) const { ASSERT(GetType() == ComboBox || GetType() == ListBox); - if (index < 0 || index >= CountOptions()) { + if (index < 0 || index >= CountOptions()) return FALSE; - } - if (IsOptionSelected(index)) { + if (IsOptionSelected(index)) return TRUE; - } + CFX_WideString opt_value = GetOptionValue(index); CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V"); if (!pValue) { pValue = FPDF_GetFieldAttr(m_pDict, "I"); - if (!pValue) { + if (!pValue) return FALSE; - } } if (pValue->IsString()) @@ -623,9 +635,11 @@ CFX_WideString CPDF_FormField::GetOptionText(int index, int sub_index) const { CPDF_String* pString = ToString(pOption); return pString ? pString->GetUnicodeText() : CFX_WideString(); } + CFX_WideString CPDF_FormField::GetOptionLabel(int index) const { return GetOptionText(index, 1); } + CFX_WideString CPDF_FormField::GetOptionValue(int index) const { return GetOptionText(index, 0); } @@ -707,37 +721,35 @@ FX_BOOL CPDF_FormField::CheckControl(int iControlIndex, bool bNotify) { ASSERT(GetType() == CheckBox || GetType() == RadioButton); CPDF_FormControl* pControl = GetControl(iControlIndex); - if (!pControl) { + if (!pControl) return FALSE; - } - if (!bChecked && pControl->IsChecked() == bChecked) { + if (!bChecked && pControl->IsChecked() == bChecked) return FALSE; - } + CFX_WideString csWExport = pControl->GetExportValue(); CFX_ByteString csBExport = PDF_EncodeText(csWExport); int iCount = CountControls(); - bool bUnison = PDF_FormField_IsUnison(this); + bool bUnison = IsUnison(this); for (int i = 0; i < iCount; i++) { CPDF_FormControl* pCtrl = GetControl(i); if (bUnison) { CFX_WideString csEValue = pCtrl->GetExportValue(); if (csEValue == csWExport) { - if (pCtrl->GetOnStateName() == pControl->GetOnStateName()) { + if (pCtrl->GetOnStateName() == pControl->GetOnStateName()) pCtrl->CheckControl(bChecked); - } else if (bChecked) { + else if (bChecked) pCtrl->CheckControl(FALSE); - } } else if (bChecked) { pCtrl->CheckControl(FALSE); } } else { - if (i == iControlIndex) { + if (i == iControlIndex) pCtrl->CheckControl(bChecked); - } else if (bChecked) { + else if (bChecked) pCtrl->CheckControl(FALSE); - } } } + CPDF_Object* pOpt = FPDF_GetFieldAttr(m_pDict, "Opt"); if (!ToArray(pOpt)) { if (bChecked) { @@ -745,12 +757,10 @@ FX_BOOL CPDF_FormField::CheckControl(int iControlIndex, } else { CFX_ByteString csV; CPDF_Object* pV = FPDF_GetFieldAttr(m_pDict, "V"); - if (pV) { + if (pV) csV = pV->GetString(); - } - if (csV == csBExport) { + if (csV == csBExport) m_pDict->SetAtName("V", "Off"); - } } } else if (bChecked) { CFX_ByteString csIndex; diff --git a/core/fpdfdoc/cpdf_iconfit.cpp b/core/fpdfdoc/cpdf_iconfit.cpp new file mode 100644 index 0000000000..3b3a09a54b --- /dev/null +++ b/core/fpdfdoc/cpdf_iconfit.cpp @@ -0,0 +1,48 @@ +// Copyright 2016 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 "core/fpdfdoc/include/cpdf_iconfit.h" + +#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" +#include "core/fxcrt/include/fx_string.h" + +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() { + return m_pDict ? m_pDict->GetStringBy("S", "P") != "A" : TRUE; +} + +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) { + uint32_t dwCount = pA->GetCount(); + if (dwCount > 0) + fLeft = pA->GetNumberAt(0); + if (dwCount > 1) + fBottom = pA->GetNumberAt(1); + } +} + +bool CPDF_IconFit::GetFittingBounds() { + return m_pDict ? m_pDict->GetBooleanBy("FB") : false; +} diff --git a/core/fpdfdoc/doc_form.cpp b/core/fpdfdoc/cpdf_interform.cpp index 3dde448a24..cf728a7d4b 100644 --- a/core/fpdfdoc/doc_form.cpp +++ b/core/fpdfdoc/cpdf_interform.cpp @@ -1,4 +1,4 @@ -// Copyright 2014 PDFium Authors. All rights reserved. +// Copyright 2016 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. @@ -6,6 +6,7 @@ #include <vector> +#include "core/fpdfapi/fpdf_font/include/cpdf_font.h" #include "core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h" #include "core/fpdfapi/fpdf_page/include/cpdf_page.h" #include "core/fpdfapi/fpdf_parser/include/cfdf_document.h" @@ -15,7 +16,7 @@ #include "core/fpdfdoc/include/cpdf_filespec.h" #include "core/fpdfdoc/include/cpdf_formcontrol.h" #include "core/fpdfdoc/include/cpdf_interform.h" -#include "core/fpdfdoc/doc_utils.h" +#include "core/fxge/include/fx_font.h" #include "third_party/base/stl_util.h" namespace { @@ -32,8 +33,8 @@ const struct SupportFieldEncoding { {"UHC", 949}, }; -CFX_WideString FPDFDOC_FDF_GetFieldValue(const CPDF_Dictionary& pFieldDict, - const CFX_ByteString& bsEncoding) { +CFX_WideString GetFieldValue(const CPDF_Dictionary& pFieldDict, + const CFX_ByteString& bsEncoding) { const CFX_ByteString csBValue = pFieldDict.GetStringBy("V"); for (const auto& encoding : g_fieldEncoding) { if (bsEncoding == encoding.m_name) @@ -46,7 +47,419 @@ CFX_WideString FPDFDOC_FDF_GetFieldValue(const CPDF_Dictionary& pFieldDict, return CFX_WideString::FromLocal(csBValue.AsStringC()); } -} // namespace +void AddFont(CPDF_Dictionary*& pFormDict, + CPDF_Document* pDocument, + const CPDF_Font* pFont, + CFX_ByteString& csNameTag); + +void InitDict(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument) { + if (!pDocument) + return; + + if (!pFormDict) { + pFormDict = new CPDF_Dictionary; + uint32_t dwObjNum = pDocument->AddIndirectObject(pFormDict); + CPDF_Dictionary* pRoot = pDocument->GetRoot(); + pRoot->SetAtReference("AcroForm", pDocument, dwObjNum); + } + + CFX_ByteString csDA; + if (!pFormDict->KeyExist("DR")) { + CFX_ByteString csBaseName; + CFX_ByteString csDefault; + uint8_t charSet = CPDF_InterForm::GetNativeCharSet(); + CPDF_Font* pFont = CPDF_InterForm::AddStandardFont(pDocument, "Helvetica"); + if (pFont) { + AddFont(pFormDict, pDocument, pFont, csBaseName); + csDefault = csBaseName; + } + if (charSet != FXFONT_ANSI_CHARSET) { + CFX_ByteString csFontName = + CPDF_InterForm::GetNativeFont(charSet, nullptr); + if (!pFont || csFontName != "Helvetica") { + pFont = CPDF_InterForm::AddNativeFont(pDocument); + if (pFont) { + csBaseName = ""; + AddFont(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); +} + +uint32_t CountFonts(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; + + uint32_t 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* GetFont(CPDF_Dictionary* pFormDict, + CPDF_Document* pDocument, + uint32_t index, + CFX_ByteString& csNameTag) { + if (!pFormDict) + return nullptr; + + CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR"); + if (!pDR) + return nullptr; + + CPDF_Dictionary* pFonts = pDR->GetDictBy("Font"); + if (!pFonts) + return nullptr; + + uint32_t 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 nullptr; +} + +CPDF_Font* GetFont(CPDF_Dictionary* pFormDict, + CPDF_Document* pDocument, + CFX_ByteString csNameTag) { + CFX_ByteString csAlias = PDF_NameDecode(csNameTag); + if (!pFormDict || csAlias.IsEmpty()) + return nullptr; + + CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR"); + if (!pDR) + return nullptr; + + CPDF_Dictionary* pFonts = pDR->GetDictBy("Font"); + if (!pFonts) + return nullptr; + + CPDF_Dictionary* pElement = pFonts->GetDictBy(csAlias); + if (!pElement) + return nullptr; + + if (pElement->GetStringBy("Type") == "Font") + return pDocument->LoadFont(pElement); + return nullptr; +} + +CPDF_Font* GetFont(CPDF_Dictionary* pFormDict, + CPDF_Document* pDocument, + CFX_ByteString csFontName, + CFX_ByteString& csNameTag) { + if (!pFormDict || csFontName.IsEmpty()) + return nullptr; + + CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR"); + if (!pDR) + return nullptr; + + CPDF_Dictionary* pFonts = pDR->GetDictBy("Font"); + if (!pFonts) + return nullptr; + + 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 nullptr; +} + +CPDF_Font* GetNativeFont(CPDF_Dictionary* pFormDict, + CPDF_Document* pDocument, + uint8_t charSet, + CFX_ByteString& csNameTag) { + if (!pFormDict) + return nullptr; + + CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR"); + if (!pDR) + return nullptr; + + CPDF_Dictionary* pFonts = pDR->GetDictBy("Font"); + if (!pFonts) + return nullptr; + + 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 = pFind->GetSubstFont(); + if (!pSubst) + continue; + + if (pSubst->m_Charset == (int)charSet) { + csNameTag = csKey; + return pFind; + } + } + return nullptr; +} + +CPDF_Font* GetDefaultFont(CPDF_Dictionary* pFormDict, + CPDF_Document* pDocument) { + if (!pFormDict) + return nullptr; + + CPDF_DefaultAppearance cDA(pFormDict->GetStringBy("DA")); + CFX_ByteString csFontNameTag; + FX_FLOAT fFontSize; + cDA.GetFont(csFontNameTag, fFontSize); + return GetFont(pFormDict, pDocument, csFontNameTag); +} + +FX_BOOL FindFont(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; +} + +CPDF_Font* GetNativeFont(CPDF_Dictionary* pFormDict, + CPDF_Document* pDocument, + CFX_ByteString& csNameTag) { + csNameTag.clear(); + uint8_t charSet = CPDF_InterForm::GetNativeCharSet(); + CPDF_Font* pFont = GetDefaultFont(pFormDict, pDocument); + if (pFont) { + CFX_SubstFont* pSubst = pFont->GetSubstFont(); + if (pSubst && pSubst->m_Charset == (int)charSet) { + FindFont(pFormDict, pFont, csNameTag); + return pFont; + } + } + return GetNativeFont(pFormDict, pDocument, charSet, csNameTag); +} + +FX_BOOL FindFont(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 AddFont(CPDF_Dictionary*& pFormDict, + CPDF_Document* pDocument, + const CPDF_Font* pFont, + CFX_ByteString& csNameTag) { + if (!pFont) + return; + if (!pFormDict) + InitDict(pFormDict, pDocument); + + CFX_ByteString csTag; + if (FindFont(pFormDict, pFont, csTag)) { + csNameTag = csTag; + return; + } + if (!pFormDict) + InitDict(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.c_str()); + pFonts->SetAtReference(csNameTag, pDocument, pFont->GetFontDict()); +} + +CPDF_Font* AddNativeFont(CPDF_Dictionary*& pFormDict, + CPDF_Document* pDocument, + uint8_t charSet, + CFX_ByteString& csNameTag) { + if (!pFormDict) + InitDict(pFormDict, pDocument); + + CFX_ByteString csTemp; + CPDF_Font* pFont = GetNativeFont(pFormDict, pDocument, charSet, csTemp); + if (pFont) { + csNameTag = csTemp; + return pFont; + } + CFX_ByteString csFontName = CPDF_InterForm::GetNativeFont(charSet); + if (!csFontName.IsEmpty() && + FindFont(pFormDict, pDocument, csFontName, pFont, csNameTag)) { + return pFont; + } + pFont = CPDF_InterForm::AddNativeFont(charSet, pDocument); + if (pFont) + AddFont(pFormDict, pDocument, pFont, csNameTag); + + return pFont; +} + +void RemoveFont(CPDF_Dictionary* pFormDict, const CPDF_Font* pFont) { + if (!pFormDict || !pFont) + return; + + CFX_ByteString csTag; + if (!FindFont(pFormDict, pFont, csTag)) + return; + + CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR"); + CPDF_Dictionary* pFonts = pDR->GetDictBy("Font"); + pFonts->RemoveAt(csTag); +} + +void RemoveFont(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); +} class CFieldNameExtractor { public: @@ -58,13 +471,12 @@ class CFieldNameExtractor { void GetNext(const FX_WCHAR*& pSubName, FX_STRSIZE& size) { pSubName = m_pCur; - while (m_pCur < m_pEnd && m_pCur[0] != L'.') { + while (m_pCur < m_pEnd && m_pCur[0] != L'.') m_pCur++; - } + size = (FX_STRSIZE)(m_pCur - pSubName); - if (m_pCur < m_pEnd && m_pCur[0] == L'.') { + if (m_pCur < m_pEnd && m_pCur[0] == L'.') m_pCur++; - } } protected: @@ -73,31 +485,79 @@ class CFieldNameExtractor { const FX_WCHAR* m_pEnd; }; +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ +typedef struct { + FX_BOOL bFind; + LOGFONTA lf; +} PDF_FONTDATA; + +static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXA* lpelfe, + NEWTEXTMETRICEX* lpntme, + DWORD FontType, + LPARAM lParam) { + if (FontType != 0x004 || strchr(lpelfe->elfLogFont.lfFaceName, '@')) + return 1; + + PDF_FONTDATA* pData = (PDF_FONTDATA*)lParam; + memcpy(&pData->lf, &lpelfe->elfLogFont, sizeof(LOGFONTA)); + pData->bFind = TRUE; + return 0; +} + +FX_BOOL RetrieveSpecificFont(LOGFONTA& lf) { + PDF_FONTDATA fd; + memset(&fd, 0, sizeof(PDF_FONTDATA)); + HDC hDC = ::GetDC(nullptr); + EnumFontFamiliesExA(hDC, &lf, (FONTENUMPROCA)EnumFontFamExProc, (LPARAM)&fd, + 0); + ::ReleaseDC(nullptr, hDC); + if (fd.bFind) + memcpy(&lf, &fd.lf, sizeof(LOGFONTA)); + + return fd.bFind; +} + +FX_BOOL RetrieveSpecificFont(uint8_t charSet, + uint8_t pitchAndFamily, + LPCSTR pcsFontName, + LOGFONTA& lf) { + memset(&lf, 0, sizeof(LOGFONTA)); + lf.lfCharSet = charSet; + lf.lfPitchAndFamily = pitchAndFamily; + if (pcsFontName) { + // TODO(dsinclair): Should this be strncpy? + strcpy(lf.lfFaceName, pcsFontName); + } + return RetrieveSpecificFont(lf); +} +#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + +} // namespace + class CFieldTree { public: - struct _Node { - _Node* parent; - CFX_ArrayTemplate<_Node*> children; + struct Node { + Node* parent; + CFX_ArrayTemplate<Node*> children; CFX_WideString short_name; CPDF_FormField* field_ptr; int CountFields(int nLevel = 0) { - if (nLevel > nMaxRecursion) { + if (nLevel > nMaxRecursion) return 0; - } - if (field_ptr) { + if (field_ptr) return 1; - } + int count = 0; - for (int i = 0; i < children.GetSize(); i++) { + for (int i = 0; i < children.GetSize(); i++) count += children.GetAt(i)->CountFields(nLevel + 1); - } return count; } + CPDF_FormField* GetField(int* fields_to_go) { if (field_ptr) { - if (*fields_to_go == 0) { + if (*fields_to_go == 0) return field_ptr; - } + --*fields_to_go; return nullptr; } @@ -107,63 +567,72 @@ class CFieldTree { } return nullptr; } + CPDF_FormField* GetField(int index) { int fields_to_go = index; return GetField(&fields_to_go); } }; + CFieldTree(); ~CFieldTree(); + void SetField(const CFX_WideString& full_name, CPDF_FormField* field_ptr); CPDF_FormField* GetField(const CFX_WideString& full_name); CPDF_FormField* RemoveField(const CFX_WideString& full_name); void RemoveAll(); - _Node* FindNode(const CFX_WideString& full_name); - _Node* AddChild(_Node* pParent, - const CFX_WideString& short_name, - CPDF_FormField* field_ptr); - void RemoveNode(_Node* pNode, int nLevel = 0); - _Node* _Lookup(_Node* pParent, const CFX_WideString& short_name); - _Node m_Root; + + Node* FindNode(const CFX_WideString& full_name); + Node* AddChild(Node* pParent, + const CFX_WideString& short_name, + CPDF_FormField* field_ptr); + void RemoveNode(Node* pNode, int nLevel = 0); + + Node* Lookup(Node* pParent, const CFX_WideString& short_name); + + Node m_Root; }; + CFieldTree::CFieldTree() { m_Root.parent = nullptr; m_Root.field_ptr = nullptr; } + CFieldTree::~CFieldTree() { RemoveAll(); } -CFieldTree::_Node* CFieldTree::AddChild(_Node* pParent, - const CFX_WideString& short_name, - CPDF_FormField* field_ptr) { - if (!pParent) { + +CFieldTree::Node* CFieldTree::AddChild(Node* pParent, + const CFX_WideString& short_name, + CPDF_FormField* field_ptr) { + if (!pParent) return nullptr; - } - _Node* pNode = new _Node; + + Node* pNode = new Node; pNode->parent = pParent; pNode->short_name = short_name; pNode->field_ptr = field_ptr; pParent->children.Add(pNode); return pNode; } -void CFieldTree::RemoveNode(_Node* pNode, int nLevel) { - if (!pNode) { + +void CFieldTree::RemoveNode(Node* pNode, int nLevel) { + if (!pNode) return; - } if (nLevel <= nMaxRecursion) { - for (int i = 0; i < pNode->children.GetSize(); i++) { + for (int i = 0; i < pNode->children.GetSize(); i++) RemoveNode(pNode->children[i], nLevel + 1); - } } delete pNode; } -CFieldTree::_Node* CFieldTree::_Lookup(_Node* pParent, - const CFX_WideString& short_name) { - if (!pParent) { + +CFieldTree::Node* CFieldTree::Lookup(Node* pParent, + const CFX_WideString& short_name) { + if (!pParent) return nullptr; - } + for (int i = 0; i < pParent->children.GetSize(); i++) { - _Node* pNode = pParent->children[i]; + Node* pNode = pParent->children[i]; if (pNode->short_name.GetLength() == short_name.GetLength() && FXSYS_memcmp(pNode->short_name.c_str(), short_name.c_str(), short_name.GetLength() * sizeof(FX_WCHAR)) == 0) { @@ -172,67 +641,72 @@ CFieldTree::_Node* CFieldTree::_Lookup(_Node* pParent, } return nullptr; } + void CFieldTree::RemoveAll() { - for (int i = 0; i < m_Root.children.GetSize(); i++) { + for (int i = 0; i < m_Root.children.GetSize(); i++) RemoveNode(m_Root.children[i]); - } } + void CFieldTree::SetField(const CFX_WideString& full_name, CPDF_FormField* field_ptr) { - if (full_name == L"") { + if (full_name == L"") return; - } + CFieldNameExtractor name_extractor(full_name); const FX_WCHAR* pName; FX_STRSIZE nLength; name_extractor.GetNext(pName, nLength); - _Node *pNode = &m_Root, *pLast = nullptr; + Node* pNode = &m_Root; + Node* pLast = nullptr; while (nLength > 0) { pLast = pNode; CFX_WideString name = CFX_WideString(pName, nLength); - pNode = _Lookup(pLast, name); - if (!pNode) { + pNode = Lookup(pLast, name); + if (!pNode) pNode = AddChild(pLast, name, nullptr); - } + name_extractor.GetNext(pName, nLength); } - if (pNode != &m_Root) { + if (pNode != &m_Root) pNode->field_ptr = field_ptr; - } } + CPDF_FormField* CFieldTree::GetField(const CFX_WideString& full_name) { - if (full_name == L"") { + if (full_name == L"") return nullptr; - } + CFieldNameExtractor name_extractor(full_name); const FX_WCHAR* pName; FX_STRSIZE nLength; name_extractor.GetNext(pName, nLength); - _Node *pNode = &m_Root, *pLast = nullptr; + Node* pNode = &m_Root; + Node* pLast = nullptr; while (nLength > 0 && pNode) { pLast = pNode; CFX_WideString name = CFX_WideString(pName, nLength); - pNode = _Lookup(pLast, name); + pNode = Lookup(pLast, name); name_extractor.GetNext(pName, nLength); } return pNode ? pNode->field_ptr : nullptr; } + CPDF_FormField* CFieldTree::RemoveField(const CFX_WideString& full_name) { - if (full_name == L"") { + if (full_name == L"") return nullptr; - } + CFieldNameExtractor name_extractor(full_name); const FX_WCHAR* pName; FX_STRSIZE nLength; name_extractor.GetNext(pName, nLength); - _Node* pNode = &m_Root; - _Node* pLast = nullptr; + Node* pNode = &m_Root; + Node* pLast = nullptr; while (nLength > 0 && pNode) { pLast = pNode; CFX_WideString name = CFX_WideString(pName, nLength); - pNode = _Lookup(pLast, name); + pNode = Lookup(pLast, name); name_extractor.GetNext(pName, nLength); } + if (pNode && pNode != &m_Root) { for (int i = 0; i < pLast->children.GetSize(); i++) { if (pNode == pLast->children[i]) { @@ -246,24 +720,94 @@ CPDF_FormField* CFieldTree::RemoveField(const CFX_WideString& full_name) { } return nullptr; } -CFieldTree::_Node* CFieldTree::FindNode(const CFX_WideString& full_name) { - if (full_name == L"") { + +CFieldTree::Node* CFieldTree::FindNode(const CFX_WideString& full_name) { + if (full_name == L"") return nullptr; - } + CFieldNameExtractor name_extractor(full_name); const FX_WCHAR* pName; FX_STRSIZE nLength; name_extractor.GetNext(pName, nLength); - _Node *pNode = &m_Root, *pLast = nullptr; + Node* pNode = &m_Root; + Node* pLast = nullptr; while (nLength > 0 && pNode) { pLast = pNode; CFX_WideString name = CFX_WideString(pName, nLength); - pNode = _Lookup(pLast, name); + pNode = Lookup(pLast, name); name_extractor.GetNext(pName, nLength); } return pNode; } +CPDF_Font* AddNativeInterFormFont(CPDF_Dictionary*& pFormDict, + CPDF_Document* pDocument, + CFX_ByteString& csNameTag) { + uint8_t charSet = CPDF_InterForm::GetNativeCharSet(); + return AddNativeFont(pFormDict, pDocument, charSet, csNameTag); +} + +// static +uint8_t CPDF_InterForm::GetNativeCharSet() { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + uint8_t charSet = ANSI_CHARSET; + UINT iCodePage = ::GetACP(); + switch (iCodePage) { + case 932: + charSet = SHIFTJIS_CHARSET; + break; + case 936: + charSet = GB2312_CHARSET; + break; + case 950: + charSet = CHINESEBIG5_CHARSET; + break; + case 1252: + charSet = ANSI_CHARSET; + break; + case 874: + charSet = THAI_CHARSET; + break; + case 949: + charSet = HANGUL_CHARSET; + break; + case 1200: + charSet = ANSI_CHARSET; + break; + case 1250: + charSet = EASTEUROPE_CHARSET; + break; + case 1251: + charSet = RUSSIAN_CHARSET; + break; + case 1253: + charSet = GREEK_CHARSET; + break; + case 1254: + charSet = TURKISH_CHARSET; + break; + case 1255: + charSet = HEBREW_CHARSET; + break; + case 1256: + charSet = ARABIC_CHARSET; + break; + case 1257: + charSet = BALTIC_CHARSET; + break; + case 1258: + charSet = VIETNAMESE_CHARSET; + break; + case 1361: + charSet = JOHAB_CHARSET; + break; + } + return charSet; +#else + return 0; +#endif +} + CPDF_InterForm::CPDF_InterForm(CPDF_Document* pDocument) : m_pDocument(pDocument), m_pFormDict(nullptr), @@ -290,9 +834,8 @@ CPDF_InterForm::~CPDF_InterForm() { delete it.second; int nCount = m_pFieldTree->m_Root.CountFields(); - for (int i = 0; i < nCount; ++i) { + for (int i = 0; i < nCount; ++i) delete m_pFieldTree->m_Root.GetField(i); - } } FX_BOOL CPDF_InterForm::s_bUpdateAP = TRUE; @@ -313,24 +856,22 @@ CFX_ByteString CPDF_InterForm::GenerateNewResourceName( CFX_ByteString csStr = csPrefix; CFX_ByteString csBType = csType; if (csStr.IsEmpty()) { - if (csBType == "ExtGState") { + if (csBType == "ExtGState") csStr = "GS"; - } else if (csBType == "ColorSpace") { + else if (csBType == "ColorSpace") csStr = "CS"; - } else if (csBType == "Font") { + else if (csBType == "Font") csStr = "ZiTi"; - } else { + else csStr = "Res"; - } } CFX_ByteString csTmp = csStr; int iCount = csStr.GetLength(); int m = 0; if (iMinLen > 0) { csTmp = ""; - while (m < iMinLen && m < iCount) { + while (m < iMinLen && m < iCount) csTmp += csStr[m++]; - } while (m < iMinLen) { csTmp += '0' + m % 10; m++; @@ -338,72 +879,28 @@ CFX_ByteString CPDF_InterForm::GenerateNewResourceName( } else { m = iCount; } - if (!pResDict) { + if (!pResDict) return csTmp; - } + CPDF_Dictionary* pDict = pResDict->GetDictBy(csType); - if (!pDict) { + if (!pDict) return csTmp; - } + int num = 0; CFX_ByteString bsNum; while (TRUE) { CFX_ByteString csKey = csTmp + bsNum; - if (!pDict->KeyExist(csKey)) { + if (!pDict->KeyExist(csKey)) return csKey; - } - if (m < iCount) { + if (m < iCount) csTmp += csStr[m++]; - } else { + else bsNum.Format("%d", num++); - } + m++; } return csTmp; } -#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ -typedef struct PDF_FONTDATA_ { - FX_BOOL bFind; - LOGFONTA lf; -} PDF_FONTDATA, FAR* LPDF_FONTDATA; -static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXA* lpelfe, - NEWTEXTMETRICEX* lpntme, - DWORD FontType, - LPARAM lParam) { - if (FontType != 0x004 || strchr(lpelfe->elfLogFont.lfFaceName, '@')) { - return 1; - } - LPDF_FONTDATA pData = (LPDF_FONTDATA)lParam; - memcpy(&pData->lf, &lpelfe->elfLogFont, sizeof(LOGFONTA)); - pData->bFind = TRUE; - return 0; -} -static FX_BOOL RetrieveSpecificFont(LOGFONTA& lf) { - PDF_FONTDATA fd; - memset(&fd, 0, sizeof(PDF_FONTDATA)); - HDC hDC = ::GetDC(nullptr); - EnumFontFamiliesExA(hDC, &lf, (FONTENUMPROCA)EnumFontFamExProc, (LPARAM)&fd, - 0); - ::ReleaseDC(nullptr, hDC); - if (fd.bFind) { - memcpy(&lf, &fd.lf, sizeof(LOGFONTA)); - } - return fd.bFind; -} -static FX_BOOL RetrieveSpecificFont(uint8_t charSet, - uint8_t pitchAndFamily, - LPCSTR pcsFontName, - LOGFONTA& lf) { - memset(&lf, 0, sizeof(LOGFONTA)); - lf.lfCharSet = charSet; - lf.lfPitchAndFamily = pitchAndFamily; - if (pcsFontName) { - // TODO(dsinclair): Should this be strncpy? - strcpy(lf.lfFaceName, pcsFontName); - } - return RetrieveSpecificFont(lf); -} -#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ CPDF_Font* CPDF_InterForm::AddStandardFont(CPDF_Document* pDocument, CFX_ByteString csFontName) { @@ -449,9 +946,9 @@ CFX_ByteString CPDF_InterForm::GetNativeFont(uint8_t charSet, void* pLogFont) { RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, nullptr, lf); } if (bRet) { - if (pLogFont) { + if (pLogFont) memcpy(pLogFont, &lf, sizeof(LOGFONTA)); - } + csFontName = lf.lfFaceName; return csFontName; } @@ -467,67 +964,6 @@ CFX_ByteString CPDF_InterForm::GetNativeFont(void* pLogFont) { #endif } -// static -uint8_t CPDF_InterForm::GetNativeCharSet() { -#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ - uint8_t charSet = ANSI_CHARSET; - UINT iCodePage = ::GetACP(); - switch (iCodePage) { - case 932: - charSet = SHIFTJIS_CHARSET; - break; - case 936: - charSet = GB2312_CHARSET; - break; - case 950: - charSet = CHINESEBIG5_CHARSET; - break; - case 1252: - charSet = ANSI_CHARSET; - break; - case 874: - charSet = THAI_CHARSET; - break; - case 949: - charSet = HANGUL_CHARSET; - break; - case 1200: - charSet = ANSI_CHARSET; - break; - case 1250: - charSet = EASTEUROPE_CHARSET; - break; - case 1251: - charSet = RUSSIAN_CHARSET; - break; - case 1253: - charSet = GREEK_CHARSET; - break; - case 1254: - charSet = TURKISH_CHARSET; - break; - case 1255: - charSet = HEBREW_CHARSET; - break; - case 1256: - charSet = ARABIC_CHARSET; - break; - case 1257: - charSet = BALTIC_CHARSET; - break; - case 1258: - charSet = VIETNAMESE_CHARSET; - break; - case 1361: - charSet = JOHAB_CHARSET; - break; - } - return charSet; -#else - return 0; -#endif -} - CPDF_Font* CPDF_InterForm::AddNativeFont(uint8_t charSet, CPDF_Document* pDocument) { if (!pDocument) @@ -554,9 +990,9 @@ FX_BOOL CPDF_InterForm::ValidateFieldName( int iType, const CPDF_FormField* pExcludedField, const CPDF_FormControl* pExcludedControl) { - if (csNewFieldName.IsEmpty()) { + if (csNewFieldName.IsEmpty()) return FALSE; - } + int iPos = 0; int iLength = csNewFieldName.GetLength(); CFX_WideString csSub; @@ -565,30 +1001,25 @@ FX_BOOL CPDF_InterForm::ValidateFieldName( (csNewFieldName[iPos] == L'.' || csNewFieldName[iPos] == L' ')) { iPos++; } - if (iPos < iLength && !csSub.IsEmpty()) { + if (iPos < iLength && !csSub.IsEmpty()) csSub += L'.'; - } - while (iPos < iLength && csNewFieldName[iPos] != L'.') { + while (iPos < iLength && csNewFieldName[iPos] != L'.') csSub += csNewFieldName[iPos++]; - } for (int i = csSub.GetLength() - 1; i > -1; i--) { - if (csSub[i] == L' ' || csSub[i] == L'.') { + if (csSub[i] == L' ' || csSub[i] == L'.') csSub.SetAt(i, L'\0'); - } else { + else break; - } } uint32_t dwCount = m_pFieldTree->m_Root.CountFields(); for (uint32_t m = 0; m < dwCount; m++) { CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(m); - if (!pField) { + if (!pField) continue; - } if (pField == pExcludedField) { if (pExcludedControl) { - if (pField->CountControls() < 2) { + if (pField->CountControls() < 2) continue; - } } else { continue; } @@ -596,108 +1027,105 @@ FX_BOOL CPDF_InterForm::ValidateFieldName( CFX_WideString csFullName = pField->GetFullName(); int iRet = CompareFieldName(csSub, csFullName); if (iRet == 1) { - if (pField->GetFieldType() != iType) { + if (pField->GetFieldType() != iType) return FALSE; - } } else if (iRet == 2 && csSub == csNewFieldName) { - if (csFullName[iPos] == L'.') { + if (csFullName[iPos] == L'.') return FALSE; - } } else if (iRet == 3 && csSub == csNewFieldName) { - if (csNewFieldName[csFullName.GetLength()] == L'.') { + if (csNewFieldName[csFullName.GetLength()] == L'.') return FALSE; - } } } - if (iPos >= iLength) { + if (iPos >= iLength) break; - } } - if (csSub.IsEmpty()) { + if (csSub.IsEmpty()) return FALSE; - } + csNewFieldName = csSub; return TRUE; } + FX_BOOL CPDF_InterForm::ValidateFieldName(CFX_WideString& csNewFieldName, int iType) { return ValidateFieldName(csNewFieldName, iType, nullptr, nullptr); } + FX_BOOL CPDF_InterForm::ValidateFieldName(const CPDF_FormField* pField, CFX_WideString& csNewFieldName) { return pField && !csNewFieldName.IsEmpty() && ValidateFieldName(csNewFieldName, pField->GetFieldType(), pField, nullptr); } + FX_BOOL CPDF_InterForm::ValidateFieldName(const CPDF_FormControl* pControl, CFX_WideString& csNewFieldName) { - if (!pControl || csNewFieldName.IsEmpty()) { + if (!pControl || csNewFieldName.IsEmpty()) return FALSE; - } + CPDF_FormField* pField = pControl->GetField(); return ValidateFieldName(csNewFieldName, pField->GetFieldType(), pField, pControl); } + int CPDF_InterForm::CompareFieldName(const CFX_ByteString& name1, const CFX_ByteString& name2) { - if (name1.GetLength() == name2.GetLength()) { + if (name1.GetLength() == name2.GetLength()) return name1 == name2 ? 1 : 0; - } + const FX_CHAR* ptr1 = name1.c_str(); const FX_CHAR* ptr2 = name2.c_str(); int i = 0; - while (ptr1[i] == ptr2[i]) { + while (ptr1[i] == ptr2[i]) i++; - } - if (i == name1.GetLength()) { + if (i == name1.GetLength()) return 2; - } - if (i == name2.GetLength()) { + if (i == name2.GetLength()) return 3; - } return 0; } + int CPDF_InterForm::CompareFieldName(const CFX_WideString& name1, const CFX_WideString& name2) { const FX_WCHAR* ptr1 = name1.c_str(); const FX_WCHAR* ptr2 = name2.c_str(); - if (name1.GetLength() == name2.GetLength()) { + if (name1.GetLength() == name2.GetLength()) return name1 == name2 ? 1 : 0; - } + int i = 0; - while (ptr1[i] == ptr2[i]) { + while (ptr1[i] == ptr2[i]) i++; - } - if (i == name1.GetLength()) { + if (i == name1.GetLength()) return 2; - } - if (i == name2.GetLength()) { + if (i == name2.GetLength()) return 3; - } return 0; } + uint32_t CPDF_InterForm::CountFields(const CFX_WideString& csFieldName) { - if (csFieldName.IsEmpty()) { + if (csFieldName.IsEmpty()) return (uint32_t)m_pFieldTree->m_Root.CountFields(); - } - CFieldTree::_Node* pNode = m_pFieldTree->FindNode(csFieldName); + + CFieldTree::Node* pNode = m_pFieldTree->FindNode(csFieldName); return pNode ? pNode->CountFields() : 0; } + CPDF_FormField* CPDF_InterForm::GetField(uint32_t index, const CFX_WideString& csFieldName) { - if (csFieldName == L"") { + if (csFieldName == L"") return m_pFieldTree->m_Root.GetField(index); - } - CFieldTree::_Node* pNode = m_pFieldTree->FindNode(csFieldName); + + CFieldTree::Node* pNode = m_pFieldTree->FindNode(csFieldName); return pNode ? pNode->GetField(index) : nullptr; } CPDF_FormField* CPDF_InterForm::GetFieldByDict( CPDF_Dictionary* pFieldDict) const { - if (!pFieldDict) { + if (!pFieldDict) return nullptr; - } - CFX_WideString csWName = GetFullName(pFieldDict); + + CFX_WideString csWName = FPDF_GetFullName(pFieldDict); return m_pFieldTree->GetField(csWName); } @@ -771,53 +1199,58 @@ int CPDF_InterForm::FindFieldInCalculationOrder(const CPDF_FormField* pField) { for (size_t i = 0; i < pArray->GetCount(); i++) { CPDF_Object* pElement = pArray->GetDirectObjectAt(i); - if (pElement == pField->m_pDict) { + if (pElement == pField->m_pDict) return i; - } } return -1; } uint32_t CPDF_InterForm::CountFormFonts() { - return CountInterFormFonts(m_pFormDict); + return CountFonts(m_pFormDict); } CPDF_Font* CPDF_InterForm::GetFormFont(uint32_t index, CFX_ByteString& csNameTag) { - return GetInterFormFont(m_pFormDict, m_pDocument, index, csNameTag); + return GetFont(m_pFormDict, m_pDocument, index, csNameTag); } + CPDF_Font* CPDF_InterForm::GetFormFont(CFX_ByteString csNameTag) { - return GetInterFormFont(m_pFormDict, m_pDocument, csNameTag); + return GetFont(m_pFormDict, m_pDocument, csNameTag); } + CPDF_Font* CPDF_InterForm::GetFormFont(CFX_ByteString csFontName, CFX_ByteString& csNameTag) { - return GetInterFormFont(m_pFormDict, m_pDocument, csFontName, csNameTag); + return GetFont(m_pFormDict, m_pDocument, csFontName, csNameTag); } + CPDF_Font* CPDF_InterForm::GetNativeFormFont(uint8_t charSet, CFX_ByteString& csNameTag) { - return GetNativeInterFormFont(m_pFormDict, m_pDocument, charSet, csNameTag); + return ::GetNativeFont(m_pFormDict, m_pDocument, charSet, csNameTag); } + CPDF_Font* CPDF_InterForm::GetNativeFormFont(CFX_ByteString& csNameTag) { - return GetNativeInterFormFont(m_pFormDict, m_pDocument, csNameTag); + return ::GetNativeFont(m_pFormDict, m_pDocument, csNameTag); } + FX_BOOL CPDF_InterForm::FindFormFont(const CPDF_Font* pFont, CFX_ByteString& csNameTag) { - return FindInterFormFont(m_pFormDict, pFont, csNameTag); + return FindFont(m_pFormDict, pFont, csNameTag); } + FX_BOOL CPDF_InterForm::FindFormFont(CFX_ByteString csFontName, CPDF_Font*& pFont, CFX_ByteString& csNameTag) { - return FindInterFormFont(m_pFormDict, m_pDocument, csFontName, pFont, - csNameTag); + return FindFont(m_pFormDict, m_pDocument, csFontName, pFont, csNameTag); } + void CPDF_InterForm::AddFormFont(const CPDF_Font* pFont, CFX_ByteString& csNameTag) { - AddInterFormFont(m_pFormDict, m_pDocument, pFont, csNameTag); + AddFont(m_pFormDict, m_pDocument, pFont, csNameTag); } CPDF_Font* CPDF_InterForm::AddNativeFormFont(uint8_t charSet, CFX_ByteString& csNameTag) { - return AddNativeInterFormFont(m_pFormDict, m_pDocument, charSet, csNameTag); + return ::AddNativeFont(m_pFormDict, m_pDocument, charSet, csNameTag); } CPDF_Font* CPDF_InterForm::AddNativeFormFont(CFX_ByteString& csNameTag) { @@ -825,11 +1258,11 @@ CPDF_Font* CPDF_InterForm::AddNativeFormFont(CFX_ByteString& csNameTag) { } void CPDF_InterForm::RemoveFormFont(const CPDF_Font* pFont) { - RemoveInterFormFont(m_pFormDict, pFont); + RemoveFont(m_pFormDict, pFont); } void CPDF_InterForm::RemoveFormFont(CFX_ByteString csNameTag) { - RemoveInterFormFont(m_pFormDict, csNameTag); + RemoveFont(m_pFormDict, csNameTag); } CPDF_DefaultAppearance CPDF_InterForm::GetDefaultAppearance() { @@ -839,8 +1272,9 @@ CPDF_DefaultAppearance CPDF_InterForm::GetDefaultAppearance() { } CPDF_Font* CPDF_InterForm::GetDefaultFormFont() { - return GetDefaultInterFormFont(m_pFormDict, m_pDocument); + return GetDefaultFont(m_pFormDict, m_pDocument); } + int CPDF_InterForm::GetFormAlignment() { return m_pFormDict ? m_pFormDict->GetIntegerBy("Q", 0) : 0; } @@ -883,63 +1317,64 @@ bool CPDF_InterForm::ResetForm(bool bNotify) { } void CPDF_InterForm::LoadField(CPDF_Dictionary* pFieldDict, int nLevel) { - if (nLevel > nMaxRecursion) { + if (nLevel > nMaxRecursion) return; - } - if (!pFieldDict) { + if (!pFieldDict) return; - } + uint32_t dwParentObjNum = pFieldDict->GetObjNum(); CPDF_Array* pKids = pFieldDict->GetArrayBy("Kids"); if (!pKids) { AddTerminalField(pFieldDict); return; } + CPDF_Dictionary* pFirstKid = pKids->GetDictAt(0); - if (!pFirstKid) { + if (!pFirstKid) return; - } + if (pFirstKid->KeyExist("T") || pFirstKid->KeyExist("Kids")) { for (size_t i = 0; i < pKids->GetCount(); i++) { CPDF_Dictionary* pChildDict = pKids->GetDictAt(i); if (pChildDict) { - if (pChildDict->GetObjNum() != dwParentObjNum) { + if (pChildDict->GetObjNum() != dwParentObjNum) LoadField(pChildDict, nLevel + 1); - } } } } else { AddTerminalField(pFieldDict); } } + FX_BOOL CPDF_InterForm::HasXFAForm() const { return m_pFormDict && m_pFormDict->GetArrayBy("XFA"); } + void CPDF_InterForm::FixPageFields(const CPDF_Page* pPage) { CPDF_Dictionary* pPageDict = pPage->m_pFormDict; - if (!pPageDict) { + if (!pPageDict) return; - } + CPDF_Array* pAnnots = pPageDict->GetArrayBy("Annots"); - if (!pAnnots) { + if (!pAnnots) return; - } + for (size_t i = 0; i < pAnnots->GetCount(); i++) { CPDF_Dictionary* pAnnot = pAnnots->GetDictAt(i); - if (pAnnot && pAnnot->GetStringBy("Subtype") == "Widget") { + if (pAnnot && pAnnot->GetStringBy("Subtype") == "Widget") LoadField(pAnnot); - } } } + CPDF_FormField* CPDF_InterForm::AddTerminalField(CPDF_Dictionary* pFieldDict) { - if (!pFieldDict->KeyExist("T")) { + if (!pFieldDict->KeyExist("T")) return nullptr; - } + CPDF_Dictionary* pDict = pFieldDict; - CFX_WideString csWName = GetFullName(pFieldDict); - if (csWName.IsEmpty()) { + CFX_WideString csWName = FPDF_GetFullName(pFieldDict); + if (csWName.IsEmpty()) return nullptr; - } + CPDF_FormField* pField = nullptr; pField = m_pFieldTree->GetField(csWName); if (!pField) { @@ -947,24 +1382,24 @@ CPDF_FormField* CPDF_InterForm::AddTerminalField(CPDF_Dictionary* pFieldDict) { if (!pFieldDict->KeyExist("T") && pFieldDict->GetStringBy("Subtype") == "Widget") { pParent = pFieldDict->GetDictBy("Parent"); - if (!pParent) { + if (!pParent) pParent = pFieldDict; - } } + if (pParent && pParent != pFieldDict && !pParent->KeyExist("FT")) { if (pFieldDict->KeyExist("FT")) { CPDF_Object* pFTValue = pFieldDict->GetDirectObjectBy("FT"); - if (pFTValue) { + if (pFTValue) pParent->SetAt("FT", pFTValue->Clone()); - } } + if (pFieldDict->KeyExist("Ff")) { CPDF_Object* pFfValue = pFieldDict->GetDirectObjectBy("Ff"); - if (pFfValue) { + if (pFfValue) pParent->SetAt("Ff", pFfValue->Clone()); - } } } + pField = new CPDF_FormField(this, pParent); CPDF_Object* pTObj = pDict->GetObjectBy("T"); if (ToReference(pTObj)) { @@ -976,25 +1411,25 @@ CPDF_FormField* CPDF_InterForm::AddTerminalField(CPDF_Dictionary* pFieldDict) { } m_pFieldTree->SetField(csWName, pField); } + CPDF_Array* pKids = pFieldDict->GetArrayBy("Kids"); if (!pKids) { - if (pFieldDict->GetStringBy("Subtype") == "Widget") { + if (pFieldDict->GetStringBy("Subtype") == "Widget") AddControl(pField, pFieldDict); - } } else { for (size_t i = 0; i < pKids->GetCount(); i++) { CPDF_Dictionary* pKid = pKids->GetDictAt(i); - if (!pKid) { + if (!pKid) continue; - } - if (pKid->GetStringBy("Subtype") != "Widget") { + if (pKid->GetStringBy("Subtype") != "Widget") continue; - } + AddControl(pField, pKid); } } return pField; } + CPDF_FormControl* CPDF_InterForm::AddControl(CPDF_FormField* pField, CPDF_Dictionary* pWidgetDict) { const auto it = m_ControlMap.find(pWidgetDict); @@ -1031,9 +1466,8 @@ CPDF_FormField* CPDF_InterForm::CheckRequiredFields( bFind = pdfium::ContainsValue(*fields, pField); if (bIncludeOrExclude == bFind) { CPDF_Dictionary* pFieldDict = pField->m_pDict; - if ((dwFlags & 0x02) != 0 && pFieldDict->GetStringBy("V").IsEmpty()) { + if ((dwFlags & 0x02) != 0 && pFieldDict->GetStringBy("V").IsEmpty()) return pField; - } } } return nullptr; @@ -1054,9 +1488,9 @@ CFDF_Document* CPDF_InterForm::ExportToFDF( bool bIncludeOrExclude, bool bSimpleFileSpec) const { CFDF_Document* pDoc = CFDF_Document::CreateNewDoc(); - if (!pDoc) { + if (!pDoc) return nullptr; - } + CPDF_Dictionary* pMainDict = pDoc->GetRoot()->GetDictBy("FDF"); if (!pdf_path.IsEmpty()) { if (bSimpleFileSpec) { @@ -1069,14 +1503,15 @@ CFDF_Document* CPDF_InterForm::ExportToFDF( pMainDict->SetAt("F", filespec.GetObj()); } } + CPDF_Array* pFields = new CPDF_Array; pMainDict->SetAt("Fields", pFields); int nCount = m_pFieldTree->m_Root.CountFields(); for (int i = 0; i < nCount; i++) { CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i); - if (!pField || pField->GetType() == CPDF_FormField::PushButton) { + if (!pField || pField->GetType() == CPDF_FormField::PushButton) continue; - } + uint32_t dwFlags = pField->GetFieldFlags(); if (dwFlags & 0x04) continue; @@ -1085,7 +1520,7 @@ CFDF_Document* CPDF_InterForm::ExportToFDF( if ((dwFlags & 0x02) != 0 && pField->m_pDict->GetStringBy("V").IsEmpty()) continue; - CFX_WideString fullname = GetFullName(pField->GetFieldDict()); + CFX_WideString fullname = FPDF_GetFullName(pField->GetFieldDict()); CPDF_Dictionary* pFieldDict = new CPDF_Dictionary; pFieldDict->SetAt("T", new CPDF_String(fullname)); if (pField->GetType() == CPDF_FormField::CheckBox || @@ -1113,44 +1548,41 @@ void CPDF_InterForm::FDF_ImportField(CPDF_Dictionary* pFieldDict, FX_BOOL bNotify, int nLevel) { CFX_WideString name; - if (!parent_name.IsEmpty()) { + if (!parent_name.IsEmpty()) name = parent_name + L"."; - } + name += pFieldDict->GetUnicodeTextBy("T"); CPDF_Array* pKids = pFieldDict->GetArrayBy("Kids"); if (pKids) { for (size_t i = 0; i < pKids->GetCount(); i++) { CPDF_Dictionary* pKid = pKids->GetDictAt(i); - if (!pKid) { + if (!pKid) continue; - } - if (nLevel <= nMaxRecursion) { + if (nLevel <= nMaxRecursion) FDF_ImportField(pKid, name, bNotify, nLevel + 1); - } } return; } - if (!pFieldDict->KeyExist("V")) { + if (!pFieldDict->KeyExist("V")) return; - } + CPDF_FormField* pField = m_pFieldTree->GetField(name); - if (!pField) { + if (!pField) return; - } - CFX_WideString csWValue = - FPDFDOC_FDF_GetFieldValue(*pFieldDict, m_bsEncoding); + + CFX_WideString csWValue = GetFieldValue(*pFieldDict, m_bsEncoding); int iType = pField->GetFieldType(); if (bNotify && m_pFormNotify) { int iRet = 0; - if (iType == FIELDTYPE_LISTBOX) { + if (iType == FIELDTYPE_LISTBOX) iRet = m_pFormNotify->BeforeSelectionChange(pField, csWValue); - } else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD) { + else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD) iRet = m_pFormNotify->BeforeValueChange(pField, csWValue); - } - if (iRet < 0) { + + if (iRet < 0) return; - } } + pField->SetValue(csWValue); CPDF_FormField::Type eType = pField->GetType(); if ((eType == CPDF_FormField::ListBox || eType == CPDF_FormField::ComboBox) && @@ -1158,14 +1590,14 @@ void CPDF_InterForm::FDF_ImportField(CPDF_Dictionary* pFieldDict, pField->m_pDict->SetAt("Opt", pFieldDict->GetDirectObjectBy("Opt")->Clone(TRUE)); } + if (bNotify && m_pFormNotify) { - if (iType == FIELDTYPE_CHECKBOX || iType == FIELDTYPE_RADIOBUTTON) { + if (iType == FIELDTYPE_CHECKBOX || iType == FIELDTYPE_RADIOBUTTON) m_pFormNotify->AfterCheckedStatusChange(pField); - } else if (iType == FIELDTYPE_LISTBOX) { + else if (iType == FIELDTYPE_LISTBOX) m_pFormNotify->AfterSelectionChange(pField); - } else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD) { + else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD) m_pFormNotify->AfterValueChange(pField); - } } } diff --git a/core/fpdfdoc/cpdf_numbertree.cpp b/core/fpdfdoc/cpdf_numbertree.cpp new file mode 100644 index 0000000000..9e2881f414 --- /dev/null +++ b/core/fpdfdoc/cpdf_numbertree.cpp @@ -0,0 +1,52 @@ +// Copyright 2016 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 "core/fpdfdoc/cpdf_numbertree.h" + +#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" + +namespace { + +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 nullptr; + } + CPDF_Array* pNumbers = pNode->GetArrayBy("Nums"); + if (pNumbers) { + for (size_t i = 0; i < pNumbers->GetCount() / 2; i++) { + int index = pNumbers->GetIntegerAt(i * 2); + if (num == index) + return pNumbers->GetDirectObjectAt(i * 2 + 1); + if (index > num) + break; + } + return nullptr; + } + + CPDF_Array* pKids = pNode->GetArrayBy("Kids"); + if (!pKids) + return nullptr; + + for (size_t 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 nullptr; +} + +} // namespace + +CPDF_Object* CPDF_NumberTree::LookupValue(int num) const { + return SearchNumberNode(m_pRoot, num); +} diff --git a/core/fpdfdoc/cpdf_numbertree.h b/core/fpdfdoc/cpdf_numbertree.h new file mode 100644 index 0000000000..bfe44fddb9 --- /dev/null +++ b/core/fpdfdoc/cpdf_numbertree.h @@ -0,0 +1,23 @@ +// Copyright 2016 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 + +#ifndef CORE_FPDFDOC_CPDF_NUMBERTREE_H_ +#define CORE_FPDFDOC_CPDF_NUMBERTREE_H_ + +class CPDF_Dictionary; +class CPDF_Object; + +class CPDF_NumberTree { + public: + explicit CPDF_NumberTree(CPDF_Dictionary* pRoot) : m_pRoot(pRoot) {} + + CPDF_Object* LookupValue(int num) const; + + protected: + CPDF_Dictionary* const m_pRoot; +}; + +#endif // CORE_FPDFDOC_CPDF_NUMBERTREE_H_ diff --git a/core/fpdfdoc/cpdf_pagelabel.cpp b/core/fpdfdoc/cpdf_pagelabel.cpp index 886e8448b2..4b888b9a61 100644 --- a/core/fpdfdoc/cpdf_pagelabel.cpp +++ b/core/fpdfdoc/cpdf_pagelabel.cpp @@ -9,7 +9,7 @@ #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" #include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h" -#include "core/fpdfdoc/doc_utils.h" +#include "core/fpdfdoc/cpdf_numbertree.h" namespace { diff --git a/core/fpdfdoc/cpvt_fontmap.cpp b/core/fpdfdoc/cpvt_fontmap.cpp index 35a56f811d..ea4aad96d3 100644 --- a/core/fpdfdoc/cpvt_fontmap.cpp +++ b/core/fpdfdoc/cpvt_fontmap.cpp @@ -9,7 +9,7 @@ #include "core/fpdfapi/fpdf_font/include/cpdf_font.h" #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" -#include "core/fpdfdoc/doc_utils.h" +#include "core/fpdfdoc/include/cpdf_interform.h" CPVT_FontMap::CPVT_FontMap(CPDF_Document* pDoc, CPDF_Dictionary* pResDict, diff --git a/core/fpdfdoc/doc_utils.cpp b/core/fpdfdoc/doc_utils.cpp deleted file mode 100644 index aaaaddf0c6..0000000000 --- a/core/fpdfdoc/doc_utils.cpp +++ /dev/null @@ -1,770 +0,0 @@ -// 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/fpdfapi/fpdf_font/include/cpdf_font.h" -#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" -#include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h" -#include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h" -#include "core/fpdfdoc/doc_utils.h" -#include "core/fpdfdoc/include/cpdf_defaultappearance.h" -#include "core/fpdfdoc/include/cpdf_formcontrol.h" -#include "core/fpdfdoc/include/cpdf_interform.h" -#include "core/fxge/include/fx_font.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 nullptr; - } - CPDF_Array* pNumbers = pNode->GetArrayBy("Nums"); - if (pNumbers) { - for (size_t i = 0; i < pNumbers->GetCount() / 2; i++) { - int index = pNumbers->GetIntegerAt(i * 2); - if (num == index) { - return pNumbers->GetDirectObjectAt(i * 2 + 1); - } - if (index > num) { - break; - } - } - return nullptr; - } - CPDF_Array* pKids = pNode->GetArrayBy("Kids"); - if (!pKids) { - return nullptr; - } - for (size_t 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 nullptr; -} - -} // 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.AsStringC()); - return syntax.FindTagParamFromStart("Tf", 2); -} -CFX_ByteString CPDF_DefaultAppearance::GetFontString() { - CFX_ByteString csFont; - if (m_csDA.IsEmpty()) { - return csFont; - } - CPDF_SimpleParser syntax(m_csDA.AsStringC()); - if (syntax.FindTagParamFromStart("Tf", 2)) { - csFont += syntax.GetWord(); - csFont += " "; - csFont += syntax.GetWord(); - csFont += " "; - csFont += 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.AsStringC()); - if (syntax.FindTagParamFromStart("Tf", 2)) { - csFontNameTag = CFX_ByteString(syntax.GetWord()); - csFontNameTag.Delete(0, 1); - fFontSize = FX_atof(syntax.GetWord()); - } - csFontNameTag = PDF_NameDecode(csFontNameTag); -} -FX_BOOL CPDF_DefaultAppearance::HasColor(PaintOperation nOperation) { - if (m_csDA.IsEmpty()) { - return FALSE; - } - CPDF_SimpleParser syntax(m_csDA.AsStringC()); - if (syntax.FindTagParamFromStart( - (nOperation == PaintOperation::STROKE ? "G" : "g"), 1)) { - return TRUE; - } - if (syntax.FindTagParamFromStart( - (nOperation == PaintOperation::STROKE ? "RG" : "rg"), 3)) { - return TRUE; - } - return syntax.FindTagParamFromStart( - (nOperation == PaintOperation::STROKE ? "K" : "k"), 4); -} -CFX_ByteString CPDF_DefaultAppearance::GetColorString( - PaintOperation nOperation) { - CFX_ByteString csColor; - if (m_csDA.IsEmpty()) { - return csColor; - } - CPDF_SimpleParser syntax(m_csDA.AsStringC()); - if (syntax.FindTagParamFromStart( - (nOperation == PaintOperation::STROKE ? "G" : "g"), 1)) { - csColor += syntax.GetWord(); - csColor += " "; - csColor += syntax.GetWord(); - return csColor; - } - if (syntax.FindTagParamFromStart( - (nOperation == PaintOperation::STROKE ? "RG" : "rg"), 3)) { - csColor += syntax.GetWord(); - csColor += " "; - csColor += syntax.GetWord(); - csColor += " "; - csColor += syntax.GetWord(); - csColor += " "; - csColor += syntax.GetWord(); - return csColor; - } - if (syntax.FindTagParamFromStart( - (nOperation == PaintOperation::STROKE ? "K" : "k"), 4)) { - csColor += syntax.GetWord(); - csColor += " "; - csColor += syntax.GetWord(); - csColor += " "; - csColor += syntax.GetWord(); - csColor += " "; - csColor += syntax.GetWord(); - csColor += " "; - csColor += syntax.GetWord(); - } - return csColor; -} -void CPDF_DefaultAppearance::GetColor(int& iColorType, - FX_FLOAT fc[4], - PaintOperation nOperation) { - iColorType = COLORTYPE_TRANSPARENT; - for (int c = 0; c < 4; c++) { - fc[c] = 0; - } - if (m_csDA.IsEmpty()) { - return; - } - CPDF_SimpleParser syntax(m_csDA.AsStringC()); - if (syntax.FindTagParamFromStart( - (nOperation == PaintOperation::STROKE ? "G" : "g"), 1)) { - iColorType = COLORTYPE_GRAY; - fc[0] = FX_atof(syntax.GetWord()); - return; - } - if (syntax.FindTagParamFromStart( - (nOperation == PaintOperation::STROKE ? "RG" : "rg"), 3)) { - iColorType = COLORTYPE_RGB; - fc[0] = FX_atof(syntax.GetWord()); - fc[1] = FX_atof(syntax.GetWord()); - fc[2] = FX_atof(syntax.GetWord()); - return; - } - if (syntax.FindTagParamFromStart( - (nOperation == PaintOperation::STROKE ? "K" : "k"), 4)) { - iColorType = COLORTYPE_CMYK; - fc[0] = FX_atof(syntax.GetWord()); - fc[1] = FX_atof(syntax.GetWord()); - fc[2] = FX_atof(syntax.GetWord()); - fc[3] = FX_atof(syntax.GetWord()); - } -} -void CPDF_DefaultAppearance::GetColor(FX_ARGB& color, - int& iColorType, - PaintOperation nOperation) { - color = 0; - iColorType = COLORTYPE_TRANSPARENT; - if (m_csDA.IsEmpty()) { - return; - } - CPDF_SimpleParser syntax(m_csDA.AsStringC()); - if (syntax.FindTagParamFromStart( - (nOperation == PaintOperation::STROKE ? "G" : "g"), 1)) { - iColorType = COLORTYPE_GRAY; - FX_FLOAT g = FX_atof(syntax.GetWord()) * 255 + 0.5f; - color = ArgbEncode(255, (int)g, (int)g, (int)g); - return; - } - if (syntax.FindTagParamFromStart( - (nOperation == PaintOperation::STROKE ? "RG" : "rg"), 3)) { - iColorType = COLORTYPE_RGB; - FX_FLOAT r = FX_atof(syntax.GetWord()) * 255 + 0.5f; - FX_FLOAT g = FX_atof(syntax.GetWord()) * 255 + 0.5f; - FX_FLOAT b = FX_atof(syntax.GetWord()) * 255 + 0.5f; - color = ArgbEncode(255, (int)r, (int)g, (int)b); - return; - } - if (syntax.FindTagParamFromStart( - (nOperation == PaintOperation::STROKE ? "K" : "k"), 4)) { - iColorType = COLORTYPE_CMYK; - FX_FLOAT c = FX_atof(syntax.GetWord()); - FX_FLOAT m = FX_atof(syntax.GetWord()); - FX_FLOAT y = FX_atof(syntax.GetWord()); - FX_FLOAT k = FX_atof(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.AsStringC()); - return syntax.FindTagParamFromStart("Tm", 6); -} -CFX_ByteString CPDF_DefaultAppearance::GetTextMatrixString() { - CFX_ByteString csTM; - if (m_csDA.IsEmpty()) { - return csTM; - } - CPDF_SimpleParser syntax(m_csDA.AsStringC()); - if (syntax.FindTagParamFromStart("Tm", 6)) { - for (int i = 0; i < 6; i++) { - csTM += syntax.GetWord(); - csTM += " "; - } - csTM += syntax.GetWord(); - } - return csTM; -} -CFX_Matrix CPDF_DefaultAppearance::GetTextMatrix() { - CFX_Matrix tm; - if (m_csDA.IsEmpty()) { - return tm; - } - CPDF_SimpleParser syntax(m_csDA.AsStringC()); - if (syntax.FindTagParamFromStart("Tm", 6)) { - FX_FLOAT f[6]; - for (int i = 0; i < 6; i++) { - f[i] = FX_atof(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; - uint32_t dwObjNum = pDocument->AddIndirectObject(pFormDict); - CPDF_Dictionary* pRoot = pDocument->GetRoot(); - pRoot->SetAtReference("AcroForm", pDocument, dwObjNum); - } - CFX_ByteString csDA; - if (!pFormDict->KeyExist("DR")) { - CFX_ByteString csBaseName; - CFX_ByteString csDefault; - uint8_t charSet = CPDF_InterForm::GetNativeCharSet(); - CPDF_Font* pFont = CPDF_InterForm::AddStandardFont(pDocument, "Helvetica"); - if (pFont) { - AddInterFormFont(pFormDict, pDocument, pFont, csBaseName); - csDefault = csBaseName; - } - if (charSet != FXFONT_ANSI_CHARSET) { - CFX_ByteString csFontName = - CPDF_InterForm::GetNativeFont(charSet, nullptr); - 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); - } -} -uint32_t 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; - } - uint32_t 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, - uint32_t index, - CFX_ByteString& csNameTag) { - if (!pFormDict) { - return nullptr; - } - CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR"); - if (!pDR) { - return nullptr; - } - CPDF_Dictionary* pFonts = pDR->GetDictBy("Font"); - if (!pFonts) { - return nullptr; - } - uint32_t 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 nullptr; -} -CPDF_Font* GetInterFormFont(CPDF_Dictionary* pFormDict, - CPDF_Document* pDocument, - CFX_ByteString csNameTag) { - CFX_ByteString csAlias = PDF_NameDecode(csNameTag); - if (!pFormDict || csAlias.IsEmpty()) { - return nullptr; - } - CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR"); - if (!pDR) { - return nullptr; - } - CPDF_Dictionary* pFonts = pDR->GetDictBy("Font"); - if (!pFonts) { - return nullptr; - } - CPDF_Dictionary* pElement = pFonts->GetDictBy(csAlias); - if (!pElement) { - return nullptr; - } - if (pElement->GetStringBy("Type") == "Font") { - return pDocument->LoadFont(pElement); - } - return nullptr; -} -CPDF_Font* GetInterFormFont(CPDF_Dictionary* pFormDict, - CPDF_Document* pDocument, - CFX_ByteString csFontName, - CFX_ByteString& csNameTag) { - if (!pFormDict || csFontName.IsEmpty()) { - return nullptr; - } - CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR"); - if (!pDR) { - return nullptr; - } - CPDF_Dictionary* pFonts = pDR->GetDictBy("Font"); - if (!pFonts) { - return nullptr; - } - 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 nullptr; -} -CPDF_Font* GetNativeInterFormFont(CPDF_Dictionary* pFormDict, - CPDF_Document* pDocument, - uint8_t charSet, - CFX_ByteString& csNameTag) { - if (!pFormDict) { - return nullptr; - } - CPDF_Dictionary* pDR = pFormDict->GetDictBy("DR"); - if (!pDR) { - return nullptr; - } - CPDF_Dictionary* pFonts = pDR->GetDictBy("Font"); - if (!pFonts) { - return nullptr; - } - 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 = pFind->GetSubstFont(); - if (!pSubst) { - continue; - } - if (pSubst->m_Charset == (int)charSet) { - csNameTag = csKey; - return pFind; - } - } - return nullptr; -} - -CPDF_Font* GetNativeInterFormFont(CPDF_Dictionary* pFormDict, - CPDF_Document* pDocument, - CFX_ByteString& csNameTag) { - csNameTag.clear(); - uint8_t charSet = CPDF_InterForm::GetNativeCharSet(); - CPDF_Font* pFont = GetDefaultInterFormFont(pFormDict, pDocument); - if (pFont) { - CFX_SubstFont* pSubst = 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.c_str()); - 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() && - 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 nullptr; - } - 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) { - uint32_t dwCount = pA->GetCount(); - if (dwCount > 0) { - fLeft = pA->GetNumberAt(0); - } - if (dwCount > 1) { - fBottom = pA->GetNumberAt(1); - } - } -} - -bool CPDF_IconFit::GetFittingBounds() { - return m_pDict ? m_pDict->GetBooleanBy("FB") : false; -} - -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 nullptr; - } - if (!pFieldDict) { - return nullptr; - } - CPDF_Object* pAttr = pFieldDict->GetDirectObjectBy(name); - if (pAttr) { - return pAttr; - } - CPDF_Dictionary* pParent = pFieldDict->GetDictBy("Parent"); - if (!pParent) { - return nullptr; - } - return FPDF_GetFieldAttr(pParent, name, nLevel + 1); -} diff --git a/core/fpdfdoc/doc_utils.h b/core/fpdfdoc/doc_utils.h deleted file mode 100644 index 35b7d2d598..0000000000 --- a/core/fpdfdoc/doc_utils.h +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2015 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 - -#ifndef CORE_FPDFDOC_DOC_UTILS_H_ -#define CORE_FPDFDOC_DOC_UTILS_H_ - -#include <vector> - -#include "core/fpdfapi/fpdf_parser/include/cpdf_parser.h" - -class CPDF_Dictionary; -class CPDF_FormField; - -class CPDF_NumberTree { - public: - CPDF_NumberTree(CPDF_Dictionary* pRoot) : m_pRoot(pRoot) {} - CPDF_Object* LookupValue(int num) const; - - protected: - CPDF_Dictionary* const m_pRoot; -}; - -CFX_WideString GetFullName(CPDF_Dictionary* pFieldDict); -void InitInterFormDict(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument); -uint32_t CountInterFormFonts(CPDF_Dictionary* pFormDict); -CPDF_Font* GetInterFormFont(CPDF_Dictionary* pFormDict, - CPDF_Document* pDocument, - uint32_t index, - CFX_ByteString& csNameTag); -CPDF_Font* GetInterFormFont(CPDF_Dictionary* pFormDict, - CPDF_Document* pDocument, - CFX_ByteString csNameTag); -CPDF_Font* GetInterFormFont(CPDF_Dictionary* pFormDict, - CPDF_Document* pDocument, - CFX_ByteString csFontName, - CFX_ByteString& csNameTag); -CPDF_Font* GetNativeInterFormFont(CPDF_Dictionary* pFormDict, - CPDF_Document* pDocument, - uint8_t charSet, - CFX_ByteString& csNameTag); -CPDF_Font* GetNativeInterFormFont(CPDF_Dictionary* pFormDict, - CPDF_Document* pDocument, - CFX_ByteString& csNameTag); -FX_BOOL FindInterFormFont(CPDF_Dictionary* pFormDict, - const CPDF_Font* pFont, - CFX_ByteString& csNameTag); -FX_BOOL FindInterFormFont(CPDF_Dictionary* pFormDict, - CPDF_Document* pDocument, - CFX_ByteString csFontName, - CPDF_Font*& pFont, - CFX_ByteString& csNameTag); -void AddInterFormFont(CPDF_Dictionary*& pFormDict, - CPDF_Document* pDocument, - const CPDF_Font* pFont, - CFX_ByteString& csNameTag); -CPDF_Font* AddNativeInterFormFont(CPDF_Dictionary*& pFormDict, - CPDF_Document* pDocument, - uint8_t charSet, - CFX_ByteString& csNameTag); -CPDF_Font* AddNativeInterFormFont(CPDF_Dictionary*& pFormDict, - CPDF_Document* pDocument, - CFX_ByteString& csNameTag); -void RemoveInterFormFont(CPDF_Dictionary* pFormDict, const CPDF_Font* pFont); -void RemoveInterFormFont(CPDF_Dictionary* pFormDict, CFX_ByteString csNameTag); -CPDF_Font* GetDefaultInterFormFont(CPDF_Dictionary* pFormDict, - CPDF_Document* pDocument); -void SetDefaultInterFormFont(CPDF_Dictionary*& pFormDict, - CPDF_Document* pDocument, - const CPDF_Font* pFont); -std::vector<bool> SaveCheckedFieldStatus(CPDF_FormField* pField); -FX_BOOL NeedPDFEncodeForFieldFullName(const CFX_WideString& csFieldName); -FX_BOOL NeedPDFEncodeForFieldTree(CPDF_Dictionary* pFieldDict, int nLevel = 0); -void EncodeFieldName(const CFX_WideString& csName, CFX_ByteString& csT); -void UpdateEncodeFieldName(CPDF_Dictionary* pFieldDict, int nLevel = 0); - -#endif // CORE_FPDFDOC_DOC_UTILS_H_ diff --git a/core/fpdfdoc/include/cpdf_formfield.h b/core/fpdfdoc/include/cpdf_formfield.h index 3d9d88fb6b..d39c6da4d4 100644 --- a/core/fpdfdoc/include/cpdf_formfield.h +++ b/core/fpdfdoc/include/cpdf_formfield.h @@ -31,6 +31,7 @@ class CPDF_String; CPDF_Object* FPDF_GetFieldAttr(CPDF_Dictionary* pFieldDict, const FX_CHAR* name, int nLevel = 0); +CFX_WideString FPDF_GetFullName(CPDF_Dictionary* pFieldDict); class CPDF_FormField { public: diff --git a/core/fpdfdoc/include/cpdf_interform.h b/core/fpdfdoc/include/cpdf_interform.h index f07172c42b..6d9d616c89 100644 --- a/core/fpdfdoc/include/cpdf_interform.h +++ b/core/fpdfdoc/include/cpdf_interform.h @@ -27,6 +27,10 @@ class CPDF_Object; class CPDF_Page; class IPDF_FormNotify; +CPDF_Font* AddNativeInterFormFont(CPDF_Dictionary*& pFormDict, + CPDF_Document* pDocument, + CFX_ByteString& csNameTag); + class CPDF_InterForm { public: explicit CPDF_InterForm(CPDF_Document* pDocument); diff --git a/pdfium.gyp b/pdfium.gyp index 501ed9e06b..61890e81cd 100644 --- a/pdfium.gyp +++ b/pdfium.gyp @@ -189,18 +189,26 @@ 'core/fpdfdoc/cpdf_aaction.cpp', 'core/fpdfdoc/cpdf_action.cpp', 'core/fpdfdoc/cpdf_actionfields.cpp', + 'core/fpdfdoc/cpdf_apsettings.cpp', 'core/fpdfdoc/cpdf_apsettings.h', 'core/fpdfdoc/cpdf_annot.cpp', 'core/fpdfdoc/cpdf_annotlist.cpp', 'core/fpdfdoc/cpdf_bookmark.cpp', 'core/fpdfdoc/cpdf_bookmarktree.cpp', + 'core/fpdfdoc/cpdf_defaultappearance.cpp', 'core/fpdfdoc/cpdf_dest.cpp', 'core/fpdfdoc/cpdf_docjsactions.cpp', 'core/fpdfdoc/cpdf_filespec.cpp', + 'core/fpdfdoc/cpdf_formcontrol.cpp', + 'core/fpdfdoc/cpdf_formfield.cpp', + 'core/fpdfdoc/cpdf_iconfit.cpp', + 'core/fpdfdoc/cpdf_interform.cpp', 'core/fpdfdoc/cpdf_link.cpp', 'core/fpdfdoc/cpdf_linklist.cpp', 'core/fpdfdoc/cpdf_metadata.cpp', 'core/fpdfdoc/cpdf_nametree.cpp', + 'core/fpdfdoc/cpdf_numbertree.cpp', + 'core/fpdfdoc/cpdf_numbertree.h', 'core/fpdfdoc/cpdf_occontext.cpp', 'core/fpdfdoc/cpdf_pagelabel.cpp', 'core/fpdfdoc/cpdf_pagelabel.h', @@ -224,11 +232,6 @@ 'core/fpdfdoc/csection.h', 'core/fpdfdoc/ctypeset.cpp', 'core/fpdfdoc/ctypeset.h', - 'core/fpdfdoc/doc_form.cpp', - 'core/fpdfdoc/doc_formcontrol.cpp', - 'core/fpdfdoc/doc_formfield.cpp', - 'core/fpdfdoc/doc_utils.cpp', - 'core/fpdfdoc/doc_utils.h', 'core/fpdfdoc/include/cpdf_aaction.h', 'core/fpdfdoc/include/cpdf_action.h', 'core/fpdfdoc/include/cpdf_actionfields.h', |