AffineTransform SVGGraphicsElement::animatedLocalTransform() const { AffineTransform matrix; RenderStyle* style = renderer() ? &renderer()->style() : nullptr; // If CSS property was set, use that, otherwise fallback to attribute (if set). if (style && style->hasTransform()) { // Note: objectBoundingBox is an emptyRect for elements like pattern or clipPath. // See the "Object bounding box units" section of http://dev.w3.org/csswg/css3-transforms/ TransformationMatrix transform; style->applyTransform(transform, renderer()->objectBoundingBox()); // Flatten any 3D transform. matrix = transform.toAffineTransform(); // CSS bakes the zoom factor into lengths, including translation components. // In order to align CSS & SVG transforms, we need to invert this operation. float zoom = style->effectiveZoom(); if (zoom != 1) { matrix.setE(matrix.e() / zoom); matrix.setF(matrix.f() / zoom); } } else transform().concatenate(matrix); if (m_supplementalTransform) return *m_supplementalTransform * matrix; return matrix; }
AffineTransform SVGGraphicsElement::calculateAnimatedLocalTransform() const { AffineTransform matrix; RenderStyle* style = renderer() ? renderer()->style() : 0; // If CSS property was set, use that, otherwise fallback to attribute (if set). if (style && style->hasTransform()) { TransformationMatrix transform; float zoom = style->effectiveZoom(); // SVGTextElements need special handling for the text positioning code. if (isSVGTextElement(this)) { // Do not take into account SVG's zoom rules, transform-origin, or percentage values. style->applyTransform(transform, IntSize(0, 0), RenderStyle::ExcludeTransformOrigin); } else { // CSS transforms operate with pre-scaled lengths. To make this work with SVG // (which applies the zoom factor globally, at the root level) we // // * pre-scale the bounding box (to bring it into the same space as the other CSS values) // * invert the zoom factor (to effectively compute the CSS transform under a 1.0 zoom) // // Note: objectBoundingBox is an emptyRect for elements like pattern or clipPath. // See the "Object bounding box units" section of http://dev.w3.org/csswg/css3-transforms/ if (zoom != 1) { FloatRect scaledBBox = renderer()->objectBoundingBox(); scaledBBox.scale(zoom); transform.scale(1 / zoom); style->applyTransform(transform, scaledBBox); transform.scale(zoom); } else { style->applyTransform(transform, renderer()->objectBoundingBox()); } } // Flatten any 3D transform. matrix = transform.toAffineTransform(); } else { m_transform->currentValue()->concatenate(matrix); } if (hasSVGRareData()) return *svgRareData()->animateMotionTransform() * matrix; return matrix; }
bool AnimationBase::computeTransformedExtentViaMatrix(const FloatRect& rendererBox, const RenderStyle& style, LayoutRect& bounds) const { TransformationMatrix transform; style.applyTransform(transform, rendererBox, RenderStyle::IncludeTransformOrigin); if (!transform.isAffine()) return false; TransformationMatrix::Decomposed2Type fromDecomp; transform.decompose2(fromDecomp); // Any rotation prevents us from using a simple start/end rect union. if (fromDecomp.angle) return false; bounds = LayoutRect(transform.mapRect(bounds)); return true; }
AffineTransform SVGStyledTransformableElement::animatedLocalTransform() const { AffineTransform matrix; RenderStyle* style = renderer() ? renderer()->style() : 0; // if CSS property was set, use that, otherwise fallback to attribute (if set) if (style && style->hasTransform()) { TransformationMatrix t; // For now, the transform-origin is not taken into account // Also, any percentage values will not be taken into account style->applyTransform(t, IntSize(0, 0), RenderStyle::ExcludeTransformOrigin); // Flatten any 3D transform matrix = t.toAffineTransform(); } else transform().concatenate(matrix); if (m_supplementalTransform) return *m_supplementalTransform * matrix; return matrix; }
AffineTransform SVGGraphicsElement::animatedLocalTransform() const { AffineTransform matrix; RenderStyle* style = renderer() ? &renderer()->style() : nullptr; // If CSS property was set, use that, otherwise fallback to attribute (if set). if (style && style->hasTransform()) { // Note: objectBoundingBox is an emptyRect for elements like pattern or clipPath. // See the "Object bounding box units" section of http://dev.w3.org/csswg/css3-transforms/ TransformationMatrix transform; style->applyTransform(transform, renderer()->objectBoundingBox()); // Flatten any 3D transform. matrix = transform.toAffineTransform(); } else transform().concatenate(matrix); if (m_supplementalTransform) return *m_supplementalTransform * matrix; return matrix; }
// We override SVGGraphics::animatedLocalTransform() so that the transform-origin // is not taken into account. AffineTransform SVGTextElement::animatedLocalTransform() const { AffineTransform matrix; RenderStyle* style = renderer() ? &renderer()->style() : nullptr; // if CSS property was set, use that, otherwise fallback to attribute (if set) if (style && style->hasTransform()) { TransformationMatrix t; // For now, the transform-origin is not taken into account // Also, any percentage values will not be taken into account style->applyTransform(t, FloatRect(0, 0, 0, 0), RenderStyle::ExcludeTransformOrigin); // Flatten any 3D transform matrix = t.toAffineTransform(); } else transform().concatenate(matrix); const AffineTransform* transform = const_cast<SVGTextElement*>(this)->supplementalTransform(); if (transform) return *transform * matrix; return matrix; }