OLD | NEW |
| (Empty) |
1 // The functions in this file are intended to be used to test non-complex polygo
ns | |
2 // where horizontal lines that overlap the polygon only cross the polygon twice. | |
3 function createPolygon(vertices) { | |
4 var xCoordinates = vertices.map( function(p) { return p.x; } ); | |
5 var yCoordinates = vertices.map( function(p) { return p.y; } ); | |
6 return { | |
7 vertices: vertices, | |
8 minX: Math.min.apply(null, xCoordinates), | |
9 maxX: Math.max.apply(null, xCoordinates), | |
10 minY: Math.min.apply(null, yCoordinates), | |
11 maxY: Math.max.apply(null, yCoordinates) | |
12 }; | |
13 } | |
14 | |
15 function createRegularPolygonVertices(size, nSides) | |
16 { | |
17 var radius = size / (2 * Math.cos(Math.PI / nSides)); | |
18 var inset = size / 2 + 20; | |
19 var vertices = []; | |
20 | |
21 for (var i = 0; i < nSides/2; i++) { | |
22 var a = (1 + 2*i) * (Math.PI / nSides); | |
23 vertices[i] = {x: Math.floor(radius * Math.cos(a)), y: Math.floor(radius
* Math.sin(a))}; | |
24 vertices[nSides - i - 1] = {x: vertices[i].x, y: -vertices[i].y} // Y a
xis symmetry | |
25 } | |
26 | |
27 for (var i = 0; i < nSides; i++) { | |
28 vertices[i].x += inset; | |
29 vertices[i].y += inset; | |
30 } | |
31 | |
32 return vertices; | |
33 } | |
34 | |
35 // Return two X intercepts of the horizontal line at y. We're assuming that the
polygon | |
36 // has 0 or 2 intercepts for all y. Of course this isn't true for polygons in ge
neral, | |
37 // just the ones used by the test cases supported by this file. | |
38 | |
39 function polygonXIntercepts(polygon, y) { | |
40 var vertices = polygon.vertices; | |
41 var foundXIntercept = false; | |
42 var interceptsMinX, interceptsMaxX; | |
43 | |
44 for(var i = 0; i < vertices.length; i++) { | |
45 var v1 = vertices[i]; | |
46 var v2 = vertices[(i + 1) % vertices.length]; | |
47 | |
48 if (Math.max(v1.y, v2.y) < y || Math.min(v1.y, v2.y) > y) | |
49 continue; | |
50 | |
51 if (v1.y == y && v2.y == y) { // horizontal edge | |
52 if (y != polygon.maxY) | |
53 continue; | |
54 | |
55 if (!foundXIntercept) { | |
56 interceptsMinX = Math.min(v1.x, v2.x); | |
57 interceptsMaxX = Math.max(v1.x, v2.x); | |
58 foundXIntercept = true; | |
59 } | |
60 else { | |
61 interceptsMinX = Math.min(v1.x, v2.x, interceptsMinX); | |
62 interceptsMaxX = Math.max(v1.x, v2.x, interceptsMaxX); | |
63 } | |
64 } | |
65 else { | |
66 var interceptX; | |
67 | |
68 if (v1.y == y) | |
69 interceptX = v1.x; | |
70 else if (v2.y == y) | |
71 interceptX = v2.x; | |
72 else | |
73 interceptX = ((y - v1.y) * (v2.x - v1.x) / (v2.y - v1.y)) + v1.x
; | |
74 | |
75 if (!foundXIntercept) { | |
76 interceptsMinX = interceptsMaxX = interceptX; | |
77 foundXIntercept = true; | |
78 } | |
79 else { | |
80 interceptsMinX = Math.min(interceptX, interceptsMinX); | |
81 interceptsMaxX = Math.max(interceptX, interceptsMaxX); | |
82 } | |
83 } | |
84 } | |
85 | |
86 if (!foundXIntercept) | |
87 return []; | |
88 | |
89 return [SubPixelLayout.snapToLayoutUnit(interceptsMinX), SubPixelLayout.snap
ToLayoutUnit(interceptsMaxX)]; | |
90 } | |
91 | |
92 function polygonLineIntercepts(polygon, y, lineHeight) { | |
93 var i1 = polygonXIntercepts(polygon, y); | |
94 var i2 = polygonXIntercepts(polygon, y + lineHeight); | |
95 | |
96 if (i1.length < 2) | |
97 return i2; | |
98 if (i2.length < 2) | |
99 return i1; | |
100 | |
101 return [Math.max(i1[0], i2[0]), Math.min(i1[1], i2[1])]; | |
102 } | |
103 | |
104 // Generate an "X X ..." string that contains enough characters to fill the poly
gon. Each | |
105 // character occupies a lineHeight size square cell, the top of first line of ch
aracters is aligned | |
106 // with the the polygon's bounds minimum Y value, and each line of characters fi
lls the interior | |
107 // of the polygon. | |
108 | |
109 function generatePolygonContentString(polygon, lineHeight) { | |
110 var result = ""; | |
111 | |
112 for (var y = polygon.minY; y < polygon.maxY; y += lineHeight) { | |
113 var xIntercepts = polygonLineIntercepts(polygon, y, lineHeight); | |
114 var lengthInCells = Math.floor(xIntercepts[1] / lineHeight) - Math.ceil(
xIntercepts[0] / lineHeight); | |
115 for (var i = 0; i < lengthInCells / 2; i++) | |
116 result += "X "; // all lines end in a space, to enable line breakin
g | |
117 } | |
118 | |
119 return result; | |
120 } | |
121 | |
122 function generatePolygonShapeInsideElement(elementId, stylesheet, polygon, lineH
eight) { | |
123 var verticesString = polygon.vertices.map( function(p) { return p.x + "px "
+ p.y + "px"; } ).join(", "); | |
124 stylesheet.insertRule("#" + elementId + " { " | |
125 + "shape-inside: polygon(" + verticesString + "); " | |
126 + "width: " + polygon.maxX + "px; " | |
127 + "height: " + polygon.maxY + "px; " | |
128 + "font: " + lineHeight + "px/1 Ahem, sans-serif; }"); | |
129 stylesheet.insertRule("#" + elementId + " p { -webkit-margin-before: 0; word
-wrap: break-word; letter-spacing: 0;}"); | |
130 | |
131 var text = document.createTextNode(generatePolygonContentString(polygon, lin
eHeight)); | |
132 var p = document.createElement("p"); | |
133 p.appendChild(text); | |
134 | |
135 var element = document.getElementById(elementId); | |
136 element.appendChild(p); | |
137 } | |
138 | |
139 function generatePolygonSVGElements(elementId, stylesheet, polygon, lineHeight)
{ | |
140 var svgNS = "http://www.w3.org/2000/svg"; | |
141 | |
142 var svgPolygon = document.createElementNS(svgNS, "polygon"); | |
143 svgPolygon.setAttribute("points", polygon.vertices.map( function(p) { return
p.x + "," + p.y; } ).join(" ")); | |
144 svgPolygon.setAttribute("fill", "#636363"); | |
145 | |
146 var svgElement = document.getElementById(elementId); | |
147 svgElement.style.width = polygon.maxX + "px"; | |
148 svgElement.style.height = polygon.maxY + "px"; | |
149 svgElement.appendChild(svgPolygon); | |
150 } | |
151 | |
152 function simulatePolygonShape(elementId, stylesheet, polygon, lineHeight) { | |
153 var width = Math.ceil(polygon.maxX); | |
154 var height = Math.ceil(polygon.maxY); | |
155 stylesheet.insertRule("#" + elementId + " { width: " + width + "px; height:
" + height + "px; font: " + lineHeight + "px/1 Ahem, sans-serif;}"); | |
156 stylesheet.insertRule("#" + elementId + " .float { height: " + lineHeight +
"px; }"); | |
157 stylesheet.insertRule("#" + elementId + " .left { float: left; clear: left;
}"); | |
158 stylesheet.insertRule("#" + elementId + " .right { float: right; clear: righ
t; }"); | |
159 stylesheet.insertRule("#" + elementId + " p { -webkit-margin-before: 0; word
-wrap: break-word; letter-spacing: 0; }"); | |
160 | |
161 var element = document.getElementById(elementId); | |
162 | |
163 var paddingTop = document.createElement("div"); | |
164 paddingTop.setAttribute("class", "float left"); | |
165 paddingTop.style.width = width + "px"; | |
166 paddingTop.style.height = polygon.minY + "px"; | |
167 element.appendChild(paddingTop); | |
168 | |
169 for (var y = polygon.minY; y < polygon.maxY; y += lineHeight) { | |
170 var xIntercepts = polygonLineIntercepts(polygon, y, lineHeight); | |
171 var left = xIntercepts[0]; | |
172 var right = xIntercepts[1]; | |
173 | |
174 var paddingLeft = document.createElement("div"); | |
175 paddingLeft.setAttribute("class", "float left"); | |
176 paddingLeft.style.width = left + "px"; | |
177 element.appendChild(paddingLeft); | |
178 | |
179 var paddingRight = document.createElement("div"); | |
180 paddingRight.setAttribute("class", "float right"); | |
181 paddingRight.style.width = width - right + "px"; | |
182 element.appendChild(paddingRight); | |
183 } | |
184 } | |
185 | |
186 function generateSimulatedPolygonShapeInsideElement(elementId, stylesheet, polyg
on, lineHeight) { | |
187 var width = Math.ceil(polygon.maxX); | |
188 var height = Math.ceil(polygon.maxY); | |
189 | |
190 stylesheet.insertRule("#" + elementId + " { width: " + width + "px; height:
" + height + "px; font: " + lineHeight + "px/1 Ahem, sans-serif;}"); | |
191 stylesheet.insertRule("#" + elementId + " .float { height: " + lineHeight +
"px; }"); | |
192 stylesheet.insertRule("#" + elementId + " .left { float: left; clear: left;
}"); | |
193 stylesheet.insertRule("#" + elementId + " .right { float: right; clear: righ
t; }"); | |
194 stylesheet.insertRule("#" + elementId + " p { -webkit-margin-before: 0; word
-wrap: break-word; letter-spacing: 0; }"); | |
195 | |
196 var element = document.getElementById(elementId); | |
197 | |
198 var paddingTop = document.createElement("div"); | |
199 paddingTop.setAttribute("class", "float left"); | |
200 paddingTop.style.width = width + "px"; | |
201 paddingTop.style.height = polygon.minY + "px"; | |
202 element.appendChild(paddingTop); | |
203 | |
204 for (var y = polygon.minY; y < polygon.maxY; y += lineHeight) { | |
205 var xIntercepts = polygonLineIntercepts(polygon, y, lineHeight); | |
206 var left = xIntercepts[0]; | |
207 var right = xIntercepts[1]; | |
208 | |
209 var paddingLeft = document.createElement("div"); | |
210 paddingLeft.setAttribute("class", "float left"); | |
211 paddingLeft.style.width = left + "px"; | |
212 element.appendChild(paddingLeft); | |
213 | |
214 var paddingRight = document.createElement("div"); | |
215 paddingRight.setAttribute("class", "float right"); | |
216 paddingRight.style.width = width - right + "px"; | |
217 element.appendChild(paddingRight); | |
218 } | |
219 | |
220 var text = document.createTextNode(generatePolygonContentString(polygon, lin
eHeight)); | |
221 var p = document.createElement("p"); | |
222 p.appendChild(text); | |
223 | |
224 var element = document.getElementById(elementId); | |
225 element.appendChild(p); | |
226 } | |
227 | |
228 function positionInformativeText(elementId, stylesheet, polygon, lineHeight) | |
229 { | |
230 stylesheet.insertRule("#" + elementId + " { position: absolute; top: " + (po
lygon.maxY + lineHeight) + "px;}"); | |
231 } | |
232 | |
233 function createPolygonShapeInsideTestCase() { | |
234 var stylesheet = document.getElementById("stylesheet").sheet; | |
235 var polygon = createPolygon(vertices); | |
236 generatePolygonShapeInsideElement("polygon-shape-inside", stylesheet, polygo
n, lineHeight); | |
237 generatePolygonSVGElements("polygon-svg-shape", stylesheet, polygon, lineHei
ght); | |
238 positionInformativeText("informative-text", stylesheet, polygon, lineHeight) | |
239 } | |
240 | |
241 function createPolygonShapeInsideTestCaseExpected() { | |
242 var stylesheet = document.getElementById("stylesheet").sheet; | |
243 var polygon = createPolygon(vertices); | |
244 generateSimulatedPolygonShapeInsideElement("polygon-shape-inside", styleshee
t, polygon, lineHeight); | |
245 generatePolygonSVGElements("polygon-svg-shape", stylesheet, polygon, lineHei
ght); | |
246 positionInformativeText("informative-text", stylesheet, polygon, lineHeight) | |
247 } | |
OLD | NEW |