Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: Source/core/rendering/svg/RenderSVGRoot.cpp

Issue 26390004: Rework SVG sizing (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fix mishap during rebase in svg.css Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698