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 |