OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann |
3 * <zimmermann@kde.org> | 3 * <zimmermann@kde.org> |
4 * Copyright (C) 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> | 4 * Copyright (C) 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> |
5 * Copyright (C) 2008 Apple Inc. All rights reserved. | 5 * Copyright (C) 2008 Apple Inc. All rights reserved. |
6 * Copyright (C) 2008 Alp Toker <alp@atoker.com> | 6 * Copyright (C) 2008 Alp Toker <alp@atoker.com> |
7 * Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> | 7 * Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> |
8 * | 8 * |
9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
309 return true; | 309 return true; |
310 if (style.transform().dependsOnBoxSize()) | 310 if (style.transform().dependsOnBoxSize()) |
311 return true; | 311 return true; |
312 if (style.translate() && style.translate()->dependsOnBoxSize()) | 312 if (style.translate() && style.translate()->dependsOnBoxSize()) |
313 return true; | 313 return true; |
314 if (style.hasOffset()) | 314 if (style.hasOffset()) |
315 return true; | 315 return true; |
316 return false; | 316 return false; |
317 } | 317 } |
318 | 318 |
319 static FloatRect computeTransformReferenceBox(const SVGElement& element) { | |
320 const LayoutObject& layoutObject = *element.layoutObject(); | |
321 const ComputedStyle& style = layoutObject.styleRef(); | |
322 if (!RuntimeEnabledFeatures::cssTransformBoxEnabled()) { | |
323 FloatRect referenceBox = layoutObject.objectBoundingBox(); | |
324 // Set the reference origin to zero when transform-origin (x/y) has a | |
325 // non-percentage unit. | |
326 const TransformOrigin& transformOrigin = style.transformOrigin(); | |
327 if (transformOrigin.x().type() != Percent) | |
328 referenceBox.setX(0); | |
329 if (transformOrigin.y().type() != Percent) | |
330 referenceBox.setY(0); | |
331 return referenceBox; | |
332 } | |
333 if (style.transformBox() == ETransformBox::kFillBox) | |
pdr.
2017/04/04 22:47:13
I was looking at Gecko's implementation and they a
fs
2017/04/05 08:48:17
I've not managed to find any relevant minutes abou
| |
334 return layoutObject.objectBoundingBox(); | |
335 DCHECK(style.transformBox() == ETransformBox::kBorderBox || | |
336 style.transformBox() == ETransformBox::kViewBox); | |
337 SVGLengthContext lengthContext(&element); | |
338 FloatSize viewportSize; | |
339 lengthContext.determineViewport(viewportSize); | |
340 return FloatRect(FloatPoint(), viewportSize); | |
341 } | |
342 | |
319 AffineTransform SVGElement::calculateTransform( | 343 AffineTransform SVGElement::calculateTransform( |
320 ApplyMotionTransform applyMotionTransform) const { | 344 ApplyMotionTransform applyMotionTransform) const { |
321 const ComputedStyle* style = | 345 const ComputedStyle* style = |
322 layoutObject() ? layoutObject()->style() : nullptr; | 346 layoutObject() ? layoutObject()->style() : nullptr; |
323 | 347 |
324 // If CSS property was set, use that, otherwise fallback to attribute (if | 348 // If CSS property was set, use that, otherwise fallback to attribute (if |
325 // set). | 349 // set). |
326 AffineTransform matrix; | 350 AffineTransform matrix; |
327 if (style && style->hasTransform()) { | 351 if (style && style->hasTransform()) { |
328 TransformationMatrix transform; | 352 FloatRect referenceBox = computeTransformReferenceBox(*this); |
329 float zoom = style->effectiveZoom(); | |
330 | |
331 FloatRect boundingBox = layoutObject()->objectBoundingBox(); | |
332 ComputedStyle::ApplyTransformOrigin applyTransformOrigin = | 353 ComputedStyle::ApplyTransformOrigin applyTransformOrigin = |
333 ComputedStyle::IncludeTransformOrigin; | 354 ComputedStyle::IncludeTransformOrigin; |
334 // SVGTextElements need special handling for the text positioning code. | 355 // SVGTextElements need special handling for the text positioning code. |
335 if (isSVGTextElement(this)) { | 356 if (isSVGTextElement(this)) { |
336 // Do not take into account transform-origin, or percentage values. | 357 // Do not take into account transform-origin, or percentage values. |
337 boundingBox = FloatRect(); | 358 referenceBox = FloatRect(); |
338 applyTransformOrigin = ComputedStyle::ExcludeTransformOrigin; | 359 applyTransformOrigin = ComputedStyle::ExcludeTransformOrigin; |
339 } | 360 } |
340 | 361 |
341 if (transformUsesBoxSize(*style, applyTransformOrigin)) | 362 if (transformUsesBoxSize(*style, applyTransformOrigin)) |
342 UseCounter::count(document(), UseCounter::TransformUsesBoxSizeOnSVG); | 363 UseCounter::count(document(), UseCounter::TransformUsesBoxSizeOnSVG); |
343 | 364 |
344 // CSS transforms operate with pre-scaled lengths. To make this work with | 365 // CSS transforms operate with pre-scaled lengths. To make this work with |
345 // SVG (which applies the zoom factor globally, at the root level) we | 366 // SVG (which applies the zoom factor globally, at the root level) we |
346 // | 367 // |
347 // * pre-scale the bounding box (to bring it into the same space as the | 368 // * pre-scale the reference box (to bring it into the same space as the |
348 // other CSS values) | 369 // other CSS values) |
349 // * invert the zoom factor (to effectively compute the CSS transform | 370 // * invert the zoom factor (to effectively compute the CSS transform |
350 // under a 1.0 zoom) | 371 // under a 1.0 zoom) |
351 // | 372 // |
352 // Note: objectBoundingBox is an emptyRect for elements like pattern or | 373 // Note: objectBoundingBox is an emptyRect for elements like pattern or |
353 // clipPath. See the "Object bounding box units" section of | 374 // clipPath. See the "Object bounding box units" section of |
354 // http://dev.w3.org/csswg/css3-transforms/ | 375 // http://dev.w3.org/csswg/css3-transforms/ |
376 float zoom = style->effectiveZoom(); | |
377 TransformationMatrix transform; | |
355 if (zoom != 1) { | 378 if (zoom != 1) { |
356 boundingBox.scale(zoom); | 379 referenceBox.scale(zoom); |
357 transform.scale(1 / zoom); | 380 transform.scale(1 / zoom); |
358 style->applyTransform( | 381 style->applyTransform( |
359 transform, boundingBox, applyTransformOrigin, | 382 transform, referenceBox, applyTransformOrigin, |
360 ComputedStyle::IncludeMotionPath, | 383 ComputedStyle::IncludeMotionPath, |
361 ComputedStyle::IncludeIndependentTransformProperties); | 384 ComputedStyle::IncludeIndependentTransformProperties); |
362 transform.scale(zoom); | 385 transform.scale(zoom); |
363 } else { | 386 } else { |
364 style->applyTransform( | 387 style->applyTransform( |
365 transform, boundingBox, applyTransformOrigin, | 388 transform, referenceBox, applyTransformOrigin, |
366 ComputedStyle::IncludeMotionPath, | 389 ComputedStyle::IncludeMotionPath, |
367 ComputedStyle::IncludeIndependentTransformProperties); | 390 ComputedStyle::IncludeIndependentTransformProperties); |
368 } | 391 } |
369 // Flatten any 3D transform. | 392 // Flatten any 3D transform. |
370 matrix = transform.toAffineTransform(); | 393 matrix = transform.toAffineTransform(); |
371 } | 394 } |
372 | 395 |
373 // Apply any "motion transform" contribution if requested (and existing.) | 396 // Apply any "motion transform" contribution if requested (and existing.) |
374 if (applyMotionTransform == IncludeMotionTransform && hasSVGRareData()) | 397 if (applyMotionTransform == IncludeMotionTransform && hasSVGRareData()) |
375 matrix.preMultiply(*svgRareData()->animateMotionTransform()); | 398 matrix.preMultiply(*svgRareData()->animateMotionTransform()); |
(...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1300 visitor->trace(m_className); | 1323 visitor->trace(m_className); |
1301 Element::trace(visitor); | 1324 Element::trace(visitor); |
1302 } | 1325 } |
1303 | 1326 |
1304 const AtomicString& SVGElement::eventParameterName() { | 1327 const AtomicString& SVGElement::eventParameterName() { |
1305 DEFINE_STATIC_LOCAL(const AtomicString, evtString, ("evt")); | 1328 DEFINE_STATIC_LOCAL(const AtomicString, evtString, ("evt")); |
1306 return evtString; | 1329 return evtString; |
1307 } | 1330 } |
1308 | 1331 |
1309 } // namespace blink | 1332 } // namespace blink |
OLD | NEW |