From 95bec8046a28928df627ce4d48eee8b209b3e36e Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Thu, 19 Jan 2017 10:27:58 -0500 Subject: Split fde/css files into individual class files. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This CL splits the files in xfa/fde/css into class per file and renames any needed files to match the class names. Update some of the classes to use std::stack. Change-Id: I4eca0fb3556d949a15a873bb0f0fd732f47e4fb1 Reviewed-on: https://pdfium-review.googlesource.com/2253 Commit-Queue: dsinclair Reviewed-by: Tom Sepez Reviewed-by: Nicolás Peña --- BUILD.gn | 40 +- testing/libfuzzer/pdf_css_fuzzer.cc | 2 +- xfa/fde/css/cfde_cssaccelerator.cpp | 23 + xfa/fde/css/cfde_cssaccelerator.h | 40 + xfa/fde/css/cfde_csscomputedstyle.cpp | 204 ++++++ xfa/fde/css/cfde_csscomputedstyle.h | 112 +++ xfa/fde/css/cfde_csscustomproperty.h | 18 + xfa/fde/css/cfde_cssdeclaration.cpp | 662 +++++++++++++++++ xfa/fde/css/cfde_cssdeclaration.h | 111 +++ xfa/fde/css/cfde_cssdeclaration_unittest.cpp | 61 ++ xfa/fde/css/cfde_cssfontfacerule.cpp | 12 + xfa/fde/css/cfde_cssfontfacerule.h | 24 + xfa/fde/css/cfde_cssmediarule.cpp | 26 + xfa/fde/css/cfde_cssmediarule.h | 31 + xfa/fde/css/cfde_csspropertyholder.cpp | 11 + xfa/fde/css/cfde_csspropertyholder.h | 24 + xfa/fde/css/cfde_cssrulecollection.cpp | 53 +- xfa/fde/css/cfde_cssrulecollection.h | 79 ++ xfa/fde/css/cfde_cssselector.cpp | 162 ++++ xfa/fde/css/cfde_cssselector.h | 44 ++ xfa/fde/css/cfde_cssstylerule.cpp | 30 + xfa/fde/css/cfde_cssstylerule.h | 33 + xfa/fde/css/cfde_cssstyleselector.cpp | 808 ++++++++++++++++++++ xfa/fde/css/cfde_cssstyleselector.h | 95 +++ xfa/fde/css/cfde_cssstylesheet.cpp | 292 ++++++++ xfa/fde/css/cfde_cssstylesheet.h | 55 ++ xfa/fde/css/cfde_cssstylesheet_unittest.cpp | 5 +- xfa/fde/css/cfde_csssyntaxparser.cpp | 380 ++++++++++ xfa/fde/css/cfde_csssyntaxparser.h | 88 +++ xfa/fde/css/cfde_csstagcache.cpp | 44 ++ xfa/fde/css/cfde_csstagcache.h | 46 ++ xfa/fde/css/cfde_csstextbuf.cpp | 86 +++ xfa/fde/css/cfde_csstextbuf.h | 66 ++ xfa/fde/css/fde_css.h | 20 - xfa/fde/css/fde_csscache.cpp | 66 -- xfa/fde/css/fde_csscache.h | 59 -- xfa/fde/css/fde_cssdatatable.cpp | 218 +----- xfa/fde/css/fde_cssdatatable.h | 47 +- xfa/fde/css/fde_cssdatatable_unittest.cpp | 60 -- xfa/fde/css/fde_cssdeclaration.cpp | 552 -------------- xfa/fde/css/fde_cssdeclaration.h | 112 --- xfa/fde/css/fde_cssstyleselector.cpp | 1014 -------------------------- xfa/fde/css/fde_cssstyleselector.h | 249 ------- xfa/fde/css/fde_cssstylesheet.cpp | 484 ------------ xfa/fde/css/fde_cssstylesheet.h | 127 ---- xfa/fde/css/fde_csssyntax.cpp | 442 ----------- xfa/fde/css/fde_csssyntax.h | 122 ---- xfa/fxfa/app/cxfa_textlayout.cpp | 3 +- xfa/fxfa/app/cxfa_textparsecontext.cpp | 5 +- xfa/fxfa/app/cxfa_textparser.cpp | 6 +- xfa/fxfa/app/cxfa_textuserdata.cpp | 3 +- xfa/fxfa/parser/cxfa_scriptcontext.cpp | 2 +- 52 files changed, 3764 insertions(+), 3594 deletions(-) create mode 100644 xfa/fde/css/cfde_cssaccelerator.cpp create mode 100644 xfa/fde/css/cfde_cssaccelerator.h create mode 100644 xfa/fde/css/cfde_csscomputedstyle.cpp create mode 100644 xfa/fde/css/cfde_csscomputedstyle.h create mode 100644 xfa/fde/css/cfde_csscustomproperty.h create mode 100644 xfa/fde/css/cfde_cssdeclaration.cpp create mode 100644 xfa/fde/css/cfde_cssdeclaration.h create mode 100644 xfa/fde/css/cfde_cssdeclaration_unittest.cpp create mode 100644 xfa/fde/css/cfde_cssfontfacerule.cpp create mode 100644 xfa/fde/css/cfde_cssfontfacerule.h create mode 100644 xfa/fde/css/cfde_cssmediarule.cpp create mode 100644 xfa/fde/css/cfde_cssmediarule.h create mode 100644 xfa/fde/css/cfde_csspropertyholder.cpp create mode 100644 xfa/fde/css/cfde_csspropertyholder.h create mode 100644 xfa/fde/css/cfde_cssrulecollection.h create mode 100644 xfa/fde/css/cfde_cssselector.cpp create mode 100644 xfa/fde/css/cfde_cssselector.h create mode 100644 xfa/fde/css/cfde_cssstylerule.cpp create mode 100644 xfa/fde/css/cfde_cssstylerule.h create mode 100644 xfa/fde/css/cfde_cssstyleselector.cpp create mode 100644 xfa/fde/css/cfde_cssstyleselector.h create mode 100644 xfa/fde/css/cfde_cssstylesheet.cpp create mode 100644 xfa/fde/css/cfde_cssstylesheet.h create mode 100644 xfa/fde/css/cfde_csssyntaxparser.cpp create mode 100644 xfa/fde/css/cfde_csssyntaxparser.h create mode 100644 xfa/fde/css/cfde_csstagcache.cpp create mode 100644 xfa/fde/css/cfde_csstagcache.h create mode 100644 xfa/fde/css/cfde_csstextbuf.cpp create mode 100644 xfa/fde/css/cfde_csstextbuf.h delete mode 100644 xfa/fde/css/fde_csscache.cpp delete mode 100644 xfa/fde/css/fde_csscache.h delete mode 100644 xfa/fde/css/fde_cssdatatable_unittest.cpp delete mode 100644 xfa/fde/css/fde_cssdeclaration.cpp delete mode 100644 xfa/fde/css/fde_cssdeclaration.h delete mode 100644 xfa/fde/css/fde_cssstyleselector.cpp delete mode 100644 xfa/fde/css/fde_cssstyleselector.h delete mode 100644 xfa/fde/css/fde_cssstylesheet.cpp delete mode 100644 xfa/fde/css/fde_cssstylesheet.h delete mode 100644 xfa/fde/css/fde_csssyntax.cpp delete mode 100644 xfa/fde/css/fde_csssyntax.h diff --git a/BUILD.gn b/BUILD.gn index 7f1a5f8df5..12c0f603d7 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1143,17 +1143,45 @@ if (pdf_enable_xfa) { "xfa/fde/cfx_chariter.h", "xfa/fde/cfx_wordbreak.cpp", "xfa/fde/cfx_wordbreak.h", + "xfa/fde/css/cfde_cssaccelerator.cpp", + "xfa/fde/css/cfde_cssaccelerator.h", "xfa/fde/css/cfde_csscolorvalue.cpp", "xfa/fde/css/cfde_csscolorvalue.h", + "xfa/fde/css/cfde_csscomputedstyle.cpp", + "xfa/fde/css/cfde_csscomputedstyle.h", + "xfa/fde/css/cfde_csscustomproperty.h", + "xfa/fde/css/cfde_cssdeclaration.cpp", + "xfa/fde/css/cfde_cssdeclaration.h", "xfa/fde/css/cfde_cssenumvalue.cpp", "xfa/fde/css/cfde_cssenumvalue.h", + "xfa/fde/css/cfde_cssfontfacerule.cpp", + "xfa/fde/css/cfde_cssfontfacerule.h", + "xfa/fde/css/cfde_cssmediarule.cpp", + "xfa/fde/css/cfde_cssmediarule.h", "xfa/fde/css/cfde_cssnumbervalue.cpp", "xfa/fde/css/cfde_cssnumbervalue.h", + "xfa/fde/css/cfde_csspropertyholder.cpp", + "xfa/fde/css/cfde_csspropertyholder.h", "xfa/fde/css/cfde_cssrule.cpp", "xfa/fde/css/cfde_cssrule.h", "xfa/fde/css/cfde_cssrulecollection.cpp", + "xfa/fde/css/cfde_cssrulecollection.h", + "xfa/fde/css/cfde_cssselector.cpp", + "xfa/fde/css/cfde_cssselector.h", "xfa/fde/css/cfde_cssstringvalue.cpp", "xfa/fde/css/cfde_cssstringvalue.h", + "xfa/fde/css/cfde_cssstylerule.cpp", + "xfa/fde/css/cfde_cssstylerule.h", + "xfa/fde/css/cfde_cssstyleselector.cpp", + "xfa/fde/css/cfde_cssstyleselector.h", + "xfa/fde/css/cfde_cssstylesheet.cpp", + "xfa/fde/css/cfde_cssstylesheet.h", + "xfa/fde/css/cfde_csssyntaxparser.cpp", + "xfa/fde/css/cfde_csssyntaxparser.h", + "xfa/fde/css/cfde_csstagcache.cpp", + "xfa/fde/css/cfde_csstagcache.h", + "xfa/fde/css/cfde_csstextbuf.cpp", + "xfa/fde/css/cfde_csstextbuf.h", "xfa/fde/css/cfde_cssvalue.cpp", "xfa/fde/css/cfde_cssvalue.h", "xfa/fde/css/cfde_cssvaluelist.cpp", @@ -1161,18 +1189,8 @@ if (pdf_enable_xfa) { "xfa/fde/css/cfde_cssvaluelistparser.cpp", "xfa/fde/css/cfde_cssvaluelistparser.h", "xfa/fde/css/fde_css.h", - "xfa/fde/css/fde_csscache.cpp", - "xfa/fde/css/fde_csscache.h", "xfa/fde/css/fde_cssdatatable.cpp", "xfa/fde/css/fde_cssdatatable.h", - "xfa/fde/css/fde_cssdeclaration.cpp", - "xfa/fde/css/fde_cssdeclaration.h", - "xfa/fde/css/fde_cssstyleselector.cpp", - "xfa/fde/css/fde_cssstyleselector.h", - "xfa/fde/css/fde_cssstylesheet.cpp", - "xfa/fde/css/fde_cssstylesheet.h", - "xfa/fde/css/fde_csssyntax.cpp", - "xfa/fde/css/fde_csssyntax.h", "xfa/fde/fde_gedevice.cpp", "xfa/fde/fde_iterator.cpp", "xfa/fde/fde_iterator.h", @@ -1769,8 +1787,8 @@ test("pdfium_unittests") { if (pdf_enable_xfa) { sources += [ "xfa/fde/cfde_txtedtbuf_unittest.cpp", + "xfa/fde/css/cfde_cssdeclaration_unittest.cpp", "xfa/fde/css/cfde_cssstylesheet_unittest.cpp", - "xfa/fde/css/fde_cssdatatable_unittest.cpp", "xfa/fde/xml/fde_xml_imp_unittest.cpp", "xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp", "xfa/fxfa/app/cxfa_textparser_unittest.cpp", diff --git a/testing/libfuzzer/pdf_css_fuzzer.cc b/testing/libfuzzer/pdf_css_fuzzer.cc index 779f5ca37f..9135b25f3d 100644 --- a/testing/libfuzzer/pdf_css_fuzzer.cc +++ b/testing/libfuzzer/pdf_css_fuzzer.cc @@ -6,8 +6,8 @@ #include "core/fxcrt/cfx_retain_ptr.h" #include "core/fxcrt/fx_string.h" +#include "xfa/fde/css/cfde_csssyntaxparser.h" #include "xfa/fde/css/fde_css.h" -#include "xfa/fde/css/fde_csssyntax.h" #include "xfa/fgas/crt/fgas_stream.h" #include "xfa/fxfa/parser/cxfa_widetextread.h" diff --git a/xfa/fde/css/cfde_cssaccelerator.cpp b/xfa/fde/css/cfde_cssaccelerator.cpp new file mode 100644 index 0000000000..40fa13e058 --- /dev/null +++ b/xfa/fde/css/cfde_cssaccelerator.cpp @@ -0,0 +1,23 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fde/css/cfde_cssaccelerator.h" + +#include "third_party/base/ptr_util.h" + +CFDE_CSSAccelerator::CFDE_CSSAccelerator() {} + +CFDE_CSSAccelerator::~CFDE_CSSAccelerator() {} + +void CFDE_CSSAccelerator::OnEnterTag(CXFA_CSSTagProvider* pTag) { + stack_.push(pdfium::MakeUnique(top(), pTag)); +} + +void CFDE_CSSAccelerator::OnLeaveTag(CXFA_CSSTagProvider* pTag) { + ASSERT(!stack_.empty()); + ASSERT(stack_.top()->GetTag() == pTag); + stack_.pop(); +} diff --git a/xfa/fde/css/cfde_cssaccelerator.h b/xfa/fde/css/cfde_cssaccelerator.h new file mode 100644 index 0000000000..4ef493d79a --- /dev/null +++ b/xfa/fde/css/cfde_cssaccelerator.h @@ -0,0 +1,40 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FDE_CSS_CFDE_CSSACCELERATOR_H_ +#define XFA_FDE_CSS_CFDE_CSSACCELERATOR_H_ + +#include +#include + +#include "xfa/fde/css/cfde_csstagcache.h" + +class CXFA_CSSTagProvider; + +class CFDE_CSSAccelerator { + public: + CFDE_CSSAccelerator(); + ~CFDE_CSSAccelerator(); + + void OnEnterTag(CXFA_CSSTagProvider* pTag); + void OnLeaveTag(CXFA_CSSTagProvider* pTag); + + void Clear() { + std::stack> tmp; + stack_.swap(tmp); + } + + CFDE_CSSTagCache* top() const { + if (stack_.empty()) + return nullptr; + return stack_.top().get(); + } + + private: + std::stack> stack_; +}; + +#endif // XFA_FDE_CSS_CFDE_CSSACCELERATOR_H_ diff --git a/xfa/fde/css/cfde_csscomputedstyle.cpp b/xfa/fde/css/cfde_csscomputedstyle.cpp new file mode 100644 index 0000000000..010f573c04 --- /dev/null +++ b/xfa/fde/css/cfde_csscomputedstyle.cpp @@ -0,0 +1,204 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fde/css/cfde_csscomputedstyle.h" + +#include "third_party/base/stl_util.h" +#include "xfa/fde/css/cfde_cssstringvalue.h" +#include "xfa/fde/css/cfde_cssvaluelist.h" + +CFDE_CSSComputedStyle::CFDE_CSSComputedStyle() : m_dwRefCount(1) {} + +CFDE_CSSComputedStyle::~CFDE_CSSComputedStyle() {} + +uint32_t CFDE_CSSComputedStyle::Retain() { + return ++m_dwRefCount; +} + +uint32_t CFDE_CSSComputedStyle::Release() { + uint32_t dwRefCount = --m_dwRefCount; + if (dwRefCount == 0) + delete this; + return dwRefCount; +} + +bool CFDE_CSSComputedStyle::GetCustomStyle(const CFX_WideStringC& wsName, + CFX_WideString& wsValue) const { + for (int32_t i = pdfium::CollectionSize(m_CustomProperties) - 2; + i > -1; i -= 2) { + if (wsName == m_CustomProperties[i]) { + wsValue = m_CustomProperties[i + 1]; + return true; + } + } + return false; +} + +int32_t CFDE_CSSComputedStyle::CountFontFamilies() const { + return m_InheritedData.m_pFontFamily + ? m_InheritedData.m_pFontFamily->CountValues() + : 0; +} + +const CFX_WideString CFDE_CSSComputedStyle::GetFontFamily(int32_t index) const { + return static_cast( + m_InheritedData.m_pFontFamily->GetValue(index)) + ->Value(); +} + +uint16_t CFDE_CSSComputedStyle::GetFontWeight() const { + return m_InheritedData.m_wFontWeight; +} + +FDE_CSSFontVariant CFDE_CSSComputedStyle::GetFontVariant() const { + return m_InheritedData.m_eFontVariant; +} + +FDE_CSSFontStyle CFDE_CSSComputedStyle::GetFontStyle() const { + return m_InheritedData.m_eFontStyle; +} + +FX_FLOAT CFDE_CSSComputedStyle::GetFontSize() const { + return m_InheritedData.m_fFontSize; +} + +FX_ARGB CFDE_CSSComputedStyle::GetColor() const { + return m_InheritedData.m_dwFontColor; +} + +void CFDE_CSSComputedStyle::SetFontWeight(uint16_t wFontWeight) { + m_InheritedData.m_wFontWeight = wFontWeight; +} + +void CFDE_CSSComputedStyle::SetFontVariant(FDE_CSSFontVariant eFontVariant) { + m_InheritedData.m_eFontVariant = eFontVariant; +} + +void CFDE_CSSComputedStyle::SetFontStyle(FDE_CSSFontStyle eFontStyle) { + m_InheritedData.m_eFontStyle = eFontStyle; +} + +void CFDE_CSSComputedStyle::SetFontSize(FX_FLOAT fFontSize) { + m_InheritedData.m_fFontSize = fFontSize; +} + +void CFDE_CSSComputedStyle::SetColor(FX_ARGB dwFontColor) { + m_InheritedData.m_dwFontColor = dwFontColor; +} + +const FDE_CSSRect* CFDE_CSSComputedStyle::GetBorderWidth() const { + return m_NonInheritedData.m_bHasBorder ? &(m_NonInheritedData.m_BorderWidth) + : nullptr; +} + +const FDE_CSSRect* CFDE_CSSComputedStyle::GetMarginWidth() const { + return m_NonInheritedData.m_bHasMargin ? &(m_NonInheritedData.m_MarginWidth) + : nullptr; +} + +const FDE_CSSRect* CFDE_CSSComputedStyle::GetPaddingWidth() const { + return m_NonInheritedData.m_bHasPadding ? &(m_NonInheritedData.m_PaddingWidth) + : nullptr; +} + +void CFDE_CSSComputedStyle::SetMarginWidth(const FDE_CSSRect& rect) { + m_NonInheritedData.m_MarginWidth = rect; + m_NonInheritedData.m_bHasMargin = true; +} + +void CFDE_CSSComputedStyle::SetPaddingWidth(const FDE_CSSRect& rect) { + m_NonInheritedData.m_PaddingWidth = rect; + m_NonInheritedData.m_bHasPadding = true; +} + +FDE_CSSDisplay CFDE_CSSComputedStyle::GetDisplay() const { + return m_NonInheritedData.m_eDisplay; +} + +FX_FLOAT CFDE_CSSComputedStyle::GetLineHeight() const { + return m_InheritedData.m_fLineHeight; +} + +const FDE_CSSLength& CFDE_CSSComputedStyle::GetTextIndent() const { + return m_InheritedData.m_TextIndent; +} + +FDE_CSSTextAlign CFDE_CSSComputedStyle::GetTextAlign() const { + return m_InheritedData.m_eTextAlign; +} + +FDE_CSSVerticalAlign CFDE_CSSComputedStyle::GetVerticalAlign() const { + return m_NonInheritedData.m_eVerticalAlign; +} + +FX_FLOAT CFDE_CSSComputedStyle::GetNumberVerticalAlign() const { + return m_NonInheritedData.m_fVerticalAlign; +} + +uint32_t CFDE_CSSComputedStyle::GetTextDecoration() const { + return m_NonInheritedData.m_dwTextDecoration; +} + +const FDE_CSSLength& CFDE_CSSComputedStyle::GetLetterSpacing() const { + return m_InheritedData.m_LetterSpacing; +} + +void CFDE_CSSComputedStyle::SetLineHeight(FX_FLOAT fLineHeight) { + m_InheritedData.m_fLineHeight = fLineHeight; +} + +void CFDE_CSSComputedStyle::SetTextIndent(const FDE_CSSLength& textIndent) { + m_InheritedData.m_TextIndent = textIndent; +} + +void CFDE_CSSComputedStyle::SetTextAlign(FDE_CSSTextAlign eTextAlign) { + m_InheritedData.m_eTextAlign = eTextAlign; +} + +void CFDE_CSSComputedStyle::SetNumberVerticalAlign(FX_FLOAT fAlign) { + m_NonInheritedData.m_eVerticalAlign = FDE_CSSVerticalAlign::Number, + m_NonInheritedData.m_fVerticalAlign = fAlign; +} + +void CFDE_CSSComputedStyle::SetTextDecoration(uint32_t dwTextDecoration) { + m_NonInheritedData.m_dwTextDecoration = dwTextDecoration; +} + +void CFDE_CSSComputedStyle::SetLetterSpacing( + const FDE_CSSLength& letterSpacing) { + m_InheritedData.m_LetterSpacing = letterSpacing; +} + +void CFDE_CSSComputedStyle::AddCustomStyle(const CFX_WideString& wsName, + const CFX_WideString& wsValue) { + m_CustomProperties.push_back(wsName); + m_CustomProperties.push_back(wsValue); +} + +CFDE_CSSComputedStyle::InheritedData::InheritedData() + : m_LetterSpacing(FDE_CSSLengthUnit::Normal), + m_WordSpacing(FDE_CSSLengthUnit::Normal), + m_TextIndent(FDE_CSSLengthUnit::Point, 0), + m_pFontFamily(nullptr), + m_fFontSize(12.0f), + m_fLineHeight(14.0f), + m_dwFontColor(0xFF000000), + m_wFontWeight(400), + m_eFontVariant(FDE_CSSFontVariant::Normal), + m_eFontStyle(FDE_CSSFontStyle::Normal), + m_eTextAlign(FDE_CSSTextAlign::Left) {} + +CFDE_CSSComputedStyle::NonInheritedData::NonInheritedData() + : m_MarginWidth(FDE_CSSLengthUnit::Point, 0), + m_BorderWidth(FDE_CSSLengthUnit::Point, 0), + m_PaddingWidth(FDE_CSSLengthUnit::Point, 0), + m_fVerticalAlign(0.0f), + m_eDisplay(FDE_CSSDisplay::Inline), + m_eVerticalAlign(FDE_CSSVerticalAlign::Baseline), + m_dwTextDecoration(0), + m_bHasMargin(false), + m_bHasBorder(false), + m_bHasPadding(false) {} diff --git a/xfa/fde/css/cfde_csscomputedstyle.h b/xfa/fde/css/cfde_csscomputedstyle.h new file mode 100644 index 0000000000..73eb996f0d --- /dev/null +++ b/xfa/fde/css/cfde_csscomputedstyle.h @@ -0,0 +1,112 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FDE_CSS_CFDE_CSSCOMPUTEDSTYLE_H_ +#define XFA_FDE_CSS_CFDE_CSSCOMPUTEDSTYLE_H_ + +#include + +#include "core/fxcrt/fx_basic.h" +#include "core/fxcrt/fx_string.h" +#include "xfa/fde/css/fde_css.h" + +class CFDE_CSSValueList; + +class CFDE_CSSComputedStyle : public IFX_Retainable { + public: + class InheritedData { + public: + InheritedData(); + + FDE_CSSLength m_LetterSpacing; + FDE_CSSLength m_WordSpacing; + FDE_CSSLength m_TextIndent; + CFDE_CSSValueList* m_pFontFamily; + FX_FLOAT m_fFontSize; + FX_FLOAT m_fLineHeight; + FX_ARGB m_dwFontColor; + uint16_t m_wFontWeight; + FDE_CSSFontVariant m_eFontVariant; + FDE_CSSFontStyle m_eFontStyle; + FDE_CSSTextAlign m_eTextAlign; + }; + + class NonInheritedData { + public: + NonInheritedData(); + + FDE_CSSRect m_MarginWidth; + FDE_CSSRect m_BorderWidth; + FDE_CSSRect m_PaddingWidth; + FDE_CSSLength m_Top; + FDE_CSSLength m_Bottom; + FDE_CSSLength m_Left; + FDE_CSSLength m_Right; + FX_FLOAT m_fVerticalAlign; + FDE_CSSDisplay m_eDisplay; + FDE_CSSVerticalAlign m_eVerticalAlign; + uint8_t m_dwTextDecoration; + bool m_bHasMargin; + bool m_bHasBorder; + bool m_bHasPadding; + }; + + CFDE_CSSComputedStyle(); + ~CFDE_CSSComputedStyle() override; + + // IFX_Retainable + uint32_t Retain() override; + uint32_t Release() override; + + int32_t CountFontFamilies() const; + const CFX_WideString GetFontFamily(int32_t index) const; + uint16_t GetFontWeight() const; + FDE_CSSFontVariant GetFontVariant() const; + FDE_CSSFontStyle GetFontStyle() const; + FX_FLOAT GetFontSize() const; + FX_ARGB GetColor() const; + void SetFontWeight(uint16_t wFontWeight); + void SetFontVariant(FDE_CSSFontVariant eFontVariant); + void SetFontStyle(FDE_CSSFontStyle eFontStyle); + void SetFontSize(FX_FLOAT fFontSize); + void SetColor(FX_ARGB dwFontColor); + + const FDE_CSSRect* GetBorderWidth() const; + const FDE_CSSRect* GetMarginWidth() const; + const FDE_CSSRect* GetPaddingWidth() const; + void SetMarginWidth(const FDE_CSSRect& rect); + void SetPaddingWidth(const FDE_CSSRect& rect); + + FDE_CSSDisplay GetDisplay() const; + + FX_FLOAT GetLineHeight() const; + const FDE_CSSLength& GetTextIndent() const; + FDE_CSSTextAlign GetTextAlign() const; + FDE_CSSVerticalAlign GetVerticalAlign() const; + FX_FLOAT GetNumberVerticalAlign() const; + uint32_t GetTextDecoration() const; + const FDE_CSSLength& GetLetterSpacing() const; + void SetLineHeight(FX_FLOAT fLineHeight); + void SetTextIndent(const FDE_CSSLength& textIndent); + void SetTextAlign(FDE_CSSTextAlign eTextAlign); + void SetNumberVerticalAlign(FX_FLOAT fAlign); + void SetTextDecoration(uint32_t dwTextDecoration); + void SetLetterSpacing(const FDE_CSSLength& letterSpacing); + void AddCustomStyle(const CFX_WideString& wsName, + const CFX_WideString& wsValue); + + bool GetCustomStyle(const CFX_WideStringC& wsName, + CFX_WideString& wsValue) const; + + InheritedData m_InheritedData; + NonInheritedData m_NonInheritedData; + + private: + uint32_t m_dwRefCount; + std::vector m_CustomProperties; +}; + +#endif // XFA_FDE_CSS_CFDE_CSSCOMPUTEDSTYLE_H_ diff --git a/xfa/fde/css/cfde_csscustomproperty.h b/xfa/fde/css/cfde_csscustomproperty.h new file mode 100644 index 0000000000..6e99630e1c --- /dev/null +++ b/xfa/fde/css/cfde_csscustomproperty.h @@ -0,0 +1,18 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FDE_CSS_CFDE_CSSCUSTOMPROPERTY_H_ +#define XFA_FDE_CSS_CFDE_CSSCUSTOMPROPERTY_H_ + +#include "core/fxcrt/fx_string.h" + +class CFDE_CSSCustomProperty { + public: + const FX_WCHAR* pwsName; + const FX_WCHAR* pwsValue; +}; + +#endif // XFA_FDE_CSS_CFDE_CSSCUSTOMPROPERTY_H_ diff --git a/xfa/fde/css/cfde_cssdeclaration.cpp b/xfa/fde/css/cfde_cssdeclaration.cpp new file mode 100644 index 0000000000..4ed20eb0cc --- /dev/null +++ b/xfa/fde/css/cfde_cssdeclaration.cpp @@ -0,0 +1,662 @@ +// 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 "xfa/fde/css/cfde_cssdeclaration.h" + +#include "core/fxcrt/fx_ext.h" +#include "third_party/base/ptr_util.h" +#include "xfa/fde/css/cfde_csscolorvalue.h" +#include "xfa/fde/css/cfde_csscustomproperty.h" +#include "xfa/fde/css/cfde_cssenumvalue.h" +#include "xfa/fde/css/cfde_cssnumbervalue.h" +#include "xfa/fde/css/cfde_csspropertyholder.h" +#include "xfa/fde/css/cfde_cssstringvalue.h" +#include "xfa/fde/css/cfde_cssvaluelist.h" +#include "xfa/fde/css/cfde_cssvaluelistparser.h" + +namespace { + +uint8_t Hex2Dec(uint8_t hexHigh, uint8_t hexLow) { + return (FXSYS_toHexDigit(hexHigh) << 4) + FXSYS_toHexDigit(hexLow); +} + +bool ParseCSSNumber(const FX_WCHAR* pszValue, + int32_t iValueLen, + FX_FLOAT& fValue, + FDE_CSSNumberType& eUnit) { + ASSERT(pszValue && iValueLen > 0); + int32_t iUsedLen = 0; + fValue = FXSYS_wcstof(pszValue, iValueLen, &iUsedLen); + if (iUsedLen <= 0) + return false; + + iValueLen -= iUsedLen; + pszValue += iUsedLen; + eUnit = FDE_CSSNumberType::Number; + if (iValueLen >= 1 && *pszValue == '%') { + eUnit = FDE_CSSNumberType::Percent; + } else if (iValueLen == 2) { + const FDE_CSSLengthUnitTable* pUnit = + FDE_GetCSSLengthUnitByName(CFX_WideStringC(pszValue, 2)); + if (pUnit) + eUnit = pUnit->wValue; + } + return true; +} + +} // namespace + +// static +bool CFDE_CSSDeclaration::ParseCSSString(const FX_WCHAR* pszValue, + int32_t iValueLen, + int32_t* iOffset, + int32_t* iLength) { + ASSERT(pszValue && iValueLen > 0); + *iOffset = 0; + *iLength = iValueLen; + if (iValueLen >= 2) { + FX_WCHAR first = pszValue[0], last = pszValue[iValueLen - 1]; + if ((first == '\"' && last == '\"') || (first == '\'' && last == '\'')) { + *iOffset = 1; + *iLength -= 2; + } + } + return iValueLen > 0; +} + +// static. +bool CFDE_CSSDeclaration::ParseCSSColor(const FX_WCHAR* pszValue, + int32_t iValueLen, + FX_ARGB* dwColor) { + ASSERT(pszValue && iValueLen > 0); + ASSERT(dwColor); + + if (*pszValue == '#') { + switch (iValueLen) { + case 4: { + uint8_t red = Hex2Dec((uint8_t)pszValue[1], (uint8_t)pszValue[1]); + uint8_t green = Hex2Dec((uint8_t)pszValue[2], (uint8_t)pszValue[2]); + uint8_t blue = Hex2Dec((uint8_t)pszValue[3], (uint8_t)pszValue[3]); + *dwColor = ArgbEncode(255, red, green, blue); + return true; + } + case 7: { + uint8_t red = Hex2Dec((uint8_t)pszValue[1], (uint8_t)pszValue[2]); + uint8_t green = Hex2Dec((uint8_t)pszValue[3], (uint8_t)pszValue[4]); + uint8_t blue = Hex2Dec((uint8_t)pszValue[5], (uint8_t)pszValue[6]); + *dwColor = ArgbEncode(255, red, green, blue); + return true; + } + default: + return false; + } + } + + if (iValueLen >= 10) { + if (pszValue[iValueLen - 1] != ')' || FXSYS_wcsnicmp(L"rgb(", pszValue, 4)) + return false; + + uint8_t rgb[3] = {0}; + FX_FLOAT fValue; + FDE_CSSPrimitiveType eType; + CFDE_CSSValueListParser list(pszValue + 4, iValueLen - 5, ','); + for (int32_t i = 0; i < 3; ++i) { + if (!list.NextValue(eType, pszValue, iValueLen)) + return false; + if (eType != FDE_CSSPrimitiveType::Number) + return false; + FDE_CSSNumberType eNumType; + if (!ParseCSSNumber(pszValue, iValueLen, fValue, eNumType)) + return false; + + rgb[i] = eNumType == FDE_CSSNumberType::Percent + ? FXSYS_round(fValue * 2.55f) + : FXSYS_round(fValue); + } + *dwColor = ArgbEncode(255, rgb[0], rgb[1], rgb[2]); + return true; + } + + const FDE_CSSCOLORTABLE* pColor = + FDE_GetCSSColorByName(CFX_WideStringC(pszValue, iValueLen)); + if (!pColor) + return false; + + *dwColor = pColor->dwValue; + return true; +} + +CFDE_CSSDeclaration::CFDE_CSSDeclaration() {} + +CFDE_CSSDeclaration::~CFDE_CSSDeclaration() {} + +CFDE_CSSValue* CFDE_CSSDeclaration::GetProperty(FDE_CSSProperty eProperty, + bool& bImportant) const { + for (const auto& p : properties_) { + if (p->eProperty == eProperty) { + bImportant = p->bImportant; + return p->pValue.Get(); + } + } + return nullptr; +} + +const FX_WCHAR* CFDE_CSSDeclaration::CopyToLocal( + const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen) { + ASSERT(iValueLen > 0); + std::unordered_map* pCache = pArgs->pStringCache; + uint32_t key = 0; + if (pCache) { + key = FX_HashCode_GetW(CFX_WideStringC(pszValue, iValueLen), false); + auto it = pCache->find(key); + if (it != pCache->end()) + return it->second; + } + FX_WCHAR* psz = FX_Alloc(FX_WCHAR, iValueLen + 1); + FXSYS_wcsncpy(psz, pszValue, iValueLen); + psz[iValueLen] = '\0'; + if (pCache) + (*pCache)[key] = psz; + + return psz; +} + +void CFDE_CSSDeclaration::AddPropertyHolder(FDE_CSSProperty eProperty, + CFX_RetainPtr pValue, + bool bImportant) { + auto pHolder = pdfium::MakeUnique(); + pHolder->bImportant = bImportant; + pHolder->eProperty = eProperty; + pHolder->pValue = pValue; + properties_.push_back(std::move(pHolder)); +} + +void CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen) { + ASSERT(iValueLen > 0); + bool bImportant = false; + if (iValueLen >= 10 && pszValue[iValueLen - 10] == '!' && + FXSYS_wcsnicmp(L"important", pszValue + iValueLen - 9, 9) == 0) { + if ((iValueLen -= 10) == 0) + return; + + bImportant = true; + } + const uint32_t dwType = pArgs->pProperty->dwType; + switch (dwType & 0x0F) { + case FDE_CSSVALUETYPE_Primitive: { + static const uint32_t g_ValueGuessOrder[] = { + FDE_CSSVALUETYPE_MaybeNumber, FDE_CSSVALUETYPE_MaybeEnum, + FDE_CSSVALUETYPE_MaybeColor, FDE_CSSVALUETYPE_MaybeString, + }; + static const int32_t g_ValueGuessCount = + sizeof(g_ValueGuessOrder) / sizeof(uint32_t); + for (int32_t i = 0; i < g_ValueGuessCount; ++i) { + const uint32_t dwMatch = dwType & g_ValueGuessOrder[i]; + if (dwMatch == 0) { + continue; + } + CFX_RetainPtr pCSSValue; + switch (dwMatch) { + case FDE_CSSVALUETYPE_MaybeNumber: + pCSSValue = ParseNumber(pArgs, pszValue, iValueLen); + break; + case FDE_CSSVALUETYPE_MaybeEnum: + pCSSValue = ParseEnum(pArgs, pszValue, iValueLen); + break; + case FDE_CSSVALUETYPE_MaybeColor: + pCSSValue = ParseColor(pArgs, pszValue, iValueLen); + break; + case FDE_CSSVALUETYPE_MaybeString: + pCSSValue = ParseString(pArgs, pszValue, iValueLen); + break; + default: + break; + } + if (pCSSValue) { + AddPropertyHolder(pArgs->pProperty->eName, pCSSValue, bImportant); + return; + } + if (FDE_IsOnlyValue(dwType, g_ValueGuessOrder[i])) + return; + } + break; + } + case FDE_CSSVALUETYPE_Shorthand: { + CFX_RetainPtr pWidth; + switch (pArgs->pProperty->eName) { + case FDE_CSSProperty::Font: + ParseFontProperty(pArgs, pszValue, iValueLen, bImportant); + return; + case FDE_CSSProperty::Border: + if (ParseBorderProperty(pszValue, iValueLen, pWidth)) { + AddPropertyHolder(FDE_CSSProperty::BorderLeftWidth, pWidth, + bImportant); + AddPropertyHolder(FDE_CSSProperty::BorderTopWidth, pWidth, + bImportant); + AddPropertyHolder(FDE_CSSProperty::BorderRightWidth, pWidth, + bImportant); + AddPropertyHolder(FDE_CSSProperty::BorderBottomWidth, pWidth, + bImportant); + return; + } + break; + case FDE_CSSProperty::BorderLeft: + if (ParseBorderProperty(pszValue, iValueLen, pWidth)) { + AddPropertyHolder(FDE_CSSProperty::BorderLeftWidth, pWidth, + bImportant); + return; + } + break; + case FDE_CSSProperty::BorderTop: + if (ParseBorderProperty(pszValue, iValueLen, pWidth)) { + AddPropertyHolder(FDE_CSSProperty::BorderTopWidth, pWidth, + bImportant); + return; + } + break; + case FDE_CSSProperty::BorderRight: + if (ParseBorderProperty(pszValue, iValueLen, pWidth)) { + AddPropertyHolder(FDE_CSSProperty::BorderRightWidth, pWidth, + bImportant); + return; + } + break; + case FDE_CSSProperty::BorderBottom: + if (ParseBorderProperty(pszValue, iValueLen, pWidth)) { + AddPropertyHolder(FDE_CSSProperty::BorderBottomWidth, pWidth, + bImportant); + return; + } + break; + default: + break; + } + } break; + case FDE_CSSVALUETYPE_List: + ParseValueListProperty(pArgs, pszValue, iValueLen, bImportant); + return; + default: + ASSERT(false); + break; + } +} + +void CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszName, + int32_t iNameLen, + const FX_WCHAR* pszValue, + int32_t iValueLen) { + auto pProperty = pdfium::MakeUnique(); + pProperty->pwsName = CopyToLocal(pArgs, pszName, iNameLen); + pProperty->pwsValue = CopyToLocal(pArgs, pszValue, iValueLen); + custom_properties_.push_back(std::move(pProperty)); +} + +CFX_RetainPtr CFDE_CSSDeclaration::ParseNumber( + const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen) { + FX_FLOAT fValue; + FDE_CSSNumberType eUnit; + if (!ParseCSSNumber(pszValue, iValueLen, fValue, eUnit)) + return nullptr; + return pdfium::MakeRetain(eUnit, fValue); +} + +CFX_RetainPtr CFDE_CSSDeclaration::ParseEnum( + const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen) { + const FDE_CSSPropertyValueTable* pValue = + FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); + return pValue ? pdfium::MakeRetain(pValue->eName) + : nullptr; +} + +CFX_RetainPtr CFDE_CSSDeclaration::ParseColor( + const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen) { + FX_ARGB dwColor; + if (!ParseCSSColor(pszValue, iValueLen, &dwColor)) + return nullptr; + return pdfium::MakeRetain(dwColor); +} + +CFX_RetainPtr CFDE_CSSDeclaration::ParseString( + const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen) { + int32_t iOffset; + if (!ParseCSSString(pszValue, iValueLen, &iOffset, &iValueLen)) + return nullptr; + + if (iValueLen <= 0) + return nullptr; + + pszValue = CopyToLocal(pArgs, pszValue + iOffset, iValueLen); + return pszValue ? pdfium::MakeRetain(pszValue) : nullptr; +} + +void CFDE_CSSDeclaration::ParseValueListProperty( + const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen, + bool bImportant) { + FX_WCHAR separator = + (pArgs->pProperty->eName == FDE_CSSProperty::FontFamily) ? ',' : ' '; + CFDE_CSSValueListParser parser(pszValue, iValueLen, separator); + + const uint32_t dwType = pArgs->pProperty->dwType; + FDE_CSSPrimitiveType eType; + std::vector> list; + while (parser.NextValue(eType, pszValue, iValueLen)) { + switch (eType) { + case FDE_CSSPrimitiveType::Number: + if (dwType & FDE_CSSVALUETYPE_MaybeNumber) { + FX_FLOAT fValue; + FDE_CSSNumberType eNumType; + if (ParseCSSNumber(pszValue, iValueLen, fValue, eNumType)) + list.push_back( + pdfium::MakeRetain(eNumType, fValue)); + } + break; + case FDE_CSSPrimitiveType::String: + if (dwType & FDE_CSSVALUETYPE_MaybeColor) { + FX_ARGB dwColor; + if (ParseCSSColor(pszValue, iValueLen, &dwColor)) { + list.push_back(pdfium::MakeRetain(dwColor)); + continue; + } + } + if (dwType & FDE_CSSVALUETYPE_MaybeEnum) { + const FDE_CSSPropertyValueTable* pValue = + FDE_GetCSSPropertyValueByName( + CFX_WideStringC(pszValue, iValueLen)); + if (pValue) { + list.push_back( + pdfium::MakeRetain(pValue->eName)); + continue; + } + } + if (dwType & FDE_CSSVALUETYPE_MaybeString) { + pszValue = CopyToLocal(pArgs, pszValue, iValueLen); + list.push_back(pdfium::MakeRetain(pszValue)); + } + break; + case FDE_CSSPrimitiveType::RGB: + if (dwType & FDE_CSSVALUETYPE_MaybeColor) { + FX_ARGB dwColor; + if (ParseCSSColor(pszValue, iValueLen, &dwColor)) { + list.push_back(pdfium::MakeRetain(dwColor)); + } + } + break; + default: + break; + } + } + if (list.empty()) + return; + + switch (pArgs->pProperty->eName) { + case FDE_CSSProperty::BorderWidth: + Add4ValuesProperty(list, bImportant, FDE_CSSProperty::BorderLeftWidth, + FDE_CSSProperty::BorderTopWidth, + FDE_CSSProperty::BorderRightWidth, + FDE_CSSProperty::BorderBottomWidth); + return; + case FDE_CSSProperty::Margin: + Add4ValuesProperty(list, bImportant, FDE_CSSProperty::MarginLeft, + FDE_CSSProperty::MarginTop, + FDE_CSSProperty::MarginRight, + FDE_CSSProperty::MarginBottom); + return; + case FDE_CSSProperty::Padding: + Add4ValuesProperty(list, bImportant, FDE_CSSProperty::PaddingLeft, + FDE_CSSProperty::PaddingTop, + FDE_CSSProperty::PaddingRight, + FDE_CSSProperty::PaddingBottom); + return; + default: { + auto pList = pdfium::MakeRetain(list); + AddPropertyHolder(pArgs->pProperty->eName, pList, bImportant); + return; + } + } +} + +void CFDE_CSSDeclaration::Add4ValuesProperty( + const std::vector>& list, + bool bImportant, + FDE_CSSProperty eLeft, + FDE_CSSProperty eTop, + FDE_CSSProperty eRight, + FDE_CSSProperty eBottom) { + switch (list.size()) { + case 1: + AddPropertyHolder(eLeft, list[0], bImportant); + AddPropertyHolder(eTop, list[0], bImportant); + AddPropertyHolder(eRight, list[0], bImportant); + AddPropertyHolder(eBottom, list[0], bImportant); + return; + case 2: + AddPropertyHolder(eLeft, list[1], bImportant); + AddPropertyHolder(eTop, list[0], bImportant); + AddPropertyHolder(eRight, list[1], bImportant); + AddPropertyHolder(eBottom, list[0], bImportant); + return; + case 3: + AddPropertyHolder(eLeft, list[1], bImportant); + AddPropertyHolder(eTop, list[0], bImportant); + AddPropertyHolder(eRight, list[1], bImportant); + AddPropertyHolder(eBottom, list[2], bImportant); + return; + case 4: + AddPropertyHolder(eLeft, list[3], bImportant); + AddPropertyHolder(eTop, list[0], bImportant); + AddPropertyHolder(eRight, list[1], bImportant); + AddPropertyHolder(eBottom, list[2], bImportant); + return; + default: + break; + } +} + +bool CFDE_CSSDeclaration::ParseBorderProperty( + const FX_WCHAR* pszValue, + int32_t iValueLen, + CFX_RetainPtr& pWidth) const { + pWidth.Reset(nullptr); + + CFDE_CSSValueListParser parser(pszValue, iValueLen, ' '); + FDE_CSSPrimitiveType eType; + while (parser.NextValue(eType, pszValue, iValueLen)) { + switch (eType) { + case FDE_CSSPrimitiveType::Number: { + if (pWidth) + continue; + + FX_FLOAT fValue; + FDE_CSSNumberType eNumType; + if (ParseCSSNumber(pszValue, iValueLen, fValue, eNumType)) + pWidth = pdfium::MakeRetain(eNumType, fValue); + break; + } + case FDE_CSSPrimitiveType::String: { + const FDE_CSSCOLORTABLE* pColorItem = + FDE_GetCSSColorByName(CFX_WideStringC(pszValue, iValueLen)); + if (pColorItem) + continue; + + const FDE_CSSPropertyValueTable* pValue = + FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); + if (!pValue) + continue; + + switch (pValue->eName) { + case FDE_CSSPropertyValue::Thin: + case FDE_CSSPropertyValue::Thick: + case FDE_CSSPropertyValue::Medium: + if (!pWidth) + pWidth = pdfium::MakeRetain(pValue->eName); + break; + default: + break; + } + break; + } + default: + break; + } + } + if (!pWidth) + pWidth = pdfium::MakeRetain(FDE_CSSNumberType::Number, + 0.0f); + + return true; +} + +void CFDE_CSSDeclaration::ParseFontProperty(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen, + bool bImportant) { + CFDE_CSSValueListParser parser(pszValue, iValueLen, '/'); + CFX_RetainPtr pStyle; + CFX_RetainPtr pVariant; + CFX_RetainPtr pWeight; + CFX_RetainPtr pFontSize; + CFX_RetainPtr pLineHeight; + std::vector> familyList; + FDE_CSSPrimitiveType eType; + while (parser.NextValue(eType, pszValue, iValueLen)) { + switch (eType) { + case FDE_CSSPrimitiveType::String: { + const FDE_CSSPropertyValueTable* pValue = + FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); + if (pValue) { + switch (pValue->eName) { + case FDE_CSSPropertyValue::XxSmall: + case FDE_CSSPropertyValue::XSmall: + case FDE_CSSPropertyValue::Small: + case FDE_CSSPropertyValue::Medium: + case FDE_CSSPropertyValue::Large: + case FDE_CSSPropertyValue::XLarge: + case FDE_CSSPropertyValue::XxLarge: + case FDE_CSSPropertyValue::Smaller: + case FDE_CSSPropertyValue::Larger: + if (!pFontSize) + pFontSize = + pdfium::MakeRetain(pValue->eName); + continue; + case FDE_CSSPropertyValue::Bold: + case FDE_CSSPropertyValue::Bolder: + case FDE_CSSPropertyValue::Lighter: + if (!pWeight) + pWeight = pdfium::MakeRetain(pValue->eName); + continue; + case FDE_CSSPropertyValue::Italic: + case FDE_CSSPropertyValue::Oblique: + if (!pStyle) + pStyle = pdfium::MakeRetain(pValue->eName); + continue; + case FDE_CSSPropertyValue::SmallCaps: + if (!pVariant) + pVariant = pdfium::MakeRetain(pValue->eName); + continue; + case FDE_CSSPropertyValue::Normal: + if (!pStyle) + pStyle = pdfium::MakeRetain(pValue->eName); + else if (!pVariant) + pVariant = pdfium::MakeRetain(pValue->eName); + else if (!pWeight) + pWeight = pdfium::MakeRetain(pValue->eName); + else if (!pFontSize) + pFontSize = + pdfium::MakeRetain(pValue->eName); + else if (!pLineHeight) + pLineHeight = + pdfium::MakeRetain(pValue->eName); + continue; + default: + break; + } + } + if (pFontSize) { + familyList.push_back(pdfium::MakeRetain( + CopyToLocal(pArgs, pszValue, iValueLen))); + } + parser.m_Separator = ','; + break; + } + case FDE_CSSPrimitiveType::Number: { + FX_FLOAT fValue; + FDE_CSSNumberType eNumType; + if (!ParseCSSNumber(pszValue, iValueLen, fValue, eNumType)) + break; + if (eType == FDE_CSSPrimitiveType::Number) { + switch ((int32_t)fValue) { + case 100: + case 200: + case 300: + case 400: + case 500: + case 600: + case 700: + case 800: + case 900: + if (!pWeight) + pWeight = pdfium::MakeRetain( + FDE_CSSNumberType::Number, fValue); + continue; + } + } + if (!pFontSize) + pFontSize = pdfium::MakeRetain(eNumType, fValue); + else if (!pLineHeight) + pLineHeight = + pdfium::MakeRetain(eNumType, fValue); + break; + } + default: + break; + } + } + + if (!pStyle) + pStyle = + pdfium::MakeRetain(FDE_CSSPropertyValue::Normal); + if (!pVariant) + pVariant = + pdfium::MakeRetain(FDE_CSSPropertyValue::Normal); + if (!pWeight) + pWeight = + pdfium::MakeRetain(FDE_CSSPropertyValue::Normal); + if (!pFontSize) + pFontSize = + pdfium::MakeRetain(FDE_CSSPropertyValue::Medium); + if (!pLineHeight) + pLineHeight = + pdfium::MakeRetain(FDE_CSSPropertyValue::Normal); + + AddPropertyHolder(FDE_CSSProperty::FontStyle, pStyle, bImportant); + AddPropertyHolder(FDE_CSSProperty::FontVariant, pVariant, bImportant); + AddPropertyHolder(FDE_CSSProperty::FontWeight, pWeight, bImportant); + AddPropertyHolder(FDE_CSSProperty::FontSize, pFontSize, bImportant); + AddPropertyHolder(FDE_CSSProperty::LineHeight, pLineHeight, bImportant); + if (!familyList.empty()) { + auto pList = pdfium::MakeRetain(familyList); + AddPropertyHolder(FDE_CSSProperty::FontFamily, pList, bImportant); + } +} + +size_t CFDE_CSSDeclaration::PropertyCountForTesting() const { + return properties_.size(); +} diff --git a/xfa/fde/css/cfde_cssdeclaration.h b/xfa/fde/css/cfde_cssdeclaration.h new file mode 100644 index 0000000000..777864efea --- /dev/null +++ b/xfa/fde/css/cfde_cssdeclaration.h @@ -0,0 +1,111 @@ +// 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 XFA_FDE_CSS_CFDE_CSSDECLARATION_H_ +#define XFA_FDE_CSS_CFDE_CSSDECLARATION_H_ + +#include +#include +#include +#include + +#include "xfa/fde/css/fde_cssdatatable.h" + +struct FDE_CSSPropertyArgs { + std::unordered_map* pStringCache; + const FDE_CSSPropertyTable* pProperty; +}; + +class CFDE_CSSPropertyHolder; +class CFDE_CSSCustomProperty; + +class CFDE_CSSDeclaration { + public: + using const_prop_iterator = + std::vector>::const_iterator; + using const_custom_iterator = + std::vector>::const_iterator; + + static bool ParseCSSString(const FX_WCHAR* pszValue, + int32_t iValueLen, + int32_t* iOffset, + int32_t* iLength); + static bool ParseCSSColor(const FX_WCHAR* pszValue, + int32_t iValueLen, + FX_ARGB* dwColor); + + CFDE_CSSDeclaration(); + ~CFDE_CSSDeclaration(); + + CFDE_CSSValue* GetProperty(FDE_CSSProperty eProperty, bool& bImportant) const; + + const_prop_iterator begin() const { return properties_.begin(); } + const_prop_iterator end() const { return properties_.end(); } + + const_custom_iterator custom_begin() const { + return custom_properties_.begin(); + } + const_custom_iterator custom_end() const { return custom_properties_.end(); } + + bool empty() const { return properties_.empty(); } + + void AddProperty(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen); + void AddProperty(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszName, + int32_t iNameLen, + const FX_WCHAR* pszValue, + int32_t iValueLen); + + size_t PropertyCountForTesting() const; + + FX_ARGB ParseColorForTest(const FX_WCHAR* pszValue, + int32_t iValueLen, + FX_ARGB* dwColor) const; + + private: + void ParseFontProperty(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen, + bool bImportant); + bool ParseBorderProperty(const FX_WCHAR* pszValue, + int32_t iValueLen, + CFX_RetainPtr& pWidth) const; + void ParseValueListProperty(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen, + bool bImportant); + void Add4ValuesProperty(const std::vector>& list, + bool bImportant, + FDE_CSSProperty eLeft, + FDE_CSSProperty eTop, + FDE_CSSProperty eRight, + FDE_CSSProperty eBottom); + CFX_RetainPtr ParseNumber(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen); + CFX_RetainPtr ParseEnum(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen); + CFX_RetainPtr ParseColor(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen); + CFX_RetainPtr ParseString(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen); + const FX_WCHAR* CopyToLocal(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen); + void AddPropertyHolder(FDE_CSSProperty eProperty, + CFX_RetainPtr pValue, + bool bImportant); + + std::vector> properties_; + std::vector> custom_properties_; +}; + +#endif // XFA_FDE_CSS_CFDE_CSSDECLARATION_H_ diff --git a/xfa/fde/css/cfde_cssdeclaration_unittest.cpp b/xfa/fde/css/cfde_cssdeclaration_unittest.cpp new file mode 100644 index 0000000000..48a3c72c39 --- /dev/null +++ b/xfa/fde/css/cfde_cssdeclaration_unittest.cpp @@ -0,0 +1,61 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "xfa/fde/css/cfde_cssdeclaration.h" + +#include "testing/gtest/include/gtest/gtest.h" + +TEST(CFDE_CSSDecalration, HexEncodingParsing) { + FX_ARGB color; + + // Length value invalid. + EXPECT_FALSE(CFDE_CSSDeclaration::ParseCSSColor(L"#000", 3, &color)); + EXPECT_FALSE(CFDE_CSSDeclaration::ParseCSSColor(L"#000000", 5, &color)); + EXPECT_FALSE(CFDE_CSSDeclaration::ParseCSSColor(L"#000000", 8, &color)); + + // Invalid characters + EXPECT_TRUE(CFDE_CSSDeclaration::ParseCSSColor(L"#zxytlm", 7, &color)); + EXPECT_EQ(0, FXARGB_R(color)); + EXPECT_EQ(0, FXARGB_G(color)); + EXPECT_EQ(0, FXARGB_B(color)); + + EXPECT_TRUE(CFDE_CSSDeclaration::ParseCSSColor(L"#000", 4, &color)); + EXPECT_EQ(0, FXARGB_R(color)); + EXPECT_EQ(0, FXARGB_G(color)); + EXPECT_EQ(0, FXARGB_B(color)); + + EXPECT_TRUE(CFDE_CSSDeclaration::ParseCSSColor(L"#FFF", 4, &color)); + EXPECT_EQ(255, FXARGB_R(color)); + EXPECT_EQ(255, FXARGB_G(color)); + EXPECT_EQ(255, FXARGB_B(color)); + + EXPECT_TRUE(CFDE_CSSDeclaration::ParseCSSColor(L"#F0F0F0", 7, &color)); + EXPECT_EQ(240, FXARGB_R(color)); + EXPECT_EQ(240, FXARGB_G(color)); + EXPECT_EQ(240, FXARGB_B(color)); + + // Upper and lower case characters. + EXPECT_TRUE(CFDE_CSSDeclaration::ParseCSSColor(L"#1b2F3c", 7, &color)); + EXPECT_EQ(27, FXARGB_R(color)); + EXPECT_EQ(47, FXARGB_G(color)); + EXPECT_EQ(60, FXARGB_B(color)); +} + +TEST(CFDE_CSSDecalration, RGBEncodingParsing) { + FX_ARGB color; + + // Invalid input for rgb() syntax. + EXPECT_FALSE(CFDE_CSSDeclaration::ParseCSSColor(L"blahblahblah", 11, &color)); + + EXPECT_TRUE(CFDE_CSSDeclaration::ParseCSSColor(L"rgb(0, 0, 0)", 12, &color)); + EXPECT_EQ(0, FXARGB_R(color)); + EXPECT_EQ(0, FXARGB_G(color)); + EXPECT_EQ(0, FXARGB_B(color)); + + EXPECT_TRUE( + CFDE_CSSDeclaration::ParseCSSColor(L"rgb(128,255,48)", 15, &color)); + EXPECT_EQ(128, FXARGB_R(color)); + EXPECT_EQ(255, FXARGB_G(color)); + EXPECT_EQ(48, FXARGB_B(color)); +} diff --git a/xfa/fde/css/cfde_cssfontfacerule.cpp b/xfa/fde/css/cfde_cssfontfacerule.cpp new file mode 100644 index 0000000000..5d56eb8c6c --- /dev/null +++ b/xfa/fde/css/cfde_cssfontfacerule.cpp @@ -0,0 +1,12 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fde/css/cfde_cssfontfacerule.h" + +CFDE_CSSFontFaceRule::CFDE_CSSFontFaceRule() + : CFDE_CSSRule(FDE_CSSRuleType::FontFace) {} + +CFDE_CSSFontFaceRule::~CFDE_CSSFontFaceRule() {} diff --git a/xfa/fde/css/cfde_cssfontfacerule.h b/xfa/fde/css/cfde_cssfontfacerule.h new file mode 100644 index 0000000000..e5249ccf18 --- /dev/null +++ b/xfa/fde/css/cfde_cssfontfacerule.h @@ -0,0 +1,24 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FDE_CSS_CFDE_CSSFONTFACERULE_H_ +#define XFA_FDE_CSS_CFDE_CSSFONTFACERULE_H_ + +#include "xfa/fde/css/cfde_cssdeclaration.h" +#include "xfa/fde/css/cfde_cssrule.h" + +class CFDE_CSSFontFaceRule : public CFDE_CSSRule { + public: + CFDE_CSSFontFaceRule(); + ~CFDE_CSSFontFaceRule() override; + + CFDE_CSSDeclaration* GetDeclaration() { return &m_Declaration; } + + private: + CFDE_CSSDeclaration m_Declaration; +}; + +#endif // XFA_FDE_CSS_CFDE_CSSFONTFACERULE_H_ diff --git a/xfa/fde/css/cfde_cssmediarule.cpp b/xfa/fde/css/cfde_cssmediarule.cpp new file mode 100644 index 0000000000..751f9d9fa1 --- /dev/null +++ b/xfa/fde/css/cfde_cssmediarule.cpp @@ -0,0 +1,26 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fde/css/cfde_cssmediarule.h" + +#include "third_party/base/stl_util.h" + +CFDE_CSSMediaRule::CFDE_CSSMediaRule(uint32_t dwMediaList) + : CFDE_CSSRule(FDE_CSSRuleType::Media), m_dwMediaList(dwMediaList) {} + +CFDE_CSSMediaRule::~CFDE_CSSMediaRule() {} + +uint32_t CFDE_CSSMediaRule::GetMediaList() const { + return m_dwMediaList; +} + +int32_t CFDE_CSSMediaRule::CountRules() const { + return pdfium::CollectionSize(m_RuleArray); +} + +CFDE_CSSRule* CFDE_CSSMediaRule::GetRule(int32_t index) { + return m_RuleArray[index].get(); +} diff --git a/xfa/fde/css/cfde_cssmediarule.h b/xfa/fde/css/cfde_cssmediarule.h new file mode 100644 index 0000000000..59febb2008 --- /dev/null +++ b/xfa/fde/css/cfde_cssmediarule.h @@ -0,0 +1,31 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FDE_CSS_CFDE_CSSMEDIARULE_H_ +#define XFA_FDE_CSS_CFDE_CSSMEDIARULE_H_ + +#include +#include + +#include "xfa/fde/css/cfde_cssrule.h" + +class CFDE_CSSMediaRule : public CFDE_CSSRule { + public: + explicit CFDE_CSSMediaRule(uint32_t dwMediaList); + ~CFDE_CSSMediaRule() override; + + uint32_t GetMediaList() const; + int32_t CountRules() const; + CFDE_CSSRule* GetRule(int32_t index); + + std::vector>& GetArray() { return m_RuleArray; } + + protected: + uint32_t m_dwMediaList; + std::vector> m_RuleArray; +}; + +#endif // XFA_FDE_CSS_CFDE_CSSMEDIARULE_H_ diff --git a/xfa/fde/css/cfde_csspropertyholder.cpp b/xfa/fde/css/cfde_csspropertyholder.cpp new file mode 100644 index 0000000000..9f47c8f08b --- /dev/null +++ b/xfa/fde/css/cfde_csspropertyholder.cpp @@ -0,0 +1,11 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fde/css/cfde_csspropertyholder.h" + +CFDE_CSSPropertyHolder::CFDE_CSSPropertyHolder() {} + +CFDE_CSSPropertyHolder::~CFDE_CSSPropertyHolder() {} diff --git a/xfa/fde/css/cfde_csspropertyholder.h b/xfa/fde/css/cfde_csspropertyholder.h new file mode 100644 index 0000000000..7f8526d92e --- /dev/null +++ b/xfa/fde/css/cfde_csspropertyholder.h @@ -0,0 +1,24 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FDE_CSS_CFDE_CSSPROPERTYHOLDER_H_ +#define XFA_FDE_CSS_CFDE_CSSPROPERTYHOLDER_H_ + +#include "core/fxcrt/cfx_retain_ptr.h" +#include "xfa/fde/css/cfde_cssvalue.h" +#include "xfa/fde/css/fde_css.h" + +class CFDE_CSSPropertyHolder { + public: + CFDE_CSSPropertyHolder(); + ~CFDE_CSSPropertyHolder(); + + FDE_CSSProperty eProperty; + bool bImportant; + CFX_RetainPtr pValue; +}; + +#endif // XFA_FDE_CSS_CFDE_CSSPROPERTYHOLDER_H_ diff --git a/xfa/fde/css/cfde_cssrulecollection.cpp b/xfa/fde/css/cfde_cssrulecollection.cpp index 5c386effeb..286f619b68 100644 --- a/xfa/fde/css/cfde_cssrulecollection.cpp +++ b/xfa/fde/css/cfde_cssrulecollection.cpp @@ -4,16 +4,20 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com -#include "xfa/fde/css/fde_cssstyleselector.h" +#include "xfa/fde/css/cfde_cssrulecollection.h" #include #include #include -#include "xfa/fde/css/fde_csscache.h" -#include "xfa/fde/css/fde_cssdeclaration.h" -#include "xfa/fde/css/fde_cssstylesheet.h" -#include "xfa/fde/css/fde_csssyntax.h" +#include "xfa/fde/css/cfde_cssdeclaration.h" +#include "xfa/fde/css/cfde_cssmediarule.h" +#include "xfa/fde/css/cfde_cssrule.h" +#include "xfa/fde/css/cfde_cssselector.h" +#include "xfa/fde/css/cfde_cssstylerule.h" +#include "xfa/fde/css/cfde_cssstylesheet.h" +#include "xfa/fde/css/cfde_csssyntaxparser.h" +#include "xfa/fde/css/cfde_csstagcache.h" #define FDE_CSSUNIVERSALHASH ('*') @@ -60,7 +64,7 @@ void CFDE_CSSRuleCollection::AddRulesFrom(CFDE_CSSStyleSheet* pStyleSheet, for (int32_t i = 0; i < iSelectors; ++i) { CFDE_CSSSelector* pSelector = pStyleRule->GetSelectorList(i); if (pSelector->GetType() == FDE_CSSSelectorType::Pseudo) { - FDE_CSSRuleData* pData = NewRuleData(pSelector, pDeclaration); + Data* pData = NewRuleData(pSelector, pDeclaration); AddRuleTo(&m_pPseudoRules, pData); continue; } @@ -71,7 +75,7 @@ void CFDE_CSSRuleCollection::AddRulesFrom(CFDE_CSSStyleSheet* pStyleSheet, } CFDE_CSSSelector* pNext = pSelector->GetNextSelector(); if (!pNext) { - FDE_CSSRuleData* pData = NewRuleData(pSelector, pDeclaration); + Data* pData = NewRuleData(pSelector, pDeclaration); AddRuleTo(&m_pUniversalRules, pData); continue; } @@ -109,13 +113,12 @@ void CFDE_CSSRuleCollection::AddRulesFrom(CFDE_CSSStyleSheet* pStyleSheet, } } -void CFDE_CSSRuleCollection::AddRuleTo( - std::map* pMap, - uint32_t dwKey, - CFDE_CSSSelector* pSel, - CFDE_CSSDeclaration* pDecl) { - FDE_CSSRuleData* pData = NewRuleData(pSel, pDecl); - FDE_CSSRuleData* pList = (*pMap)[dwKey]; +void CFDE_CSSRuleCollection::AddRuleTo(std::map* pMap, + uint32_t dwKey, + CFDE_CSSSelector* pSel, + CFDE_CSSDeclaration* pDecl) { + Data* pData = NewRuleData(pSel, pDecl); + Data* pList = (*pMap)[dwKey]; if (!pList) { (*pMap)[dwKey] = pData; } else if (AddRuleTo(&pList, pData)) { @@ -123,8 +126,7 @@ void CFDE_CSSRuleCollection::AddRuleTo( } } -bool CFDE_CSSRuleCollection::AddRuleTo(FDE_CSSRuleData** pList, - FDE_CSSRuleData* pData) { +bool CFDE_CSSRuleCollection::AddRuleTo(Data** pList, Data* pData) { if (*pList) { pData->pNext = (*pList)->pNext; (*pList)->pNext = pData; @@ -134,8 +136,23 @@ bool CFDE_CSSRuleCollection::AddRuleTo(FDE_CSSRuleData** pList, return true; } -FDE_CSSRuleData* CFDE_CSSRuleCollection::NewRuleData( +CFDE_CSSRuleCollection::Data* CFDE_CSSRuleCollection::NewRuleData( CFDE_CSSSelector* pSel, CFDE_CSSDeclaration* pDecl) { - return new FDE_CSSRuleData(pSel, pDecl, ++m_iSelectors); + return new Data(pSel, pDecl, ++m_iSelectors); +} + +CFDE_CSSRuleCollection::Data::Data(CFDE_CSSSelector* pSel, + CFDE_CSSDeclaration* pDecl, + uint32_t dwPos) + : pSelector(pSel), pDeclaration(pDecl), dwPriority(dwPos), pNext(nullptr) { + static const uint32_t s_Specific[5] = {0x00010000, 0x00010000, 0x00100000, + 0x00100000, 0x01000000}; + for (; pSel; pSel = pSel->GetNextSelector()) { + FDE_CSSSelectorType eType = pSel->GetType(); + if (eType > FDE_CSSSelectorType::Descendant || + pSel->GetNameHash() != FDE_CSSUNIVERSALHASH) { + dwPriority += s_Specific[static_cast(eType)]; + } + } } diff --git a/xfa/fde/css/cfde_cssrulecollection.h b/xfa/fde/css/cfde_cssrulecollection.h new file mode 100644 index 0000000000..1433a5a5f2 --- /dev/null +++ b/xfa/fde/css/cfde_cssrulecollection.h @@ -0,0 +1,79 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FDE_CSS_CFDE_CSSRULECOLLECTION_H_ +#define XFA_FDE_CSS_CFDE_CSSRULECOLLECTION_H_ + +#include + +#include "core/fxcrt/fx_basic.h" + +class CFDE_CSSDeclaration; +class CFDE_CSSRule; +class CFDE_CSSSelector; +class CFDE_CSSStyleSheet; +class CFGAS_FontMgr; + +class CFDE_CSSRuleCollection { + public: + class Data { + public: + Data(CFDE_CSSSelector* pSel, CFDE_CSSDeclaration* pDecl, uint32_t dwPos); + + CFDE_CSSSelector* const pSelector; + CFDE_CSSDeclaration* const pDeclaration; + uint32_t dwPriority; + Data* pNext; + }; + + CFDE_CSSRuleCollection(); + ~CFDE_CSSRuleCollection(); + + void AddRulesFrom(const CFX_ArrayTemplate& sheets, + uint32_t dwMediaList, + CFGAS_FontMgr* pFontMgr); + void Clear(); + int32_t CountSelectors() const { return m_iSelectors; } + + Data* GetIDRuleData(uint32_t dwIDHash) { + auto it = m_IDRules.find(dwIDHash); + return it != m_IDRules.end() ? it->second : nullptr; + } + + Data* GetTagRuleData(uint32_t dwTagHash) { + auto it = m_TagRules.find(dwTagHash); + return it != m_TagRules.end() ? it->second : nullptr; + } + + Data* GetClassRuleData(uint32_t dwIDHash) { + auto it = m_ClassRules.find(dwIDHash); + return it != m_ClassRules.end() ? it->second : nullptr; + } + + Data* GetUniversalRuleData() { return m_pUniversalRules; } + Data* GetPseudoRuleData() { return m_pPseudoRules; } + + protected: + void AddRulesFrom(CFDE_CSSStyleSheet* pStyleSheet, + CFDE_CSSRule* pRule, + uint32_t dwMediaList, + CFGAS_FontMgr* pFontMgr); + void AddRuleTo(std::map* pMap, + uint32_t dwKey, + CFDE_CSSSelector* pSel, + CFDE_CSSDeclaration* pDecl); + bool AddRuleTo(Data** pList, Data* pData); + Data* NewRuleData(CFDE_CSSSelector* pSel, CFDE_CSSDeclaration* pDecl); + + std::map m_IDRules; + std::map m_TagRules; + std::map m_ClassRules; + Data* m_pUniversalRules; + Data* m_pPseudoRules; + int32_t m_iSelectors; +}; + +#endif // XFA_FDE_CSS_CFDE_CSSRULECOLLECTION_H_ diff --git a/xfa/fde/css/cfde_cssselector.cpp b/xfa/fde/css/cfde_cssselector.cpp new file mode 100644 index 0000000000..4d32bd1cfa --- /dev/null +++ b/xfa/fde/css/cfde_cssselector.cpp @@ -0,0 +1,162 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fde/css/cfde_cssselector.h" + +#include + +#include "third_party/base/ptr_util.h" + +namespace { + +bool IsCSSChar(FX_WCHAR wch) { + return (wch >= 'a' && wch <= 'z') || (wch >= 'A' && wch <= 'Z'); +} + +int32_t GetCSSPseudoLen(const FX_WCHAR* psz, const FX_WCHAR* pEnd) { + ASSERT(*psz == ':'); + const FX_WCHAR* pStart = psz; + while (psz < pEnd) { + FX_WCHAR wch = *psz; + if (IsCSSChar(wch) || wch == ':') + ++psz; + else + break; + } + return psz - pStart; +} + +int32_t GetCSSNameLen(const FX_WCHAR* psz, const FX_WCHAR* pEnd) { + const FX_WCHAR* pStart = psz; + while (psz < pEnd) { + FX_WCHAR wch = *psz; + if (IsCSSChar(wch) || (wch >= '0' && wch <= '9') || wch == '_' || + wch == '-') { + ++psz; + } else { + break; + } + } + return psz - pStart; +} + +} // namespace + +CFDE_CSSSelector::CFDE_CSSSelector(FDE_CSSSelectorType eType, + const FX_WCHAR* psz, + int32_t iLen, + bool bIgnoreCase) + : m_eType(eType), + m_dwHash(FX_HashCode_GetW(CFX_WideStringC(psz, iLen), bIgnoreCase)) {} + +CFDE_CSSSelector::~CFDE_CSSSelector() {} + +FDE_CSSSelectorType CFDE_CSSSelector::GetType() const { + return m_eType; +} + +uint32_t CFDE_CSSSelector::GetNameHash() const { + return m_dwHash; +} + +CFDE_CSSSelector* CFDE_CSSSelector::GetNextSelector() const { + return m_pNext.get(); +} + +std::unique_ptr CFDE_CSSSelector::ReleaseNextSelector() { + return std::move(m_pNext); +} + +std::unique_ptr CFDE_CSSSelector::FromString( + const FX_WCHAR* psz, + int32_t iLen) { + ASSERT(psz && iLen > 0); + + const FX_WCHAR* pStart = psz; + const FX_WCHAR* pEnd = psz + iLen; + for (; psz < pEnd; ++psz) { + switch (*psz) { + case '>': + case '[': + case '+': + return nullptr; + } + } + + std::unique_ptr pFirst = nullptr; + CFDE_CSSSelector* pLast = nullptr; + std::unique_ptr pPseudoFirst = nullptr; + CFDE_CSSSelector* pPseudoLast = nullptr; + + for (psz = pStart; psz < pEnd;) { + FX_WCHAR wch = *psz; + if (wch == '.' || wch == '#') { + if (psz == pStart || psz[-1] == ' ') { + auto p = pdfium::MakeUnique( + FDE_CSSSelectorType::Element, L"*", 1, true); + + if (pFirst) { + pFirst->SetType(FDE_CSSSelectorType::Descendant); + p->SetNext(std::move(pFirst)); + } + pFirst = std::move(p); + pLast = pFirst.get(); + } + ASSERT(pLast); + + int32_t iNameLen = GetCSSNameLen(++psz, pEnd); + if (iNameLen == 0) + return nullptr; + + FDE_CSSSelectorType eType = + wch == '.' ? FDE_CSSSelectorType::Class : FDE_CSSSelectorType::ID; + auto p = + pdfium::MakeUnique(eType, psz, iNameLen, false); + + p->SetNext(pLast->ReleaseNextSelector()); + pLast->SetNext(std::move(p)); + pLast = pLast->GetNextSelector(); + psz += iNameLen; + } else if (IsCSSChar(wch) || wch == '*') { + int32_t iNameLen = wch == '*' ? 1 : GetCSSNameLen(psz, pEnd); + if (iNameLen == 0) + return nullptr; + + auto p = pdfium::MakeUnique( + FDE_CSSSelectorType::Element, psz, iNameLen, true); + if (pFirst) { + pFirst->SetType(FDE_CSSSelectorType::Descendant); + p->SetNext(std::move(pFirst)); + } + pFirst = std::move(p); + pLast = pFirst.get(); + psz += iNameLen; + } else if (wch == ':') { + int32_t iNameLen = GetCSSPseudoLen(psz, pEnd); + if (iNameLen == 0) + return nullptr; + + auto p = pdfium::MakeUnique(FDE_CSSSelectorType::Pseudo, + psz, iNameLen, true); + CFDE_CSSSelector* ptr = p.get(); + if (pPseudoFirst) + pPseudoLast->SetNext(std::move(p)); + else + pPseudoFirst = std::move(p); + pPseudoLast = ptr; + psz += iNameLen; + } else if (wch == ' ') { + psz++; + } else { + return nullptr; + } + } + if (!pPseudoFirst) + return pFirst; + + pPseudoLast->SetNext(std::move(pFirst)); + return pPseudoFirst; +} diff --git a/xfa/fde/css/cfde_cssselector.h b/xfa/fde/css/cfde_cssselector.h new file mode 100644 index 0000000000..18a7c340e5 --- /dev/null +++ b/xfa/fde/css/cfde_cssselector.h @@ -0,0 +1,44 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FDE_CSS_CFDE_CSSSELECTOR_H_ +#define XFA_FDE_CSS_CFDE_CSSSELECTOR_H_ + +#include +#include + +#include "core/fxcrt/fx_string.h" +#include "xfa/fde/css/fde_css.h" + +class CFDE_CSSSelector { + public: + static std::unique_ptr FromString(const FX_WCHAR* psz, + int32_t iLen); + + CFDE_CSSSelector(FDE_CSSSelectorType eType, + const FX_WCHAR* psz, + int32_t iLen, + bool bIgnoreCase); + ~CFDE_CSSSelector(); + + FDE_CSSSelectorType GetType() const; + uint32_t GetNameHash() const; + CFDE_CSSSelector* GetNextSelector() const; + std::unique_ptr ReleaseNextSelector(); + + void SetNext(std::unique_ptr pNext) { + m_pNext = std::move(pNext); + } + + private: + void SetType(FDE_CSSSelectorType eType) { m_eType = eType; } + + FDE_CSSSelectorType m_eType; + uint32_t m_dwHash; + std::unique_ptr m_pNext; +}; + +#endif // XFA_FDE_CSS_CFDE_CSSSELECTOR_H_ diff --git a/xfa/fde/css/cfde_cssstylerule.cpp b/xfa/fde/css/cfde_cssstylerule.cpp new file mode 100644 index 0000000000..09c4a43f34 --- /dev/null +++ b/xfa/fde/css/cfde_cssstylerule.cpp @@ -0,0 +1,30 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fde/css/cfde_cssstylerule.h" + +CFDE_CSSStyleRule::CFDE_CSSStyleRule() : CFDE_CSSRule(FDE_CSSRuleType::Style) {} + +CFDE_CSSStyleRule::~CFDE_CSSStyleRule() {} + +size_t CFDE_CSSStyleRule::CountSelectorLists() const { + return m_ppSelector.size(); +} + +CFDE_CSSSelector* CFDE_CSSStyleRule::GetSelectorList(int32_t index) const { + return m_ppSelector[index].get(); +} + +CFDE_CSSDeclaration* CFDE_CSSStyleRule::GetDeclaration() { + return &m_Declaration; +} + +void CFDE_CSSStyleRule::SetSelector( + std::vector>* list) { + ASSERT(m_ppSelector.empty()); + + m_ppSelector.swap(*list); +} diff --git a/xfa/fde/css/cfde_cssstylerule.h b/xfa/fde/css/cfde_cssstylerule.h new file mode 100644 index 0000000000..bed0a5ec12 --- /dev/null +++ b/xfa/fde/css/cfde_cssstylerule.h @@ -0,0 +1,33 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FDE_CSS_CFDE_CSSSTYLERULE_H_ +#define XFA_FDE_CSS_CFDE_CSSSTYLERULE_H_ + +#include +#include + +#include "xfa/fde/css/cfde_cssdeclaration.h" +#include "xfa/fde/css/cfde_cssrule.h" +#include "xfa/fde/css/cfde_cssselector.h" + +class CFDE_CSSStyleRule : public CFDE_CSSRule { + public: + CFDE_CSSStyleRule(); + ~CFDE_CSSStyleRule() override; + + size_t CountSelectorLists() const; + CFDE_CSSSelector* GetSelectorList(int32_t index) const; + CFDE_CSSDeclaration* GetDeclaration(); + + void SetSelector(std::vector>* list); + + private: + CFDE_CSSDeclaration m_Declaration; + std::vector> m_ppSelector; +}; + +#endif // XFA_FDE_CSS_CFDE_CSSSTYLERULE_H_ diff --git a/xfa/fde/css/cfde_cssstyleselector.cpp b/xfa/fde/css/cfde_cssstyleselector.cpp new file mode 100644 index 0000000000..1539894017 --- /dev/null +++ b/xfa/fde/css/cfde_cssstyleselector.cpp @@ -0,0 +1,808 @@ +// 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 "xfa/fde/css/cfde_cssstyleselector.h" + +#include + +#include "third_party/base/ptr_util.h" +#include "xfa/fde/css/cfde_cssaccelerator.h" +#include "xfa/fde/css/cfde_csscolorvalue.h" +#include "xfa/fde/css/cfde_csscomputedstyle.h" +#include "xfa/fde/css/cfde_csscustomproperty.h" +#include "xfa/fde/css/cfde_cssdeclaration.h" +#include "xfa/fde/css/cfde_cssenumvalue.h" +#include "xfa/fde/css/cfde_csspropertyholder.h" +#include "xfa/fde/css/cfde_cssselector.h" +#include "xfa/fde/css/cfde_csssyntaxparser.h" +#include "xfa/fde/css/cfde_csstagcache.h" +#include "xfa/fde/css/cfde_cssvaluelist.h" +#include "xfa/fxfa/app/cxfa_csstagprovider.h" + +namespace { + +template +T* ToValue(CFDE_CSSValue* val) { + return static_cast(val); +} + +template +const T* ToValue(const CFDE_CSSValue* val) { + return static_cast(val); +} + +} // namespace + +#define FDE_CSSUNIVERSALHASH ('*') + +CFDE_CSSStyleSelector::CFDE_CSSStyleSelector(CFGAS_FontMgr* pFontMgr) + : m_pFontMgr(pFontMgr), m_fDefFontSize(12.0f) { + m_ePriorities[static_cast(FDE_CSSStyleSheetPriority::High)] = + FDE_CSSStyleSheetGroup::Author; + m_ePriorities[static_cast(FDE_CSSStyleSheetPriority::Mid)] = + FDE_CSSStyleSheetGroup::User; + m_ePriorities[static_cast(FDE_CSSStyleSheetPriority::Low)] = + FDE_CSSStyleSheetGroup::UserAgent; +} + +CFDE_CSSStyleSelector::~CFDE_CSSStyleSelector() { + Reset(); +} + +void CFDE_CSSStyleSelector::SetDefFontSize(FX_FLOAT fFontSize) { + ASSERT(fFontSize > 0); + m_fDefFontSize = fFontSize; +} + +CFDE_CSSAccelerator* CFDE_CSSStyleSelector::InitAccelerator() { + if (!m_pAccelerator) + m_pAccelerator = pdfium::MakeUnique(); + m_pAccelerator->Clear(); + return m_pAccelerator.get(); +} + +CFDE_CSSComputedStyle* CFDE_CSSStyleSelector::CreateComputedStyle( + CFDE_CSSComputedStyle* pParentStyle) { + CFDE_CSSComputedStyle* pStyle = new CFDE_CSSComputedStyle(); + if (pParentStyle) + pStyle->m_InheritedData = pParentStyle->m_InheritedData; + return pStyle; +} + +bool CFDE_CSSStyleSelector::SetStyleSheet(FDE_CSSStyleSheetGroup eType, + CFDE_CSSStyleSheet* pSheet) { + CFX_ArrayTemplate& dest = + m_SheetGroups[static_cast(eType)]; + dest.RemoveAt(0, dest.GetSize()); + if (pSheet) + dest.Add(pSheet); + return true; +} + +bool CFDE_CSSStyleSelector::SetStyleSheets( + FDE_CSSStyleSheetGroup eType, + const CFX_ArrayTemplate* pArray) { + CFX_ArrayTemplate& dest = + m_SheetGroups[static_cast(eType)]; + if (pArray) + dest.Copy(*pArray); + else + dest.RemoveAt(0, dest.GetSize()); + return true; +} + +void CFDE_CSSStyleSelector::SetStylePriority( + FDE_CSSStyleSheetGroup eType, + FDE_CSSStyleSheetPriority ePriority) { + m_ePriorities[static_cast(ePriority)] = eType; +} + +void CFDE_CSSStyleSelector::UpdateStyleIndex(uint32_t dwMediaList) { + Reset(); + + // TODO(dsinclair): Hard coded size bad. This should probably just be a map. + for (int32_t iGroup = 0; iGroup < 3; ++iGroup) { + CFDE_CSSRuleCollection& rules = m_RuleCollection[iGroup]; + rules.AddRulesFrom(m_SheetGroups[iGroup], dwMediaList, m_pFontMgr); + } +} + +void CFDE_CSSStyleSelector::Reset() { + // TODO(dsinclair): Hard coded size bad. This should probably just be a map. + for (int32_t iGroup = 0; iGroup < 3; ++iGroup) { + m_RuleCollection[iGroup].Clear(); + } +} + +int32_t CFDE_CSSStyleSelector::MatchDeclarations( + CXFA_CSSTagProvider* pTag, + CFX_ArrayTemplate& matchedDecls, + FDE_CSSPseudo ePseudoType) { + ASSERT(pTag); + CFDE_CSSTagCache* pCache = m_pAccelerator->top(); + ASSERT(pCache && pCache->GetTag() == pTag); + + matchedDecls.RemoveAt(0, matchedDecls.GetSize()); + // TODO(dsinclair): Hard coded size bad ... + for (int32_t ePriority = 2; ePriority >= 0; --ePriority) { + FDE_CSSStyleSheetGroup eGroup = m_ePriorities[ePriority]; + CFDE_CSSRuleCollection& rules = + m_RuleCollection[static_cast(eGroup)]; + if (rules.CountSelectors() == 0) + continue; + + if (ePseudoType == FDE_CSSPseudo::NONE) { + MatchRules(pCache, rules.GetUniversalRuleData(), ePseudoType); + if (pCache->HashTag()) { + MatchRules(pCache, rules.GetTagRuleData(pCache->HashTag()), + ePseudoType); + } + int32_t iCount = pCache->CountHashClass(); + for (int32_t i = 0; i < iCount; i++) { + pCache->SetClassIndex(i); + MatchRules(pCache, rules.GetClassRuleData(pCache->HashClass()), + ePseudoType); + } + } else { + MatchRules(pCache, rules.GetPseudoRuleData(), ePseudoType); + } + + std::sort(m_MatchedRules.begin(), m_MatchedRules.end(), + [](const CFDE_CSSRuleCollection::Data* p1, + const CFDE_CSSRuleCollection::Data* p2) { + return p1->dwPriority < p2->dwPriority; + }); + for (const auto& rule : m_MatchedRules) + matchedDecls.Add(rule->pDeclaration); + m_MatchedRules.clear(); + } + return matchedDecls.GetSize(); +} + +void CFDE_CSSStyleSelector::MatchRules(CFDE_CSSTagCache* pCache, + CFDE_CSSRuleCollection::Data* pList, + FDE_CSSPseudo ePseudoType) { + while (pList) { + if (MatchSelector(pCache, pList->pSelector, ePseudoType)) + m_MatchedRules.push_back(pList); + pList = pList->pNext; + } +} + +bool CFDE_CSSStyleSelector::MatchSelector(CFDE_CSSTagCache* pCache, + CFDE_CSSSelector* pSel, + FDE_CSSPseudo ePseudoType) { + uint32_t dwHash; + while (pSel && pCache) { + switch (pSel->GetType()) { + case FDE_CSSSelectorType::Descendant: + dwHash = pSel->GetNameHash(); + while ((pCache = pCache->GetParent()) != nullptr) { + if (dwHash != FDE_CSSUNIVERSALHASH && dwHash != pCache->HashTag()) { + continue; + } + if (MatchSelector(pCache, pSel->GetNextSelector(), ePseudoType)) { + return true; + } + } + return false; + case FDE_CSSSelectorType::ID: + dwHash = pCache->HashID(); + if (dwHash != pSel->GetNameHash()) { + return false; + } + break; + case FDE_CSSSelectorType::Class: + dwHash = pCache->HashClass(); + if (dwHash != pSel->GetNameHash()) { + return false; + } + break; + case FDE_CSSSelectorType::Element: + dwHash = pSel->GetNameHash(); + if (dwHash != FDE_CSSUNIVERSALHASH && dwHash != pCache->HashTag()) { + return false; + } + break; + case FDE_CSSSelectorType::Pseudo: + dwHash = FDE_GetCSSPseudoByEnum(ePseudoType)->dwHash; + if (dwHash != pSel->GetNameHash()) { + return false; + } + break; + default: + ASSERT(false); + break; + } + pSel = pSel->GetNextSelector(); + } + return !pSel && pCache; +} + +void CFDE_CSSStyleSelector::ComputeStyle( + CXFA_CSSTagProvider* pTag, + const CFDE_CSSDeclaration** ppDeclArray, + int32_t iDeclCount, + CFDE_CSSComputedStyle* pDestStyle) { + ASSERT(iDeclCount >= 0); + ASSERT(pDestStyle); + + static const uint32_t s_dwStyleHash = FX_HashCode_GetW(L"style", true); + static const uint32_t s_dwAlignHash = FX_HashCode_GetW(L"align", true); + + if (!pTag->empty()) { + CFDE_CSSDeclaration* pDecl = nullptr; + for (auto it : *pTag) { + CFX_WideString wsAttri = it.first; + CFX_WideString wsValue = it.second; + uint32_t dwAttriHash = FX_HashCode_GetW(wsAttri.AsStringC(), true); + if (dwAttriHash == s_dwStyleHash) { + if (!pDecl) + pDecl = new CFDE_CSSDeclaration; + + AppendInlineStyle(pDecl, wsValue.c_str(), wsValue.GetLength()); + } else if (dwAttriHash == s_dwAlignHash) { + if (!pDecl) + pDecl = new CFDE_CSSDeclaration; + + FDE_CSSPropertyArgs args; + args.pStringCache = nullptr; + args.pProperty = FDE_GetCSSPropertyByEnum(FDE_CSSProperty::TextAlign); + pDecl->AddProperty(&args, wsValue.c_str(), wsValue.GetLength()); + } + } + + if (pDecl) { + CFX_ArrayTemplate decls; + decls.SetSize(iDeclCount + 1); + CFDE_CSSDeclaration** ppInline = decls.GetData(); + FXSYS_memcpy(ppInline, ppDeclArray, + iDeclCount * sizeof(CFDE_CSSDeclaration*)); + ppInline[iDeclCount++] = pDecl; + ApplyDeclarations(true, const_cast(ppInline), + iDeclCount, pDestStyle); + ApplyDeclarations(false, + const_cast(ppInline), + iDeclCount, pDestStyle); + return; + } + } + + if (iDeclCount > 0) { + ASSERT(ppDeclArray); + + ApplyDeclarations(true, ppDeclArray, iDeclCount, pDestStyle); + ApplyDeclarations(false, ppDeclArray, iDeclCount, pDestStyle); + } +} + +void CFDE_CSSStyleSelector::ApplyDeclarations( + bool bPriority, + const CFDE_CSSDeclaration** ppDeclArray, + int32_t iDeclCount, + CFDE_CSSComputedStyle* pDestStyle) { + CFDE_CSSComputedStyle* pComputedStyle = pDestStyle; + + int32_t i; + if (bPriority) { + CFDE_CSSValue* pLastest = nullptr; + CFDE_CSSValue* pImportant = nullptr; + for (i = 0; i < iDeclCount; ++i) { + bool bImportant; + CFDE_CSSValue* pVal = + ppDeclArray[i]->GetProperty(FDE_CSSProperty::FontSize, bImportant); + if (!pVal) + continue; + + if (bImportant) + pImportant = pVal; + else + pLastest = pVal; + } + if (pImportant) { + ApplyProperty(FDE_CSSProperty::FontSize, pImportant, pComputedStyle); + } else if (pLastest) { + ApplyProperty(FDE_CSSProperty::FontSize, pLastest, pComputedStyle); + } + } else { + CFX_ArrayTemplate importants; + const CFDE_CSSDeclaration* pDecl = nullptr; + + for (i = 0; i < iDeclCount; ++i) { + pDecl = ppDeclArray[i]; + for (auto it = pDecl->begin(); it != pDecl->end(); it++) { + if ((*it)->eProperty == FDE_CSSProperty::FontSize) + continue; + if (!(*it)->bImportant) { + ApplyProperty((*it)->eProperty, (*it)->pValue.Get(), pComputedStyle); + } else if (importants.GetSize() == 0 || + importants[importants.GetUpperBound()] != pDecl) { + importants.Add(const_cast(pDecl)); + } + } + } + + iDeclCount = importants.GetSize(); + for (i = 0; i < iDeclCount; ++i) { + pDecl = importants[i]; + + for (auto it = pDecl->begin(); it != pDecl->end(); it++) { + if ((*it)->bImportant && (*it)->eProperty != FDE_CSSProperty::FontSize) + ApplyProperty((*it)->eProperty, (*it)->pValue.Get(), pComputedStyle); + } + } + + for (auto it = pDecl->custom_begin(); it != pDecl->custom_end(); it++) { + pComputedStyle->AddCustomStyle((*it)->pwsName, (*it)->pwsValue); + } + } +} + +void CFDE_CSSStyleSelector::AppendInlineStyle(CFDE_CSSDeclaration* pDecl, + const FX_WCHAR* psz, + int32_t iLen) { + ASSERT(pDecl && psz && iLen > 0); + auto pSyntax = pdfium::MakeUnique(); + if (!pSyntax->Init(psz, iLen, 32, true)) + return; + + int32_t iLen2 = 0; + const FX_WCHAR* psz2; + FDE_CSSPropertyArgs args; + args.pStringCache = nullptr; + args.pProperty = nullptr; + CFX_WideString wsName; + while (1) { + FDE_CSSSyntaxStatus eStatus = pSyntax->DoSyntaxParse(); + if (eStatus == FDE_CSSSyntaxStatus::PropertyName) { + psz2 = pSyntax->GetCurrentString(iLen2); + args.pProperty = FDE_GetCSSPropertyByName(CFX_WideStringC(psz2, iLen2)); + if (!args.pProperty) + wsName = CFX_WideStringC(psz2, iLen2); + } else if (eStatus == FDE_CSSSyntaxStatus::PropertyValue) { + if (args.pProperty) { + psz2 = pSyntax->GetCurrentString(iLen2); + if (iLen2 > 0) + pDecl->AddProperty(&args, psz2, iLen2); + } else if (iLen2 > 0) { + psz2 = pSyntax->GetCurrentString(iLen2); + if (iLen2 > 0) { + pDecl->AddProperty(&args, wsName.c_str(), wsName.GetLength(), psz2, + iLen2); + } + } + } else { + break; + } + } +} + +void CFDE_CSSStyleSelector::ApplyProperty( + FDE_CSSProperty eProperty, + CFDE_CSSValue* pValue, + CFDE_CSSComputedStyle* pComputedStyle) { + if (pValue->GetType() != FDE_CSSPrimitiveType::List) { + FDE_CSSPrimitiveType eType = pValue->GetType(); + switch (eProperty) { + case FDE_CSSProperty::Display: + if (eType == FDE_CSSPrimitiveType::Enum) { + pComputedStyle->m_NonInheritedData.m_eDisplay = + ToDisplay(ToValue(pValue)->Value()); + } + break; + case FDE_CSSProperty::FontSize: { + FX_FLOAT& fFontSize = pComputedStyle->m_InheritedData.m_fFontSize; + if (eType == FDE_CSSPrimitiveType::Number) { + fFontSize = ToValue(pValue)->Apply(fFontSize); + } else if (eType == FDE_CSSPrimitiveType::Enum) { + fFontSize = ToFontSize(ToValue(pValue)->Value(), + fFontSize); + } + } break; + case FDE_CSSProperty::LineHeight: + if (eType == FDE_CSSPrimitiveType::Number) { + const CFDE_CSSNumberValue* v = ToValue(pValue); + if (v->Kind() == FDE_CSSNumberType::Number) { + pComputedStyle->m_InheritedData.m_fLineHeight = + v->Value() * pComputedStyle->m_InheritedData.m_fFontSize; + } else { + pComputedStyle->m_InheritedData.m_fLineHeight = + v->Apply(pComputedStyle->m_InheritedData.m_fFontSize); + } + } + break; + case FDE_CSSProperty::TextAlign: + if (eType == FDE_CSSPrimitiveType::Enum) { + pComputedStyle->m_InheritedData.m_eTextAlign = + ToTextAlign(ToValue(pValue)->Value()); + } + break; + case FDE_CSSProperty::TextIndent: + SetLengthWithPercent(pComputedStyle->m_InheritedData.m_TextIndent, + eType, pValue, + pComputedStyle->m_InheritedData.m_fFontSize); + break; + case FDE_CSSProperty::FontWeight: + if (eType == FDE_CSSPrimitiveType::Enum) { + pComputedStyle->m_InheritedData.m_wFontWeight = + ToFontWeight(ToValue(pValue)->Value()); + } else if (eType == FDE_CSSPrimitiveType::Number) { + int32_t iValue = + (int32_t)ToValue(pValue)->Value() / 100; + if (iValue >= 1 && iValue <= 9) { + pComputedStyle->m_InheritedData.m_wFontWeight = iValue * 100; + } + } + break; + case FDE_CSSProperty::FontStyle: + if (eType == FDE_CSSPrimitiveType::Enum) { + pComputedStyle->m_InheritedData.m_eFontStyle = + ToFontStyle(ToValue(pValue)->Value()); + } + break; + case FDE_CSSProperty::Color: + if (eType == FDE_CSSPrimitiveType::RGB) { + pComputedStyle->m_InheritedData.m_dwFontColor = + ToValue(pValue)->Value(); + } + break; + case FDE_CSSProperty::MarginLeft: + if (SetLengthWithPercent( + pComputedStyle->m_NonInheritedData.m_MarginWidth.left, eType, + pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { + pComputedStyle->m_NonInheritedData.m_bHasMargin = true; + } + break; + case FDE_CSSProperty::MarginTop: + if (SetLengthWithPercent( + pComputedStyle->m_NonInheritedData.m_MarginWidth.top, eType, + pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { + pComputedStyle->m_NonInheritedData.m_bHasMargin = true; + } + break; + case FDE_CSSProperty::MarginRight: + if (SetLengthWithPercent( + pComputedStyle->m_NonInheritedData.m_MarginWidth.right, eType, + pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { + pComputedStyle->m_NonInheritedData.m_bHasMargin = true; + } + break; + case FDE_CSSProperty::MarginBottom: + if (SetLengthWithPercent( + pComputedStyle->m_NonInheritedData.m_MarginWidth.bottom, eType, + pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { + pComputedStyle->m_NonInheritedData.m_bHasMargin = true; + } + break; + case FDE_CSSProperty::PaddingLeft: + if (SetLengthWithPercent( + pComputedStyle->m_NonInheritedData.m_PaddingWidth.left, eType, + pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { + pComputedStyle->m_NonInheritedData.m_bHasPadding = true; + } + break; + case FDE_CSSProperty::PaddingTop: + if (SetLengthWithPercent( + pComputedStyle->m_NonInheritedData.m_PaddingWidth.top, eType, + pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { + pComputedStyle->m_NonInheritedData.m_bHasPadding = true; + } + break; + case FDE_CSSProperty::PaddingRight: + if (SetLengthWithPercent( + pComputedStyle->m_NonInheritedData.m_PaddingWidth.right, eType, + pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { + pComputedStyle->m_NonInheritedData.m_bHasPadding = true; + } + break; + case FDE_CSSProperty::PaddingBottom: + if (SetLengthWithPercent( + pComputedStyle->m_NonInheritedData.m_PaddingWidth.bottom, eType, + pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { + pComputedStyle->m_NonInheritedData.m_bHasPadding = true; + } + break; + case FDE_CSSProperty::BorderLeftWidth: + if (SetLengthWithPercent( + pComputedStyle->m_NonInheritedData.m_BorderWidth.left, eType, + pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { + pComputedStyle->m_NonInheritedData.m_bHasBorder = true; + } + break; + case FDE_CSSProperty::BorderTopWidth: + if (SetLengthWithPercent( + pComputedStyle->m_NonInheritedData.m_BorderWidth.top, eType, + pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { + pComputedStyle->m_NonInheritedData.m_bHasBorder = true; + } + break; + case FDE_CSSProperty::BorderRightWidth: + if (SetLengthWithPercent( + pComputedStyle->m_NonInheritedData.m_BorderWidth.right, eType, + pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { + pComputedStyle->m_NonInheritedData.m_bHasBorder = true; + } + break; + case FDE_CSSProperty::BorderBottomWidth: + if (SetLengthWithPercent( + pComputedStyle->m_NonInheritedData.m_BorderWidth.bottom, eType, + pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { + pComputedStyle->m_NonInheritedData.m_bHasBorder = true; + } + break; + case FDE_CSSProperty::VerticalAlign: + if (eType == FDE_CSSPrimitiveType::Enum) { + pComputedStyle->m_NonInheritedData.m_eVerticalAlign = + ToVerticalAlign(ToValue(pValue)->Value()); + } else if (eType == FDE_CSSPrimitiveType::Number) { + pComputedStyle->m_NonInheritedData.m_eVerticalAlign = + FDE_CSSVerticalAlign::Number; + pComputedStyle->m_NonInheritedData.m_fVerticalAlign = + ToValue(pValue)->Apply( + pComputedStyle->m_InheritedData.m_fFontSize); + } + break; + case FDE_CSSProperty::FontVariant: + if (eType == FDE_CSSPrimitiveType::Enum) { + pComputedStyle->m_InheritedData.m_eFontVariant = + ToFontVariant(ToValue(pValue)->Value()); + } + break; + case FDE_CSSProperty::LetterSpacing: + if (eType == FDE_CSSPrimitiveType::Enum) { + pComputedStyle->m_InheritedData.m_LetterSpacing.Set( + FDE_CSSLengthUnit::Normal); + } else if (eType == FDE_CSSPrimitiveType::Number) { + if (ToValue(pValue)->Kind() == + FDE_CSSNumberType::Percent) { + break; + } + + SetLengthWithPercent(pComputedStyle->m_InheritedData.m_LetterSpacing, + eType, pValue, + pComputedStyle->m_InheritedData.m_fFontSize); + } + break; + case FDE_CSSProperty::WordSpacing: + if (eType == FDE_CSSPrimitiveType::Enum) { + pComputedStyle->m_InheritedData.m_WordSpacing.Set( + FDE_CSSLengthUnit::Normal); + } else if (eType == FDE_CSSPrimitiveType::Number) { + if (ToValue(pValue)->Kind() == + FDE_CSSNumberType::Percent) { + break; + } + SetLengthWithPercent(pComputedStyle->m_InheritedData.m_WordSpacing, + eType, pValue, + pComputedStyle->m_InheritedData.m_fFontSize); + } + break; + case FDE_CSSProperty::Top: + SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Top, eType, + pValue, + pComputedStyle->m_InheritedData.m_fFontSize); + break; + case FDE_CSSProperty::Bottom: + SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Bottom, eType, + pValue, + pComputedStyle->m_InheritedData.m_fFontSize); + break; + case FDE_CSSProperty::Left: + SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Left, eType, + pValue, + pComputedStyle->m_InheritedData.m_fFontSize); + break; + case FDE_CSSProperty::Right: + SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Right, eType, + pValue, + pComputedStyle->m_InheritedData.m_fFontSize); + break; + default: + break; + } + } else if (pValue->GetType() == FDE_CSSPrimitiveType::List) { + CFDE_CSSValueList* pList = ToValue(pValue); + int32_t iCount = pList->CountValues(); + if (iCount > 0) { + switch (eProperty) { + case FDE_CSSProperty::FontFamily: + pComputedStyle->m_InheritedData.m_pFontFamily = pList; + break; + case FDE_CSSProperty::TextDecoration: + pComputedStyle->m_NonInheritedData.m_dwTextDecoration = + ToTextDecoration(pList); + break; + default: + break; + } + } + } else { + ASSERT(false); + } +} + +FDE_CSSDisplay CFDE_CSSStyleSelector::ToDisplay(FDE_CSSPropertyValue eValue) { + switch (eValue) { + case FDE_CSSPropertyValue::Block: + return FDE_CSSDisplay::Block; + case FDE_CSSPropertyValue::None: + return FDE_CSSDisplay::None; + case FDE_CSSPropertyValue::ListItem: + return FDE_CSSDisplay::ListItem; + case FDE_CSSPropertyValue::InlineTable: + return FDE_CSSDisplay::InlineTable; + case FDE_CSSPropertyValue::InlineBlock: + return FDE_CSSDisplay::InlineBlock; + case FDE_CSSPropertyValue::Inline: + default: + return FDE_CSSDisplay::Inline; + } +} + +FDE_CSSTextAlign CFDE_CSSStyleSelector::ToTextAlign( + FDE_CSSPropertyValue eValue) { + switch (eValue) { + case FDE_CSSPropertyValue::Center: + return FDE_CSSTextAlign::Center; + case FDE_CSSPropertyValue::Right: + return FDE_CSSTextAlign::Right; + case FDE_CSSPropertyValue::Justify: + return FDE_CSSTextAlign::Justify; + case FDE_CSSPropertyValue::Left: + default: + return FDE_CSSTextAlign::Left; + } +} + +uint16_t CFDE_CSSStyleSelector::ToFontWeight(FDE_CSSPropertyValue eValue) { + switch (eValue) { + case FDE_CSSPropertyValue::Bold: + return 700; + case FDE_CSSPropertyValue::Bolder: + return 900; + case FDE_CSSPropertyValue::Lighter: + return 200; + case FDE_CSSPropertyValue::Normal: + default: + return 400; + } +} + +FDE_CSSFontStyle CFDE_CSSStyleSelector::ToFontStyle( + FDE_CSSPropertyValue eValue) { + switch (eValue) { + case FDE_CSSPropertyValue::Italic: + case FDE_CSSPropertyValue::Oblique: + return FDE_CSSFontStyle::Italic; + default: + return FDE_CSSFontStyle::Normal; + } +} + +bool CFDE_CSSStyleSelector::SetLengthWithPercent(FDE_CSSLength& width, + FDE_CSSPrimitiveType eType, + CFDE_CSSValue* pValue, + FX_FLOAT fFontSize) { + if (eType == FDE_CSSPrimitiveType::Number) { + const CFDE_CSSNumberValue* v = ToValue(pValue); + if (v->Kind() == FDE_CSSNumberType::Percent) { + width.Set(FDE_CSSLengthUnit::Percent, + ToValue(pValue)->Value() / 100.0f); + return width.NonZero(); + } + + FX_FLOAT fValue = v->Apply(fFontSize); + width.Set(FDE_CSSLengthUnit::Point, fValue); + return width.NonZero(); + } else if (eType == FDE_CSSPrimitiveType::Enum) { + switch (ToValue(pValue)->Value()) { + case FDE_CSSPropertyValue::Auto: + width.Set(FDE_CSSLengthUnit::Auto); + return true; + case FDE_CSSPropertyValue::None: + width.Set(FDE_CSSLengthUnit::None); + return true; + case FDE_CSSPropertyValue::Thin: + width.Set(FDE_CSSLengthUnit::Point, 2); + return true; + case FDE_CSSPropertyValue::Medium: + width.Set(FDE_CSSLengthUnit::Point, 3); + return true; + case FDE_CSSPropertyValue::Thick: + width.Set(FDE_CSSLengthUnit::Point, 4); + return true; + default: + return false; + } + } + return false; +} + +FX_FLOAT CFDE_CSSStyleSelector::ToFontSize(FDE_CSSPropertyValue eValue, + FX_FLOAT fCurFontSize) { + switch (eValue) { + case FDE_CSSPropertyValue::XxSmall: + return m_fDefFontSize / 1.2f / 1.2f / 1.2f; + case FDE_CSSPropertyValue::XSmall: + return m_fDefFontSize / 1.2f / 1.2f; + case FDE_CSSPropertyValue::Small: + return m_fDefFontSize / 1.2f; + case FDE_CSSPropertyValue::Medium: + return m_fDefFontSize; + case FDE_CSSPropertyValue::Large: + return m_fDefFontSize * 1.2f; + case FDE_CSSPropertyValue::XLarge: + return m_fDefFontSize * 1.2f * 1.2f; + case FDE_CSSPropertyValue::XxLarge: + return m_fDefFontSize * 1.2f * 1.2f * 1.2f; + case FDE_CSSPropertyValue::Larger: + return fCurFontSize * 1.2f; + case FDE_CSSPropertyValue::Smaller: + return fCurFontSize / 1.2f; + default: + return fCurFontSize; + } +} + +FDE_CSSVerticalAlign CFDE_CSSStyleSelector::ToVerticalAlign( + FDE_CSSPropertyValue eValue) { + switch (eValue) { + case FDE_CSSPropertyValue::Middle: + return FDE_CSSVerticalAlign::Middle; + case FDE_CSSPropertyValue::Bottom: + return FDE_CSSVerticalAlign::Bottom; + case FDE_CSSPropertyValue::Super: + return FDE_CSSVerticalAlign::Super; + case FDE_CSSPropertyValue::Sub: + return FDE_CSSVerticalAlign::Sub; + case FDE_CSSPropertyValue::Top: + return FDE_CSSVerticalAlign::Top; + case FDE_CSSPropertyValue::TextTop: + return FDE_CSSVerticalAlign::TextTop; + case FDE_CSSPropertyValue::TextBottom: + return FDE_CSSVerticalAlign::TextBottom; + case FDE_CSSPropertyValue::Baseline: + default: + return FDE_CSSVerticalAlign::Baseline; + } +} + +uint32_t CFDE_CSSStyleSelector::ToTextDecoration(CFDE_CSSValueList* pValue) { + uint32_t dwDecoration = 0; + for (int32_t i = pValue->CountValues() - 1; i >= 0; --i) { + CFDE_CSSValue* pVal = pValue->GetValue(i); + if (pVal->GetType() != FDE_CSSPrimitiveType::Enum) + continue; + + switch (ToValue(pVal)->Value()) { + case FDE_CSSPropertyValue::Underline: + dwDecoration |= FDE_CSSTEXTDECORATION_Underline; + break; + case FDE_CSSPropertyValue::LineThrough: + dwDecoration |= FDE_CSSTEXTDECORATION_LineThrough; + break; + case FDE_CSSPropertyValue::Overline: + dwDecoration |= FDE_CSSTEXTDECORATION_Overline; + break; + case FDE_CSSPropertyValue::Blink: + dwDecoration |= FDE_CSSTEXTDECORATION_Blink; + break; + case FDE_CSSPropertyValue::Double: + dwDecoration |= FDE_CSSTEXTDECORATION_Double; + break; + default: + break; + } + } + return dwDecoration; +} + +FDE_CSSFontVariant CFDE_CSSStyleSelector::ToFontVariant( + FDE_CSSPropertyValue eValue) { + return eValue == FDE_CSSPropertyValue::SmallCaps + ? FDE_CSSFontVariant::SmallCaps + : FDE_CSSFontVariant::Normal; +} diff --git a/xfa/fde/css/cfde_cssstyleselector.h b/xfa/fde/css/cfde_cssstyleselector.h new file mode 100644 index 0000000000..6a7ae99216 --- /dev/null +++ b/xfa/fde/css/cfde_cssstyleselector.h @@ -0,0 +1,95 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FDE_CSS_CFDE_CSSSTYLESELECTOR_H_ +#define XFA_FDE_CSS_CFDE_CSSSTYLESELECTOR_H_ + +#include +#include + +#include "core/fxcrt/fx_basic.h" +#include "core/fxcrt/fx_system.h" +#include "xfa/fde/css/cfde_cssrulecollection.h" +#include "xfa/fde/css/fde_css.h" + +class CFDE_CSSAccelerator; +class CFDE_CSSComputedStyle; +class CFDE_CSSDeclaration; +class CFDE_CSSSelector; +class CFDE_CSSStyleSheet; +class CFDE_CSSTagCache; +class CFDE_CSSValue; +class CFDE_CSSValueList; +class CFGAS_FontMgr; +class CXFA_CSSTagProvider; + +class CFDE_CSSStyleSelector { + public: + explicit CFDE_CSSStyleSelector(CFGAS_FontMgr* pFontMgr); + ~CFDE_CSSStyleSelector(); + + void SetDefFontSize(FX_FLOAT fFontSize); + + bool SetStyleSheet(FDE_CSSStyleSheetGroup eType, CFDE_CSSStyleSheet* pSheet); + bool SetStyleSheets(FDE_CSSStyleSheetGroup eType, + const CFX_ArrayTemplate* pArray); + void SetStylePriority(FDE_CSSStyleSheetGroup eType, + FDE_CSSStyleSheetPriority ePriority); + void UpdateStyleIndex(uint32_t dwMediaList); + CFDE_CSSAccelerator* InitAccelerator(); + CFDE_CSSComputedStyle* CreateComputedStyle( + CFDE_CSSComputedStyle* pParentStyle); + int32_t MatchDeclarations( + CXFA_CSSTagProvider* pTag, + CFX_ArrayTemplate& matchedDecls, + FDE_CSSPseudo ePseudoType = FDE_CSSPseudo::NONE); + void ComputeStyle(CXFA_CSSTagProvider* pTag, + const CFDE_CSSDeclaration** ppDeclArray, + int32_t iDeclCount, + CFDE_CSSComputedStyle* pDestStyle); + + protected: + void Reset(); + void MatchRules(CFDE_CSSTagCache* pCache, + CFDE_CSSRuleCollection::Data* pList, + FDE_CSSPseudo ePseudoType); + bool MatchSelector(CFDE_CSSTagCache* pCache, + CFDE_CSSSelector* pSel, + FDE_CSSPseudo ePseudoType); + void AppendInlineStyle(CFDE_CSSDeclaration* pDecl, + const FX_WCHAR* psz, + int32_t iLen); + void ApplyDeclarations(bool bPriority, + const CFDE_CSSDeclaration** ppDeclArray, + int32_t iDeclCount, + CFDE_CSSComputedStyle* pDestStyle); + void ApplyProperty(FDE_CSSProperty eProperty, + CFDE_CSSValue* pValue, + CFDE_CSSComputedStyle* pComputedStyle); + + bool SetLengthWithPercent(FDE_CSSLength& width, + FDE_CSSPrimitiveType eType, + CFDE_CSSValue* pValue, + FX_FLOAT fFontSize); + FX_FLOAT ToFontSize(FDE_CSSPropertyValue eValue, FX_FLOAT fCurFontSize); + FDE_CSSDisplay ToDisplay(FDE_CSSPropertyValue eValue); + FDE_CSSTextAlign ToTextAlign(FDE_CSSPropertyValue eValue); + uint16_t ToFontWeight(FDE_CSSPropertyValue eValue); + FDE_CSSFontStyle ToFontStyle(FDE_CSSPropertyValue eValue); + FDE_CSSVerticalAlign ToVerticalAlign(FDE_CSSPropertyValue eValue); + uint32_t ToTextDecoration(CFDE_CSSValueList* pList); + FDE_CSSFontVariant ToFontVariant(FDE_CSSPropertyValue eValue); + + CFGAS_FontMgr* const m_pFontMgr; + FX_FLOAT m_fDefFontSize; + CFX_ArrayTemplate m_SheetGroups[3]; + CFDE_CSSRuleCollection m_RuleCollection[3]; + FDE_CSSStyleSheetGroup m_ePriorities[3]; + std::unique_ptr m_pAccelerator; + std::vector m_MatchedRules; +}; + +#endif // XFA_FDE_CSS_CFDE_CSSSTYLESELECTOR_H_ diff --git a/xfa/fde/css/cfde_cssstylesheet.cpp b/xfa/fde/css/cfde_cssstylesheet.cpp new file mode 100644 index 0000000000..4ff1b97916 --- /dev/null +++ b/xfa/fde/css/cfde_cssstylesheet.cpp @@ -0,0 +1,292 @@ +// 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 "xfa/fde/css/cfde_cssstylesheet.h" + +#include + +#include "third_party/base/ptr_util.h" +#include "third_party/base/stl_util.h" +#include "xfa/fde/css/cfde_cssdeclaration.h" +#include "xfa/fde/css/cfde_cssfontfacerule.h" +#include "xfa/fde/css/cfde_cssmediarule.h" +#include "xfa/fde/css/cfde_cssrule.h" +#include "xfa/fde/css/cfde_cssstylerule.h" +#include "xfa/fde/css/fde_cssdatatable.h" +#include "xfa/fgas/crt/fgas_codepage.h" + +CFDE_CSSStyleSheet::CFDE_CSSStyleSheet() + : m_wRefCount(1), m_dwMediaList(FDE_CSSMEDIATYPE_ALL) { + ASSERT(m_dwMediaList > 0); +} + +CFDE_CSSStyleSheet::~CFDE_CSSStyleSheet() { + Reset(); +} + +void CFDE_CSSStyleSheet::Reset() { + m_RuleArray.clear(); + m_StringCache.clear(); +} + +uint32_t CFDE_CSSStyleSheet::Retain() { + return ++m_wRefCount; +} + +uint32_t CFDE_CSSStyleSheet::Release() { + uint32_t dwRefCount = --m_wRefCount; + if (dwRefCount == 0) + delete this; + return dwRefCount; +} + +uint32_t CFDE_CSSStyleSheet::GetMediaList() const { + return m_dwMediaList; +} + +int32_t CFDE_CSSStyleSheet::CountRules() const { + return pdfium::CollectionSize(m_RuleArray); +} + +CFDE_CSSRule* CFDE_CSSStyleSheet::GetRule(int32_t index) { + return m_RuleArray[index].get(); +} + +bool CFDE_CSSStyleSheet::LoadFromBuffer(const FX_WCHAR* pBuffer, + int32_t iBufSize) { + ASSERT(pBuffer && iBufSize > 0); + + auto pSyntax = pdfium::MakeUnique(); + return pSyntax->Init(pBuffer, iBufSize) && LoadFromSyntax(pSyntax.get()); +} + +bool CFDE_CSSStyleSheet::LoadFromSyntax(CFDE_CSSSyntaxParser* pSyntax) { + Reset(); + FDE_CSSSyntaxStatus eStatus; + do { + switch (eStatus = pSyntax->DoSyntaxParse()) { + case FDE_CSSSyntaxStatus::StyleRule: + eStatus = LoadStyleRule(pSyntax, &m_RuleArray); + break; + case FDE_CSSSyntaxStatus::MediaRule: + eStatus = LoadMediaRule(pSyntax); + break; + case FDE_CSSSyntaxStatus::FontFaceRule: + eStatus = LoadFontFaceRule(pSyntax, &m_RuleArray); + break; + case FDE_CSSSyntaxStatus::ImportRule: + eStatus = LoadImportRule(pSyntax); + break; + case FDE_CSSSyntaxStatus::PageRule: + eStatus = LoadPageRule(pSyntax); + break; + default: + break; + } + } while (eStatus >= FDE_CSSSyntaxStatus::None); + + m_StringCache.clear(); + return eStatus != FDE_CSSSyntaxStatus::Error; +} + +FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadMediaRule( + CFDE_CSSSyntaxParser* pSyntax) { + uint32_t dwMediaList = 0; + CFDE_CSSMediaRule* pMediaRule = nullptr; + for (;;) { + switch (pSyntax->DoSyntaxParse()) { + case FDE_CSSSyntaxStatus::MediaType: { + int32_t iLen; + const FX_WCHAR* psz = pSyntax->GetCurrentString(iLen); + const FDE_CSSMEDIATYPETABLE* pMediaType = + FDE_GetCSSMediaTypeByName(CFX_WideStringC(psz, iLen)); + if (pMediaType) + dwMediaList |= pMediaType->wValue; + } break; + case FDE_CSSSyntaxStatus::StyleRule: + if (pMediaRule) { + FDE_CSSSyntaxStatus eStatus = + LoadStyleRule(pSyntax, &pMediaRule->GetArray()); + if (eStatus < FDE_CSSSyntaxStatus::None) { + return eStatus; + } + } else { + SkipRuleSet(pSyntax); + } + break; + case FDE_CSSSyntaxStatus::DeclOpen: + if ((dwMediaList & m_dwMediaList) > 0 && !pMediaRule) { + m_RuleArray.push_back( + pdfium::MakeUnique(dwMediaList)); + pMediaRule = + static_cast(m_RuleArray.back().get()); + } + break; + case FDE_CSSSyntaxStatus::DeclClose: + return FDE_CSSSyntaxStatus::None; + case FDE_CSSSyntaxStatus::EOS: + return FDE_CSSSyntaxStatus::EOS; + case FDE_CSSSyntaxStatus::Error: + default: + return FDE_CSSSyntaxStatus::Error; + } + } +} + +FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadStyleRule( + CFDE_CSSSyntaxParser* pSyntax, + std::vector>* ruleArray) { + std::vector> selectors; + + CFDE_CSSStyleRule* pStyleRule = nullptr; + const FX_WCHAR* pszValue = nullptr; + int32_t iValueLen = 0; + FDE_CSSPropertyArgs propertyArgs; + propertyArgs.pStringCache = &m_StringCache; + propertyArgs.pProperty = nullptr; + CFX_WideString wsName; + for (;;) { + switch (pSyntax->DoSyntaxParse()) { + case FDE_CSSSyntaxStatus::Selector: { + pszValue = pSyntax->GetCurrentString(iValueLen); + auto pSelector = CFDE_CSSSelector::FromString(pszValue, iValueLen); + if (pSelector) + selectors.push_back(std::move(pSelector)); + break; + } + case FDE_CSSSyntaxStatus::PropertyName: + pszValue = pSyntax->GetCurrentString(iValueLen); + propertyArgs.pProperty = + FDE_GetCSSPropertyByName(CFX_WideStringC(pszValue, iValueLen)); + if (!propertyArgs.pProperty) + wsName = CFX_WideStringC(pszValue, iValueLen); + break; + case FDE_CSSSyntaxStatus::PropertyValue: + if (propertyArgs.pProperty) { + pszValue = pSyntax->GetCurrentString(iValueLen); + if (iValueLen > 0) { + pStyleRule->GetDeclaration()->AddProperty(&propertyArgs, pszValue, + iValueLen); + } + } else if (iValueLen > 0) { + pszValue = pSyntax->GetCurrentString(iValueLen); + if (iValueLen > 0) { + pStyleRule->GetDeclaration()->AddProperty( + &propertyArgs, wsName.c_str(), wsName.GetLength(), pszValue, + iValueLen); + } + } + break; + case FDE_CSSSyntaxStatus::DeclOpen: + if (!pStyleRule && !selectors.empty()) { + auto rule = pdfium::MakeUnique(); + pStyleRule = rule.get(); + pStyleRule->SetSelector(&selectors); + ruleArray->push_back(std::move(rule)); + } else { + SkipRuleSet(pSyntax); + return FDE_CSSSyntaxStatus::None; + } + break; + case FDE_CSSSyntaxStatus::DeclClose: + if (pStyleRule && pStyleRule->GetDeclaration()->empty()) { + ruleArray->pop_back(); + pStyleRule = nullptr; + } + return FDE_CSSSyntaxStatus::None; + case FDE_CSSSyntaxStatus::EOS: + return FDE_CSSSyntaxStatus::EOS; + case FDE_CSSSyntaxStatus::Error: + default: + return FDE_CSSSyntaxStatus::Error; + } + } +} + +FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadFontFaceRule( + CFDE_CSSSyntaxParser* pSyntax, + std::vector>* ruleArray) { + CFDE_CSSFontFaceRule* pFontFaceRule = nullptr; + const FX_WCHAR* pszValue = nullptr; + int32_t iValueLen = 0; + FDE_CSSPropertyArgs propertyArgs; + propertyArgs.pStringCache = &m_StringCache; + propertyArgs.pProperty = nullptr; + for (;;) { + switch (pSyntax->DoSyntaxParse()) { + case FDE_CSSSyntaxStatus::PropertyName: + pszValue = pSyntax->GetCurrentString(iValueLen); + propertyArgs.pProperty = + FDE_GetCSSPropertyByName(CFX_WideStringC(pszValue, iValueLen)); + break; + case FDE_CSSSyntaxStatus::PropertyValue: + if (propertyArgs.pProperty) { + pszValue = pSyntax->GetCurrentString(iValueLen); + if (iValueLen > 0) { + pFontFaceRule->GetDeclaration()->AddProperty(&propertyArgs, + pszValue, iValueLen); + } + } + break; + case FDE_CSSSyntaxStatus::DeclOpen: + if (!pFontFaceRule) { + auto rule = pdfium::MakeUnique(); + pFontFaceRule = rule.get(); + ruleArray->push_back(std::move(rule)); + } + break; + case FDE_CSSSyntaxStatus::DeclClose: + return FDE_CSSSyntaxStatus::None; + case FDE_CSSSyntaxStatus::EOS: + return FDE_CSSSyntaxStatus::EOS; + case FDE_CSSSyntaxStatus::Error: + default: + return FDE_CSSSyntaxStatus::Error; + } + } +} + +FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadImportRule( + CFDE_CSSSyntaxParser* pSyntax) { + for (;;) { + switch (pSyntax->DoSyntaxParse()) { + case FDE_CSSSyntaxStatus::ImportClose: + return FDE_CSSSyntaxStatus::None; + case FDE_CSSSyntaxStatus::URI: + break; + case FDE_CSSSyntaxStatus::EOS: + return FDE_CSSSyntaxStatus::EOS; + case FDE_CSSSyntaxStatus::Error: + default: + return FDE_CSSSyntaxStatus::Error; + } + } +} + +FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadPageRule( + CFDE_CSSSyntaxParser* pSyntax) { + return SkipRuleSet(pSyntax); +} + +FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::SkipRuleSet( + CFDE_CSSSyntaxParser* pSyntax) { + for (;;) { + switch (pSyntax->DoSyntaxParse()) { + case FDE_CSSSyntaxStatus::Selector: + case FDE_CSSSyntaxStatus::DeclOpen: + case FDE_CSSSyntaxStatus::PropertyName: + case FDE_CSSSyntaxStatus::PropertyValue: + break; + case FDE_CSSSyntaxStatus::DeclClose: + return FDE_CSSSyntaxStatus::None; + case FDE_CSSSyntaxStatus::EOS: + return FDE_CSSSyntaxStatus::EOS; + case FDE_CSSSyntaxStatus::Error: + default: + return FDE_CSSSyntaxStatus::Error; + } + } +} diff --git a/xfa/fde/css/cfde_cssstylesheet.h b/xfa/fde/css/cfde_cssstylesheet.h new file mode 100644 index 0000000000..2268efa2e4 --- /dev/null +++ b/xfa/fde/css/cfde_cssstylesheet.h @@ -0,0 +1,55 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FDE_CSS_CFDE_CSSSTYLESHEET_H_ +#define XFA_FDE_CSS_CFDE_CSSSTYLESHEET_H_ + +#include +#include +#include + +#include "core/fxcrt/fx_basic.h" +#include "core/fxcrt/fx_string.h" +#include "xfa/fde/css/cfde_csssyntaxparser.h" + +class CFDE_CSSRule; + +class CFDE_CSSStyleSheet : public IFX_Retainable { + public: + CFDE_CSSStyleSheet(); + ~CFDE_CSSStyleSheet() override; + + // IFX_Retainable: + uint32_t Retain() override; + uint32_t Release() override; + + bool LoadFromBuffer(const FX_WCHAR* pBuffer, int32_t iBufSize); + + uint32_t GetMediaList() const; + int32_t CountRules() const; + CFDE_CSSRule* GetRule(int32_t index); + + private: + void Reset(); + bool LoadFromSyntax(CFDE_CSSSyntaxParser* pSyntax); + FDE_CSSSyntaxStatus LoadStyleRule( + CFDE_CSSSyntaxParser* pSyntax, + std::vector>* ruleArray); + FDE_CSSSyntaxStatus LoadImportRule(CFDE_CSSSyntaxParser* pSyntax); + FDE_CSSSyntaxStatus LoadPageRule(CFDE_CSSSyntaxParser* pSyntax); + FDE_CSSSyntaxStatus LoadMediaRule(CFDE_CSSSyntaxParser* pSyntax); + FDE_CSSSyntaxStatus LoadFontFaceRule( + CFDE_CSSSyntaxParser* pSyntax, + std::vector>* ruleArray); + FDE_CSSSyntaxStatus SkipRuleSet(CFDE_CSSSyntaxParser* pSyntax); + + uint16_t m_wRefCount; + uint32_t m_dwMediaList; + std::vector> m_RuleArray; + std::unordered_map m_StringCache; +}; + +#endif // XFA_FDE_CSS_CFDE_CSSSTYLESHEET_H_ diff --git a/xfa/fde/css/cfde_cssstylesheet_unittest.cpp b/xfa/fde/css/cfde_cssstylesheet_unittest.cpp index e65e36d252..080b45aa1b 100644 --- a/xfa/fde/css/cfde_cssstylesheet_unittest.cpp +++ b/xfa/fde/css/cfde_cssstylesheet_unittest.cpp @@ -4,7 +4,7 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com -#include "xfa/fde/css/fde_cssstylesheet.h" +#include "xfa/fde/css/cfde_cssstylesheet.h" #include #include @@ -12,8 +12,11 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/base/ptr_util.h" #include "third_party/base/stl_util.h" +#include "xfa/fde/css/cfde_cssdeclaration.h" #include "xfa/fde/css/cfde_cssenumvalue.h" #include "xfa/fde/css/cfde_cssnumbervalue.h" +#include "xfa/fde/css/cfde_cssrule.h" +#include "xfa/fde/css/cfde_cssstylerule.h" #include "xfa/fde/css/cfde_cssvaluelist.h" class CFDE_CSSStyleSheetTest : public testing::Test { diff --git a/xfa/fde/css/cfde_csssyntaxparser.cpp b/xfa/fde/css/cfde_csssyntaxparser.cpp new file mode 100644 index 0000000000..a24b4eee66 --- /dev/null +++ b/xfa/fde/css/cfde_csssyntaxparser.cpp @@ -0,0 +1,380 @@ +// 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 "xfa/fde/css/cfde_csssyntaxparser.h" + +#include + +#include "xfa/fde/css/cfde_cssdeclaration.h" +#include "xfa/fde/css/fde_cssdatatable.h" +#include "xfa/fgas/crt/fgas_codepage.h" + +namespace { + +bool IsSelectorStart(FX_WCHAR wch) { + return wch == '.' || wch == '#' || wch == '*' || (wch >= 'a' && wch <= 'z') || + (wch >= 'A' && wch <= 'Z'); +} + +bool ParseCSSURI(const FX_WCHAR* pszValue, int32_t* iOffset, int32_t* iLength) { + ASSERT(pszValue && *iLength > 0); + if (*iLength < 6 || pszValue[*iLength - 1] != ')' || + FXSYS_wcsnicmp(L"url(", pszValue, 4)) { + return false; + } + if (CFDE_CSSDeclaration::ParseCSSString(pszValue + 4, *iLength - 5, iOffset, + iLength)) { + *iOffset += 4; + return true; + } + return false; +} + +} // namespace + +CFDE_CSSSyntaxParser::CFDE_CSSSyntaxParser() + : m_iTextDatLen(0), + m_dwCheck((uint32_t)-1), + m_eMode(FDE_CSSSyntaxMode::RuleSet), + m_eStatus(FDE_CSSSyntaxStatus::None) {} + +CFDE_CSSSyntaxParser::~CFDE_CSSSyntaxParser() { + m_TextData.Reset(); + m_TextPlane.Reset(); +} + +bool CFDE_CSSSyntaxParser::Init(const FX_WCHAR* pBuffer, + int32_t iBufferSize, + int32_t iTextDatSize, + bool bOnlyDeclaration) { + ASSERT(pBuffer && iBufferSize > 0 && iTextDatSize > 0); + Reset(bOnlyDeclaration); + if (!m_TextData.EstimateSize(iTextDatSize)) + return false; + return m_TextPlane.AttachBuffer(pBuffer, iBufferSize); +} + +void CFDE_CSSSyntaxParser::Reset(bool bOnlyDeclaration) { + m_TextPlane.Reset(); + m_TextData.Reset(); + m_iTextDatLen = 0; + m_dwCheck = (uint32_t)-1; + m_eStatus = FDE_CSSSyntaxStatus::None; + m_eMode = bOnlyDeclaration ? FDE_CSSSyntaxMode::PropertyName + : FDE_CSSSyntaxMode::RuleSet; +} + +FDE_CSSSyntaxStatus CFDE_CSSSyntaxParser::DoSyntaxParse() { + while (m_eStatus >= FDE_CSSSyntaxStatus::None) { + if (m_TextPlane.IsEOF()) { + if (m_eMode == FDE_CSSSyntaxMode::PropertyValue && + m_TextData.GetLength() > 0) { + SaveTextData(); + m_eStatus = FDE_CSSSyntaxStatus::PropertyValue; + return m_eStatus; + } + m_eStatus = FDE_CSSSyntaxStatus::EOS; + return m_eStatus; + } + FX_WCHAR wch; + while (!m_TextPlane.IsEOF()) { + wch = m_TextPlane.GetChar(); + switch (m_eMode) { + case FDE_CSSSyntaxMode::RuleSet: + switch (wch) { + case '@': + m_TextPlane.MoveNext(); + SwitchMode(FDE_CSSSyntaxMode::AtRule); + break; + case '}': + m_TextPlane.MoveNext(); + if (RestoreMode()) + return FDE_CSSSyntaxStatus::DeclClose; + + m_eStatus = FDE_CSSSyntaxStatus::Error; + return m_eStatus; + case '/': + if (m_TextPlane.GetNextChar() == '*') { + m_ModeStack.push(m_eMode); + SwitchMode(FDE_CSSSyntaxMode::Comment); + break; + } + default: + if (wch <= ' ') { + m_TextPlane.MoveNext(); + } else if (IsSelectorStart(wch)) { + SwitchMode(FDE_CSSSyntaxMode::Selector); + return FDE_CSSSyntaxStatus::StyleRule; + } else { + m_eStatus = FDE_CSSSyntaxStatus::Error; + return m_eStatus; + } + break; + } + break; + case FDE_CSSSyntaxMode::Selector: + switch (wch) { + case ',': + m_TextPlane.MoveNext(); + SwitchMode(FDE_CSSSyntaxMode::Selector); + if (m_iTextDatLen > 0) + return FDE_CSSSyntaxStatus::Selector; + break; + case '{': + if (m_TextData.GetLength() > 0) { + SaveTextData(); + return FDE_CSSSyntaxStatus::Selector; + } + m_TextPlane.MoveNext(); + m_ModeStack.push(FDE_CSSSyntaxMode::RuleSet); + SwitchMode(FDE_CSSSyntaxMode::PropertyName); + return FDE_CSSSyntaxStatus::DeclOpen; + case '/': + if (m_TextPlane.GetNextChar() == '*') { + if (SwitchToComment() > 0) + return FDE_CSSSyntaxStatus::Selector; + break; + } + default: + AppendChar(wch); + break; + } + break; + case FDE_CSSSyntaxMode::PropertyName: + switch (wch) { + case ':': + m_TextPlane.MoveNext(); + SwitchMode(FDE_CSSSyntaxMode::PropertyValue); + return FDE_CSSSyntaxStatus::PropertyName; + case '}': + m_TextPlane.MoveNext(); + if (RestoreMode()) + return FDE_CSSSyntaxStatus::DeclClose; + + m_eStatus = FDE_CSSSyntaxStatus::Error; + return m_eStatus; + case '/': + if (m_TextPlane.GetNextChar() == '*') { + if (SwitchToComment() > 0) + return FDE_CSSSyntaxStatus::PropertyName; + break; + } + default: + AppendChar(wch); + break; + } + break; + case FDE_CSSSyntaxMode::PropertyValue: + switch (wch) { + case ';': + m_TextPlane.MoveNext(); + case '}': + SwitchMode(FDE_CSSSyntaxMode::PropertyName); + return FDE_CSSSyntaxStatus::PropertyValue; + case '/': + if (m_TextPlane.GetNextChar() == '*') { + if (SwitchToComment() > 0) + return FDE_CSSSyntaxStatus::PropertyValue; + break; + } + default: + AppendChar(wch); + break; + } + break; + case FDE_CSSSyntaxMode::Comment: + if (wch == '/' && m_TextData.GetLength() > 0 && + m_TextData.GetAt(m_TextData.GetLength() - 1) == '*') { + RestoreMode(); + } else { + m_TextData.AppendChar(wch); + } + m_TextPlane.MoveNext(); + break; + case FDE_CSSSyntaxMode::MediaType: + switch (wch) { + case ',': + m_TextPlane.MoveNext(); + SwitchMode(FDE_CSSSyntaxMode::MediaType); + if (m_iTextDatLen > 0) + return FDE_CSSSyntaxStatus::MediaType; + break; + case '{': { + if (m_ModeStack.empty() || + m_ModeStack.top() != FDE_CSSSyntaxMode::MediaRule) { + m_eStatus = FDE_CSSSyntaxStatus::Error; + return m_eStatus; + } + + if (m_TextData.GetLength() > 0) { + SaveTextData(); + return FDE_CSSSyntaxStatus::MediaType; + } + m_TextPlane.MoveNext(); + + // Replace the MediaRule with a RuleSet rule. + m_ModeStack.top() = FDE_CSSSyntaxMode::RuleSet; + + SwitchMode(FDE_CSSSyntaxMode::RuleSet); + return FDE_CSSSyntaxStatus::DeclOpen; + } + case ';': { + if (m_ModeStack.empty() || + m_ModeStack.top() != FDE_CSSSyntaxMode::Import) { + m_eStatus = FDE_CSSSyntaxStatus::Error; + return m_eStatus; + } + + if (m_TextData.GetLength() > 0) { + SaveTextData(); + if (IsImportEnabled()) + return FDE_CSSSyntaxStatus::MediaType; + } else { + bool bEnabled = IsImportEnabled(); + m_TextPlane.MoveNext(); + m_ModeStack.pop(); + SwitchMode(FDE_CSSSyntaxMode::RuleSet); + if (bEnabled) { + DisableImport(); + return FDE_CSSSyntaxStatus::ImportClose; + } + } + } break; + case '/': + if (m_TextPlane.GetNextChar() == '*') { + if (SwitchToComment() > 0) + return FDE_CSSSyntaxStatus::MediaType; + break; + } + default: + AppendChar(wch); + break; + } + break; + case FDE_CSSSyntaxMode::URI: { + if (m_ModeStack.empty() || + m_ModeStack.top() != FDE_CSSSyntaxMode::Import) { + m_eStatus = FDE_CSSSyntaxStatus::Error; + return m_eStatus; + } + + if (wch <= ' ' || wch == ';') { + int32_t iURIStart, iURILength = m_TextData.GetLength(); + if (iURILength > 0 && + ParseCSSURI(m_TextData.GetBuffer(), &iURIStart, &iURILength)) { + m_TextData.Subtract(iURIStart, iURILength); + SwitchMode(FDE_CSSSyntaxMode::MediaType); + if (IsImportEnabled()) + return FDE_CSSSyntaxStatus::URI; + break; + } + } + AppendChar(wch); + } break; + case FDE_CSSSyntaxMode::AtRule: + if (wch > ' ') { + AppendChar(wch); + } else { + int32_t iLen = m_TextData.GetLength(); + const FX_WCHAR* psz = m_TextData.GetBuffer(); + if (FXSYS_wcsncmp(L"charset", psz, iLen) == 0) { + SwitchMode(FDE_CSSSyntaxMode::Charset); + } else if (FXSYS_wcsncmp(L"import", psz, iLen) == 0) { + m_ModeStack.push(FDE_CSSSyntaxMode::Import); + SwitchMode(FDE_CSSSyntaxMode::URI); + if (IsImportEnabled()) + return FDE_CSSSyntaxStatus::ImportRule; + break; + } else if (FXSYS_wcsncmp(L"media", psz, iLen) == 0) { + m_ModeStack.push(FDE_CSSSyntaxMode::MediaRule); + SwitchMode(FDE_CSSSyntaxMode::MediaType); + return FDE_CSSSyntaxStatus::MediaRule; + } else if (FXSYS_wcsncmp(L"font-face", psz, iLen) == 0) { + SwitchMode(FDE_CSSSyntaxMode::Selector); + return FDE_CSSSyntaxStatus::FontFaceRule; + } else if (FXSYS_wcsncmp(L"page", psz, iLen) == 0) { + SwitchMode(FDE_CSSSyntaxMode::Selector); + return FDE_CSSSyntaxStatus::PageRule; + } else { + SwitchMode(FDE_CSSSyntaxMode::UnknownRule); + } + } + break; + case FDE_CSSSyntaxMode::Charset: + if (wch == ';') { + m_TextPlane.MoveNext(); + SwitchMode(FDE_CSSSyntaxMode::RuleSet); + if (IsCharsetEnabled()) { + DisableCharset(); + if (m_iTextDatLen > 0) + return FDE_CSSSyntaxStatus::Charset; + } + } else { + AppendChar(wch); + } + break; + case FDE_CSSSyntaxMode::UnknownRule: + if (wch == ';') + SwitchMode(FDE_CSSSyntaxMode::RuleSet); + m_TextPlane.MoveNext(); + break; + default: + ASSERT(false); + break; + } + } + } + return m_eStatus; +} + +bool CFDE_CSSSyntaxParser::IsImportEnabled() const { + if ((m_dwCheck & FDE_CSSSYNTAXCHECK_AllowImport) == 0) + return false; + if (m_ModeStack.size() > 1) + return false; + return true; +} + +bool CFDE_CSSSyntaxParser::AppendChar(FX_WCHAR wch) { + m_TextPlane.MoveNext(); + if (m_TextData.GetLength() > 0 || wch > ' ') { + m_TextData.AppendChar(wch); + return true; + } + return false; +} + +int32_t CFDE_CSSSyntaxParser::SaveTextData() { + m_iTextDatLen = m_TextData.TrimEnd(); + m_TextData.Clear(); + return m_iTextDatLen; +} + +void CFDE_CSSSyntaxParser::SwitchMode(FDE_CSSSyntaxMode eMode) { + m_eMode = eMode; + SaveTextData(); +} + +int32_t CFDE_CSSSyntaxParser::SwitchToComment() { + int32_t iLength = m_TextData.GetLength(); + m_ModeStack.push(m_eMode); + SwitchMode(FDE_CSSSyntaxMode::Comment); + return iLength; +} + +bool CFDE_CSSSyntaxParser::RestoreMode() { + if (m_ModeStack.empty()) + return false; + + SwitchMode(m_ModeStack.top()); + m_ModeStack.pop(); + return true; +} + +const FX_WCHAR* CFDE_CSSSyntaxParser::GetCurrentString(int32_t& iLength) const { + iLength = m_iTextDatLen; + return m_TextData.GetBuffer(); +} diff --git a/xfa/fde/css/cfde_csssyntaxparser.h b/xfa/fde/css/cfde_csssyntaxparser.h new file mode 100644 index 0000000000..131fe4bf21 --- /dev/null +++ b/xfa/fde/css/cfde_csssyntaxparser.h @@ -0,0 +1,88 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FDE_CSS_CFDE_CSSSYNTAXPARSER_H_ +#define XFA_FDE_CSS_CFDE_CSSSYNTAXPARSER_H_ + +#include + +#include "xfa/fde/css/cfde_csstextbuf.h" + +#define FDE_CSSSYNTAXCHECK_AllowCharset 1 +#define FDE_CSSSYNTAXCHECK_AllowImport 2 + +enum class FDE_CSSSyntaxMode { + RuleSet, + Comment, + AtRule, + UnknownRule, + Charset, + Import, + MediaRule, + URI, + MediaType, + Selector, + PropertyName, + PropertyValue, +}; + +enum class FDE_CSSSyntaxStatus : uint8_t { + Error, + EOS, + None, + Charset, + ImportRule, + ImportClose, + PageRule, + StyleRule, + FontFaceRule, + MediaRule, + MediaType, + URI, + Selector, + DeclOpen, + DeclClose, + PropertyName, + PropertyValue, +}; + +class CFDE_CSSSyntaxParser { + public: + CFDE_CSSSyntaxParser(); + ~CFDE_CSSSyntaxParser(); + + bool Init(const FX_WCHAR* pBuffer, + int32_t iBufferSize, + int32_t iTextDatSize = 32, + bool bOnlyDeclaration = false); + FDE_CSSSyntaxStatus DoSyntaxParse(); + const FX_WCHAR* GetCurrentString(int32_t& iLength) const; + + protected: + void Reset(bool bOnlyDeclaration); + void SwitchMode(FDE_CSSSyntaxMode eMode); + int32_t SwitchToComment(); + + bool RestoreMode(); + bool AppendChar(FX_WCHAR wch); + int32_t SaveTextData(); + bool IsCharsetEnabled() const { + return (m_dwCheck & FDE_CSSSYNTAXCHECK_AllowCharset) != 0; + } + void DisableCharset() { m_dwCheck = FDE_CSSSYNTAXCHECK_AllowImport; } + bool IsImportEnabled() const; + void DisableImport() { m_dwCheck = 0; } + + CFDE_CSSTextBuf m_TextData; + CFDE_CSSTextBuf m_TextPlane; + int32_t m_iTextDatLen; + uint32_t m_dwCheck; + FDE_CSSSyntaxMode m_eMode; + FDE_CSSSyntaxStatus m_eStatus; + std::stack m_ModeStack; +}; + +#endif // XFA_FDE_CSS_CFDE_CSSSYNTAXPARSER_H_ diff --git a/xfa/fde/css/cfde_csstagcache.cpp b/xfa/fde/css/cfde_csstagcache.cpp new file mode 100644 index 0000000000..13e37982df --- /dev/null +++ b/xfa/fde/css/cfde_csstagcache.cpp @@ -0,0 +1,44 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fde/css/cfde_csstagcache.h" + +#include + +#include "core/fxcrt/fx_ext.h" +#include "xfa/fxfa/app/cxfa_csstagprovider.h" + +CFDE_CSSTagCache::CFDE_CSSTagCache(CFDE_CSSTagCache* parent, + CXFA_CSSTagProvider* tag) + : pTag(tag), pParent(parent), dwIDHash(0), dwTagHash(0), iClassIndex(0) { + static const uint32_t s_dwIDHash = FX_HashCode_GetW(L"id", true); + static const uint32_t s_dwClassHash = FX_HashCode_GetW(L"class", true); + dwTagHash = FX_HashCode_GetW(pTag->GetTagName().AsStringC(), true); + + for (auto it : *pTag) { + CFX_WideString wsValue = it.first; + CFX_WideString wsName = it.second; + uint32_t dwNameHash = FX_HashCode_GetW(wsName.AsStringC(), true); + if (dwNameHash == s_dwClassHash) { + uint32_t dwHash = FX_HashCode_GetW(wsValue.AsStringC(), false); + dwClassHashes.push_back(dwHash); + } else if (dwNameHash == s_dwIDHash) { + dwIDHash = FX_HashCode_GetW(wsValue.AsStringC(), false); + } + } +} + +CFDE_CSSTagCache::CFDE_CSSTagCache(const CFDE_CSSTagCache& it) + : pTag(it.pTag), + pParent(it.pParent), + dwIDHash(it.dwIDHash), + dwTagHash(it.dwTagHash), + iClassIndex(0) { + std::copy(it.dwClassHashes.begin(), it.dwClassHashes.end(), + dwClassHashes.begin()); +} + +CFDE_CSSTagCache::~CFDE_CSSTagCache() {} diff --git a/xfa/fde/css/cfde_csstagcache.h b/xfa/fde/css/cfde_csstagcache.h new file mode 100644 index 0000000000..6d9b4e7054 --- /dev/null +++ b/xfa/fde/css/cfde_csstagcache.h @@ -0,0 +1,46 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FDE_CSS_CFDE_CSSTAGCACHE_H_ +#define XFA_FDE_CSS_CFDE_CSSTAGCACHE_H_ + +#include + +#include "core/fxcrt/fx_system.h" +#include "third_party/base/stl_util.h" + +class CXFA_CSSTagProvider; + +class CFDE_CSSTagCache { + public: + CFDE_CSSTagCache(CFDE_CSSTagCache* parent, CXFA_CSSTagProvider* tag); + CFDE_CSSTagCache(const CFDE_CSSTagCache& it); + ~CFDE_CSSTagCache(); + + CFDE_CSSTagCache* GetParent() const { return pParent; } + CXFA_CSSTagProvider* GetTag() const { return pTag; } + uint32_t HashID() const { return dwIDHash; } + uint32_t HashTag() const { return dwTagHash; } + int32_t CountHashClass() const { + return pdfium::CollectionSize(dwClassHashes); + } + void SetClassIndex(int32_t index) { iClassIndex = index; } + uint32_t HashClass() const { + return iClassIndex < pdfium::CollectionSize(dwClassHashes) + ? dwClassHashes[iClassIndex] + : 0; + } + + private: + CXFA_CSSTagProvider* pTag; + CFDE_CSSTagCache* pParent; + uint32_t dwIDHash; + uint32_t dwTagHash; + int32_t iClassIndex; + std::vector dwClassHashes; +}; + +#endif // XFA_FDE_CSS_CFDE_CSSTAGCACHE_H_ diff --git a/xfa/fde/css/cfde_csstextbuf.cpp b/xfa/fde/css/cfde_csstextbuf.cpp new file mode 100644 index 0000000000..83b2899f19 --- /dev/null +++ b/xfa/fde/css/cfde_csstextbuf.cpp @@ -0,0 +1,86 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fde/css/cfde_csstextbuf.h" + +#include + +CFDE_CSSTextBuf::CFDE_CSSTextBuf() + : m_bExtBuf(false), + m_pBuffer(nullptr), + m_iBufLen(0), + m_iDatLen(0), + m_iDatPos(0) {} + +CFDE_CSSTextBuf::~CFDE_CSSTextBuf() { + Reset(); +} + +void CFDE_CSSTextBuf::Reset() { + if (!m_bExtBuf) { + FX_Free(m_pBuffer); + m_pBuffer = nullptr; + } + m_iDatPos = m_iDatLen = m_iBufLen; +} + +bool CFDE_CSSTextBuf::AttachBuffer(const FX_WCHAR* pBuffer, int32_t iBufLen) { + Reset(); + m_pBuffer = const_cast(pBuffer); + m_iDatLen = m_iBufLen = iBufLen; + return m_bExtBuf = true; +} + +bool CFDE_CSSTextBuf::EstimateSize(int32_t iAllocSize) { + ASSERT(iAllocSize > 0); + Clear(); + m_bExtBuf = false; + return ExpandBuf(iAllocSize); +} + +int32_t CFDE_CSSTextBuf::LoadFromStream( + const CFX_RetainPtr& pTxtStream, + int32_t iStreamOffset, + int32_t iMaxChars, + bool& bEOS) { + ASSERT(iStreamOffset >= 0 && iMaxChars > 0); + Clear(); + m_bExtBuf = false; + if (!ExpandBuf(iMaxChars)) + return 0; + + if (pTxtStream->GetPosition() != iStreamOffset) + pTxtStream->Seek(FX_STREAMSEEK_Begin, iStreamOffset); + + m_iDatLen = pTxtStream->ReadString(m_pBuffer, iMaxChars, bEOS); + return m_iDatLen; +} + +bool CFDE_CSSTextBuf::ExpandBuf(int32_t iDesiredSize) { + if (m_bExtBuf) + return false; + if (!m_pBuffer) + m_pBuffer = FX_Alloc(FX_WCHAR, iDesiredSize); + else if (m_iBufLen != iDesiredSize) + m_pBuffer = FX_Realloc(FX_WCHAR, m_pBuffer, iDesiredSize); + else + return true; + + if (!m_pBuffer) { + m_iBufLen = 0; + return false; + } + m_iBufLen = iDesiredSize; + return true; +} + +void CFDE_CSSTextBuf::Subtract(int32_t iStart, int32_t iLength) { + ASSERT(iStart >= 0 && iLength >= 0); + + iLength = std::max(std::min(iLength, m_iDatLen - iStart), 0); + FXSYS_memmove(m_pBuffer, m_pBuffer + iStart, iLength * sizeof(FX_WCHAR)); + m_iDatLen = iLength; +} diff --git a/xfa/fde/css/cfde_csstextbuf.h b/xfa/fde/css/cfde_csstextbuf.h new file mode 100644 index 0000000000..df151e02d8 --- /dev/null +++ b/xfa/fde/css/cfde_csstextbuf.h @@ -0,0 +1,66 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FDE_CSS_CFDE_CSSTEXTBUF_H_ +#define XFA_FDE_CSS_CFDE_CSSTEXTBUF_H_ + +#include "core/fxcrt/cfx_retain_ptr.h" +#include "core/fxcrt/fx_memory.h" +#include "core/fxcrt/fx_system.h" +#include "xfa/fgas/crt/fgas_stream.h" + +class CFDE_CSSTextBuf { + public: + CFDE_CSSTextBuf(); + ~CFDE_CSSTextBuf(); + + bool AttachBuffer(const FX_WCHAR* pBuffer, int32_t iBufLen); + bool EstimateSize(int32_t iAllocSize); + int32_t LoadFromStream(const CFX_RetainPtr& pTxtStream, + int32_t iStreamOffset, + int32_t iMaxChars, + bool& bEOS); + bool AppendChar(FX_WCHAR wch) { + if (m_iDatLen >= m_iBufLen && !ExpandBuf(m_iBufLen * 2)) + return false; + m_pBuffer[m_iDatLen++] = wch; + return true; + } + + void Clear() { m_iDatPos = m_iDatLen = 0; } + void Reset(); + + int32_t TrimEnd() { + while (m_iDatLen > 0 && m_pBuffer[m_iDatLen - 1] <= ' ') + --m_iDatLen; + AppendChar(0); + return --m_iDatLen; + } + + void Subtract(int32_t iStart, int32_t iLength); + bool IsEOF() const { return m_iDatPos >= m_iDatLen; } + + FX_WCHAR GetAt(int32_t index) const { return m_pBuffer[index]; } + FX_WCHAR GetChar() const { return m_pBuffer[m_iDatPos]; } + FX_WCHAR GetNextChar() const { + return (m_iDatPos + 1 >= m_iDatLen) ? 0 : m_pBuffer[m_iDatPos + 1]; + } + + void MoveNext() { m_iDatPos++; } + + int32_t GetLength() const { return m_iDatLen; } + const FX_WCHAR* GetBuffer() const { return m_pBuffer; } + + protected: + bool ExpandBuf(int32_t iDesiredSize); + bool m_bExtBuf; + FX_WCHAR* m_pBuffer; + int32_t m_iBufLen; + int32_t m_iDatLen; + int32_t m_iDatPos; +}; + +#endif // XFA_FDE_CSS_CFDE_CSSTEXTBUF_H_ diff --git a/xfa/fde/css/fde_css.h b/xfa/fde/css/fde_css.h index f9bd7673ad..2194657670 100644 --- a/xfa/fde/css/fde_css.h +++ b/xfa/fde/css/fde_css.h @@ -149,26 +149,6 @@ enum class FDE_CSSSelectorType : uint8_t { enum class FDE_CSSRuleType : uint8_t { Style, Media, FontFace }; -enum class FDE_CSSSyntaxStatus : uint8_t { - Error, - EOS, - None, - Charset, - ImportRule, - ImportClose, - PageRule, - StyleRule, - FontFaceRule, - MediaRule, - MediaType, - URI, - Selector, - DeclOpen, - DeclClose, - PropertyName, - PropertyValue, -}; - enum class FDE_CSSLengthUnit : uint8_t { Auto, None, diff --git a/xfa/fde/css/fde_csscache.cpp b/xfa/fde/css/fde_csscache.cpp deleted file mode 100644 index bf4176b787..0000000000 --- a/xfa/fde/css/fde_csscache.cpp +++ /dev/null @@ -1,66 +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 "xfa/fde/css/fde_csscache.h" - -#include - -#include "core/fxcrt/fx_ext.h" -#include "xfa/fxfa/app/cxfa_csstagprovider.h" - -FDE_CSSTagCache::FDE_CSSTagCache(FDE_CSSTagCache* parent, - CXFA_CSSTagProvider* tag) - : pTag(tag), - pParent(parent), - dwIDHash(0), - dwTagHash(0), - iClassIndex(0), - dwClassHashs(1) { - static const uint32_t s_dwIDHash = FX_HashCode_GetW(L"id", true); - static const uint32_t s_dwClassHash = FX_HashCode_GetW(L"class", true); - dwTagHash = FX_HashCode_GetW(pTag->GetTagName().AsStringC(), true); - - for (auto it : *pTag) { - CFX_WideString wsValue = it.first; - CFX_WideString wsName = it.second; - uint32_t dwNameHash = FX_HashCode_GetW(wsName.AsStringC(), true); - if (dwNameHash == s_dwClassHash) { - uint32_t dwHash = FX_HashCode_GetW(wsValue.AsStringC(), false); - dwClassHashs.Add(dwHash); - } else if (dwNameHash == s_dwIDHash) { - dwIDHash = FX_HashCode_GetW(wsValue.AsStringC(), false); - } - } -} - -FDE_CSSTagCache::FDE_CSSTagCache(const FDE_CSSTagCache& it) - : pTag(it.pTag), - pParent(it.pParent), - dwIDHash(it.dwIDHash), - dwTagHash(it.dwTagHash), - iClassIndex(0), - dwClassHashs(1) { - if (it.dwClassHashs.GetSize() > 0) - dwClassHashs.Copy(it.dwClassHashs, 0, -1); -} - -FDE_CSSTagCache::~FDE_CSSTagCache() {} - -CFDE_CSSAccelerator::CFDE_CSSAccelerator() : m_Stack(100) {} - -CFDE_CSSAccelerator::~CFDE_CSSAccelerator() {} - -void CFDE_CSSAccelerator::OnEnterTag(CXFA_CSSTagProvider* pTag) { - FDE_CSSTagCache* pTop = GetTopElement(); - FDE_CSSTagCache item(pTop, pTag); - m_Stack.Push(item); -} - -void CFDE_CSSAccelerator::OnLeaveTag(CXFA_CSSTagProvider* pTag) { - ASSERT(m_Stack.GetTopElement()); - ASSERT(m_Stack.GetTopElement()->GetTag() == pTag); - m_Stack.Pop(); -} diff --git a/xfa/fde/css/fde_csscache.h b/xfa/fde/css/fde_csscache.h deleted file mode 100644 index fd46880c1f..0000000000 --- a/xfa/fde/css/fde_csscache.h +++ /dev/null @@ -1,59 +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 XFA_FDE_CSS_FDE_CSSCACHE_H_ -#define XFA_FDE_CSS_FDE_CSSCACHE_H_ - -#include - -#include "xfa/fde/css/fde_css.h" - -class CXFA_CSSTagProvider; - -class FDE_CSSTagCache { - public: - FDE_CSSTagCache(FDE_CSSTagCache* parent, CXFA_CSSTagProvider* tag); - FDE_CSSTagCache(const FDE_CSSTagCache& it); - ~FDE_CSSTagCache(); - - FDE_CSSTagCache* GetParent() const { return pParent; } - CXFA_CSSTagProvider* GetTag() const { return pTag; } - uint32_t HashID() const { return dwIDHash; } - uint32_t HashTag() const { return dwTagHash; } - int32_t CountHashClass() const { return dwClassHashs.GetSize(); } - void SetClassIndex(int32_t index) { iClassIndex = index; } - uint32_t HashClass() const { - return iClassIndex < dwClassHashs.GetSize() - ? dwClassHashs.GetAt(iClassIndex) - : 0; - } - - private: - CXFA_CSSTagProvider* pTag; - FDE_CSSTagCache* pParent; - uint32_t dwIDHash; - uint32_t dwTagHash; - int32_t iClassIndex; - CFX_BaseArrayTemplate dwClassHashs; -}; - -class CFDE_CSSAccelerator { - public: - CFDE_CSSAccelerator(); - ~CFDE_CSSAccelerator(); - - void OnEnterTag(CXFA_CSSTagProvider* pTag); - void OnLeaveTag(CXFA_CSSTagProvider* pTag); - - void Clear() { m_Stack.RemoveAll(false); } - - FDE_CSSTagCache* GetTopElement() const { return m_Stack.GetTopElement(); } - - private: - CFX_ObjectStackTemplate m_Stack; -}; - -#endif // XFA_FDE_CSS_FDE_CSSCACHE_H_ diff --git a/xfa/fde/css/fde_cssdatatable.cpp b/xfa/fde/css/fde_cssdatatable.cpp index d645e2e508..fd4ef6bffb 100644 --- a/xfa/fde/css/fde_cssdatatable.cpp +++ b/xfa/fde/css/fde_cssdatatable.cpp @@ -9,104 +9,10 @@ #include #include "core/fxcrt/fx_ext.h" +#include "xfa/fde/css/cfde_cssstyleselector.h" #include "xfa/fde/css/cfde_cssvaluelistparser.h" -#include "xfa/fde/css/fde_cssstyleselector.h" #include "xfa/fgas/crt/fgas_codepage.h" -namespace { - -uint8_t Hex2Dec(uint8_t hexHigh, uint8_t hexLow) { - return (FXSYS_toHexDigit(hexHigh) << 4) + FXSYS_toHexDigit(hexLow); -} - -} // namespace - -bool FDE_CSSLengthToFloat(const FDE_CSSLength& len, - FX_FLOAT fPercentBase, - FX_FLOAT& fResult) { - switch (len.GetUnit()) { - case FDE_CSSLengthUnit::Point: - fResult = len.GetValue(); - return true; - case FDE_CSSLengthUnit::Percent: - fResult = len.GetValue() * fPercentBase; - return true; - default: - return false; - } -} -CFX_FloatRect FDE_CSSBoundaryToRect(CFDE_CSSComputedStyle* pBoundStyle, - FX_FLOAT fContainerWidth, - bool bPadding, - bool bBorder, - bool bMargin) { - FX_FLOAT fResult; - const FDE_CSSRect* pRect; - CFX_FloatRect rect(0, 0, 0, 0); - if (bPadding) { - pRect = pBoundStyle->GetPaddingWidth(); - if (pRect) { - if (FDE_CSSLengthToFloat(pRect->left, fContainerWidth, fResult)) { - rect.left += fResult; - } - if (FDE_CSSLengthToFloat(pRect->top, fContainerWidth, fResult)) { - rect.top += fResult; - } - if (FDE_CSSLengthToFloat(pRect->right, fContainerWidth, fResult)) { - rect.right += fResult; - } - if (FDE_CSSLengthToFloat(pRect->bottom, fContainerWidth, fResult)) { - rect.bottom += fResult; - } - } - } - if (bBorder) { - pRect = pBoundStyle->GetBorderWidth(); - if (pRect) { - if (FDE_CSSLengthToFloat(pRect->left, fContainerWidth, fResult)) { - rect.left += fResult; - } - if (FDE_CSSLengthToFloat(pRect->top, fContainerWidth, fResult)) { - rect.top += fResult; - } - if (FDE_CSSLengthToFloat(pRect->right, fContainerWidth, fResult)) { - rect.right += fResult; - } - if (FDE_CSSLengthToFloat(pRect->bottom, fContainerWidth, fResult)) { - rect.bottom += fResult; - } - } - } - if (bMargin) { - pRect = pBoundStyle->GetMarginWidth(); - if (pRect) { - if (FDE_CSSLengthToFloat(pRect->left, fContainerWidth, fResult)) { - rect.left += fResult; - } - if (FDE_CSSLengthToFloat(pRect->top, fContainerWidth, fResult)) { - rect.top += fResult; - } - if (FDE_CSSLengthToFloat(pRect->right, fContainerWidth, fResult)) { - rect.right += fResult; - } - if (FDE_CSSLengthToFloat(pRect->bottom, fContainerWidth, fResult)) { - rect.bottom += fResult; - } - } - } - return rect; -} -uint32_t FDE_CSSFontStyleToFDE(CFDE_CSSComputedStyle* pFontStyle) { - uint32_t dwFontStyle = FX_FONTSTYLE_Normal; - if (pFontStyle->GetFontStyle() == FDE_CSSFontStyle::Italic) { - dwFontStyle |= FX_FONTSTYLE_Italic; - } - if (pFontStyle->GetFontWeight() >= 700) { - dwFontStyle |= FX_FONTSTYLE_Bold; - } - return dwFontStyle; -} - static const FDE_CSSPropertyTable g_FDE_CSSProperties[] = { {FDE_CSSProperty::BorderLeft, L"border-left", 0x04080036, FDE_CSSVALUETYPE_Shorthand}, @@ -353,11 +259,6 @@ const FDE_CSSPropertyValueTable* FDE_GetCSSPropertyValueByName( return nullptr; } -const FDE_CSSPropertyValueTable* FDE_GetCSSPropertyValueByEnum( - FDE_CSSPropertyValue eName) { - return g_FDE_CSSPropertyValues + static_cast(eName); -} - const FDE_CSSMEDIATYPETABLE* FDE_GetCSSMediaTypeByName( const CFX_WideStringC& wsName) { ASSERT(!wsName.IsEmpty()); @@ -421,120 +322,3 @@ const FDE_CSSCOLORTABLE* FDE_GetCSSColorByName(const CFX_WideStringC& wsName) { } while (iStart <= iEnd); return nullptr; } - -bool FDE_ParseCSSNumber(const FX_WCHAR* pszValue, - int32_t iValueLen, - FX_FLOAT& fValue, - FDE_CSSNumberType& eUnit) { - ASSERT(pszValue && iValueLen > 0); - int32_t iUsedLen = 0; - fValue = FXSYS_wcstof(pszValue, iValueLen, &iUsedLen); - if (iUsedLen <= 0) - return false; - - iValueLen -= iUsedLen; - pszValue += iUsedLen; - eUnit = FDE_CSSNumberType::Number; - if (iValueLen >= 1 && *pszValue == '%') { - eUnit = FDE_CSSNumberType::Percent; - } else if (iValueLen == 2) { - const FDE_CSSLengthUnitTable* pUnit = - FDE_GetCSSLengthUnitByName(CFX_WideStringC(pszValue, 2)); - if (pUnit) - eUnit = pUnit->wValue; - } - return true; -} - -bool FDE_ParseCSSString(const FX_WCHAR* pszValue, - int32_t iValueLen, - int32_t* iOffset, - int32_t* iLength) { - ASSERT(pszValue && iValueLen > 0); - *iOffset = 0; - *iLength = iValueLen; - if (iValueLen >= 2) { - FX_WCHAR first = pszValue[0], last = pszValue[iValueLen - 1]; - if ((first == '\"' && last == '\"') || (first == '\'' && last == '\'')) { - *iOffset = 1; - *iLength -= 2; - } - } - return iValueLen > 0; -} - -bool FDE_ParseCSSURI(const FX_WCHAR* pszValue, - int32_t* iOffset, - int32_t* iLength) { - ASSERT(pszValue && *iLength > 0); - if (*iLength < 6 || pszValue[*iLength - 1] != ')' || - FXSYS_wcsnicmp(L"url(", pszValue, 4)) { - return false; - } - if (FDE_ParseCSSString(pszValue + 4, *iLength - 5, iOffset, iLength)) { - *iOffset += 4; - return true; - } - return false; -} - -bool FDE_ParseCSSColor(const FX_WCHAR* pszValue, - int32_t iValueLen, - FX_ARGB& dwColor) { - ASSERT(pszValue && iValueLen > 0); - - if (*pszValue == '#') { - switch (iValueLen) { - case 4: { - uint8_t red = Hex2Dec((uint8_t)pszValue[1], (uint8_t)pszValue[1]); - uint8_t green = Hex2Dec((uint8_t)pszValue[2], (uint8_t)pszValue[2]); - uint8_t blue = Hex2Dec((uint8_t)pszValue[3], (uint8_t)pszValue[3]); - dwColor = ArgbEncode(255, red, green, blue); - return true; - } - case 7: { - uint8_t red = Hex2Dec((uint8_t)pszValue[1], (uint8_t)pszValue[2]); - uint8_t green = Hex2Dec((uint8_t)pszValue[3], (uint8_t)pszValue[4]); - uint8_t blue = Hex2Dec((uint8_t)pszValue[5], (uint8_t)pszValue[6]); - dwColor = ArgbEncode(255, red, green, blue); - return true; - } - default: - return false; - } - } - - if (iValueLen >= 10) { - if (pszValue[iValueLen - 1] != ')' || FXSYS_wcsnicmp(L"rgb(", pszValue, 4)) - return false; - - uint8_t rgb[3] = {0}; - FX_FLOAT fValue; - FDE_CSSPrimitiveType eType; - CFDE_CSSValueListParser list(pszValue + 4, iValueLen - 5, ','); - for (int32_t i = 0; i < 3; ++i) { - if (!list.NextValue(eType, pszValue, iValueLen)) - return false; - if (eType != FDE_CSSPrimitiveType::Number) - return false; - FDE_CSSNumberType eNumType; - if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eNumType)) - return false; - - rgb[i] = eNumType == FDE_CSSNumberType::Percent - ? FXSYS_round(fValue * 2.55f) - : FXSYS_round(fValue); - } - dwColor = ArgbEncode(255, rgb[0], rgb[1], rgb[2]); - return true; - } - - const FDE_CSSCOLORTABLE* pColor = - FDE_GetCSSColorByName(CFX_WideStringC(pszValue, iValueLen)); - if (!pColor) - return false; - - dwColor = pColor->dwValue; - return true; -} - diff --git a/xfa/fde/css/fde_cssdatatable.h b/xfa/fde/css/fde_cssdatatable.h index f2cc2b45d4..4769f16658 100644 --- a/xfa/fde/css/fde_cssdatatable.h +++ b/xfa/fde/css/fde_cssdatatable.h @@ -25,65 +25,48 @@ struct FDE_CSSPropertyTable { uint32_t dwType; }; -const FDE_CSSPropertyTable* FDE_GetCSSPropertyByName( - const CFX_WideStringC& wsName); -const FDE_CSSPropertyTable* FDE_GetCSSPropertyByEnum(FDE_CSSProperty eName); - struct FDE_CSSPropertyValueTable { FDE_CSSPropertyValue eName; const FX_WCHAR* pszName; uint32_t dwHash; }; -const FDE_CSSPropertyValueTable* FDE_GetCSSPropertyValueByName( - const CFX_WideStringC& wsName); -const FDE_CSSPropertyValueTable* FDE_GetCSSPropertyValueByEnum( - FDE_CSSPropertyValue eName); - struct FDE_CSSMEDIATYPETABLE { uint16_t wHash; uint16_t wValue; }; -const FDE_CSSMEDIATYPETABLE* FDE_GetCSSMediaTypeByName( - const CFX_WideStringC& wsName); - struct FDE_CSSLengthUnitTable { uint16_t wHash; FDE_CSSNumberType wValue; }; -const FDE_CSSLengthUnitTable* FDE_GetCSSLengthUnitByName( - const CFX_WideStringC& wsName); - struct FDE_CSSCOLORTABLE { uint32_t dwHash; FX_ARGB dwValue; }; -const FDE_CSSCOLORTABLE* FDE_GetCSSColorByName(const CFX_WideStringC& wsName); - struct FDE_CSSPseudoTable { FDE_CSSPseudo eName; const FX_WCHAR* pszName; uint32_t dwHash; }; -const FDE_CSSPseudoTable* FDE_GetCSSPseudoByEnum(FDE_CSSPseudo ePseudo); +const FDE_CSSPropertyTable* FDE_GetCSSPropertyByName( + const CFX_WideStringC& wsName); +const FDE_CSSPropertyTable* FDE_GetCSSPropertyByEnum(FDE_CSSProperty eName); + +const FDE_CSSPropertyValueTable* FDE_GetCSSPropertyValueByName( + const CFX_WideStringC& wsName); -bool FDE_ParseCSSNumber(const FX_WCHAR* pszValue, - int32_t iValueLen, - FX_FLOAT& fValue, - FDE_CSSNumberType& eUnit); -bool FDE_ParseCSSString(const FX_WCHAR* pszValue, - int32_t iValueLen, - int32_t* iOffset, - int32_t* iLength); -bool FDE_ParseCSSColor(const FX_WCHAR* pszValue, - int32_t iValueLen, - FX_ARGB& dwColor); -bool FDE_ParseCSSURI(const FX_WCHAR* pszValue, - int32_t* iOffset, - int32_t* iLength); +const FDE_CSSMEDIATYPETABLE* FDE_GetCSSMediaTypeByName( + const CFX_WideStringC& wsName); + +const FDE_CSSLengthUnitTable* FDE_GetCSSLengthUnitByName( + const CFX_WideStringC& wsName); + +const FDE_CSSCOLORTABLE* FDE_GetCSSColorByName(const CFX_WideStringC& wsName); + +const FDE_CSSPseudoTable* FDE_GetCSSPseudoByEnum(FDE_CSSPseudo ePseudo); #endif // XFA_FDE_CSS_FDE_CSSDATATABLE_H_ diff --git a/xfa/fde/css/fde_cssdatatable_unittest.cpp b/xfa/fde/css/fde_cssdatatable_unittest.cpp deleted file mode 100644 index d602bff046..0000000000 --- a/xfa/fde/css/fde_cssdatatable_unittest.cpp +++ /dev/null @@ -1,60 +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 "xfa/fde/css/fde_cssdatatable.h" - -#include "testing/gtest/include/gtest/gtest.h" - -TEST(FDE_ParseCSSColor, HexEncodingParsing) { - FX_ARGB color; - - // Length value invalid. - EXPECT_FALSE(FDE_ParseCSSColor(L"#000", 3, color)); - EXPECT_FALSE(FDE_ParseCSSColor(L"#000000", 5, color)); - EXPECT_FALSE(FDE_ParseCSSColor(L"#000000", 8, color)); - - // Invalid characters - EXPECT_TRUE(FDE_ParseCSSColor(L"#zxytlm", 7, color)); - EXPECT_EQ(0, FXARGB_R(color)); - EXPECT_EQ(0, FXARGB_G(color)); - EXPECT_EQ(0, FXARGB_B(color)); - - EXPECT_TRUE(FDE_ParseCSSColor(L"#000", 4, color)); - EXPECT_EQ(0, FXARGB_R(color)); - EXPECT_EQ(0, FXARGB_G(color)); - EXPECT_EQ(0, FXARGB_B(color)); - - EXPECT_TRUE(FDE_ParseCSSColor(L"#FFF", 4, color)); - EXPECT_EQ(255, FXARGB_R(color)); - EXPECT_EQ(255, FXARGB_G(color)); - EXPECT_EQ(255, FXARGB_B(color)); - - EXPECT_TRUE(FDE_ParseCSSColor(L"#F0F0F0", 7, color)); - EXPECT_EQ(240, FXARGB_R(color)); - EXPECT_EQ(240, FXARGB_G(color)); - EXPECT_EQ(240, FXARGB_B(color)); - - // Upper and lower case characters. - EXPECT_TRUE(FDE_ParseCSSColor(L"#1b2F3c", 7, color)); - EXPECT_EQ(27, FXARGB_R(color)); - EXPECT_EQ(47, FXARGB_G(color)); - EXPECT_EQ(60, FXARGB_B(color)); -} - -TEST(FDE_ParseCSSColor, RGBEncodingParsing) { - FX_ARGB color; - - // Invalid input for rgb() syntax. - EXPECT_FALSE(FDE_ParseCSSColor(L"blahblahblah", 11, color)); - - EXPECT_TRUE(FDE_ParseCSSColor(L"rgb(0, 0, 0)", 12, color)); - EXPECT_EQ(0, FXARGB_R(color)); - EXPECT_EQ(0, FXARGB_G(color)); - EXPECT_EQ(0, FXARGB_B(color)); - - EXPECT_TRUE(FDE_ParseCSSColor(L"rgb(128,255,48)", 15, color)); - EXPECT_EQ(128, FXARGB_R(color)); - EXPECT_EQ(255, FXARGB_G(color)); - EXPECT_EQ(48, FXARGB_B(color)); -} diff --git a/xfa/fde/css/fde_cssdeclaration.cpp b/xfa/fde/css/fde_cssdeclaration.cpp deleted file mode 100644 index e82b279c04..0000000000 --- a/xfa/fde/css/fde_cssdeclaration.cpp +++ /dev/null @@ -1,552 +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 "xfa/fde/css/fde_cssdeclaration.h" - -#include "core/fxcrt/fx_ext.h" -#include "third_party/base/ptr_util.h" -#include "xfa/fde/css/cfde_csscolorvalue.h" -#include "xfa/fde/css/cfde_cssenumvalue.h" -#include "xfa/fde/css/cfde_cssnumbervalue.h" -#include "xfa/fde/css/cfde_cssstringvalue.h" -#include "xfa/fde/css/cfde_cssvaluelist.h" -#include "xfa/fde/css/cfde_cssvaluelistparser.h" - -CFDE_CSSDeclaration::CFDE_CSSDeclaration() {} - -CFDE_CSSDeclaration::~CFDE_CSSDeclaration() {} - -CFDE_CSSValue* CFDE_CSSDeclaration::GetProperty(FDE_CSSProperty eProperty, - bool& bImportant) const { - for (const auto& p : properties_) { - if (p->eProperty == eProperty) { - bImportant = p->bImportant; - return p->pValue.Get(); - } - } - return nullptr; -} - -const FX_WCHAR* CFDE_CSSDeclaration::CopyToLocal( - const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen) { - ASSERT(iValueLen > 0); - std::unordered_map* pCache = pArgs->pStringCache; - uint32_t key = 0; - if (pCache) { - key = FX_HashCode_GetW(CFX_WideStringC(pszValue, iValueLen), false); - auto it = pCache->find(key); - if (it != pCache->end()) - return it->second; - } - FX_WCHAR* psz = FX_Alloc(FX_WCHAR, iValueLen + 1); - FXSYS_wcsncpy(psz, pszValue, iValueLen); - psz[iValueLen] = '\0'; - if (pCache) - (*pCache)[key] = psz; - - return psz; -} - -void CFDE_CSSDeclaration::AddPropertyHolder(FDE_CSSProperty eProperty, - CFX_RetainPtr pValue, - bool bImportant) { - auto pHolder = pdfium::MakeUnique(); - pHolder->bImportant = bImportant; - pHolder->eProperty = eProperty; - pHolder->pValue = pValue; - properties_.push_back(std::move(pHolder)); -} - -void CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen) { - ASSERT(iValueLen > 0); - bool bImportant = false; - if (iValueLen >= 10 && pszValue[iValueLen - 10] == '!' && - FXSYS_wcsnicmp(L"important", pszValue + iValueLen - 9, 9) == 0) { - if ((iValueLen -= 10) == 0) - return; - - bImportant = true; - } - const uint32_t dwType = pArgs->pProperty->dwType; - switch (dwType & 0x0F) { - case FDE_CSSVALUETYPE_Primitive: { - static const uint32_t g_ValueGuessOrder[] = { - FDE_CSSVALUETYPE_MaybeNumber, FDE_CSSVALUETYPE_MaybeEnum, - FDE_CSSVALUETYPE_MaybeColor, FDE_CSSVALUETYPE_MaybeString, - }; - static const int32_t g_ValueGuessCount = - sizeof(g_ValueGuessOrder) / sizeof(uint32_t); - for (int32_t i = 0; i < g_ValueGuessCount; ++i) { - const uint32_t dwMatch = dwType & g_ValueGuessOrder[i]; - if (dwMatch == 0) { - continue; - } - CFX_RetainPtr pCSSValue; - switch (dwMatch) { - case FDE_CSSVALUETYPE_MaybeNumber: - pCSSValue = ParseNumber(pArgs, pszValue, iValueLen); - break; - case FDE_CSSVALUETYPE_MaybeEnum: - pCSSValue = ParseEnum(pArgs, pszValue, iValueLen); - break; - case FDE_CSSVALUETYPE_MaybeColor: - pCSSValue = ParseColor(pArgs, pszValue, iValueLen); - break; - case FDE_CSSVALUETYPE_MaybeString: - pCSSValue = ParseString(pArgs, pszValue, iValueLen); - break; - default: - break; - } - if (pCSSValue) { - AddPropertyHolder(pArgs->pProperty->eName, pCSSValue, bImportant); - return; - } - if (FDE_IsOnlyValue(dwType, g_ValueGuessOrder[i])) - return; - } - break; - } - case FDE_CSSVALUETYPE_Shorthand: { - CFX_RetainPtr pWidth; - switch (pArgs->pProperty->eName) { - case FDE_CSSProperty::Font: - ParseFontProperty(pArgs, pszValue, iValueLen, bImportant); - return; - case FDE_CSSProperty::Border: - if (ParseBorderProperty(pszValue, iValueLen, pWidth)) { - AddPropertyHolder(FDE_CSSProperty::BorderLeftWidth, pWidth, - bImportant); - AddPropertyHolder(FDE_CSSProperty::BorderTopWidth, pWidth, - bImportant); - AddPropertyHolder(FDE_CSSProperty::BorderRightWidth, pWidth, - bImportant); - AddPropertyHolder(FDE_CSSProperty::BorderBottomWidth, pWidth, - bImportant); - return; - } - break; - case FDE_CSSProperty::BorderLeft: - if (ParseBorderProperty(pszValue, iValueLen, pWidth)) { - AddPropertyHolder(FDE_CSSProperty::BorderLeftWidth, pWidth, - bImportant); - return; - } - break; - case FDE_CSSProperty::BorderTop: - if (ParseBorderProperty(pszValue, iValueLen, pWidth)) { - AddPropertyHolder(FDE_CSSProperty::BorderTopWidth, pWidth, - bImportant); - return; - } - break; - case FDE_CSSProperty::BorderRight: - if (ParseBorderProperty(pszValue, iValueLen, pWidth)) { - AddPropertyHolder(FDE_CSSProperty::BorderRightWidth, pWidth, - bImportant); - return; - } - break; - case FDE_CSSProperty::BorderBottom: - if (ParseBorderProperty(pszValue, iValueLen, pWidth)) { - AddPropertyHolder(FDE_CSSProperty::BorderBottomWidth, pWidth, - bImportant); - return; - } - break; - default: - break; - } - } break; - case FDE_CSSVALUETYPE_List: - ParseValueListProperty(pArgs, pszValue, iValueLen, bImportant); - return; - default: - ASSERT(false); - break; - } -} - -void CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszName, - int32_t iNameLen, - const FX_WCHAR* pszValue, - int32_t iValueLen) { - auto pProperty = pdfium::MakeUnique(); - pProperty->pwsName = CopyToLocal(pArgs, pszName, iNameLen); - pProperty->pwsValue = CopyToLocal(pArgs, pszValue, iValueLen); - custom_properties_.push_back(std::move(pProperty)); -} - -CFX_RetainPtr CFDE_CSSDeclaration::ParseNumber( - const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen) { - FX_FLOAT fValue; - FDE_CSSNumberType eUnit; - if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eUnit)) - return nullptr; - return pdfium::MakeRetain(eUnit, fValue); -} - -CFX_RetainPtr CFDE_CSSDeclaration::ParseEnum( - const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen) { - const FDE_CSSPropertyValueTable* pValue = - FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); - return pValue ? pdfium::MakeRetain(pValue->eName) - : nullptr; -} - -CFX_RetainPtr CFDE_CSSDeclaration::ParseColor( - const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen) { - FX_ARGB dwColor; - if (!FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) - return nullptr; - return pdfium::MakeRetain(dwColor); -} - -CFX_RetainPtr CFDE_CSSDeclaration::ParseString( - const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen) { - int32_t iOffset; - if (!FDE_ParseCSSString(pszValue, iValueLen, &iOffset, &iValueLen)) - return nullptr; - - if (iValueLen <= 0) - return nullptr; - - pszValue = CopyToLocal(pArgs, pszValue + iOffset, iValueLen); - return pszValue ? pdfium::MakeRetain(pszValue) : nullptr; -} - -void CFDE_CSSDeclaration::ParseValueListProperty( - const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen, - bool bImportant) { - FX_WCHAR separator = - (pArgs->pProperty->eName == FDE_CSSProperty::FontFamily) ? ',' : ' '; - CFDE_CSSValueListParser parser(pszValue, iValueLen, separator); - - const uint32_t dwType = pArgs->pProperty->dwType; - FDE_CSSPrimitiveType eType; - std::vector> list; - while (parser.NextValue(eType, pszValue, iValueLen)) { - switch (eType) { - case FDE_CSSPrimitiveType::Number: - if (dwType & FDE_CSSVALUETYPE_MaybeNumber) { - FX_FLOAT fValue; - FDE_CSSNumberType eNumType; - if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eNumType)) - list.push_back( - pdfium::MakeRetain(eNumType, fValue)); - } - break; - case FDE_CSSPrimitiveType::String: - if (dwType & FDE_CSSVALUETYPE_MaybeColor) { - FX_ARGB dwColor; - if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) { - list.push_back(pdfium::MakeRetain(dwColor)); - continue; - } - } - if (dwType & FDE_CSSVALUETYPE_MaybeEnum) { - const FDE_CSSPropertyValueTable* pValue = - FDE_GetCSSPropertyValueByName( - CFX_WideStringC(pszValue, iValueLen)); - if (pValue) { - list.push_back( - pdfium::MakeRetain(pValue->eName)); - continue; - } - } - if (dwType & FDE_CSSVALUETYPE_MaybeString) { - pszValue = CopyToLocal(pArgs, pszValue, iValueLen); - list.push_back(pdfium::MakeRetain(pszValue)); - } - break; - case FDE_CSSPrimitiveType::RGB: - if (dwType & FDE_CSSVALUETYPE_MaybeColor) { - FX_ARGB dwColor; - if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) { - list.push_back(pdfium::MakeRetain(dwColor)); - } - } - break; - default: - break; - } - } - if (list.empty()) - return; - - switch (pArgs->pProperty->eName) { - case FDE_CSSProperty::BorderWidth: - Add4ValuesProperty(list, bImportant, FDE_CSSProperty::BorderLeftWidth, - FDE_CSSProperty::BorderTopWidth, - FDE_CSSProperty::BorderRightWidth, - FDE_CSSProperty::BorderBottomWidth); - return; - case FDE_CSSProperty::Margin: - Add4ValuesProperty(list, bImportant, FDE_CSSProperty::MarginLeft, - FDE_CSSProperty::MarginTop, - FDE_CSSProperty::MarginRight, - FDE_CSSProperty::MarginBottom); - return; - case FDE_CSSProperty::Padding: - Add4ValuesProperty(list, bImportant, FDE_CSSProperty::PaddingLeft, - FDE_CSSProperty::PaddingTop, - FDE_CSSProperty::PaddingRight, - FDE_CSSProperty::PaddingBottom); - return; - default: { - auto pList = pdfium::MakeRetain(list); - AddPropertyHolder(pArgs->pProperty->eName, pList, bImportant); - return; - } - } -} - -void CFDE_CSSDeclaration::Add4ValuesProperty( - const std::vector>& list, - bool bImportant, - FDE_CSSProperty eLeft, - FDE_CSSProperty eTop, - FDE_CSSProperty eRight, - FDE_CSSProperty eBottom) { - switch (list.size()) { - case 1: - AddPropertyHolder(eLeft, list[0], bImportant); - AddPropertyHolder(eTop, list[0], bImportant); - AddPropertyHolder(eRight, list[0], bImportant); - AddPropertyHolder(eBottom, list[0], bImportant); - return; - case 2: - AddPropertyHolder(eLeft, list[1], bImportant); - AddPropertyHolder(eTop, list[0], bImportant); - AddPropertyHolder(eRight, list[1], bImportant); - AddPropertyHolder(eBottom, list[0], bImportant); - return; - case 3: - AddPropertyHolder(eLeft, list[1], bImportant); - AddPropertyHolder(eTop, list[0], bImportant); - AddPropertyHolder(eRight, list[1], bImportant); - AddPropertyHolder(eBottom, list[2], bImportant); - return; - case 4: - AddPropertyHolder(eLeft, list[3], bImportant); - AddPropertyHolder(eTop, list[0], bImportant); - AddPropertyHolder(eRight, list[1], bImportant); - AddPropertyHolder(eBottom, list[2], bImportant); - return; - default: - break; - } -} - -bool CFDE_CSSDeclaration::ParseBorderProperty( - const FX_WCHAR* pszValue, - int32_t iValueLen, - CFX_RetainPtr& pWidth) const { - pWidth.Reset(nullptr); - - CFDE_CSSValueListParser parser(pszValue, iValueLen, ' '); - FDE_CSSPrimitiveType eType; - while (parser.NextValue(eType, pszValue, iValueLen)) { - switch (eType) { - case FDE_CSSPrimitiveType::Number: { - if (pWidth) - continue; - - FX_FLOAT fValue; - FDE_CSSNumberType eNumType; - if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eNumType)) - pWidth = pdfium::MakeRetain(eNumType, fValue); - break; - } - case FDE_CSSPrimitiveType::String: { - const FDE_CSSCOLORTABLE* pColorItem = - FDE_GetCSSColorByName(CFX_WideStringC(pszValue, iValueLen)); - if (pColorItem) - continue; - - const FDE_CSSPropertyValueTable* pValue = - FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); - if (!pValue) - continue; - - switch (pValue->eName) { - case FDE_CSSPropertyValue::Thin: - case FDE_CSSPropertyValue::Thick: - case FDE_CSSPropertyValue::Medium: - if (!pWidth) - pWidth = pdfium::MakeRetain(pValue->eName); - break; - default: - break; - } - break; - } - default: - break; - } - } - if (!pWidth) - pWidth = pdfium::MakeRetain(FDE_CSSNumberType::Number, - 0.0f); - - return true; -} - -void CFDE_CSSDeclaration::ParseFontProperty(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen, - bool bImportant) { - CFDE_CSSValueListParser parser(pszValue, iValueLen, '/'); - CFX_RetainPtr pStyle; - CFX_RetainPtr pVariant; - CFX_RetainPtr pWeight; - CFX_RetainPtr pFontSize; - CFX_RetainPtr pLineHeight; - std::vector> familyList; - FDE_CSSPrimitiveType eType; - while (parser.NextValue(eType, pszValue, iValueLen)) { - switch (eType) { - case FDE_CSSPrimitiveType::String: { - const FDE_CSSPropertyValueTable* pValue = - FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); - if (pValue) { - switch (pValue->eName) { - case FDE_CSSPropertyValue::XxSmall: - case FDE_CSSPropertyValue::XSmall: - case FDE_CSSPropertyValue::Small: - case FDE_CSSPropertyValue::Medium: - case FDE_CSSPropertyValue::Large: - case FDE_CSSPropertyValue::XLarge: - case FDE_CSSPropertyValue::XxLarge: - case FDE_CSSPropertyValue::Smaller: - case FDE_CSSPropertyValue::Larger: - if (!pFontSize) - pFontSize = - pdfium::MakeRetain(pValue->eName); - continue; - case FDE_CSSPropertyValue::Bold: - case FDE_CSSPropertyValue::Bolder: - case FDE_CSSPropertyValue::Lighter: - if (!pWeight) - pWeight = pdfium::MakeRetain(pValue->eName); - continue; - case FDE_CSSPropertyValue::Italic: - case FDE_CSSPropertyValue::Oblique: - if (!pStyle) - pStyle = pdfium::MakeRetain(pValue->eName); - continue; - case FDE_CSSPropertyValue::SmallCaps: - if (!pVariant) - pVariant = pdfium::MakeRetain(pValue->eName); - continue; - case FDE_CSSPropertyValue::Normal: - if (!pStyle) - pStyle = pdfium::MakeRetain(pValue->eName); - else if (!pVariant) - pVariant = pdfium::MakeRetain(pValue->eName); - else if (!pWeight) - pWeight = pdfium::MakeRetain(pValue->eName); - else if (!pFontSize) - pFontSize = - pdfium::MakeRetain(pValue->eName); - else if (!pLineHeight) - pLineHeight = - pdfium::MakeRetain(pValue->eName); - continue; - default: - break; - } - } - if (pFontSize) { - familyList.push_back(pdfium::MakeRetain( - CopyToLocal(pArgs, pszValue, iValueLen))); - } - parser.m_Separator = ','; - break; - } - case FDE_CSSPrimitiveType::Number: { - FX_FLOAT fValue; - FDE_CSSNumberType eNumType; - if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eNumType)) - break; - if (eType == FDE_CSSPrimitiveType::Number) { - switch ((int32_t)fValue) { - case 100: - case 200: - case 300: - case 400: - case 500: - case 600: - case 700: - case 800: - case 900: - if (!pWeight) - pWeight = pdfium::MakeRetain( - FDE_CSSNumberType::Number, fValue); - continue; - } - } - if (!pFontSize) - pFontSize = pdfium::MakeRetain(eNumType, fValue); - else if (!pLineHeight) - pLineHeight = - pdfium::MakeRetain(eNumType, fValue); - break; - } - default: - break; - } - } - - if (!pStyle) - pStyle = - pdfium::MakeRetain(FDE_CSSPropertyValue::Normal); - if (!pVariant) - pVariant = - pdfium::MakeRetain(FDE_CSSPropertyValue::Normal); - if (!pWeight) - pWeight = - pdfium::MakeRetain(FDE_CSSPropertyValue::Normal); - if (!pFontSize) - pFontSize = - pdfium::MakeRetain(FDE_CSSPropertyValue::Medium); - if (!pLineHeight) - pLineHeight = - pdfium::MakeRetain(FDE_CSSPropertyValue::Normal); - - AddPropertyHolder(FDE_CSSProperty::FontStyle, pStyle, bImportant); - AddPropertyHolder(FDE_CSSProperty::FontVariant, pVariant, bImportant); - AddPropertyHolder(FDE_CSSProperty::FontWeight, pWeight, bImportant); - AddPropertyHolder(FDE_CSSProperty::FontSize, pFontSize, bImportant); - AddPropertyHolder(FDE_CSSProperty::LineHeight, pLineHeight, bImportant); - if (!familyList.empty()) { - auto pList = pdfium::MakeRetain(familyList); - AddPropertyHolder(FDE_CSSProperty::FontFamily, pList, bImportant); - } -} - -size_t CFDE_CSSDeclaration::PropertyCountForTesting() const { - return properties_.size(); -} - -FDE_CSSPropertyHolder::FDE_CSSPropertyHolder() {} - -FDE_CSSPropertyHolder::~FDE_CSSPropertyHolder() {} diff --git a/xfa/fde/css/fde_cssdeclaration.h b/xfa/fde/css/fde_cssdeclaration.h deleted file mode 100644 index 72657184eb..0000000000 --- a/xfa/fde/css/fde_cssdeclaration.h +++ /dev/null @@ -1,112 +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 XFA_FDE_CSS_FDE_CSSDECLARATION_H_ -#define XFA_FDE_CSS_FDE_CSSDECLARATION_H_ - -#include -#include -#include -#include - -#include "xfa/fde/css/fde_cssdatatable.h" - -class FDE_CSSPropertyHolder { - public: - FDE_CSSPropertyHolder(); - ~FDE_CSSPropertyHolder(); - - FDE_CSSProperty eProperty; - bool bImportant; - CFX_RetainPtr pValue; -}; - -class FDE_CSSCustomProperty { - public: - const FX_WCHAR* pwsName; - const FX_WCHAR* pwsValue; -}; - -struct FDE_CSSPropertyArgs { - std::unordered_map* pStringCache; - const FDE_CSSPropertyTable* pProperty; -}; - -class CFDE_CSSDeclaration { - public: - using const_prop_iterator = - std::vector>::const_iterator; - using const_custom_iterator = - std::vector>::const_iterator; - - CFDE_CSSDeclaration(); - ~CFDE_CSSDeclaration(); - - CFDE_CSSValue* GetProperty(FDE_CSSProperty eProperty, bool& bImportant) const; - - const_prop_iterator begin() const { return properties_.begin(); } - const_prop_iterator end() const { return properties_.end(); } - - const_custom_iterator custom_begin() const { - return custom_properties_.begin(); - } - const_custom_iterator custom_end() const { return custom_properties_.end(); } - - bool empty() const { return properties_.empty(); } - - void AddProperty(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen); - void AddProperty(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszName, - int32_t iNameLen, - const FX_WCHAR* pszValue, - int32_t iValueLen); - - size_t PropertyCountForTesting() const; - - protected: - void ParseFontProperty(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen, - bool bImportant); - bool ParseBorderProperty(const FX_WCHAR* pszValue, - int32_t iValueLen, - CFX_RetainPtr& pWidth) const; - void ParseValueListProperty(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen, - bool bImportant); - void Add4ValuesProperty(const std::vector>& list, - bool bImportant, - FDE_CSSProperty eLeft, - FDE_CSSProperty eTop, - FDE_CSSProperty eRight, - FDE_CSSProperty eBottom); - CFX_RetainPtr ParseNumber(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen); - CFX_RetainPtr ParseEnum(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen); - CFX_RetainPtr ParseColor(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen); - CFX_RetainPtr ParseString(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen); - const FX_WCHAR* CopyToLocal(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen); - void AddPropertyHolder(FDE_CSSProperty eProperty, - CFX_RetainPtr pValue, - bool bImportant); - - std::vector> properties_; - std::vector> custom_properties_; -}; - -#endif // XFA_FDE_CSS_FDE_CSSDECLARATION_H_ diff --git a/xfa/fde/css/fde_cssstyleselector.cpp b/xfa/fde/css/fde_cssstyleselector.cpp deleted file mode 100644 index 7184ce3f8a..0000000000 --- a/xfa/fde/css/fde_cssstyleselector.cpp +++ /dev/null @@ -1,1014 +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 "xfa/fde/css/fde_cssstyleselector.h" - -#include -#include - -#include "third_party/base/ptr_util.h" -#include "third_party/base/stl_util.h" -#include "xfa/fde/css/cfde_csscolorvalue.h" -#include "xfa/fde/css/cfde_cssenumvalue.h" -#include "xfa/fde/css/cfde_cssstringvalue.h" -#include "xfa/fde/css/cfde_cssvaluelist.h" -#include "xfa/fde/css/fde_csscache.h" -#include "xfa/fde/css/fde_cssdeclaration.h" -#include "xfa/fde/css/fde_cssstylesheet.h" -#include "xfa/fde/css/fde_csssyntax.h" -#include "xfa/fxfa/app/cxfa_csstagprovider.h" - -namespace { - -template -T* ToValue(CFDE_CSSValue* val) { - return static_cast(val); -} - -template -const T* ToValue(const CFDE_CSSValue* val) { - return static_cast(val); -} - -} // namespace - -#define FDE_CSSUNIVERSALHASH ('*') - -FDE_CSSRuleData::FDE_CSSRuleData(CFDE_CSSSelector* pSel, - CFDE_CSSDeclaration* pDecl, - uint32_t dwPos) - : pSelector(pSel), pDeclaration(pDecl), dwPriority(dwPos), pNext(nullptr) { - static const uint32_t s_Specific[5] = {0x00010000, 0x00010000, 0x00100000, - 0x00100000, 0x01000000}; - for (; pSel; pSel = pSel->GetNextSelector()) { - FDE_CSSSelectorType eType = pSel->GetType(); - if (eType > FDE_CSSSelectorType::Descendant || - pSel->GetNameHash() != FDE_CSSUNIVERSALHASH) { - dwPriority += s_Specific[static_cast(eType)]; - } - } -} - -CFDE_CSSStyleSelector::CFDE_CSSStyleSelector(CFGAS_FontMgr* pFontMgr) - : m_pFontMgr(pFontMgr), m_fDefFontSize(12.0f) { - m_ePriorities[static_cast(FDE_CSSStyleSheetPriority::High)] = - FDE_CSSStyleSheetGroup::Author; - m_ePriorities[static_cast(FDE_CSSStyleSheetPriority::Mid)] = - FDE_CSSStyleSheetGroup::User; - m_ePriorities[static_cast(FDE_CSSStyleSheetPriority::Low)] = - FDE_CSSStyleSheetGroup::UserAgent; -} - -CFDE_CSSStyleSelector::~CFDE_CSSStyleSelector() { - Reset(); -} - -void CFDE_CSSStyleSelector::SetDefFontSize(FX_FLOAT fFontSize) { - ASSERT(fFontSize > 0); - m_fDefFontSize = fFontSize; -} - -CFDE_CSSAccelerator* CFDE_CSSStyleSelector::InitAccelerator() { - if (!m_pAccelerator) - m_pAccelerator = pdfium::MakeUnique(); - m_pAccelerator->Clear(); - return m_pAccelerator.get(); -} - -CFDE_CSSComputedStyle* CFDE_CSSStyleSelector::CreateComputedStyle( - CFDE_CSSComputedStyle* pParentStyle) { - CFDE_CSSComputedStyle* pStyle = new CFDE_CSSComputedStyle(); - if (pParentStyle) - pStyle->m_InheritedData = pParentStyle->m_InheritedData; - return pStyle; -} - -bool CFDE_CSSStyleSelector::SetStyleSheet(FDE_CSSStyleSheetGroup eType, - CFDE_CSSStyleSheet* pSheet) { - CFX_ArrayTemplate& dest = - m_SheetGroups[static_cast(eType)]; - dest.RemoveAt(0, dest.GetSize()); - if (pSheet) - dest.Add(pSheet); - return true; -} - -bool CFDE_CSSStyleSelector::SetStyleSheets( - FDE_CSSStyleSheetGroup eType, - const CFX_ArrayTemplate* pArray) { - CFX_ArrayTemplate& dest = - m_SheetGroups[static_cast(eType)]; - if (pArray) - dest.Copy(*pArray); - else - dest.RemoveAt(0, dest.GetSize()); - return true; -} - -void CFDE_CSSStyleSelector::SetStylePriority( - FDE_CSSStyleSheetGroup eType, - FDE_CSSStyleSheetPriority ePriority) { - m_ePriorities[static_cast(ePriority)] = eType; -} - -void CFDE_CSSStyleSelector::UpdateStyleIndex(uint32_t dwMediaList) { - Reset(); - - // TODO(dsinclair): Hard coded size bad. This should probably just be a map. - for (int32_t iGroup = 0; iGroup < 3; ++iGroup) { - CFDE_CSSRuleCollection& rules = m_RuleCollection[iGroup]; - rules.AddRulesFrom(m_SheetGroups[iGroup], dwMediaList, m_pFontMgr); - } -} - -void CFDE_CSSStyleSelector::Reset() { - // TODO(dsinclair): Hard coded size bad. This should probably just be a map. - for (int32_t iGroup = 0; iGroup < 3; ++iGroup) { - m_RuleCollection[iGroup].Clear(); - } -} - -int32_t CFDE_CSSStyleSelector::MatchDeclarations( - CXFA_CSSTagProvider* pTag, - CFX_ArrayTemplate& matchedDecls, - FDE_CSSPseudo ePseudoType) { - ASSERT(pTag); - FDE_CSSTagCache* pCache = m_pAccelerator->GetTopElement(); - ASSERT(pCache && pCache->GetTag() == pTag); - - matchedDecls.RemoveAt(0, matchedDecls.GetSize()); - // TODO(dsinclair): Hard coded size bad ... - for (int32_t ePriority = 2; ePriority >= 0; --ePriority) { - FDE_CSSStyleSheetGroup eGroup = m_ePriorities[ePriority]; - CFDE_CSSRuleCollection& rules = - m_RuleCollection[static_cast(eGroup)]; - if (rules.CountSelectors() == 0) - continue; - - if (ePseudoType == FDE_CSSPseudo::NONE) { - MatchRules(pCache, rules.GetUniversalRuleData(), ePseudoType); - if (pCache->HashTag()) { - MatchRules(pCache, rules.GetTagRuleData(pCache->HashTag()), - ePseudoType); - } - int32_t iCount = pCache->CountHashClass(); - for (int32_t i = 0; i < iCount; i++) { - pCache->SetClassIndex(i); - MatchRules(pCache, rules.GetClassRuleData(pCache->HashClass()), - ePseudoType); - } - } else { - MatchRules(pCache, rules.GetPseudoRuleData(), ePseudoType); - } - - std::sort(m_MatchedRules.begin(), m_MatchedRules.end(), - [](const FDE_CSSRuleData* p1, const FDE_CSSRuleData* p2) { - return p1->dwPriority < p2->dwPriority; - }); - for (const auto& rule : m_MatchedRules) - matchedDecls.Add(rule->pDeclaration); - m_MatchedRules.clear(); - } - return matchedDecls.GetSize(); -} - -void CFDE_CSSStyleSelector::MatchRules(FDE_CSSTagCache* pCache, - FDE_CSSRuleData* pList, - FDE_CSSPseudo ePseudoType) { - while (pList) { - if (MatchSelector(pCache, pList->pSelector, ePseudoType)) - m_MatchedRules.push_back(pList); - pList = pList->pNext; - } -} - -bool CFDE_CSSStyleSelector::MatchSelector(FDE_CSSTagCache* pCache, - CFDE_CSSSelector* pSel, - FDE_CSSPseudo ePseudoType) { - uint32_t dwHash; - while (pSel && pCache) { - switch (pSel->GetType()) { - case FDE_CSSSelectorType::Descendant: - dwHash = pSel->GetNameHash(); - while ((pCache = pCache->GetParent()) != nullptr) { - if (dwHash != FDE_CSSUNIVERSALHASH && dwHash != pCache->HashTag()) { - continue; - } - if (MatchSelector(pCache, pSel->GetNextSelector(), ePseudoType)) { - return true; - } - } - return false; - case FDE_CSSSelectorType::ID: - dwHash = pCache->HashID(); - if (dwHash != pSel->GetNameHash()) { - return false; - } - break; - case FDE_CSSSelectorType::Class: - dwHash = pCache->HashClass(); - if (dwHash != pSel->GetNameHash()) { - return false; - } - break; - case FDE_CSSSelectorType::Element: - dwHash = pSel->GetNameHash(); - if (dwHash != FDE_CSSUNIVERSALHASH && dwHash != pCache->HashTag()) { - return false; - } - break; - case FDE_CSSSelectorType::Pseudo: - dwHash = FDE_GetCSSPseudoByEnum(ePseudoType)->dwHash; - if (dwHash != pSel->GetNameHash()) { - return false; - } - break; - default: - ASSERT(false); - break; - } - pSel = pSel->GetNextSelector(); - } - return !pSel && pCache; -} - -void CFDE_CSSStyleSelector::ComputeStyle( - CXFA_CSSTagProvider* pTag, - const CFDE_CSSDeclaration** ppDeclArray, - int32_t iDeclCount, - CFDE_CSSComputedStyle* pDestStyle) { - ASSERT(iDeclCount >= 0); - ASSERT(pDestStyle); - - static const uint32_t s_dwStyleHash = FX_HashCode_GetW(L"style", true); - static const uint32_t s_dwAlignHash = FX_HashCode_GetW(L"align", true); - - if (!pTag->empty()) { - CFDE_CSSDeclaration* pDecl = nullptr; - for (auto it : *pTag) { - CFX_WideString wsAttri = it.first; - CFX_WideString wsValue = it.second; - uint32_t dwAttriHash = FX_HashCode_GetW(wsAttri.AsStringC(), true); - if (dwAttriHash == s_dwStyleHash) { - if (!pDecl) - pDecl = new CFDE_CSSDeclaration; - - AppendInlineStyle(pDecl, wsValue.c_str(), wsValue.GetLength()); - } else if (dwAttriHash == s_dwAlignHash) { - if (!pDecl) - pDecl = new CFDE_CSSDeclaration; - - FDE_CSSPropertyArgs args; - args.pStringCache = nullptr; - args.pProperty = FDE_GetCSSPropertyByEnum(FDE_CSSProperty::TextAlign); - pDecl->AddProperty(&args, wsValue.c_str(), wsValue.GetLength()); - } - } - - if (pDecl) { - CFX_ArrayTemplate decls; - decls.SetSize(iDeclCount + 1); - CFDE_CSSDeclaration** ppInline = decls.GetData(); - FXSYS_memcpy(ppInline, ppDeclArray, - iDeclCount * sizeof(CFDE_CSSDeclaration*)); - ppInline[iDeclCount++] = pDecl; - ApplyDeclarations(true, const_cast(ppInline), - iDeclCount, pDestStyle); - ApplyDeclarations(false, - const_cast(ppInline), - iDeclCount, pDestStyle); - return; - } - } - - if (iDeclCount > 0) { - ASSERT(ppDeclArray); - - ApplyDeclarations(true, ppDeclArray, iDeclCount, pDestStyle); - ApplyDeclarations(false, ppDeclArray, iDeclCount, pDestStyle); - } -} - -void CFDE_CSSStyleSelector::ApplyDeclarations( - bool bPriority, - const CFDE_CSSDeclaration** ppDeclArray, - int32_t iDeclCount, - CFDE_CSSComputedStyle* pDestStyle) { - CFDE_CSSComputedStyle* pComputedStyle = pDestStyle; - - int32_t i; - if (bPriority) { - CFDE_CSSValue* pLastest = nullptr; - CFDE_CSSValue* pImportant = nullptr; - for (i = 0; i < iDeclCount; ++i) { - bool bImportant; - CFDE_CSSValue* pVal = - ppDeclArray[i]->GetProperty(FDE_CSSProperty::FontSize, bImportant); - if (!pVal) - continue; - - if (bImportant) - pImportant = pVal; - else - pLastest = pVal; - } - if (pImportant) { - ApplyProperty(FDE_CSSProperty::FontSize, pImportant, pComputedStyle); - } else if (pLastest) { - ApplyProperty(FDE_CSSProperty::FontSize, pLastest, pComputedStyle); - } - } else { - CFX_ArrayTemplate importants; - const CFDE_CSSDeclaration* pDecl = nullptr; - - for (i = 0; i < iDeclCount; ++i) { - pDecl = ppDeclArray[i]; - for (auto it = pDecl->begin(); it != pDecl->end(); it++) { - if ((*it)->eProperty == FDE_CSSProperty::FontSize) - continue; - if (!(*it)->bImportant) { - ApplyProperty((*it)->eProperty, (*it)->pValue.Get(), pComputedStyle); - } else if (importants.GetSize() == 0 || - importants[importants.GetUpperBound()] != pDecl) { - importants.Add(const_cast(pDecl)); - } - } - } - - iDeclCount = importants.GetSize(); - for (i = 0; i < iDeclCount; ++i) { - pDecl = importants[i]; - - for (auto it = pDecl->begin(); it != pDecl->end(); it++) { - if ((*it)->bImportant && (*it)->eProperty != FDE_CSSProperty::FontSize) - ApplyProperty((*it)->eProperty, (*it)->pValue.Get(), pComputedStyle); - } - } - - for (auto it = pDecl->custom_begin(); it != pDecl->custom_end(); it++) { - pComputedStyle->AddCustomStyle((*it)->pwsName, (*it)->pwsValue); - } - } -} - -void CFDE_CSSStyleSelector::AppendInlineStyle(CFDE_CSSDeclaration* pDecl, - const FX_WCHAR* psz, - int32_t iLen) { - ASSERT(pDecl && psz && iLen > 0); - auto pSyntax = pdfium::MakeUnique(); - if (!pSyntax->Init(psz, iLen, 32, true)) - return; - - int32_t iLen2 = 0; - const FX_WCHAR* psz2; - FDE_CSSPropertyArgs args; - args.pStringCache = nullptr; - args.pProperty = nullptr; - CFX_WideString wsName; - while (1) { - FDE_CSSSyntaxStatus eStatus = pSyntax->DoSyntaxParse(); - if (eStatus == FDE_CSSSyntaxStatus::PropertyName) { - psz2 = pSyntax->GetCurrentString(iLen2); - args.pProperty = FDE_GetCSSPropertyByName(CFX_WideStringC(psz2, iLen2)); - if (!args.pProperty) - wsName = CFX_WideStringC(psz2, iLen2); - } else if (eStatus == FDE_CSSSyntaxStatus::PropertyValue) { - if (args.pProperty) { - psz2 = pSyntax->GetCurrentString(iLen2); - if (iLen2 > 0) - pDecl->AddProperty(&args, psz2, iLen2); - } else if (iLen2 > 0) { - psz2 = pSyntax->GetCurrentString(iLen2); - if (iLen2 > 0) { - pDecl->AddProperty(&args, wsName.c_str(), wsName.GetLength(), psz2, - iLen2); - } - } - } else { - break; - } - } -} - -void CFDE_CSSStyleSelector::ApplyProperty( - FDE_CSSProperty eProperty, - CFDE_CSSValue* pValue, - CFDE_CSSComputedStyle* pComputedStyle) { - if (pValue->GetType() != FDE_CSSPrimitiveType::List) { - FDE_CSSPrimitiveType eType = pValue->GetType(); - switch (eProperty) { - case FDE_CSSProperty::Display: - if (eType == FDE_CSSPrimitiveType::Enum) { - pComputedStyle->m_NonInheritedData.m_eDisplay = - ToDisplay(ToValue(pValue)->Value()); - } - break; - case FDE_CSSProperty::FontSize: { - FX_FLOAT& fFontSize = pComputedStyle->m_InheritedData.m_fFontSize; - if (eType == FDE_CSSPrimitiveType::Number) { - fFontSize = ToValue(pValue)->Apply(fFontSize); - } else if (eType == FDE_CSSPrimitiveType::Enum) { - fFontSize = ToFontSize(ToValue(pValue)->Value(), - fFontSize); - } - } break; - case FDE_CSSProperty::LineHeight: - if (eType == FDE_CSSPrimitiveType::Number) { - const CFDE_CSSNumberValue* v = ToValue(pValue); - if (v->Kind() == FDE_CSSNumberType::Number) { - pComputedStyle->m_InheritedData.m_fLineHeight = - v->Value() * pComputedStyle->m_InheritedData.m_fFontSize; - } else { - pComputedStyle->m_InheritedData.m_fLineHeight = - v->Apply(pComputedStyle->m_InheritedData.m_fFontSize); - } - } - break; - case FDE_CSSProperty::TextAlign: - if (eType == FDE_CSSPrimitiveType::Enum) { - pComputedStyle->m_InheritedData.m_eTextAlign = - ToTextAlign(ToValue(pValue)->Value()); - } - break; - case FDE_CSSProperty::TextIndent: - SetLengthWithPercent(pComputedStyle->m_InheritedData.m_TextIndent, - eType, pValue, - pComputedStyle->m_InheritedData.m_fFontSize); - break; - case FDE_CSSProperty::FontWeight: - if (eType == FDE_CSSPrimitiveType::Enum) { - pComputedStyle->m_InheritedData.m_wFontWeight = - ToFontWeight(ToValue(pValue)->Value()); - } else if (eType == FDE_CSSPrimitiveType::Number) { - int32_t iValue = - (int32_t)ToValue(pValue)->Value() / 100; - if (iValue >= 1 && iValue <= 9) { - pComputedStyle->m_InheritedData.m_wFontWeight = iValue * 100; - } - } - break; - case FDE_CSSProperty::FontStyle: - if (eType == FDE_CSSPrimitiveType::Enum) { - pComputedStyle->m_InheritedData.m_eFontStyle = - ToFontStyle(ToValue(pValue)->Value()); - } - break; - case FDE_CSSProperty::Color: - if (eType == FDE_CSSPrimitiveType::RGB) { - pComputedStyle->m_InheritedData.m_dwFontColor = - ToValue(pValue)->Value(); - } - break; - case FDE_CSSProperty::MarginLeft: - if (SetLengthWithPercent( - pComputedStyle->m_NonInheritedData.m_MarginWidth.left, eType, - pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { - pComputedStyle->m_NonInheritedData.m_bHasMargin = true; - } - break; - case FDE_CSSProperty::MarginTop: - if (SetLengthWithPercent( - pComputedStyle->m_NonInheritedData.m_MarginWidth.top, eType, - pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { - pComputedStyle->m_NonInheritedData.m_bHasMargin = true; - } - break; - case FDE_CSSProperty::MarginRight: - if (SetLengthWithPercent( - pComputedStyle->m_NonInheritedData.m_MarginWidth.right, eType, - pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { - pComputedStyle->m_NonInheritedData.m_bHasMargin = true; - } - break; - case FDE_CSSProperty::MarginBottom: - if (SetLengthWithPercent( - pComputedStyle->m_NonInheritedData.m_MarginWidth.bottom, eType, - pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { - pComputedStyle->m_NonInheritedData.m_bHasMargin = true; - } - break; - case FDE_CSSProperty::PaddingLeft: - if (SetLengthWithPercent( - pComputedStyle->m_NonInheritedData.m_PaddingWidth.left, eType, - pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { - pComputedStyle->m_NonInheritedData.m_bHasPadding = true; - } - break; - case FDE_CSSProperty::PaddingTop: - if (SetLengthWithPercent( - pComputedStyle->m_NonInheritedData.m_PaddingWidth.top, eType, - pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { - pComputedStyle->m_NonInheritedData.m_bHasPadding = true; - } - break; - case FDE_CSSProperty::PaddingRight: - if (SetLengthWithPercent( - pComputedStyle->m_NonInheritedData.m_PaddingWidth.right, eType, - pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { - pComputedStyle->m_NonInheritedData.m_bHasPadding = true; - } - break; - case FDE_CSSProperty::PaddingBottom: - if (SetLengthWithPercent( - pComputedStyle->m_NonInheritedData.m_PaddingWidth.bottom, eType, - pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { - pComputedStyle->m_NonInheritedData.m_bHasPadding = true; - } - break; - case FDE_CSSProperty::BorderLeftWidth: - if (SetLengthWithPercent( - pComputedStyle->m_NonInheritedData.m_BorderWidth.left, eType, - pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { - pComputedStyle->m_NonInheritedData.m_bHasBorder = true; - } - break; - case FDE_CSSProperty::BorderTopWidth: - if (SetLengthWithPercent( - pComputedStyle->m_NonInheritedData.m_BorderWidth.top, eType, - pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { - pComputedStyle->m_NonInheritedData.m_bHasBorder = true; - } - break; - case FDE_CSSProperty::BorderRightWidth: - if (SetLengthWithPercent( - pComputedStyle->m_NonInheritedData.m_BorderWidth.right, eType, - pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { - pComputedStyle->m_NonInheritedData.m_bHasBorder = true; - } - break; - case FDE_CSSProperty::BorderBottomWidth: - if (SetLengthWithPercent( - pComputedStyle->m_NonInheritedData.m_BorderWidth.bottom, eType, - pValue, pComputedStyle->m_InheritedData.m_fFontSize)) { - pComputedStyle->m_NonInheritedData.m_bHasBorder = true; - } - break; - case FDE_CSSProperty::VerticalAlign: - if (eType == FDE_CSSPrimitiveType::Enum) { - pComputedStyle->m_NonInheritedData.m_eVerticalAlign = - ToVerticalAlign(ToValue(pValue)->Value()); - } else if (eType == FDE_CSSPrimitiveType::Number) { - pComputedStyle->m_NonInheritedData.m_eVerticalAlign = - FDE_CSSVerticalAlign::Number; - pComputedStyle->m_NonInheritedData.m_fVerticalAlign = - ToValue(pValue)->Apply( - pComputedStyle->m_InheritedData.m_fFontSize); - } - break; - case FDE_CSSProperty::FontVariant: - if (eType == FDE_CSSPrimitiveType::Enum) { - pComputedStyle->m_InheritedData.m_eFontVariant = - ToFontVariant(ToValue(pValue)->Value()); - } - break; - case FDE_CSSProperty::LetterSpacing: - if (eType == FDE_CSSPrimitiveType::Enum) { - pComputedStyle->m_InheritedData.m_LetterSpacing.Set( - FDE_CSSLengthUnit::Normal); - } else if (eType == FDE_CSSPrimitiveType::Number) { - if (ToValue(pValue)->Kind() == - FDE_CSSNumberType::Percent) { - break; - } - - SetLengthWithPercent(pComputedStyle->m_InheritedData.m_LetterSpacing, - eType, pValue, - pComputedStyle->m_InheritedData.m_fFontSize); - } - break; - case FDE_CSSProperty::WordSpacing: - if (eType == FDE_CSSPrimitiveType::Enum) { - pComputedStyle->m_InheritedData.m_WordSpacing.Set( - FDE_CSSLengthUnit::Normal); - } else if (eType == FDE_CSSPrimitiveType::Number) { - if (ToValue(pValue)->Kind() == - FDE_CSSNumberType::Percent) { - break; - } - SetLengthWithPercent(pComputedStyle->m_InheritedData.m_WordSpacing, - eType, pValue, - pComputedStyle->m_InheritedData.m_fFontSize); - } - break; - case FDE_CSSProperty::Top: - SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Top, eType, - pValue, - pComputedStyle->m_InheritedData.m_fFontSize); - break; - case FDE_CSSProperty::Bottom: - SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Bottom, eType, - pValue, - pComputedStyle->m_InheritedData.m_fFontSize); - break; - case FDE_CSSProperty::Left: - SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Left, eType, - pValue, - pComputedStyle->m_InheritedData.m_fFontSize); - break; - case FDE_CSSProperty::Right: - SetLengthWithPercent(pComputedStyle->m_NonInheritedData.m_Right, eType, - pValue, - pComputedStyle->m_InheritedData.m_fFontSize); - break; - default: - break; - } - } else if (pValue->GetType() == FDE_CSSPrimitiveType::List) { - CFDE_CSSValueList* pList = ToValue(pValue); - int32_t iCount = pList->CountValues(); - if (iCount > 0) { - switch (eProperty) { - case FDE_CSSProperty::FontFamily: - pComputedStyle->m_InheritedData.m_pFontFamily = pList; - break; - case FDE_CSSProperty::TextDecoration: - pComputedStyle->m_NonInheritedData.m_dwTextDecoration = - ToTextDecoration(pList); - break; - default: - break; - } - } - } else { - ASSERT(false); - } -} - -FDE_CSSDisplay CFDE_CSSStyleSelector::ToDisplay(FDE_CSSPropertyValue eValue) { - switch (eValue) { - case FDE_CSSPropertyValue::Block: - return FDE_CSSDisplay::Block; - case FDE_CSSPropertyValue::None: - return FDE_CSSDisplay::None; - case FDE_CSSPropertyValue::ListItem: - return FDE_CSSDisplay::ListItem; - case FDE_CSSPropertyValue::InlineTable: - return FDE_CSSDisplay::InlineTable; - case FDE_CSSPropertyValue::InlineBlock: - return FDE_CSSDisplay::InlineBlock; - case FDE_CSSPropertyValue::Inline: - default: - return FDE_CSSDisplay::Inline; - } -} - -FDE_CSSTextAlign CFDE_CSSStyleSelector::ToTextAlign( - FDE_CSSPropertyValue eValue) { - switch (eValue) { - case FDE_CSSPropertyValue::Center: - return FDE_CSSTextAlign::Center; - case FDE_CSSPropertyValue::Right: - return FDE_CSSTextAlign::Right; - case FDE_CSSPropertyValue::Justify: - return FDE_CSSTextAlign::Justify; - case FDE_CSSPropertyValue::Left: - default: - return FDE_CSSTextAlign::Left; - } -} - -uint16_t CFDE_CSSStyleSelector::ToFontWeight(FDE_CSSPropertyValue eValue) { - switch (eValue) { - case FDE_CSSPropertyValue::Bold: - return 700; - case FDE_CSSPropertyValue::Bolder: - return 900; - case FDE_CSSPropertyValue::Lighter: - return 200; - case FDE_CSSPropertyValue::Normal: - default: - return 400; - } -} - -FDE_CSSFontStyle CFDE_CSSStyleSelector::ToFontStyle( - FDE_CSSPropertyValue eValue) { - switch (eValue) { - case FDE_CSSPropertyValue::Italic: - case FDE_CSSPropertyValue::Oblique: - return FDE_CSSFontStyle::Italic; - default: - return FDE_CSSFontStyle::Normal; - } -} - -bool CFDE_CSSStyleSelector::SetLengthWithPercent(FDE_CSSLength& width, - FDE_CSSPrimitiveType eType, - CFDE_CSSValue* pValue, - FX_FLOAT fFontSize) { - if (eType == FDE_CSSPrimitiveType::Number) { - const CFDE_CSSNumberValue* v = ToValue(pValue); - if (v->Kind() == FDE_CSSNumberType::Percent) { - width.Set(FDE_CSSLengthUnit::Percent, - ToValue(pValue)->Value() / 100.0f); - return width.NonZero(); - } - - FX_FLOAT fValue = v->Apply(fFontSize); - width.Set(FDE_CSSLengthUnit::Point, fValue); - return width.NonZero(); - } else if (eType == FDE_CSSPrimitiveType::Enum) { - switch (ToValue(pValue)->Value()) { - case FDE_CSSPropertyValue::Auto: - width.Set(FDE_CSSLengthUnit::Auto); - return true; - case FDE_CSSPropertyValue::None: - width.Set(FDE_CSSLengthUnit::None); - return true; - case FDE_CSSPropertyValue::Thin: - width.Set(FDE_CSSLengthUnit::Point, 2); - return true; - case FDE_CSSPropertyValue::Medium: - width.Set(FDE_CSSLengthUnit::Point, 3); - return true; - case FDE_CSSPropertyValue::Thick: - width.Set(FDE_CSSLengthUnit::Point, 4); - return true; - default: - return false; - } - } - return false; -} - -FX_FLOAT CFDE_CSSStyleSelector::ToFontSize(FDE_CSSPropertyValue eValue, - FX_FLOAT fCurFontSize) { - switch (eValue) { - case FDE_CSSPropertyValue::XxSmall: - return m_fDefFontSize / 1.2f / 1.2f / 1.2f; - case FDE_CSSPropertyValue::XSmall: - return m_fDefFontSize / 1.2f / 1.2f; - case FDE_CSSPropertyValue::Small: - return m_fDefFontSize / 1.2f; - case FDE_CSSPropertyValue::Medium: - return m_fDefFontSize; - case FDE_CSSPropertyValue::Large: - return m_fDefFontSize * 1.2f; - case FDE_CSSPropertyValue::XLarge: - return m_fDefFontSize * 1.2f * 1.2f; - case FDE_CSSPropertyValue::XxLarge: - return m_fDefFontSize * 1.2f * 1.2f * 1.2f; - case FDE_CSSPropertyValue::Larger: - return fCurFontSize * 1.2f; - case FDE_CSSPropertyValue::Smaller: - return fCurFontSize / 1.2f; - default: - return fCurFontSize; - } -} - -FDE_CSSVerticalAlign CFDE_CSSStyleSelector::ToVerticalAlign( - FDE_CSSPropertyValue eValue) { - switch (eValue) { - case FDE_CSSPropertyValue::Middle: - return FDE_CSSVerticalAlign::Middle; - case FDE_CSSPropertyValue::Bottom: - return FDE_CSSVerticalAlign::Bottom; - case FDE_CSSPropertyValue::Super: - return FDE_CSSVerticalAlign::Super; - case FDE_CSSPropertyValue::Sub: - return FDE_CSSVerticalAlign::Sub; - case FDE_CSSPropertyValue::Top: - return FDE_CSSVerticalAlign::Top; - case FDE_CSSPropertyValue::TextTop: - return FDE_CSSVerticalAlign::TextTop; - case FDE_CSSPropertyValue::TextBottom: - return FDE_CSSVerticalAlign::TextBottom; - case FDE_CSSPropertyValue::Baseline: - default: - return FDE_CSSVerticalAlign::Baseline; - } -} - -uint32_t CFDE_CSSStyleSelector::ToTextDecoration(CFDE_CSSValueList* pValue) { - uint32_t dwDecoration = 0; - for (int32_t i = pValue->CountValues() - 1; i >= 0; --i) { - CFDE_CSSValue* pVal = pValue->GetValue(i); - if (pVal->GetType() != FDE_CSSPrimitiveType::Enum) - continue; - - switch (ToValue(pVal)->Value()) { - case FDE_CSSPropertyValue::Underline: - dwDecoration |= FDE_CSSTEXTDECORATION_Underline; - break; - case FDE_CSSPropertyValue::LineThrough: - dwDecoration |= FDE_CSSTEXTDECORATION_LineThrough; - break; - case FDE_CSSPropertyValue::Overline: - dwDecoration |= FDE_CSSTEXTDECORATION_Overline; - break; - case FDE_CSSPropertyValue::Blink: - dwDecoration |= FDE_CSSTEXTDECORATION_Blink; - break; - case FDE_CSSPropertyValue::Double: - dwDecoration |= FDE_CSSTEXTDECORATION_Double; - break; - default: - break; - } - } - return dwDecoration; -} - -FDE_CSSFontVariant CFDE_CSSStyleSelector::ToFontVariant( - FDE_CSSPropertyValue eValue) { - return eValue == FDE_CSSPropertyValue::SmallCaps - ? FDE_CSSFontVariant::SmallCaps - : FDE_CSSFontVariant::Normal; -} - -CFDE_CSSComputedStyle::CFDE_CSSComputedStyle() : m_dwRefCount(1) {} - -CFDE_CSSComputedStyle::~CFDE_CSSComputedStyle() {} - -uint32_t CFDE_CSSComputedStyle::Retain() { - return ++m_dwRefCount; -} - -uint32_t CFDE_CSSComputedStyle::Release() { - uint32_t dwRefCount = --m_dwRefCount; - if (dwRefCount == 0) - delete this; - return dwRefCount; -} - -bool CFDE_CSSComputedStyle::GetCustomStyle(const CFX_WideStringC& wsName, - CFX_WideString& wsValue) const { - for (int32_t i = pdfium::CollectionSize(m_CustomProperties) - 2; - i > -1; i -= 2) { - if (wsName == m_CustomProperties[i]) { - wsValue = m_CustomProperties[i + 1]; - return true; - } - } - return false; -} - -int32_t CFDE_CSSComputedStyle::CountFontFamilies() const { - return m_InheritedData.m_pFontFamily - ? m_InheritedData.m_pFontFamily->CountValues() - : 0; -} - -const CFX_WideString CFDE_CSSComputedStyle::GetFontFamily(int32_t index) const { - return ToValue( - m_InheritedData.m_pFontFamily->GetValue(index)) - ->Value(); -} - -uint16_t CFDE_CSSComputedStyle::GetFontWeight() const { - return m_InheritedData.m_wFontWeight; -} - -FDE_CSSFontVariant CFDE_CSSComputedStyle::GetFontVariant() const { - return m_InheritedData.m_eFontVariant; -} - -FDE_CSSFontStyle CFDE_CSSComputedStyle::GetFontStyle() const { - return m_InheritedData.m_eFontStyle; -} - -FX_FLOAT CFDE_CSSComputedStyle::GetFontSize() const { - return m_InheritedData.m_fFontSize; -} - -FX_ARGB CFDE_CSSComputedStyle::GetColor() const { - return m_InheritedData.m_dwFontColor; -} - -void CFDE_CSSComputedStyle::SetFontWeight(uint16_t wFontWeight) { - m_InheritedData.m_wFontWeight = wFontWeight; -} - -void CFDE_CSSComputedStyle::SetFontVariant(FDE_CSSFontVariant eFontVariant) { - m_InheritedData.m_eFontVariant = eFontVariant; -} - -void CFDE_CSSComputedStyle::SetFontStyle(FDE_CSSFontStyle eFontStyle) { - m_InheritedData.m_eFontStyle = eFontStyle; -} - -void CFDE_CSSComputedStyle::SetFontSize(FX_FLOAT fFontSize) { - m_InheritedData.m_fFontSize = fFontSize; -} - -void CFDE_CSSComputedStyle::SetColor(FX_ARGB dwFontColor) { - m_InheritedData.m_dwFontColor = dwFontColor; -} - -const FDE_CSSRect* CFDE_CSSComputedStyle::GetBorderWidth() const { - return m_NonInheritedData.m_bHasBorder ? &(m_NonInheritedData.m_BorderWidth) - : nullptr; -} - -const FDE_CSSRect* CFDE_CSSComputedStyle::GetMarginWidth() const { - return m_NonInheritedData.m_bHasMargin ? &(m_NonInheritedData.m_MarginWidth) - : nullptr; -} - -const FDE_CSSRect* CFDE_CSSComputedStyle::GetPaddingWidth() const { - return m_NonInheritedData.m_bHasPadding ? &(m_NonInheritedData.m_PaddingWidth) - : nullptr; -} - -void CFDE_CSSComputedStyle::SetMarginWidth(const FDE_CSSRect& rect) { - m_NonInheritedData.m_MarginWidth = rect; - m_NonInheritedData.m_bHasMargin = true; -} - -void CFDE_CSSComputedStyle::SetPaddingWidth(const FDE_CSSRect& rect) { - m_NonInheritedData.m_PaddingWidth = rect; - m_NonInheritedData.m_bHasPadding = true; -} - -FDE_CSSDisplay CFDE_CSSComputedStyle::GetDisplay() const { - return m_NonInheritedData.m_eDisplay; -} - -FX_FLOAT CFDE_CSSComputedStyle::GetLineHeight() const { - return m_InheritedData.m_fLineHeight; -} - -const FDE_CSSLength& CFDE_CSSComputedStyle::GetTextIndent() const { - return m_InheritedData.m_TextIndent; -} - -FDE_CSSTextAlign CFDE_CSSComputedStyle::GetTextAlign() const { - return m_InheritedData.m_eTextAlign; -} - -FDE_CSSVerticalAlign CFDE_CSSComputedStyle::GetVerticalAlign() const { - return m_NonInheritedData.m_eVerticalAlign; -} - -FX_FLOAT CFDE_CSSComputedStyle::GetNumberVerticalAlign() const { - return m_NonInheritedData.m_fVerticalAlign; -} - -uint32_t CFDE_CSSComputedStyle::GetTextDecoration() const { - return m_NonInheritedData.m_dwTextDecoration; -} - -const FDE_CSSLength& CFDE_CSSComputedStyle::GetLetterSpacing() const { - return m_InheritedData.m_LetterSpacing; -} - -void CFDE_CSSComputedStyle::SetLineHeight(FX_FLOAT fLineHeight) { - m_InheritedData.m_fLineHeight = fLineHeight; -} - -void CFDE_CSSComputedStyle::SetTextIndent(const FDE_CSSLength& textIndent) { - m_InheritedData.m_TextIndent = textIndent; -} - -void CFDE_CSSComputedStyle::SetTextAlign(FDE_CSSTextAlign eTextAlign) { - m_InheritedData.m_eTextAlign = eTextAlign; -} - -void CFDE_CSSComputedStyle::SetNumberVerticalAlign(FX_FLOAT fAlign) { - m_NonInheritedData.m_eVerticalAlign = FDE_CSSVerticalAlign::Number, - m_NonInheritedData.m_fVerticalAlign = fAlign; -} - -void CFDE_CSSComputedStyle::SetTextDecoration(uint32_t dwTextDecoration) { - m_NonInheritedData.m_dwTextDecoration = dwTextDecoration; -} - -void CFDE_CSSComputedStyle::SetLetterSpacing( - const FDE_CSSLength& letterSpacing) { - m_InheritedData.m_LetterSpacing = letterSpacing; -} - -void CFDE_CSSComputedStyle::AddCustomStyle(const CFX_WideString& wsName, - const CFX_WideString& wsValue) { - m_CustomProperties.push_back(wsName); - m_CustomProperties.push_back(wsValue); -} - -CFDE_CSSInheritedData::CFDE_CSSInheritedData() - : m_LetterSpacing(FDE_CSSLengthUnit::Normal), - m_WordSpacing(FDE_CSSLengthUnit::Normal), - m_TextIndent(FDE_CSSLengthUnit::Point, 0), - m_pFontFamily(nullptr), - m_fFontSize(12.0f), - m_fLineHeight(14.0f), - m_dwFontColor(0xFF000000), - m_wFontWeight(400), - m_eFontVariant(FDE_CSSFontVariant::Normal), - m_eFontStyle(FDE_CSSFontStyle::Normal), - m_eTextAlign(FDE_CSSTextAlign::Left) {} - -CFDE_CSSNonInheritedData::CFDE_CSSNonInheritedData() - : m_MarginWidth(FDE_CSSLengthUnit::Point, 0), - m_BorderWidth(FDE_CSSLengthUnit::Point, 0), - m_PaddingWidth(FDE_CSSLengthUnit::Point, 0), - m_fVerticalAlign(0.0f), - m_eDisplay(FDE_CSSDisplay::Inline), - m_eVerticalAlign(FDE_CSSVerticalAlign::Baseline), - m_dwTextDecoration(0), - m_bHasMargin(false), - m_bHasBorder(false), - m_bHasPadding(false) {} diff --git a/xfa/fde/css/fde_cssstyleselector.h b/xfa/fde/css/fde_cssstyleselector.h deleted file mode 100644 index f4c811b1e7..0000000000 --- a/xfa/fde/css/fde_cssstyleselector.h +++ /dev/null @@ -1,249 +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 XFA_FDE_CSS_FDE_CSSSTYLESELECTOR_H_ -#define XFA_FDE_CSS_FDE_CSSSTYLESELECTOR_H_ - -#include -#include -#include - -#include "core/fxcrt/fx_ext.h" -#include "xfa/fde/css/fde_css.h" -#include "xfa/fde/css/fde_csscache.h" -#include "xfa/fde/css/fde_cssdeclaration.h" - -class CFDE_CSSAccelerator; -class CFDE_CSSComputedStyle; -class CFDE_CSSRule; -class CFDE_CSSSelector; -class CFDE_CSSStyleSheet; -class CFDE_CSSValueList; -class CXFA_CSSTagProvider; - -class FDE_CSSRuleData { - public: - FDE_CSSRuleData(CFDE_CSSSelector* pSel, - CFDE_CSSDeclaration* pDecl, - uint32_t dwPos); - - CFDE_CSSSelector* const pSelector; - CFDE_CSSDeclaration* const pDeclaration; - uint32_t dwPriority; - FDE_CSSRuleData* pNext; -}; - -class CFDE_CSSRuleCollection { - public: - CFDE_CSSRuleCollection(); - ~CFDE_CSSRuleCollection(); - - void AddRulesFrom(const CFX_ArrayTemplate& sheets, - uint32_t dwMediaList, - CFGAS_FontMgr* pFontMgr); - void Clear(); - int32_t CountSelectors() const { return m_iSelectors; } - - FDE_CSSRuleData* GetIDRuleData(uint32_t dwIDHash) { - auto it = m_IDRules.find(dwIDHash); - return it != m_IDRules.end() ? it->second : nullptr; - } - - FDE_CSSRuleData* GetTagRuleData(uint32_t dwTagHash) { - auto it = m_TagRules.find(dwTagHash); - return it != m_TagRules.end() ? it->second : nullptr; - } - - FDE_CSSRuleData* GetClassRuleData(uint32_t dwIDHash) { - auto it = m_ClassRules.find(dwIDHash); - return it != m_ClassRules.end() ? it->second : nullptr; - } - - FDE_CSSRuleData* GetUniversalRuleData() { return m_pUniversalRules; } - FDE_CSSRuleData* GetPseudoRuleData() { return m_pPseudoRules; } - - protected: - void AddRulesFrom(CFDE_CSSStyleSheet* pStyleSheet, - CFDE_CSSRule* pRule, - uint32_t dwMediaList, - CFGAS_FontMgr* pFontMgr); - void AddRuleTo(std::map* pMap, - uint32_t dwKey, - CFDE_CSSSelector* pSel, - CFDE_CSSDeclaration* pDecl); - bool AddRuleTo(FDE_CSSRuleData** pList, FDE_CSSRuleData* pData); - FDE_CSSRuleData* NewRuleData(CFDE_CSSSelector* pSel, - CFDE_CSSDeclaration* pDecl); - - std::map m_IDRules; - std::map m_TagRules; - std::map m_ClassRules; - FDE_CSSRuleData* m_pUniversalRules; - FDE_CSSRuleData* m_pPseudoRules; - int32_t m_iSelectors; -}; - -class CFDE_CSSStyleSelector { - public: - explicit CFDE_CSSStyleSelector(CFGAS_FontMgr* pFontMgr); - ~CFDE_CSSStyleSelector(); - - void SetDefFontSize(FX_FLOAT fFontSize); - - bool SetStyleSheet(FDE_CSSStyleSheetGroup eType, CFDE_CSSStyleSheet* pSheet); - bool SetStyleSheets(FDE_CSSStyleSheetGroup eType, - const CFX_ArrayTemplate* pArray); - void SetStylePriority(FDE_CSSStyleSheetGroup eType, - FDE_CSSStyleSheetPriority ePriority); - void UpdateStyleIndex(uint32_t dwMediaList); - CFDE_CSSAccelerator* InitAccelerator(); - CFDE_CSSComputedStyle* CreateComputedStyle( - CFDE_CSSComputedStyle* pParentStyle); - int32_t MatchDeclarations( - CXFA_CSSTagProvider* pTag, - CFX_ArrayTemplate& matchedDecls, - FDE_CSSPseudo ePseudoType = FDE_CSSPseudo::NONE); - void ComputeStyle(CXFA_CSSTagProvider* pTag, - const CFDE_CSSDeclaration** ppDeclArray, - int32_t iDeclCount, - CFDE_CSSComputedStyle* pDestStyle); - - protected: - void Reset(); - void MatchRules(FDE_CSSTagCache* pCache, - FDE_CSSRuleData* pList, - FDE_CSSPseudo ePseudoType); - bool MatchSelector(FDE_CSSTagCache* pCache, - CFDE_CSSSelector* pSel, - FDE_CSSPseudo ePseudoType); - void AppendInlineStyle(CFDE_CSSDeclaration* pDecl, - const FX_WCHAR* psz, - int32_t iLen); - void ApplyDeclarations(bool bPriority, - const CFDE_CSSDeclaration** ppDeclArray, - int32_t iDeclCount, - CFDE_CSSComputedStyle* pDestStyle); - void ApplyProperty(FDE_CSSProperty eProperty, - CFDE_CSSValue* pValue, - CFDE_CSSComputedStyle* pComputedStyle); - - bool SetLengthWithPercent(FDE_CSSLength& width, - FDE_CSSPrimitiveType eType, - CFDE_CSSValue* pValue, - FX_FLOAT fFontSize); - FX_FLOAT ToFontSize(FDE_CSSPropertyValue eValue, FX_FLOAT fCurFontSize); - FDE_CSSDisplay ToDisplay(FDE_CSSPropertyValue eValue); - FDE_CSSTextAlign ToTextAlign(FDE_CSSPropertyValue eValue); - uint16_t ToFontWeight(FDE_CSSPropertyValue eValue); - FDE_CSSFontStyle ToFontStyle(FDE_CSSPropertyValue eValue); - FDE_CSSVerticalAlign ToVerticalAlign(FDE_CSSPropertyValue eValue); - uint32_t ToTextDecoration(CFDE_CSSValueList* pList); - FDE_CSSFontVariant ToFontVariant(FDE_CSSPropertyValue eValue); - - CFGAS_FontMgr* const m_pFontMgr; - FX_FLOAT m_fDefFontSize; - CFX_ArrayTemplate m_SheetGroups[3]; - CFDE_CSSRuleCollection m_RuleCollection[3]; - FDE_CSSStyleSheetGroup m_ePriorities[3]; - std::unique_ptr m_pAccelerator; - std::vector m_MatchedRules; -}; - -class CFDE_CSSInheritedData { - public: - CFDE_CSSInheritedData(); - - FDE_CSSLength m_LetterSpacing; - FDE_CSSLength m_WordSpacing; - FDE_CSSLength m_TextIndent; - CFDE_CSSValueList* m_pFontFamily; - FX_FLOAT m_fFontSize; - FX_FLOAT m_fLineHeight; - FX_ARGB m_dwFontColor; - uint16_t m_wFontWeight; - FDE_CSSFontVariant m_eFontVariant; - FDE_CSSFontStyle m_eFontStyle; - FDE_CSSTextAlign m_eTextAlign; -}; - -class CFDE_CSSNonInheritedData { - public: - CFDE_CSSNonInheritedData(); - - FDE_CSSRect m_MarginWidth; - FDE_CSSRect m_BorderWidth; - FDE_CSSRect m_PaddingWidth; - FDE_CSSLength m_Top; - FDE_CSSLength m_Bottom; - FDE_CSSLength m_Left; - FDE_CSSLength m_Right; - FX_FLOAT m_fVerticalAlign; - FDE_CSSDisplay m_eDisplay; - FDE_CSSVerticalAlign m_eVerticalAlign; - uint8_t m_dwTextDecoration; - bool m_bHasMargin; - bool m_bHasBorder; - bool m_bHasPadding; -}; - -class CFDE_CSSComputedStyle : public IFX_Retainable { - public: - CFDE_CSSComputedStyle(); - ~CFDE_CSSComputedStyle() override; - - // IFX_Retainable - uint32_t Retain() override; - uint32_t Release() override; - - int32_t CountFontFamilies() const; - const CFX_WideString GetFontFamily(int32_t index) const; - uint16_t GetFontWeight() const; - FDE_CSSFontVariant GetFontVariant() const; - FDE_CSSFontStyle GetFontStyle() const; - FX_FLOAT GetFontSize() const; - FX_ARGB GetColor() const; - void SetFontWeight(uint16_t wFontWeight); - void SetFontVariant(FDE_CSSFontVariant eFontVariant); - void SetFontStyle(FDE_CSSFontStyle eFontStyle); - void SetFontSize(FX_FLOAT fFontSize); - void SetColor(FX_ARGB dwFontColor); - - const FDE_CSSRect* GetBorderWidth() const; - const FDE_CSSRect* GetMarginWidth() const; - const FDE_CSSRect* GetPaddingWidth() const; - void SetMarginWidth(const FDE_CSSRect& rect); - void SetPaddingWidth(const FDE_CSSRect& rect); - - FDE_CSSDisplay GetDisplay() const; - - FX_FLOAT GetLineHeight() const; - const FDE_CSSLength& GetTextIndent() const; - FDE_CSSTextAlign GetTextAlign() const; - FDE_CSSVerticalAlign GetVerticalAlign() const; - FX_FLOAT GetNumberVerticalAlign() const; - uint32_t GetTextDecoration() const; - const FDE_CSSLength& GetLetterSpacing() const; - void SetLineHeight(FX_FLOAT fLineHeight); - void SetTextIndent(const FDE_CSSLength& textIndent); - void SetTextAlign(FDE_CSSTextAlign eTextAlign); - void SetNumberVerticalAlign(FX_FLOAT fAlign); - void SetTextDecoration(uint32_t dwTextDecoration); - void SetLetterSpacing(const FDE_CSSLength& letterSpacing); - void AddCustomStyle(const CFX_WideString& wsName, - const CFX_WideString& wsValue); - - bool GetCustomStyle(const CFX_WideStringC& wsName, - CFX_WideString& wsValue) const; - - CFDE_CSSInheritedData m_InheritedData; - CFDE_CSSNonInheritedData m_NonInheritedData; - - private: - uint32_t m_dwRefCount; - std::vector m_CustomProperties; -}; - -#endif // XFA_FDE_CSS_FDE_CSSSTYLESELECTOR_H_ diff --git a/xfa/fde/css/fde_cssstylesheet.cpp b/xfa/fde/css/fde_cssstylesheet.cpp deleted file mode 100644 index 5bbd9fd49e..0000000000 --- a/xfa/fde/css/fde_cssstylesheet.cpp +++ /dev/null @@ -1,484 +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 "xfa/fde/css/fde_cssstylesheet.h" - -#include - -#include "third_party/base/ptr_util.h" -#include "third_party/base/stl_util.h" -#include "xfa/fde/css/fde_cssdatatable.h" -#include "xfa/fde/css/fde_csssyntax.h" -#include "xfa/fgas/crt/fgas_codepage.h" - -namespace { - -bool IsCSSChar(FX_WCHAR wch) { - return (wch >= 'a' && wch <= 'z') || (wch >= 'A' && wch <= 'Z'); -} - -int32_t GetCSSPseudoLen(const FX_WCHAR* psz, const FX_WCHAR* pEnd) { - ASSERT(*psz == ':'); - const FX_WCHAR* pStart = psz; - while (psz < pEnd) { - FX_WCHAR wch = *psz; - if (IsCSSChar(wch) || wch == ':') - ++psz; - else - break; - } - return psz - pStart; -} - -int32_t GetCSSNameLen(const FX_WCHAR* psz, const FX_WCHAR* pEnd) { - const FX_WCHAR* pStart = psz; - while (psz < pEnd) { - FX_WCHAR wch = *psz; - if (IsCSSChar(wch) || (wch >= '0' && wch <= '9') || wch == '_' || - wch == '-') { - ++psz; - } else { - break; - } - } - return psz - pStart; -} - -} // namespace - -CFDE_CSSStyleSheet::CFDE_CSSStyleSheet() - : m_wRefCount(1), m_dwMediaList(FDE_CSSMEDIATYPE_ALL) { - ASSERT(m_dwMediaList > 0); -} - -CFDE_CSSStyleSheet::~CFDE_CSSStyleSheet() { - Reset(); -} - -void CFDE_CSSStyleSheet::Reset() { - m_RuleArray.clear(); - m_StringCache.clear(); -} - -uint32_t CFDE_CSSStyleSheet::Retain() { - return ++m_wRefCount; -} - -uint32_t CFDE_CSSStyleSheet::Release() { - uint32_t dwRefCount = --m_wRefCount; - if (dwRefCount == 0) - delete this; - return dwRefCount; -} - -uint32_t CFDE_CSSStyleSheet::GetMediaList() const { - return m_dwMediaList; -} - -int32_t CFDE_CSSStyleSheet::CountRules() const { - return pdfium::CollectionSize(m_RuleArray); -} - -CFDE_CSSRule* CFDE_CSSStyleSheet::GetRule(int32_t index) { - return m_RuleArray[index].get(); -} - -bool CFDE_CSSStyleSheet::LoadFromBuffer(const FX_WCHAR* pBuffer, - int32_t iBufSize) { - ASSERT(pBuffer && iBufSize > 0); - - auto pSyntax = pdfium::MakeUnique(); - return pSyntax->Init(pBuffer, iBufSize) && LoadFromSyntax(pSyntax.get()); -} - -bool CFDE_CSSStyleSheet::LoadFromSyntax(CFDE_CSSSyntaxParser* pSyntax) { - Reset(); - FDE_CSSSyntaxStatus eStatus; - do { - switch (eStatus = pSyntax->DoSyntaxParse()) { - case FDE_CSSSyntaxStatus::StyleRule: - eStatus = LoadStyleRule(pSyntax, &m_RuleArray); - break; - case FDE_CSSSyntaxStatus::MediaRule: - eStatus = LoadMediaRule(pSyntax); - break; - case FDE_CSSSyntaxStatus::FontFaceRule: - eStatus = LoadFontFaceRule(pSyntax, &m_RuleArray); - break; - case FDE_CSSSyntaxStatus::ImportRule: - eStatus = LoadImportRule(pSyntax); - break; - case FDE_CSSSyntaxStatus::PageRule: - eStatus = LoadPageRule(pSyntax); - break; - default: - break; - } - } while (eStatus >= FDE_CSSSyntaxStatus::None); - - m_StringCache.clear(); - return eStatus != FDE_CSSSyntaxStatus::Error; -} - -FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadMediaRule( - CFDE_CSSSyntaxParser* pSyntax) { - uint32_t dwMediaList = 0; - CFDE_CSSMediaRule* pMediaRule = nullptr; - for (;;) { - switch (pSyntax->DoSyntaxParse()) { - case FDE_CSSSyntaxStatus::MediaType: { - int32_t iLen; - const FX_WCHAR* psz = pSyntax->GetCurrentString(iLen); - const FDE_CSSMEDIATYPETABLE* pMediaType = - FDE_GetCSSMediaTypeByName(CFX_WideStringC(psz, iLen)); - if (pMediaType) - dwMediaList |= pMediaType->wValue; - } break; - case FDE_CSSSyntaxStatus::StyleRule: - if (pMediaRule) { - FDE_CSSSyntaxStatus eStatus = - LoadStyleRule(pSyntax, &pMediaRule->GetArray()); - if (eStatus < FDE_CSSSyntaxStatus::None) { - return eStatus; - } - } else { - SkipRuleSet(pSyntax); - } - break; - case FDE_CSSSyntaxStatus::DeclOpen: - if ((dwMediaList & m_dwMediaList) > 0 && !pMediaRule) { - m_RuleArray.push_back( - pdfium::MakeUnique(dwMediaList)); - pMediaRule = - static_cast(m_RuleArray.back().get()); - } - break; - case FDE_CSSSyntaxStatus::DeclClose: - return FDE_CSSSyntaxStatus::None; - case FDE_CSSSyntaxStatus::EOS: - return FDE_CSSSyntaxStatus::EOS; - case FDE_CSSSyntaxStatus::Error: - default: - return FDE_CSSSyntaxStatus::Error; - } - } -} - -FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadStyleRule( - CFDE_CSSSyntaxParser* pSyntax, - std::vector>* ruleArray) { - std::vector> selectors; - - CFDE_CSSStyleRule* pStyleRule = nullptr; - const FX_WCHAR* pszValue = nullptr; - int32_t iValueLen = 0; - FDE_CSSPropertyArgs propertyArgs; - propertyArgs.pStringCache = &m_StringCache; - propertyArgs.pProperty = nullptr; - CFX_WideString wsName; - for (;;) { - switch (pSyntax->DoSyntaxParse()) { - case FDE_CSSSyntaxStatus::Selector: { - pszValue = pSyntax->GetCurrentString(iValueLen); - auto pSelector = CFDE_CSSSelector::FromString(pszValue, iValueLen); - if (pSelector) - selectors.push_back(std::move(pSelector)); - break; - } - case FDE_CSSSyntaxStatus::PropertyName: - pszValue = pSyntax->GetCurrentString(iValueLen); - propertyArgs.pProperty = - FDE_GetCSSPropertyByName(CFX_WideStringC(pszValue, iValueLen)); - if (!propertyArgs.pProperty) - wsName = CFX_WideStringC(pszValue, iValueLen); - break; - case FDE_CSSSyntaxStatus::PropertyValue: - if (propertyArgs.pProperty) { - pszValue = pSyntax->GetCurrentString(iValueLen); - if (iValueLen > 0) { - pStyleRule->GetDeclaration()->AddProperty(&propertyArgs, pszValue, - iValueLen); - } - } else if (iValueLen > 0) { - pszValue = pSyntax->GetCurrentString(iValueLen); - if (iValueLen > 0) { - pStyleRule->GetDeclaration()->AddProperty( - &propertyArgs, wsName.c_str(), wsName.GetLength(), pszValue, - iValueLen); - } - } - break; - case FDE_CSSSyntaxStatus::DeclOpen: - if (!pStyleRule && !selectors.empty()) { - auto rule = pdfium::MakeUnique(); - pStyleRule = rule.get(); - pStyleRule->SetSelector(&selectors); - ruleArray->push_back(std::move(rule)); - } else { - SkipRuleSet(pSyntax); - return FDE_CSSSyntaxStatus::None; - } - break; - case FDE_CSSSyntaxStatus::DeclClose: - if (pStyleRule && pStyleRule->GetDeclaration()->empty()) { - ruleArray->pop_back(); - pStyleRule = nullptr; - } - return FDE_CSSSyntaxStatus::None; - case FDE_CSSSyntaxStatus::EOS: - return FDE_CSSSyntaxStatus::EOS; - case FDE_CSSSyntaxStatus::Error: - default: - return FDE_CSSSyntaxStatus::Error; - } - } -} - -FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadFontFaceRule( - CFDE_CSSSyntaxParser* pSyntax, - std::vector>* ruleArray) { - CFDE_CSSFontFaceRule* pFontFaceRule = nullptr; - const FX_WCHAR* pszValue = nullptr; - int32_t iValueLen = 0; - FDE_CSSPropertyArgs propertyArgs; - propertyArgs.pStringCache = &m_StringCache; - propertyArgs.pProperty = nullptr; - for (;;) { - switch (pSyntax->DoSyntaxParse()) { - case FDE_CSSSyntaxStatus::PropertyName: - pszValue = pSyntax->GetCurrentString(iValueLen); - propertyArgs.pProperty = - FDE_GetCSSPropertyByName(CFX_WideStringC(pszValue, iValueLen)); - break; - case FDE_CSSSyntaxStatus::PropertyValue: - if (propertyArgs.pProperty) { - pszValue = pSyntax->GetCurrentString(iValueLen); - if (iValueLen > 0) { - pFontFaceRule->GetDeclaration()->AddProperty(&propertyArgs, - pszValue, iValueLen); - } - } - break; - case FDE_CSSSyntaxStatus::DeclOpen: - if (!pFontFaceRule) { - auto rule = pdfium::MakeUnique(); - pFontFaceRule = rule.get(); - ruleArray->push_back(std::move(rule)); - } - break; - case FDE_CSSSyntaxStatus::DeclClose: - return FDE_CSSSyntaxStatus::None; - case FDE_CSSSyntaxStatus::EOS: - return FDE_CSSSyntaxStatus::EOS; - case FDE_CSSSyntaxStatus::Error: - default: - return FDE_CSSSyntaxStatus::Error; - } - } -} - -FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadImportRule( - CFDE_CSSSyntaxParser* pSyntax) { - for (;;) { - switch (pSyntax->DoSyntaxParse()) { - case FDE_CSSSyntaxStatus::ImportClose: - return FDE_CSSSyntaxStatus::None; - case FDE_CSSSyntaxStatus::URI: - break; - case FDE_CSSSyntaxStatus::EOS: - return FDE_CSSSyntaxStatus::EOS; - case FDE_CSSSyntaxStatus::Error: - default: - return FDE_CSSSyntaxStatus::Error; - } - } -} - -FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadPageRule( - CFDE_CSSSyntaxParser* pSyntax) { - return SkipRuleSet(pSyntax); -} - -FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::SkipRuleSet( - CFDE_CSSSyntaxParser* pSyntax) { - for (;;) { - switch (pSyntax->DoSyntaxParse()) { - case FDE_CSSSyntaxStatus::Selector: - case FDE_CSSSyntaxStatus::DeclOpen: - case FDE_CSSSyntaxStatus::PropertyName: - case FDE_CSSSyntaxStatus::PropertyValue: - break; - case FDE_CSSSyntaxStatus::DeclClose: - return FDE_CSSSyntaxStatus::None; - case FDE_CSSSyntaxStatus::EOS: - return FDE_CSSSyntaxStatus::EOS; - case FDE_CSSSyntaxStatus::Error: - default: - return FDE_CSSSyntaxStatus::Error; - } - } -} - -CFDE_CSSStyleRule::CFDE_CSSStyleRule() : CFDE_CSSRule(FDE_CSSRuleType::Style) {} - -CFDE_CSSStyleRule::~CFDE_CSSStyleRule() {} - -size_t CFDE_CSSStyleRule::CountSelectorLists() const { - return m_ppSelector.size(); -} - -CFDE_CSSSelector* CFDE_CSSStyleRule::GetSelectorList(int32_t index) const { - return m_ppSelector[index].get(); -} - -CFDE_CSSDeclaration* CFDE_CSSStyleRule::GetDeclaration() { - return &m_Declaration; -} - -void CFDE_CSSStyleRule::SetSelector( - std::vector>* list) { - ASSERT(m_ppSelector.empty()); - - m_ppSelector.swap(*list); -} - -CFDE_CSSMediaRule::CFDE_CSSMediaRule(uint32_t dwMediaList) - : CFDE_CSSRule(FDE_CSSRuleType::Media), m_dwMediaList(dwMediaList) {} - -CFDE_CSSMediaRule::~CFDE_CSSMediaRule() {} - -uint32_t CFDE_CSSMediaRule::GetMediaList() const { - return m_dwMediaList; -} - -int32_t CFDE_CSSMediaRule::CountRules() const { - return pdfium::CollectionSize(m_RuleArray); -} - -CFDE_CSSRule* CFDE_CSSMediaRule::GetRule(int32_t index) { - return m_RuleArray[index].get(); -} - -CFDE_CSSSelector::CFDE_CSSSelector(FDE_CSSSelectorType eType, - const FX_WCHAR* psz, - int32_t iLen, - bool bIgnoreCase) - : m_eType(eType), - m_dwHash(FX_HashCode_GetW(CFX_WideStringC(psz, iLen), bIgnoreCase)) {} - -CFDE_CSSSelector::~CFDE_CSSSelector() {} - -FDE_CSSSelectorType CFDE_CSSSelector::GetType() const { - return m_eType; -} - -uint32_t CFDE_CSSSelector::GetNameHash() const { - return m_dwHash; -} - -CFDE_CSSSelector* CFDE_CSSSelector::GetNextSelector() const { - return m_pNext.get(); -} - -std::unique_ptr CFDE_CSSSelector::ReleaseNextSelector() { - return std::move(m_pNext); -} - -std::unique_ptr CFDE_CSSSelector::FromString( - const FX_WCHAR* psz, - int32_t iLen) { - ASSERT(psz && iLen > 0); - - const FX_WCHAR* pStart = psz; - const FX_WCHAR* pEnd = psz + iLen; - for (; psz < pEnd; ++psz) { - switch (*psz) { - case '>': - case '[': - case '+': - return nullptr; - } - } - - std::unique_ptr pFirst = nullptr; - CFDE_CSSSelector* pLast = nullptr; - std::unique_ptr pPseudoFirst = nullptr; - CFDE_CSSSelector* pPseudoLast = nullptr; - - for (psz = pStart; psz < pEnd;) { - FX_WCHAR wch = *psz; - if (wch == '.' || wch == '#') { - if (psz == pStart || psz[-1] == ' ') { - auto p = pdfium::MakeUnique( - FDE_CSSSelectorType::Element, L"*", 1, true); - - if (pFirst) { - pFirst->SetType(FDE_CSSSelectorType::Descendant); - p->SetNext(std::move(pFirst)); - } - pFirst = std::move(p); - pLast = pFirst.get(); - } - ASSERT(pLast); - - int32_t iNameLen = GetCSSNameLen(++psz, pEnd); - if (iNameLen == 0) - return nullptr; - - FDE_CSSSelectorType eType = - wch == '.' ? FDE_CSSSelectorType::Class : FDE_CSSSelectorType::ID; - auto p = - pdfium::MakeUnique(eType, psz, iNameLen, false); - - p->SetNext(pLast->ReleaseNextSelector()); - pLast->SetNext(std::move(p)); - pLast = pLast->GetNextSelector(); - psz += iNameLen; - } else if (IsCSSChar(wch) || wch == '*') { - int32_t iNameLen = wch == '*' ? 1 : GetCSSNameLen(psz, pEnd); - if (iNameLen == 0) - return nullptr; - - auto p = pdfium::MakeUnique( - FDE_CSSSelectorType::Element, psz, iNameLen, true); - if (pFirst) { - pFirst->SetType(FDE_CSSSelectorType::Descendant); - p->SetNext(std::move(pFirst)); - } - pFirst = std::move(p); - pLast = pFirst.get(); - psz += iNameLen; - } else if (wch == ':') { - int32_t iNameLen = GetCSSPseudoLen(psz, pEnd); - if (iNameLen == 0) - return nullptr; - - auto p = pdfium::MakeUnique(FDE_CSSSelectorType::Pseudo, - psz, iNameLen, true); - CFDE_CSSSelector* ptr = p.get(); - if (pPseudoFirst) - pPseudoLast->SetNext(std::move(p)); - else - pPseudoFirst = std::move(p); - pPseudoLast = ptr; - psz += iNameLen; - } else if (wch == ' ') { - psz++; - } else { - return nullptr; - } - } - if (!pPseudoFirst) - return pFirst; - - pPseudoLast->SetNext(std::move(pFirst)); - return pPseudoFirst; -} - -CFDE_CSSFontFaceRule::CFDE_CSSFontFaceRule() - : CFDE_CSSRule(FDE_CSSRuleType::FontFace) {} - -CFDE_CSSFontFaceRule::~CFDE_CSSFontFaceRule() {} diff --git a/xfa/fde/css/fde_cssstylesheet.h b/xfa/fde/css/fde_cssstylesheet.h deleted file mode 100644 index aa05a9dda1..0000000000 --- a/xfa/fde/css/fde_cssstylesheet.h +++ /dev/null @@ -1,127 +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 XFA_FDE_CSS_FDE_CSSSTYLESHEET_H_ -#define XFA_FDE_CSS_FDE_CSSSTYLESHEET_H_ - -#include -#include -#include -#include - -#include "core/fxcrt/fx_ext.h" -#include "xfa/fde/css/cfde_cssrule.h" -#include "xfa/fde/css/fde_cssdeclaration.h" - -class CFDE_CSSSyntaxParser; - -class CFDE_CSSSelector { - public: - static std::unique_ptr FromString(const FX_WCHAR* psz, - int32_t iLen); - - CFDE_CSSSelector(FDE_CSSSelectorType eType, - const FX_WCHAR* psz, - int32_t iLen, - bool bIgnoreCase); - ~CFDE_CSSSelector(); - - FDE_CSSSelectorType GetType() const; - uint32_t GetNameHash() const; - CFDE_CSSSelector* GetNextSelector() const; - std::unique_ptr ReleaseNextSelector(); - - void SetNext(std::unique_ptr pNext) { - m_pNext = std::move(pNext); - } - - protected: - void SetType(FDE_CSSSelectorType eType) { m_eType = eType; } - - FDE_CSSSelectorType m_eType; - uint32_t m_dwHash; - std::unique_ptr m_pNext; -}; - -class CFDE_CSSStyleRule : public CFDE_CSSRule { - public: - CFDE_CSSStyleRule(); - ~CFDE_CSSStyleRule() override; - - size_t CountSelectorLists() const; - CFDE_CSSSelector* GetSelectorList(int32_t index) const; - CFDE_CSSDeclaration* GetDeclaration(); - - void SetSelector(std::vector>* list); - - private: - CFDE_CSSDeclaration m_Declaration; - std::vector> m_ppSelector; -}; - -class CFDE_CSSMediaRule : public CFDE_CSSRule { - public: - explicit CFDE_CSSMediaRule(uint32_t dwMediaList); - ~CFDE_CSSMediaRule() override; - - uint32_t GetMediaList() const; - int32_t CountRules() const; - CFDE_CSSRule* GetRule(int32_t index); - - std::vector>& GetArray() { return m_RuleArray; } - - protected: - uint32_t m_dwMediaList; - std::vector> m_RuleArray; -}; - -class CFDE_CSSFontFaceRule : public CFDE_CSSRule { - public: - CFDE_CSSFontFaceRule(); - ~CFDE_CSSFontFaceRule() override; - - CFDE_CSSDeclaration* GetDeclaration() { return &m_Declaration; } - - private: - CFDE_CSSDeclaration m_Declaration; -}; - -class CFDE_CSSStyleSheet : public IFX_Retainable { - public: - CFDE_CSSStyleSheet(); - ~CFDE_CSSStyleSheet() override; - - // IFX_Retainable: - uint32_t Retain() override; - uint32_t Release() override; - - bool LoadFromBuffer(const FX_WCHAR* pBuffer, int32_t iBufSize); - - uint32_t GetMediaList() const; - int32_t CountRules() const; - CFDE_CSSRule* GetRule(int32_t index); - - private: - void Reset(); - bool LoadFromSyntax(CFDE_CSSSyntaxParser* pSyntax); - FDE_CSSSyntaxStatus LoadStyleRule( - CFDE_CSSSyntaxParser* pSyntax, - std::vector>* ruleArray); - FDE_CSSSyntaxStatus LoadImportRule(CFDE_CSSSyntaxParser* pSyntax); - FDE_CSSSyntaxStatus LoadPageRule(CFDE_CSSSyntaxParser* pSyntax); - FDE_CSSSyntaxStatus LoadMediaRule(CFDE_CSSSyntaxParser* pSyntax); - FDE_CSSSyntaxStatus LoadFontFaceRule( - CFDE_CSSSyntaxParser* pSyntax, - std::vector>* ruleArray); - FDE_CSSSyntaxStatus SkipRuleSet(CFDE_CSSSyntaxParser* pSyntax); - - uint16_t m_wRefCount; - uint32_t m_dwMediaList; - std::vector> m_RuleArray; - std::unordered_map m_StringCache; -}; - -#endif // XFA_FDE_CSS_FDE_CSSSTYLESHEET_H_ diff --git a/xfa/fde/css/fde_csssyntax.cpp b/xfa/fde/css/fde_csssyntax.cpp deleted file mode 100644 index ef3f8d89a2..0000000000 --- a/xfa/fde/css/fde_csssyntax.cpp +++ /dev/null @@ -1,442 +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 "xfa/fde/css/fde_csssyntax.h" - -#include - -#include "xfa/fde/css/fde_cssdatatable.h" -#include "xfa/fgas/crt/fgas_codepage.h" - -namespace { - -bool FDE_IsSelectorStart(FX_WCHAR wch) { - return wch == '.' || wch == '#' || wch == '*' || (wch >= 'a' && wch <= 'z') || - (wch >= 'A' && wch <= 'Z'); -} - -} // namespace - -CFDE_CSSSyntaxParser::CFDE_CSSSyntaxParser() - : m_iTextDatLen(0), - m_dwCheck((uint32_t)-1), - m_eMode(FDE_CSSSyntaxMode::RuleSet), - m_eStatus(FDE_CSSSyntaxStatus::None) {} - -CFDE_CSSSyntaxParser::~CFDE_CSSSyntaxParser() { - m_TextData.Reset(); - m_TextPlane.Reset(); -} - -bool CFDE_CSSSyntaxParser::Init(const FX_WCHAR* pBuffer, - int32_t iBufferSize, - int32_t iTextDatSize, - bool bOnlyDeclaration) { - ASSERT(pBuffer && iBufferSize > 0 && iTextDatSize > 0); - Reset(bOnlyDeclaration); - if (!m_TextData.EstimateSize(iTextDatSize)) - return false; - return m_TextPlane.AttachBuffer(pBuffer, iBufferSize); -} - -void CFDE_CSSSyntaxParser::Reset(bool bOnlyDeclaration) { - m_TextPlane.Reset(); - m_TextData.Reset(); - m_iTextDatLen = 0; - m_dwCheck = (uint32_t)-1; - m_eStatus = FDE_CSSSyntaxStatus::None; - m_eMode = bOnlyDeclaration ? FDE_CSSSyntaxMode::PropertyName - : FDE_CSSSyntaxMode::RuleSet; -} - -FDE_CSSSyntaxStatus CFDE_CSSSyntaxParser::DoSyntaxParse() { - while (m_eStatus >= FDE_CSSSyntaxStatus::None) { - if (m_TextPlane.IsEOF()) { - if (m_eMode == FDE_CSSSyntaxMode::PropertyValue && - m_TextData.GetLength() > 0) { - SaveTextData(); - m_eStatus = FDE_CSSSyntaxStatus::PropertyValue; - return m_eStatus; - } - m_eStatus = FDE_CSSSyntaxStatus::EOS; - return m_eStatus; - } - FX_WCHAR wch; - while (!m_TextPlane.IsEOF()) { - wch = m_TextPlane.GetChar(); - switch (m_eMode) { - case FDE_CSSSyntaxMode::RuleSet: - switch (wch) { - case '@': - m_TextPlane.MoveNext(); - SwitchMode(FDE_CSSSyntaxMode::AtRule); - break; - case '}': - m_TextPlane.MoveNext(); - if (RestoreMode()) - return FDE_CSSSyntaxStatus::DeclClose; - - m_eStatus = FDE_CSSSyntaxStatus::Error; - return m_eStatus; - case '/': - if (m_TextPlane.GetNextChar() == '*') { - m_ModeStack.push(m_eMode); - SwitchMode(FDE_CSSSyntaxMode::Comment); - break; - } - default: - if (wch <= ' ') { - m_TextPlane.MoveNext(); - } else if (FDE_IsSelectorStart(wch)) { - SwitchMode(FDE_CSSSyntaxMode::Selector); - return FDE_CSSSyntaxStatus::StyleRule; - } else { - m_eStatus = FDE_CSSSyntaxStatus::Error; - return m_eStatus; - } - break; - } - break; - case FDE_CSSSyntaxMode::Selector: - switch (wch) { - case ',': - m_TextPlane.MoveNext(); - SwitchMode(FDE_CSSSyntaxMode::Selector); - if (m_iTextDatLen > 0) - return FDE_CSSSyntaxStatus::Selector; - break; - case '{': - if (m_TextData.GetLength() > 0) { - SaveTextData(); - return FDE_CSSSyntaxStatus::Selector; - } - m_TextPlane.MoveNext(); - m_ModeStack.push(FDE_CSSSyntaxMode::RuleSet); - SwitchMode(FDE_CSSSyntaxMode::PropertyName); - return FDE_CSSSyntaxStatus::DeclOpen; - case '/': - if (m_TextPlane.GetNextChar() == '*') { - if (SwitchToComment() > 0) - return FDE_CSSSyntaxStatus::Selector; - break; - } - default: - AppendChar(wch); - break; - } - break; - case FDE_CSSSyntaxMode::PropertyName: - switch (wch) { - case ':': - m_TextPlane.MoveNext(); - SwitchMode(FDE_CSSSyntaxMode::PropertyValue); - return FDE_CSSSyntaxStatus::PropertyName; - case '}': - m_TextPlane.MoveNext(); - if (RestoreMode()) - return FDE_CSSSyntaxStatus::DeclClose; - - m_eStatus = FDE_CSSSyntaxStatus::Error; - return m_eStatus; - case '/': - if (m_TextPlane.GetNextChar() == '*') { - if (SwitchToComment() > 0) - return FDE_CSSSyntaxStatus::PropertyName; - break; - } - default: - AppendChar(wch); - break; - } - break; - case FDE_CSSSyntaxMode::PropertyValue: - switch (wch) { - case ';': - m_TextPlane.MoveNext(); - case '}': - SwitchMode(FDE_CSSSyntaxMode::PropertyName); - return FDE_CSSSyntaxStatus::PropertyValue; - case '/': - if (m_TextPlane.GetNextChar() == '*') { - if (SwitchToComment() > 0) - return FDE_CSSSyntaxStatus::PropertyValue; - break; - } - default: - AppendChar(wch); - break; - } - break; - case FDE_CSSSyntaxMode::Comment: - if (wch == '/' && m_TextData.GetLength() > 0 && - m_TextData.GetAt(m_TextData.GetLength() - 1) == '*') { - RestoreMode(); - } else { - m_TextData.AppendChar(wch); - } - m_TextPlane.MoveNext(); - break; - case FDE_CSSSyntaxMode::MediaType: - switch (wch) { - case ',': - m_TextPlane.MoveNext(); - SwitchMode(FDE_CSSSyntaxMode::MediaType); - if (m_iTextDatLen > 0) - return FDE_CSSSyntaxStatus::MediaType; - break; - case '{': { - if (m_ModeStack.empty() || - m_ModeStack.top() != FDE_CSSSyntaxMode::MediaRule) { - m_eStatus = FDE_CSSSyntaxStatus::Error; - return m_eStatus; - } - - if (m_TextData.GetLength() > 0) { - SaveTextData(); - return FDE_CSSSyntaxStatus::MediaType; - } - m_TextPlane.MoveNext(); - - // Replace the MediaRule with a RuleSet rule. - m_ModeStack.top() = FDE_CSSSyntaxMode::RuleSet; - - SwitchMode(FDE_CSSSyntaxMode::RuleSet); - return FDE_CSSSyntaxStatus::DeclOpen; - } - case ';': { - if (m_ModeStack.empty() || - m_ModeStack.top() != FDE_CSSSyntaxMode::Import) { - m_eStatus = FDE_CSSSyntaxStatus::Error; - return m_eStatus; - } - - if (m_TextData.GetLength() > 0) { - SaveTextData(); - if (IsImportEnabled()) - return FDE_CSSSyntaxStatus::MediaType; - } else { - bool bEnabled = IsImportEnabled(); - m_TextPlane.MoveNext(); - m_ModeStack.pop(); - SwitchMode(FDE_CSSSyntaxMode::RuleSet); - if (bEnabled) { - DisableImport(); - return FDE_CSSSyntaxStatus::ImportClose; - } - } - } break; - case '/': - if (m_TextPlane.GetNextChar() == '*') { - if (SwitchToComment() > 0) - return FDE_CSSSyntaxStatus::MediaType; - break; - } - default: - AppendChar(wch); - break; - } - break; - case FDE_CSSSyntaxMode::URI: { - if (m_ModeStack.empty() || - m_ModeStack.top() != FDE_CSSSyntaxMode::Import) { - m_eStatus = FDE_CSSSyntaxStatus::Error; - return m_eStatus; - } - - if (wch <= ' ' || wch == ';') { - int32_t iURIStart, iURILength = m_TextData.GetLength(); - if (iURILength > 0 && FDE_ParseCSSURI(m_TextData.GetBuffer(), - &iURIStart, &iURILength)) { - m_TextData.Subtract(iURIStart, iURILength); - SwitchMode(FDE_CSSSyntaxMode::MediaType); - if (IsImportEnabled()) - return FDE_CSSSyntaxStatus::URI; - break; - } - } - AppendChar(wch); - } break; - case FDE_CSSSyntaxMode::AtRule: - if (wch > ' ') { - AppendChar(wch); - } else { - int32_t iLen = m_TextData.GetLength(); - const FX_WCHAR* psz = m_TextData.GetBuffer(); - if (FXSYS_wcsncmp(L"charset", psz, iLen) == 0) { - SwitchMode(FDE_CSSSyntaxMode::Charset); - } else if (FXSYS_wcsncmp(L"import", psz, iLen) == 0) { - m_ModeStack.push(FDE_CSSSyntaxMode::Import); - SwitchMode(FDE_CSSSyntaxMode::URI); - if (IsImportEnabled()) - return FDE_CSSSyntaxStatus::ImportRule; - break; - } else if (FXSYS_wcsncmp(L"media", psz, iLen) == 0) { - m_ModeStack.push(FDE_CSSSyntaxMode::MediaRule); - SwitchMode(FDE_CSSSyntaxMode::MediaType); - return FDE_CSSSyntaxStatus::MediaRule; - } else if (FXSYS_wcsncmp(L"font-face", psz, iLen) == 0) { - SwitchMode(FDE_CSSSyntaxMode::Selector); - return FDE_CSSSyntaxStatus::FontFaceRule; - } else if (FXSYS_wcsncmp(L"page", psz, iLen) == 0) { - SwitchMode(FDE_CSSSyntaxMode::Selector); - return FDE_CSSSyntaxStatus::PageRule; - } else { - SwitchMode(FDE_CSSSyntaxMode::UnknownRule); - } - } - break; - case FDE_CSSSyntaxMode::Charset: - if (wch == ';') { - m_TextPlane.MoveNext(); - SwitchMode(FDE_CSSSyntaxMode::RuleSet); - if (IsCharsetEnabled()) { - DisableCharset(); - if (m_iTextDatLen > 0) - return FDE_CSSSyntaxStatus::Charset; - } - } else { - AppendChar(wch); - } - break; - case FDE_CSSSyntaxMode::UnknownRule: - if (wch == ';') - SwitchMode(FDE_CSSSyntaxMode::RuleSet); - m_TextPlane.MoveNext(); - break; - default: - ASSERT(false); - break; - } - } - } - return m_eStatus; -} - -bool CFDE_CSSSyntaxParser::IsImportEnabled() const { - if ((m_dwCheck & FDE_CSSSYNTAXCHECK_AllowImport) == 0) - return false; - if (m_ModeStack.size() > 1) - return false; - return true; -} - -bool CFDE_CSSSyntaxParser::AppendChar(FX_WCHAR wch) { - m_TextPlane.MoveNext(); - if (m_TextData.GetLength() > 0 || wch > ' ') { - m_TextData.AppendChar(wch); - return true; - } - return false; -} - -int32_t CFDE_CSSSyntaxParser::SaveTextData() { - m_iTextDatLen = m_TextData.TrimEnd(); - m_TextData.Clear(); - return m_iTextDatLen; -} - -void CFDE_CSSSyntaxParser::SwitchMode(FDE_CSSSyntaxMode eMode) { - m_eMode = eMode; - SaveTextData(); -} - -int32_t CFDE_CSSSyntaxParser::SwitchToComment() { - int32_t iLength = m_TextData.GetLength(); - m_ModeStack.push(m_eMode); - SwitchMode(FDE_CSSSyntaxMode::Comment); - return iLength; -} - -bool CFDE_CSSSyntaxParser::RestoreMode() { - if (m_ModeStack.empty()) - return false; - - SwitchMode(m_ModeStack.top()); - m_ModeStack.pop(); - return true; -} - -const FX_WCHAR* CFDE_CSSSyntaxParser::GetCurrentString(int32_t& iLength) const { - iLength = m_iTextDatLen; - return m_TextData.GetBuffer(); -} - -CFDE_CSSTextBuf::CFDE_CSSTextBuf() - : m_bExtBuf(false), - m_pBuffer(nullptr), - m_iBufLen(0), - m_iDatLen(0), - m_iDatPos(0) {} - -CFDE_CSSTextBuf::~CFDE_CSSTextBuf() { - Reset(); -} - -void CFDE_CSSTextBuf::Reset() { - if (!m_bExtBuf) { - FX_Free(m_pBuffer); - m_pBuffer = nullptr; - } - m_iDatPos = m_iDatLen = m_iBufLen; -} - -bool CFDE_CSSTextBuf::AttachBuffer(const FX_WCHAR* pBuffer, int32_t iBufLen) { - Reset(); - m_pBuffer = const_cast(pBuffer); - m_iDatLen = m_iBufLen = iBufLen; - return m_bExtBuf = true; -} - -bool CFDE_CSSTextBuf::EstimateSize(int32_t iAllocSize) { - ASSERT(iAllocSize > 0); - Clear(); - m_bExtBuf = false; - return ExpandBuf(iAllocSize); -} - -int32_t CFDE_CSSTextBuf::LoadFromStream( - const CFX_RetainPtr& pTxtStream, - int32_t iStreamOffset, - int32_t iMaxChars, - bool& bEOS) { - ASSERT(iStreamOffset >= 0 && iMaxChars > 0); - Clear(); - m_bExtBuf = false; - if (!ExpandBuf(iMaxChars)) - return 0; - - if (pTxtStream->GetPosition() != iStreamOffset) - pTxtStream->Seek(FX_STREAMSEEK_Begin, iStreamOffset); - - m_iDatLen = pTxtStream->ReadString(m_pBuffer, iMaxChars, bEOS); - return m_iDatLen; -} - -bool CFDE_CSSTextBuf::ExpandBuf(int32_t iDesiredSize) { - if (m_bExtBuf) - return false; - if (!m_pBuffer) - m_pBuffer = FX_Alloc(FX_WCHAR, iDesiredSize); - else if (m_iBufLen != iDesiredSize) - m_pBuffer = FX_Realloc(FX_WCHAR, m_pBuffer, iDesiredSize); - else - return true; - - if (!m_pBuffer) { - m_iBufLen = 0; - return false; - } - m_iBufLen = iDesiredSize; - return true; -} - -void CFDE_CSSTextBuf::Subtract(int32_t iStart, int32_t iLength) { - ASSERT(iStart >= 0 && iLength >= 0); - - iLength = std::max(std::min(iLength, m_iDatLen - iStart), 0); - FXSYS_memmove(m_pBuffer, m_pBuffer + iStart, iLength * sizeof(FX_WCHAR)); - m_iDatLen = iLength; -} diff --git a/xfa/fde/css/fde_csssyntax.h b/xfa/fde/css/fde_csssyntax.h deleted file mode 100644 index 81475cb58a..0000000000 --- a/xfa/fde/css/fde_csssyntax.h +++ /dev/null @@ -1,122 +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 XFA_FDE_CSS_FDE_CSSSYNTAX_H_ -#define XFA_FDE_CSS_FDE_CSSSYNTAX_H_ - -#include - -#include "core/fxcrt/cfx_retain_ptr.h" -#include "xfa/fde/css/fde_css.h" -#include "xfa/fgas/crt/fgas_stream.h" - -class CFDE_CSSTextBuf { - public: - CFDE_CSSTextBuf(); - ~CFDE_CSSTextBuf(); - - bool AttachBuffer(const FX_WCHAR* pBuffer, int32_t iBufLen); - bool EstimateSize(int32_t iAllocSize); - int32_t LoadFromStream(const CFX_RetainPtr& pTxtStream, - int32_t iStreamOffset, - int32_t iMaxChars, - bool& bEOS); - bool AppendChar(FX_WCHAR wch) { - if (m_iDatLen >= m_iBufLen && !ExpandBuf(m_iBufLen * 2)) - return false; - m_pBuffer[m_iDatLen++] = wch; - return true; - } - - void Clear() { m_iDatPos = m_iDatLen = 0; } - void Reset(); - - int32_t TrimEnd() { - while (m_iDatLen > 0 && m_pBuffer[m_iDatLen - 1] <= ' ') { - --m_iDatLen; - } - AppendChar(0); - return --m_iDatLen; - } - - void Subtract(int32_t iStart, int32_t iLength); - bool IsEOF() const { return m_iDatPos >= m_iDatLen; } - - FX_WCHAR GetAt(int32_t index) const { return m_pBuffer[index]; } - FX_WCHAR GetChar() const { return m_pBuffer[m_iDatPos]; } - FX_WCHAR GetNextChar() const { - return (m_iDatPos + 1 >= m_iDatLen) ? 0 : m_pBuffer[m_iDatPos + 1]; - } - - void MoveNext() { m_iDatPos++; } - - int32_t GetLength() const { return m_iDatLen; } - const FX_WCHAR* GetBuffer() const { return m_pBuffer; } - - protected: - bool ExpandBuf(int32_t iDesiredSize); - bool m_bExtBuf; - FX_WCHAR* m_pBuffer; - int32_t m_iBufLen; - int32_t m_iDatLen; - int32_t m_iDatPos; -}; - -#define FDE_CSSSYNTAXCHECK_AllowCharset 1 -#define FDE_CSSSYNTAXCHECK_AllowImport 2 - -enum class FDE_CSSSyntaxMode { - RuleSet, - Comment, - AtRule, - UnknownRule, - Charset, - Import, - MediaRule, - URI, - MediaType, - Selector, - PropertyName, - PropertyValue, -}; - -class CFDE_CSSSyntaxParser { - public: - CFDE_CSSSyntaxParser(); - ~CFDE_CSSSyntaxParser(); - - bool Init(const FX_WCHAR* pBuffer, - int32_t iBufferSize, - int32_t iTextDatSize = 32, - bool bOnlyDeclaration = false); - FDE_CSSSyntaxStatus DoSyntaxParse(); - const FX_WCHAR* GetCurrentString(int32_t& iLength) const; - - protected: - void Reset(bool bOnlyDeclaration); - void SwitchMode(FDE_CSSSyntaxMode eMode); - int32_t SwitchToComment(); - - bool RestoreMode(); - bool AppendChar(FX_WCHAR wch); - int32_t SaveTextData(); - bool IsCharsetEnabled() const { - return (m_dwCheck & FDE_CSSSYNTAXCHECK_AllowCharset) != 0; - } - void DisableCharset() { m_dwCheck = FDE_CSSSYNTAXCHECK_AllowImport; } - bool IsImportEnabled() const; - void DisableImport() { m_dwCheck = 0; } - - CFDE_CSSTextBuf m_TextData; - CFDE_CSSTextBuf m_TextPlane; - int32_t m_iTextDatLen; - uint32_t m_dwCheck; - FDE_CSSSyntaxMode m_eMode; - FDE_CSSSyntaxStatus m_eStatus; - std::stack m_ModeStack; -}; - -#endif // XFA_FDE_CSS_FDE_CSSSYNTAX_H_ diff --git a/xfa/fxfa/app/cxfa_textlayout.cpp b/xfa/fxfa/app/cxfa_textlayout.cpp index d831b600dc..788fea2e7d 100644 --- a/xfa/fxfa/app/cxfa_textlayout.cpp +++ b/xfa/fxfa/app/cxfa_textlayout.cpp @@ -12,7 +12,8 @@ #include "third_party/base/ptr_util.h" #include "third_party/base/stl_util.h" #include "xfa/fde/cfde_path.h" -#include "xfa/fde/css/fde_cssstyleselector.h" +#include "xfa/fde/css/cfde_csscomputedstyle.h" +#include "xfa/fde/css/cfde_cssstyleselector.h" #include "xfa/fde/fde_gedevice.h" #include "xfa/fde/fde_object.h" #include "xfa/fde/xml/fde_xml_imp.h" diff --git a/xfa/fxfa/app/cxfa_textparsecontext.cpp b/xfa/fxfa/app/cxfa_textparsecontext.cpp index e416242309..c0c226c4ac 100644 --- a/xfa/fxfa/app/cxfa_textparsecontext.cpp +++ b/xfa/fxfa/app/cxfa_textparsecontext.cpp @@ -6,8 +6,9 @@ #include "xfa/fxfa/app/cxfa_textparsecontext.h" -#include "xfa/fde/css/fde_cssdeclaration.h" -#include "xfa/fde/css/fde_cssstyleselector.h" +#include "xfa/fde/css/cfde_csscomputedstyle.h" +#include "xfa/fde/css/cfde_cssdeclaration.h" +#include "xfa/fde/css/cfde_cssstyleselector.h" CXFA_TextParseContext::CXFA_TextParseContext() : m_pParentStyle(nullptr), diff --git a/xfa/fxfa/app/cxfa_textparser.cpp b/xfa/fxfa/app/cxfa_textparser.cpp index 1f8036937e..9920f6e723 100644 --- a/xfa/fxfa/app/cxfa_textparser.cpp +++ b/xfa/fxfa/app/cxfa_textparser.cpp @@ -9,9 +9,11 @@ #include #include "third_party/base/ptr_util.h" +#include "xfa/fde/css/cfde_cssaccelerator.h" +#include "xfa/fde/css/cfde_csscomputedstyle.h" +#include "xfa/fde/css/cfde_cssstyleselector.h" +#include "xfa/fde/css/cfde_cssstylesheet.h" #include "xfa/fde/css/fde_css.h" -#include "xfa/fde/css/fde_cssstyleselector.h" -#include "xfa/fde/css/fde_cssstylesheet.h" #include "xfa/fgas/crt/fgas_codepage.h" #include "xfa/fgas/font/cfgas_fontmgr.h" #include "xfa/fxfa/app/cxfa_csstagprovider.h" diff --git a/xfa/fxfa/app/cxfa_textuserdata.cpp b/xfa/fxfa/app/cxfa_textuserdata.cpp index 7087810f4d..4fdabd6bb3 100644 --- a/xfa/fxfa/app/cxfa_textuserdata.cpp +++ b/xfa/fxfa/app/cxfa_textuserdata.cpp @@ -6,8 +6,9 @@ #include "xfa/fxfa/app/cxfa_textuserdata.h" +#include "xfa/fde/css/cfde_csscomputedstyle.h" +#include "xfa/fde/css/cfde_cssstyleselector.h" #include "xfa/fde/css/fde_css.h" -#include "xfa/fde/css/fde_cssstyleselector.h" #include "xfa/fxfa/app/cxfa_linkuserdata.h" CXFA_TextUserData::CXFA_TextUserData(CFDE_CSSComputedStyle* pStyle) diff --git a/xfa/fxfa/parser/cxfa_scriptcontext.cpp b/xfa/fxfa/parser/cxfa_scriptcontext.cpp index b33d4efda4..44ae9a4e5a 100644 --- a/xfa/fxfa/parser/cxfa_scriptcontext.cpp +++ b/xfa/fxfa/parser/cxfa_scriptcontext.cpp @@ -9,10 +9,10 @@ #include #include "core/fxcrt/fx_ext.h" -#include "third_party/base/ptr_util.h" #include "fxjs/cfxjse_arguments.h" #include "fxjs/cfxjse_class.h" #include "fxjs/cfxjse_value.h" +#include "third_party/base/ptr_util.h" #include "xfa/fxfa/app/xfa_ffnotify.h" #include "xfa/fxfa/cxfa_eventparam.h" #include "xfa/fxfa/parser/cxfa_document.h" -- cgit v1.2.3