| 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 |