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

Side by Side Diff: Source/core/svg/SVGLengthContext.cpp

Issue 1065223003: Cleanup resolving of 'em' units in SVGLengthContext (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/svg/SVGLengthContext.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> 2 * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> 3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
4 * Copyright (C) 2007 Apple Inc. All rights reserved. 4 * Copyright (C) 2007 Apple Inc. All rights reserved.
5 * Copyright (C) Research In Motion Limited 2011. All rights reserved. 5 * Copyright (C) Research In Motion Limited 2011. All rights reserved.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public 8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 } 46 }
47 ASSERT_NOT_REACHED(); 47 ASSERT_NOT_REACHED();
48 return 0; 48 return 0;
49 } 49 }
50 50
51 static float convertValueFromPercentageToUserUnits(const SVGLength& value, const FloatSize& viewportSize) 51 static float convertValueFromPercentageToUserUnits(const SVGLength& value, const FloatSize& viewportSize)
52 { 52 {
53 return CSSPrimitiveValue::clampToCSSLengthRange(value.scaleByPercentage(dime nsionForLengthMode(value.unitMode(), viewportSize))); 53 return CSSPrimitiveValue::clampToCSSLengthRange(value.scaleByPercentage(dime nsionForLengthMode(value.unitMode(), viewportSize)));
54 } 54 }
55 55
56 static const ComputedStyle* computedStyleForLengthResolving(const SVGElement* co ntext)
57 {
58 if (!context)
59 return 0;
60
61 const ContainerNode* currentContext = context;
62 do {
63 if (currentContext->layoutObject())
64 return currentContext->layoutObject()->style();
65 currentContext = currentContext->parentNode();
66 } while (currentContext);
67
68 // There must be at least a LayoutSVGRoot renderer, carrying a style.
69 ASSERT_NOT_REACHED();
70 return 0;
71 }
72
73 static const ComputedStyle* rootElementStyle(const Node* context)
74 {
75 if (!context)
76 return 0;
77
78 const Document& document = context->document();
79 Node* documentElement = document.documentElement();
80 const ComputedStyle* documentStyle = document.computedStyle();
81 const ComputedStyle* style = documentElement && context != documentElement ? documentElement->computedStyle() : documentStyle;
82 if (!style)
83 style = documentStyle;
84 return style;
85 }
86
87 static float convertValueFromUserUnitsToEMS(const ComputedStyle* style, float va lue)
88 {
89 if (!style)
90 return 0;
91 float fontSize = style->specifiedFontSize();
92 if (!fontSize)
93 return 0;
94 return value / fontSize;
95 }
96
97 static float convertValueFromEMSToUserUnits(const ComputedStyle* style, float va lue)
98 {
99 if (!style)
100 return 0;
101 return value * style->specifiedFontSize();
102 }
103
56 SVGLengthContext::SVGLengthContext(const SVGElement* context) 104 SVGLengthContext::SVGLengthContext(const SVGElement* context)
57 : m_context(context) 105 : m_context(context)
58 { 106 {
59 } 107 }
60 108
61 FloatRect SVGLengthContext::resolveRectangle(const SVGElement* context, SVGUnitT ypes::SVGUnitType type, const FloatRect& viewport, const SVGLength& x, const SVG Length& y, const SVGLength& width, const SVGLength& height) 109 FloatRect SVGLengthContext::resolveRectangle(const SVGElement* context, SVGUnitT ypes::SVGUnitType type, const FloatRect& viewport, const SVGLength& x, const SVG Length& y, const SVGLength& width, const SVGLength& height)
62 { 110 {
63 ASSERT(type != SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN); 111 ASSERT(type != SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN);
64 if (type != SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE && !viewport.isEmpty( )) { 112 if (type != SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE && !viewport.isEmpty( )) {
65 const FloatSize& viewportSize = viewport.size(); 113 const FloatSize& viewportSize = viewport.size();
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 userUnits = value; 190 userUnits = value;
143 break; 191 break;
144 case LengthTypePercentage: { 192 case LengthTypePercentage: {
145 FloatSize viewportSize; 193 FloatSize viewportSize;
146 if (!determineViewport(viewportSize)) 194 if (!determineViewport(viewportSize))
147 return 0; 195 return 0;
148 userUnits = value * dimensionForLengthMode(mode, viewportSize) / 100; 196 userUnits = value * dimensionForLengthMode(mode, viewportSize) / 100;
149 break; 197 break;
150 } 198 }
151 case LengthTypeEMS: 199 case LengthTypeEMS:
152 userUnits = convertValueFromEMSToUserUnits(value); 200 userUnits = convertValueFromEMSToUserUnits(computedStyleForLengthResolvi ng(m_context), value);
153 break; 201 break;
154 case LengthTypeEXS: 202 case LengthTypeEXS:
155 userUnits = convertValueFromEXSToUserUnits(value); 203 userUnits = convertValueFromEXSToUserUnits(value);
156 break; 204 break;
157 case LengthTypeCM: 205 case LengthTypeCM:
158 userUnits = value * cssPixelsPerCentimeter; 206 userUnits = value * cssPixelsPerCentimeter;
159 break; 207 break;
160 case LengthTypeMM: 208 case LengthTypeMM:
161 userUnits = value * cssPixelsPerMillimeter; 209 userUnits = value * cssPixelsPerMillimeter;
162 break; 210 break;
163 case LengthTypeIN: 211 case LengthTypeIN:
164 userUnits = value * cssPixelsPerInch; 212 userUnits = value * cssPixelsPerInch;
165 break; 213 break;
166 case LengthTypePT: 214 case LengthTypePT:
167 userUnits = value * cssPixelsPerPoint; 215 userUnits = value * cssPixelsPerPoint;
168 break; 216 break;
169 case LengthTypePC: 217 case LengthTypePC:
170 userUnits = value * cssPixelsPerPica; 218 userUnits = value * cssPixelsPerPica;
171 break; 219 break;
172 case LengthTypeREMS: 220 case LengthTypeREMS:
173 userUnits = convertValueFromREMSToUserUnits(value); 221 userUnits = convertValueFromEMSToUserUnits(rootElementStyle(m_context), value);
174 break; 222 break;
175 default: 223 default:
176 ASSERT_NOT_REACHED(); 224 ASSERT_NOT_REACHED();
177 break; 225 break;
178 } 226 }
179 227
180 // Since we mix css <length> values with svg's length values we need to 228 // Since we mix css <length> values with svg's length values we need to
181 // clamp values to the narrowest range, otherwise it can result in 229 // clamp values to the narrowest range, otherwise it can result in
182 // rendering issues. 230 // rendering issues.
183 return CSSPrimitiveValue::clampToCSSLengthRange(userUnits); 231 return CSSPrimitiveValue::clampToCSSLengthRange(userUnits);
184 } 232 }
185 233
186 float SVGLengthContext::convertValueFromUserUnits(float value, SVGLengthMode mod e, SVGLengthType toUnit) const 234 float SVGLengthContext::convertValueFromUserUnits(float value, SVGLengthMode mod e, SVGLengthType toUnit) const
187 { 235 {
188 switch (toUnit) { 236 switch (toUnit) {
189 case LengthTypeUnknown: 237 case LengthTypeUnknown:
190 return 0; 238 return 0;
191 case LengthTypeNumber: 239 case LengthTypeNumber:
192 return value; 240 return value;
193 case LengthTypePercentage: { 241 case LengthTypePercentage: {
194 FloatSize viewportSize; 242 FloatSize viewportSize;
195 if (!determineViewport(viewportSize)) 243 if (!determineViewport(viewportSize))
196 return 0; 244 return 0;
197 // LengthTypePercentage is represented with 100% = 100.0. 245 // LengthTypePercentage is represented with 100% = 100.0.
198 // Good for accuracy but could eventually be changed. 246 // Good for accuracy but could eventually be changed.
199 return value * 100 / dimensionForLengthMode(mode, viewportSize); 247 return value * 100 / dimensionForLengthMode(mode, viewportSize);
200 } 248 }
201 case LengthTypeEMS: 249 case LengthTypeEMS:
202 return convertValueFromUserUnitsToEMS(value); 250 return convertValueFromUserUnitsToEMS(computedStyleForLengthResolving(m_ context), value);
203 case LengthTypeEXS: 251 case LengthTypeEXS:
204 return convertValueFromUserUnitsToEXS(value); 252 return convertValueFromUserUnitsToEXS(value);
205 case LengthTypeREMS: 253 case LengthTypeREMS:
206 return convertValueFromUserUnitsToREMS(value); 254 return convertValueFromUserUnitsToEMS(rootElementStyle(m_context), value );
207 case LengthTypePX: 255 case LengthTypePX:
208 return value; 256 return value;
209 case LengthTypeCM: 257 case LengthTypeCM:
210 return value / cssPixelsPerCentimeter; 258 return value / cssPixelsPerCentimeter;
211 case LengthTypeMM: 259 case LengthTypeMM:
212 return value / cssPixelsPerMillimeter; 260 return value / cssPixelsPerMillimeter;
213 case LengthTypeIN: 261 case LengthTypeIN:
214 return value / cssPixelsPerInch; 262 return value / cssPixelsPerInch;
215 case LengthTypePT: 263 case LengthTypePT:
216 return value / cssPixelsPerPoint; 264 return value / cssPixelsPerPoint;
217 case LengthTypePC: 265 case LengthTypePC:
218 return value / cssPixelsPerPica; 266 return value / cssPixelsPerPica;
219 } 267 }
220 268
221 ASSERT_NOT_REACHED(); 269 ASSERT_NOT_REACHED();
222 return 0; 270 return 0;
223 } 271 }
224 272
225 static inline const ComputedStyle* computedStyleForLengthResolving(const SVGElem ent* context)
226 {
227 if (!context)
228 return 0;
229
230 const ContainerNode* currentContext = context;
231 do {
232 if (currentContext->layoutObject())
233 return currentContext->layoutObject()->style();
234 currentContext = currentContext->parentNode();
235 } while (currentContext);
236
237 // There must be at least a LayoutSVGRoot renderer, carrying a style.
238 ASSERT_NOT_REACHED();
239 return 0;
240 }
241
242 float SVGLengthContext::convertValueFromUserUnitsToEMS(float value) const
243 {
244 const ComputedStyle* style = computedStyleForLengthResolving(m_context);
245 if (!style)
246 return 0;
247
248 float fontSize = style->specifiedFontSize();
249 if (!fontSize)
250 return 0;
251
252 return value / fontSize;
253 }
254
255 float SVGLengthContext::convertValueFromEMSToUserUnits(float value) const
256 {
257 const ComputedStyle* style = computedStyleForLengthResolving(m_context);
258 if (!style)
259 return 0;
260 return value * style->specifiedFontSize();
261 }
262
263 float SVGLengthContext::convertValueFromUserUnitsToREMS(float value) const
264 {
265 if (!m_context)
266 return 0;
267
268 const ComputedStyle* style = 0;
269 const Document& document = m_context->document();
270 Node* documentElement = document.documentElement();
271 const ComputedStyle* documentStyle = document.computedStyle();
272 style = documentElement && (static_cast<const Node*>(m_context.get()) != doc umentElement) ? documentElement->computedStyle() : documentStyle;
273 if (!style)
274 style = documentStyle;
275
276 if (!style)
277 return 0;
278
279 float fontSize = style->specifiedFontSize();
280 if (!fontSize)
281 return 0;
282
283 return value / fontSize;
284 }
285
286 float SVGLengthContext::convertValueFromREMSToUserUnits(float value) const
287 {
288 if (!m_context)
289 return 0;
290
291 const ComputedStyle* style = 0;
292 const Document& document = m_context->document();
293 Node* documentElement = document.documentElement();
294 const ComputedStyle* documentStyle = document.computedStyle();
295 style = documentElement && (static_cast<const Node*>(m_context.get()) != doc umentElement) ? documentElement->computedStyle() : documentStyle;
296 if (!style)
297 style = documentStyle;
298
299 if (!style)
300 return 0;
301
302 return value * style->specifiedFontSize();
303 }
304
305 float SVGLengthContext::convertValueFromUserUnitsToEXS(float value) const 273 float SVGLengthContext::convertValueFromUserUnitsToEXS(float value) const
306 { 274 {
307 const ComputedStyle* style = computedStyleForLengthResolving(m_context); 275 const ComputedStyle* style = computedStyleForLengthResolving(m_context);
308 if (!style) 276 if (!style)
309 return 0; 277 return 0;
310 278
311 // Use of ceil allows a pixel match to the W3Cs expected output of coords-un its-03-b.svg 279 // Use of ceil allows a pixel match to the W3Cs expected output of coords-un its-03-b.svg
312 // if this causes problems in real world cases maybe it would be best to rem ove this 280 // if this causes problems in real world cases maybe it would be best to rem ove this
313 float xHeight = ceilf(style->fontMetrics().xHeight()); 281 float xHeight = ceilf(style->fontMetrics().xHeight());
314 if (!xHeight) 282 if (!xHeight)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 314
347 const SVGSVGElement& svg = toSVGSVGElement(*viewportElement); 315 const SVGSVGElement& svg = toSVGSVGElement(*viewportElement);
348 viewportSize = svg.currentViewBoxRect().size(); 316 viewportSize = svg.currentViewBoxRect().size();
349 if (viewportSize.isEmpty()) 317 if (viewportSize.isEmpty())
350 viewportSize = svg.currentViewportSize(); 318 viewportSize = svg.currentViewportSize();
351 319
352 return true; 320 return true;
353 } 321 }
354 322
355 } 323 }
OLDNEW
« no previous file with comments | « Source/core/svg/SVGLengthContext.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698