// 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" IFDE_CSSValue* CFDE_CSSDeclaration::GetProperty(FDE_CSSPROPERTY eProperty, FX_BOOL& bImportant) const { for (const FDE_CSSPropertyHolder* pHolder = m_pFirstProperty; pHolder; pHolder = pHolder->pNext) { if (pHolder->eProperty == eProperty) { bImportant = pHolder->bImportant; return pHolder->pValue; } } return nullptr; } FX_POSITION CFDE_CSSDeclaration::GetStartPosition() const { return (FX_POSITION)m_pFirstProperty; } void CFDE_CSSDeclaration::GetNextProperty(FX_POSITION& pos, FDE_CSSPROPERTY& eProperty, IFDE_CSSValue*& pValue, FX_BOOL& bImportant) const { const FDE_CSSPropertyHolder* pHolder = (const FDE_CSSPropertyHolder*)pos; bImportant = pHolder->bImportant; eProperty = (FDE_CSSPROPERTY)pHolder->eProperty; pValue = pHolder->pValue; pos = (FX_POSITION)pHolder->pNext; } FX_POSITION CFDE_CSSDeclaration::GetStartCustom() const { return (FX_POSITION)m_pFirstCustom; } void CFDE_CSSDeclaration::GetNextCustom(FX_POSITION& pos, CFX_WideString& wsName, CFX_WideString& wsValue) const { const FDE_CSSCustomProperty* pProperty = (const FDE_CSSCustomProperty*)pos; if (!pProperty) return; wsName = pProperty->pwsName; wsValue = pProperty->pwsValue; pos = (FX_POSITION)pProperty->pNext; } 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_WCHAR*)pArgs->pStaticStore->Alloc((iValueLen + 1) * sizeof(FX_WCHAR)); FXSYS_wcsncpy(psz, pszValue, iValueLen); psz[iValueLen] = '\0'; if (pCache) (*pCache)[key] = psz; return psz; } IFDE_CSSPrimitiveValue* CFDE_CSSDeclaration::NewNumberValue( IFX_MemoryAllocator* pStaticStore, FDE_CSSPRIMITIVETYPE eUnit, FX_FLOAT fValue) const { static CFDE_CSSPrimitiveValue s_ZeroValue(FDE_CSSPRIMITIVETYPE_Number, 0.0f); if (eUnit == FDE_CSSPRIMITIVETYPE_Number && FXSYS_fabs(fValue) < 0.001f) { return &s_ZeroValue; } return FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eUnit, fValue); } inline IFDE_CSSPrimitiveValue* CFDE_CSSDeclaration::NewEnumValue( IFX_MemoryAllocator* pStaticStore, FDE_CSSPROPERTYVALUE eValue) const { return FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eValue); } void CFDE_CSSDeclaration::AddPropertyHolder(IFX_MemoryAllocator* pStaticStore, FDE_CSSPROPERTY eProperty, IFDE_CSSValue* pValue, FX_BOOL bImportant) { FDE_CSSPropertyHolder* pHolder = FXTARGET_NewWith(pStaticStore) FDE_CSSPropertyHolder; pHolder->bImportant = bImportant; pHolder->eProperty = eProperty; pHolder->pValue = pValue; pHolder->pNext = nullptr; if (m_pLastProperty) m_pLastProperty->pNext = pHolder; else m_pFirstProperty = pHolder; m_pLastProperty = pHolder; } FX_BOOL CFDE_CSSDeclaration::AddProperty(const FDE_CSSPROPERTYARGS* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen) { ASSERT(iValueLen > 0); FX_BOOL bImportant = FALSE; if (iValueLen >= 10 && pszValue[iValueLen - 10] == '!' && FXSYS_wcsnicmp(L"important", pszValue + iValueLen - 9, 9) == 0) { if ((iValueLen -= 10) == 0) { return FALSE; } 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_MaybeURI, FDE_CSSVALUETYPE_MaybeFunction, 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; } IFDE_CSSValue* pCSSValue = nullptr; switch (dwMatch) { case FDE_CSSVALUETYPE_MaybeFunction: pCSSValue = ParseFunction(pArgs, pszValue, iValueLen); break; 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_MaybeURI: pCSSValue = ParseURI(pArgs, pszValue, iValueLen); break; case FDE_CSSVALUETYPE_MaybeString: pCSSValue = ParseString(pArgs, pszValue, iValueLen); break; default: break; } if (pCSSValue) { AddPropertyHolder(pArgs->pStaticStore, pArgs->pProperty->eName, pCSSValue, bImportant); return TRUE; } if (FDE_IsOnlyValue(dwType, g_ValueGuessOrder[i])) { return FALSE; } } } break; case FDE_CSSVALUETYPE_Shorthand: { IFX_MemoryAllocator* pStaticStore = pArgs->pStaticStore; IFDE_CSSValue *pColor, *pStyle, *pWidth; switch (pArgs->pProperty->eName) { case FDE_CSSPROPERTY_Font: return ParseFontProperty(pArgs, pszValue, iValueLen, bImportant); case FDE_CSSPROPERTY_Background: return ParseBackgroundProperty(pArgs, pszValue, iValueLen, bImportant); case FDE_CSSPROPERTY_ListStyle: return ParseListStyleProperty(pArgs, pszValue, iValueLen, bImportant); case FDE_CSSPROPERTY_Border: if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor, pStyle, pWidth)) { AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant, FDE_CSSPROPERTY_BorderLeftColor, FDE_CSSPROPERTY_BorderLeftStyle, FDE_CSSPROPERTY_BorderLeftWidth); AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant, FDE_CSSPROPERTY_BorderTopColor, FDE_CSSPROPERTY_BorderTopStyle, FDE_CSSPROPERTY_BorderTopWidth); AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant, FDE_CSSPROPERTY_BorderRightColor, FDE_CSSPROPERTY_BorderRightStyle, FDE_CSSPROPERTY_BorderRightWidth); AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant, FDE_CSSPROPERTY_BorderBottomColor, FDE_CSSPROPERTY_BorderBottomStyle, FDE_CSSPROPERTY_BorderBottomWidth); return TRUE; } break; case FDE_CSSPROPERTY_BorderLeft: if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor, pStyle, pWidth)) { AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant, FDE_CSSPROPERTY_BorderLeftColor, FDE_CSSPROPERTY_BorderLeftStyle, FDE_CSSPROPERTY_BorderLeftWidth); return TRUE; } break; case FDE_CSSPROPERTY_BorderTop: if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor, pStyle, pWidth)) { AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant, FDE_CSSPROPERTY_BorderTopColor, FDE_CSSPROPERTY_BorderTopStyle, FDE_CSSPROPERTY_BorderTopWidth); return TRUE; } break; case FDE_CSSPROPERTY_BorderRight: if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor, pStyle, pWidth)) { AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant, FDE_CSSPROPERTY_BorderRightColor, FDE_CSSPROPERTY_BorderRightStyle, FDE_CSSPROPERTY_BorderRightWidth); return TRUE; } break; case FDE_CSSPROPERTY_BorderBottom: if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor, pStyle, pWidth)) { AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant, FDE_CSSPROPERTY_BorderBottomColor, FDE_CSSPROPERTY_BorderBottomStyle, FDE_CSSPROPERTY_BorderBottomWidth); return TRUE; } break; case FDE_CSSPROPERTY_Overflow: return ParseOverflowProperty(pArgs, pszValue, iValueLen, bImportant); case FDE_CSSPROPERTY_ColumnRule: return ParseColumnRuleProperty(pArgs, pszValue, iValueLen, bImportant); default: break; } } break; case FDE_CSSVALUETYPE_List: switch (pArgs->pProperty->eName) { case FDE_CSSPROPERTY_CounterIncrement: case FDE_CSSPROPERTY_CounterReset: return ParseCounterProperty(pArgs, pszValue, iValueLen, bImportant); case FDE_CSSPROPERTY_Content: return ParseContentProperty(pArgs, pszValue, iValueLen, bImportant); default: return ParseValueListProperty(pArgs, pszValue, iValueLen, bImportant); } default: ASSERT(FALSE); break; } return FALSE; } FX_BOOL CFDE_CSSDeclaration::AddProperty(const FDE_CSSPROPERTYARGS* pArgs, const FX_WCHAR* pszName, int32_t iNameLen, const FX_WCHAR* pszValue, int32_t iValueLen) { FDE_CSSCustomProperty* pProperty = FXTARGET_NewWith(pArgs->pStaticStore) FDE_CSSCustomProperty; pProperty->pwsName = CopyToLocal(pArgs, pszName, iNameLen); pProperty->pwsValue = CopyToLocal(pArgs, pszValue, iValueLen); pProperty->pNext = nullptr; if (m_pLastCustom) m_pLastCustom->pNext = pProperty; else m_pFirstCustom = pProperty; m_pLastCustom = pProperty; return TRUE; } IFDE_CSSValue* CFDE_CSSDeclaration::ParseNumber( const FDE_CSSPROPERTYARGS* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen) { FX_FLOAT fValue; FDE_CSSPRIMITIVETYPE eUnit; if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eUnit)) { return nullptr; } return NewNumberValue(pArgs->pStaticStore, eUnit, fValue); } IFDE_CSSValue* 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 ? NewEnumValue(pArgs->pStaticStore, pValue->eName) : nullptr; } IFDE_CSSValue* 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 FXTARGET_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(dwColor); } IFDE_CSSValue* CFDE_CSSDeclaration::ParseURI(const FDE_CSSPROPERTYARGS* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen) { int32_t iOffset; if (!FDE_ParseCSSURI(pszValue, iValueLen, iOffset, iValueLen)) { return nullptr; } if (iValueLen <= 0) { return nullptr; } pszValue = CopyToLocal(pArgs, pszValue + iOffset, iValueLen); return pszValue ? FXTARGET_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_URI, pszValue) : nullptr; } IFDE_CSSValue* 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 ? FXTARGET_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, pszValue) : nullptr; } IFDE_CSSValue* CFDE_CSSDeclaration::ParseFunction( const FDE_CSSPROPERTYARGS* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen) { if (pszValue[iValueLen - 1] != ')') { return nullptr; } int32_t iStartBracket = 0; while (pszValue[iStartBracket] != '(') { if (iStartBracket < iValueLen) { iStartBracket++; } else { return nullptr; } } if (iStartBracket == 0) { return nullptr; } const FX_WCHAR* pszFuncName = CopyToLocal(pArgs, pszValue, iStartBracket); pszValue += (iStartBracket + 1); iValueLen -= (iStartBracket + 2); CFDE_CSSValueArray argumentArr; CFDE_CSSValueListParser parser(pszValue, iValueLen, ','); FDE_CSSPRIMITIVETYPE ePrimitiveType; while (parser.NextValue(ePrimitiveType, pszValue, iValueLen)) { switch (ePrimitiveType) { case FDE_CSSPRIMITIVETYPE_String: { const FDE_CSSPROPERTYVALUETABLE* pPropertyValue = FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); if (pPropertyValue) { argumentArr.Add( NewEnumValue(pArgs->pStaticStore, pPropertyValue->eName)); continue; } IFDE_CSSValue* pFunctionValue = ParseFunction(pArgs, pszValue, iValueLen); if (pFunctionValue) { argumentArr.Add(pFunctionValue); continue; } argumentArr.Add(FXTARGET_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue( FDE_CSSPRIMITIVETYPE_String, CopyToLocal(pArgs, pszValue, iValueLen))); } break; case FDE_CSSPRIMITIVETYPE_Number: { FX_FLOAT fValue; if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, ePrimitiveType)) { argumentArr.Add( NewNumberValue(pArgs->pStaticStore, ePrimitiveType, fValue)); } } break; default: argumentArr.Add(FXTARGET_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue( FDE_CSSPRIMITIVETYPE_String, CopyToLocal(pArgs, pszValue, iValueLen))); break; } } IFDE_CSSValueList* pArgumentList = FXTARGET_NewWith(pArgs->pStaticStore) CFDE_CSSValueList(pArgs->pStaticStore, argumentArr); CFDE_CSSFunction* pFunction = FXTARGET_NewWith(pArgs->pStaticStore) CFDE_CSSFunction(pszFuncName, pArgumentList); return FXTARGET_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(pFunction); } FX_BOOL CFDE_CSSDeclaration::ParseContentProperty( const FDE_CSSPROPERTYARGS* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen, FX_BOOL bImportant) { IFX_MemoryAllocator* pStaticStore = pArgs->pStaticStore; CFDE_CSSValueListParser parser(pszValue, iValueLen, ' '); FDE_CSSPRIMITIVETYPE eType; CFDE_CSSValueArray list; while (parser.NextValue(eType, pszValue, iValueLen)) { switch (eType) { case FDE_CSSPRIMITIVETYPE_URI: list.Add(FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue( eType, CopyToLocal(pArgs, pszValue, iValueLen))); break; case FDE_CSSPRIMITIVETYPE_Number: return FALSE; case FDE_CSSPRIMITIVETYPE_String: { const FDE_CSSPROPERTYVALUETABLE* pValue = FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); if (pValue) { switch (pValue->eName) { case FDE_CSSPROPERTYVALUE_Normal: case FDE_CSSPROPERTYVALUE_None: { if (list.GetSize() == 0) { list.Add(NewEnumValue(pStaticStore, pValue->eName)); } else { return FALSE; } } break; case FDE_CSSPROPERTYVALUE_OpenQuote: case FDE_CSSPROPERTYVALUE_CloseQuote: case FDE_CSSPROPERTYVALUE_NoOpenQuote: case FDE_CSSPROPERTYVALUE_NoCloseQuote: list.Add(NewEnumValue(pStaticStore, pValue->eName)); break; default: return FALSE; } continue; } IFDE_CSSValue* pFunction = ParseFunction(pArgs, pszValue, iValueLen); if (pFunction) { list.Add(pFunction); continue; } list.Add(FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue( eType, CopyToLocal(pArgs, pszValue, iValueLen))); } break; case FDE_CSSPRIMITIVETYPE_RGB: return FALSE; default: break; } } if (list.GetSize() == 0) { return FALSE; } AddPropertyHolder(pStaticStore, pArgs->pProperty->eName, FXTARGET_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, list), bImportant); return TRUE; } FX_BOOL CFDE_CSSDeclaration::ParseCounterProperty( const FDE_CSSPROPERTYARGS* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen, FX_BOOL bImportant) { IFX_MemoryAllocator* pStaticStore = pArgs->pStaticStore; CFDE_CSSValueListParser parser(pszValue, iValueLen, ' '); CFDE_CSSValueArray list; CFDE_CSSValueArray listFull; FDE_CSSPRIMITIVETYPE eType; while (parser.NextValue(eType, pszValue, iValueLen)) { switch (eType) { case FDE_CSSPRIMITIVETYPE_Number: { FX_FLOAT fValue; if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) { if (list.GetSize() == 1) { list.Add(NewNumberValue(pStaticStore, eType, fValue)); listFull.Add(FXTARGET_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, list)); list.RemoveAll(); } else { return FALSE; } } } break; case FDE_CSSPRIMITIVETYPE_String: { if (list.GetSize() == 0) { pszValue = CopyToLocal(pArgs, pszValue, iValueLen); list.Add(FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue( FDE_CSSPRIMITIVETYPE_String, pszValue)); } else { listFull.Add(FXTARGET_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, list)); list.RemoveAll(); pszValue = CopyToLocal(pArgs, pszValue, iValueLen); list.Add(FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue( FDE_CSSPRIMITIVETYPE_String, pszValue)); } } break; default: break; } } if (list.GetSize() == 1) { listFull.Add(FXTARGET_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, list)); } if (listFull.GetSize() == 0) { return FALSE; } AddPropertyHolder(pStaticStore, pArgs->pProperty->eName, FXTARGET_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, listFull), bImportant); return TRUE; } FX_BOOL CFDE_CSSDeclaration::ParseValueListProperty( const FDE_CSSPROPERTYARGS* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen, FX_BOOL bImportant) { IFX_MemoryAllocator* pStaticStore = pArgs->pStaticStore; 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; CFDE_CSSValueArray list; while (parser.NextValue(eType, pszValue, iValueLen)) { switch (eType) { case FDE_CSSPRIMITIVETYPE_Number: if (dwType & FDE_CSSVALUETYPE_MaybeNumber) { FX_FLOAT fValue; if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) { list.Add(NewNumberValue(pStaticStore, eType, fValue)); } } break; case FDE_CSSPRIMITIVETYPE_String: if (dwType & FDE_CSSVALUETYPE_MaybeColor) { FX_ARGB dwColor; if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) { list.Add(FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor)); continue; } } if (dwType & FDE_CSSVALUETYPE_MaybeEnum) { const FDE_CSSPROPERTYVALUETABLE* pValue = FDE_GetCSSPropertyValueByName( CFX_WideStringC(pszValue, iValueLen)); if (pValue) { list.Add(NewEnumValue(pStaticStore, pValue->eName)); continue; } } if (dwType & FDE_CSSVALUETYPE_MaybeString) { pszValue = CopyToLocal(pArgs, pszValue, iValueLen); list.Add(FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue( FDE_CSSPRIMITIVETYPE_String, pszValue)); } break; case FDE_CSSPRIMITIVETYPE_RGB: if (dwType & FDE_CSSVALUETYPE_MaybeColor) { FX_ARGB dwColor; if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) { list.Add(FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor)); } } break; default: break; } } if (list.GetSize() == 0) { return FALSE; } switch (pArgs->pProperty->eName) { case FDE_CSSPROPERTY_BorderColor: return Add4ValuesProperty( pStaticStore, list, bImportant, FDE_CSSPROPERTY_BorderLeftColor, FDE_CSSPROPERTY_BorderTopColor, FDE_CSSPROPERTY_BorderRightColor, FDE_CSSPROPERTY_BorderBottomColor); case FDE_CSSPROPERTY_BorderStyle: return Add4ValuesProperty( pStaticStore, list, bImportant, FDE_CSSPROPERTY_BorderLeftStyle, FDE_CSSPROPERTY_BorderTopStyle, FDE_CSSPROPERTY_BorderRightStyle, FDE_CSSPROPERTY_BorderBottomStyle); case FDE_CSSPROPERTY_BorderWidth: return Add4ValuesProperty( pStaticStore, list, bImportant, FDE_CSSPROPERTY_BorderLeftWidth, FDE_CSSPROPERTY_BorderTopWidth, FDE_CSSPROPERTY_BorderRightWidth, FDE_CSSPROPERTY_BorderBottomWidth); case FDE_CSSPROPERTY_Margin: return Add4ValuesProperty( pStaticStore, list, bImportant, FDE_CSSPROPERTY_MarginLeft, FDE_CSSPROPERTY_MarginTop, FDE_CSSPROPERTY_MarginRight, FDE_CSSPROPERTY_MarginBottom); case FDE_CSSPROPERTY_Padding: return Add4ValuesProperty( pStaticStore, list, bImportant, FDE_CSSPROPERTY_PaddingLeft, FDE_CSSPROPERTY_PaddingTop, FDE_CSSPROPERTY_PaddingRight, FDE_CSSPROPERTY_PaddingBottom); default: { CFDE_CSSValueList* pList = FXTARGET_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, list); AddPropertyHolder(pStaticStore, pArgs->pProperty->eName, pList, bImportant); return TRUE; } break; } return FALSE; } FX_BOOL CFDE_CSSDeclaration::Add4ValuesProperty( IFX_MemoryAllocator* pStaticStore, const CFDE_CSSValueArray& list, FX_BOOL bImportant, FDE_CSSPROPERTY eLeft, FDE_CSSPROPERTY eTop, FDE_CSSPROPERTY eRight, FDE_CSSPROPERTY eBottom) { switch (list.GetSize()) { case 1: AddPropertyHolder(pStaticStore, eLeft, list[0], bImportant); AddPropertyHolder(pStaticStore, eTop, list[0], bImportant); AddPropertyHolder(pStaticStore, eRight, list[0], bImportant); AddPropertyHolder(pStaticStore, eBottom, list[0], bImportant); return TRUE; case 2: AddPropertyHolder(pStaticStore, eLeft, list[1], bImportant); AddPropertyHolder(pStaticStore, eTop, list[0], bImportant); AddPropertyHolder(pStaticStore, eRight, list[1], bImportant); AddPropertyHolder(pStaticStore, eBottom, list[0], bImportant); return TRUE; case 3: AddPropertyHolder(pStaticStore, eLeft, list[1], bImportant); AddPropertyHolder(pStaticStore, eTop, list[0], bImportant); AddPropertyHolder(pStaticStore, eRight, list[1], bImportant); AddPropertyHolder(pStaticStore, eBottom, list[2], bImportant); return TRUE; case 4: AddPropertyHolder(pStaticStore, eLeft, list[3], bImportant); AddPropertyHolder(pStaticStore, eTop, list[0], bImportant); AddPropertyHolder(pStaticStore, eRight, list[1], bImportant); AddPropertyHolder(pStaticStore, eBottom, list[2], bImportant); return TRUE; default: break; } return FALSE; } FX_BOOL CFDE_CSSDeclaration::ParseBorderPropoerty( IFX_MemoryAllocator* pStaticStore, const FX_WCHAR* pszValue, int32_t iValueLen, IFDE_CSSValue*& pColor, IFDE_CSSValue*& pStyle, IFDE_CSSValue*& pWidth) const { pColor = pStyle = pWidth = nullptr; CFDE_CSSValueListParser parser(pszValue, iValueLen, ' '); FDE_CSSPRIMITIVETYPE eType; while (parser.NextValue(eType, pszValue, iValueLen)) { switch (eType) { case FDE_CSSPRIMITIVETYPE_Number: if (!pWidth) { FX_FLOAT fValue; if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) { pWidth = NewNumberValue(pStaticStore, eType, fValue); } } break; case FDE_CSSPRIMITIVETYPE_RGB: if (!pColor) { FX_ARGB dwColor; if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) { pColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor); } } break; case FDE_CSSPRIMITIVETYPE_String: { const FDE_CSSCOLORTABLE* pColorItem = FDE_GetCSSColorByName(CFX_WideStringC(pszValue, iValueLen)); if (pColorItem) { if (!pColor) { pColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(pColorItem->dwValue); } continue; } const FDE_CSSPROPERTYVALUETABLE* pValue = FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); if (!pValue) continue; switch (pValue->eName) { case FDE_CSSPROPERTYVALUE_Transparent: if (!pColor) { pColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0); } break; case FDE_CSSPROPERTYVALUE_Thin: case FDE_CSSPROPERTYVALUE_Thick: case FDE_CSSPROPERTYVALUE_Medium: if (!pWidth) pWidth = NewEnumValue(pStaticStore, pValue->eName); break; case FDE_CSSPROPERTYVALUE_None: case FDE_CSSPROPERTYVALUE_Hidden: case FDE_CSSPROPERTYVALUE_Dotted: case FDE_CSSPROPERTYVALUE_Dashed: case FDE_CSSPROPERTYVALUE_Solid: case FDE_CSSPROPERTYVALUE_Double: case FDE_CSSPROPERTYVALUE_Groove: case FDE_CSSPROPERTYVALUE_Ridge: case FDE_CSSPROPERTYVALUE_Inset: case FDE_CSSPROPERTYVALUE_Outset: if (!pStyle) pStyle = NewEnumValue(pStaticStore, pValue->eName); break; default: break; } }; break; default: break; } } if (!pColor) pColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0); if (!pStyle) pStyle = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None); if (!pWidth) pWidth = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f); return TRUE; } void CFDE_CSSDeclaration::AddBorderProperty(IFX_MemoryAllocator* pStaticStore, IFDE_CSSValue* pColor, IFDE_CSSValue* pStyle, IFDE_CSSValue* pWidth, FX_BOOL bImportant, FDE_CSSPROPERTY eColor, FDE_CSSPROPERTY eStyle, FDE_CSSPROPERTY eWidth) { AddPropertyHolder(pStaticStore, eStyle, pStyle, bImportant); AddPropertyHolder(pStaticStore, eWidth, pWidth, bImportant); AddPropertyHolder(pStaticStore, eColor, pColor, bImportant); } FX_BOOL CFDE_CSSDeclaration::ParseListStyleProperty( const FDE_CSSPROPERTYARGS* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen, FX_BOOL bImportant) { IFX_MemoryAllocator* pStaticStore = pArgs->pStaticStore; CFDE_CSSValueListParser parser(pszValue, iValueLen, ' '); IFDE_CSSPrimitiveValue* pType = nullptr; IFDE_CSSPrimitiveValue* pImage = nullptr; IFDE_CSSPrimitiveValue* pPosition = nullptr; FDE_CSSPRIMITIVETYPE eType; while (parser.NextValue(eType, pszValue, iValueLen)) { switch (eType) { case FDE_CSSPRIMITIVETYPE_URI: if (!pImage) { pImage = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue( eType, CopyToLocal(pArgs, pszValue, iValueLen)); } break; case FDE_CSSPRIMITIVETYPE_String: { const FDE_CSSPROPERTYVALUETABLE* pValue = FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); if (!pValue) break; switch (pValue->eName) { case FDE_CSSPROPERTYVALUE_None: if (!pImage) pImage = NewEnumValue(pStaticStore, pValue->eName); else if (!pType) pImage = NewEnumValue(pStaticStore, pValue->eName); break; case FDE_CSSPROPERTYVALUE_Inside: case FDE_CSSPROPERTYVALUE_Outside: if (!pPosition) pPosition = NewEnumValue(pStaticStore, pValue->eName); break; case FDE_CSSPROPERTYVALUE_Disc: case FDE_CSSPROPERTYVALUE_Circle: case FDE_CSSPROPERTYVALUE_Square: case FDE_CSSPROPERTYVALUE_Decimal: case FDE_CSSPROPERTYVALUE_DecimalLeadingZero: case FDE_CSSPROPERTYVALUE_LowerRoman: case FDE_CSSPROPERTYVALUE_UpperRoman: case FDE_CSSPROPERTYVALUE_LowerGreek: case FDE_CSSPROPERTYVALUE_LowerLatin: case FDE_CSSPROPERTYVALUE_UpperLatin: case FDE_CSSPROPERTYVALUE_Armenian: case FDE_CSSPROPERTYVALUE_Georgian: case FDE_CSSPROPERTYVALUE_LowerAlpha: case FDE_CSSPROPERTYVALUE_UpperAlpha: if (!pType) pType = NewEnumValue(pStaticStore, pValue->eName); break; default: break; } }; break; default: break; } } if (!pPosition) pPosition = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Outside); if (!pImage) pImage = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None); if (!pType) pType = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ListStylePosition, pPosition, bImportant); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ListStyleImage, pImage, bImportant); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ListStyleType, pType, bImportant); return TRUE; } FX_BOOL CFDE_CSSDeclaration::ParseBackgroundProperty( const FDE_CSSPROPERTYARGS* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen, FX_BOOL bImportant) { IFX_MemoryAllocator* pStaticStore = pArgs->pStaticStore; CFDE_CSSValueListParser parser(pszValue, iValueLen, ' '); IFDE_CSSPrimitiveValue* pColor = nullptr; IFDE_CSSPrimitiveValue* pImage = nullptr; IFDE_CSSPrimitiveValue* pRepeat = nullptr; IFDE_CSSPrimitiveValue* pPosX = nullptr; IFDE_CSSPrimitiveValue* pPosY = nullptr; IFDE_CSSPrimitiveValue* pAttachment = nullptr; FDE_CSSPRIMITIVETYPE eType; while (parser.NextValue(eType, pszValue, iValueLen)) { switch (eType) { case FDE_CSSPRIMITIVETYPE_URI: if (!pImage) { pImage = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue( eType, CopyToLocal(pArgs, pszValue, iValueLen)); } break; case FDE_CSSPRIMITIVETYPE_Number: { FX_FLOAT fValue; if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) { break; } if (!pPosX) pPosX = NewNumberValue(pStaticStore, eType, fValue); else if (!pPosY) pPosY = NewNumberValue(pStaticStore, eType, fValue); } break; case FDE_CSSPRIMITIVETYPE_String: { const FDE_CSSPROPERTYVALUETABLE* pValue = FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); if (pValue) { switch (pValue->eName) { case FDE_CSSPROPERTYVALUE_None: if (!pImage) pImage = NewEnumValue(pStaticStore, pValue->eName); break; case FDE_CSSPROPERTYVALUE_Transparent: if (!pColor) { pColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0); } break; case FDE_CSSPROPERTYVALUE_Fixed: case FDE_CSSPROPERTYVALUE_Scroll: if (!pAttachment) pAttachment = NewEnumValue(pStaticStore, pValue->eName); break; case FDE_CSSPROPERTYVALUE_Repeat: case FDE_CSSPROPERTYVALUE_RepeatX: case FDE_CSSPROPERTYVALUE_RepeatY: case FDE_CSSPROPERTYVALUE_NoRepeat: if (!pRepeat) pRepeat = NewEnumValue(pStaticStore, pValue->eName); break; case FDE_CSSPROPERTYVALUE_Left: case FDE_CSSPROPERTYVALUE_Right: if (!pPosX) pPosX = NewEnumValue(pStaticStore, pValue->eName); break; case FDE_CSSPROPERTYVALUE_Top: case FDE_CSSPROPERTYVALUE_Bottom: if (!pPosY) pPosX = NewEnumValue(pStaticStore, pValue->eName); break; case FDE_CSSPROPERTYVALUE_Center: if (!pPosX) pPosX = NewEnumValue(pStaticStore, pValue->eName); else if (!pPosY) pPosX = NewEnumValue(pStaticStore, pValue->eName); break; default: break; } break; } const FDE_CSSCOLORTABLE* pColorItem = FDE_GetCSSColorByName(CFX_WideStringC(pszValue, iValueLen)); if (pColorItem) { if (!pColor) { pColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(pColorItem->dwValue); } } } break; case FDE_CSSPRIMITIVETYPE_RGB: if (!pColor) { FX_ARGB dwColor; if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) { pColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor); } } break; default: break; } } if (!pColor) { pColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0); } if (!pImage) pImage = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None); if (!pRepeat) pRepeat = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Repeat); if (!pAttachment) pAttachment = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Scroll); if (!pPosX) { pPosX = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f); pPosY = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f); } else if (!pPosY) { pPosY = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f); } CFDE_CSSValueArray position; position.Add(pPosX); position.Add(pPosY); CFDE_CSSValueList* pPosList = FXTARGET_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, position); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundColor, pColor, bImportant); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundImage, pImage, bImportant); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundRepeat, pRepeat, bImportant); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundPosition, pPosList, bImportant); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundAttachment, pAttachment, bImportant); return TRUE; } FX_BOOL CFDE_CSSDeclaration::ParseFontProperty(const FDE_CSSPROPERTYARGS* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen, FX_BOOL bImportant) { IFX_MemoryAllocator* pStaticStore = pArgs->pStaticStore; CFDE_CSSValueListParser parser(pszValue, iValueLen, '/'); IFDE_CSSPrimitiveValue* pStyle = nullptr; IFDE_CSSPrimitiveValue* pVariant = nullptr; IFDE_CSSPrimitiveValue* pWeight = nullptr; IFDE_CSSPrimitiveValue* pFontSize = nullptr; IFDE_CSSPrimitiveValue* pLineHeight = nullptr; CFDE_CSSValueArray 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 = NewEnumValue(pStaticStore, pValue->eName); continue; case FDE_CSSPROPERTYVALUE_Bold: case FDE_CSSPROPERTYVALUE_Bolder: case FDE_CSSPROPERTYVALUE_Lighter: if (!pWeight) pWeight = NewEnumValue(pStaticStore, pValue->eName); continue; case FDE_CSSPROPERTYVALUE_Italic: case FDE_CSSPROPERTYVALUE_Oblique: if (!pStyle) pStyle = NewEnumValue(pStaticStore, pValue->eName); continue; case FDE_CSSPROPERTYVALUE_SmallCaps: if (!pVariant) pVariant = NewEnumValue(pStaticStore, pValue->eName); continue; case FDE_CSSPROPERTYVALUE_Normal: if (!pStyle) pStyle = NewEnumValue(pStaticStore, pValue->eName); else if (!pVariant) pVariant = NewEnumValue(pStaticStore, pValue->eName); else if (!pWeight) pWeight = NewEnumValue(pStaticStore, pValue->eName); else if (!pFontSize) pFontSize = NewEnumValue(pStaticStore, pValue->eName); else if (!pLineHeight) pLineHeight = NewEnumValue(pStaticStore, pValue->eName); continue; default: break; } } if (pFontSize) { familyList.Add(FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue( eType, CopyToLocal(pArgs, pszValue, iValueLen))); } parser.m_Separator = ','; } break; case FDE_CSSPRIMITIVETYPE_Number: { FX_FLOAT fValue; if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) { 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 = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, fValue); } continue; } } if (!pFontSize) pFontSize = NewNumberValue(pStaticStore, eType, fValue); else if (!pLineHeight) pLineHeight = NewNumberValue(pStaticStore, eType, fValue); } break; default: break; } } if (!pStyle) pStyle = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal); if (!pVariant) pVariant = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal); if (!pWeight) pWeight = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal); if (!pFontSize) pFontSize = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Medium); if (!pLineHeight) pLineHeight = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontStyle, pStyle, bImportant); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontVariant, pVariant, bImportant); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontWeight, pWeight, bImportant); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontSize, pFontSize, bImportant); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_LineHeight, pLineHeight, bImportant); if (familyList.GetSize() > 0) { CFDE_CSSValueList* pList = FXTARGET_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, familyList); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontFamily, pList, bImportant); } return TRUE; } FX_BOOL CFDE_CSSDeclaration::ParseColumnRuleProperty( const FDE_CSSPROPERTYARGS* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen, FX_BOOL bImportant) { IFX_MemoryAllocator* pStaticStore = pArgs->pStaticStore; CFDE_CSSValueListParser parser(pszValue, iValueLen, ' '); IFDE_CSSPrimitiveValue* pColumnRuleWidth = nullptr; IFDE_CSSPrimitiveValue* pColumnRuleStyle = nullptr; IFDE_CSSPrimitiveValue* pColumnRuleColor = nullptr; 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_None: case FDE_CSSPROPERTYVALUE_Hidden: case FDE_CSSPROPERTYVALUE_Dotted: case FDE_CSSPROPERTYVALUE_Dashed: case FDE_CSSPROPERTYVALUE_Solid: case FDE_CSSPROPERTYVALUE_Double: case FDE_CSSPROPERTYVALUE_Groove: case FDE_CSSPROPERTYVALUE_Ridge: case FDE_CSSPROPERTYVALUE_Inset: case FDE_CSSPROPERTYVALUE_Outset: if (!pColumnRuleStyle) pColumnRuleStyle = NewEnumValue(pStaticStore, pValue->eName); break; case FDE_CSSPROPERTYVALUE_Transparent: if (!pColumnRuleColor) pColumnRuleColor = NewEnumValue(pStaticStore, pValue->eName); break; case FDE_CSSPROPERTYVALUE_Thin: case FDE_CSSPROPERTYVALUE_Medium: case FDE_CSSPROPERTYVALUE_Thick: if (!pColumnRuleWidth) pColumnRuleWidth = NewEnumValue(pStaticStore, pValue->eName); break; default: break; } continue; } FX_ARGB dwColor; if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor) && !pColumnRuleColor) { pColumnRuleColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)dwColor); continue; } } break; case FDE_CSSPRIMITIVETYPE_Number: { FX_FLOAT fValue; if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType) && !pColumnRuleWidth) { pColumnRuleWidth = NewNumberValue(pStaticStore, eType, fValue); } } break; case FDE_CSSPRIMITIVETYPE_RGB: { FX_ARGB dwColor; if (!pColumnRuleColor && FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) { pColumnRuleColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)dwColor); } } break; default: break; } } if (!pColumnRuleColor && !pColumnRuleStyle && !pColumnRuleWidth) return FALSE; if (!pColumnRuleStyle) pColumnRuleStyle = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None); if (!pColumnRuleWidth) pColumnRuleWidth = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Medium); if (!pColumnRuleColor) { pColumnRuleColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0); } AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnRuleStyle, pColumnRuleStyle, bImportant); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnRuleWidth, pColumnRuleWidth, bImportant); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnRuleColor, pColumnRuleColor, bImportant); return TRUE; } FX_BOOL CFDE_CSSDeclaration::ParseTextEmphasisProperty( FDE_CSSPROPERTYARGS* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen, FX_BOOL bImportant) { IFX_MemoryAllocator* pStaticStore = pArgs->pStaticStore; CFDE_CSSValueListParser parser(pszValue, iValueLen, ' '); CFDE_CSSValueArray arrEmphasisStyle; FDE_CSSPRIMITIVETYPE eType; IFDE_CSSPrimitiveValue* pEmphasisColor = nullptr; while (parser.NextValue(eType, pszValue, iValueLen)) { switch (eType) { case FDE_CSSPRIMITIVETYPE_String: { const FDE_CSSPROPERTYVALUETABLE* pValue = FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); if (pValue) { arrEmphasisStyle.Add(NewEnumValue(pStaticStore, pValue->eName)); continue; } FX_ARGB dwColor; if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) { pEmphasisColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor); continue; } pszValue = CopyToLocal(pArgs, pszValue, iValueLen); arrEmphasisStyle.Add( FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, pszValue)); } break; case FDE_CSSPRIMITIVETYPE_RGB: { FX_ARGB dwColor; if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) { pEmphasisColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor); } } break; default: break; } } if (arrEmphasisStyle.GetSize() != 0) { AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_TextEmphasisStyle, FXTARGET_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, arrEmphasisStyle), bImportant); } if (pEmphasisColor) { AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_TextEmphasisColor, pEmphasisColor, bImportant); } return TRUE; } FX_BOOL CFDE_CSSDeclaration::ParseColumnsProperty( const FDE_CSSPROPERTYARGS* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen, FX_BOOL bImportant) { IFX_MemoryAllocator* pStaticStore = pArgs->pStaticStore; CFDE_CSSValueListParser parser(pszValue, iValueLen, ' '); IFDE_CSSPrimitiveValue* pColumnWidth = nullptr; IFDE_CSSPrimitiveValue* pColumnCount = nullptr; 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 && pValue->eName == FDE_CSSPROPERTYVALUE_Auto) { pColumnWidth = NewEnumValue(pStaticStore, pValue->eName); } } break; case FDE_CSSPRIMITIVETYPE_Number: { FX_FLOAT fValue; if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) { switch (eType) { case FDE_CSSPRIMITIVETYPE_Number: if (!pColumnCount) pColumnCount = NewNumberValue(pStaticStore, eType, fValue); break; default: if (!pColumnWidth) pColumnWidth = NewNumberValue(pStaticStore, eType, fValue); break; } } } break; default: break; } } if (!pColumnWidth && !pColumnCount) return FALSE; if (!pColumnWidth) pColumnWidth = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Auto); else if (!pColumnCount) pColumnCount = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Auto); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnWidth, pColumnWidth, bImportant); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnCount, pColumnCount, bImportant); return TRUE; } FX_BOOL CFDE_CSSDeclaration::ParseOverflowProperty( const FDE_CSSPROPERTYARGS* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen, FX_BOOL bImportant) { IFX_MemoryAllocator* pStaticStore = pArgs->pStaticStore; CFDE_CSSValueListParser parser(pszValue, iValueLen, ' '); IFDE_CSSPrimitiveValue* pOverflowX = nullptr; IFDE_CSSPrimitiveValue* pOverflowY = nullptr; FDE_CSSPRIMITIVETYPE eType; while (parser.NextValue(eType, pszValue, iValueLen)) { if (eType == FDE_CSSPRIMITIVETYPE_String) { const FDE_CSSPROPERTYVALUETABLE* pValue = FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); if (pValue) { switch (pValue->eName) { case FDE_CSSOVERFLOW_Visible: case FDE_CSSOVERFLOW_Hidden: case FDE_CSSOVERFLOW_Scroll: case FDE_CSSOVERFLOW_Auto: case FDE_CSSOVERFLOW_NoDisplay: case FDE_CSSOVERFLOW_NoContent: if (pOverflowX && pOverflowY) return FALSE; if (!pOverflowX) { pOverflowX = NewEnumValue(pStaticStore, pValue->eName); } else if (!pOverflowY) { pOverflowY = NewEnumValue(pStaticStore, pValue->eName); } break; default: break; } } } } if (!pOverflowX && !pOverflowY) return FALSE; if (!pOverflowY) pOverflowY = NewEnumValue(pStaticStore, pOverflowX->GetEnum()); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_OverflowX, pOverflowX, bImportant); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_OverflowY, pOverflowY, bImportant); return TRUE; }