void StyleBuilderFunctions::applyValueCSSPropertySize(StyleResolverState& state, CSSValue* value) { state.style()->resetPageSizeType(); FloatSize size; PageSizeType pageSizeType = PAGE_SIZE_AUTO; CSSValueList* list = toCSSValueList(value); if (list->length() == 2) { // <length>{2} | <page-size> <orientation> CSSPrimitiveValue* first = toCSSPrimitiveValue(list->item(0)); CSSPrimitiveValue* second = toCSSPrimitiveValue(list->item(1)); if (first->isLength()) { // <length>{2} size = FloatSize(first->computeLength<float>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0)), second->computeLength<float>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0))); } else { // <page-size> <orientation> size = getPageSizeFromName(first); ASSERT(second->getValueID() == CSSValueLandscape || second->getValueID() == CSSValuePortrait); if (second->getValueID() == CSSValueLandscape) size = size.transposedSize(); } pageSizeType = PAGE_SIZE_RESOLVED; } else { ASSERT(list->length() == 1); // <length> | auto | <page-size> | [ portrait | landscape] CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(list->item(0)); if (primitiveValue->isLength()) { // <length> pageSizeType = PAGE_SIZE_RESOLVED; float width = primitiveValue->computeLength<float>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0)); size = FloatSize(width, width); } else { switch (primitiveValue->getValueID()) { case CSSValueAuto: pageSizeType = PAGE_SIZE_AUTO; break; case CSSValuePortrait: pageSizeType = PAGE_SIZE_AUTO_PORTRAIT; break; case CSSValueLandscape: pageSizeType = PAGE_SIZE_AUTO_LANDSCAPE; break; default: // <page-size> pageSizeType = PAGE_SIZE_RESOLVED; size = getPageSizeFromName(primitiveValue); } } } state.style()->setPageSizeType(pageSizeType); state.style()->setPageSize(size); }
Length ViewportStyleResolver::viewportLengthValue(CSSPropertyID id) const { ASSERT(id == CSSPropertyMaxHeight || id == CSSPropertyMinHeight || id == CSSPropertyMaxWidth || id == CSSPropertyMinWidth); RefPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id); if (!value || !value->isPrimitiveValue()) return Length(); // auto CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value.get()); if (primitiveValue->isLength()) return primitiveValue->computeLength<Length>(m_document->renderStyle(), m_document->renderStyle()); if (primitiveValue->isViewportPercentageLength()) return primitiveValue->viewportPercentageLength(); if (primitiveValue->isPercentage()) return Length(primitiveValue->getFloatValue(), Percent); switch (primitiveValue->getValueID()) { case CSSValueInternalExtendToZoom: return Length(ExtendToZoom); case CSSValueAuto: return Length(); default: // Unrecognized keyword. ASSERT_NOT_REACHED(); return Length(0, Fixed); } }
void CSSToStyleMap::mapFillYPosition(CSSPropertyID, FillLayer* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setYPosition(FillLayer::initialFillYPosition(layer->type())); return; } if (!value->isPrimitiveValue()) return; float zoomFactor = style()->effectiveZoom(); CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); Length length; if (primitiveValue->isLength()) length = primitiveValue->computeLength<Length>(style(), rootElementStyle(), zoomFactor); else if (primitiveValue->isPercentage()) length = Length(primitiveValue->getDoubleValue(), Percent); else if (primitiveValue->isCalculatedPercentageWithLength()) length = Length(primitiveValue->cssCalcValue()->toCalcValue(style(), rootElementStyle(), zoomFactor)); else if (primitiveValue->isViewportPercentageLength()) length = primitiveValue->viewportPercentageLength(); else return; layer->setYPosition(length); }
bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSPrimitiveValue& primitiveValue) { // FIXME: consider other types. if (primitiveValue.isNumber() || primitiveValue.isPercentage() || primitiveValue.isAngle() || primitiveValue.isRGBColor() || primitiveValue.isURI()) return false; if (primitiveValue.isLength()) return primitiveValue.isFontRelativeLength() || primitiveValue.isViewportPercentageLength(); if (primitiveValue.isCalculated()) { CSSLengthArray lengthArray(CSSPrimitiveValue::LengthUnitTypeCount); primitiveValue.accumulateLengthArray(lengthArray); return lengthArray[CSSPrimitiveValue::UnitTypeFontSize] != 0 || lengthArray[CSSPrimitiveValue::UnitTypeFontXSize] != 0 || lengthArray[CSSPrimitiveValue::UnitTypeRootFontSize] != 0 || lengthArray[CSSPrimitiveValue::UnitTypeZeroCharacterWidth] != 0 || lengthArray[CSSPrimitiveValue::UnitTypeViewportWidth] != 0 || lengthArray[CSSPrimitiveValue::UnitTypeViewportHeight] != 0 || lengthArray[CSSPrimitiveValue::UnitTypeViewportMin] != 0 || lengthArray[CSSPrimitiveValue::UnitTypeViewportMax] != 0; } CSSValueID id = primitiveValue.getValueID(); bool isColor = ((id >= CSSValueAqua && id <= CSSValueTransparent) || (id >= CSSValueAliceblue && id <= CSSValueYellowgreen) || id == CSSValueGrey); return (id != CSSValueNone) && !isColor; }
static CSSValuePair* buildSerializablePositionOffset(CSSValue* offset, CSSValueID defaultSide) { CSSValueID side = defaultSide; CSSPrimitiveValue* amount = nullptr; if (!offset) { side = CSSValueCenter; } else if (offset->isPrimitiveValue() && toCSSPrimitiveValue(offset)->isValueID()) { side = toCSSPrimitiveValue(offset)->getValueID(); } else if (offset->isValuePair()) { side = toCSSPrimitiveValue(toCSSValuePair(*offset).first()).getValueID(); amount = &toCSSPrimitiveValue(toCSSValuePair(*offset).second()); if ((side == CSSValueRight || side == CSSValueBottom) && amount->isPercentage()) { side = defaultSide; amount = cssValuePool().createValue(100 - amount->getFloatValue(), CSSPrimitiveValue::UnitType::Percentage); } } else { amount = toCSSPrimitiveValue(offset); } if (side == CSSValueCenter) { side = defaultSide; amount = cssValuePool().createValue(50, CSSPrimitiveValue::UnitType::Percentage); } else if (!amount || (amount->isLength() && !amount->getFloatValue())) { if (side == CSSValueRight || side == CSSValueBottom) amount = cssValuePool().createValue(100, CSSPrimitiveValue::UnitType::Percentage); else amount = cssValuePool().createValue(0, CSSPrimitiveValue::UnitType::Percentage); side = defaultSide; } return CSSValuePair::create(cssValuePool().createIdentifierValue(side), amount, CSSValuePair::KeepIdenticalValues); }
void CSSToStyleMap::mapFillYPosition(CSSPropertyID propertyID, FillLayer* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setYPosition(FillLayer::initialFillYPosition(layer->type())); return; } if (!is<CSSPrimitiveValue>(*value)) return; CSSPrimitiveValue* primitiveValue = downcast<CSSPrimitiveValue>(value); Pair* pair = primitiveValue->getPairValue(); if (pair) { ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPositionY || propertyID == CSSPropertyWebkitMaskPositionY); primitiveValue = pair->second(); } Length length; if (primitiveValue->isLength()) length = primitiveValue->computeLength<Length>(m_resolver->state().cssToLengthConversionData()); else if (primitiveValue->isPercentage()) length = Length(primitiveValue->getDoubleValue(), Percent); else if (primitiveValue->isCalculatedPercentageWithLength()) length = Length(primitiveValue->cssCalcValue()->createCalculationValue(m_resolver->state().cssToLengthConversionData())); else return; layer->setYPosition(length); if (pair) layer->setBackgroundYOrigin(*(pair->first())); }
void CSSToStyleMap::mapFillYPosition(CSSPropertyID propertyID, FillLayer* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setYPosition(FillLayer::initialFillYPosition(layer->type())); return; } if (!value->isPrimitiveValue()) return; float zoomFactor = style()->effectiveZoom(); CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); Pair* pair = primitiveValue->getPairValue(); if (pair) { ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPositionY || propertyID == CSSPropertyWebkitMaskPositionY); primitiveValue = pair->second(); } Length length; if (primitiveValue->isLength()) length = primitiveValue->computeLength<Length>(style(), rootElementStyle(), zoomFactor); else if (primitiveValue->isPercentage()) length = Length(primitiveValue->getDoubleValue(), Percent); else if (primitiveValue->isCalculatedPercentageWithLength()) length = Length(primitiveValue->cssCalcValue()->toCalcValue(style(), rootElementStyle(), zoomFactor)); else if (primitiveValue->isViewportPercentageLength()) length = primitiveValue->viewportPercentageLength(); else return; layer->setYPosition(length); if (pair) layer->setBackgroundYOrigin(*(pair->first())); }
void StyleBuilderFunctions::applyValueCSSPropertyPerspective(StyleResolverState& state, CSSValue* value) { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->getValueID() == CSSValueNone) { state.style()->setPerspective(0); return; } if (!primitiveValue->isLength()) return; float perspectiveValue = primitiveValue->computeLength<float>(state.cssToLengthConversionData()); if (perspectiveValue >= 0.0f) state.style()->setPerspective(perspectiveValue); }
bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSPrimitiveValue& primitiveValue) { // FIXME: consider other types. if (primitiveValue.isNumber() || primitiveValue.isPercentage() || primitiveValue.isAngle() || primitiveValue.isRGBColor() || primitiveValue.isURI()) return false; if (primitiveValue.isLength()) return primitiveValue.isFontRelativeLength() || primitiveValue.isViewportPercentageLength(); if (primitiveValue.isCalculated()) { CSSLengthArray lengthArray(CSSPrimitiveValue::LengthUnitTypeCount); primitiveValue.accumulateLengthArray(lengthArray); return lengthArray[CSSPrimitiveValue::UnitTypeFontSize] != 0 || lengthArray[CSSPrimitiveValue::UnitTypeFontXSize] != 0 || lengthArray[CSSPrimitiveValue::UnitTypeRootFontSize] != 0 || lengthArray[CSSPrimitiveValue::UnitTypeZeroCharacterWidth] != 0 || lengthArray[CSSPrimitiveValue::UnitTypeViewportWidth] != 0 || lengthArray[CSSPrimitiveValue::UnitTypeViewportHeight] != 0 || lengthArray[CSSPrimitiveValue::UnitTypeViewportMin] != 0 || lengthArray[CSSPrimitiveValue::UnitTypeViewportMax] != 0; } if (Pair* pair = primitiveValue.getPairValue()) { return interpolationRequiresStyleResolve(*pair->first()) || interpolationRequiresStyleResolve(*pair->second()); } if (Rect* rect = primitiveValue.getRectValue()) { return interpolationRequiresStyleResolve(*rect->top()) || interpolationRequiresStyleResolve(*rect->right()) || interpolationRequiresStyleResolve(*rect->bottom()) || interpolationRequiresStyleResolve(*rect->left()); } if (Quad* quad = primitiveValue.getQuadValue()) { return interpolationRequiresStyleResolve(*quad->top()) || interpolationRequiresStyleResolve(*quad->right()) || interpolationRequiresStyleResolve(*quad->bottom()) || interpolationRequiresStyleResolve(*quad->left()); } if (primitiveValue.isShape()) return interpolationRequiresStyleResolve(*primitiveValue.getShapeValue()); return (primitiveValue.getValueID() != CSSValueNone); }
static bool computeLength(CSSValue* value, bool strict, RenderStyle* style, RenderStyle* rootStyle, int& result) { if (!value->isPrimitiveValue()) return false; CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); if (primitiveValue->isNumber()) { result = primitiveValue->getIntValue(); return !strict || !result; } if (primitiveValue->isLength()) { result = primitiveValue->computeLength<int>(style, rootStyle); return true; } return false; }
static bool computeLength(CSSValue* value, bool strict, const CSSToLengthConversionData& conversionData, int& result) { if (!value->isPrimitiveValue()) return false; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->isNumber()) { result = primitiveValue->getIntValue(); return !strict || !result; } if (primitiveValue->isLength()) { result = primitiveValue->computeLength<int>(conversionData); return true; } return false; }
void StyleBuilderFunctions::applyValueCSSPropertyLineHeight(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); Length lineHeight; if (primitiveValue->getValueID() == CSSValueNormal) { lineHeight = RenderStyle::initialLineHeight(); } else if (primitiveValue->isLength()) { lineHeight = primitiveValue->computeLength<Length>(state.cssToLengthConversionData()); } else if (primitiveValue->isPercentage()) { lineHeight = Length((state.style()->computedFontSize() * primitiveValue->getIntValue()) / 100.0, Fixed); } else if (primitiveValue->isNumber()) { lineHeight = Length(primitiveValue->getDoubleValue() * 100.0, Percent); } else if (primitiveValue->isCalculated()) { Length length = Length(primitiveValue->cssCalcValue()->toCalcValue(state.cssToLengthConversionData())); lineHeight = Length(valueForLength(length, state.style()->fontSize()), Fixed); } else { return; } state.style()->setLineHeight(lineHeight); }
static bool computeLength(CSSValue* value, bool strict, RenderStyle* initialStyle, int& result) { if (!value->isPrimitiveValue()) return false; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->isNumber()) { result = primitiveValue->getIntValue(); return !strict || !result; } if (primitiveValue->isLength()) { // Relative (like EM) and root relative (like REM) units are always resolved against // the initial values for media queries, hence the two initialStyle parameters. // FIXME: We need to plumb viewport unit support down to here. result = primitiveValue->computeLength<int>(CSSToLengthConversionData(initialStyle, initialStyle, 0, 1.0 /* zoom */, true /* computingFontSize */)); return true; } return false; }
// FIXME: Have to pass RenderStyles here for calc/computed values. This shouldn't be neecessary. void FontBuilder::setFontSizeValue(CSSValue* value, RenderStyle* parentStyle, const RenderStyle* rootElementStyle, float effectiveZoom) { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); FontDescriptionChangeScope scope(this); scope.fontDescription().setKeywordSize(0); float parentSize = 0; bool parentIsAbsoluteSize = false; float size = 0; // FIXME: Find out when parentStyle could be 0? if (parentStyle) { parentSize = parentStyle->fontDescription().specifiedSize(); parentIsAbsoluteSize = parentStyle->fontDescription().isAbsoluteSize(); } if (CSSValueID valueID = primitiveValue->getValueID()) { switch (valueID) { case CSSValueXxSmall: case CSSValueXSmall: case CSSValueSmall: case CSSValueMedium: case CSSValueLarge: case CSSValueXLarge: case CSSValueXxLarge: case CSSValueWebkitXxxLarge: size = FontSize::fontSizeForKeyword(m_document, valueID, scope.fontDescription().useFixedDefaultSize()); scope.fontDescription().setKeywordSize(valueID - CSSValueXxSmall + 1); break; case CSSValueLarger: size = largerFontSize(parentSize); break; case CSSValueSmaller: size = smallerFontSize(parentSize); break; default: return; } scope.fontDescription().setIsAbsoluteSize(parentIsAbsoluteSize && (valueID == CSSValueLarger || valueID == CSSValueSmaller)); } else { scope.fontDescription().setIsAbsoluteSize(parentIsAbsoluteSize || !(primitiveValue->isPercentage() || primitiveValue->isFontRelativeLength())); if (primitiveValue->isLength()) size = primitiveValue->computeLength<float>(parentStyle, rootElementStyle, 1.0, true); else if (primitiveValue->isPercentage()) size = (primitiveValue->getFloatValue() * parentSize) / 100.0f; else if (primitiveValue->isCalculatedPercentageWithLength()) size = primitiveValue->cssCalcValue()->toCalcValue(parentStyle, rootElementStyle)->evaluate(parentSize); else if (primitiveValue->isViewportPercentageLength()) size = valueForLength(primitiveValue->viewportPercentageLength(), 0, m_document->renderView()); else return; } if (size < 0) return; // Overly large font sizes will cause crashes on some platforms (such as Windows). // Cap font size here to make sure that doesn't happen. size = std::min(maximumAllowedFontSize, size); setSize(scope.fontDescription(), effectiveZoom, size); }
bool TransformBuilder::createTransformOperations(CSSValue* inValue, RenderStyle* style, RenderStyle* rootStyle, TransformOperations& outOperations) { if (!inValue || !inValue->isValueList()) { outOperations.clear(); return false; } float zoomFactor = style ? style->effectiveZoom() : 1; TransformOperations operations; for (CSSValueListIterator i = inValue; i.hasMore(); i.advance()) { CSSValue* currValue = i.value(); if (!currValue->isCSSTransformValue()) continue; CSSTransformValue* transformValue = static_cast<CSSTransformValue*>(i.value()); if (!transformValue->length()) continue; bool haveNonPrimitiveValue = false; for (unsigned j = 0; j < transformValue->length(); ++j) { if (!transformValue->itemWithoutBoundsCheck(j)->isPrimitiveValue()) { haveNonPrimitiveValue = true; break; } } if (haveNonPrimitiveValue) continue; CSSPrimitiveValue* firstValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(0)); switch (transformValue->operationType()) { case CSSTransformValue::ScaleTransformOperation: case CSSTransformValue::ScaleXTransformOperation: case CSSTransformValue::ScaleYTransformOperation: { double sx = 1.0; double sy = 1.0; if (transformValue->operationType() == CSSTransformValue::ScaleYTransformOperation) sy = firstValue->getDoubleValue(); else { sx = firstValue->getDoubleValue(); if (transformValue->operationType() != CSSTransformValue::ScaleXTransformOperation) { if (transformValue->length() > 1) { CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(1)); sy = secondValue->getDoubleValue(); } else sy = sx; } } operations.operations().append(ScaleTransformOperation::create(sx, sy, 1.0, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::ScaleZTransformOperation: case CSSTransformValue::Scale3DTransformOperation: { double sx = 1.0; double sy = 1.0; double sz = 1.0; if (transformValue->operationType() == CSSTransformValue::ScaleZTransformOperation) sz = firstValue->getDoubleValue(); else if (transformValue->operationType() == CSSTransformValue::ScaleYTransformOperation) sy = firstValue->getDoubleValue(); else { sx = firstValue->getDoubleValue(); if (transformValue->operationType() != CSSTransformValue::ScaleXTransformOperation) { if (transformValue->length() > 2) { CSSPrimitiveValue* thirdValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(2)); sz = thirdValue->getDoubleValue(); } if (transformValue->length() > 1) { CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(1)); sy = secondValue->getDoubleValue(); } else sy = sx; } } operations.operations().append(ScaleTransformOperation::create(sx, sy, sz, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::TranslateTransformOperation: case CSSTransformValue::TranslateXTransformOperation: case CSSTransformValue::TranslateYTransformOperation: { Length tx = Length(0, Fixed); Length ty = Length(0, Fixed); if (transformValue->operationType() == CSSTransformValue::TranslateYTransformOperation) ty = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); else { tx = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); if (transformValue->operationType() != CSSTransformValue::TranslateXTransformOperation) { if (transformValue->length() > 1) { CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(1)); ty = convertToFloatLength(secondValue, style, rootStyle, zoomFactor); } } } if (tx.isUndefined() || ty.isUndefined()) return false; operations.operations().append(TranslateTransformOperation::create(tx, ty, Length(0, Fixed), getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::TranslateZTransformOperation: case CSSTransformValue::Translate3DTransformOperation: { Length tx = Length(0, Fixed); Length ty = Length(0, Fixed); Length tz = Length(0, Fixed); if (transformValue->operationType() == CSSTransformValue::TranslateZTransformOperation) tz = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); else if (transformValue->operationType() == CSSTransformValue::TranslateYTransformOperation) ty = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); else { tx = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); if (transformValue->operationType() != CSSTransformValue::TranslateXTransformOperation) { if (transformValue->length() > 2) { CSSPrimitiveValue* thirdValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(2)); tz = convertToFloatLength(thirdValue, style, rootStyle, zoomFactor); } if (transformValue->length() > 1) { CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(1)); ty = convertToFloatLength(secondValue, style, rootStyle, zoomFactor); } } } if (tx.isUndefined() || ty.isUndefined() || tz.isUndefined()) return false; operations.operations().append(TranslateTransformOperation::create(tx, ty, tz, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::RotateTransformOperation: { double angle = firstValue->computeDegrees(); operations.operations().append(RotateTransformOperation::create(0, 0, 1, angle, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::RotateXTransformOperation: case CSSTransformValue::RotateYTransformOperation: case CSSTransformValue::RotateZTransformOperation: { double x = 0; double y = 0; double z = 0; double angle = firstValue->computeDegrees(); if (transformValue->operationType() == CSSTransformValue::RotateXTransformOperation) x = 1; else if (transformValue->operationType() == CSSTransformValue::RotateYTransformOperation) y = 1; else z = 1; operations.operations().append(RotateTransformOperation::create(x, y, z, angle, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::Rotate3DTransformOperation: { if (transformValue->length() < 4) break; CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(1)); CSSPrimitiveValue* thirdValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(2)); CSSPrimitiveValue* fourthValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(3)); double x = firstValue->getDoubleValue(); double y = secondValue->getDoubleValue(); double z = thirdValue->getDoubleValue(); double angle = fourthValue->computeDegrees(); operations.operations().append(RotateTransformOperation::create(x, y, z, angle, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::SkewTransformOperation: case CSSTransformValue::SkewXTransformOperation: case CSSTransformValue::SkewYTransformOperation: { double angleX = 0; double angleY = 0; double angle = firstValue->computeDegrees(); if (transformValue->operationType() == CSSTransformValue::SkewYTransformOperation) angleY = angle; else { angleX = angle; if (transformValue->operationType() == CSSTransformValue::SkewTransformOperation) { if (transformValue->length() > 1) { CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(1)); angleY = secondValue->computeDegrees(); } } } operations.operations().append(SkewTransformOperation::create(angleX, angleY, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::MatrixTransformOperation: { if (transformValue->length() < 6) break; double a = firstValue->getDoubleValue(); double b = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(1))->getDoubleValue(); double c = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(2))->getDoubleValue(); double d = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(3))->getDoubleValue(); double e = zoomFactor * toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(4))->getDoubleValue(); double f = zoomFactor * toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(5))->getDoubleValue(); operations.operations().append(MatrixTransformOperation::create(a, b, c, d, e, f)); break; } case CSSTransformValue::Matrix3DTransformOperation: { if (transformValue->length() < 16) break; TransformationMatrix matrix(toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(0))->getDoubleValue(), toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(1))->getDoubleValue(), toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(2))->getDoubleValue(), toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(3))->getDoubleValue(), toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(4))->getDoubleValue(), toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(5))->getDoubleValue(), toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(6))->getDoubleValue(), toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(7))->getDoubleValue(), toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(8))->getDoubleValue(), toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(9))->getDoubleValue(), toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(10))->getDoubleValue(), toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(11))->getDoubleValue(), zoomFactor * toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(12))->getDoubleValue(), zoomFactor * toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(13))->getDoubleValue(), toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(14))->getDoubleValue(), toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(15))->getDoubleValue()); operations.operations().append(Matrix3DTransformOperation::create(matrix)); break; } case CSSTransformValue::PerspectiveTransformOperation: { Length p = Length(0, Fixed); if (firstValue->isLength()) p = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); else { // This is a quirk that should go away when 3d transforms are finalized. double val = firstValue->getDoubleValue(); p = val >= 0 ? Length(clampToPositiveInteger(val), Fixed) : Length(Undefined); } if (p.isUndefined()) return false; operations.operations().append(PerspectiveTransformOperation::create(p)); break; } case CSSTransformValue::UnknownTransformOperation: ASSERT_NOT_REACHED(); break; } } outOperations = operations; return true; }
bool TransformBuilder::createTransformOperations(CSSValue* inValue, const CSSToLengthConversionData& conversionData, TransformOperations& outOperations) { if (!inValue || !inValue->isValueList()) { outOperations.clear(); return false; } TransformOperations operations; for (CSSValueListIterator i = inValue; i.hasMore(); i.advance()) { CSSValue* currValue = i.value(); if (!currValue->isTransformValue()) continue; CSSTransformValue* transformValue = toCSSTransformValue(i.value()); if (!transformValue->length()) continue; bool haveNonPrimitiveValue = false; for (unsigned j = 0; j < transformValue->length(); ++j) { if (!transformValue->item(j)->isPrimitiveValue()) { haveNonPrimitiveValue = true; break; } } if (haveNonPrimitiveValue) continue; CSSPrimitiveValue* firstValue = toCSSPrimitiveValue(transformValue->item(0)); switch (transformValue->operationType()) { case CSSTransformValue::ScaleTransformOperation: case CSSTransformValue::ScaleXTransformOperation: case CSSTransformValue::ScaleYTransformOperation: { double sx = 1.0; double sy = 1.0; if (transformValue->operationType() == CSSTransformValue::ScaleYTransformOperation) sy = firstValue->getDoubleValue(); else { sx = firstValue->getDoubleValue(); if (transformValue->operationType() != CSSTransformValue::ScaleXTransformOperation) { if (transformValue->length() > 1) { CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->item(1)); sy = secondValue->getDoubleValue(); } else sy = sx; } } operations.operations().append(ScaleTransformOperation::create(sx, sy, 1.0, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::ScaleZTransformOperation: case CSSTransformValue::Scale3DTransformOperation: { double sx = 1.0; double sy = 1.0; double sz = 1.0; if (transformValue->operationType() == CSSTransformValue::ScaleZTransformOperation) sz = firstValue->getDoubleValue(); else if (transformValue->operationType() == CSSTransformValue::ScaleYTransformOperation) sy = firstValue->getDoubleValue(); else { sx = firstValue->getDoubleValue(); if (transformValue->operationType() != CSSTransformValue::ScaleXTransformOperation) { if (transformValue->length() > 2) { CSSPrimitiveValue* thirdValue = toCSSPrimitiveValue(transformValue->item(2)); sz = thirdValue->getDoubleValue(); } if (transformValue->length() > 1) { CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->item(1)); sy = secondValue->getDoubleValue(); } else sy = sx; } } operations.operations().append(ScaleTransformOperation::create(sx, sy, sz, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::TranslateTransformOperation: case CSSTransformValue::TranslateXTransformOperation: case CSSTransformValue::TranslateYTransformOperation: { Length tx = Length(0, Fixed); Length ty = Length(0, Fixed); if (transformValue->operationType() == CSSTransformValue::TranslateYTransformOperation) ty = convertToFloatLength(firstValue, conversionData); else { tx = convertToFloatLength(firstValue, conversionData); if (transformValue->operationType() != CSSTransformValue::TranslateXTransformOperation) { if (transformValue->length() > 1) { CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->item(1)); ty = convertToFloatLength(secondValue, conversionData); } } } operations.operations().append(TranslateTransformOperation::create(tx, ty, 0, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::TranslateZTransformOperation: case CSSTransformValue::Translate3DTransformOperation: { Length tx = Length(0, Fixed); Length ty = Length(0, Fixed); double tz = 0; if (transformValue->operationType() == CSSTransformValue::TranslateZTransformOperation) tz = firstValue->computeLength<double>(conversionData); else if (transformValue->operationType() == CSSTransformValue::TranslateYTransformOperation) ty = convertToFloatLength(firstValue, conversionData); else { tx = convertToFloatLength(firstValue, conversionData); if (transformValue->operationType() != CSSTransformValue::TranslateXTransformOperation) { if (transformValue->length() > 2) { CSSPrimitiveValue* thirdValue = toCSSPrimitiveValue(transformValue->item(2)); tz = thirdValue->computeLength<double>(conversionData); } if (transformValue->length() > 1) { CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->item(1)); ty = convertToFloatLength(secondValue, conversionData); } } } operations.operations().append(TranslateTransformOperation::create(tx, ty, tz, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::RotateTransformOperation: { double angle = firstValue->computeDegrees(); operations.operations().append(RotateTransformOperation::create(0, 0, 1, angle, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::RotateXTransformOperation: case CSSTransformValue::RotateYTransformOperation: case CSSTransformValue::RotateZTransformOperation: { double x = 0; double y = 0; double z = 0; double angle = firstValue->computeDegrees(); if (transformValue->operationType() == CSSTransformValue::RotateXTransformOperation) x = 1; else if (transformValue->operationType() == CSSTransformValue::RotateYTransformOperation) y = 1; else z = 1; operations.operations().append(RotateTransformOperation::create(x, y, z, angle, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::Rotate3DTransformOperation: { if (transformValue->length() < 4) break; CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->item(1)); CSSPrimitiveValue* thirdValue = toCSSPrimitiveValue(transformValue->item(2)); CSSPrimitiveValue* fourthValue = toCSSPrimitiveValue(transformValue->item(3)); double x = firstValue->getDoubleValue(); double y = secondValue->getDoubleValue(); double z = thirdValue->getDoubleValue(); double angle = fourthValue->computeDegrees(); operations.operations().append(RotateTransformOperation::create(x, y, z, angle, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::SkewTransformOperation: case CSSTransformValue::SkewXTransformOperation: case CSSTransformValue::SkewYTransformOperation: { double angleX = 0; double angleY = 0; double angle = firstValue->computeDegrees(); if (transformValue->operationType() == CSSTransformValue::SkewYTransformOperation) angleY = angle; else { angleX = angle; if (transformValue->operationType() == CSSTransformValue::SkewTransformOperation) { if (transformValue->length() > 1) { CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->item(1)); angleY = secondValue->computeDegrees(); } } } operations.operations().append(SkewTransformOperation::create(angleX, angleY, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::MatrixTransformOperation: { if (transformValue->length() < 6) break; double a = firstValue->getDoubleValue(); double b = toCSSPrimitiveValue(transformValue->item(1))->getDoubleValue(); double c = toCSSPrimitiveValue(transformValue->item(2))->getDoubleValue(); double d = toCSSPrimitiveValue(transformValue->item(3))->getDoubleValue(); double e = toCSSPrimitiveValue(transformValue->item(4))->getDoubleValue(); double f = toCSSPrimitiveValue(transformValue->item(5))->getDoubleValue(); operations.operations().append(MatrixTransformOperation::create(a, b, c, d, e, f)); break; } case CSSTransformValue::Matrix3DTransformOperation: { if (transformValue->length() < 16) break; TransformationMatrix matrix(toCSSPrimitiveValue(transformValue->item(0))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(1))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(2))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(3))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(4))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(5))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(6))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(7))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(8))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(9))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(10))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(11))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(12))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(13))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(14))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(15))->getDoubleValue()); operations.operations().append(Matrix3DTransformOperation::create(matrix)); break; } case CSSTransformValue::PerspectiveTransformOperation: { double p; if (firstValue->isLength()) p = firstValue->computeLength<double>(conversionData); else { // This is a quirk that should go away when 3d transforms are finalized. double val = firstValue->getDoubleValue(); if (val < 0) return false; p = clampToPositiveInteger(val); } operations.operations().append(PerspectiveTransformOperation::create(p)); break; } case CSSTransformValue::UnknownTransformOperation: ASSERT_NOT_REACHED(); break; } } outOperations = operations; return true; }
void StyleBuilderFunctions::applyValueCSSPropertySize(StyleResolverState& state, CSSValue* value) { state.style()->resetPageSizeType(); Length width; Length height; PageSizeType pageSizeType = PAGE_SIZE_AUTO; CSSValueListInspector inspector(value); switch (inspector.length()) { case 2: { // <length>{2} | <page-size> <orientation> if (!inspector.first()->isPrimitiveValue() || !inspector.second()->isPrimitiveValue()) return; CSSPrimitiveValue* first = toCSSPrimitiveValue(inspector.first()); CSSPrimitiveValue* second = toCSSPrimitiveValue(inspector.second()); if (first->isLength()) { // <length>{2} if (!second->isLength()) return; width = first->computeLength<Length>(state.cssToLengthConversionData()); height = second->computeLength<Length>(state.cssToLengthConversionData()); } else { // <page-size> <orientation> // The value order is guaranteed. See BisonCSSParser::parseSizeParameter. if (!getPageSizeFromName(first, second, width, height)) return; } pageSizeType = PAGE_SIZE_RESOLVED; break; } case 1: { // <length> | auto | <page-size> | [ portrait | landscape] if (!inspector.first()->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(inspector.first()); if (primitiveValue->isLength()) { // <length> pageSizeType = PAGE_SIZE_RESOLVED; width = height = primitiveValue->computeLength<Length>(state.cssToLengthConversionData()); } else { switch (primitiveValue->getValueID()) { case 0: return; case CSSValueAuto: pageSizeType = PAGE_SIZE_AUTO; break; case CSSValuePortrait: pageSizeType = PAGE_SIZE_AUTO_PORTRAIT; break; case CSSValueLandscape: pageSizeType = PAGE_SIZE_AUTO_LANDSCAPE; break; default: // <page-size> pageSizeType = PAGE_SIZE_RESOLVED; if (!getPageSizeFromName(primitiveValue, 0, width, height)) return; } } break; } default: return; } state.style()->setPageSizeType(pageSizeType); state.style()->setPageSize(LengthSize(width, height)); }