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" 9 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 } 20 FX_POSITION CFDE_CSSDeclaration::GetStartPosition() const { 21 return (FX_POSITION)m_pFirstProperty; 22 } 23 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 } 34 FX_POSITION CFDE_CSSDeclaration::GetStartCustom() const { 35 return (FX_POSITION)m_pFirstCustom; 36 } 37 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 } 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 } 74 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 } 84 inline IFDE_CSSPrimitiveValue* CFDE_CSSDeclaration::NewEnumValue( 85 IFX_MEMAllocator* pStaticStore, 86 FDE_CSSPROPERTYVALUE eValue) const { 87 return FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eValue); 88 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 653 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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