1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "xfa/src/foxitlib.h"
8 #include "fde_cssdeclaration.h"
GetProperty(FDE_CSSPROPERTY eProperty,FX_BOOL & bImportant) const9 IFDE_CSSValue* CFDE_CSSDeclaration::GetProperty(FDE_CSSPROPERTY eProperty,
10 FX_BOOL& bImportant) const {
11 for (FDE_LPCSSPROPERTYHOLDER pHolder = m_pFirstProperty; pHolder;
12 pHolder = pHolder->pNext) {
13 if (pHolder->eProperty == eProperty) {
14 bImportant = pHolder->bImportant;
15 return pHolder->pValue;
16 }
17 }
18 return NULL;
19 }
GetStartPosition() const20 FX_POSITION CFDE_CSSDeclaration::GetStartPosition() const {
21 return (FX_POSITION)m_pFirstProperty;
22 }
GetNextProperty(FX_POSITION & pos,FDE_CSSPROPERTY & eProperty,IFDE_CSSValue * & pValue,FX_BOOL & bImportant) const23 void CFDE_CSSDeclaration::GetNextProperty(FX_POSITION& pos,
24 FDE_CSSPROPERTY& eProperty,
25 IFDE_CSSValue*& pValue,
26 FX_BOOL& bImportant) const {
27 FDE_LPCSSPROPERTYHOLDER pHolder = (FDE_LPCSSPROPERTYHOLDER)pos;
28 FXSYS_assert(pHolder != NULL);
29 bImportant = pHolder->bImportant;
30 eProperty = (FDE_CSSPROPERTY)pHolder->eProperty;
31 pValue = pHolder->pValue;
32 pos = (FX_POSITION)pHolder->pNext;
33 }
GetStartCustom() const34 FX_POSITION CFDE_CSSDeclaration::GetStartCustom() const {
35 return (FX_POSITION)m_pFirstCustom;
36 }
GetNextCustom(FX_POSITION & pos,CFX_WideString & wsName,CFX_WideString & wsValue) const37 void CFDE_CSSDeclaration::GetNextCustom(FX_POSITION& pos,
38 CFX_WideString& wsName,
39 CFX_WideString& wsValue) const {
40 FDE_LPCSSCUSTOMPROPERTY pProperty = (FDE_LPCSSCUSTOMPROPERTY)pos;
41 if (pProperty == NULL) {
42 return;
43 }
44 wsName = pProperty->pwsName;
45 wsValue = pProperty->pwsValue;
46 pos = (FX_POSITION)pProperty->pNext;
47 }
CopyToLocal(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen)48 const FX_WCHAR* CFDE_CSSDeclaration::CopyToLocal(FDE_LPCCSSPROPERTYARGS pArgs,
49 const FX_WCHAR* pszValue,
50 int32_t iValueLen) {
51 FXSYS_assert(iValueLen > 0);
52 CFX_MapPtrToPtr* pCache = pArgs->pStringCache;
53 void* pKey = NULL;
54 if (pCache) {
55 void* pszCached = NULL;
56 pKey =
57 (void*)(uintptr_t)FX_HashCode_String_GetW(pszValue, iValueLen, FALSE);
58 if (pCache->Lookup(pKey, pszCached)) {
59 return (const FX_WCHAR*)pszCached;
60 }
61 }
62 FX_WCHAR* psz =
63 (FX_WCHAR*)pArgs->pStaticStore->Alloc((iValueLen + 1) * sizeof(FX_WCHAR));
64 if (psz == NULL) {
65 return NULL;
66 }
67 FXSYS_wcsncpy(psz, pszValue, iValueLen);
68 psz[iValueLen] = '\0';
69 if (pCache) {
70 pCache->SetAt(pKey, psz);
71 }
72 return psz;
73 }
NewNumberValue(IFX_MEMAllocator * pStaticStore,FDE_CSSPRIMITIVETYPE eUnit,FX_FLOAT fValue) const74 IFDE_CSSPrimitiveValue* CFDE_CSSDeclaration::NewNumberValue(
75 IFX_MEMAllocator* pStaticStore,
76 FDE_CSSPRIMITIVETYPE eUnit,
77 FX_FLOAT fValue) const {
78 static CFDE_CSSPrimitiveValue s_ZeroValue(FDE_CSSPRIMITIVETYPE_Number, 0.0f);
79 if (eUnit == FDE_CSSPRIMITIVETYPE_Number && FXSYS_fabs(fValue) < 0.001f) {
80 return &s_ZeroValue;
81 }
82 return FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eUnit, fValue);
83 }
NewEnumValue(IFX_MEMAllocator * pStaticStore,FDE_CSSPROPERTYVALUE eValue) const84 inline IFDE_CSSPrimitiveValue* CFDE_CSSDeclaration::NewEnumValue(
85 IFX_MEMAllocator* pStaticStore,
86 FDE_CSSPROPERTYVALUE eValue) const {
87 return FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eValue);
88 }
AddPropertyHolder(IFX_MEMAllocator * pStaticStore,FDE_CSSPROPERTY eProperty,IFDE_CSSValue * pValue,FX_BOOL bImportant)89 void CFDE_CSSDeclaration::AddPropertyHolder(IFX_MEMAllocator* pStaticStore,
90 FDE_CSSPROPERTY eProperty,
91 IFDE_CSSValue* pValue,
92 FX_BOOL bImportant) {
93 FDE_LPCSSPROPERTYHOLDER pHolder =
94 FDE_NewWith(pStaticStore) FDE_CSSPROPERTYHOLDER;
95 pHolder->bImportant = bImportant;
96 pHolder->eProperty = eProperty;
97 pHolder->pValue = pValue;
98 pHolder->pNext = NULL;
99 if (m_pLastProperty == NULL) {
100 m_pLastProperty = m_pFirstProperty = pHolder;
101 } else {
102 m_pLastProperty->pNext = pHolder;
103 m_pLastProperty = pHolder;
104 }
105 }
AddProperty(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen)106 FX_BOOL CFDE_CSSDeclaration::AddProperty(FDE_LPCCSSPROPERTYARGS pArgs,
107 const FX_WCHAR* pszValue,
108 int32_t iValueLen) {
109 FXSYS_assert(iValueLen > 0);
110 FX_BOOL bImportant = FALSE;
111 if (iValueLen >= 10 && pszValue[iValueLen - 10] == '!' &&
112 FX_wcsnicmp(L"important", pszValue + iValueLen - 9, 9) == 0) {
113 if ((iValueLen -= 10) == 0) {
114 return FALSE;
115 }
116 bImportant = TRUE;
117 }
118 const FX_DWORD dwType = pArgs->pProperty->dwType;
119 switch (dwType & 0x0F) {
120 case FDE_CSSVALUETYPE_Primitive: {
121 static const FX_DWORD g_ValueGuessOrder[] = {
122 FDE_CSSVALUETYPE_MaybeNumber, FDE_CSSVALUETYPE_MaybeEnum,
123 FDE_CSSVALUETYPE_MaybeColor, FDE_CSSVALUETYPE_MaybeURI,
124 FDE_CSSVALUETYPE_MaybeFunction, FDE_CSSVALUETYPE_MaybeString,
125 };
126 static const int32_t g_ValueGuessCount =
127 sizeof(g_ValueGuessOrder) / sizeof(FX_DWORD);
128 for (int32_t i = 0; i < g_ValueGuessCount; ++i) {
129 const FX_DWORD dwMatch = dwType & g_ValueGuessOrder[i];
130 if (dwMatch == 0) {
131 continue;
132 }
133 IFDE_CSSValue* pCSSValue = NULL;
134 switch (dwMatch) {
135 case FDE_CSSVALUETYPE_MaybeFunction:
136 pCSSValue = ParseFunction(pArgs, pszValue, iValueLen);
137 break;
138 case FDE_CSSVALUETYPE_MaybeNumber:
139 pCSSValue = ParseNumber(pArgs, pszValue, iValueLen);
140 break;
141 case FDE_CSSVALUETYPE_MaybeEnum:
142 pCSSValue = ParseEnum(pArgs, pszValue, iValueLen);
143 break;
144 case FDE_CSSVALUETYPE_MaybeColor:
145 pCSSValue = ParseColor(pArgs, pszValue, iValueLen);
146 break;
147 case FDE_CSSVALUETYPE_MaybeURI:
148 pCSSValue = ParseURI(pArgs, pszValue, iValueLen);
149 break;
150 case FDE_CSSVALUETYPE_MaybeString:
151 pCSSValue = ParseString(pArgs, pszValue, iValueLen);
152 break;
153 default:
154 break;
155 }
156 if (pCSSValue != NULL) {
157 AddPropertyHolder(pArgs->pStaticStore, pArgs->pProperty->eName,
158 pCSSValue, bImportant);
159 return TRUE;
160 }
161 if (FDE_IsOnlyValue(dwType, g_ValueGuessOrder[i])) {
162 return FALSE;
163 }
164 }
165 } break;
166 case FDE_CSSVALUETYPE_Shorthand: {
167 IFX_MEMAllocator* pStaticStore = pArgs->pStaticStore;
168 IFDE_CSSValue *pColor, *pStyle, *pWidth;
169 switch (pArgs->pProperty->eName) {
170 case FDE_CSSPROPERTY_Font:
171 return ParseFontProperty(pArgs, pszValue, iValueLen, bImportant);
172 case FDE_CSSPROPERTY_Background:
173 return ParseBackgroundProperty(pArgs, pszValue, iValueLen,
174 bImportant);
175 case FDE_CSSPROPERTY_ListStyle:
176 return ParseListStyleProperty(pArgs, pszValue, iValueLen, bImportant);
177 case FDE_CSSPROPERTY_Border:
178 if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor,
179 pStyle, pWidth)) {
180 AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
181 FDE_CSSPROPERTY_BorderLeftColor,
182 FDE_CSSPROPERTY_BorderLeftStyle,
183 FDE_CSSPROPERTY_BorderLeftWidth);
184 AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
185 FDE_CSSPROPERTY_BorderTopColor,
186 FDE_CSSPROPERTY_BorderTopStyle,
187 FDE_CSSPROPERTY_BorderTopWidth);
188 AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
189 FDE_CSSPROPERTY_BorderRightColor,
190 FDE_CSSPROPERTY_BorderRightStyle,
191 FDE_CSSPROPERTY_BorderRightWidth);
192 AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
193 FDE_CSSPROPERTY_BorderBottomColor,
194 FDE_CSSPROPERTY_BorderBottomStyle,
195 FDE_CSSPROPERTY_BorderBottomWidth);
196 return TRUE;
197 }
198 break;
199 case FDE_CSSPROPERTY_BorderLeft:
200 if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor,
201 pStyle, pWidth)) {
202 AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
203 FDE_CSSPROPERTY_BorderLeftColor,
204 FDE_CSSPROPERTY_BorderLeftStyle,
205 FDE_CSSPROPERTY_BorderLeftWidth);
206 return TRUE;
207 }
208 break;
209 case FDE_CSSPROPERTY_BorderTop:
210 if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor,
211 pStyle, pWidth)) {
212 AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
213 FDE_CSSPROPERTY_BorderTopColor,
214 FDE_CSSPROPERTY_BorderTopStyle,
215 FDE_CSSPROPERTY_BorderTopWidth);
216 return TRUE;
217 }
218 break;
219 case FDE_CSSPROPERTY_BorderRight:
220 if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor,
221 pStyle, pWidth)) {
222 AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
223 FDE_CSSPROPERTY_BorderRightColor,
224 FDE_CSSPROPERTY_BorderRightStyle,
225 FDE_CSSPROPERTY_BorderRightWidth);
226 return TRUE;
227 }
228 break;
229 case FDE_CSSPROPERTY_BorderBottom:
230 if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor,
231 pStyle, pWidth)) {
232 AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
233 FDE_CSSPROPERTY_BorderBottomColor,
234 FDE_CSSPROPERTY_BorderBottomStyle,
235 FDE_CSSPROPERTY_BorderBottomWidth);
236 return TRUE;
237 }
238 break;
239 case FDE_CSSPROPERTY_Overflow:
240 return ParseOverflowProperty(pArgs, pszValue, iValueLen, bImportant);
241 case FDE_CSSPROPERTY_ColumnRule:
242 return ParseColumnRuleProperty(pArgs, pszValue, iValueLen,
243 bImportant);
244 default:
245 break;
246 }
247 } break;
248 case FDE_CSSVALUETYPE_List:
249 switch (pArgs->pProperty->eName) {
250 case FDE_CSSPROPERTY_CounterIncrement:
251 case FDE_CSSPROPERTY_CounterReset:
252 return ParseCounterProperty(pArgs, pszValue, iValueLen, bImportant);
253 case FDE_CSSPROPERTY_Content:
254 return ParseContentProperty(pArgs, pszValue, iValueLen, bImportant);
255 default:
256 return ParseValueListProperty(pArgs, pszValue, iValueLen, bImportant);
257 }
258 default:
259 FXSYS_assert(FALSE);
260 break;
261 }
262 return FALSE;
263 }
AddProperty(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszName,int32_t iNameLen,const FX_WCHAR * pszValue,int32_t iValueLen)264 FX_BOOL CFDE_CSSDeclaration::AddProperty(FDE_LPCCSSPROPERTYARGS pArgs,
265 const FX_WCHAR* pszName,
266 int32_t iNameLen,
267 const FX_WCHAR* pszValue,
268 int32_t iValueLen) {
269 FDE_LPCSSCUSTOMPROPERTY pProperty =
270 FDE_NewWith(pArgs->pStaticStore) FDE_CSSCUSTOMPROPERTY;
271 pProperty->pwsName = CopyToLocal(pArgs, pszName, iNameLen);
272 pProperty->pwsValue = CopyToLocal(pArgs, pszValue, iValueLen);
273 pProperty->pNext = NULL;
274 if (m_pLastCustom == NULL) {
275 m_pLastCustom = m_pFirstCustom = pProperty;
276 } else {
277 m_pLastCustom->pNext = pProperty;
278 m_pLastCustom = pProperty;
279 }
280 return TRUE;
281 }
ParseNumber(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen)282 IFDE_CSSValue* CFDE_CSSDeclaration::ParseNumber(FDE_LPCCSSPROPERTYARGS pArgs,
283 const FX_WCHAR* pszValue,
284 int32_t iValueLen) {
285 FX_FLOAT fValue;
286 FDE_CSSPRIMITIVETYPE eUnit;
287 if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eUnit)) {
288 return NULL;
289 }
290 return NewNumberValue(pArgs->pStaticStore, eUnit, fValue);
291 }
ParseEnum(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen)292 IFDE_CSSValue* CFDE_CSSDeclaration::ParseEnum(FDE_LPCCSSPROPERTYARGS pArgs,
293 const FX_WCHAR* pszValue,
294 int32_t iValueLen) {
295 FDE_LPCCSSPROPERTYVALUETABLE pValue =
296 FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
297 return pValue ? NewEnumValue(pArgs->pStaticStore, pValue->eName) : NULL;
298 }
ParseColor(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen)299 IFDE_CSSValue* CFDE_CSSDeclaration::ParseColor(FDE_LPCCSSPROPERTYARGS pArgs,
300 const FX_WCHAR* pszValue,
301 int32_t iValueLen) {
302 FX_ARGB dwColor;
303 if (!FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
304 return NULL;
305 }
306 return FDE_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(dwColor);
307 }
ParseURI(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen)308 IFDE_CSSValue* CFDE_CSSDeclaration::ParseURI(FDE_LPCCSSPROPERTYARGS pArgs,
309 const FX_WCHAR* pszValue,
310 int32_t iValueLen) {
311 int32_t iOffset;
312 if (!FDE_ParseCSSURI(pszValue, iValueLen, iOffset, iValueLen)) {
313 return NULL;
314 }
315 if (iValueLen <= 0) {
316 return NULL;
317 }
318 pszValue = CopyToLocal(pArgs, pszValue + iOffset, iValueLen);
319 return pszValue
320 ? FDE_NewWith(pArgs->pStaticStore)
321 CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_URI, pszValue)
322 : NULL;
323 }
ParseString(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen)324 IFDE_CSSValue* CFDE_CSSDeclaration::ParseString(FDE_LPCCSSPROPERTYARGS pArgs,
325 const FX_WCHAR* pszValue,
326 int32_t iValueLen) {
327 int32_t iOffset;
328 if (!FDE_ParseCSSString(pszValue, iValueLen, iOffset, iValueLen)) {
329 return NULL;
330 }
331 if (iValueLen <= 0) {
332 return NULL;
333 }
334 pszValue = CopyToLocal(pArgs, pszValue + iOffset, iValueLen);
335 return pszValue
336 ? FDE_NewWith(pArgs->pStaticStore)
337 CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, pszValue)
338 : NULL;
339 }
ParseFunction(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen)340 IFDE_CSSValue* CFDE_CSSDeclaration::ParseFunction(FDE_LPCCSSPROPERTYARGS pArgs,
341 const FX_WCHAR* pszValue,
342 int32_t iValueLen) {
343 if (pszValue[iValueLen - 1] != ')') {
344 return NULL;
345 }
346 int32_t iStartBracket = 0;
347 while (pszValue[iStartBracket] != '(') {
348 if (iStartBracket < iValueLen) {
349 iStartBracket++;
350 } else {
351 return NULL;
352 }
353 }
354 if (iStartBracket == 0) {
355 return NULL;
356 }
357 const FX_WCHAR* pszFuncName = CopyToLocal(pArgs, pszValue, iStartBracket);
358 pszValue += (iStartBracket + 1);
359 iValueLen -= (iStartBracket + 2);
360 CFDE_CSSValueArray argumentArr;
361 CFDE_CSSValueListParser parser(pszValue, iValueLen, ',');
362 FDE_CSSPRIMITIVETYPE ePrimitiveType;
363 while (parser.NextValue(ePrimitiveType, pszValue, iValueLen)) {
364 switch (ePrimitiveType) {
365 case FDE_CSSPRIMITIVETYPE_String: {
366 FDE_LPCCSSPROPERTYVALUETABLE pPropertyValue =
367 FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
368 if (pPropertyValue != NULL) {
369 argumentArr.Add(
370 NewEnumValue(pArgs->pStaticStore, pPropertyValue->eName));
371 continue;
372 }
373 IFDE_CSSValue* pFunctionValue =
374 ParseFunction(pArgs, pszValue, iValueLen);
375 if (pFunctionValue != NULL) {
376 argumentArr.Add(pFunctionValue);
377 continue;
378 }
379 argumentArr.Add(FDE_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(
380 FDE_CSSPRIMITIVETYPE_String,
381 CopyToLocal(pArgs, pszValue, iValueLen)));
382 } break;
383 case FDE_CSSPRIMITIVETYPE_Number: {
384 FX_FLOAT fValue;
385 if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, ePrimitiveType)) {
386 argumentArr.Add(
387 NewNumberValue(pArgs->pStaticStore, ePrimitiveType, fValue));
388 }
389 } break;
390 default:
391 argumentArr.Add(FDE_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(
392 FDE_CSSPRIMITIVETYPE_String,
393 CopyToLocal(pArgs, pszValue, iValueLen)));
394 break;
395 }
396 }
397 IFDE_CSSValueList* pArgumentList = FDE_NewWith(pArgs->pStaticStore)
398 CFDE_CSSValueList(pArgs->pStaticStore, argumentArr);
399 CFDE_CSSFunction* pFunction = FDE_NewWith(pArgs->pStaticStore)
400 CFDE_CSSFunction(pszFuncName, pArgumentList);
401 return FDE_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(pFunction);
402 }
ParseContentProperty(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen,FX_BOOL bImportant)403 FX_BOOL CFDE_CSSDeclaration::ParseContentProperty(FDE_LPCCSSPROPERTYARGS pArgs,
404 const FX_WCHAR* pszValue,
405 int32_t iValueLen,
406 FX_BOOL bImportant) {
407 IFX_MEMAllocator* pStaticStore = (IFX_MEMAllocator*)pArgs->pStaticStore;
408 CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
409 FDE_CSSPRIMITIVETYPE eType;
410 CFDE_CSSValueArray list;
411 while (parser.NextValue(eType, pszValue, iValueLen)) {
412 switch (eType) {
413 case FDE_CSSPRIMITIVETYPE_URI:
414 list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(
415 eType, CopyToLocal(pArgs, pszValue, iValueLen)));
416 break;
417 case FDE_CSSPRIMITIVETYPE_Number:
418 return FALSE;
419 case FDE_CSSPRIMITIVETYPE_String: {
420 FDE_LPCCSSPROPERTYVALUETABLE pValue =
421 FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
422 if (pValue != NULL) {
423 switch (pValue->eName) {
424 case FDE_CSSPROPERTYVALUE_Normal:
425 case FDE_CSSPROPERTYVALUE_None: {
426 if (list.GetSize() == 0) {
427 list.Add(NewEnumValue(pStaticStore, pValue->eName));
428 } else {
429 return FALSE;
430 }
431 } break;
432 case FDE_CSSPROPERTYVALUE_OpenQuote:
433 case FDE_CSSPROPERTYVALUE_CloseQuote:
434 case FDE_CSSPROPERTYVALUE_NoOpenQuote:
435 case FDE_CSSPROPERTYVALUE_NoCloseQuote:
436 list.Add(NewEnumValue(pStaticStore, pValue->eName));
437 break;
438 default:
439 return FALSE;
440 }
441 continue;
442 }
443 IFDE_CSSValue* pFunction = ParseFunction(pArgs, pszValue, iValueLen);
444 if (pFunction != NULL) {
445 list.Add(pFunction);
446 continue;
447 }
448 list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(
449 eType, CopyToLocal(pArgs, pszValue, iValueLen)));
450 } break;
451 case FDE_CSSPRIMITIVETYPE_RGB:
452 return FALSE;
453 default:
454 break;
455 }
456 }
457 if (list.GetSize() == 0) {
458 return FALSE;
459 }
460 AddPropertyHolder(pStaticStore, pArgs->pProperty->eName,
461 FDE_NewWith(pStaticStore)
462 CFDE_CSSValueList(pStaticStore, list),
463 bImportant);
464 return TRUE;
465 }
ParseCounterProperty(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen,FX_BOOL bImportant)466 FX_BOOL CFDE_CSSDeclaration::ParseCounterProperty(FDE_LPCCSSPROPERTYARGS pArgs,
467 const FX_WCHAR* pszValue,
468 int32_t iValueLen,
469 FX_BOOL bImportant) {
470 IFX_MEMAllocator* pStaticStore = pArgs->pStaticStore;
471 CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
472 CFDE_CSSValueArray list;
473 CFDE_CSSValueArray listFull;
474 FDE_CSSPRIMITIVETYPE eType;
475 while (parser.NextValue(eType, pszValue, iValueLen)) {
476 switch (eType) {
477 case FDE_CSSPRIMITIVETYPE_Number: {
478 FX_FLOAT fValue;
479 if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
480 if (list.GetSize() == 1) {
481 list.Add(NewNumberValue(pStaticStore, eType, fValue));
482 listFull.Add(FDE_NewWith(pStaticStore)
483 CFDE_CSSValueList(pStaticStore, list));
484 list.RemoveAll();
485 } else {
486 return FALSE;
487 }
488 }
489 } break;
490 case FDE_CSSPRIMITIVETYPE_String: {
491 if (list.GetSize() == 0) {
492 pszValue = CopyToLocal(pArgs, pszValue, iValueLen);
493 list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(
494 FDE_CSSPRIMITIVETYPE_String, pszValue));
495 } else {
496 listFull.Add(FDE_NewWith(pStaticStore)
497 CFDE_CSSValueList(pStaticStore, list));
498 list.RemoveAll();
499 pszValue = CopyToLocal(pArgs, pszValue, iValueLen);
500 list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(
501 FDE_CSSPRIMITIVETYPE_String, pszValue));
502 }
503 } break;
504 default:
505 break;
506 }
507 }
508 if (list.GetSize() == 1) {
509 listFull.Add(FDE_NewWith(pStaticStore)
510 CFDE_CSSValueList(pStaticStore, list));
511 }
512 if (listFull.GetSize() == 0) {
513 return FALSE;
514 }
515 AddPropertyHolder(pStaticStore, pArgs->pProperty->eName,
516 FDE_NewWith(pStaticStore)
517 CFDE_CSSValueList(pStaticStore, listFull),
518 bImportant);
519 return TRUE;
520 }
ParseValueListProperty(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen,FX_BOOL bImportant)521 FX_BOOL CFDE_CSSDeclaration::ParseValueListProperty(
522 FDE_LPCCSSPROPERTYARGS pArgs,
523 const FX_WCHAR* pszValue,
524 int32_t iValueLen,
525 FX_BOOL bImportant) {
526 IFX_MEMAllocator* pStaticStore = pArgs->pStaticStore;
527 FX_WCHAR separator =
528 (pArgs->pProperty->eName == FDE_CSSPROPERTY_FontFamily) ? ',' : ' ';
529 CFDE_CSSValueListParser parser(pszValue, iValueLen, separator);
530 const FX_DWORD dwType = pArgs->pProperty->dwType;
531 FDE_CSSPRIMITIVETYPE eType;
532 CFDE_CSSValueArray list;
533 while (parser.NextValue(eType, pszValue, iValueLen)) {
534 switch (eType) {
535 case FDE_CSSPRIMITIVETYPE_Number:
536 if (dwType & FDE_CSSVALUETYPE_MaybeNumber) {
537 FX_FLOAT fValue;
538 if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
539 list.Add(NewNumberValue(pStaticStore, eType, fValue));
540 }
541 }
542 break;
543 case FDE_CSSPRIMITIVETYPE_String:
544 if (dwType & FDE_CSSVALUETYPE_MaybeColor) {
545 FX_ARGB dwColor;
546 if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
547 list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor));
548 continue;
549 }
550 }
551 if (dwType & FDE_CSSVALUETYPE_MaybeEnum) {
552 FDE_LPCCSSPROPERTYVALUETABLE pValue =
553 FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
554 if (pValue != NULL) {
555 list.Add(NewEnumValue(pStaticStore, pValue->eName));
556 continue;
557 }
558 }
559 if (dwType & FDE_CSSVALUETYPE_MaybeString) {
560 pszValue = CopyToLocal(pArgs, pszValue, iValueLen);
561 list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(
562 FDE_CSSPRIMITIVETYPE_String, pszValue));
563 }
564 break;
565 case FDE_CSSPRIMITIVETYPE_RGB:
566 if (dwType & FDE_CSSVALUETYPE_MaybeColor) {
567 FX_ARGB dwColor;
568 if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
569 list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor));
570 }
571 }
572 break;
573 default:
574 break;
575 }
576 }
577 if (list.GetSize() == 0) {
578 return FALSE;
579 }
580 switch (pArgs->pProperty->eName) {
581 case FDE_CSSPROPERTY_BorderColor:
582 return Add4ValuesProperty(
583 pStaticStore, list, bImportant, FDE_CSSPROPERTY_BorderLeftColor,
584 FDE_CSSPROPERTY_BorderTopColor, FDE_CSSPROPERTY_BorderRightColor,
585 FDE_CSSPROPERTY_BorderBottomColor);
586 case FDE_CSSPROPERTY_BorderStyle:
587 return Add4ValuesProperty(
588 pStaticStore, list, bImportant, FDE_CSSPROPERTY_BorderLeftStyle,
589 FDE_CSSPROPERTY_BorderTopStyle, FDE_CSSPROPERTY_BorderRightStyle,
590 FDE_CSSPROPERTY_BorderBottomStyle);
591 case FDE_CSSPROPERTY_BorderWidth:
592 return Add4ValuesProperty(
593 pStaticStore, list, bImportant, FDE_CSSPROPERTY_BorderLeftWidth,
594 FDE_CSSPROPERTY_BorderTopWidth, FDE_CSSPROPERTY_BorderRightWidth,
595 FDE_CSSPROPERTY_BorderBottomWidth);
596 case FDE_CSSPROPERTY_Margin:
597 return Add4ValuesProperty(
598 pStaticStore, list, bImportant, FDE_CSSPROPERTY_MarginLeft,
599 FDE_CSSPROPERTY_MarginTop, FDE_CSSPROPERTY_MarginRight,
600 FDE_CSSPROPERTY_MarginBottom);
601 case FDE_CSSPROPERTY_Padding:
602 return Add4ValuesProperty(
603 pStaticStore, list, bImportant, FDE_CSSPROPERTY_PaddingLeft,
604 FDE_CSSPROPERTY_PaddingTop, FDE_CSSPROPERTY_PaddingRight,
605 FDE_CSSPROPERTY_PaddingBottom);
606 default: {
607 CFDE_CSSValueList* pList =
608 FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, list);
609 AddPropertyHolder(pStaticStore, pArgs->pProperty->eName, pList,
610 bImportant);
611 return TRUE;
612 } break;
613 }
614 return FALSE;
615 }
Add4ValuesProperty(IFX_MEMAllocator * pStaticStore,const CFDE_CSSValueArray & list,FX_BOOL bImportant,FDE_CSSPROPERTY eLeft,FDE_CSSPROPERTY eTop,FDE_CSSPROPERTY eRight,FDE_CSSPROPERTY eBottom)616 FX_BOOL CFDE_CSSDeclaration::Add4ValuesProperty(IFX_MEMAllocator* pStaticStore,
617 const CFDE_CSSValueArray& list,
618 FX_BOOL bImportant,
619 FDE_CSSPROPERTY eLeft,
620 FDE_CSSPROPERTY eTop,
621 FDE_CSSPROPERTY eRight,
622 FDE_CSSPROPERTY eBottom) {
623 switch (list.GetSize()) {
624 case 1:
625 AddPropertyHolder(pStaticStore, eLeft, list[0], bImportant);
626 AddPropertyHolder(pStaticStore, eTop, list[0], bImportant);
627 AddPropertyHolder(pStaticStore, eRight, list[0], bImportant);
628 AddPropertyHolder(pStaticStore, eBottom, list[0], bImportant);
629 return TRUE;
630 case 2:
631 AddPropertyHolder(pStaticStore, eLeft, list[1], bImportant);
632 AddPropertyHolder(pStaticStore, eTop, list[0], bImportant);
633 AddPropertyHolder(pStaticStore, eRight, list[1], bImportant);
634 AddPropertyHolder(pStaticStore, eBottom, list[0], bImportant);
635 return TRUE;
636 case 3:
637 AddPropertyHolder(pStaticStore, eLeft, list[1], bImportant);
638 AddPropertyHolder(pStaticStore, eTop, list[0], bImportant);
639 AddPropertyHolder(pStaticStore, eRight, list[1], bImportant);
640 AddPropertyHolder(pStaticStore, eBottom, list[2], bImportant);
641 return TRUE;
642 case 4:
643 AddPropertyHolder(pStaticStore, eLeft, list[3], bImportant);
644 AddPropertyHolder(pStaticStore, eTop, list[0], bImportant);
645 AddPropertyHolder(pStaticStore, eRight, list[1], bImportant);
646 AddPropertyHolder(pStaticStore, eBottom, list[2], bImportant);
647 return TRUE;
648 default:
649 break;
650 }
651 return FALSE;
652 }
ParseBorderPropoerty(IFX_MEMAllocator * pStaticStore,const FX_WCHAR * pszValue,int32_t iValueLen,IFDE_CSSValue * & pColor,IFDE_CSSValue * & pStyle,IFDE_CSSValue * & pWidth) const653 FX_BOOL CFDE_CSSDeclaration::ParseBorderPropoerty(
654 IFX_MEMAllocator* pStaticStore,
655 const FX_WCHAR* pszValue,
656 int32_t iValueLen,
657 IFDE_CSSValue*& pColor,
658 IFDE_CSSValue*& pStyle,
659 IFDE_CSSValue*& pWidth) const {
660 pColor = pStyle = pWidth = NULL;
661 CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
662 FDE_CSSPRIMITIVETYPE eType;
663 while (parser.NextValue(eType, pszValue, iValueLen)) {
664 switch (eType) {
665 case FDE_CSSPRIMITIVETYPE_Number:
666 if (pWidth == NULL) {
667 FX_FLOAT fValue;
668 if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
669 pWidth = NewNumberValue(pStaticStore, eType, fValue);
670 }
671 }
672 break;
673 case FDE_CSSPRIMITIVETYPE_RGB:
674 if (pColor == NULL) {
675 FX_ARGB dwColor;
676 if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
677 pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor);
678 }
679 }
680 break;
681 case FDE_CSSPRIMITIVETYPE_String: {
682 FDE_LPCCSSCOLORTABLE pColorItem =
683 FDE_GetCSSColorByName(pszValue, iValueLen);
684 if (pColorItem != NULL) {
685 if (pColor == NULL) {
686 pColor = FDE_NewWith(pStaticStore)
687 CFDE_CSSPrimitiveValue(pColorItem->dwValue);
688 }
689 continue;
690 }
691 FDE_LPCCSSPROPERTYVALUETABLE pValue =
692 FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
693 if (pValue == NULL) {
694 continue;
695 }
696 switch (pValue->eName) {
697 case FDE_CSSPROPERTYVALUE_Transparent:
698 if (pColor == NULL) {
699 pColor =
700 FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0);
701 }
702 break;
703 case FDE_CSSPROPERTYVALUE_Thin:
704 case FDE_CSSPROPERTYVALUE_Thick:
705 case FDE_CSSPROPERTYVALUE_Medium:
706 if (pWidth == NULL) {
707 pWidth = NewEnumValue(pStaticStore, pValue->eName);
708 }
709 break;
710 case FDE_CSSPROPERTYVALUE_None:
711 case FDE_CSSPROPERTYVALUE_Hidden:
712 case FDE_CSSPROPERTYVALUE_Dotted:
713 case FDE_CSSPROPERTYVALUE_Dashed:
714 case FDE_CSSPROPERTYVALUE_Solid:
715 case FDE_CSSPROPERTYVALUE_Double:
716 case FDE_CSSPROPERTYVALUE_Groove:
717 case FDE_CSSPROPERTYVALUE_Ridge:
718 case FDE_CSSPROPERTYVALUE_Inset:
719 case FDE_CSSPROPERTYVALUE_Outset:
720 if (pStyle == NULL) {
721 pStyle = NewEnumValue(pStaticStore, pValue->eName);
722 }
723 break;
724 default:
725 break;
726 }
727 }; break;
728 default:
729 break;
730 }
731 }
732 if (pColor == NULL) {
733 pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0);
734 }
735 if (pStyle == NULL) {
736 pStyle = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None);
737 }
738 if (pWidth == NULL) {
739 pWidth = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f);
740 }
741 return TRUE;
742 }
AddBorderProperty(IFX_MEMAllocator * pStaticStore,IFDE_CSSValue * pColor,IFDE_CSSValue * pStyle,IFDE_CSSValue * pWidth,FX_BOOL bImportant,FDE_CSSPROPERTY eColor,FDE_CSSPROPERTY eStyle,FDE_CSSPROPERTY eWidth)743 void CFDE_CSSDeclaration::AddBorderProperty(IFX_MEMAllocator* pStaticStore,
744 IFDE_CSSValue* pColor,
745 IFDE_CSSValue* pStyle,
746 IFDE_CSSValue* pWidth,
747 FX_BOOL bImportant,
748 FDE_CSSPROPERTY eColor,
749 FDE_CSSPROPERTY eStyle,
750 FDE_CSSPROPERTY eWidth) {
751 AddPropertyHolder(pStaticStore, eStyle, pStyle, bImportant);
752 AddPropertyHolder(pStaticStore, eWidth, pWidth, bImportant);
753 AddPropertyHolder(pStaticStore, eColor, pColor, bImportant);
754 }
ParseListStyleProperty(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen,FX_BOOL bImportant)755 FX_BOOL CFDE_CSSDeclaration::ParseListStyleProperty(
756 FDE_LPCCSSPROPERTYARGS pArgs,
757 const FX_WCHAR* pszValue,
758 int32_t iValueLen,
759 FX_BOOL bImportant) {
760 IFX_MEMAllocator* pStaticStore = pArgs->pStaticStore;
761 CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
762 IFDE_CSSPrimitiveValue *pType = NULL, *pImage = NULL, *pPosition = NULL;
763 FDE_CSSPRIMITIVETYPE eType;
764 while (parser.NextValue(eType, pszValue, iValueLen)) {
765 switch (eType) {
766 case FDE_CSSPRIMITIVETYPE_URI:
767 if (pImage == NULL) {
768 pImage = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(
769 eType, CopyToLocal(pArgs, pszValue, iValueLen));
770 }
771 break;
772 case FDE_CSSPRIMITIVETYPE_String: {
773 FDE_LPCCSSPROPERTYVALUETABLE pValue =
774 FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
775 if (pValue == NULL) {
776 break;
777 }
778 switch (pValue->eName) {
779 case FDE_CSSPROPERTYVALUE_None:
780 if (pImage == NULL) {
781 pImage = NewEnumValue(pStaticStore, pValue->eName);
782 } else if (pType == NULL) {
783 pImage = NewEnumValue(pStaticStore, pValue->eName);
784 }
785 break;
786 case FDE_CSSPROPERTYVALUE_Inside:
787 case FDE_CSSPROPERTYVALUE_Outside:
788 if (pPosition == NULL) {
789 pPosition = NewEnumValue(pStaticStore, pValue->eName);
790 }
791 break;
792 case FDE_CSSPROPERTYVALUE_Disc:
793 case FDE_CSSPROPERTYVALUE_Circle:
794 case FDE_CSSPROPERTYVALUE_Square:
795 case FDE_CSSPROPERTYVALUE_Decimal:
796 case FDE_CSSPROPERTYVALUE_DecimalLeadingZero:
797 case FDE_CSSPROPERTYVALUE_LowerRoman:
798 case FDE_CSSPROPERTYVALUE_UpperRoman:
799 case FDE_CSSPROPERTYVALUE_LowerGreek:
800 case FDE_CSSPROPERTYVALUE_LowerLatin:
801 case FDE_CSSPROPERTYVALUE_UpperLatin:
802 case FDE_CSSPROPERTYVALUE_Armenian:
803 case FDE_CSSPROPERTYVALUE_Georgian:
804 case FDE_CSSPROPERTYVALUE_LowerAlpha:
805 case FDE_CSSPROPERTYVALUE_UpperAlpha:
806 if (pType == NULL) {
807 pType = NewEnumValue(pStaticStore, pValue->eName);
808 }
809 break;
810 default:
811 break;
812 }
813 }; break;
814 default:
815 break;
816 }
817 }
818 if (pPosition == NULL) {
819 pPosition = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Outside);
820 }
821 if (pImage == NULL) {
822 pImage = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None);
823 }
824 if (pType == NULL) {
825 pType = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None);
826 }
827 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ListStylePosition, pPosition,
828 bImportant);
829 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ListStyleImage, pImage,
830 bImportant);
831 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ListStyleType, pType,
832 bImportant);
833 return TRUE;
834 }
ParseBackgroundProperty(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen,FX_BOOL bImportant)835 FX_BOOL CFDE_CSSDeclaration::ParseBackgroundProperty(
836 FDE_LPCCSSPROPERTYARGS pArgs,
837 const FX_WCHAR* pszValue,
838 int32_t iValueLen,
839 FX_BOOL bImportant) {
840 IFX_MEMAllocator* pStaticStore = pArgs->pStaticStore;
841 CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
842 IFDE_CSSPrimitiveValue *pColor = NULL, *pImage = NULL, *pRepeat = NULL;
843 IFDE_CSSPrimitiveValue *pPosX = NULL, *pPosY = NULL, *pAttachment = NULL;
844 FDE_CSSPRIMITIVETYPE eType;
845 while (parser.NextValue(eType, pszValue, iValueLen)) {
846 switch (eType) {
847 case FDE_CSSPRIMITIVETYPE_URI:
848 if (pImage == NULL) {
849 pImage = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(
850 eType, CopyToLocal(pArgs, pszValue, iValueLen));
851 }
852 break;
853 case FDE_CSSPRIMITIVETYPE_Number: {
854 FX_FLOAT fValue;
855 if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
856 break;
857 }
858 if (pPosX == NULL) {
859 pPosX = NewNumberValue(pStaticStore, eType, fValue);
860 } else if (pPosY == NULL) {
861 pPosY = NewNumberValue(pStaticStore, eType, fValue);
862 }
863 } break;
864 case FDE_CSSPRIMITIVETYPE_String: {
865 FDE_LPCCSSPROPERTYVALUETABLE pValue =
866 FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
867 if (pValue != NULL) {
868 switch (pValue->eName) {
869 case FDE_CSSPROPERTYVALUE_None:
870 if (pImage == NULL) {
871 pImage = NewEnumValue(pStaticStore, pValue->eName);
872 }
873 break;
874 case FDE_CSSPROPERTYVALUE_Transparent:
875 if (pColor == NULL) {
876 pColor = FDE_NewWith(pStaticStore)
877 CFDE_CSSPrimitiveValue((FX_ARGB)0);
878 }
879 break;
880 case FDE_CSSPROPERTYVALUE_Fixed:
881 case FDE_CSSPROPERTYVALUE_Scroll:
882 if (pAttachment == NULL) {
883 pAttachment = NewEnumValue(pStaticStore, pValue->eName);
884 }
885 break;
886 case FDE_CSSPROPERTYVALUE_Repeat:
887 case FDE_CSSPROPERTYVALUE_RepeatX:
888 case FDE_CSSPROPERTYVALUE_RepeatY:
889 case FDE_CSSPROPERTYVALUE_NoRepeat:
890 if (pRepeat == NULL) {
891 pRepeat = NewEnumValue(pStaticStore, pValue->eName);
892 }
893 break;
894 case FDE_CSSPROPERTYVALUE_Left:
895 case FDE_CSSPROPERTYVALUE_Right:
896 if (pPosX == NULL) {
897 pPosX = NewEnumValue(pStaticStore, pValue->eName);
898 }
899 break;
900 case FDE_CSSPROPERTYVALUE_Top:
901 case FDE_CSSPROPERTYVALUE_Bottom:
902 if (pPosY == NULL) {
903 pPosX = NewEnumValue(pStaticStore, pValue->eName);
904 }
905 break;
906 case FDE_CSSPROPERTYVALUE_Center:
907 if (pPosX == NULL) {
908 pPosX = NewEnumValue(pStaticStore, pValue->eName);
909 } else if (pPosY == NULL) {
910 pPosX = NewEnumValue(pStaticStore, pValue->eName);
911 }
912 break;
913 default:
914 break;
915 }
916 break;
917 }
918 FDE_LPCCSSCOLORTABLE pColorItem =
919 FDE_GetCSSColorByName(pszValue, iValueLen);
920 if (pColorItem != NULL)
921 if (pColor == NULL) {
922 pColor = FDE_NewWith(pStaticStore)
923 CFDE_CSSPrimitiveValue(pColorItem->dwValue);
924 }
925 } break;
926 case FDE_CSSPRIMITIVETYPE_RGB:
927 if (pColor == NULL) {
928 FX_ARGB dwColor;
929 if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
930 pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor);
931 }
932 }
933 break;
934 default:
935 break;
936 }
937 }
938 if (pColor == NULL) {
939 pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0);
940 }
941 if (pImage == NULL) {
942 pImage = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None);
943 }
944 if (pRepeat == NULL) {
945 pRepeat = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Repeat);
946 }
947 if (pAttachment == NULL) {
948 pAttachment = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Scroll);
949 }
950 if (pPosX == NULL) {
951 pPosX = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f);
952 pPosY = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f);
953 } else if (pPosY == NULL) {
954 pPosY = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f);
955 }
956 CFDE_CSSValueArray position;
957 position.Add(pPosX);
958 position.Add(pPosY);
959 CFDE_CSSValueList* pPosList =
960 FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, position);
961 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundColor, pColor,
962 bImportant);
963 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundImage, pImage,
964 bImportant);
965 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundRepeat, pRepeat,
966 bImportant);
967 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundPosition, pPosList,
968 bImportant);
969 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundAttachment,
970 pAttachment, bImportant);
971 return TRUE;
972 }
ParseFontProperty(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen,FX_BOOL bImportant)973 FX_BOOL CFDE_CSSDeclaration::ParseFontProperty(FDE_LPCCSSPROPERTYARGS pArgs,
974 const FX_WCHAR* pszValue,
975 int32_t iValueLen,
976 FX_BOOL bImportant) {
977 IFX_MEMAllocator* pStaticStore = pArgs->pStaticStore;
978 CFDE_CSSValueListParser parser(pszValue, iValueLen, '/');
979 IFDE_CSSPrimitiveValue *pStyle = NULL, *pVariant = NULL, *pWeight = NULL;
980 IFDE_CSSPrimitiveValue *pFontSize = NULL, *pLineHeight = NULL;
981 CFDE_CSSValueArray familyList;
982 FDE_CSSPRIMITIVETYPE eType;
983 while (parser.NextValue(eType, pszValue, iValueLen)) {
984 switch (eType) {
985 case FDE_CSSPRIMITIVETYPE_String: {
986 FDE_LPCCSSPROPERTYVALUETABLE pValue =
987 FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
988 if (pValue != NULL) {
989 switch (pValue->eName) {
990 case FDE_CSSPROPERTYVALUE_XxSmall:
991 case FDE_CSSPROPERTYVALUE_XSmall:
992 case FDE_CSSPROPERTYVALUE_Small:
993 case FDE_CSSPROPERTYVALUE_Medium:
994 case FDE_CSSPROPERTYVALUE_Large:
995 case FDE_CSSPROPERTYVALUE_XLarge:
996 case FDE_CSSPROPERTYVALUE_XxLarge:
997 case FDE_CSSPROPERTYVALUE_Smaller:
998 case FDE_CSSPROPERTYVALUE_Larger:
999 if (pFontSize == NULL) {
1000 pFontSize = NewEnumValue(pStaticStore, pValue->eName);
1001 }
1002 continue;
1003 case FDE_CSSPROPERTYVALUE_Bold:
1004 case FDE_CSSPROPERTYVALUE_Bolder:
1005 case FDE_CSSPROPERTYVALUE_Lighter:
1006 if (pWeight == NULL) {
1007 pWeight = NewEnumValue(pStaticStore, pValue->eName);
1008 }
1009 continue;
1010 case FDE_CSSPROPERTYVALUE_Italic:
1011 case FDE_CSSPROPERTYVALUE_Oblique:
1012 if (pStyle == NULL) {
1013 pStyle = NewEnumValue(pStaticStore, pValue->eName);
1014 }
1015 continue;
1016 case FDE_CSSPROPERTYVALUE_SmallCaps:
1017 if (pVariant == NULL) {
1018 pVariant = NewEnumValue(pStaticStore, pValue->eName);
1019 }
1020 continue;
1021 case FDE_CSSPROPERTYVALUE_Normal:
1022 if (pStyle == NULL) {
1023 pStyle = NewEnumValue(pStaticStore, pValue->eName);
1024 } else if (pVariant == NULL) {
1025 pVariant = NewEnumValue(pStaticStore, pValue->eName);
1026 } else if (pWeight == NULL) {
1027 pWeight = NewEnumValue(pStaticStore, pValue->eName);
1028 } else if (pFontSize == NULL) {
1029 pFontSize = NewEnumValue(pStaticStore, pValue->eName);
1030 } else if (pLineHeight == NULL) {
1031 pLineHeight = NewEnumValue(pStaticStore, pValue->eName);
1032 }
1033 continue;
1034 default:
1035 break;
1036 }
1037 }
1038 if (pFontSize != NULL) {
1039 familyList.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(
1040 eType, CopyToLocal(pArgs, pszValue, iValueLen)));
1041 }
1042 parser.m_Separator = ',';
1043 } break;
1044 case FDE_CSSPRIMITIVETYPE_Number: {
1045 FX_FLOAT fValue;
1046 if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
1047 break;
1048 }
1049 if (eType == FDE_CSSPRIMITIVETYPE_Number) {
1050 switch ((int32_t)fValue) {
1051 case 100:
1052 case 200:
1053 case 300:
1054 case 400:
1055 case 500:
1056 case 600:
1057 case 700:
1058 case 800:
1059 case 900:
1060 if (pWeight == NULL) {
1061 pWeight = NewNumberValue(pStaticStore,
1062 FDE_CSSPRIMITIVETYPE_Number, fValue);
1063 }
1064 continue;
1065 }
1066 }
1067 if (pFontSize == NULL) {
1068 pFontSize = NewNumberValue(pStaticStore, eType, fValue);
1069 } else if (pLineHeight == NULL) {
1070 pLineHeight = NewNumberValue(pStaticStore, eType, fValue);
1071 }
1072 } break;
1073 default:
1074 break;
1075 }
1076 }
1077 if (pStyle == NULL) {
1078 pStyle = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal);
1079 }
1080 if (pVariant == NULL) {
1081 pVariant = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal);
1082 }
1083 if (pWeight == NULL) {
1084 pWeight = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal);
1085 }
1086 if (pFontSize == NULL) {
1087 pFontSize = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Medium);
1088 }
1089 if (pLineHeight == NULL) {
1090 pLineHeight = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal);
1091 }
1092 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontStyle, pStyle,
1093 bImportant);
1094 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontVariant, pVariant,
1095 bImportant);
1096 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontWeight, pWeight,
1097 bImportant);
1098 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontSize, pFontSize,
1099 bImportant);
1100 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_LineHeight, pLineHeight,
1101 bImportant);
1102 if (familyList.GetSize() > 0) {
1103 CFDE_CSSValueList* pList =
1104 FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, familyList);
1105 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontFamily, pList,
1106 bImportant);
1107 }
1108 return TRUE;
1109 }
ParseColumnRuleProperty(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen,FX_BOOL bImportant)1110 FX_BOOL CFDE_CSSDeclaration::ParseColumnRuleProperty(
1111 FDE_LPCCSSPROPERTYARGS pArgs,
1112 const FX_WCHAR* pszValue,
1113 int32_t iValueLen,
1114 FX_BOOL bImportant) {
1115 IFX_MEMAllocator* pStaticStore = pArgs->pStaticStore;
1116 CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
1117 IFDE_CSSPrimitiveValue* pColumnRuleWidth = NULL;
1118 IFDE_CSSPrimitiveValue* pColumnRuleStyle = NULL;
1119 IFDE_CSSPrimitiveValue* pColumnRuleColor = NULL;
1120 FDE_CSSPRIMITIVETYPE eType;
1121 while (parser.NextValue(eType, pszValue, iValueLen)) {
1122 switch (eType) {
1123 case FDE_CSSPRIMITIVETYPE_String: {
1124 FDE_LPCCSSPROPERTYVALUETABLE pValue =
1125 FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
1126 if (pValue != NULL) {
1127 switch (pValue->eName) {
1128 case FDE_CSSPROPERTYVALUE_None:
1129 case FDE_CSSPROPERTYVALUE_Hidden:
1130 case FDE_CSSPROPERTYVALUE_Dotted:
1131 case FDE_CSSPROPERTYVALUE_Dashed:
1132 case FDE_CSSPROPERTYVALUE_Solid:
1133 case FDE_CSSPROPERTYVALUE_Double:
1134 case FDE_CSSPROPERTYVALUE_Groove:
1135 case FDE_CSSPROPERTYVALUE_Ridge:
1136 case FDE_CSSPROPERTYVALUE_Inset:
1137 case FDE_CSSPROPERTYVALUE_Outset:
1138 if (pColumnRuleStyle == NULL) {
1139 pColumnRuleStyle = NewEnumValue(pStaticStore, pValue->eName);
1140 }
1141 break;
1142 case FDE_CSSPROPERTYVALUE_Transparent:
1143 if (pColumnRuleColor == NULL) {
1144 pColumnRuleColor = NewEnumValue(pStaticStore, pValue->eName);
1145 }
1146 break;
1147 case FDE_CSSPROPERTYVALUE_Thin:
1148 case FDE_CSSPROPERTYVALUE_Medium:
1149 case FDE_CSSPROPERTYVALUE_Thick:
1150 if (pColumnRuleWidth == NULL) {
1151 pColumnRuleWidth = NewEnumValue(pStaticStore, pValue->eName);
1152 }
1153 break;
1154 default:
1155 break;
1156 }
1157 continue;
1158 }
1159 FX_ARGB dwColor;
1160 if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor) &&
1161 pColumnRuleColor == NULL) {
1162 pColumnRuleColor = FDE_NewWith(pStaticStore)
1163 CFDE_CSSPrimitiveValue((FX_ARGB)dwColor);
1164 continue;
1165 }
1166 } break;
1167 case FDE_CSSPRIMITIVETYPE_Number: {
1168 FX_FLOAT fValue;
1169 if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType) &&
1170 pColumnRuleWidth == NULL) {
1171 pColumnRuleWidth = NewNumberValue(pStaticStore, eType, fValue);
1172 }
1173 } break;
1174 case FDE_CSSPRIMITIVETYPE_RGB: {
1175 FX_ARGB dwColor;
1176 if (pColumnRuleColor == NULL &&
1177 FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
1178 pColumnRuleColor = FDE_NewWith(pStaticStore)
1179 CFDE_CSSPrimitiveValue((FX_ARGB)dwColor);
1180 }
1181 } break;
1182 default:
1183 break;
1184 }
1185 }
1186 if (pColumnRuleColor == NULL && pColumnRuleStyle == NULL &&
1187 pColumnRuleWidth == NULL) {
1188 return FALSE;
1189 }
1190 if (pColumnRuleStyle == NULL) {
1191 pColumnRuleStyle = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None);
1192 }
1193 if (pColumnRuleWidth == NULL) {
1194 pColumnRuleWidth = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Medium);
1195 }
1196 if (pColumnRuleColor == NULL) {
1197 pColumnRuleColor =
1198 FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0);
1199 }
1200 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnRuleStyle,
1201 pColumnRuleStyle, bImportant);
1202 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnRuleWidth,
1203 pColumnRuleWidth, bImportant);
1204 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnRuleColor,
1205 pColumnRuleColor, bImportant);
1206 return TRUE;
1207 }
ParseTextEmphasisProperty(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen,FX_BOOL bImportant)1208 FX_BOOL CFDE_CSSDeclaration::ParseTextEmphasisProperty(
1209 FDE_LPCCSSPROPERTYARGS pArgs,
1210 const FX_WCHAR* pszValue,
1211 int32_t iValueLen,
1212 FX_BOOL bImportant) {
1213 IFX_MEMAllocator* pStaticStore = pArgs->pStaticStore;
1214 CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
1215 CFDE_CSSValueArray arrEmphasisStyle;
1216 FDE_CSSPRIMITIVETYPE eType;
1217 IFDE_CSSPrimitiveValue* pEmphasisColor = NULL;
1218 while (parser.NextValue(eType, pszValue, iValueLen)) {
1219 switch (eType) {
1220 case FDE_CSSPRIMITIVETYPE_String: {
1221 FDE_LPCCSSPROPERTYVALUETABLE pValue =
1222 FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
1223 if (pValue != NULL) {
1224 arrEmphasisStyle.Add(NewEnumValue(pStaticStore, pValue->eName));
1225 continue;
1226 }
1227 FX_ARGB dwColor;
1228 if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
1229 pEmphasisColor =
1230 FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor);
1231 continue;
1232 }
1233 pszValue = CopyToLocal(pArgs, pszValue, iValueLen);
1234 arrEmphasisStyle.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(
1235 FDE_CSSPRIMITIVETYPE_String, pszValue));
1236 } break;
1237 case FDE_CSSPRIMITIVETYPE_RGB: {
1238 FX_ARGB dwColor;
1239 if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
1240 pEmphasisColor =
1241 FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor);
1242 }
1243 } break;
1244 default:
1245 break;
1246 }
1247 }
1248 if (arrEmphasisStyle.GetSize() != 0) {
1249 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_TextEmphasisStyle,
1250 FDE_NewWith(pStaticStore)
1251 CFDE_CSSValueList(pStaticStore, arrEmphasisStyle),
1252 bImportant);
1253 }
1254 if (pEmphasisColor != NULL) {
1255 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_TextEmphasisColor,
1256 pEmphasisColor, bImportant);
1257 }
1258 return TRUE;
1259 }
ParseColumnsProperty(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen,FX_BOOL bImportant)1260 FX_BOOL CFDE_CSSDeclaration::ParseColumnsProperty(FDE_LPCCSSPROPERTYARGS pArgs,
1261 const FX_WCHAR* pszValue,
1262 int32_t iValueLen,
1263 FX_BOOL bImportant) {
1264 IFX_MEMAllocator* pStaticStore = pArgs->pStaticStore;
1265 CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
1266 IFDE_CSSPrimitiveValue* pColumnWidth = NULL;
1267 IFDE_CSSPrimitiveValue* pColumnCount = NULL;
1268 FDE_CSSPRIMITIVETYPE eType;
1269 while (parser.NextValue(eType, pszValue, iValueLen)) {
1270 switch (eType) {
1271 case FDE_CSSPRIMITIVETYPE_String: {
1272 FDE_LPCCSSPROPERTYVALUETABLE pValue =
1273 FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
1274 if (pValue == NULL && pValue->eName == FDE_CSSPROPERTYVALUE_Auto) {
1275 pColumnWidth = NewEnumValue(pStaticStore, pValue->eName);
1276 }
1277 } break;
1278 case FDE_CSSPRIMITIVETYPE_Number: {
1279 FX_FLOAT fValue;
1280 if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
1281 switch (eType) {
1282 case FDE_CSSPRIMITIVETYPE_Number:
1283 if (pColumnCount == NULL) {
1284 pColumnCount = NewNumberValue(pStaticStore, eType, fValue);
1285 }
1286 break;
1287 default:
1288 if (pColumnWidth == NULL) {
1289 pColumnWidth = NewNumberValue(pStaticStore, eType, fValue);
1290 }
1291 break;
1292 }
1293 }
1294 } break;
1295 default:
1296 break;
1297 }
1298 }
1299 if (pColumnWidth == NULL && pColumnCount == NULL) {
1300 return FALSE;
1301 } else if (pColumnWidth == NULL) {
1302 pColumnWidth = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Auto);
1303 } else if (pColumnCount == NULL) {
1304 pColumnCount = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Auto);
1305 }
1306 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnWidth, pColumnWidth,
1307 bImportant);
1308 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnCount, pColumnCount,
1309 bImportant);
1310 return TRUE;
1311 }
ParseOverflowProperty(FDE_LPCCSSPROPERTYARGS pArgs,const FX_WCHAR * pszValue,int32_t iValueLen,FX_BOOL bImportant)1312 FX_BOOL CFDE_CSSDeclaration::ParseOverflowProperty(FDE_LPCCSSPROPERTYARGS pArgs,
1313 const FX_WCHAR* pszValue,
1314 int32_t iValueLen,
1315 FX_BOOL bImportant) {
1316 IFX_MEMAllocator* pStaticStore = pArgs->pStaticStore;
1317 CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
1318 IFDE_CSSPrimitiveValue* pOverflowX = NULL;
1319 IFDE_CSSPrimitiveValue* pOverflowY = NULL;
1320 FDE_CSSPRIMITIVETYPE eType;
1321 while (parser.NextValue(eType, pszValue, iValueLen)) {
1322 if (eType == FDE_CSSPRIMITIVETYPE_String) {
1323 FDE_LPCCSSPROPERTYVALUETABLE pValue =
1324 FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
1325 if (pValue != NULL) {
1326 switch (pValue->eName) {
1327 case FDE_CSSOVERFLOW_Visible:
1328 case FDE_CSSOVERFLOW_Hidden:
1329 case FDE_CSSOVERFLOW_Scroll:
1330 case FDE_CSSOVERFLOW_Auto:
1331 case FDE_CSSOVERFLOW_NoDisplay:
1332 case FDE_CSSOVERFLOW_NoContent:
1333 if (pOverflowX != NULL && pOverflowY != NULL) {
1334 return FALSE;
1335 } else if (pOverflowX == NULL) {
1336 pOverflowX = NewEnumValue(pStaticStore, pValue->eName);
1337 } else if (pOverflowY == NULL) {
1338 pOverflowY = NewEnumValue(pStaticStore, pValue->eName);
1339 }
1340 break;
1341 default:
1342 break;
1343 }
1344 }
1345 }
1346 }
1347 if (pOverflowX == NULL && pOverflowY == NULL) {
1348 return FALSE;
1349 } else if (pOverflowY == NULL) {
1350 pOverflowY = NewEnumValue(pStaticStore, pOverflowX->GetEnum());
1351 }
1352 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_OverflowX, pOverflowX,
1353 bImportant);
1354 AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_OverflowY, pOverflowY,
1355 bImportant);
1356 return TRUE;
1357 }
1358