25 #include "wtf/Platform.h"
30 #include "css/csshelper.h"
40 #include <wtf/Assertions.h>
45 static inline unsigned int storeUnit(SVGLengthMode mode, SVGLengthType type)
47 return (mode << 4) | type;
50 static inline SVGLengthMode extractMode(
unsigned int unit)
52 unsigned int mode = unit >> 4;
53 return static_cast<SVGLengthMode
>(mode);
56 static inline SVGLengthType extractType(
unsigned int unit)
58 unsigned int mode = unit >> 4;
59 unsigned int type = unit ^ (mode << 4);
60 return static_cast<SVGLengthType
>(type);
63 static inline String lengthTypeToString(SVGLengthType type)
66 case LengthTypeUnknown:
67 case LengthTypeNumber:
69 case LengthTypePercentage:
92 inline SVGLengthType stringToLengthType(
const String&
string)
94 if (
string.endsWith(
"%"))
95 return LengthTypePercentage;
96 else if (
string.endsWith(
"em"))
98 else if (
string.endsWith(
"ex"))
100 else if (
string.endsWith(
"px"))
102 else if (
string.endsWith(
"cm"))
104 else if (
string.endsWith(
"mm"))
106 else if (
string.endsWith(
"in"))
108 else if (
string.endsWith(
"pt"))
110 else if (
string.endsWith(
"pc"))
112 else if (!
string.isEmpty())
113 return LengthTypeNumber;
115 return LengthTypeUnknown;
118 SVGLength::SVGLength(
const SVGStyledElement* context, SVGLengthMode mode,
const String& valueAsString)
119 : m_valueInSpecifiedUnits(0.0f)
120 , m_unit(storeUnit(mode, LengthTypeNumber))
123 setValueAsString(valueAsString);
126 SVGLengthType SVGLength::unitType()
const
128 return extractType(m_unit);
131 float SVGLength::value()
const
133 SVGLengthType type = extractType(m_unit);
134 if (type == LengthTypeUnknown)
138 case LengthTypeNumber:
139 return m_valueInSpecifiedUnits;
140 case LengthTypePercentage:
141 return SVGLength::PercentageOfViewport(m_valueInSpecifiedUnits / 100.0f, m_context, extractMode(m_unit));
163 return m_valueInSpecifiedUnits;
165 return m_valueInSpecifiedUnits / 2.54f * cssPixelsPerInch;
167 return m_valueInSpecifiedUnits / 25.4f * cssPixelsPerInch;
169 return m_valueInSpecifiedUnits * cssPixelsPerInch;
171 return m_valueInSpecifiedUnits / 72.0f * cssPixelsPerInch;
173 return m_valueInSpecifiedUnits / 6.0f * cssPixelsPerInch;
178 ASSERT_NOT_REACHED();
182 void SVGLength::setValue(
float value)
184 SVGLengthType type = extractType(m_unit);
185 ASSERT(type != LengthTypeUnknown);
188 case LengthTypeNumber:
189 m_valueInSpecifiedUnits = value;
191 case LengthTypePercentage:
194 ASSERT_NOT_REACHED();
197 m_valueInSpecifiedUnits = value;
200 m_valueInSpecifiedUnits = value * 2.54f / cssPixelsPerInch;
203 m_valueInSpecifiedUnits = value * 25.4f / cssPixelsPerInch;
206 m_valueInSpecifiedUnits = value / cssPixelsPerInch;
209 m_valueInSpecifiedUnits = value * 72.0f / cssPixelsPerInch;
212 m_valueInSpecifiedUnits = value / 6.0f * cssPixelsPerInch;
219 void SVGLength::setValueInSpecifiedUnits(
float value)
221 m_valueInSpecifiedUnits = value;
224 float SVGLength::valueInSpecifiedUnits()
const
226 return m_valueInSpecifiedUnits;
229 float SVGLength::valueAsPercentage()
const
232 if (extractType(m_unit) == LengthTypePercentage)
233 return valueInSpecifiedUnits() / 100.0f;
235 return valueInSpecifiedUnits();
238 bool SVGLength::setValueAsString(
const String& s)
243 float convertedNumber = 0.0f;
244 const UChar* ptr = s.characters();
245 const UChar*
end = ptr + s.length();
247 if (!parseNumber(ptr, end, convertedNumber,
false))
250 SVGLengthType type = stringToLengthType(s);
251 if (ptr != end && type == LengthTypeNumber)
254 kDebug() << convertedNumber << type;
256 m_unit = storeUnit(extractMode(m_unit), type);
257 m_valueInSpecifiedUnits = convertedNumber;
261 String SVGLength::valueAsString()
const
268 void SVGLength::newValueSpecifiedUnits(
unsigned short type,
float value)
270 ASSERT(type <= LengthTypePC);
272 m_unit = storeUnit(extractMode(m_unit), (SVGLengthType) type);
273 m_valueInSpecifiedUnits = value;
276 void SVGLength::convertToSpecifiedUnits(
unsigned short type)
278 ASSERT(type <= LengthTypePC);
280 float valueInUserUnits = value();
281 m_unit = storeUnit(extractMode(m_unit), (SVGLengthType) type);
282 setValue(valueInUserUnits);
285 float SVGLength::PercentageOfViewport(
float value,
const SVGStyledElement* context, SVGLengthMode mode)
289 float width = 0.0f, height = 0.0f;
290 SVGElement* viewportElement = context->viewportElement();
292 Document* doc = context->document();
293 if (doc->documentElement() == context) {
296 if (view && view->view()) {
297 width = view->view()->visibleWidth();
298 height = view->view()->visibleHeight();
300 }
else if (viewportElement && viewportElement->isSVG()) {
301 const SVGSVGElement* svg =
static_cast<const SVGSVGElement*
>(viewportElement);
303 width = svg->viewBox().width();
304 height = svg->viewBox().height();
306 width = svg->width().value();
307 height = svg->height().value();
309 }
else if (context->parent() && !context->parent()->isSVGElement()) {
310 if (RenderObject* renderer = context->renderer()) {
311 width = renderer->width();
312 height = renderer->height();
316 if (mode == LengthModeWidth)
317 return value * width;
318 else if (mode == LengthModeHeight)
319 return value * height;
320 else if (mode == LengthModeOther)
321 return value * sqrtf(powf(width, 2) + powf(height, 2)) / sqrtf(2.0f);
328 #endif // ENABLE(SVG)
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
DOM::QualifiedName viewBoxAttr