util.js (6598B)
1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 // The possible values of the "align" component of preserveAspectRatio. 7 const ALIGN_VALS = ["none", 8 "xMinYMin", "xMinYMid", "xMinYMax", 9 "xMidYMin", "xMidYMid", "xMidYMax", 10 "xMaxYMin", "xMaxYMid", "xMaxYMax"]; 11 12 // The possible values of the "meetOrSlice" component of preserveAspectRatio. 13 const MEETORSLICE_VALS = [ "meet", "slice" ]; 14 15 const SVGNS = "http://www.w3.org/2000/svg"; 16 const XLINKNS = "http://www.w3.org/1999/xlink"; 17 18 // This is the separation between the x & y values of each <image> in a 19 // generated grid. 20 const IMAGE_OFFSET = 50; 21 22 function generateBorderRect(aX, aY, aWidth, aHeight) { 23 var rect = document.createElementNS(SVGNS, "rect"); 24 rect.setAttribute("x", aX); 25 rect.setAttribute("y", aY); 26 rect.setAttribute("width", aWidth); 27 rect.setAttribute("height", aHeight); 28 rect.setAttribute("fill", "none"); 29 rect.setAttribute("stroke", "black"); 30 rect.setAttribute("stroke-width", "2"); 31 rect.setAttribute("stroke-dasharray", "3 2"); 32 return rect; 33 } 34 35 // Returns an SVG <image> element with the given xlink:href, width, height, 36 // and preserveAspectRatio=[aAlign aMeetOrSlice] attributes 37 function generateImageElementForParams(aX, aY, aWidth, aHeight, 38 aHref, aAlign, aMeetOrSlice) { 39 var image = document.createElementNS(SVGNS, "image"); 40 image.setAttribute("x", aX); 41 image.setAttribute("y", aY); 42 image.setAttribute("width", aWidth); 43 image.setAttribute("height", aHeight); 44 image.setAttributeNS(XLINKNS, "href", aHref); 45 image.setAttribute("preserveAspectRatio", aAlign + " " + aMeetOrSlice); 46 return image; 47 } 48 49 // Returns a <g> element filled with a grid of <image> elements which each 50 // have the specified aWidth & aHeight and which use all possible values of 51 // preserveAspectRatio. 52 // 53 // The final "aBonusPARVal" argument (if specified) is used as the 54 // preserveAspectRatio value on a bonus <image> element, added at the end. 55 function generateImageGrid(aHref, aWidth, aHeight, aBonusPARVal) { 56 var grid = document.createElementNS(SVGNS, "g"); 57 var y = 0; 58 var x = 0; 59 for (var i = 0; i < ALIGN_VALS.length; i++) { 60 // Jump to next line of grid, for every other "i" value. 61 // (every fourth entry) 62 if (i && i % 2 == 0) { 63 y += IMAGE_OFFSET; 64 x = 0; 65 } 66 var alignVal = ALIGN_VALS[i]; 67 for (var j = 0; j < MEETORSLICE_VALS.length; j++) { 68 var meetorsliceVal = MEETORSLICE_VALS[j]; 69 var border = generateBorderRect(x, y, aWidth, aHeight); 70 var image = generateImageElementForParams(x, y, aWidth, aHeight, 71 aHref, alignVal, 72 meetorsliceVal); 73 grid.appendChild(border); 74 grid.appendChild(image); 75 x += IMAGE_OFFSET; 76 } 77 } 78 79 if (aBonusPARVal) { 80 // Add one final entry with "bonus" pAR value. 81 y += IMAGE_OFFSET; 82 x = 0; 83 var border = generateBorderRect(x, y, aWidth, aHeight); 84 var image = generateImageElementForParams(x, y, aWidth, aHeight, 85 aHref, aBonusPARVal, ""); 86 grid.appendChild(border); 87 grid.appendChild(image); 88 } 89 90 return grid; 91 } 92 93 // Returns an SVG <symbol> element that... 94 // (a) has the given ID 95 // (b) contains only a <use> element to the given URI 96 // (c) has a hardcoded viewBox="0 0 10 10" attribute 97 // (d) has the given preserveAspectRatio=[aAlign aMeetOrSlice] attribute 98 function generateSymbolElementForParams(aSymbolID, aHref, 99 aAlign, aMeetOrSlice) { 100 var use = document.createElementNS(SVGNS, "use"); 101 use.setAttributeNS(XLINKNS, "href", aHref); 102 103 var symbol = document.createElementNS(SVGNS, "symbol"); 104 symbol.setAttribute("id", aSymbolID); 105 symbol.setAttribute("viewBox", "0 0 10 10"); 106 symbol.setAttribute("preserveAspectRatio", aAlign + " " + aMeetOrSlice); 107 108 symbol.appendChild(use); 109 return symbol; 110 } 111 112 function generateUseElementForParams(aTargetURI, aX, aY, aWidth, aHeight) { 113 var use = document.createElementNS(SVGNS, "use"); 114 use.setAttributeNS(XLINKNS, "href", aTargetURI); 115 use.setAttribute("x", aX); 116 use.setAttribute("y", aY); 117 use.setAttribute("width", aWidth); 118 use.setAttribute("height", aHeight); 119 return use; 120 } 121 122 // Returns a <g> element filled with a grid of <use> elements which each 123 // have the specified aWidth & aHeight and which reference <symbol> elements 124 // with all possible values of preserveAspectRatio. Each <symbol> contains 125 // a <use> that links to the given URI, aHref. 126 // 127 // The final "aBonusPARVal" argument (if specified) is used as the 128 // preserveAspectRatio value on a bonus <symbol> element, added at the end. 129 function generateSymbolGrid(aHref, aWidth, aHeight, aBonusPARVal) { 130 var grid = document.createElementNS(SVGNS, "g"); 131 var y = 0; 132 var x = 0; 133 for (var i = 0; i < ALIGN_VALS.length; i++) { 134 // Jump to next line of grid, for every other "i" value. 135 // (every fourth entry) 136 if (i && i % 2 == 0) { 137 y += IMAGE_OFFSET; 138 x = 0; 139 } 140 var alignVal = ALIGN_VALS[i]; 141 for (var j = 0; j < MEETORSLICE_VALS.length; j++) { 142 var meetorsliceVal = MEETORSLICE_VALS[j]; 143 var border = generateBorderRect(x, y, aWidth, aHeight); 144 145 var symbolID = "symbol_" + alignVal + "_" + meetorsliceVal; 146 var symbol = generateSymbolElementForParams(symbolID, aHref, 147 alignVal, meetorsliceVal); 148 var use = generateUseElementForParams("#" + symbolID, 149 x, y, aWidth, aHeight); 150 grid.appendChild(symbol); // This isn't painted 151 grid.appendChild(border); 152 grid.appendChild(use); 153 x += IMAGE_OFFSET; 154 } 155 } 156 157 if (aBonusPARVal) { 158 // Add one final entry with "bonus" pAR value. 159 y += IMAGE_OFFSET; 160 x = 0; 161 var border = generateBorderRect(x, y, aWidth, aHeight); 162 var symbolID = "symbol_Bonus"; 163 var symbol = generateSymbolElementForParams(symbolID, aHref, 164 aBonusPARVal, ""); 165 var use = generateUseElementForParams("#" + symbolID, 166 x, y, aWidth, aHeight); 167 grid.appendChild(symbol); // This isn't painted 168 grid.appendChild(border); 169 grid.appendChild(use); 170 } 171 172 return grid; 173 }