diff options
Diffstat (limited to 'core/fpdfdoc')
-rw-r--r-- | core/fpdfdoc/cpdf_defaultappearance.cpp | 65 | ||||
-rw-r--r-- | core/fpdfdoc/cpdf_defaultappearance.h | 5 | ||||
-rw-r--r-- | core/fpdfdoc/cpdf_defaultappearance_unittest.cpp | 47 | ||||
-rw-r--r-- | core/fpdfdoc/cpdf_formfield.cpp | 11 | ||||
-rw-r--r-- | core/fpdfdoc/cpvt_generateap.cpp | 15 |
5 files changed, 124 insertions, 19 deletions
diff --git a/core/fpdfdoc/cpdf_defaultappearance.cpp b/core/fpdfdoc/cpdf_defaultappearance.cpp index cae553a7c2..8878dc0093 100644 --- a/core/fpdfdoc/cpdf_defaultappearance.cpp +++ b/core/fpdfdoc/cpdf_defaultappearance.cpp @@ -7,17 +7,58 @@ #include "core/fpdfdoc/cpdf_defaultappearance.h" #include <algorithm> +#include <vector> #include "core/fpdfapi/parser/cpdf_simple_parser.h" #include "core/fpdfapi/parser/fpdf_parser_decode.h" #include "core/fxge/cfx_color.h" +namespace { + +// Find the token and its |nParams| parameters from the start of data, +// and move the current position to the start of those parameters. +bool FindTagParamFromStart(CPDF_SimpleParser* parser, + const ByteStringView& token, + int nParams) { + nParams++; + + std::vector<uint32_t> pBuf(nParams); + int buf_index = 0; + int buf_count = 0; + + parser->SetCurPos(0); + while (1) { + pBuf[buf_index++] = parser->GetCurPos(); + if (buf_index == nParams) + buf_index = 0; + + buf_count++; + if (buf_count > nParams) + buf_count = nParams; + + ByteStringView word = parser->GetWord(); + if (word.IsEmpty()) + return false; + + if (word == token) { + if (buf_count < nParams) + continue; + + parser->SetCurPos(pBuf[buf_index]); + return true; + } + } + return false; +} + +} // namespace + bool CPDF_DefaultAppearance::HasFont() { if (m_csDA.IsEmpty()) return false; CPDF_SimpleParser syntax(m_csDA.AsStringView()); - return syntax.FindTagParamFromStart("Tf", 2); + return FindTagParamFromStart(&syntax, "Tf", 2); } ByteString CPDF_DefaultAppearance::GetFont(float* fFontSize) { @@ -27,7 +68,7 @@ ByteString CPDF_DefaultAppearance::GetFont(float* fFontSize) { ByteString csFontNameTag; CPDF_SimpleParser syntax(m_csDA.AsStringView()); - if (syntax.FindTagParamFromStart("Tf", 2)) { + if (FindTagParamFromStart(&syntax, "Tf", 2)) { csFontNameTag = ByteString(syntax.GetWord()); csFontNameTag.Delete(0, 1); *fFontSize = FX_atof(syntax.GetWord()); @@ -40,11 +81,11 @@ bool CPDF_DefaultAppearance::HasColor() { return false; CPDF_SimpleParser syntax(m_csDA.AsStringView()); - if (syntax.FindTagParamFromStart("g", 1)) + if (FindTagParamFromStart(&syntax, "g", 1)) return true; - if (syntax.FindTagParamFromStart("rg", 3)) + if (FindTagParamFromStart(&syntax, "rg", 3)) return true; - return syntax.FindTagParamFromStart("k", 4); + return FindTagParamFromStart(&syntax, "k", 4); } void CPDF_DefaultAppearance::GetColor(int& iColorType, float fc[4]) { @@ -56,19 +97,19 @@ void CPDF_DefaultAppearance::GetColor(int& iColorType, float fc[4]) { return; CPDF_SimpleParser syntax(m_csDA.AsStringView()); - if (syntax.FindTagParamFromStart("g", 1)) { + if (FindTagParamFromStart(&syntax, "g", 1)) { iColorType = CFX_Color::kGray; fc[0] = FX_atof(syntax.GetWord()); return; } - if (syntax.FindTagParamFromStart("rg", 3)) { + if (FindTagParamFromStart(&syntax, "rg", 3)) { iColorType = CFX_Color::kRGB; fc[0] = FX_atof(syntax.GetWord()); fc[1] = FX_atof(syntax.GetWord()); fc[2] = FX_atof(syntax.GetWord()); return; } - if (syntax.FindTagParamFromStart("k", 4)) { + if (FindTagParamFromStart(&syntax, "k", 4)) { iColorType = CFX_Color::kCMYK; fc[0] = FX_atof(syntax.GetWord()); fc[1] = FX_atof(syntax.GetWord()); @@ -104,4 +145,12 @@ void CPDF_DefaultAppearance::GetColor(FX_ARGB& color, int& iColorType) { static_cast<int>(g * 255 + 0.5f), static_cast<int>(b * 255 + 0.5f)); } + NOTREACHED(); +} + +bool CPDF_DefaultAppearance::FindTagParamFromStartForTesting( + CPDF_SimpleParser* parser, + const ByteStringView& token, + int nParams) { + return FindTagParamFromStart(parser, token, nParams); } diff --git a/core/fpdfdoc/cpdf_defaultappearance.h b/core/fpdfdoc/cpdf_defaultappearance.h index af13a3f8bc..79ad0bb526 100644 --- a/core/fpdfdoc/cpdf_defaultappearance.h +++ b/core/fpdfdoc/cpdf_defaultappearance.h @@ -7,6 +7,7 @@ #ifndef CORE_FPDFDOC_CPDF_DEFAULTAPPEARANCE_H_ #define CORE_FPDFDOC_CPDF_DEFAULTAPPEARANCE_H_ +#include "core/fpdfapi/parser/cpdf_simple_parser.h" #include "core/fpdfdoc/cpdf_defaultappearance.h" #include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/fx_string.h" @@ -29,6 +30,10 @@ class CPDF_DefaultAppearance { void GetColor(int& iColorType, float fc[4]); void GetColor(FX_ARGB& color, int& iColorType); + bool FindTagParamFromStartForTesting(CPDF_SimpleParser* parser, + const ByteStringView& token, + int nParams); + private: ByteString m_csDA; }; diff --git a/core/fpdfdoc/cpdf_defaultappearance_unittest.cpp b/core/fpdfdoc/cpdf_defaultappearance_unittest.cpp new file mode 100644 index 0000000000..031fa8c89d --- /dev/null +++ b/core/fpdfdoc/cpdf_defaultappearance_unittest.cpp @@ -0,0 +1,47 @@ +// Copyright 2018 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 "core/fpdfdoc/cpdf_defaultappearance.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/test_support.h" + +TEST(CPDFDefaultAppearanceTest, FindTagParamFromStart) { + static const struct FindTagTestStruct { + const unsigned char* input; + unsigned int input_size; + const char* token; + int num_params; + bool result; + unsigned int result_pos; + } test_data[] = { + // Empty strings. + STR_IN_TEST_CASE("", "Tj", 1, false, 0), + STR_IN_TEST_CASE("", "", 1, false, 0), + // Empty token. + STR_IN_TEST_CASE(" T j", "", 1, false, 5), + // No parameter. + STR_IN_TEST_CASE("Tj", "Tj", 1, false, 2), + STR_IN_TEST_CASE("(Tj", "Tj", 1, false, 3), + // Partial token match. + STR_IN_TEST_CASE("\r12\t34 56 78Tj", "Tj", 1, false, 15), + // Regular cases with various parameters. + STR_IN_TEST_CASE("\r\0abd Tj", "Tj", 1, true, 0), + STR_IN_TEST_CASE("12 4 Tj 3 46 Tj", "Tj", 1, true, 2), + STR_IN_TEST_CASE("er^ 2 (34) (5667) Tj", "Tj", 2, true, 5), + STR_IN_TEST_CASE("<344> (232)\t343.4\n12 45 Tj", "Tj", 3, true, 11), + STR_IN_TEST_CASE("1 2 3 4 5 6 7 8 cm", "cm", 6, true, 3), + }; + + CPDF_DefaultAppearance da; + for (size_t i = 0; i < FX_ArraySize(test_data); ++i) { + CPDF_SimpleParser parser( + ByteStringView(test_data[i].input, test_data[i].input_size)); + EXPECT_EQ(test_data[i].result, + da.FindTagParamFromStartForTesting(&parser, test_data[i].token, + test_data[i].num_params)) + << " for case " << i; + EXPECT_EQ(test_data[i].result_pos, parser.GetCurPos()) << " for case " << i; + } +} diff --git a/core/fpdfdoc/cpdf_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp index 679acd1dc8..f3dcac2228 100644 --- a/core/fpdfdoc/cpdf_formfield.cpp +++ b/core/fpdfdoc/cpdf_formfield.cpp @@ -15,9 +15,9 @@ #include "core/fpdfapi/parser/cpdf_document.h" #include "core/fpdfapi/parser/cpdf_name.h" #include "core/fpdfapi/parser/cpdf_number.h" -#include "core/fpdfapi/parser/cpdf_simple_parser.h" #include "core/fpdfapi/parser/cpdf_string.h" #include "core/fpdfapi/parser/fpdf_parser_decode.h" +#include "core/fpdfdoc/cpdf_defaultappearance.h" #include "core/fpdfdoc/cpdf_formcontrol.h" #include "core/fpdfdoc/cpdf_interform.h" #include "core/fpdfdoc/cpvt_generateap.h" @@ -914,15 +914,16 @@ void CPDF_FormField::LoadDA() { if (!pFont) return; - CPDF_SimpleParser syntax(DA.AsStringView()); - syntax.FindTagParamFromStart("Tf", 2); - ByteString font_name(syntax.GetWord()); + CPDF_DefaultAppearance appearance(DA); + if (!appearance.HasFont()) + return; + + ByteString font_name = appearance.GetFont(&m_FontSize); CPDF_Dictionary* pFontDict = pFont->GetDictFor(font_name); if (!pFontDict) return; m_pFont = m_pForm->GetDocument()->LoadFont(pFontDict); - m_FontSize = FX_atof(syntax.GetWord()); } bool CPDF_FormField::NotifyBeforeSelectionChange(const WideString& value) { diff --git a/core/fpdfdoc/cpvt_generateap.cpp b/core/fpdfdoc/cpvt_generateap.cpp index 4138b21a6b..a6a64aaf8d 100644 --- a/core/fpdfdoc/cpvt_generateap.cpp +++ b/core/fpdfdoc/cpvt_generateap.cpp @@ -19,11 +19,11 @@ #include "core/fpdfapi/parser/cpdf_name.h" #include "core/fpdfapi/parser/cpdf_number.h" #include "core/fpdfapi/parser/cpdf_reference.h" -#include "core/fpdfapi/parser/cpdf_simple_parser.h" #include "core/fpdfapi/parser/cpdf_stream.h" #include "core/fpdfapi/parser/cpdf_string.h" #include "core/fpdfapi/parser/fpdf_parser_decode.h" #include "core/fpdfdoc/cpdf_annot.h" +#include "core/fpdfdoc/cpdf_defaultappearance.h" #include "core/fpdfdoc/cpdf_formfield.h" #include "core/fpdfdoc/cpvt_fontmap.h" #include "core/fpdfdoc/cpvt_word.h" @@ -922,14 +922,17 @@ void CPVT_GenerateAP::GenerateFormAP(Type type, if (DA.IsEmpty()) return; - CPDF_SimpleParser syntax(DA.AsStringView()); - syntax.FindTagParamFromStart("Tf", 2); - ByteString sFontName(syntax.GetWord()); - sFontName = PDF_NameDecode(sFontName.AsStringView()); + CPDF_DefaultAppearance appearance(DA); + if (!appearance.HasFont()) + return; + + ASSERT(appearance.HasFont()); + float fFontSize = 0; + ByteString sFontName = + PDF_NameDecode(appearance.GetFont(&fFontSize).AsStringView()); if (sFontName.IsEmpty()) return; - float fFontSize = FX_atof(syntax.GetWord()); CFX_Color crText = CFX_Color::ParseColor(DA); CPDF_Dictionary* pDRDict = pFormDict->GetDictFor("DR"); if (!pDRDict) |