michael@0: /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: // The possible values of the "align" component of preserveAspectRatio. michael@0: const ALIGN_VALS = ["none", michael@0: "xMinYMin", "xMinYMid", "xMinYMax", michael@0: "xMidYMin", "xMidYMid", "xMidYMax", michael@0: "xMaxYMin", "xMaxYMid", "xMaxYMax"]; michael@0: michael@0: // The possible values of the "meetOrSlice" component of preserveAspectRatio. michael@0: const MEETORSLICE_VALS = [ "meet", "slice" ]; michael@0: michael@0: const SVGNS = "http://www.w3.org/2000/svg"; michael@0: const XLINKNS = "http://www.w3.org/1999/xlink"; michael@0: michael@0: // This is the separation between the x & y values of each in a michael@0: // generated grid. michael@0: const IMAGE_OFFSET = 50; michael@0: michael@0: function generateBorderRect(aX, aY, aWidth, aHeight) { michael@0: var rect = document.createElementNS(SVGNS, "rect"); michael@0: rect.setAttribute("x", aX); michael@0: rect.setAttribute("y", aY); michael@0: rect.setAttribute("width", aWidth); michael@0: rect.setAttribute("height", aHeight); michael@0: rect.setAttribute("fill", "none"); michael@0: rect.setAttribute("stroke", "black"); michael@0: rect.setAttribute("stroke-width", "2"); michael@0: rect.setAttribute("stroke-dasharray", "3 2"); michael@0: return rect; michael@0: } michael@0: michael@0: // Returns an SVG element with the given xlink:href, width, height, michael@0: // and preserveAspectRatio=[aAlign aMeetOrSlice] attributes michael@0: function generateImageElementForParams(aX, aY, aWidth, aHeight, michael@0: aHref, aAlign, aMeetOrSlice) { michael@0: var image = document.createElementNS(SVGNS, "image"); michael@0: image.setAttribute("x", aX); michael@0: image.setAttribute("y", aY); michael@0: image.setAttribute("width", aWidth); michael@0: image.setAttribute("height", aHeight); michael@0: image.setAttributeNS(XLINKNS, "href", aHref); michael@0: image.setAttribute("preserveAspectRatio", aAlign + " " + aMeetOrSlice); michael@0: return image; michael@0: } michael@0: michael@0: // Returns a element filled with a grid of elements which each michael@0: // have the specified aWidth & aHeight and which use all possible values of michael@0: // preserveAspectRatio. michael@0: // michael@0: // The final "aBonusPARVal" argument (if specified) is used as the michael@0: // preserveAspectRatio value on a bonus element, added at the end. michael@0: function generateImageGrid(aHref, aWidth, aHeight, aBonusPARVal) { michael@0: var grid = document.createElementNS(SVGNS, "g"); michael@0: var y = 0; michael@0: var x = 0; michael@0: for (var i = 0; i < ALIGN_VALS.length; i++) { michael@0: // Jump to next line of grid, for every other "i" value. michael@0: // (every fourth entry) michael@0: if (i && i % 2 == 0) { michael@0: y += IMAGE_OFFSET; michael@0: x = 0; michael@0: } michael@0: var alignVal = ALIGN_VALS[i]; michael@0: for (var j = 0; j < MEETORSLICE_VALS.length; j++) { michael@0: var meetorsliceVal = MEETORSLICE_VALS[j]; michael@0: var border = generateBorderRect(x, y, aWidth, aHeight); michael@0: var image = generateImageElementForParams(x, y, aWidth, aHeight, michael@0: aHref, alignVal, michael@0: meetorsliceVal); michael@0: grid.appendChild(border); michael@0: grid.appendChild(image); michael@0: x += IMAGE_OFFSET; michael@0: } michael@0: } michael@0: michael@0: if (aBonusPARVal) { michael@0: // Add one final entry with "bonus" pAR value. michael@0: y += IMAGE_OFFSET; michael@0: x = 0; michael@0: var border = generateBorderRect(x, y, aWidth, aHeight); michael@0: var image = generateImageElementForParams(x, y, aWidth, aHeight, michael@0: aHref, aBonusPARVal, ""); michael@0: grid.appendChild(border); michael@0: grid.appendChild(image); michael@0: } michael@0: michael@0: return grid; michael@0: } michael@0: michael@0: // Returns an SVG element that... michael@0: // (a) has the given ID michael@0: // (b) contains only a element to the given URI michael@0: // (c) has a hardcoded viewBox="0 0 10 10" attribute michael@0: // (d) has the given preserveAspectRatio=[aAlign aMeetOrSlice] attribute michael@0: function generateSymbolElementForParams(aSymbolID, aHref, michael@0: aAlign, aMeetOrSlice) { michael@0: var use = document.createElementNS(SVGNS, "use"); michael@0: use.setAttributeNS(XLINKNS, "href", aHref); michael@0: michael@0: var symbol = document.createElementNS(SVGNS, "symbol"); michael@0: symbol.setAttribute("id", aSymbolID); michael@0: symbol.setAttribute("viewBox", "0 0 10 10"); michael@0: symbol.setAttribute("preserveAspectRatio", aAlign + " " + aMeetOrSlice); michael@0: michael@0: symbol.appendChild(use); michael@0: return symbol; michael@0: } michael@0: michael@0: function generateUseElementForParams(aTargetURI, aX, aY, aWidth, aHeight) { michael@0: var use = document.createElementNS(SVGNS, "use"); michael@0: use.setAttributeNS(XLINKNS, "href", aTargetURI); michael@0: use.setAttribute("x", aX); michael@0: use.setAttribute("y", aY); michael@0: use.setAttribute("width", aWidth); michael@0: use.setAttribute("height", aHeight); michael@0: return use; michael@0: } michael@0: michael@0: // Returns a element filled with a grid of elements which each michael@0: // have the specified aWidth & aHeight and which reference elements michael@0: // with all possible values of preserveAspectRatio. Each contains michael@0: // a that links to the given URI, aHref. michael@0: // michael@0: // The final "aBonusPARVal" argument (if specified) is used as the michael@0: // preserveAspectRatio value on a bonus element, added at the end. michael@0: function generateSymbolGrid(aHref, aWidth, aHeight, aBonusPARVal) { michael@0: var grid = document.createElementNS(SVGNS, "g"); michael@0: var y = 0; michael@0: var x = 0; michael@0: for (var i = 0; i < ALIGN_VALS.length; i++) { michael@0: // Jump to next line of grid, for every other "i" value. michael@0: // (every fourth entry) michael@0: if (i && i % 2 == 0) { michael@0: y += IMAGE_OFFSET; michael@0: x = 0; michael@0: } michael@0: var alignVal = ALIGN_VALS[i]; michael@0: for (var j = 0; j < MEETORSLICE_VALS.length; j++) { michael@0: var meetorsliceVal = MEETORSLICE_VALS[j]; michael@0: var border = generateBorderRect(x, y, aWidth, aHeight); michael@0: michael@0: var symbolID = "symbol_" + alignVal + "_" + meetorsliceVal; michael@0: var symbol = generateSymbolElementForParams(symbolID, aHref, michael@0: alignVal, meetorsliceVal); michael@0: var use = generateUseElementForParams("#" + symbolID, michael@0: x, y, aWidth, aHeight); michael@0: grid.appendChild(symbol); // This isn't painted michael@0: grid.appendChild(border); michael@0: grid.appendChild(use); michael@0: x += IMAGE_OFFSET; michael@0: } michael@0: } michael@0: michael@0: if (aBonusPARVal) { michael@0: // Add one final entry with "bonus" pAR value. michael@0: y += IMAGE_OFFSET; michael@0: x = 0; michael@0: var border = generateBorderRect(x, y, aWidth, aHeight); michael@0: var symbolID = "symbol_Bonus"; michael@0: var symbol = generateSymbolElementForParams(symbolID, aHref, michael@0: aBonusPARVal, ""); michael@0: var use = generateUseElementForParams("#" + symbolID, michael@0: x, y, aWidth, aHeight); michael@0: grid.appendChild(symbol); // This isn't painted michael@0: grid.appendChild(border); michael@0: grid.appendChild(use); michael@0: } michael@0: michael@0: return grid; michael@0: }