+EGlyphOrientation StyleBuilderConverter::convertGlyphOrientation(StyleResolverState&, CSSValue* value)
+{
+ if (!value->isPrimitiveValue())
+ return GO_0DEG;
+
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
+ if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_DEG)
+ return GO_0DEG;
+
+ float angle = fabsf(fmodf(primitiveValue->getFloatValue(), 360.0f));
+
+ if (angle <= 45.0f || angle > 315.0f)
+ return GO_0DEG;
+ if (angle > 45.0f && angle <= 135.0f)
+ return GO_90DEG;
+ if (angle > 135.0f && angle <= 225.0f)
+ return GO_180DEG;
+ return GO_270DEG;
+}
+
+
+GridPosition StyleBuilderConverter::convertGridPosition(StyleResolverState&, CSSValue* value)
+{
+ // We accept the specification's grammar:
+ // 'auto' | [ <integer> || <string> ] | [ span && [ <integer> || string ] ] | <ident>
+
+ GridPosition position;
+
+ if (value->isPrimitiveValue()) {
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
+ // We translate <ident> to <string> during parsing as it
+ // makes handling it more simple.
+ if (primitiveValue->isString()) {
+ position.setNamedGridArea(primitiveValue->getStringValue());
+ return position;
+ }
+
+ ASSERT(primitiveValue->getValueID() == CSSValueAuto);
+ return position;
+ }
+
+ CSSValueList* values = toCSSValueList(value);
+ ASSERT(values->length());
+
+ bool isSpanPosition = false;
+ // The specification makes the <integer> optional, in which case it default to '1'.
+ int gridLineNumber = 1;
+ String gridLineName;
+
+ CSSValueListIterator it = values;
+ CSSPrimitiveValue* currentValue = toCSSPrimitiveValue(it.value());
+ if (currentValue->getValueID() == CSSValueSpan) {
+ isSpanPosition = true;
+ it.advance();
+ currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0;
+ }
+
+ if (currentValue && currentValue->isNumber()) {
+ gridLineNumber = currentValue->getIntValue();
+ it.advance();
+ currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0;
+ }
+
+ if (currentValue && currentValue->isString()) {
+ gridLineName = currentValue->getStringValue();
+ it.advance();
+ }
+
+ ASSERT(!it.hasMore());
+ if (isSpanPosition)
+ position.setSpanPosition(gridLineNumber, gridLineName);
+ else
+ position.setExplicitPosition(gridLineNumber, gridLineName);
+
+ return position;
+}
+
+GridTrackSize StyleBuilderConverter::convertGridTrackSize(StyleResolverState& state, CSSValue* value)
+{
+ if (value->isPrimitiveValue())
+ return GridTrackSize(convertGridTrackBreadth(state, toCSSPrimitiveValue(value)));
+
+ CSSFunctionValue* minmaxFunction = toCSSFunctionValue(value);
+ CSSValueList* arguments = minmaxFunction->arguments();
+ ASSERT_WITH_SECURITY_IMPLICATION(arguments->length() == 2);
+ GridLength minTrackBreadth(convertGridTrackBreadth(state, toCSSPrimitiveValue(arguments->itemWithoutBoundsCheck(0))));
+ GridLength maxTrackBreadth(convertGridTrackBreadth(state, toCSSPrimitiveValue(arguments->itemWithoutBoundsCheck(1))));
+ return GridTrackSize(minTrackBreadth, maxTrackBreadth);
+}
+
+bool StyleBuilderConverter::convertGridTrackList(CSSValue* value, Vector<GridTrackSize>& trackSizes, NamedGridLinesMap& namedGridLines, OrderedNamedGridLines& orderedNamedGridLines, StyleResolverState& state)
+{
+ // Handle 'none'.
+ if (value->isPrimitiveValue()) {
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
+ return primitiveValue->getValueID() == CSSValueNone;
+ }
+
+ if (!value->isValueList())
+ return false;
+
+ size_t currentNamedGridLine = 0;
+ for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
+ CSSValue* currValue = i.value();
+ if (currValue->isGridLineNamesValue()) {
+ CSSGridLineNamesValue* lineNamesValue = toCSSGridLineNamesValue(currValue);
+ for (CSSValueListIterator j = lineNamesValue; j.hasMore(); j.advance()) {
+ String namedGridLine = toCSSPrimitiveValue(j.value())->getStringValue();
+ NamedGridLinesMap::AddResult result = namedGridLines.add(namedGridLine, Vector<size_t>());
+ result.storedValue->value.append(currentNamedGridLine);
+ OrderedNamedGridLines::AddResult orderedInsertionResult = orderedNamedGridLines.add(currentNamedGridLine, Vector<String>());
+ orderedInsertionResult.storedValue->value.append(namedGridLine);
+ }
+ continue;
+ }
+
+ ++currentNamedGridLine;
+ trackSizes.append(convertGridTrackSize(state, currValue));
+ }
+
+ // The parser should have rejected any <track-list> without any <track-size> as
+ // this is not conformant to the syntax.
+ ASSERT(!trackSizes.isEmpty());
+ return true;
+}
+