Commit 12ed8948 authored by fs's avatar fs Committed by Commit bot

Perform "zoom compensation" for 'transform' on <svg:text>

SVGElement::calculateTransform would not compensate for effective zoom
on 'transform' for SVG <text> elements.
Refactor the code a bit so that the different parameter configurations
are selected first, and then use the same code for both <text> and non-
<text>. This makes sure that effective zoom is factored into the
computed transform for <text> as well.

BUG=665387,369942

Review-Url: https://codereview.chromium.org/2565403002
Cr-Commit-Position: refs/heads/master@{#437927}
parent 0467760e
<!DOCTYPE html>
<div style="width: 200px; height: 100px; background-color: green"></div>
<!DOCTYPE html>
<script src="../../resources/ahem.js"></script>
<svg height="100" width="100" style="zoom: 2" fill="green" font-family="Ahem" font-size="50px">
<text transform="translate(-50,-40)" x="50" y="80">X</text>
<text style="transform: translate(-50px, -40px)" x="100" y="80">X</text>
</svg>
...@@ -331,42 +331,40 @@ AffineTransform SVGElement::calculateTransform( ...@@ -331,42 +331,40 @@ AffineTransform SVGElement::calculateTransform(
TransformationMatrix transform; TransformationMatrix transform;
float zoom = style->effectiveZoom(); float zoom = style->effectiveZoom();
FloatRect boundingBox = layoutObject()->objectBoundingBox();
ComputedStyle::ApplyTransformOrigin applyTransformOrigin =
ComputedStyle::IncludeTransformOrigin;
// SVGTextElements need special handling for the text positioning code. // SVGTextElements need special handling for the text positioning code.
if (isSVGTextElement(this)) { if (isSVGTextElement(this)) {
// Do not take into account SVG's zoom rules, transform-origin, or // Do not take into account transform-origin, or percentage values.
// percentage values. boundingBox = FloatRect();
applyTransformOrigin = ComputedStyle::ExcludeTransformOrigin;
}
// 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) {
boundingBox.scale(zoom);
transform.scale(1 / zoom);
style->applyTransform( style->applyTransform(
transform, LayoutSize(0, 0), ComputedStyle::ExcludeTransformOrigin, transform, boundingBox, applyTransformOrigin,
ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeMotionPath,
ComputedStyle::IncludeIndependentTransformProperties); ComputedStyle::IncludeIndependentTransformProperties);
transform.scale(zoom);
} else { } else {
// CSS transforms operate with pre-scaled lengths. To make this work with style->applyTransform(
// SVG (which applies the zoom factor globally, at the root level) we transform, boundingBox, applyTransformOrigin,
// ComputedStyle::IncludeMotionPath,
// * pre-scale the bounding box (to bring it into the same space as the ComputedStyle::IncludeIndependentTransformProperties);
// 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 = layoutObject()->objectBoundingBox();
scaledBBox.scale(zoom);
transform.scale(1 / zoom);
style->applyTransform(
transform, scaledBBox, ComputedStyle::IncludeTransformOrigin,
ComputedStyle::IncludeMotionPath,
ComputedStyle::IncludeIndependentTransformProperties);
transform.scale(zoom);
} else {
style->applyTransform(
transform, layoutObject()->objectBoundingBox(),
ComputedStyle::IncludeTransformOrigin,
ComputedStyle::IncludeMotionPath,
ComputedStyle::IncludeIndependentTransformProperties);
}
} }
// Flatten any 3D transform. // Flatten any 3D transform.
matrix = transform.toAffineTransform(); matrix = transform.toAffineTransform();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment