You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
602 lines
22 KiB
602 lines
22 KiB
// 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 <algorithm> |
|
#include <utility> |
|
|
|
#include "third_party/base/ptr_util.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_cssstylesheet.h" |
|
#include "xfa/fde/css/cfde_csssyntaxparser.h" |
|
#include "xfa/fde/css/cfde_cssvaluelist.h" |
|
#include "xfa/fxfa/app/cxfa_csstagprovider.h" |
|
|
|
CFDE_CSSStyleSelector::CFDE_CSSStyleSelector(CFGAS_FontMgr* pFontMgr) |
|
: m_pFontMgr(pFontMgr), m_fDefFontSize(12.0f) {} |
|
|
|
CFDE_CSSStyleSelector::~CFDE_CSSStyleSelector() {} |
|
|
|
void CFDE_CSSStyleSelector::SetDefFontSize(FX_FLOAT fFontSize) { |
|
ASSERT(fFontSize > 0); |
|
m_fDefFontSize = fFontSize; |
|
} |
|
|
|
CFX_RetainPtr<CFDE_CSSComputedStyle> CFDE_CSSStyleSelector::CreateComputedStyle( |
|
CFDE_CSSComputedStyle* pParentStyle) { |
|
auto pStyle = pdfium::MakeRetain<CFDE_CSSComputedStyle>(); |
|
if (pParentStyle) |
|
pStyle->m_InheritedData = pParentStyle->m_InheritedData; |
|
return pStyle; |
|
} |
|
|
|
void CFDE_CSSStyleSelector::SetUAStyleSheet( |
|
std::unique_ptr<CFDE_CSSStyleSheet> pSheet) { |
|
m_UAStyles = std::move(pSheet); |
|
} |
|
|
|
void CFDE_CSSStyleSelector::UpdateStyleIndex() { |
|
m_UARules.Clear(); |
|
m_UARules.AddRulesFrom(m_UAStyles.get(), m_pFontMgr); |
|
} |
|
|
|
std::vector<const CFDE_CSSDeclaration*> |
|
CFDE_CSSStyleSelector::MatchDeclarations(const CFX_WideString& tagname) { |
|
std::vector<const CFDE_CSSDeclaration*> matchedDecls; |
|
if (m_UARules.CountSelectors() == 0 || tagname.IsEmpty()) |
|
return matchedDecls; |
|
|
|
auto rules = m_UARules.GetTagRuleData(tagname); |
|
if (!rules) |
|
return matchedDecls; |
|
|
|
for (const auto& d : *rules) { |
|
if (MatchSelector(tagname, d->pSelector)) |
|
matchedDecls.push_back(d->pDeclaration); |
|
} |
|
return matchedDecls; |
|
} |
|
|
|
bool CFDE_CSSStyleSelector::MatchSelector(const CFX_WideString& tagname, |
|
CFDE_CSSSelector* pSel) { |
|
// TODO(dsinclair): The code only supports a single level of selector at this |
|
// point. None of the code using selectors required the complexity so lets |
|
// just say we don't support them to simplify the code for now. |
|
if (!pSel || pSel->GetNextSelector() || |
|
pSel->GetType() == FDE_CSSSelectorType::Descendant) { |
|
return false; |
|
} |
|
return pSel->GetNameHash() == FX_HashCode_GetW(tagname.c_str(), true); |
|
} |
|
|
|
void CFDE_CSSStyleSelector::ComputeStyle( |
|
const std::vector<const CFDE_CSSDeclaration*>& declArray, |
|
const CFX_WideString& styleString, |
|
const CFX_WideString& alignString, |
|
CFDE_CSSComputedStyle* pDest) { |
|
std::unique_ptr<CFDE_CSSDeclaration> pDecl; |
|
if (!styleString.IsEmpty() || !alignString.IsEmpty()) { |
|
pDecl = pdfium::MakeUnique<CFDE_CSSDeclaration>(); |
|
|
|
if (!styleString.IsEmpty()) |
|
AppendInlineStyle(pDecl.get(), styleString); |
|
if (!alignString.IsEmpty()) { |
|
pDecl->AddProperty(FDE_GetCSSPropertyByEnum(FDE_CSSProperty::TextAlign), |
|
alignString.AsStringC()); |
|
} |
|
} |
|
ApplyDeclarations(declArray, pDecl.get(), pDest); |
|
} |
|
|
|
void CFDE_CSSStyleSelector::ApplyDeclarations( |
|
const std::vector<const CFDE_CSSDeclaration*>& declArray, |
|
const CFDE_CSSDeclaration* extraDecl, |
|
CFDE_CSSComputedStyle* pComputedStyle) { |
|
std::vector<const CFDE_CSSPropertyHolder*> importants; |
|
std::vector<const CFDE_CSSPropertyHolder*> normals; |
|
std::vector<const CFDE_CSSCustomProperty*> customs; |
|
|
|
for (auto& decl : declArray) |
|
ExtractValues(decl, &importants, &normals, &customs); |
|
|
|
if (extraDecl) |
|
ExtractValues(extraDecl, &importants, &normals, &customs); |
|
|
|
for (auto& prop : normals) |
|
ApplyProperty(prop->eProperty, prop->pValue, pComputedStyle); |
|
|
|
for (auto& prop : customs) |
|
pComputedStyle->AddCustomStyle(*prop); |
|
|
|
for (auto& prop : importants) |
|
ApplyProperty(prop->eProperty, prop->pValue, pComputedStyle); |
|
} |
|
|
|
void CFDE_CSSStyleSelector::ExtractValues( |
|
const CFDE_CSSDeclaration* decl, |
|
std::vector<const CFDE_CSSPropertyHolder*>* importants, |
|
std::vector<const CFDE_CSSPropertyHolder*>* normals, |
|
std::vector<const CFDE_CSSCustomProperty*>* custom) { |
|
for (const auto& holder : *decl) { |
|
if (holder->bImportant) |
|
importants->push_back(holder.get()); |
|
else |
|
normals->push_back(holder.get()); |
|
} |
|
for (auto it = decl->custom_begin(); it != decl->custom_end(); it++) |
|
custom->push_back(it->get()); |
|
} |
|
|
|
void CFDE_CSSStyleSelector::AppendInlineStyle(CFDE_CSSDeclaration* pDecl, |
|
const CFX_WideString& style) { |
|
ASSERT(pDecl && !style.IsEmpty()); |
|
|
|
auto pSyntax = pdfium::MakeUnique<CFDE_CSSSyntaxParser>(); |
|
if (!pSyntax->Init(style.c_str(), style.GetLength(), 32, true)) |
|
return; |
|
|
|
int32_t iLen2 = 0; |
|
const FDE_CSSPropertyTable* table = nullptr; |
|
CFX_WideString wsName; |
|
while (1) { |
|
FDE_CSSSyntaxStatus eStatus = pSyntax->DoSyntaxParse(); |
|
if (eStatus == FDE_CSSSyntaxStatus::PropertyName) { |
|
CFX_WideStringC strValue = pSyntax->GetCurrentString(); |
|
table = FDE_GetCSSPropertyByName(strValue); |
|
if (!table) |
|
wsName = CFX_WideString(strValue); |
|
} else if (eStatus == FDE_CSSSyntaxStatus::PropertyValue) { |
|
if (table || iLen2 > 0) { |
|
CFX_WideStringC strValue = pSyntax->GetCurrentString(); |
|
if (!strValue.IsEmpty()) { |
|
if (table) |
|
pDecl->AddProperty(table, strValue); |
|
else if (iLen2 > 0) |
|
pDecl->AddProperty(wsName, CFX_WideString(strValue)); |
|
} |
|
} |
|
} else { |
|
break; |
|
} |
|
} |
|
} |
|
|
|
void CFDE_CSSStyleSelector::ApplyProperty( |
|
FDE_CSSProperty eProperty, |
|
const CFX_RetainPtr<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(pValue.As<CFDE_CSSEnumValue>()->Value()); |
|
} |
|
break; |
|
case FDE_CSSProperty::FontSize: { |
|
FX_FLOAT& fFontSize = pComputedStyle->m_InheritedData.m_fFontSize; |
|
if (eType == FDE_CSSPrimitiveType::Number) { |
|
fFontSize = pValue.As<CFDE_CSSNumberValue>()->Apply(fFontSize); |
|
} else if (eType == FDE_CSSPrimitiveType::Enum) { |
|
fFontSize = |
|
ToFontSize(pValue.As<CFDE_CSSEnumValue>()->Value(), fFontSize); |
|
} |
|
} break; |
|
case FDE_CSSProperty::LineHeight: |
|
if (eType == FDE_CSSPrimitiveType::Number) { |
|
CFX_RetainPtr<CFDE_CSSNumberValue> v = |
|
pValue.As<CFDE_CSSNumberValue>(); |
|
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(pValue.As<CFDE_CSSEnumValue>()->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(pValue.As<CFDE_CSSEnumValue>()->Value()); |
|
} else if (eType == FDE_CSSPrimitiveType::Number) { |
|
int32_t iValue = |
|
(int32_t)pValue.As<CFDE_CSSNumberValue>()->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(pValue.As<CFDE_CSSEnumValue>()->Value()); |
|
} |
|
break; |
|
case FDE_CSSProperty::Color: |
|
if (eType == FDE_CSSPrimitiveType::RGB) { |
|
pComputedStyle->m_InheritedData.m_dwFontColor = |
|
pValue.As<CFDE_CSSColorValue>()->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(pValue.As<CFDE_CSSEnumValue>()->Value()); |
|
} else if (eType == FDE_CSSPrimitiveType::Number) { |
|
pComputedStyle->m_NonInheritedData.m_eVerticalAlign = |
|
FDE_CSSVerticalAlign::Number; |
|
pComputedStyle->m_NonInheritedData.m_fVerticalAlign = |
|
pValue.As<CFDE_CSSNumberValue>()->Apply( |
|
pComputedStyle->m_InheritedData.m_fFontSize); |
|
} |
|
break; |
|
case FDE_CSSProperty::FontVariant: |
|
if (eType == FDE_CSSPrimitiveType::Enum) { |
|
pComputedStyle->m_InheritedData.m_eFontVariant = |
|
ToFontVariant(pValue.As<CFDE_CSSEnumValue>()->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 (pValue.As<CFDE_CSSNumberValue>()->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 (pValue.As<CFDE_CSSNumberValue>()->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) { |
|
CFX_RetainPtr<CFDE_CSSValueList> pList = pValue.As<CFDE_CSSValueList>(); |
|
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, |
|
const CFX_RetainPtr<CFDE_CSSValue>& pValue, |
|
FX_FLOAT fFontSize) { |
|
if (eType == FDE_CSSPrimitiveType::Number) { |
|
CFX_RetainPtr<CFDE_CSSNumberValue> v = pValue.As<CFDE_CSSNumberValue>(); |
|
if (v->Kind() == FDE_CSSNumberType::Percent) { |
|
width.Set(FDE_CSSLengthUnit::Percent, |
|
pValue.As<CFDE_CSSNumberValue>()->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 (pValue.As<CFDE_CSSEnumValue>()->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( |
|
const CFX_RetainPtr<CFDE_CSSValueList>& pValue) { |
|
uint32_t dwDecoration = 0; |
|
for (int32_t i = pValue->CountValues() - 1; i >= 0; --i) { |
|
const CFX_RetainPtr<CFDE_CSSValue> pVal = pValue->GetValue(i); |
|
if (pVal->GetType() != FDE_CSSPrimitiveType::Enum) |
|
continue; |
|
|
|
switch (pVal.As<CFDE_CSSEnumValue>()->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; |
|
}
|
|
|