// 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/include/fx_ext.h" #include "xfa/fgas/crt/fgas_system.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 NULL; } 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; ASSERT(pHolder != NULL); 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 == NULL) { 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); CFX_MapPtrToPtr* pCache = pArgs->pStringCache; void* pKey = NULL; if (pCache) { void* pszCached = NULL; pKey = (void*)(uintptr_t)FX_HashCode_GetW( CFX_WideStringC(pszValue, iValueLen), false); if (pCache->Lookup(pKey, pszCached)) { return (const FX_WCHAR*)pszCached; } } FX_WCHAR* psz = (FX_WCHAR*)pArgs->pStaticStore->Alloc((iValueLen + 1) * sizeof(FX_WCHAR)); if (psz == NULL) { return NULL; } FXSYS_wcsncpy(psz, pszValue, iValueLen); psz[iValueLen] = '\0'; if (pCache) { pCache->SetAt(pKey, 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 = NULL; if (m_pLastProperty == NULL) { m_pLastProperty = m_pFirstProperty = pHolder; } else { m_pLastProperty->pNext = 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] == '!' && FX_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 = NULL; 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 != NULL) { 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 = NULL; if (m_pLastCustom == NULL) { m_pLastCustom = m_pFirstCustom = pProperty; } else { m_pLastCustom->pNext = 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 NULL; } 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) : NULL; } 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 NULL; } 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 NULL; } if (iValueLen <= 0) { return NULL; } pszValue = CopyToLocal(pArgs, pszValue + iOffset, iValueLen); return pszValue ? FXTARGET_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_URI, pszValue) : NULL; } 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 NULL; } if (iValueLen <= 0) { return NULL; } pszValue = CopyToLocal(pArgs, pszValue + iOffset, iValueLen); return pszValue ? FXTARGET_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, pszValue) : NULL; } IFDE_CSSValue* CFDE_CSSDeclaration::ParseFunction( const FDE_CSSPROPERTYARGS* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen) { if (pszValue[iValueLen - 1] != ')') { return NULL; } int32_t iStartBracket = 0; while (pszValue[iStartBracket] != '(') { if (iStartBracket < iValueLen) { iStartBracket++; } else { return NULL; } } if (iStartBracket == 0) { return NULL; } 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 != NULL) { argumentArr.Add( NewEnumValue(pArgs->pStaticStore, pPropertyValue->eName)); continue; } IFDE_CSSValue* pFunctionValue = ParseFunction(pArgs, pszValue, iValueLen); if (pFunctionValue != NULL) { 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 != NULL) { 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 != NULL) { 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 != NULL) { 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 = NULL; CFDE_CSSValueListParser parser(pszValue, iValueLen, ' '); FDE_CSSPRIMITIVETYPE eType; while (parser.NextValue(eType, pszValue, iValueLen)) { switch (eType) { case FDE_CSSPRIMITIVETYPE_Number: if (pWidth == NULL) { FX_FLOAT fValue; if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) { pWidth = NewNumberValue(pStaticStore, eType, fValue); } } break; case FDE_CSSPRIMITIVETYPE_RGB: if (pColor == NULL) { 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 != NULL) { if (pColor == NULL) { pColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(pColorItem->dwValue); } continue; } const FDE_CSSPROPERTYVALUETABLE* pValue = FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); if (pValue == NULL) { continue; } switch (pValue->eName) { case FDE_CSSPROPERTYVALUE_Transparent: if (pColor == NULL) { pColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0); } break; case FDE_CSSPROPERTYVALUE_Thin: case FDE_CSSPROPERTYVALUE_Thick: case FDE_CSSPROPERTYVALUE_Medium: if (pWidth == NULL) { 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 == NULL) { pStyle = NewEnumValue(pStaticStore, pValue->eName); } break; default: break; } }; break; default: break; } } if (pColor == NULL) { pColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0); } if (pStyle == NULL) { pStyle = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None); } if (pWidth == NULL) { 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 = NULL, *pImage = NULL, *pPosition = NULL; FDE_CSSPRIMITIVETYPE eType; while (parser.NextValue(eType, pszValue, iValueLen)) { switch (eType) { case FDE_CSSPRIMITIVETYPE_URI: if (pImage == NULL) { 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 == NULL) { break; } switch (pValue->eName) { case FDE_CSSPROPERTYVALUE_None: if (pImage == NULL) { pImage = NewEnumValue(pStaticStore, pValue->eName); } else if (pType == NULL) { pImage = NewEnumValue(pStaticStore, pValue->eName); } break; case FDE_CSSPROPERTYVALUE_Inside: case FDE_CSSPROPERTYVALUE_Outside: if (pPosition == NULL) { 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 == NULL) { pType = NewEnumValue(pStaticStore, pValue->eName); } break; default: break; } }; break; default: break; } } if (pPosition == NULL) { pPosition = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Outside); } if (pImage == NULL) { pImage = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None); } if (pType == NULL) { 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 = NULL, *pImage = NULL, *pRepeat = NULL; IFDE_CSSPrimitiveValue *pPosX = NULL, *pPosY = NULL, *pAttachment = NULL; FDE_CSSPRIMITIVETYPE eType; while (parser.NextValue(eType, pszValue, iValueLen)) { switch (eType) { case FDE_CSSPRIMITIVETYPE_URI: if (pImage == NULL) { 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 == NULL) { pPosX = NewNumberValue(pStaticStore, eType, fValue); } else if (pPosY == NULL) { pPosY = NewNumberValue(pStaticStore, eType, fValue); } } break; case FDE_CSSPRIMITIVETYPE_String: { const FDE_CSSPROPERTYVALUETABLE* pValue = FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); if (pValue != NULL) { switch (pValue->eName) { case FDE_CSSPROPERTYVALUE_None: if (pImage == NULL) { pImage = NewEnumValue(pStaticStore, pValue->eName); } break; case FDE_CSSPROPERTYVALUE_Transparent: if (pColor == NULL) { pColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0); } break; case FDE_CSSPROPERTYVALUE_Fixed: case FDE_CSSPROPERTYVALUE_Scroll: if (pAttachment == NULL) { pAttachment = NewEnumValue(pStaticStore, pValue->eName); } break; case FDE_CSSPROPERTYVALUE_Repeat: case FDE_CSSPROPERTYVALUE_RepeatX: case FDE_CSSPROPERTYVALUE_RepeatY: case FDE_CSSPROPERTYVALUE_NoRepeat: if (pRepeat == NULL) { pRepeat = NewEnumValue(pStaticStore, pValue->eName); } break; case FDE_CSSPROPERTYVALUE_Left: case FDE_CSSPROPERTYVALUE_Right: if (pPosX == NULL) { pPosX = NewEnumValue(pStaticStore, pValue->eName); } break; case FDE_CSSPROPERTYVALUE_Top: case FDE_CSSPROPERTYVALUE_Bottom: if (pPosY == NULL) { pPosX = NewEnumValue(pStaticStore, pValue->eName); } break; case FDE_CSSPROPERTYVALUE_Center: if (pPosX == NULL) { pPosX = NewEnumValue(pStaticStore, pValue->eName); } else if (pPosY == NULL) { pPosX = NewEnumValue(pStaticStore, pValue->eName); } break; default: break; } break; } const FDE_CSSCOLORTABLE* pColorItem = FDE_GetCSSColorByName(CFX_WideStringC(pszValue, iValueLen)); if (pColorItem != NULL) { if (pColor == NULL) { pColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(pColorItem->dwValue); } } } break; case FDE_CSSPRIMITIVETYPE_RGB: if (pColor == NULL) { FX_ARGB dwColor; if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) { pColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor); } } break; default: break; } } if (pColor == NULL) { pColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0); } if (pImage == NULL) { pImage = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None); } if (pRepeat == NULL) { pRepeat = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Repeat); } if (pAttachment == NULL) { pAttachment = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Scroll); } if (pPosX == NULL) { pPosX = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f); pPosY = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f); } else if (pPosY == NULL) { 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 = NULL, *pVariant = NULL, *pWeight = NULL; IFDE_CSSPrimitiveValue *pFontSize = NULL, *pLineHeight = NULL; 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 != NULL) { 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 == NULL) { pFontSize = NewEnumValue(pStaticStore, pValue->eName); } continue; case FDE_CSSPROPERTYVALUE_Bold: case FDE_CSSPROPERTYVALUE_Bolder: case FDE_CSSPROPERTYVALUE_Lighter: if (pWeight == NULL) { pWeight = NewEnumValue(pStaticStore, pValue->eName); } continue; case FDE_CSSPROPERTYVALUE_Italic: case FDE_CSSPROPERTYVALUE_Oblique: if (pStyle == NULL) { pStyle = NewEnumValue(pStaticStore, pValue->eName); } continue; case FDE_CSSPROPERTYVALUE_SmallCaps: if (pVariant == NULL) { pVariant = NewEnumValue(pStaticStore, pValue->eName); } continue; case FDE_CSSPROPERTYVALUE_Normal: if (pStyle == NULL) { pStyle = NewEnumValue(pStaticStore, pValue->eName); } else if (pVariant == NULL) { pVariant = NewEnumValue(pStaticStore, pValue->eName); } else if (pWeight == NULL) { pWeight = NewEnumValue(pStaticStore, pValue->eName); } else if (pFontSize == NULL) { pFontSize = NewEnumValue(pStaticStore, pValue->eName); } else if (pLineHeight == NULL) { pLineHeight = NewEnumValue(pStaticStore, pValue->eName); } continue; default: break; } } if (pFontSize != NULL) { 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 == NULL) { pWeight = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, fValue); } continue; } } if (pFontSize == NULL) { pFontSize = NewNumberValue(pStaticStore, eType, fValue); } else if (pLineHeight == NULL) { pLineHeight = NewNumberValue(pStaticStore, eType, fValue); } } break; default: break; } } if (pStyle == NULL) { pStyle = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal); } if (pVariant == NULL) { pVariant = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal); } if (pWeight == NULL) { pWeight = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal); } if (pFontSize == NULL) { pFontSize = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Medium); } if (pLineHeight == NULL) { 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 = NULL; IFDE_CSSPrimitiveValue* pColumnRuleStyle = NULL; IFDE_CSSPrimitiveValue* pColumnRuleColor = NULL; 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 != NULL) { 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 == NULL) { pColumnRuleStyle = NewEnumValue(pStaticStore, pValue->eName); } break; case FDE_CSSPROPERTYVALUE_Transparent: if (pColumnRuleColor == NULL) { pColumnRuleColor = NewEnumValue(pStaticStore, pValue->eName); } break; case FDE_CSSPROPERTYVALUE_Thin: case FDE_CSSPROPERTYVALUE_Medium: case FDE_CSSPROPERTYVALUE_Thick: if (pColumnRuleWidth == NULL) { pColumnRuleWidth = NewEnumValue(pStaticStore, pValue->eName); } break; default: break; } continue; } FX_ARGB dwColor; if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor) && pColumnRuleColor == NULL) { 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 == NULL) { pColumnRuleWidth = NewNumberValue(pStaticStore, eType, fValue); } } break; case FDE_CSSPRIMITIVETYPE_RGB: { FX_ARGB dwColor; if (pColumnRuleColor == NULL && FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) { pColumnRuleColor = FXTARGET_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)dwColor); } } break; default: break; } } if (pColumnRuleColor == NULL && pColumnRuleStyle == NULL && pColumnRuleWidth == NULL) { return FALSE; } if (pColumnRuleStyle == NULL) { pColumnRuleStyle = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None); } if (pColumnRuleWidth == NULL) { pColumnRuleWidth = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Medium); } if (pColumnRuleColor == NULL) { 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 = NULL; while (parser.NextValue(eType, pszValue, iValueLen)) { switch (eType) { case FDE_CSSPRIMITIVETYPE_String: { const FDE_CSSPROPERTYVALUETABLE* pValue = FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); if (pValue != NULL) { 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 != NULL) { 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 = NULL; IFDE_CSSPrimitiveValue* pColumnCount = NULL; 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 == NULL && 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 == NULL) { pColumnCount = NewNumberValue(pStaticStore, eType, fValue); } break; default: if (pColumnWidth == NULL) { pColumnWidth = NewNumberValue(pStaticStore, eType, fValue); } break; } } } break; default: break; } } if (pColumnWidth == NULL && pColumnCount == NULL) { return FALSE; } else if (pColumnWidth == NULL) { pColumnWidth = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Auto); } else if (pColumnCount == NULL) { 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 = NULL; IFDE_CSSPrimitiveValue* pOverflowY = NULL; 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 != NULL) { 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 != NULL && pOverflowY != NULL) { return FALSE; } else if (pOverflowX == NULL) { pOverflowX = NewEnumValue(pStaticStore, pValue->eName); } else if (pOverflowY == NULL) { pOverflowY = NewEnumValue(pStaticStore, pValue->eName); } break; default: break; } } } } if (pOverflowX == NULL && pOverflowY == NULL) { return FALSE; } else if (pOverflowY == NULL) { pOverflowY = NewEnumValue(pStaticStore, pOverflowX->GetEnum()); } AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_OverflowX, pOverflowX, bImportant); AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_OverflowY, pOverflowY, bImportant); return TRUE; }