| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> | 2 * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> |
| 3 * Copyright (C) 2004, 2005, 2007, 2008, 2009 Rob Buis <buis@kde.org> | 3 * Copyright (C) 2004, 2005, 2007, 2008, 2009 Rob Buis <buis@kde.org> |
| 4 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> | 4 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> |
| 5 * Copyright (C) 2009 Google, Inc. | 5 * Copyright (C) 2009 Google, Inc. |
| 6 * Copyright (C) Research In Motion Limited 2011. All rights reserved. | 6 * Copyright (C) Research In Motion Limited 2011. All rights reserved. |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 , m_isLayoutSizeChanged(false) | 51 , m_isLayoutSizeChanged(false) |
| 52 , m_needsBoundariesOrTransformUpdate(true) | 52 , m_needsBoundariesOrTransformUpdate(true) |
| 53 , m_hasBoxDecorations(false) | 53 , m_hasBoxDecorations(false) |
| 54 { | 54 { |
| 55 } | 55 } |
| 56 | 56 |
| 57 RenderSVGRoot::~RenderSVGRoot() | 57 RenderSVGRoot::~RenderSVGRoot() |
| 58 { | 58 { |
| 59 } | 59 } |
| 60 | 60 |
| 61 void RenderSVGRoot::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, d
ouble& intrinsicRatio, bool& isPercentageIntrinsicSize) const | 61 void RenderSVGRoot::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, d
ouble& intrinsicRatio) const |
| 62 { | 62 { |
| 63 // Spec: http://www.w3.org/TR/SVG/coords.html#IntrinsicSizing | 63 // Spec: http://www.w3.org/TR/SVG/coords.html#IntrinsicSizing |
| 64 // SVG needs to specify how to calculate some intrinsic sizing properties to
enable inclusion within other languages. | 64 // SVG needs to specify how to calculate some intrinsic sizing properties to
enable inclusion within other languages. |
| 65 // The intrinsic width and height of the viewport of SVG content must be det
ermined from the ‘width’ and ‘height’ attributes. | 65 // The intrinsic width and height of the viewport of SVG content must be det
ermined from the ‘width’ and ‘height’ attributes. |
| 66 // If either of these are not specified, a value of '100%' must be assumed.
Note: the ‘width’ and ‘height’ attributes are not | |
| 67 // the same as the CSS width and height properties. Specifically, percentage
values do not provide an intrinsic width or height, | |
| 68 // and do not indicate a percentage of the containing block. Rather, once th
e viewport is established, they indicate the portion | |
| 69 // of the viewport that is actually covered by image data. | |
| 70 SVGSVGElement* svg = toSVGSVGElement(node()); | 66 SVGSVGElement* svg = toSVGSVGElement(node()); |
| 71 ASSERT(svg); | 67 ASSERT(svg); |
| 72 Length intrinsicWidthAttribute = svg->intrinsicWidth(SVGSVGElement::IgnoreCS
SProperties); | |
| 73 Length intrinsicHeightAttribute = svg->intrinsicHeight(SVGSVGElement::Ignore
CSSProperties); | |
| 74 | 68 |
| 75 // The intrinsic aspect ratio of the viewport of SVG content is necessary fo
r example, when including SVG from an ‘object’ | 69 // The intrinsic aspect ratio of the viewport of SVG content is necessary fo
r example, when including SVG from an ‘object’ |
| 76 // element in HTML styled with CSS. It is possible (indeed, common) for an S
VG graphic to have an intrinsic aspect ratio but | 70 // element in HTML styled with CSS. It is possible (indeed, common) for an S
VG graphic to have an intrinsic aspect ratio but |
| 77 // not to have an intrinsic width or height. The intrinsic aspect ratio must
be calculated based upon the following rules: | 71 // not to have an intrinsic width or height. The intrinsic aspect ratio must
be calculated based upon the following rules: |
| 78 // - The aspect ratio is calculated by dividing a width by a height. | 72 // - The aspect ratio is calculated by dividing a width by a height. |
| 79 // - If the ‘width’ and ‘height’ of the rootmost ‘svg’ element are both spec
ified with unit identifiers (in, mm, cm, pt, pc, | 73 // - If the ‘width’ and ‘height’ of the rootmost ‘svg’ element are both spec
ified with unit identifiers (in, mm, cm, pt, pc, |
| 80 // px, em, ex) or in user units, then the aspect ratio is calculated from
the ‘width’ and ‘height’ attributes after | 74 // px, em, ex) or in user units, then the aspect ratio is calculated from
the ‘width’ and ‘height’ attributes after |
| 81 // resolving both values to user units. | 75 // resolving both values to user units. |
| 82 if (intrinsicWidthAttribute.isFixed() || intrinsicHeightAttribute.isFixed())
{ | 76 intrinsicSize.setWidth(floatValueForLength(svg->intrinsicWidth(), 0)); |
| 83 if (intrinsicWidthAttribute.isFixed()) | 77 intrinsicSize.setHeight(floatValueForLength(svg->intrinsicHeight(), 0)); |
| 84 intrinsicSize.setWidth(floatValueForLength(intrinsicWidthAttribute,
0)); | |
| 85 if (intrinsicHeightAttribute.isFixed()) | |
| 86 intrinsicSize.setHeight(floatValueForLength(intrinsicHeightAttribute
, 0)); | |
| 87 if (!intrinsicSize.isEmpty()) | |
| 88 intrinsicRatio = intrinsicSize.width() / static_cast<double>(intrins
icSize.height()); | |
| 89 return; | |
| 90 } | |
| 91 | 78 |
| 92 // - If either/both of the ‘width’ and ‘height’ of the rootmost ‘svg’ elemen
t are in percentage units (or omitted), the | |
| 93 // aspect ratio is calculated from the width and height values of the ‘vie
wBox’ specified for the current SVG document | |
| 94 // fragment. If the ‘viewBox’ is not correctly specified, or set to 'none'
, the intrinsic aspect ratio cannot be | |
| 95 // calculated and is considered unspecified. | |
| 96 intrinsicSize = svg->viewBox()->currentValue()->value().size(); | |
| 97 if (!intrinsicSize.isEmpty()) { | 79 if (!intrinsicSize.isEmpty()) { |
| 98 // The viewBox can only yield an intrinsic ratio, not an intrinsic size. | |
| 99 intrinsicRatio = intrinsicSize.width() / static_cast<double>(intrinsicSi
ze.height()); | 80 intrinsicRatio = intrinsicSize.width() / static_cast<double>(intrinsicSi
ze.height()); |
| 100 intrinsicSize = FloatSize(); | 81 } else { |
| 101 return; | 82 // - If either/both of the ‘width’ and ‘height’ of the rootmost ‘svg’ el
ement are in percentage units (or omitted), the |
| 102 } | 83 // aspect ratio is calculated from the width and height values of the
‘viewBox’ specified for the current SVG document |
| 103 | 84 // fragment. If the ‘viewBox’ is not correctly specified, or set to 'n
one', the intrinsic aspect ratio cannot be |
| 104 // If our intrinsic size is in percentage units, return those to the caller
through the intrinsicSize. Notify the caller | 85 // calculated and is considered unspecified. |
| 105 // about the special situation, by setting isPercentageIntrinsicSize=true, s
o it knows how to interpret the return values. | 86 FloatSize viewBoxSize = svg->viewBox()->currentValue()->value().size(); |
| 106 if (intrinsicWidthAttribute.isPercent() && intrinsicHeightAttribute.isPercen
t()) { | 87 if (!viewBoxSize.isEmpty()) { |
| 107 isPercentageIntrinsicSize = true; | 88 // The viewBox can only yield an intrinsic ratio, not an intrinsic s
ize. |
| 108 intrinsicSize = FloatSize(intrinsicWidthAttribute.percent(), intrinsicHe
ightAttribute.percent()); | 89 intrinsicRatio = viewBoxSize.width() / static_cast<double>(viewBoxSi
ze.height()); |
| 90 } |
| 109 } | 91 } |
| 110 } | 92 } |
| 111 | 93 |
| 112 bool RenderSVGRoot::isEmbeddedThroughSVGImage() const | 94 bool RenderSVGRoot::isEmbeddedThroughSVGImage() const |
| 113 { | 95 { |
| 114 return SVGImage::isInSVGImage(toSVGSVGElement(node())); | 96 return SVGImage::isInSVGImage(toSVGSVGElement(node())); |
| 115 } | 97 } |
| 116 | 98 |
| 117 bool RenderSVGRoot::isEmbeddedThroughFrameContainingSVGDocument() const | 99 bool RenderSVGRoot::isEmbeddedThroughFrameContainingSVGDocument() const |
| 118 { | 100 { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 137 | 119 |
| 138 LayoutUnit RenderSVGRoot::computeReplacedLogicalWidth(ShouldComputePreferred sho
uldComputePreferred) const | 120 LayoutUnit RenderSVGRoot::computeReplacedLogicalWidth(ShouldComputePreferred sho
uldComputePreferred) const |
| 139 { | 121 { |
| 140 SVGSVGElement* svg = toSVGSVGElement(node()); | 122 SVGSVGElement* svg = toSVGSVGElement(node()); |
| 141 ASSERT(svg); | 123 ASSERT(svg); |
| 142 | 124 |
| 143 // When we're embedded through SVGImage (border-image/background-image/<html
:img>/...) we're forced to resize to a specific size. | 125 // When we're embedded through SVGImage (border-image/background-image/<html
:img>/...) we're forced to resize to a specific size. |
| 144 if (!m_containerSize.isEmpty()) | 126 if (!m_containerSize.isEmpty()) |
| 145 return m_containerSize.width(); | 127 return m_containerSize.width(); |
| 146 | 128 |
| 129 if (isEmbeddedThroughFrameContainingSVGDocument()) |
| 130 return containingBlock()->availableLogicalWidth(); |
| 131 |
| 147 if (style()->logicalWidth().isSpecified() || style()->logicalMaxWidth().isSp
ecified()) | 132 if (style()->logicalWidth().isSpecified() || style()->logicalMaxWidth().isSp
ecified()) |
| 148 return RenderReplaced::computeReplacedLogicalWidth(shouldComputePreferre
d); | 133 return RenderReplaced::computeReplacedLogicalWidth(shouldComputePreferre
d); |
| 149 | 134 |
| 150 if (svg->widthAttributeEstablishesViewport()) | 135 if (svg->hasIntrinsicWidth()) |
| 151 return resolveLengthAttributeForSVG(svg->intrinsicWidth(SVGSVGElement::I
gnoreCSSProperties), style()->effectiveZoom(), containingBlock()->availableLogic
alWidth().toFloat()); | 136 return resolveLengthAttributeForSVG(svg->intrinsicWidth(), style()->effe
ctiveZoom(), containingBlock()->availableLogicalWidth().toFloat()); |
| 152 | |
| 153 // SVG embedded through object/embed/iframe. | |
| 154 if (isEmbeddedThroughFrameContainingSVGDocument()) | |
| 155 return document().frame()->ownerRenderer()->availableLogicalWidth(); | |
| 156 | 137 |
| 157 // SVG embedded via SVGImage (background-image/border-image/etc) / Inline SV
G. | 138 // SVG embedded via SVGImage (background-image/border-image/etc) / Inline SV
G. |
| 158 return RenderReplaced::computeReplacedLogicalWidth(shouldComputePreferred); | 139 return RenderReplaced::computeReplacedLogicalWidth(shouldComputePreferred); |
| 159 } | 140 } |
| 160 | 141 |
| 161 LayoutUnit RenderSVGRoot::computeReplacedLogicalHeight() const | 142 LayoutUnit RenderSVGRoot::computeReplacedLogicalHeight() const |
| 162 { | 143 { |
| 163 SVGSVGElement* svg = toSVGSVGElement(node()); | 144 SVGSVGElement* svg = toSVGSVGElement(node()); |
| 164 ASSERT(svg); | 145 ASSERT(svg); |
| 165 | 146 |
| 166 // When we're embedded through SVGImage (border-image/background-image/<html
:img>/...) we're forced to resize to a specific size. | 147 // When we're embedded through SVGImage (border-image/background-image/<html
:img>/...) we're forced to resize to a specific size. |
| 167 if (!m_containerSize.isEmpty()) | 148 if (!m_containerSize.isEmpty()) |
| 168 return m_containerSize.height(); | 149 return m_containerSize.height(); |
| 169 | 150 |
| 151 if (isEmbeddedThroughFrameContainingSVGDocument()) |
| 152 return containingBlock()->availableLogicalHeight(IncludeMarginBorderPadd
ing); |
| 153 |
| 170 if (style()->logicalHeight().isSpecified() || style()->logicalMaxHeight().is
Specified()) | 154 if (style()->logicalHeight().isSpecified() || style()->logicalMaxHeight().is
Specified()) |
| 171 return RenderReplaced::computeReplacedLogicalHeight(); | 155 return RenderReplaced::computeReplacedLogicalHeight(); |
| 172 | 156 |
| 173 if (svg->heightAttributeEstablishesViewport()) { | 157 if (svg->hasIntrinsicHeight()) |
| 174 Length height = svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties)
; | 158 return resolveLengthAttributeForSVG(svg->intrinsicHeight(), style()->eff
ectiveZoom(), containingBlock()->availableLogicalHeight(IncludeMarginBorderPaddi
ng).toFloat()); |
| 175 if (height.isPercent()) { | |
| 176 RenderBlock* cb = containingBlock(); | |
| 177 ASSERT(cb); | |
| 178 while (cb->isAnonymous()) | |
| 179 cb = cb->containingBlock(); | |
| 180 cb->addPercentHeightDescendant(const_cast<RenderSVGRoot*>(this)); | |
| 181 } else | |
| 182 RenderBlock::removePercentHeightDescendant(const_cast<RenderSVGRoot*
>(this)); | |
| 183 | |
| 184 return resolveLengthAttributeForSVG(height, style()->effectiveZoom(), co
ntainingBlock()->availableLogicalHeight(IncludeMarginBorderPadding).toFloat()); | |
| 185 } | |
| 186 | |
| 187 // SVG embedded through object/embed/iframe. | |
| 188 if (isEmbeddedThroughFrameContainingSVGDocument()) | |
| 189 return document().frame()->ownerRenderer()->availableLogicalHeight(Inclu
deMarginBorderPadding); | |
| 190 | 159 |
| 191 // SVG embedded via SVGImage (background-image/border-image/etc) / Inline SV
G. | 160 // SVG embedded via SVGImage (background-image/border-image/etc) / Inline SV
G. |
| 192 return RenderReplaced::computeReplacedLogicalHeight(); | 161 return RenderReplaced::computeReplacedLogicalHeight(); |
| 193 } | 162 } |
| 194 | 163 |
| 195 void RenderSVGRoot::layout() | 164 void RenderSVGRoot::layout() |
| 196 { | 165 { |
| 197 ASSERT(needsLayout()); | 166 ASSERT(needsLayout()); |
| 198 | 167 |
| 199 // Arbitrary affine transforms are incompatible with LayoutState. | 168 // Arbitrary affine transforms are incompatible with LayoutState. |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 if (locationInContainer.intersects(boundsRect)) { | 428 if (locationInContainer.intersects(boundsRect)) { |
| 460 updateHitTestResult(result, pointInBorderBox); | 429 updateHitTestResult(result, pointInBorderBox); |
| 461 if (!result.addNodeToRectBasedTestResult(node(), request, locationIn
Container, boundsRect)) | 430 if (!result.addNodeToRectBasedTestResult(node(), request, locationIn
Container, boundsRect)) |
| 462 return true; | 431 return true; |
| 463 } | 432 } |
| 464 } | 433 } |
| 465 | 434 |
| 466 return false; | 435 return false; |
| 467 } | 436 } |
| 468 | 437 |
| 469 bool RenderSVGRoot::hasRelativeIntrinsicLogicalWidth() const | |
| 470 { | |
| 471 SVGSVGElement* svg = toSVGSVGElement(node()); | |
| 472 ASSERT(svg); | |
| 473 return svg->intrinsicWidth(SVGSVGElement::IgnoreCSSProperties).isPercent(); | |
| 474 } | 438 } |
| 475 | |
| 476 bool RenderSVGRoot::hasRelativeLogicalHeight() const | |
| 477 { | |
| 478 SVGSVGElement* svg = toSVGSVGElement(node()); | |
| 479 ASSERT(svg); | |
| 480 | |
| 481 return svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties).isPercent(); | |
| 482 } | |
| 483 | |
| 484 } | |
| OLD | NEW |