2 * Copyright (C) 2013 Google Inc. All rights reserved.
4 * * Redistributions of source code must retain the above copyright
5 * notice, this list of conditions and the following disclaimer.
6 * * Redistributions in binary form must reproduce the above
7 * copyright notice, this list of conditions and the following disclaimer
8 * in the documentation and/or other materials provided with the
10 * * Neither the name of Google Inc. nor the names of its
11 * contributors may be used to endorse or promote products derived from
12 * this software without specific prior written permission.
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "core/css/resolver/StyleBuilderConverter.h"
30 #include "core/css/CSSFontFeatureValue.h"
31 #include "core/css/CSSFunctionValue.h"
32 #include "core/css/CSSGridLineNamesValue.h"
33 #include "core/css/CSSPrimitiveValueMappings.h"
34 #include "core/css/CSSReflectValue.h"
35 #include "core/css/CSSShadowValue.h"
36 #include "core/css/Pair.h"
37 #include "core/css/Rect.h"
38 #include "core/svg/SVGURIReference.h"
44 static GridLength convertGridTrackBreadth(const StyleResolverState& state, CSSPrimitiveValue* primitiveValue)
46 if (primitiveValue->getValueID() == CSSValueMinContent)
47 return Length(MinContent);
49 if (primitiveValue->getValueID() == CSSValueMaxContent)
50 return Length(MaxContent);
53 if (primitiveValue->isFlex())
54 return GridLength(primitiveValue->getDoubleValue());
56 return primitiveValue->convertToLength<FixedConversion | PercentConversion | AutoConversion>(state.cssToLengthConversionData());
61 PassRefPtr<StyleReflection> StyleBuilderConverter::convertBoxReflect(StyleResolverState& state, CSSValue* value)
63 if (value->isPrimitiveValue()) {
64 ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone);
65 return RenderStyle::initialBoxReflect();
68 CSSReflectValue* reflectValue = toCSSReflectValue(value);
69 RefPtr<StyleReflection> reflection = StyleReflection::create();
70 reflection->setDirection(*reflectValue->direction());
71 if (reflectValue->offset())
72 reflection->setOffset(reflectValue->offset()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()));
74 mask.setMaskDefaults();
75 state.styleMap().mapNinePieceImage(state.style(), CSSPropertyWebkitBoxReflect, reflectValue->mask(), mask);
76 reflection->setMask(mask);
78 return reflection.release();
81 Color StyleBuilderConverter::convertColor(StyleResolverState& state, CSSValue* value, bool forVisitedLink)
83 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
84 return state.document().textLinkColors().colorFromPrimitiveValue(primitiveValue, state.style()->color(), forVisitedLink);
87 AtomicString StyleBuilderConverter::convertFragmentIdentifier(StyleResolverState& state, CSSValue* value)
89 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
90 if (primitiveValue->isURI())
91 return SVGURIReference::fragmentIdentifierFromIRIString(primitiveValue->getStringValue(), state.element()->treeScope());
95 LengthBox StyleBuilderConverter::convertClip(StyleResolverState& state, CSSValue* value)
97 Rect* rect = toCSSPrimitiveValue(value)->getRectValue();
99 return LengthBox(convertLengthOrAuto(state, rect->top()),
100 convertLengthOrAuto(state, rect->right()),
101 convertLengthOrAuto(state, rect->bottom()),
102 convertLengthOrAuto(state, rect->left()));
105 PassRefPtr<FontFeatureSettings> StyleBuilderConverter::convertFontFeatureSettings(StyleResolverState& state, CSSValue* value)
107 if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueNormal)
108 return FontBuilder::initialFeatureSettings();
110 CSSValueList* list = toCSSValueList(value);
111 RefPtr<FontFeatureSettings> settings = FontFeatureSettings::create();
112 int len = list->length();
113 for (int i = 0; i < len; ++i) {
114 CSSFontFeatureValue* feature = toCSSFontFeatureValue(list->item(i));
115 settings->append(FontFeature(feature->tag(), feature->value()));
120 class RedirectSetHasViewportUnits {
122 RedirectSetHasViewportUnits(RenderStyle* from, RenderStyle* to)
123 : m_from(from), m_to(to), m_hadViewportUnits(from->hasViewportUnits())
125 from->setHasViewportUnits(false);
127 ~RedirectSetHasViewportUnits()
129 m_to->setHasViewportUnits(m_from->hasViewportUnits());
130 m_from->setHasViewportUnits(m_hadViewportUnits);
135 bool m_hadViewportUnits;
138 static float computeFontSize(StyleResolverState& state, CSSPrimitiveValue* primitiveValue, const FontDescription::Size& parentSize)
140 RedirectSetHasViewportUnits redirect(state.parentStyle(), state.style());
142 CSSToLengthConversionData conversionData(state.parentStyle(), state.rootElementStyle(), state.document().renderView(), 1.0f, true);
143 if (primitiveValue->isLength())
144 return primitiveValue->computeLength<float>(conversionData);
145 if (primitiveValue->isCalculatedPercentageWithLength())
146 return primitiveValue->cssCalcValue()->toCalcValue(conversionData)->evaluate(parentSize.value);
148 ASSERT_NOT_REACHED();
152 FontDescription::Size StyleBuilderConverter::convertFontSize(StyleResolverState& state, CSSValue* value)
154 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
156 FontDescription::Size parentSize(0, 0.0f, false);
158 // FIXME: Find out when parentStyle could be 0?
159 if (state.parentStyle())
160 parentSize = state.parentFontDescription().size();
162 if (CSSValueID valueID = primitiveValue->getValueID()) {
164 case CSSValueXxSmall:
170 case CSSValueXxLarge:
171 case CSSValueWebkitXxxLarge:
172 return FontDescription::Size(FontSize::keywordSize(valueID), 0.0f, false);
174 return FontDescription::largerSize(parentSize);
175 case CSSValueSmaller:
176 return FontDescription::smallerSize(parentSize);
178 ASSERT_NOT_REACHED();
179 return FontBuilder::initialSize();
183 bool parentIsAbsoluteSize = state.parentFontDescription().isAbsoluteSize();
185 if (primitiveValue->isPercentage())
186 return FontDescription::Size(0, (primitiveValue->getFloatValue() * parentSize.value / 100.0f), parentIsAbsoluteSize);
188 return FontDescription::Size(0, computeFontSize(state, primitiveValue, parentSize), parentIsAbsoluteSize || !primitiveValue->isFontRelativeLength());
191 FontWeight StyleBuilderConverter::convertFontWeight(StyleResolverState& state, CSSValue* value)
193 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
194 switch (primitiveValue->getValueID()) {
196 return FontDescription::bolderWeight(state.parentStyle()->fontDescription().weight());
197 case CSSValueLighter:
198 return FontDescription::lighterWeight(state.parentStyle()->fontDescription().weight());
200 return *primitiveValue;
204 FontDescription::VariantLigatures StyleBuilderConverter::convertFontVariantLigatures(StyleResolverState&, CSSValue* value)
206 if (value->isValueList()) {
207 FontDescription::VariantLigatures ligatures;
208 CSSValueList* valueList = toCSSValueList(value);
209 for (size_t i = 0; i < valueList->length(); ++i) {
210 CSSValue* item = valueList->item(i);
211 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(item);
212 switch (primitiveValue->getValueID()) {
213 case CSSValueNoCommonLigatures:
214 ligatures.common = FontDescription::DisabledLigaturesState;
216 case CSSValueCommonLigatures:
217 ligatures.common = FontDescription::EnabledLigaturesState;
219 case CSSValueNoDiscretionaryLigatures:
220 ligatures.discretionary = FontDescription::DisabledLigaturesState;
222 case CSSValueDiscretionaryLigatures:
223 ligatures.discretionary = FontDescription::EnabledLigaturesState;
225 case CSSValueNoHistoricalLigatures:
226 ligatures.historical = FontDescription::DisabledLigaturesState;
228 case CSSValueHistoricalLigatures:
229 ligatures.historical = FontDescription::EnabledLigaturesState;
231 case CSSValueNoContextual:
232 ligatures.contextual = FontDescription::DisabledLigaturesState;
234 case CSSValueContextual:
235 ligatures.contextual = FontDescription::EnabledLigaturesState;
238 ASSERT_NOT_REACHED();
245 ASSERT_WITH_SECURITY_IMPLICATION(value->isPrimitiveValue());
246 ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNormal);
247 return FontDescription::VariantLigatures();
250 EGlyphOrientation StyleBuilderConverter::convertGlyphOrientation(StyleResolverState&, CSSValue* value)
252 if (!value->isPrimitiveValue())
255 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
256 if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_DEG)
259 float angle = fabsf(fmodf(primitiveValue->getFloatValue(), 360.0f));
261 if (angle <= 45.0f || angle > 315.0f)
263 if (angle > 45.0f && angle <= 135.0f)
265 if (angle > 135.0f && angle <= 225.0f)
270 GridPosition StyleBuilderConverter::convertGridPosition(StyleResolverState&, CSSValue* value)
272 // We accept the specification's grammar:
273 // 'auto' | [ <integer> || <custom-ident> ] | [ span && [ <integer> || <custom-ident> ] ] | <custom-ident>
275 GridPosition position;
277 if (value->isPrimitiveValue()) {
278 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
279 // We translate <custom-ident> to <string> during parsing as it
280 // makes handling it more simple.
281 if (primitiveValue->isString()) {
282 position.setNamedGridArea(primitiveValue->getStringValue());
286 ASSERT(primitiveValue->getValueID() == CSSValueAuto);
290 CSSValueList* values = toCSSValueList(value);
291 ASSERT(values->length());
293 bool isSpanPosition = false;
294 // The specification makes the <integer> optional, in which case it default to '1'.
295 int gridLineNumber = 1;
298 CSSValueListIterator it = values;
299 CSSPrimitiveValue* currentValue = toCSSPrimitiveValue(it.value());
300 if (currentValue->getValueID() == CSSValueSpan) {
301 isSpanPosition = true;
303 currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0;
306 if (currentValue && currentValue->isNumber()) {
307 gridLineNumber = currentValue->getIntValue();
309 currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0;
312 if (currentValue && currentValue->isString()) {
313 gridLineName = currentValue->getStringValue();
317 ASSERT(!it.hasMore());
319 position.setSpanPosition(gridLineNumber, gridLineName);
321 position.setExplicitPosition(gridLineNumber, gridLineName);
326 GridTrackSize StyleBuilderConverter::convertGridTrackSize(StyleResolverState& state, CSSValue* value)
328 if (value->isPrimitiveValue())
329 return GridTrackSize(convertGridTrackBreadth(state, toCSSPrimitiveValue(value)));
331 CSSFunctionValue* minmaxFunction = toCSSFunctionValue(value);
332 CSSValueList* arguments = minmaxFunction->arguments();
333 ASSERT_WITH_SECURITY_IMPLICATION(arguments->length() == 2);
334 GridLength minTrackBreadth(convertGridTrackBreadth(state, toCSSPrimitiveValue(arguments->item(0))));
335 GridLength maxTrackBreadth(convertGridTrackBreadth(state, toCSSPrimitiveValue(arguments->item(1))));
336 return GridTrackSize(minTrackBreadth, maxTrackBreadth);
339 bool StyleBuilderConverter::convertGridTrackList(CSSValue* value, Vector<GridTrackSize>& trackSizes, NamedGridLinesMap& namedGridLines, OrderedNamedGridLines& orderedNamedGridLines, StyleResolverState& state)
342 if (value->isPrimitiveValue()) {
343 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
344 return primitiveValue->getValueID() == CSSValueNone;
347 if (!value->isValueList())
350 size_t currentNamedGridLine = 0;
351 for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
352 CSSValue* currValue = i.value();
353 if (currValue->isGridLineNamesValue()) {
354 CSSGridLineNamesValue* lineNamesValue = toCSSGridLineNamesValue(currValue);
355 for (CSSValueListIterator j = lineNamesValue; j.hasMore(); j.advance()) {
356 String namedGridLine = toCSSPrimitiveValue(j.value())->getStringValue();
357 NamedGridLinesMap::AddResult result = namedGridLines.add(namedGridLine, Vector<size_t>());
358 result.storedValue->value.append(currentNamedGridLine);
359 OrderedNamedGridLines::AddResult orderedInsertionResult = orderedNamedGridLines.add(currentNamedGridLine, Vector<String>());
360 orderedInsertionResult.storedValue->value.append(namedGridLine);
365 ++currentNamedGridLine;
366 trackSizes.append(convertGridTrackSize(state, currValue));
369 // The parser should have rejected any <track-list> without any <track-size> as
370 // this is not conformant to the syntax.
371 ASSERT(!trackSizes.isEmpty());
375 void StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(const NamedGridAreaMap& namedGridAreas, NamedGridLinesMap& namedGridLines, GridTrackSizingDirection direction)
377 NamedGridAreaMap::const_iterator end = namedGridAreas.end();
378 for (NamedGridAreaMap::const_iterator it = namedGridAreas.begin(); it != end; ++it) {
379 GridSpan areaSpan = direction == ForRows ? it->value.rows : it->value.columns;
381 NamedGridLinesMap::AddResult startResult = namedGridLines.add(it->key + "-start", Vector<size_t>());
382 startResult.storedValue->value.append(areaSpan.resolvedInitialPosition.toInt());
383 std::sort(startResult.storedValue->value.begin(), startResult.storedValue->value.end());
386 NamedGridLinesMap::AddResult endResult = namedGridLines.add(it->key + "-end", Vector<size_t>());
387 endResult.storedValue->value.append(areaSpan.resolvedFinalPosition.toInt() + 1);
388 std::sort(endResult.storedValue->value.begin(), endResult.storedValue->value.end());
393 Length StyleBuilderConverter::convertLength(StyleResolverState& state, CSSValue* value)
395 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
396 Length result = primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
397 result.setQuirk(primitiveValue->isQuirkValue());
401 Length StyleBuilderConverter::convertLengthOrAuto(StyleResolverState& state, CSSValue* value)
403 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
404 Length result = primitiveValue->convertToLength<FixedConversion | PercentConversion | AutoConversion>(state.cssToLengthConversionData());
405 result.setQuirk(primitiveValue->isQuirkValue());
409 Length StyleBuilderConverter::convertLengthSizing(StyleResolverState& state, CSSValue* value)
411 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
412 switch (primitiveValue->getValueID()) {
413 case CSSValueInvalid:
414 return convertLength(state, value);
415 case CSSValueIntrinsic:
416 return Length(Intrinsic);
417 case CSSValueMinIntrinsic:
418 return Length(MinIntrinsic);
419 case CSSValueWebkitMinContent:
420 return Length(MinContent);
421 case CSSValueWebkitMaxContent:
422 return Length(MaxContent);
423 case CSSValueWebkitFillAvailable:
424 return Length(FillAvailable);
425 case CSSValueWebkitFitContent:
426 return Length(FitContent);
430 ASSERT_NOT_REACHED();
435 Length StyleBuilderConverter::convertLengthMaxSizing(StyleResolverState& state, CSSValue* value)
437 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
438 if (primitiveValue->getValueID() == CSSValueNone)
439 return Length(MaxSizeNone);
440 return convertLengthSizing(state, value);
443 LengthPoint StyleBuilderConverter::convertLengthPoint(StyleResolverState& state, CSSValue* value)
445 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
446 Pair* pair = primitiveValue->getPairValue();
447 Length x = pair->first()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
448 Length y = pair->second()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
449 return LengthPoint(x, y);
452 LineBoxContain StyleBuilderConverter::convertLineBoxContain(StyleResolverState&, CSSValue* value)
454 if (value->isPrimitiveValue()) {
455 ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone);
456 return LineBoxContainNone;
459 return toCSSLineBoxContainValue(value)->value();
462 float StyleBuilderConverter::convertNumberOrPercentage(StyleResolverState& state, CSSValue* value)
464 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
465 ASSERT(primitiveValue->isNumber() || primitiveValue->isPercentage());
466 if (primitiveValue->isNumber())
467 return primitiveValue->getFloatValue();
468 return primitiveValue->getFloatValue() / 100.0f;
471 EPaintOrder StyleBuilderConverter::convertPaintOrder(StyleResolverState&, CSSValue* cssPaintOrder)
473 if (cssPaintOrder->isValueList()) {
475 CSSValueListInspector iter(cssPaintOrder);
476 for (size_t i = 0; i < iter.length(); i++) {
477 CSSPrimitiveValue* value = toCSSPrimitiveValue(iter.item(i));
479 EPaintOrderType paintOrderType = PT_NONE;
480 switch (value->getValueID()) {
482 paintOrderType = PT_FILL;
485 paintOrderType = PT_STROKE;
487 case CSSValueMarkers:
488 paintOrderType = PT_MARKERS;
491 ASSERT_NOT_REACHED();
495 paintOrder |= (paintOrderType << kPaintOrderBitwidth*i);
497 return (EPaintOrder)paintOrder;
503 PassRefPtr<QuotesData> StyleBuilderConverter::convertQuotes(StyleResolverState&, CSSValue* value)
505 if (value->isValueList()) {
506 CSSValueList* list = toCSSValueList(value);
507 RefPtr<QuotesData> quotes = QuotesData::create();
508 for (size_t i = 0; i < list->length(); i += 2) {
509 CSSValue* first = list->item(i);
510 CSSValue* second = list->item(i + 1);
511 String startQuote = toCSSPrimitiveValue(first)->getStringValue();
512 String endQuote = toCSSPrimitiveValue(second)->getStringValue();
513 quotes->addPair(std::make_pair(startQuote, endQuote));
515 return quotes.release();
517 // FIXME: We should assert we're a primitive value with valueID = CSSValueNone
518 return QuotesData::create();
521 LengthSize StyleBuilderConverter::convertRadius(StyleResolverState& state, CSSValue* value)
523 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
524 Pair* pair = primitiveValue->getPairValue();
525 Length radiusWidth = pair->first()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
526 Length radiusHeight = pair->second()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
527 float width = radiusWidth.value();
528 float height = radiusHeight.value();
529 ASSERT(width >= 0 && height >= 0);
530 if (width <= 0 || height <= 0)
531 return LengthSize(Length(0, Fixed), Length(0, Fixed));
532 return LengthSize(radiusWidth, radiusHeight);
535 PassRefPtr<ShadowList> StyleBuilderConverter::convertShadow(StyleResolverState& state, CSSValue* value)
537 if (value->isPrimitiveValue()) {
538 ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone);
539 return PassRefPtr<ShadowList>();
542 const CSSValueList* valueList = toCSSValueList(value);
543 size_t shadowCount = valueList->length();
544 ShadowDataVector shadows;
545 for (size_t i = 0; i < shadowCount; ++i) {
546 const CSSShadowValue* item = toCSSShadowValue(valueList->item(i));
547 float x = item->x->computeLength<float>(state.cssToLengthConversionData());
548 float y = item->y->computeLength<float>(state.cssToLengthConversionData());
549 float blur = item->blur ? item->blur->computeLength<float>(state.cssToLengthConversionData()) : 0;
550 float spread = item->spread ? item->spread->computeLength<float>(state.cssToLengthConversionData()) : 0;
551 ShadowStyle shadowStyle = item->style && item->style->getValueID() == CSSValueInset ? Inset : Normal;
554 color = convertColor(state, item->color.get());
556 color = state.style()->color();
557 shadows.append(ShadowData(FloatPoint(x, y), blur, spread, shadowStyle, color));
559 return ShadowList::adopt(shadows);
562 float StyleBuilderConverter::convertSpacing(StyleResolverState& state, CSSValue* value)
564 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
565 if (primitiveValue->getValueID() == CSSValueNormal)
567 return primitiveValue->computeLength<float>(state.cssToLengthConversionData());
570 PassRefPtr<SVGLengthList> StyleBuilderConverter::convertStrokeDasharray(StyleResolverState&, CSSValue* value)
572 if (!value->isValueList()) {
573 return SVGRenderStyle::initialStrokeDashArray();
576 CSSValueList* dashes = toCSSValueList(value);
578 RefPtr<SVGLengthList> array = SVGLengthList::create();
579 size_t length = dashes->length();
580 for (size_t i = 0; i < length; ++i) {
581 CSSValue* currValue = dashes->item(i);
582 if (!currValue->isPrimitiveValue())
585 CSSPrimitiveValue* dash = toCSSPrimitiveValue(dashes->item(i));
586 array->append(SVGLength::fromCSSPrimitiveValue(dash));
589 return array.release();
592 StyleColor StyleBuilderConverter::convertStyleColor(StyleResolverState& state, CSSValue* value, bool forVisitedLink)
594 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
595 if (primitiveValue->getValueID() == CSSValueCurrentcolor)
596 return StyleColor::currentColor();
597 return state.document().textLinkColors().colorFromPrimitiveValue(primitiveValue, Color(), forVisitedLink);
600 Color StyleBuilderConverter::convertSVGColor(StyleResolverState& state, CSSValue* value)
602 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
603 if (primitiveValue->isRGBColor())
604 return primitiveValue->getRGBA32Value();
605 ASSERT(primitiveValue->getValueID() == CSSValueCurrentcolor);
606 return state.style()->color();
609 PassRefPtr<SVGLength> StyleBuilderConverter::convertSVGLength(StyleResolverState&, CSSValue* value)
611 return SVGLength::fromCSSPrimitiveValue(toCSSPrimitiveValue(value));
614 float StyleBuilderConverter::convertTextStrokeWidth(StyleResolverState& state, CSSValue* value)
616 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
617 if (primitiveValue->getValueID()) {
618 float multiplier = convertLineWidth<float>(state, value);
619 return CSSPrimitiveValue::create(multiplier / 48, CSSPrimitiveValue::CSS_EMS)->computeLength<float>(state.cssToLengthConversionData());
621 return primitiveValue->computeLength<float>(state.cssToLengthConversionData());