// 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 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<uint32_t, FX_WCHAR*>* 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] == '!' &&
|
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 = 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;
|
}
|