From 448c4337f2be2523727451b265311d48e9550ee5 Mon Sep 17 00:00:00 2001 From: dsinclair Date: Tue, 2 Aug 2016 12:07:35 -0700 Subject: Splitting fpdfdoc/doc_* part II. This splits the doc_ocg, doc_vt and doc_basic files into individual class files. Review-Url: https://codereview.chromium.org/2187073005 --- core/fpdfdoc/cline.cpp | 38 +++ core/fpdfdoc/cline.h | 26 ++ core/fpdfdoc/clines.cpp | 2 + core/fpdfdoc/clines.h | 7 +- core/fpdfdoc/cpdf_dest.cpp | 74 ++++ core/fpdfdoc/cpdf_filespec.cpp | 167 +++++++++ core/fpdfdoc/cpdf_filespec_unittest.cpp | 169 +++++++++ core/fpdfdoc/cpdf_nametree.cpp | 198 +++++++++++ core/fpdfdoc/cpdf_occontext.cpp | 281 +++++++++++++++ core/fpdfdoc/cpdf_pagelabel.cpp | 136 ++++++++ core/fpdfdoc/cpdf_variabletext.cpp | 47 ++- core/fpdfdoc/cpvt_arraytemplate.h | 30 ++ core/fpdfdoc/cpvt_generateap.cpp | 1 - core/fpdfdoc/csection.cpp | 1 + core/fpdfdoc/ctypeset.cpp | 1 + core/fpdfdoc/doc_basic.cpp | 568 ------------------------------- core/fpdfdoc/doc_basic_unittest.cpp | 169 --------- core/fpdfdoc/doc_ocg.cpp | 285 ---------------- core/fpdfdoc/doc_vt.cpp | 58 ---- core/fpdfdoc/include/cpdf_variabletext.h | 27 +- core/fpdfdoc/ipdf_formnotify.cpp | 37 ++ core/fpdfdoc/pdf_vt.h | 99 ------ core/fxcrt/include/fx_system.h | 5 + 23 files changed, 1235 insertions(+), 1191 deletions(-) create mode 100644 core/fpdfdoc/cline.cpp create mode 100644 core/fpdfdoc/cline.h create mode 100644 core/fpdfdoc/cpdf_dest.cpp create mode 100644 core/fpdfdoc/cpdf_filespec.cpp create mode 100644 core/fpdfdoc/cpdf_filespec_unittest.cpp create mode 100644 core/fpdfdoc/cpdf_nametree.cpp create mode 100644 core/fpdfdoc/cpdf_occontext.cpp create mode 100644 core/fpdfdoc/cpdf_pagelabel.cpp create mode 100644 core/fpdfdoc/cpvt_arraytemplate.h delete mode 100644 core/fpdfdoc/doc_basic.cpp delete mode 100644 core/fpdfdoc/doc_basic_unittest.cpp delete mode 100644 core/fpdfdoc/doc_ocg.cpp delete mode 100644 core/fpdfdoc/doc_vt.cpp create mode 100644 core/fpdfdoc/ipdf_formnotify.cpp delete mode 100644 core/fpdfdoc/pdf_vt.h (limited to 'core') diff --git a/core/fpdfdoc/cline.cpp b/core/fpdfdoc/cline.cpp new file mode 100644 index 0000000000..2e8477cfe7 --- /dev/null +++ b/core/fpdfdoc/cline.cpp @@ -0,0 +1,38 @@ +// 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/cline.h" + +CLine::CLine() {} + +CLine::~CLine() {} + +CPVT_WordPlace CLine::GetBeginWordPlace() const { + return CPVT_WordPlace(LinePlace.nSecIndex, LinePlace.nLineIndex, -1); +} + +CPVT_WordPlace CLine::GetEndWordPlace() const { + return CPVT_WordPlace(LinePlace.nSecIndex, LinePlace.nLineIndex, + m_LineInfo.nEndWordIndex); +} + +CPVT_WordPlace CLine::GetPrevWordPlace(const CPVT_WordPlace& place) const { + if (place.nWordIndex > m_LineInfo.nEndWordIndex) { + return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, + m_LineInfo.nEndWordIndex); + } + return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, + place.nWordIndex - 1); +} + +CPVT_WordPlace CLine::GetNextWordPlace(const CPVT_WordPlace& place) const { + if (place.nWordIndex < m_LineInfo.nBeginWordIndex) { + return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, + m_LineInfo.nBeginWordIndex); + } + return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, + place.nWordIndex + 1); +} diff --git a/core/fpdfdoc/cline.h b/core/fpdfdoc/cline.h new file mode 100644 index 0000000000..a0cdbfd4af --- /dev/null +++ b/core/fpdfdoc/cline.h @@ -0,0 +1,26 @@ +// 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_CLINE_H_ +#define CORE_FPDFDOC_CLINE_H_ + +#include "core/fpdfdoc/cpvt_lineinfo.h" +#include "core/fpdfdoc/include/cpvt_wordplace.h" + +class CLine final { + public: + CLine(); + ~CLine(); + + CPVT_WordPlace GetBeginWordPlace() const; + CPVT_WordPlace GetEndWordPlace() const; + CPVT_WordPlace GetPrevWordPlace(const CPVT_WordPlace& place) const; + CPVT_WordPlace GetNextWordPlace(const CPVT_WordPlace& place) const; + CPVT_WordPlace LinePlace; + CPVT_LineInfo m_LineInfo; +}; + +#endif // CORE_FPDFDOC_CLINE_H_ diff --git a/core/fpdfdoc/clines.cpp b/core/fpdfdoc/clines.cpp index b11731042d..1e425eab93 100644 --- a/core/fpdfdoc/clines.cpp +++ b/core/fpdfdoc/clines.cpp @@ -6,6 +6,8 @@ #include "core/fpdfdoc/clines.h" +#include "core/fpdfdoc/cline.h" + CLines::CLines() : m_nTotal(0) {} CLines::~CLines() { diff --git a/core/fpdfdoc/clines.h b/core/fpdfdoc/clines.h index 9d71d3f048..b4db0e3966 100644 --- a/core/fpdfdoc/clines.h +++ b/core/fpdfdoc/clines.h @@ -7,7 +7,12 @@ #ifndef CORE_FPDFDOC_CLINES_H_ #define CORE_FPDFDOC_CLINES_H_ -#include "core/fpdfdoc/pdf_vt.h" +#include + +#include "core/fpdfdoc/cpvt_arraytemplate.h" +#include "core/fpdfdoc/cpvt_lineinfo.h" + +class CLine; class CLines final { public: diff --git a/core/fpdfdoc/cpdf_dest.cpp b/core/fpdfdoc/cpdf_dest.cpp new file mode 100644 index 0000000000..27626a3d8f --- /dev/null +++ b/core/fpdfdoc/cpdf_dest.cpp @@ -0,0 +1,74 @@ +// 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_dest.h" + +#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" + +namespace { + +const FX_CHAR* const g_sZoomModes[] = {"XYZ", "Fit", "FitH", "FitV", "FitR", + "FitB", "FitBH", "FitBV", nullptr}; + +} // namespace + +int CPDF_Dest::GetPageIndex(CPDF_Document* pDoc) { + CPDF_Array* pArray = ToArray(m_pObj); + if (!pArray) + return 0; + + CPDF_Object* pPage = pArray->GetDirectObjectAt(0); + if (!pPage) + return 0; + if (pPage->IsNumber()) + return pPage->GetInteger(); + if (!pPage->IsDictionary()) + return 0; + return pDoc->GetPageIndex(pPage->GetObjNum()); +} + +uint32_t CPDF_Dest::GetPageObjNum() { + CPDF_Array* pArray = ToArray(m_pObj); + if (!pArray) + return 0; + + CPDF_Object* pPage = pArray->GetDirectObjectAt(0); + if (!pPage) + return 0; + if (pPage->IsNumber()) + return pPage->GetInteger(); + if (pPage->IsDictionary()) + return pPage->GetObjNum(); + return 0; +} + +int CPDF_Dest::GetZoomMode() { + CPDF_Array* pArray = ToArray(m_pObj); + if (!pArray) + return 0; + + CPDF_Object* pObj = pArray->GetDirectObjectAt(1); + if (!pObj) + return 0; + + CFX_ByteString mode = pObj->GetString(); + for (int i = 0; g_sZoomModes[i]; ++i) { + if (mode == g_sZoomModes[i]) + return i + 1; + } + + return 0; +} + +FX_FLOAT CPDF_Dest::GetParam(int index) { + CPDF_Array* pArray = ToArray(m_pObj); + return pArray ? pArray->GetNumberAt(2 + index) : 0; +} + +CFX_ByteString CPDF_Dest::GetRemoteName() { + return m_pObj ? m_pObj->GetString() : CFX_ByteString(); +} diff --git a/core/fpdfdoc/cpdf_filespec.cpp b/core/fpdfdoc/cpdf_filespec.cpp new file mode 100644 index 0000000000..2084606629 --- /dev/null +++ b/core/fpdfdoc/cpdf_filespec.cpp @@ -0,0 +1,167 @@ +// 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_filespec.h" + +#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/include/cpdf_object.h" +#include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h" +#include "core/fxcrt/include/fx_system.h" + +namespace { + +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || \ + _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ +CFX_WideString ChangeSlashToPlatform(const FX_WCHAR* str) { + CFX_WideString result; + while (*str) { + if (*str == '/') { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + result += ':'; +#else + result += '\\'; +#endif + } else { + result += *str; + } + str++; + } + return result; +} + +CFX_WideString ChangeSlashToPDF(const FX_WCHAR* str) { + CFX_WideString result; + while (*str) { + if (*str == '\\' || *str == ':') + result += '/'; + else + result += *str; + + str++; + } + return result; +} +#endif // _FXM_PLATFORM_APPLE_ || _FXM_PLATFORM_WINDOWS_ + +} // namespace + +CFX_WideString CPDF_FileSpec::DecodeFileName(const CFX_WideStringC& filepath) { + if (filepath.GetLength() <= 1) + return CFX_WideString(); + +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (filepath.Left(sizeof("/Mac") - 1) == CFX_WideStringC(L"/Mac")) + return ChangeSlashToPlatform(filepath.c_str() + 1); + return ChangeSlashToPlatform(filepath.c_str()); +#elif _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + + if (filepath.GetAt(0) != '/') + return ChangeSlashToPlatform(filepath.c_str()); + if (filepath.GetAt(1) == '/') + return ChangeSlashToPlatform(filepath.c_str() + 1); + if (filepath.GetAt(2) == '/') { + CFX_WideString result; + result += filepath.GetAt(1); + result += ':'; + result += ChangeSlashToPlatform(filepath.c_str() + 2); + return result; + } + CFX_WideString result; + result += '\\'; + result += ChangeSlashToPlatform(filepath.c_str()); + return result; +#else + return CFX_WideString(filepath); +#endif +} + +bool CPDF_FileSpec::GetFileName(CFX_WideString* csFileName) const { + if (CPDF_Dictionary* pDict = m_pObj->AsDictionary()) { + *csFileName = pDict->GetUnicodeTextBy("UF"); + if (csFileName->IsEmpty()) { + *csFileName = + CFX_WideString::FromLocal(pDict->GetStringBy("F").AsStringC()); + } + if (pDict->GetStringBy("FS") == "URL") + return true; + if (csFileName->IsEmpty()) { + if (pDict->KeyExist("DOS")) { + *csFileName = + CFX_WideString::FromLocal(pDict->GetStringBy("DOS").AsStringC()); + } else if (pDict->KeyExist("Mac")) { + *csFileName = + CFX_WideString::FromLocal(pDict->GetStringBy("Mac").AsStringC()); + } else if (pDict->KeyExist("Unix")) { + *csFileName = + CFX_WideString::FromLocal(pDict->GetStringBy("Unix").AsStringC()); + } else { + return false; + } + } + } else if (m_pObj->IsString()) { + *csFileName = CFX_WideString::FromLocal(m_pObj->GetString().AsStringC()); + } else { + return false; + } + *csFileName = DecodeFileName(csFileName->AsStringC()); + return true; +} + +CPDF_FileSpec::CPDF_FileSpec() { + m_pObj = new CPDF_Dictionary; + m_pObj->AsDictionary()->SetAtName("Type", "Filespec"); +} + +CFX_WideString CPDF_FileSpec::EncodeFileName(const CFX_WideStringC& filepath) { + if (filepath.GetLength() <= 1) + return CFX_WideString(); + +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + if (filepath.GetAt(1) == ':') { + CFX_WideString result; + result = '/'; + result += filepath.GetAt(0); + if (filepath.GetAt(2) != '\\') + result += '/'; + + result += ChangeSlashToPDF(filepath.c_str() + 2); + return result; + } + if (filepath.GetAt(0) == '\\' && filepath.GetAt(1) == '\\') + return ChangeSlashToPDF(filepath.c_str() + 1); + + if (filepath.GetAt(0) == '\\') { + CFX_WideString result; + result = '/'; + result += ChangeSlashToPDF(filepath.c_str()); + return result; + } + return ChangeSlashToPDF(filepath.c_str()); +#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (filepath.Left(sizeof("Mac") - 1) == FX_WSTRC(L"Mac")) { + CFX_WideString result; + result = '/'; + result += ChangeSlashToPDF(filepath.c_str()); + return result; + } + return ChangeSlashToPDF(filepath.c_str()); +#else + return CFX_WideString(filepath); +#endif +} + +void CPDF_FileSpec::SetFileName(const CFX_WideStringC& wsFileName) { + if (!m_pObj) + return; + + CFX_WideString wsStr = EncodeFileName(wsFileName); + if (m_pObj->IsString()) { + m_pObj->SetString(CFX_ByteString::FromUnicode(wsStr)); + } else if (CPDF_Dictionary* pDict = m_pObj->AsDictionary()) { + pDict->SetAtString("F", CFX_ByteString::FromUnicode(wsStr)); + pDict->SetAtString("UF", PDF_EncodeText(wsStr)); + } +} diff --git a/core/fpdfdoc/cpdf_filespec_unittest.cpp b/core/fpdfdoc/cpdf_filespec_unittest.cpp new file mode 100644 index 0000000000..0843f3045b --- /dev/null +++ b/core/fpdfdoc/cpdf_filespec_unittest.cpp @@ -0,0 +1,169 @@ +// 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. + +#include +#include + +#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/include/cpdf_name.h" +#include "core/fpdfapi/fpdf_parser/include/cpdf_string.h" +#include "core/fpdfdoc/include/cpdf_filespec.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/test_support.h" + +namespace { + +using ScopedObj = std::unique_ptr>; +using ScopedDict = + std::unique_ptr>; +} + +TEST(cpdf_filespec, EncodeDecodeFileName) { + std::vector test_data = { + // Empty src string. + {L"", L""}, + // only file name. + {L"test.pdf", L"test.pdf"}, +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + // With drive identifier. + {L"r:\\pdfdocs\\spec.pdf", L"/r/pdfdocs/spec.pdf"}, + // Relative path. + {L"My Document\\test.pdf", L"My Document/test.pdf"}, + // Absolute path without drive identifier. + {L"\\pdfdocs\\spec.pdf", L"//pdfdocs/spec.pdf"}, + // Absolute path with double backslashes. + {L"\\\\pdfdocs\\spec.pdf", L"/pdfdocs/spec.pdf"}, +// Network resource name. It is not supported yet. +// {L"pclib/eng:\\pdfdocs\\spec.pdf", L"/pclib/eng/pdfdocs/spec.pdf"}, +#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + // Absolute path with colon separator. + {L"Mac HD:PDFDocs:spec.pdf", L"/Mac HD/PDFDocs/spec.pdf"}, + // Relative path with colon separator. + {L"PDFDocs:spec.pdf", L"PDFDocs/spec.pdf"}, +#else + // Relative path. + {L"./docs/test.pdf", L"./docs/test.pdf"}, + // Relative path with parent dir. + {L"../test_docs/test.pdf", L"../test_docs/test.pdf"}, + // Absolute path. + {L"/usr/local/home/test.pdf", L"/usr/local/home/test.pdf"}, +#endif + }; + for (const auto& data : test_data) { + CFX_WideString encoded_str = CPDF_FileSpec::EncodeFileName(data.input); + EXPECT_TRUE(encoded_str == data.expected); + // DecodeFileName is the reverse procedure of EncodeFileName. + CFX_WideString decoded_str = CPDF_FileSpec::DecodeFileName(data.expected); + EXPECT_TRUE(decoded_str == data.input); + } +} + +TEST(cpdf_filespec, GetFileName) { + { + // String object. + pdfium::NullTermWstrFuncTestData test_data = { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + L"/C/docs/test.pdf", + L"C:\\docs\\test.pdf" +#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + L"/Mac HD/docs/test.pdf", + L"Mac HD:docs:test.pdf" +#else + L"/docs/test.pdf", + L"/docs/test.pdf" +#endif + }; + ScopedObj str_obj(new CPDF_String(test_data.input)); + CPDF_FileSpec file_spec(str_obj.get()); + CFX_WideString file_name; + EXPECT_TRUE(file_spec.GetFileName(&file_name)); + EXPECT_TRUE(file_name == test_data.expected); + } + { + // Dictionary object. + pdfium::NullTermWstrFuncTestData test_data[5] = { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + {L"/C/docs/test.pdf", L"C:\\docs\\test.pdf"}, + {L"/D/docs/test.pdf", L"D:\\docs\\test.pdf"}, + {L"/E/docs/test.pdf", L"E:\\docs\\test.pdf"}, + {L"/F/docs/test.pdf", L"F:\\docs\\test.pdf"}, + {L"/G/docs/test.pdf", L"G:\\docs\\test.pdf"}, +#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + {L"/Mac HD/docs1/test.pdf", L"Mac HD:docs1:test.pdf"}, + {L"/Mac HD/docs2/test.pdf", L"Mac HD:docs2:test.pdf"}, + {L"/Mac HD/docs3/test.pdf", L"Mac HD:docs3:test.pdf"}, + {L"/Mac HD/docs4/test.pdf", L"Mac HD:docs4:test.pdf"}, + {L"/Mac HD/docs5/test.pdf", L"Mac HD:docs5:test.pdf"}, +#else + {L"/docs/a/test.pdf", L"/docs/a/test.pdf"}, + {L"/docs/b/test.pdf", L"/docs/b/test.pdf"}, + {L"/docs/c/test.pdf", L"/docs/c/test.pdf"}, + {L"/docs/d/test.pdf", L"/docs/d/test.pdf"}, + {L"/docs/e/test.pdf", L"/docs/e/test.pdf"}, +#endif + }; + // Keyword fields in reverse order of precedence to retrieve the file name. + const char* const keywords[5] = {"Unix", "Mac", "DOS", "F", "UF"}; + ScopedDict dict_obj(new CPDF_Dictionary); + CPDF_FileSpec file_spec(dict_obj.get()); + CFX_WideString file_name; + for (int i = 0; i < 5; ++i) { + dict_obj->SetAt(keywords[i], new CPDF_String(test_data[i].input)); + EXPECT_TRUE(file_spec.GetFileName(&file_name)); + EXPECT_TRUE(file_name == test_data[i].expected); + } + + // With all the former fields and 'FS' field suggests 'URL' type. + dict_obj->SetAtString("FS", "URL"); + EXPECT_TRUE(file_spec.GetFileName(&file_name)); + // Url string is not decoded. + EXPECT_TRUE(file_name == test_data[4].input); + } + { + // Invalid object. + ScopedObj name_obj(new CPDF_Name("test.pdf")); + CPDF_FileSpec file_spec(name_obj.get()); + CFX_WideString file_name; + EXPECT_FALSE(file_spec.GetFileName(&file_name)); + } +} + +TEST(cpdf_filespec, SetFileName) { + pdfium::NullTermWstrFuncTestData test_data = { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + L"C:\\docs\\test.pdf", + L"/C/docs/test.pdf" +#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + L"Mac HD:docs:test.pdf", + L"/Mac HD/docs/test.pdf" +#else + L"/docs/test.pdf", + L"/docs/test.pdf" +#endif + }; + // String object. + ScopedObj str_obj(new CPDF_String(L"babababa")); + CPDF_FileSpec file_spec1(str_obj.get()); + file_spec1.SetFileName(test_data.input); + // Check internal object value. + CFX_ByteString str = CFX_ByteString::FromUnicode(test_data.expected); + EXPECT_TRUE(str == str_obj->GetString()); + // Check we can get the file name back. + CFX_WideString file_name; + EXPECT_TRUE(file_spec1.GetFileName(&file_name)); + EXPECT_TRUE(file_name == test_data.input); + + // Dictionary object. + ScopedDict dict_obj(new CPDF_Dictionary); + CPDF_FileSpec file_spec2(dict_obj.get()); + file_spec2.SetFileName(test_data.input); + // Check internal object value. + file_name = dict_obj->GetUnicodeTextBy("F"); + EXPECT_TRUE(file_name == test_data.expected); + file_name = dict_obj->GetUnicodeTextBy("UF"); + EXPECT_TRUE(file_name == test_data.expected); + // Check we can get the file name back. + EXPECT_TRUE(file_spec2.GetFileName(&file_name)); + EXPECT_TRUE(file_name == test_data.input); +} diff --git a/core/fpdfdoc/cpdf_nametree.cpp b/core/fpdfdoc/cpdf_nametree.cpp new file mode 100644 index 0000000000..e046b6bf1a --- /dev/null +++ b/core/fpdfdoc/cpdf_nametree.cpp @@ -0,0 +1,198 @@ +// 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_nametree.h" + +#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" + +namespace { + +const int nMaxRecursion = 32; + +CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode, + const CFX_ByteString& csName, + size_t& nIndex, + CPDF_Array** ppFind, + int nLevel = 0) { + if (nLevel > nMaxRecursion) + return nullptr; + + CPDF_Array* pLimits = pNode->GetArrayBy("Limits"); + if (pLimits) { + CFX_ByteString csLeft = pLimits->GetStringAt(0); + CFX_ByteString csRight = pLimits->GetStringAt(1); + if (csLeft.Compare(csRight.AsStringC()) > 0) { + CFX_ByteString csTmp = csRight; + csRight = csLeft; + csLeft = csTmp; + } + if (csName.Compare(csLeft.AsStringC()) < 0 || + csName.Compare(csRight.AsStringC()) > 0) { + return nullptr; + } + } + + CPDF_Array* pNames = pNode->GetArrayBy("Names"); + if (pNames) { + size_t dwCount = pNames->GetCount() / 2; + for (size_t i = 0; i < dwCount; i++) { + CFX_ByteString csValue = pNames->GetStringAt(i * 2); + int32_t iCompare = csValue.Compare(csName.AsStringC()); + if (iCompare <= 0) { + if (ppFind) + *ppFind = pNames; + if (iCompare < 0) + continue; + } else { + break; + } + nIndex += i; + return pNames->GetDirectObjectAt(i * 2 + 1); + } + nIndex += dwCount; + 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 = + SearchNameNode(pKid, csName, nIndex, ppFind, nLevel + 1); + if (pFound) + return pFound; + } + return nullptr; +} + +CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode, + size_t nIndex, + size_t& nCurIndex, + CFX_ByteString& csName, + CPDF_Array** ppFind, + int nLevel = 0) { + if (nLevel > nMaxRecursion) + return nullptr; + + CPDF_Array* pNames = pNode->GetArrayBy("Names"); + if (pNames) { + size_t nCount = pNames->GetCount() / 2; + if (nIndex >= nCurIndex + nCount) { + nCurIndex += nCount; + return nullptr; + } + if (ppFind) + *ppFind = pNames; + csName = pNames->GetStringAt((nIndex - nCurIndex) * 2); + return pNames->GetDirectObjectAt((nIndex - nCurIndex) * 2 + 1); + } + 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 = + SearchNameNode(pKid, nIndex, nCurIndex, csName, ppFind, nLevel + 1); + if (pFound) + return pFound; + } + return nullptr; +} + +size_t CountNames(CPDF_Dictionary* pNode, int nLevel = 0) { + if (nLevel > nMaxRecursion) + return 0; + + CPDF_Array* pNames = pNode->GetArrayBy("Names"); + if (pNames) + return pNames->GetCount() / 2; + + CPDF_Array* pKids = pNode->GetArrayBy("Kids"); + if (!pKids) + return 0; + + size_t nCount = 0; + for (size_t i = 0; i < pKids->GetCount(); i++) { + CPDF_Dictionary* pKid = pKids->GetDictAt(i); + if (!pKid) + continue; + + nCount += CountNames(pKid, nLevel + 1); + } + return nCount; +} + +} // namespace + +CPDF_NameTree::CPDF_NameTree(CPDF_Document* pDoc, + const CFX_ByteString& category) + : m_pRoot(nullptr) { + CPDF_Dictionary* pRoot = pDoc->GetRoot(); + if (!pRoot) + return; + + CPDF_Dictionary* pNames = pRoot->GetDictBy("Names"); + if (!pNames) + return; + + m_pRoot = pNames->GetDictBy(category); +} + +size_t CPDF_NameTree::GetCount() const { + return m_pRoot ? ::CountNames(m_pRoot) : 0; +} + +int CPDF_NameTree::GetIndex(const CFX_ByteString& csName) const { + if (!m_pRoot) + return -1; + + size_t nIndex = 0; + if (!SearchNameNode(m_pRoot, csName, nIndex, nullptr)) + return -1; + return nIndex; +} + +CPDF_Object* CPDF_NameTree::LookupValue(int nIndex, + CFX_ByteString& csName) const { + if (!m_pRoot) + return nullptr; + size_t nCurIndex = 0; + return SearchNameNode(m_pRoot, nIndex, nCurIndex, csName, nullptr); +} + +CPDF_Object* CPDF_NameTree::LookupValue(const CFX_ByteString& csName) const { + if (!m_pRoot) + return nullptr; + size_t nIndex = 0; + return SearchNameNode(m_pRoot, csName, nIndex, nullptr); +} + +CPDF_Array* CPDF_NameTree::LookupNamedDest(CPDF_Document* pDoc, + const CFX_ByteString& sName) { + CPDF_Object* pValue = LookupValue(sName); + if (!pValue) { + CPDF_Dictionary* pDests = pDoc->GetRoot()->GetDictBy("Dests"); + if (!pDests) + return nullptr; + pValue = pDests->GetDirectObjectBy(sName); + } + if (!pValue) + return nullptr; + if (CPDF_Array* pArray = pValue->AsArray()) + return pArray; + if (CPDF_Dictionary* pDict = pValue->AsDictionary()) + return pDict->GetArrayBy("D"); + return nullptr; +} diff --git a/core/fpdfdoc/cpdf_occontext.cpp b/core/fpdfdoc/cpdf_occontext.cpp new file mode 100644 index 0000000000..9206b97e6f --- /dev/null +++ b/core/fpdfdoc/cpdf_occontext.cpp @@ -0,0 +1,281 @@ +// 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_occontext.h" + +#include "core/fpdfapi/fpdf_page/cpdf_contentmarkdata.h" +#include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h" +#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" + +namespace { + +int32_t FindGroup(const CPDF_Array* pArray, const CPDF_Dictionary* pGroupDict) { + if (!pArray || !pGroupDict) + return -1; + + for (size_t i = 0; i < pArray->GetCount(); i++) { + if (pArray->GetDictAt(i) == pGroupDict) + return i; + } + return -1; +} + +bool HasIntent(const CPDF_Dictionary* pDict, + const CFX_ByteStringC& csElement, + const CFX_ByteStringC& csDef) { + CPDF_Object* pIntent = pDict->GetDirectObjectBy("Intent"); + if (!pIntent) + return csElement == csDef; + + CFX_ByteString bsIntent; + if (CPDF_Array* pArray = pIntent->AsArray()) { + for (size_t i = 0; i < pArray->GetCount(); i++) { + bsIntent = pArray->GetStringAt(i); + if (bsIntent == "All" || bsIntent == csElement) + return true; + } + return false; + } + bsIntent = pIntent->GetString(); + return bsIntent == "All" || bsIntent == csElement; +} + +CPDF_Dictionary* GetConfig(CPDF_Document* pDoc, + const CPDF_Dictionary* pOCGDict) { + ASSERT(pOCGDict); + CPDF_Dictionary* pOCProperties = pDoc->GetRoot()->GetDictBy("OCProperties"); + if (!pOCProperties) + return nullptr; + + CPDF_Array* pOCGs = pOCProperties->GetArrayBy("OCGs"); + if (!pOCGs) + return nullptr; + + if (FindGroup(pOCGs, pOCGDict) < 0) + return nullptr; + + CPDF_Dictionary* pConfig = pOCProperties->GetDictBy("D"); + CPDF_Array* pConfigs = pOCProperties->GetArrayBy("Configs"); + if (!pConfigs) + return pConfig; + + for (size_t i = 0; i < pConfigs->GetCount(); i++) { + CPDF_Dictionary* pFind = pConfigs->GetDictAt(i); + if (pFind && HasIntent(pFind, "View", "View")) + return pFind; + } + return pConfig; +} + +CFX_ByteString GetUsageTypeString(CPDF_OCContext::UsageType eType) { + CFX_ByteString csState; + switch (eType) { + case CPDF_OCContext::Design: + csState = "Design"; + break; + case CPDF_OCContext::Print: + csState = "Print"; + break; + case CPDF_OCContext::Export: + csState = "Export"; + break; + default: + csState = "View"; + break; + } + return csState; +} + +} // namespace + +CPDF_OCContext::CPDF_OCContext(CPDF_Document* pDoc, UsageType eUsageType) + : m_pDocument(pDoc), m_eUsageType(eUsageType) { + ASSERT(pDoc); +} + +CPDF_OCContext::~CPDF_OCContext() {} + +bool CPDF_OCContext::LoadOCGStateFromConfig( + const CFX_ByteString& csConfig, + const CPDF_Dictionary* pOCGDict) const { + CPDF_Dictionary* pConfig = GetConfig(m_pDocument, pOCGDict); + if (!pConfig) + return true; + + bool bState = pConfig->GetStringBy("BaseState", "ON") != "OFF"; + CPDF_Array* pArray = pConfig->GetArrayBy("ON"); + if (pArray) { + if (FindGroup(pArray, pOCGDict) >= 0) + bState = true; + } + pArray = pConfig->GetArrayBy("OFF"); + if (pArray) { + if (FindGroup(pArray, pOCGDict) >= 0) + bState = false; + } + pArray = pConfig->GetArrayBy("AS"); + if (!pArray) + return bState; + + CFX_ByteString csFind = csConfig + "State"; + for (size_t i = 0; i < pArray->GetCount(); i++) { + CPDF_Dictionary* pUsage = pArray->GetDictAt(i); + if (!pUsage) + continue; + + if (pUsage->GetStringBy("Event", "View") != csConfig) + continue; + + CPDF_Array* pOCGs = pUsage->GetArrayBy("OCGs"); + if (!pOCGs) + continue; + + if (FindGroup(pOCGs, pOCGDict) < 0) + continue; + + CPDF_Dictionary* pState = pUsage->GetDictBy(csConfig); + if (!pState) + continue; + + bState = pState->GetStringBy(csFind) != "OFF"; + } + return bState; +} + +bool CPDF_OCContext::LoadOCGState(const CPDF_Dictionary* pOCGDict) const { + if (!HasIntent(pOCGDict, "View", "View")) + return true; + + CFX_ByteString csState = GetUsageTypeString(m_eUsageType); + CPDF_Dictionary* pUsage = pOCGDict->GetDictBy("Usage"); + if (pUsage) { + CPDF_Dictionary* pState = pUsage->GetDictBy(csState); + if (pState) { + CFX_ByteString csFind = csState + "State"; + if (pState->KeyExist(csFind)) + return pState->GetStringBy(csFind) != "OFF"; + } + if (csState != "View") { + pState = pUsage->GetDictBy("View"); + if (pState && pState->KeyExist("ViewState")) + return pState->GetStringBy("ViewState") != "OFF"; + } + } + return LoadOCGStateFromConfig(csState, pOCGDict); +} + +bool CPDF_OCContext::GetOCGVisible(const CPDF_Dictionary* pOCGDict) { + if (!pOCGDict) + return false; + + const auto it = m_OCGStates.find(pOCGDict); + if (it != m_OCGStates.end()) + return it->second; + + bool bState = LoadOCGState(pOCGDict); + m_OCGStates[pOCGDict] = bState; + return bState; +} + +bool CPDF_OCContext::CheckObjectVisible(const CPDF_PageObject* pObj) { + const CPDF_ContentMarkData* pData = pObj->m_ContentMark.GetObject(); + for (int i = 0; i < pData->CountItems(); i++) { + const CPDF_ContentMarkItem& item = pData->GetItem(i); + if (item.GetName() == "OC" && + item.GetParamType() == CPDF_ContentMarkItem::PropertiesDict && + !CheckOCGVisible(item.GetParam())) { + return false; + } + } + return true; +} + +bool CPDF_OCContext::GetOCGVE(CPDF_Array* pExpression, int nLevel) { + if (nLevel > 32 || !pExpression) + return false; + + CFX_ByteString csOperator = pExpression->GetStringAt(0); + if (csOperator == "Not") { + CPDF_Object* pOCGObj = pExpression->GetDirectObjectAt(1); + if (!pOCGObj) + return false; + if (CPDF_Dictionary* pDict = pOCGObj->AsDictionary()) + return !GetOCGVisible(pDict); + if (CPDF_Array* pArray = pOCGObj->AsArray()) + return !GetOCGVE(pArray, nLevel + 1); + return false; + } + + if (csOperator != "Or" && csOperator != "And") + return false; + + bool bValue = false; + for (size_t i = 1; i < pExpression->GetCount(); i++) { + CPDF_Object* pOCGObj = pExpression->GetDirectObjectAt(1); + if (!pOCGObj) + continue; + + bool bItem = false; + if (CPDF_Dictionary* pDict = pOCGObj->AsDictionary()) + bItem = GetOCGVisible(pDict); + else if (CPDF_Array* pArray = pOCGObj->AsArray()) + bItem = GetOCGVE(pArray, nLevel + 1); + + if (i == 1) { + bValue = bItem; + } else { + if (csOperator == "Or") { + bValue = bValue || bItem; + } else { + bValue = bValue && bItem; + } + } + } + return bValue; +} + +bool CPDF_OCContext::LoadOCMDState(const CPDF_Dictionary* pOCMDDict) { + CPDF_Array* pVE = pOCMDDict->GetArrayBy("VE"); + if (pVE) + return GetOCGVE(pVE, 0); + + CFX_ByteString csP = pOCMDDict->GetStringBy("P", "AnyOn"); + CPDF_Object* pOCGObj = pOCMDDict->GetDirectObjectBy("OCGs"); + if (!pOCGObj) + return true; + + if (const CPDF_Dictionary* pDict = pOCGObj->AsDictionary()) + return GetOCGVisible(pDict); + + CPDF_Array* pArray = pOCGObj->AsArray(); + if (!pArray) + return true; + + bool bState = (csP == "AllOn" || csP == "AllOff"); + for (size_t i = 0; i < pArray->GetCount(); i++) { + bool bItem = true; + CPDF_Dictionary* pItemDict = pArray->GetDictAt(i); + if (pItemDict) + bItem = GetOCGVisible(pItemDict); + + if ((csP == "AnyOn" && bItem) || (csP == "AnyOff" && !bItem)) + return true; + if ((csP == "AllOn" && !bItem) || (csP == "AllOff" && bItem)) + return false; + } + return bState; +} + +bool CPDF_OCContext::CheckOCGVisible(const CPDF_Dictionary* pOCGDict) { + if (!pOCGDict) + return true; + + CFX_ByteString csType = pOCGDict->GetStringBy("Type", "OCG"); + if (csType == "OCG") + return GetOCGVisible(pOCGDict); + return LoadOCMDState(pOCGDict); +} diff --git a/core/fpdfdoc/cpdf_pagelabel.cpp b/core/fpdfdoc/cpdf_pagelabel.cpp new file mode 100644 index 0000000000..886e8448b2 --- /dev/null +++ b/core/fpdfdoc/cpdf_pagelabel.cpp @@ -0,0 +1,136 @@ +// 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_pagelabel.h" + +#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" + +namespace { + +CFX_WideString MakeRoman(int num) { + const int kArabic[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; + const CFX_WideString kRoman[] = {L"m", L"cm", L"d", L"cd", L"c", + L"xc", L"l", L"xl", L"x", L"ix", + L"v", L"iv", L"i"}; + const int kMaxNum = 1000000; + + num %= kMaxNum; + int i = 0; + CFX_WideString wsRomanNumber; + while (num > 0) { + while (num >= kArabic[i]) { + num = num - kArabic[i]; + wsRomanNumber += kRoman[i]; + } + i = i + 1; + } + return wsRomanNumber; +} + +CFX_WideString MakeLetters(int num) { + if (num == 0) + return CFX_WideString(); + + CFX_WideString wsLetters; + const int nMaxCount = 1000; + const int nLetterCount = 26; + --num; + + int count = num / nLetterCount + 1; + count %= nMaxCount; + FX_WCHAR ch = L'a' + num % nLetterCount; + for (int i = 0; i < count; i++) + wsLetters += ch; + return wsLetters; +} + +CFX_WideString GetLabelNumPortion(int num, const CFX_ByteString& bsStyle) { + CFX_WideString wsNumPortion; + if (bsStyle.IsEmpty()) + return wsNumPortion; + if (bsStyle == "D") { + wsNumPortion.Format(L"%d", num); + } else if (bsStyle == "R") { + wsNumPortion = MakeRoman(num); + wsNumPortion.MakeUpper(); + } else if (bsStyle == "r") { + wsNumPortion = MakeRoman(num); + } else if (bsStyle == "A") { + wsNumPortion = MakeLetters(num); + wsNumPortion.MakeUpper(); + } else if (bsStyle == "a") { + wsNumPortion = MakeLetters(num); + } + return wsNumPortion; +} + +} // namespace + +CPDF_PageLabel::CPDF_PageLabel(CPDF_Document* pDocument) + : m_pDocument(pDocument) {} + +CFX_WideString CPDF_PageLabel::GetLabel(int nPage) const { + CFX_WideString wsLabel; + if (!m_pDocument) + return wsLabel; + + CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot(); + if (!pPDFRoot) + return wsLabel; + + CPDF_Dictionary* pLabels = pPDFRoot->GetDictBy("PageLabels"); + CPDF_NumberTree numberTree(pLabels); + CPDF_Object* pValue = nullptr; + int n = nPage; + while (n >= 0) { + pValue = numberTree.LookupValue(n); + if (pValue) + break; + n--; + } + + if (pValue) { + pValue = pValue->GetDirect(); + if (CPDF_Dictionary* pLabel = pValue->AsDictionary()) { + if (pLabel->KeyExist("P")) + wsLabel += pLabel->GetUnicodeTextBy("P"); + + CFX_ByteString bsNumberingStyle = pLabel->GetStringBy("S", ""); + int nLabelNum = nPage - n + pLabel->GetIntegerBy("St", 1); + CFX_WideString wsNumPortion = + GetLabelNumPortion(nLabelNum, bsNumberingStyle); + wsLabel += wsNumPortion; + return wsLabel; + } + } + wsLabel.Format(L"%d", nPage + 1); + return wsLabel; +} + +int32_t CPDF_PageLabel::GetPageByLabel(const CFX_ByteStringC& bsLabel) const { + if (!m_pDocument) + return -1; + + CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot(); + if (!pPDFRoot) + return -1; + + int nPages = m_pDocument->GetPageCount(); + for (int i = 0; i < nPages; i++) { + if (PDF_EncodeText(GetLabel(i)).Compare(bsLabel)) + return i; + } + + int nPage = FXSYS_atoi(CFX_ByteString(bsLabel).c_str()); // NUL terminate. + return nPage > 0 && nPage <= nPages ? nPage : -1; +} + +int32_t CPDF_PageLabel::GetPageByLabel(const CFX_WideStringC& wsLabel) const { + return GetPageByLabel(PDF_EncodeText(wsLabel.c_str()).AsStringC()); +} diff --git a/core/fpdfdoc/cpdf_variabletext.cpp b/core/fpdfdoc/cpdf_variabletext.cpp index a4f9d8923f..040b7e6051 100644 --- a/core/fpdfdoc/cpdf_variabletext.cpp +++ b/core/fpdfdoc/cpdf_variabletext.cpp @@ -8,6 +8,7 @@ #include "core/fpdfapi/fpdf_font/include/cpdf_font.h" #include "core/fpdfdoc/cpvt_wordinfo.h" +#include "core/fpdfdoc/cline.h" #include "core/fpdfdoc/csection.h" #include "core/fpdfdoc/include/cpvt_section.h" #include "core/fpdfdoc/include/cpvt_word.h" @@ -756,15 +757,19 @@ FX_BOOL CPDF_VariableText::GetSectionInfo(const CPVT_WordPlace& place, } void CPDF_VariableText::SetPlateRect(const CFX_FloatRect& rect) { - CPDF_EditContainer::SetPlateRect(rect); + m_rcPlate = rect; +} + +void CPDF_VariableText::SetContentRect(const CPVT_FloatRect& rect) { + m_rcContent = rect; } CFX_FloatRect CPDF_VariableText::GetContentRect() const { - return InToOut(CPVT_FloatRect(CPDF_EditContainer::GetContentRect())); + return InToOut(CPVT_FloatRect(m_rcContent)); } const CFX_FloatRect& CPDF_VariableText::GetPlateRect() const { - return CPDF_EditContainer::GetPlateRect(); + return m_rcPlate; } FX_FLOAT CPDF_VariableText::GetWordFontSize(const CPVT_WordInfo& WordInfo) { @@ -1103,3 +1108,39 @@ CPDF_VariableText::Iterator* CPDF_VariableText::GetIterator() { void CPDF_VariableText::SetProvider(CPDF_VariableText::Provider* pProvider) { m_pVTProvider = pProvider; } + +CFX_SizeF CPDF_VariableText::GetPlateSize() const { + return CFX_SizeF(GetPlateWidth(), GetPlateHeight()); +} + +CFX_FloatPoint CPDF_VariableText::GetBTPoint() const { + return CFX_FloatPoint(m_rcPlate.left, m_rcPlate.top); +} + +CFX_FloatPoint CPDF_VariableText::GetETPoint() const { + return CFX_FloatPoint(m_rcPlate.right, m_rcPlate.bottom); +} + +CFX_FloatPoint CPDF_VariableText::InToOut(const CFX_FloatPoint& point) const { + return CFX_FloatPoint(point.x + GetBTPoint().x, GetBTPoint().y - point.y); +} + +CFX_FloatPoint CPDF_VariableText::OutToIn(const CFX_FloatPoint& point) const { + return CFX_FloatPoint(point.x - GetBTPoint().x, GetBTPoint().y - point.y); +} + +CFX_FloatRect CPDF_VariableText::InToOut(const CPVT_FloatRect& rect) const { + CFX_FloatPoint ptLeftTop = InToOut(CFX_FloatPoint(rect.left, rect.top)); + CFX_FloatPoint ptRightBottom = + InToOut(CFX_FloatPoint(rect.right, rect.bottom)); + return CFX_FloatRect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x, + ptLeftTop.y); +} + +CPVT_FloatRect CPDF_VariableText::OutToIn(const CFX_FloatRect& rect) const { + CFX_FloatPoint ptLeftTop = OutToIn(CFX_FloatPoint(rect.left, rect.top)); + CFX_FloatPoint ptRightBottom = + OutToIn(CFX_FloatPoint(rect.right, rect.bottom)); + return CPVT_FloatRect(ptLeftTop.x, ptLeftTop.y, ptRightBottom.x, + ptRightBottom.y); +} diff --git a/core/fpdfdoc/cpvt_arraytemplate.h b/core/fpdfdoc/cpvt_arraytemplate.h new file mode 100644 index 0000000000..a0f129d083 --- /dev/null +++ b/core/fpdfdoc/cpvt_arraytemplate.h @@ -0,0 +1,30 @@ +// 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_CPVT_ARRAYTEMPLATE_H_ +#define CORE_FPDFDOC_CPVT_ARRAYTEMPLATE_H_ + +#include "core/fxcrt/include/fx_basic.h" +#include "core/fxcrt/include/fx_system.h" + +template +class CPVT_ArrayTemplate : public CFX_ArrayTemplate { + public: + bool IsEmpty() { return CFX_ArrayTemplate::GetSize() <= 0; } + + TYPE GetAt(int nIndex) const { + if (nIndex >= 0 && nIndex < CFX_ArrayTemplate::GetSize()) + return CFX_ArrayTemplate::GetAt(nIndex); + return nullptr; + } + + void RemoveAt(int nIndex) { + if (nIndex >= 0 && nIndex < CFX_ArrayTemplate::GetSize()) + CFX_ArrayTemplate::RemoveAt(nIndex); + } +}; + +#endif // CORE_FPDFDOC_CPVT_ARRAYTEMPLATE_H_ diff --git a/core/fpdfdoc/cpvt_generateap.cpp b/core/fpdfdoc/cpvt_generateap.cpp index 13ef506158..78bd780eb5 100644 --- a/core/fpdfdoc/cpvt_generateap.cpp +++ b/core/fpdfdoc/cpvt_generateap.cpp @@ -16,7 +16,6 @@ #include "core/fpdfdoc/cpvt_fontmap.h" #include "core/fpdfdoc/include/cpdf_formfield.h" #include "core/fpdfdoc/include/cpvt_word.h" -#include "core/fpdfdoc/pdf_vt.h" namespace { diff --git a/core/fpdfdoc/csection.cpp b/core/fpdfdoc/csection.cpp index 0cf08fd49b..6686c0c773 100644 --- a/core/fpdfdoc/csection.cpp +++ b/core/fpdfdoc/csection.cpp @@ -8,6 +8,7 @@ #include +#include "core/fpdfdoc/cline.h" #include "core/fpdfdoc/cpvt_wordinfo.h" CSection::CSection(CPDF_VariableText* pVT) : m_pVT(pVT) {} diff --git a/core/fpdfdoc/ctypeset.cpp b/core/fpdfdoc/ctypeset.cpp index 57d3733dc3..082cef8187 100644 --- a/core/fpdfdoc/ctypeset.cpp +++ b/core/fpdfdoc/ctypeset.cpp @@ -8,6 +8,7 @@ #include +#include "core/fpdfdoc/cline.h" #include "core/fpdfdoc/csection.h" #include "core/fpdfdoc/cpvt_wordinfo.h" diff --git a/core/fpdfdoc/doc_basic.cpp b/core/fpdfdoc/doc_basic.cpp deleted file mode 100644 index 97acf2384f..0000000000 --- a/core/fpdfdoc/doc_basic.cpp +++ /dev/null @@ -1,568 +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 "core/fpdfapi/fpdf_parser/include/cpdf_array.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_pagelabel.h" -#include "core/fpdfdoc/include/cpdf_filespec.h" -#include "core/fpdfdoc/include/cpdf_nametree.h" -#include "core/fpdfdoc/include/ipdf_formnotify.h" - -namespace { - -const int nMaxRecursion = 32; -const FX_CHAR* const g_sZoomModes[] = {"XYZ", "Fit", "FitH", "FitV", "FitR", - "FitB", "FitBH", "FitBV", nullptr}; - -} // namespace - -int CPDF_Dest::GetPageIndex(CPDF_Document* pDoc) { - CPDF_Array* pArray = ToArray(m_pObj); - if (!pArray) - return 0; - - CPDF_Object* pPage = pArray->GetDirectObjectAt(0); - if (!pPage) - return 0; - if (pPage->IsNumber()) - return pPage->GetInteger(); - if (!pPage->IsDictionary()) - return 0; - return pDoc->GetPageIndex(pPage->GetObjNum()); -} - -uint32_t CPDF_Dest::GetPageObjNum() { - CPDF_Array* pArray = ToArray(m_pObj); - if (!pArray) - return 0; - - CPDF_Object* pPage = pArray->GetDirectObjectAt(0); - if (!pPage) - return 0; - if (pPage->IsNumber()) - return pPage->GetInteger(); - if (pPage->IsDictionary()) - return pPage->GetObjNum(); - return 0; -} - -int CPDF_Dest::GetZoomMode() { - CPDF_Array* pArray = ToArray(m_pObj); - if (!pArray) - return 0; - - CPDF_Object* pObj = pArray->GetDirectObjectAt(1); - if (!pObj) - return 0; - - CFX_ByteString mode = pObj->GetString(); - for (int i = 0; g_sZoomModes[i]; ++i) { - if (mode == g_sZoomModes[i]) - return i + 1; - } - - return 0; -} - -FX_FLOAT CPDF_Dest::GetParam(int index) { - CPDF_Array* pArray = ToArray(m_pObj); - return pArray ? pArray->GetNumberAt(2 + index) : 0; -} - -CFX_ByteString CPDF_Dest::GetRemoteName() { - return m_pObj ? m_pObj->GetString() : CFX_ByteString(); -} - -CPDF_NameTree::CPDF_NameTree(CPDF_Document* pDoc, - const CFX_ByteString& category) - : m_pRoot(nullptr) { - CPDF_Dictionary* pRoot = pDoc->GetRoot(); - if (!pRoot) - return; - - CPDF_Dictionary* pNames = pRoot->GetDictBy("Names"); - if (!pNames) - return; - - m_pRoot = pNames->GetDictBy(category); -} - -static CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode, - const CFX_ByteString& csName, - size_t& nIndex, - CPDF_Array** ppFind, - int nLevel = 0) { - if (nLevel > nMaxRecursion) { - return nullptr; - } - CPDF_Array* pLimits = pNode->GetArrayBy("Limits"); - if (pLimits) { - CFX_ByteString csLeft = pLimits->GetStringAt(0); - CFX_ByteString csRight = pLimits->GetStringAt(1); - if (csLeft.Compare(csRight.AsStringC()) > 0) { - CFX_ByteString csTmp = csRight; - csRight = csLeft; - csLeft = csTmp; - } - if (csName.Compare(csLeft.AsStringC()) < 0 || - csName.Compare(csRight.AsStringC()) > 0) { - return nullptr; - } - } - CPDF_Array* pNames = pNode->GetArrayBy("Names"); - if (pNames) { - size_t dwCount = pNames->GetCount() / 2; - for (size_t i = 0; i < dwCount; i++) { - CFX_ByteString csValue = pNames->GetStringAt(i * 2); - int32_t iCompare = csValue.Compare(csName.AsStringC()); - if (iCompare <= 0) { - if (ppFind) { - *ppFind = pNames; - } - if (iCompare < 0) { - continue; - } - } else { - break; - } - nIndex += i; - return pNames->GetDirectObjectAt(i * 2 + 1); - } - nIndex += dwCount; - 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 = - SearchNameNode(pKid, csName, nIndex, ppFind, nLevel + 1); - if (pFound) { - return pFound; - } - } - return nullptr; -} - -static CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode, - size_t nIndex, - size_t& nCurIndex, - CFX_ByteString& csName, - CPDF_Array** ppFind, - int nLevel = 0) { - if (nLevel > nMaxRecursion) - return nullptr; - - CPDF_Array* pNames = pNode->GetArrayBy("Names"); - if (pNames) { - size_t nCount = pNames->GetCount() / 2; - if (nIndex >= nCurIndex + nCount) { - nCurIndex += nCount; - return nullptr; - } - if (ppFind) - *ppFind = pNames; - csName = pNames->GetStringAt((nIndex - nCurIndex) * 2); - return pNames->GetDirectObjectAt((nIndex - nCurIndex) * 2 + 1); - } - 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 = - SearchNameNode(pKid, nIndex, nCurIndex, csName, ppFind, nLevel + 1); - if (pFound) - return pFound; - } - return nullptr; -} - -static size_t CountNames(CPDF_Dictionary* pNode, int nLevel = 0) { - if (nLevel > nMaxRecursion) { - return 0; - } - CPDF_Array* pNames = pNode->GetArrayBy("Names"); - if (pNames) { - return pNames->GetCount() / 2; - } - CPDF_Array* pKids = pNode->GetArrayBy("Kids"); - if (!pKids) { - return 0; - } - size_t nCount = 0; - for (size_t i = 0; i < pKids->GetCount(); i++) { - CPDF_Dictionary* pKid = pKids->GetDictAt(i); - if (!pKid) { - continue; - } - nCount += CountNames(pKid, nLevel + 1); - } - return nCount; -} - -size_t CPDF_NameTree::GetCount() const { - if (!m_pRoot) { - return 0; - } - return ::CountNames(m_pRoot); -} - -int CPDF_NameTree::GetIndex(const CFX_ByteString& csName) const { - if (!m_pRoot) { - return -1; - } - size_t nIndex = 0; - if (!SearchNameNode(m_pRoot, csName, nIndex, nullptr)) { - return -1; - } - return nIndex; -} - -CPDF_Object* CPDF_NameTree::LookupValue(int nIndex, - CFX_ByteString& csName) const { - if (!m_pRoot) { - return nullptr; - } - size_t nCurIndex = 0; - return SearchNameNode(m_pRoot, nIndex, nCurIndex, csName, nullptr); -} - -CPDF_Object* CPDF_NameTree::LookupValue(const CFX_ByteString& csName) const { - if (!m_pRoot) { - return nullptr; - } - size_t nIndex = 0; - return SearchNameNode(m_pRoot, csName, nIndex, nullptr); -} - -CPDF_Array* CPDF_NameTree::LookupNamedDest(CPDF_Document* pDoc, - const CFX_ByteString& sName) { - CPDF_Object* pValue = LookupValue(sName); - if (!pValue) { - CPDF_Dictionary* pDests = pDoc->GetRoot()->GetDictBy("Dests"); - if (!pDests) - return nullptr; - pValue = pDests->GetDirectObjectBy(sName); - } - if (!pValue) - return nullptr; - if (CPDF_Array* pArray = pValue->AsArray()) - return pArray; - if (CPDF_Dictionary* pDict = pValue->AsDictionary()) - return pDict->GetArrayBy("D"); - return nullptr; -} - -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || \ - _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ -static CFX_WideString ChangeSlashToPlatform(const FX_WCHAR* str) { - CFX_WideString result; - while (*str) { - if (*str == '/') { -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - result += ':'; -#else - result += '\\'; -#endif - } else { - result += *str; - } - str++; - } - return result; -} - -static CFX_WideString ChangeSlashToPDF(const FX_WCHAR* str) { - CFX_WideString result; - while (*str) { - if (*str == '\\' || *str == ':') { - result += '/'; - } else { - result += *str; - } - str++; - } - return result; -} -#endif // _FXM_PLATFORM_APPLE_ || _FXM_PLATFORM_WINDOWS_ - -CFX_WideString CPDF_FileSpec::DecodeFileName(const CFX_WideStringC& filepath) { - if (filepath.GetLength() <= 1) - return CFX_WideString(); - -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if (filepath.Left(sizeof("/Mac") - 1) == CFX_WideStringC(L"/Mac")) - return ChangeSlashToPlatform(filepath.c_str() + 1); - return ChangeSlashToPlatform(filepath.c_str()); -#elif _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ - if (filepath.GetAt(0) != '/') - return ChangeSlashToPlatform(filepath.c_str()); - if (filepath.GetAt(1) == '/') - return ChangeSlashToPlatform(filepath.c_str() + 1); - if (filepath.GetAt(2) == '/') { - CFX_WideString result; - result += filepath.GetAt(1); - result += ':'; - result += ChangeSlashToPlatform(filepath.c_str() + 2); - return result; - } - CFX_WideString result; - result += '\\'; - result += ChangeSlashToPlatform(filepath.c_str()); - return result; -#else - return CFX_WideString(filepath); -#endif -} - -bool CPDF_FileSpec::GetFileName(CFX_WideString* csFileName) const { - if (CPDF_Dictionary* pDict = m_pObj->AsDictionary()) { - *csFileName = pDict->GetUnicodeTextBy("UF"); - if (csFileName->IsEmpty()) { - *csFileName = - CFX_WideString::FromLocal(pDict->GetStringBy("F").AsStringC()); - } - if (pDict->GetStringBy("FS") == "URL") - return true; - if (csFileName->IsEmpty()) { - if (pDict->KeyExist("DOS")) { - *csFileName = - CFX_WideString::FromLocal(pDict->GetStringBy("DOS").AsStringC()); - } else if (pDict->KeyExist("Mac")) { - *csFileName = - CFX_WideString::FromLocal(pDict->GetStringBy("Mac").AsStringC()); - } else if (pDict->KeyExist("Unix")) { - *csFileName = - CFX_WideString::FromLocal(pDict->GetStringBy("Unix").AsStringC()); - } else { - return false; - } - } - } else if (m_pObj->IsString()) { - *csFileName = CFX_WideString::FromLocal(m_pObj->GetString().AsStringC()); - } else { - return false; - } - *csFileName = DecodeFileName(csFileName->AsStringC()); - return true; -} - -CPDF_FileSpec::CPDF_FileSpec() { - m_pObj = new CPDF_Dictionary; - m_pObj->AsDictionary()->SetAtName("Type", "Filespec"); -} - -CFX_WideString CPDF_FileSpec::EncodeFileName(const CFX_WideStringC& filepath) { - if (filepath.GetLength() <= 1) { - return CFX_WideString(); - } -#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ - if (filepath.GetAt(1) == ':') { - CFX_WideString result; - result = '/'; - result += filepath.GetAt(0); - if (filepath.GetAt(2) != '\\') { - result += '/'; - } - result += ChangeSlashToPDF(filepath.c_str() + 2); - return result; - } - if (filepath.GetAt(0) == '\\' && filepath.GetAt(1) == '\\') { - return ChangeSlashToPDF(filepath.c_str() + 1); - } - if (filepath.GetAt(0) == '\\') { - CFX_WideString result; - result = '/'; - result += ChangeSlashToPDF(filepath.c_str()); - return result; - } - return ChangeSlashToPDF(filepath.c_str()); -#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if (filepath.Left(sizeof("Mac") - 1) == FX_WSTRC(L"Mac")) { - CFX_WideString result; - result = '/'; - result += ChangeSlashToPDF(filepath.c_str()); - return result; - } - return ChangeSlashToPDF(filepath.c_str()); -#else - return CFX_WideString(filepath); -#endif -} - -void CPDF_FileSpec::SetFileName(const CFX_WideStringC& wsFileName) { - if (!m_pObj) - return; - - CFX_WideString wsStr = EncodeFileName(wsFileName); - if (m_pObj->IsString()) { - m_pObj->SetString(CFX_ByteString::FromUnicode(wsStr)); - } else if (CPDF_Dictionary* pDict = m_pObj->AsDictionary()) { - pDict->SetAtString("F", CFX_ByteString::FromUnicode(wsStr)); - pDict->SetAtString("UF", PDF_EncodeText(wsStr)); - } -} - -static CFX_WideString _MakeRoman(int num) { - const int arabic[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; - const CFX_WideString roman[] = {L"m", L"cm", L"d", L"cd", L"c", - L"xc", L"l", L"xl", L"x", L"ix", - L"v", L"iv", L"i"}; - const int nMaxNum = 1000000; - num %= nMaxNum; - int i = 0; - CFX_WideString wsRomanNumber; - while (num > 0) { - while (num >= arabic[i]) { - num = num - arabic[i]; - wsRomanNumber += roman[i]; - } - i = i + 1; - } - return wsRomanNumber; -} - -static CFX_WideString _MakeLetters(int num) { - if (num == 0) { - return CFX_WideString(); - } - CFX_WideString wsLetters; - const int nMaxCount = 1000; - const int nLetterCount = 26; - num -= 1; - int count = num / nLetterCount + 1; - count %= nMaxCount; - FX_WCHAR ch = L'a' + num % nLetterCount; - for (int i = 0; i < count; i++) { - wsLetters += ch; - } - return wsLetters; -} - -static CFX_WideString _GetLabelNumPortion(int num, - const CFX_ByteString& bsStyle) { - CFX_WideString wsNumPortion; - if (bsStyle.IsEmpty()) { - return wsNumPortion; - } - if (bsStyle == "D") { - wsNumPortion.Format(L"%d", num); - } else if (bsStyle == "R") { - wsNumPortion = _MakeRoman(num); - wsNumPortion.MakeUpper(); - } else if (bsStyle == "r") { - wsNumPortion = _MakeRoman(num); - } else if (bsStyle == "A") { - wsNumPortion = _MakeLetters(num); - wsNumPortion.MakeUpper(); - } else if (bsStyle == "a") { - wsNumPortion = _MakeLetters(num); - } - return wsNumPortion; -} - -IPDF_FormNotify::~IPDF_FormNotify() {} - -int IPDF_FormNotify::BeforeValueChange(CPDF_FormField* pField, - const CFX_WideString& csValue) { - return 0; -} - -void IPDF_FormNotify::AfterValueChange(CPDF_FormField* pField) {} - -int IPDF_FormNotify::BeforeSelectionChange(CPDF_FormField* pField, - const CFX_WideString& csValue) { - return 0; -} - -void IPDF_FormNotify::AfterSelectionChange(CPDF_FormField* pField) {} - -void IPDF_FormNotify::AfterCheckedStatusChange(CPDF_FormField* pField) {} - -int IPDF_FormNotify::BeforeFormReset(CPDF_InterForm* pForm) { - return 0; -} - -void IPDF_FormNotify::AfterFormReset(CPDF_InterForm* pForm) {} - -int IPDF_FormNotify::BeforeFormImportData(CPDF_InterForm* pForm) { - return 0; -} - -void IPDF_FormNotify::AfterFormImportData(CPDF_InterForm* pForm) {} - -CPDF_PageLabel::CPDF_PageLabel(CPDF_Document* pDocument) - : m_pDocument(pDocument) {} - -CFX_WideString CPDF_PageLabel::GetLabel(int nPage) const { - CFX_WideString wsLabel; - if (!m_pDocument) { - return wsLabel; - } - CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot(); - if (!pPDFRoot) { - return wsLabel; - } - CPDF_Dictionary* pLabels = pPDFRoot->GetDictBy("PageLabels"); - CPDF_NumberTree numberTree(pLabels); - CPDF_Object* pValue = nullptr; - int n = nPage; - while (n >= 0) { - pValue = numberTree.LookupValue(n); - if (pValue) { - break; - } - n--; - } - if (pValue) { - pValue = pValue->GetDirect(); - if (CPDF_Dictionary* pLabel = pValue->AsDictionary()) { - if (pLabel->KeyExist("P")) { - wsLabel += pLabel->GetUnicodeTextBy("P"); - } - CFX_ByteString bsNumberingStyle = pLabel->GetStringBy("S", ""); - int nLabelNum = nPage - n + pLabel->GetIntegerBy("St", 1); - CFX_WideString wsNumPortion = - _GetLabelNumPortion(nLabelNum, bsNumberingStyle); - wsLabel += wsNumPortion; - return wsLabel; - } - } - wsLabel.Format(L"%d", nPage + 1); - return wsLabel; -} - -int32_t CPDF_PageLabel::GetPageByLabel(const CFX_ByteStringC& bsLabel) const { - if (!m_pDocument) - return -1; - - CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot(); - if (!pPDFRoot) - return -1; - - int nPages = m_pDocument->GetPageCount(); - for (int i = 0; i < nPages; i++) { - if (PDF_EncodeText(GetLabel(i)).Compare(bsLabel)) - return i; - } - - int nPage = FXSYS_atoi(CFX_ByteString(bsLabel).c_str()); // NUL terminate. - return nPage > 0 && nPage <= nPages ? nPage : -1; -} - -int32_t CPDF_PageLabel::GetPageByLabel(const CFX_WideStringC& wsLabel) const { - return GetPageByLabel(PDF_EncodeText(wsLabel.c_str()).AsStringC()); -} diff --git a/core/fpdfdoc/doc_basic_unittest.cpp b/core/fpdfdoc/doc_basic_unittest.cpp deleted file mode 100644 index 23e88385d1..0000000000 --- a/core/fpdfdoc/doc_basic_unittest.cpp +++ /dev/null @@ -1,169 +0,0 @@ -// 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. - -#include -#include - -#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" -#include "core/fpdfapi/fpdf_parser/include/cpdf_name.h" -#include "core/fpdfapi/fpdf_parser/include/cpdf_string.h" -#include "core/fpdfdoc/include/cpdf_filespec.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/test_support.h" - -namespace { - -using ScopedObj = std::unique_ptr>; -using ScopedDict = - std::unique_ptr>; -} - -TEST(doc_basic_filespec, EncodeDecodeFileName) { - std::vector test_data = { - // Empty src string. - {L"", L""}, - // only file name. - {L"test.pdf", L"test.pdf"}, -#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ - // With drive identifier. - {L"r:\\pdfdocs\\spec.pdf", L"/r/pdfdocs/spec.pdf"}, - // Relative path. - {L"My Document\\test.pdf", L"My Document/test.pdf"}, - // Absolute path without drive identifier. - {L"\\pdfdocs\\spec.pdf", L"//pdfdocs/spec.pdf"}, - // Absolute path with double backslashes. - {L"\\\\pdfdocs\\spec.pdf", L"/pdfdocs/spec.pdf"}, -// Network resource name. It is not supported yet. -// {L"pclib/eng:\\pdfdocs\\spec.pdf", L"/pclib/eng/pdfdocs/spec.pdf"}, -#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - // Absolute path with colon separator. - {L"Mac HD:PDFDocs:spec.pdf", L"/Mac HD/PDFDocs/spec.pdf"}, - // Relative path with colon separator. - {L"PDFDocs:spec.pdf", L"PDFDocs/spec.pdf"}, -#else - // Relative path. - {L"./docs/test.pdf", L"./docs/test.pdf"}, - // Relative path with parent dir. - {L"../test_docs/test.pdf", L"../test_docs/test.pdf"}, - // Absolute path. - {L"/usr/local/home/test.pdf", L"/usr/local/home/test.pdf"}, -#endif - }; - for (const auto& data : test_data) { - CFX_WideString encoded_str = CPDF_FileSpec::EncodeFileName(data.input); - EXPECT_TRUE(encoded_str == data.expected); - // DecodeFileName is the reverse procedure of EncodeFileName. - CFX_WideString decoded_str = CPDF_FileSpec::DecodeFileName(data.expected); - EXPECT_TRUE(decoded_str == data.input); - } -} - -TEST(doc_basic_filespec, GetFileName) { - { - // String object. - pdfium::NullTermWstrFuncTestData test_data = { -#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ - L"/C/docs/test.pdf", - L"C:\\docs\\test.pdf" -#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - L"/Mac HD/docs/test.pdf", - L"Mac HD:docs:test.pdf" -#else - L"/docs/test.pdf", - L"/docs/test.pdf" -#endif - }; - ScopedObj str_obj(new CPDF_String(test_data.input)); - CPDF_FileSpec file_spec(str_obj.get()); - CFX_WideString file_name; - EXPECT_TRUE(file_spec.GetFileName(&file_name)); - EXPECT_TRUE(file_name == test_data.expected); - } - { - // Dictionary object. - pdfium::NullTermWstrFuncTestData test_data[5] = { -#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ - {L"/C/docs/test.pdf", L"C:\\docs\\test.pdf"}, - {L"/D/docs/test.pdf", L"D:\\docs\\test.pdf"}, - {L"/E/docs/test.pdf", L"E:\\docs\\test.pdf"}, - {L"/F/docs/test.pdf", L"F:\\docs\\test.pdf"}, - {L"/G/docs/test.pdf", L"G:\\docs\\test.pdf"}, -#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - {L"/Mac HD/docs1/test.pdf", L"Mac HD:docs1:test.pdf"}, - {L"/Mac HD/docs2/test.pdf", L"Mac HD:docs2:test.pdf"}, - {L"/Mac HD/docs3/test.pdf", L"Mac HD:docs3:test.pdf"}, - {L"/Mac HD/docs4/test.pdf", L"Mac HD:docs4:test.pdf"}, - {L"/Mac HD/docs5/test.pdf", L"Mac HD:docs5:test.pdf"}, -#else - {L"/docs/a/test.pdf", L"/docs/a/test.pdf"}, - {L"/docs/b/test.pdf", L"/docs/b/test.pdf"}, - {L"/docs/c/test.pdf", L"/docs/c/test.pdf"}, - {L"/docs/d/test.pdf", L"/docs/d/test.pdf"}, - {L"/docs/e/test.pdf", L"/docs/e/test.pdf"}, -#endif - }; - // Keyword fields in reverse order of precedence to retrieve the file name. - const char* const keywords[5] = {"Unix", "Mac", "DOS", "F", "UF"}; - ScopedDict dict_obj(new CPDF_Dictionary); - CPDF_FileSpec file_spec(dict_obj.get()); - CFX_WideString file_name; - for (int i = 0; i < 5; ++i) { - dict_obj->SetAt(keywords[i], new CPDF_String(test_data[i].input)); - EXPECT_TRUE(file_spec.GetFileName(&file_name)); - EXPECT_TRUE(file_name == test_data[i].expected); - } - - // With all the former fields and 'FS' field suggests 'URL' type. - dict_obj->SetAtString("FS", "URL"); - EXPECT_TRUE(file_spec.GetFileName(&file_name)); - // Url string is not decoded. - EXPECT_TRUE(file_name == test_data[4].input); - } - { - // Invalid object. - ScopedObj name_obj(new CPDF_Name("test.pdf")); - CPDF_FileSpec file_spec(name_obj.get()); - CFX_WideString file_name; - EXPECT_FALSE(file_spec.GetFileName(&file_name)); - } -} - -TEST(doc_basic_filespec, SetFileName) { - pdfium::NullTermWstrFuncTestData test_data = { -#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ - L"C:\\docs\\test.pdf", - L"/C/docs/test.pdf" -#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - L"Mac HD:docs:test.pdf", - L"/Mac HD/docs/test.pdf" -#else - L"/docs/test.pdf", - L"/docs/test.pdf" -#endif - }; - // String object. - ScopedObj str_obj(new CPDF_String(L"babababa")); - CPDF_FileSpec file_spec1(str_obj.get()); - file_spec1.SetFileName(test_data.input); - // Check internal object value. - CFX_ByteString str = CFX_ByteString::FromUnicode(test_data.expected); - EXPECT_TRUE(str == str_obj->GetString()); - // Check we can get the file name back. - CFX_WideString file_name; - EXPECT_TRUE(file_spec1.GetFileName(&file_name)); - EXPECT_TRUE(file_name == test_data.input); - - // Dictionary object. - ScopedDict dict_obj(new CPDF_Dictionary); - CPDF_FileSpec file_spec2(dict_obj.get()); - file_spec2.SetFileName(test_data.input); - // Check internal object value. - file_name = dict_obj->GetUnicodeTextBy("F"); - EXPECT_TRUE(file_name == test_data.expected); - file_name = dict_obj->GetUnicodeTextBy("UF"); - EXPECT_TRUE(file_name == test_data.expected); - // Check we can get the file name back. - EXPECT_TRUE(file_spec2.GetFileName(&file_name)); - EXPECT_TRUE(file_name == test_data.input); -} diff --git a/core/fpdfdoc/doc_ocg.cpp b/core/fpdfdoc/doc_ocg.cpp deleted file mode 100644 index 50bae65800..0000000000 --- a/core/fpdfdoc/doc_ocg.cpp +++ /dev/null @@ -1,285 +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 "core/fpdfdoc/include/cpdf_occontext.h" - -#include "core/fpdfapi/fpdf_page/cpdf_contentmarkdata.h" -#include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h" -#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" - -namespace { - -int32_t FPDFDOC_OCG_FindGroup(const CPDF_Array* pArray, - const CPDF_Dictionary* pGroupDict) { - if (!pArray || !pGroupDict) - return -1; - - for (size_t i = 0; i < pArray->GetCount(); i++) { - if (pArray->GetDictAt(i) == pGroupDict) - return i; - } - return -1; -} - -bool FPDFDOC_OCG_HasIntent(const CPDF_Dictionary* pDict, - const CFX_ByteStringC& csElement, - const CFX_ByteStringC& csDef) { - CPDF_Object* pIntent = pDict->GetDirectObjectBy("Intent"); - if (!pIntent) - return csElement == csDef; - - CFX_ByteString bsIntent; - if (CPDF_Array* pArray = pIntent->AsArray()) { - for (size_t i = 0; i < pArray->GetCount(); i++) { - bsIntent = pArray->GetStringAt(i); - if (bsIntent == "All" || bsIntent == csElement) - return true; - } - return false; - } - bsIntent = pIntent->GetString(); - return bsIntent == "All" || bsIntent == csElement; -} - -CPDF_Dictionary* FPDFDOC_OCG_GetConfig(CPDF_Document* pDoc, - const CPDF_Dictionary* pOCGDict) { - ASSERT(pOCGDict); - CPDF_Dictionary* pOCProperties = pDoc->GetRoot()->GetDictBy("OCProperties"); - if (!pOCProperties) - return nullptr; - - CPDF_Array* pOCGs = pOCProperties->GetArrayBy("OCGs"); - if (!pOCGs) - return nullptr; - - if (FPDFDOC_OCG_FindGroup(pOCGs, pOCGDict) < 0) - return nullptr; - - CPDF_Dictionary* pConfig = pOCProperties->GetDictBy("D"); - CPDF_Array* pConfigs = pOCProperties->GetArrayBy("Configs"); - if (!pConfigs) - return pConfig; - - for (size_t i = 0; i < pConfigs->GetCount(); i++) { - CPDF_Dictionary* pFind = pConfigs->GetDictAt(i); - if (pFind && FPDFDOC_OCG_HasIntent(pFind, "View", "View")) - return pFind; - } - return pConfig; -} - -CFX_ByteString FPDFDOC_OCG_GetUsageTypeString(CPDF_OCContext::UsageType eType) { - CFX_ByteString csState; - switch (eType) { - case CPDF_OCContext::Design: - csState = "Design"; - break; - case CPDF_OCContext::Print: - csState = "Print"; - break; - case CPDF_OCContext::Export: - csState = "Export"; - break; - default: - csState = "View"; - break; - } - return csState; -} - -} // namespace - -CPDF_OCContext::CPDF_OCContext(CPDF_Document* pDoc, UsageType eUsageType) - : m_pDocument(pDoc), m_eUsageType(eUsageType) { - ASSERT(pDoc); -} - -CPDF_OCContext::~CPDF_OCContext() { -} - -bool CPDF_OCContext::LoadOCGStateFromConfig( - const CFX_ByteString& csConfig, - const CPDF_Dictionary* pOCGDict) const { - CPDF_Dictionary* pConfig = FPDFDOC_OCG_GetConfig(m_pDocument, pOCGDict); - if (!pConfig) - return true; - - bool bState = pConfig->GetStringBy("BaseState", "ON") != "OFF"; - CPDF_Array* pArray = pConfig->GetArrayBy("ON"); - if (pArray) { - if (FPDFDOC_OCG_FindGroup(pArray, pOCGDict) >= 0) - bState = true; - } - pArray = pConfig->GetArrayBy("OFF"); - if (pArray) { - if (FPDFDOC_OCG_FindGroup(pArray, pOCGDict) >= 0) - bState = false; - } - pArray = pConfig->GetArrayBy("AS"); - if (!pArray) - return bState; - - CFX_ByteString csFind = csConfig + "State"; - for (size_t i = 0; i < pArray->GetCount(); i++) { - CPDF_Dictionary* pUsage = pArray->GetDictAt(i); - if (!pUsage) - continue; - - if (pUsage->GetStringBy("Event", "View") != csConfig) - continue; - - CPDF_Array* pOCGs = pUsage->GetArrayBy("OCGs"); - if (!pOCGs) - continue; - - if (FPDFDOC_OCG_FindGroup(pOCGs, pOCGDict) < 0) - continue; - - CPDF_Dictionary* pState = pUsage->GetDictBy(csConfig); - if (!pState) - continue; - - bState = pState->GetStringBy(csFind) != "OFF"; - } - return bState; -} - -bool CPDF_OCContext::LoadOCGState(const CPDF_Dictionary* pOCGDict) const { - if (!FPDFDOC_OCG_HasIntent(pOCGDict, "View", "View")) - return true; - - CFX_ByteString csState = FPDFDOC_OCG_GetUsageTypeString(m_eUsageType); - CPDF_Dictionary* pUsage = pOCGDict->GetDictBy("Usage"); - if (pUsage) { - CPDF_Dictionary* pState = pUsage->GetDictBy(csState); - if (pState) { - CFX_ByteString csFind = csState + "State"; - if (pState->KeyExist(csFind)) { - return pState->GetStringBy(csFind) != "OFF"; - } - } - if (csState != "View") { - pState = pUsage->GetDictBy("View"); - if (pState && pState->KeyExist("ViewState")) { - return pState->GetStringBy("ViewState") != "OFF"; - } - } - } - return LoadOCGStateFromConfig(csState, pOCGDict); -} - -bool CPDF_OCContext::GetOCGVisible(const CPDF_Dictionary* pOCGDict) { - if (!pOCGDict) - return false; - - const auto it = m_OCGStates.find(pOCGDict); - if (it != m_OCGStates.end()) - return it->second; - - bool bState = LoadOCGState(pOCGDict); - m_OCGStates[pOCGDict] = bState; - return bState; -} - -bool CPDF_OCContext::CheckObjectVisible(const CPDF_PageObject* pObj) { - const CPDF_ContentMarkData* pData = pObj->m_ContentMark.GetObject(); - for (int i = 0; i < pData->CountItems(); i++) { - const CPDF_ContentMarkItem& item = pData->GetItem(i); - if (item.GetName() == "OC" && - item.GetParamType() == CPDF_ContentMarkItem::PropertiesDict && - !CheckOCGVisible(item.GetParam())) { - return false; - } - } - return true; -} - -bool CPDF_OCContext::GetOCGVE(CPDF_Array* pExpression, int nLevel) { - if (nLevel > 32 || !pExpression) - return false; - - CFX_ByteString csOperator = pExpression->GetStringAt(0); - if (csOperator == "Not") { - CPDF_Object* pOCGObj = pExpression->GetDirectObjectAt(1); - if (!pOCGObj) - return false; - if (CPDF_Dictionary* pDict = pOCGObj->AsDictionary()) - return !GetOCGVisible(pDict); - if (CPDF_Array* pArray = pOCGObj->AsArray()) - return !GetOCGVE(pArray, nLevel + 1); - return false; - } - - if (csOperator != "Or" && csOperator != "And") - return false; - - bool bValue = false; - for (size_t i = 1; i < pExpression->GetCount(); i++) { - CPDF_Object* pOCGObj = pExpression->GetDirectObjectAt(1); - if (!pOCGObj) - continue; - - bool bItem = false; - if (CPDF_Dictionary* pDict = pOCGObj->AsDictionary()) - bItem = GetOCGVisible(pDict); - else if (CPDF_Array* pArray = pOCGObj->AsArray()) - bItem = GetOCGVE(pArray, nLevel + 1); - - if (i == 1) { - bValue = bItem; - } else { - if (csOperator == "Or") { - bValue = bValue || bItem; - } else { - bValue = bValue && bItem; - } - } - } - return bValue; -} - -bool CPDF_OCContext::LoadOCMDState(const CPDF_Dictionary* pOCMDDict) { - CPDF_Array* pVE = pOCMDDict->GetArrayBy("VE"); - if (pVE) - return GetOCGVE(pVE, 0); - - CFX_ByteString csP = pOCMDDict->GetStringBy("P", "AnyOn"); - CPDF_Object* pOCGObj = pOCMDDict->GetDirectObjectBy("OCGs"); - if (!pOCGObj) - return true; - - if (const CPDF_Dictionary* pDict = pOCGObj->AsDictionary()) - return GetOCGVisible(pDict); - - CPDF_Array* pArray = pOCGObj->AsArray(); - if (!pArray) - return true; - - bool bState = (csP == "AllOn" || csP == "AllOff"); - for (size_t i = 0; i < pArray->GetCount(); i++) { - bool bItem = true; - CPDF_Dictionary* pItemDict = pArray->GetDictAt(i); - if (pItemDict) - bItem = GetOCGVisible(pItemDict); - - if ((csP == "AnyOn" && bItem) || (csP == "AnyOff" && !bItem)) - return true; - if ((csP == "AllOn" && !bItem) || (csP == "AllOff" && bItem)) - return false; - } - return bState; -} - -bool CPDF_OCContext::CheckOCGVisible(const CPDF_Dictionary* pOCGDict) { - if (!pOCGDict) - return true; - - CFX_ByteString csType = pOCGDict->GetStringBy("Type", "OCG"); - if (csType == "OCG") - return GetOCGVisible(pOCGDict); - return LoadOCMDState(pOCGDict); -} diff --git a/core/fpdfdoc/doc_vt.cpp b/core/fpdfdoc/doc_vt.cpp deleted file mode 100644 index 84d6a1ac07..0000000000 --- a/core/fpdfdoc/doc_vt.cpp +++ /dev/null @@ -1,58 +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 "core/fpdfdoc/pdf_vt.h" - -CLine::CLine() {} - -CLine::~CLine() {} - -CPVT_WordPlace CLine::GetBeginWordPlace() const { - return CPVT_WordPlace(LinePlace.nSecIndex, LinePlace.nLineIndex, -1); -} - -CPVT_WordPlace CLine::GetEndWordPlace() const { - return CPVT_WordPlace(LinePlace.nSecIndex, LinePlace.nLineIndex, - m_LineInfo.nEndWordIndex); -} - -CPVT_WordPlace CLine::GetPrevWordPlace(const CPVT_WordPlace& place) const { - if (place.nWordIndex > m_LineInfo.nEndWordIndex) { - return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, - m_LineInfo.nEndWordIndex); - } - return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, - place.nWordIndex - 1); -} - -CPVT_WordPlace CLine::GetNextWordPlace(const CPVT_WordPlace& place) const { - if (place.nWordIndex < m_LineInfo.nBeginWordIndex) { - return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, - m_LineInfo.nBeginWordIndex); - } - return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, - place.nWordIndex + 1); -} - -CPDF_EditContainer::CPDF_EditContainer() {} - -CPDF_EditContainer::~CPDF_EditContainer() {} - -void CPDF_EditContainer::SetPlateRect(const CFX_FloatRect& rect) { - m_rcPlate = rect; -} - -const CFX_FloatRect& CPDF_EditContainer::GetPlateRect() const { - return m_rcPlate; -} - -void CPDF_EditContainer::SetContentRect(const CPVT_FloatRect& rect) { - m_rcContent = rect; -} - -CFX_FloatRect CPDF_EditContainer::GetContentRect() const { - return m_rcContent; -} diff --git a/core/fpdfdoc/include/cpdf_variabletext.h b/core/fpdfdoc/include/cpdf_variabletext.h index c898b18ad8..fa5fe07dba 100644 --- a/core/fpdfdoc/include/cpdf_variabletext.h +++ b/core/fpdfdoc/include/cpdf_variabletext.h @@ -9,12 +9,12 @@ #include +#include "core/fpdfdoc/cpvt_arraytemplate.h" #include "core/fpdfdoc/cpvt_floatrect.h" #include "core/fpdfdoc/cpvt_lineinfo.h" #include "core/fpdfdoc/include/cpvt_line.h" #include "core/fpdfdoc/include/cpvt_wordplace.h" #include "core/fpdfdoc/include/cpvt_wordrange.h" -#include "core/fpdfdoc/pdf_vt.h" #include "core/fxcrt/include/fx_coordinates.h" #include "core/fxcrt/include/fx_string.h" #include "core/fxcrt/include/fx_system.h" @@ -32,7 +32,7 @@ struct CPVT_WordProps; #define VARIABLETEXT_HALF 0.5f -class CPDF_VariableText : private CPDF_EditContainer { +class CPDF_VariableText { public: enum class ScriptType { Normal, Super, Sub }; @@ -82,15 +82,15 @@ class CPDF_VariableText : private CPDF_EditContainer { }; CPDF_VariableText(); - ~CPDF_VariableText() override; + ~CPDF_VariableText(); void SetProvider(CPDF_VariableText::Provider* pProvider); CPDF_VariableText::Iterator* GetIterator(); - // CPDF_EditContainer. - void SetPlateRect(const CFX_FloatRect& rect) override; - CFX_FloatRect GetContentRect() const override; - const CFX_FloatRect& GetPlateRect() const override; + void SetContentRect(const CPVT_FloatRect& rect); + CFX_FloatRect GetContentRect() const; + void SetPlateRect(const CFX_FloatRect& rect); + const CFX_FloatRect& GetPlateRect() const; void SetAlignment(int32_t nFormat) { m_nAlignment = nFormat; } void SetPasswordChar(uint16_t wSubWord) { m_wSubWord = wSubWord; } @@ -151,6 +151,17 @@ class CPDF_VariableText : private CPDF_EditContainer { uint16_t GetSubWord() const { return m_wSubWord; } + FX_FLOAT GetPlateWidth() const { return m_rcPlate.right - m_rcPlate.left; } + FX_FLOAT GetPlateHeight() const { return m_rcPlate.top - m_rcPlate.bottom; } + CFX_SizeF GetPlateSize() const; + CFX_FloatPoint GetBTPoint() const; + CFX_FloatPoint GetETPoint() const; + + CFX_FloatPoint InToOut(const CFX_FloatPoint& point) const; + CFX_FloatPoint OutToIn(const CFX_FloatPoint& point) const; + CFX_FloatRect InToOut(const CPVT_FloatRect& rect) const; + CPVT_FloatRect OutToIn(const CFX_FloatRect& rect) const; + private: friend class CTypeset; friend class CSection; @@ -233,6 +244,8 @@ class CPDF_VariableText : private CPDF_EditContainer { FX_BOOL m_bInitial; CPDF_VariableText::Provider* m_pVTProvider; std::unique_ptr m_pVTIterator; + CFX_FloatRect m_rcPlate; + CPVT_FloatRect m_rcContent; }; #endif // CORE_FPDFDOC_INCLUDE_CPDF_VARIABLETEXT_H_ diff --git a/core/fpdfdoc/ipdf_formnotify.cpp b/core/fpdfdoc/ipdf_formnotify.cpp new file mode 100644 index 0000000000..b36419d0e0 --- /dev/null +++ b/core/fpdfdoc/ipdf_formnotify.cpp @@ -0,0 +1,37 @@ +// 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/ipdf_formnotify.h" + +IPDF_FormNotify::~IPDF_FormNotify() {} + +int IPDF_FormNotify::BeforeValueChange(CPDF_FormField* pField, + const CFX_WideString& csValue) { + return 0; +} + +void IPDF_FormNotify::AfterValueChange(CPDF_FormField* pField) {} + +int IPDF_FormNotify::BeforeSelectionChange(CPDF_FormField* pField, + const CFX_WideString& csValue) { + return 0; +} + +void IPDF_FormNotify::AfterSelectionChange(CPDF_FormField* pField) {} + +void IPDF_FormNotify::AfterCheckedStatusChange(CPDF_FormField* pField) {} + +int IPDF_FormNotify::BeforeFormReset(CPDF_InterForm* pForm) { + return 0; +} + +void IPDF_FormNotify::AfterFormReset(CPDF_InterForm* pForm) {} + +int IPDF_FormNotify::BeforeFormImportData(CPDF_InterForm* pForm) { + return 0; +} + +void IPDF_FormNotify::AfterFormImportData(CPDF_InterForm* pForm) {} diff --git a/core/fpdfdoc/pdf_vt.h b/core/fpdfdoc/pdf_vt.h deleted file mode 100644 index 71e28daad9..0000000000 --- a/core/fpdfdoc/pdf_vt.h +++ /dev/null @@ -1,99 +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 - -#ifndef CORE_FPDFDOC_PDF_VT_H_ -#define CORE_FPDFDOC_PDF_VT_H_ - -#include "core/fpdfdoc/cpvt_floatrect.h" -#include "core/fpdfdoc/cpvt_lineinfo.h" -#include "core/fpdfdoc/include/cpvt_wordrange.h" - -class CPDF_VariableText; - -struct CPVT_WordInfo; - -#define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001) -#define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb))) -#define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb))) -#define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb)) - -template -class CPVT_ArrayTemplate : public CFX_ArrayTemplate { - public: - FX_BOOL IsEmpty() { return CFX_ArrayTemplate::GetSize() <= 0; } - TYPE GetAt(int nIndex) const { - if (nIndex >= 0 && nIndex < CFX_ArrayTemplate::GetSize()) { - return CFX_ArrayTemplate::GetAt(nIndex); - } - return nullptr; - } - void RemoveAt(int nIndex) { - if (nIndex >= 0 && nIndex < CFX_ArrayTemplate::GetSize()) { - CFX_ArrayTemplate::RemoveAt(nIndex); - } - } -}; -class CLine final { - public: - CLine(); - ~CLine(); - - CPVT_WordPlace GetBeginWordPlace() const; - CPVT_WordPlace GetEndWordPlace() const; - CPVT_WordPlace GetPrevWordPlace(const CPVT_WordPlace& place) const; - CPVT_WordPlace GetNextWordPlace(const CPVT_WordPlace& place) const; - CPVT_WordPlace LinePlace; - CPVT_LineInfo m_LineInfo; -}; - -class CPDF_EditContainer { - public: - CPDF_EditContainer(); - virtual ~CPDF_EditContainer(); - - virtual void SetPlateRect(const CFX_FloatRect& rect); - virtual const CFX_FloatRect& GetPlateRect() const; - virtual void SetContentRect(const CPVT_FloatRect& rect); - virtual CFX_FloatRect GetContentRect() const; - - FX_FLOAT GetPlateWidth() const { return m_rcPlate.right - m_rcPlate.left; } - FX_FLOAT GetPlateHeight() const { return m_rcPlate.top - m_rcPlate.bottom; } - CFX_SizeF GetPlateSize() const { - return CFX_SizeF(GetPlateWidth(), GetPlateHeight()); - } - CFX_FloatPoint GetBTPoint() const { - return CFX_FloatPoint(m_rcPlate.left, m_rcPlate.top); - } - CFX_FloatPoint GetETPoint() const { - return CFX_FloatPoint(m_rcPlate.right, m_rcPlate.bottom); - } - CFX_FloatPoint InToOut(const CFX_FloatPoint& point) const { - return CFX_FloatPoint(point.x + GetBTPoint().x, GetBTPoint().y - point.y); - } - CFX_FloatPoint OutToIn(const CFX_FloatPoint& point) const { - return CFX_FloatPoint(point.x - GetBTPoint().x, GetBTPoint().y - point.y); - } - CFX_FloatRect InToOut(const CPVT_FloatRect& rect) const { - CFX_FloatPoint ptLeftTop = InToOut(CFX_FloatPoint(rect.left, rect.top)); - CFX_FloatPoint ptRightBottom = - InToOut(CFX_FloatPoint(rect.right, rect.bottom)); - return CFX_FloatRect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x, - ptLeftTop.y); - } - CPVT_FloatRect OutToIn(const CFX_FloatRect& rect) const { - CFX_FloatPoint ptLeftTop = OutToIn(CFX_FloatPoint(rect.left, rect.top)); - CFX_FloatPoint ptRightBottom = - OutToIn(CFX_FloatPoint(rect.right, rect.bottom)); - return CPVT_FloatRect(ptLeftTop.x, ptLeftTop.y, ptRightBottom.x, - ptRightBottom.y); - } - - private: - CFX_FloatRect m_rcPlate; - CPVT_FloatRect m_rcContent; -}; - -#endif // CORE_FPDFDOC_PDF_VT_H_ diff --git a/core/fxcrt/include/fx_system.h b/core/fxcrt/include/fx_system.h index f4fc2e819c..0542f33047 100644 --- a/core/fxcrt/include/fx_system.h +++ b/core/fxcrt/include/fx_system.h @@ -73,6 +73,11 @@ typedef int FX_BOOL; // Keep, sadly not always 0 or 1. typedef char FX_CHAR; // Keep, questionable signedness. typedef wchar_t FX_WCHAR; // Keep, maybe bad platform wchars. +#define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001) +#define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb))) +#define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb))) +#define IsFloatEqual(fa, fb) IsFloatZero(fa - fb) + // PDFium string sizes are limited to 2^31-1, and the value is signed to // allow -1 as a placeholder for "unknown". // TODO(palmer): it should be a |size_t|, or at least unsigned. -- cgit v1.2.3