OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. | 2 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above | 8 * 1. Redistributions of source code must retain the above |
9 * copyright notice, this list of conditions and the following | 9 * copyright notice, this list of conditions and the following |
10 * disclaimer. | 10 * disclaimer. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 #include "wtf/OwnPtr.h" | 45 #include "wtf/OwnPtr.h" |
46 | 46 |
47 namespace WebCore { | 47 namespace WebCore { |
48 | 48 |
49 static PassOwnPtr<Shape> createInsetShape(const FloatRoundedRect& bounds) | 49 static PassOwnPtr<Shape> createInsetShape(const FloatRoundedRect& bounds) |
50 { | 50 { |
51 ASSERT(bounds.rect().width() >= 0 && bounds.rect().height() >= 0); | 51 ASSERT(bounds.rect().width() >= 0 && bounds.rect().height() >= 0); |
52 return adoptPtr(new BoxShape(bounds)); | 52 return adoptPtr(new BoxShape(bounds)); |
53 } | 53 } |
54 | 54 |
55 static PassOwnPtr<Shape> createRectangleShape(const FloatRect& bounds, const Flo
atSize& radii) | |
56 { | |
57 ASSERT(bounds.width() >= 0 && bounds.height() >= 0 && radii.width() >= 0 &&
radii.height() >= 0); | |
58 return adoptPtr(new RectangleShape(bounds, radii)); | |
59 } | |
60 | |
61 static PassOwnPtr<Shape> createCircleShape(const FloatPoint& center, float radiu
s) | 55 static PassOwnPtr<Shape> createCircleShape(const FloatPoint& center, float radiu
s) |
62 { | 56 { |
63 ASSERT(radius >= 0); | 57 ASSERT(radius >= 0); |
64 return adoptPtr(new RectangleShape(FloatRect(center.x() - radius, center.y()
- radius, radius*2, radius*2), FloatSize(radius, radius))); | 58 return adoptPtr(new RectangleShape(FloatRect(center.x() - radius, center.y()
- radius, radius*2, radius*2), FloatSize(radius, radius))); |
65 } | 59 } |
66 | 60 |
67 static PassOwnPtr<Shape> createEllipseShape(const FloatPoint& center, const Floa
tSize& radii) | 61 static PassOwnPtr<Shape> createEllipseShape(const FloatPoint& center, const Floa
tSize& radii) |
68 { | 62 { |
69 ASSERT(radii.width() >= 0 && radii.height() >= 0); | 63 ASSERT(radii.width() >= 0 && radii.height() >= 0); |
70 return adoptPtr(new RectangleShape(FloatRect(center.x() - radii.width(), cen
ter.y() - radii.height(), radii.width()*2, radii.height()*2), radii)); | 64 return adoptPtr(new RectangleShape(FloatRect(center.x() - radii.width(), cen
ter.y() - radii.height(), radii.width()*2, radii.height()*2), radii)); |
(...skipping 22 matching lines...) Expand all Loading... |
93 return point.transposedPoint(); | 87 return point.transposedPoint(); |
94 } | 88 } |
95 | 89 |
96 static inline FloatSize physicalSizeToLogical(const FloatSize& size, WritingMode
writingMode) | 90 static inline FloatSize physicalSizeToLogical(const FloatSize& size, WritingMode
writingMode) |
97 { | 91 { |
98 if (isHorizontalWritingMode(writingMode)) | 92 if (isHorizontalWritingMode(writingMode)) |
99 return size; | 93 return size; |
100 return size.transposedSize(); | 94 return size.transposedSize(); |
101 } | 95 } |
102 | 96 |
103 static inline void ensureRadiiDoNotOverlap(FloatRect& bounds, FloatSize& radii) | |
104 { | |
105 float widthRatio = bounds.width() / (2 * radii.width()); | |
106 float heightRatio = bounds.height() / (2 * radii.height()); | |
107 float reductionRatio = std::min<float>(widthRatio, heightRatio); | |
108 if (reductionRatio < 1) { | |
109 radii.setWidth(reductionRatio * radii.width()); | |
110 radii.setHeight(reductionRatio * radii.height()); | |
111 } | |
112 } | |
113 | |
114 PassOwnPtr<Shape> Shape::createShape(const BasicShape* basicShape, const LayoutS
ize& logicalBoxSize, WritingMode writingMode, Length margin, Length padding) | 97 PassOwnPtr<Shape> Shape::createShape(const BasicShape* basicShape, const LayoutS
ize& logicalBoxSize, WritingMode writingMode, Length margin, Length padding) |
115 { | 98 { |
116 ASSERT(basicShape); | 99 ASSERT(basicShape); |
117 | 100 |
118 bool horizontalWritingMode = isHorizontalWritingMode(writingMode); | 101 bool horizontalWritingMode = isHorizontalWritingMode(writingMode); |
119 float boxWidth = horizontalWritingMode ? logicalBoxSize.width().toFloat() :
logicalBoxSize.height().toFloat(); | 102 float boxWidth = horizontalWritingMode ? logicalBoxSize.width().toFloat() :
logicalBoxSize.height().toFloat(); |
120 float boxHeight = horizontalWritingMode ? logicalBoxSize.height().toFloat()
: logicalBoxSize.width().toFloat(); | 103 float boxHeight = horizontalWritingMode ? logicalBoxSize.height().toFloat()
: logicalBoxSize.width().toFloat(); |
121 OwnPtr<Shape> shape; | 104 OwnPtr<Shape> shape; |
122 | 105 |
123 switch (basicShape->type()) { | 106 switch (basicShape->type()) { |
124 | 107 |
125 case BasicShape::BasicShapeRectangleType: { | |
126 const BasicShapeRectangle* rectangle = static_cast<const BasicShapeRecta
ngle*>(basicShape); | |
127 FloatRect bounds( | |
128 floatValueForLength(rectangle->x(), boxWidth), | |
129 floatValueForLength(rectangle->y(), boxHeight), | |
130 floatValueForLength(rectangle->width(), boxWidth), | |
131 floatValueForLength(rectangle->height(), boxHeight)); | |
132 FloatSize cornerRadii( | |
133 floatValueForLength(rectangle->cornerRadiusX(), boxWidth), | |
134 floatValueForLength(rectangle->cornerRadiusY(), boxHeight)); | |
135 ensureRadiiDoNotOverlap(bounds, cornerRadii); | |
136 FloatRect logicalBounds = physicalRectToLogical(bounds, logicalBoxSize.h
eight().toFloat(), writingMode); | |
137 | |
138 shape = createRectangleShape(logicalBounds, physicalSizeToLogical(corner
Radii, writingMode)); | |
139 break; | |
140 } | |
141 | |
142 case BasicShape::DeprecatedBasicShapeCircleType: { | |
143 const DeprecatedBasicShapeCircle* circle = static_cast<const DeprecatedB
asicShapeCircle*>(basicShape); | |
144 float centerX = floatValueForLength(circle->centerX(), boxWidth); | |
145 float centerY = floatValueForLength(circle->centerY(), boxHeight); | |
146 // This method of computing the radius is as defined in SVG | |
147 // (http://www.w3.org/TR/SVG/coords.html#Units). It bases the radius | |
148 // off of the diagonal of the box and ensures that if the box is | |
149 // square, the radius is equal to half the diagonal. | |
150 float radius = floatValueForLength(circle->radius(), sqrtf((boxWidth * b
oxWidth + boxHeight * boxHeight) / 2)); | |
151 FloatPoint logicalCenter = physicalPointToLogical(FloatPoint(centerX, ce
nterY), logicalBoxSize.height().toFloat(), writingMode); | |
152 | |
153 shape = createCircleShape(logicalCenter, radius); | |
154 break; | |
155 } | |
156 | |
157 case BasicShape::BasicShapeCircleType: { | 108 case BasicShape::BasicShapeCircleType: { |
158 const BasicShapeCircle* circle = static_cast<const BasicShapeCircle*>(ba
sicShape); | 109 const BasicShapeCircle* circle = static_cast<const BasicShapeCircle*>(ba
sicShape); |
159 FloatPoint center = floatPointForCenterCoordinate(circle->centerX(), cir
cle->centerY(), FloatSize(boxWidth, boxHeight)); | 110 FloatPoint center = floatPointForCenterCoordinate(circle->centerX(), cir
cle->centerY(), FloatSize(boxWidth, boxHeight)); |
160 float radius = circle->floatValueForRadiusInBox(FloatSize(boxWidth, boxH
eight)); | 111 float radius = circle->floatValueForRadiusInBox(FloatSize(boxWidth, boxH
eight)); |
161 FloatPoint logicalCenter = physicalPointToLogical(center, logicalBoxSize
.height().toFloat(), writingMode); | 112 FloatPoint logicalCenter = physicalPointToLogical(center, logicalBoxSize
.height().toFloat(), writingMode); |
162 | 113 |
163 shape = createCircleShape(logicalCenter, radius); | 114 shape = createCircleShape(logicalCenter, radius); |
164 break; | 115 break; |
165 } | 116 } |
166 | 117 |
167 case BasicShape::DeprecatedBasicShapeEllipseType: { | |
168 const DeprecatedBasicShapeEllipse* ellipse = static_cast<const Deprecate
dBasicShapeEllipse*>(basicShape); | |
169 float centerX = floatValueForLength(ellipse->centerX(), boxWidth); | |
170 float centerY = floatValueForLength(ellipse->centerY(), boxHeight); | |
171 float radiusX = floatValueForLength(ellipse->radiusX(), boxWidth); | |
172 float radiusY = floatValueForLength(ellipse->radiusY(), boxHeight); | |
173 FloatPoint logicalCenter = physicalPointToLogical(FloatPoint(centerX, ce
nterY), logicalBoxSize.height().toFloat(), writingMode); | |
174 FloatSize logicalRadii = physicalSizeToLogical(FloatSize(radiusX, radius
Y), writingMode); | |
175 | |
176 shape = createEllipseShape(logicalCenter, logicalRadii); | |
177 break; | |
178 } | |
179 | |
180 case BasicShape::BasicShapeEllipseType: { | 118 case BasicShape::BasicShapeEllipseType: { |
181 const BasicShapeEllipse* ellipse = static_cast<const BasicShapeEllipse*>
(basicShape); | 119 const BasicShapeEllipse* ellipse = static_cast<const BasicShapeEllipse*>
(basicShape); |
182 FloatPoint center = floatPointForCenterCoordinate(ellipse->centerX(), el
lipse->centerY(), FloatSize(boxWidth, boxHeight)); | 120 FloatPoint center = floatPointForCenterCoordinate(ellipse->centerX(), el
lipse->centerY(), FloatSize(boxWidth, boxHeight)); |
183 float radiusX = ellipse->floatValueForRadiusInBox(ellipse->radiusX(), ce
nter.x(), boxWidth); | 121 float radiusX = ellipse->floatValueForRadiusInBox(ellipse->radiusX(), ce
nter.x(), boxWidth); |
184 float radiusY = ellipse->floatValueForRadiusInBox(ellipse->radiusY(), ce
nter.y(), boxHeight); | 122 float radiusY = ellipse->floatValueForRadiusInBox(ellipse->radiusY(), ce
nter.y(), boxHeight); |
185 FloatPoint logicalCenter = physicalPointToLogical(center, logicalBoxSize
.height().toFloat(), writingMode); | 123 FloatPoint logicalCenter = physicalPointToLogical(center, logicalBoxSize
.height().toFloat(), writingMode); |
186 | 124 |
187 shape = createEllipseShape(logicalCenter, FloatSize(radiusX, radiusY)); | 125 shape = createEllipseShape(logicalCenter, FloatSize(radiusX, radiusY)); |
188 break; | 126 break; |
189 } | 127 } |
190 | 128 |
191 case BasicShape::BasicShapePolygonType: { | 129 case BasicShape::BasicShapePolygonType: { |
192 const BasicShapePolygon* polygon = static_cast<const BasicShapePolygon*>
(basicShape); | 130 const BasicShapePolygon* polygon = static_cast<const BasicShapePolygon*>
(basicShape); |
193 const Vector<Length>& values = polygon->values(); | 131 const Vector<Length>& values = polygon->values(); |
194 size_t valuesSize = values.size(); | 132 size_t valuesSize = values.size(); |
195 ASSERT(!(valuesSize % 2)); | 133 ASSERT(!(valuesSize % 2)); |
196 OwnPtr<Vector<FloatPoint> > vertices = adoptPtr(new Vector<FloatPoint>(v
aluesSize / 2)); | 134 OwnPtr<Vector<FloatPoint> > vertices = adoptPtr(new Vector<FloatPoint>(v
aluesSize / 2)); |
197 for (unsigned i = 0; i < valuesSize; i += 2) { | 135 for (unsigned i = 0; i < valuesSize; i += 2) { |
198 FloatPoint vertex( | 136 FloatPoint vertex( |
199 floatValueForLength(values.at(i), boxWidth), | 137 floatValueForLength(values.at(i), boxWidth), |
200 floatValueForLength(values.at(i + 1), boxHeight)); | 138 floatValueForLength(values.at(i + 1), boxHeight)); |
201 (*vertices)[i / 2] = physicalPointToLogical(vertex, logicalBoxSize.h
eight().toFloat(), writingMode); | 139 (*vertices)[i / 2] = physicalPointToLogical(vertex, logicalBoxSize.h
eight().toFloat(), writingMode); |
202 } | 140 } |
203 shape = createPolygonShape(vertices.release(), polygon->windRule()); | 141 shape = createPolygonShape(vertices.release(), polygon->windRule()); |
204 break; | 142 break; |
205 } | 143 } |
206 | 144 |
207 case BasicShape::BasicShapeInsetRectangleType: { | |
208 const BasicShapeInsetRectangle* rectangle = static_cast<const BasicShape
InsetRectangle*>(basicShape); | |
209 float left = floatValueForLength(rectangle->left(), boxWidth); | |
210 float top = floatValueForLength(rectangle->top(), boxHeight); | |
211 float right = floatValueForLength(rectangle->right(), boxWidth); | |
212 float bottom = floatValueForLength(rectangle->bottom(), boxHeight); | |
213 FloatRect bounds( | |
214 left, | |
215 top, | |
216 std::max<float>(boxWidth - left - right, 0), | |
217 std::max<float>(boxHeight - top - bottom, 0)); | |
218 FloatSize cornerRadii( | |
219 floatValueForLength(rectangle->cornerRadiusX(), boxWidth), | |
220 floatValueForLength(rectangle->cornerRadiusY(), boxHeight)); | |
221 ensureRadiiDoNotOverlap(bounds, cornerRadii); | |
222 FloatRect logicalBounds = physicalRectToLogical(bounds, logicalBoxSize.h
eight().toFloat(), writingMode); | |
223 | |
224 shape = createRectangleShape(logicalBounds, physicalSizeToLogical(corner
Radii, writingMode)); | |
225 break; | |
226 } | |
227 | |
228 case BasicShape::BasicShapeInsetType: { | 145 case BasicShape::BasicShapeInsetType: { |
229 const BasicShapeInset& inset = *static_cast<const BasicShapeInset*>(basi
cShape); | 146 const BasicShapeInset& inset = *static_cast<const BasicShapeInset*>(basi
cShape); |
230 float left = floatValueForLength(inset.left(), boxWidth); | 147 float left = floatValueForLength(inset.left(), boxWidth); |
231 float top = floatValueForLength(inset.top(), boxHeight); | 148 float top = floatValueForLength(inset.top(), boxHeight); |
232 float right = floatValueForLength(inset.right(), boxWidth); | 149 float right = floatValueForLength(inset.right(), boxWidth); |
233 float bottom = floatValueForLength(inset.bottom(), boxHeight); | 150 float bottom = floatValueForLength(inset.bottom(), boxHeight); |
234 FloatRect rect(left, top, std::max<float>(boxWidth - left - right, 0), s
td::max<float>(boxHeight - top - bottom, 0)); | 151 FloatRect rect(left, top, std::max<float>(boxWidth - left - right, 0), s
td::max<float>(boxHeight - top - bottom, 0)); |
235 FloatRect logicalRect = physicalRectToLogical(rect, logicalBoxSize.heigh
t().toFloat(), writingMode); | 152 FloatRect logicalRect = physicalRectToLogical(rect, logicalBoxSize.heigh
t().toFloat(), writingMode); |
236 | 153 |
237 FloatSize boxSize(boxWidth, boxHeight); | 154 FloatSize boxSize(boxWidth, boxHeight); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 FloatRoundedRect bounds(rect, roundedRect.radii()); | 223 FloatRoundedRect bounds(rect, roundedRect.radii()); |
307 OwnPtr<Shape> shape = createInsetShape(bounds); | 224 OwnPtr<Shape> shape = createInsetShape(bounds); |
308 shape->m_writingMode = writingMode; | 225 shape->m_writingMode = writingMode; |
309 shape->m_margin = floatValueForLength(margin, 0); | 226 shape->m_margin = floatValueForLength(margin, 0); |
310 shape->m_padding = floatValueForLength(padding, 0); | 227 shape->m_padding = floatValueForLength(padding, 0); |
311 | 228 |
312 return shape.release(); | 229 return shape.release(); |
313 } | 230 } |
314 | 231 |
315 } // namespace WebCore | 232 } // namespace WebCore |
OLD | NEW |