summaryrefslogtreecommitdiffstats
path: root/layout/reftests/svg/image/util.js
blob: 144edd356ae18a41356bd6fcb82c79a2578cdf59 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// The possible values of the "align" component of preserveAspectRatio.
const ALIGN_VALS = ["none",
                    "xMinYMin", "xMinYMid", "xMinYMax",
                    "xMidYMin", "xMidYMid", "xMidYMax",
                    "xMaxYMin", "xMaxYMid", "xMaxYMax"];

// The possible values of the "meetOrSlice" component of preserveAspectRatio.
const MEETORSLICE_VALS = [ "meet", "slice" ];

const SVGNS   = "http://www.w3.org/2000/svg";
const XLINKNS = "http://www.w3.org/1999/xlink";

// This is the separation between the x & y values of each <image> in a
// generated grid.
const IMAGE_OFFSET = 50;

function generateBorderRect(aX, aY, aWidth, aHeight) {
  var rect = document.createElementNS(SVGNS, "rect");
  rect.setAttribute("x", aX);
  rect.setAttribute("y", aY);
  rect.setAttribute("width", aWidth);
  rect.setAttribute("height", aHeight);
  rect.setAttribute("fill", "none");
  rect.setAttribute("stroke", "black");
  rect.setAttribute("stroke-width", "2");
  rect.setAttribute("stroke-dasharray", "3 2");
  return rect;
}

// Returns an SVG <image> element with the given xlink:href, width, height,
// and preserveAspectRatio=[aAlign aMeetOrSlice] attributes
function generateImageElementForParams(aX, aY, aWidth, aHeight,
                                       aHref, aAlign, aMeetOrSlice) {
  var image = document.createElementNS(SVGNS, "image");
  image.setAttribute("x", aX);
  image.setAttribute("y", aY);
  image.setAttribute("width", aWidth);
  image.setAttribute("height", aHeight);
  image.setAttributeNS(XLINKNS, "href", aHref);
  image.setAttribute("preserveAspectRatio", aAlign + " " + aMeetOrSlice);
  return image;
}

// Returns a <g> element filled with a grid of <image> elements which each
// have the specified aWidth & aHeight and which use all possible values of
// preserveAspectRatio.
//
// The final "aBonusPARVal" argument (if specified) is used as the
// preserveAspectRatio value on a bonus <image> element, added at the end.
function generateImageGrid(aHref, aWidth, aHeight, aBonusPARVal) {
  var grid = document.createElementNS(SVGNS, "g");
  var y = 0;
  var x = 0;
  for (var i = 0; i < ALIGN_VALS.length; i++) {
    // Jump to next line of grid, for every other "i" value.
    // (every fourth entry)
    if (i && i % 2 == 0) {
      y += IMAGE_OFFSET;
      x = 0;
    }
    var alignVal = ALIGN_VALS[i];
    for (var j = 0; j < MEETORSLICE_VALS.length; j++) {
      var meetorsliceVal = MEETORSLICE_VALS[j];
      var border = generateBorderRect(x, y, aWidth, aHeight);
      var image  = generateImageElementForParams(x, y, aWidth, aHeight,
                                                 aHref, alignVal,
                                                 meetorsliceVal);
      grid.appendChild(border);
      grid.appendChild(image);
      x += IMAGE_OFFSET;
    }
  }

  if (aBonusPARVal) {
    // Add one final entry with "bonus" pAR value.
    y += IMAGE_OFFSET;
    x = 0;
    var border = generateBorderRect(x, y, aWidth, aHeight);
    var image  = generateImageElementForParams(x, y, aWidth, aHeight,
                                               aHref, aBonusPARVal, "");
    grid.appendChild(border);
    grid.appendChild(image);
  }

  return grid;
}

// Returns an SVG <symbol> element that...
//  (a) has the given ID
//  (b) contains only a <use> element to the given URI
//  (c) has a hardcoded viewBox="0 0 10 10" attribute
//  (d) has the given preserveAspectRatio=[aAlign aMeetOrSlice] attribute
function generateSymbolElementForParams(aSymbolID, aHref,
                                        aAlign, aMeetOrSlice) {
  var use = document.createElementNS(SVGNS, "use");
  use.setAttributeNS(XLINKNS, "href", aHref);

  var symbol = document.createElementNS(SVGNS, "symbol");
  symbol.setAttribute("id", aSymbolID);
  symbol.setAttribute("viewBox", "0 0 10 10");
  symbol.setAttribute("preserveAspectRatio", aAlign + " " + aMeetOrSlice);

  symbol.appendChild(use);
  return symbol;
}

function generateUseElementForParams(aTargetURI, aX, aY, aWidth, aHeight) {
  var use = document.createElementNS(SVGNS, "use");
  use.setAttributeNS(XLINKNS, "href", aTargetURI);
  use.setAttribute("x", aX);
  use.setAttribute("y", aY);
  use.setAttribute("width", aWidth);
  use.setAttribute("height", aHeight);
  return use;
}

// Returns a <g> element filled with a grid of <use> elements which each
// have the specified aWidth & aHeight and which reference <symbol> elements
// with all possible values of preserveAspectRatio.  Each <symbol> contains
// a <use> that links to the given URI, aHref.
//
// The final "aBonusPARVal" argument (if specified) is used as the
// preserveAspectRatio value on a bonus <symbol> element, added at the end.
function generateSymbolGrid(aHref, aWidth, aHeight, aBonusPARVal) {
  var grid = document.createElementNS(SVGNS, "g");
  var y = 0;
  var x = 0;
  for (var i = 0; i < ALIGN_VALS.length; i++) {
    // Jump to next line of grid, for every other "i" value.
    // (every fourth entry)
    if (i && i % 2 == 0) {
      y += IMAGE_OFFSET;
      x = 0;
    }
    var alignVal = ALIGN_VALS[i];
    for (var j = 0; j < MEETORSLICE_VALS.length; j++) {
      var meetorsliceVal = MEETORSLICE_VALS[j];
      var border = generateBorderRect(x, y, aWidth, aHeight);

      var symbolID = "symbol_" + alignVal + "_" + meetorsliceVal;
      var symbol = generateSymbolElementForParams(symbolID, aHref,
                                                  alignVal, meetorsliceVal);
      var use = generateUseElementForParams("#" + symbolID,
                                            x, y, aWidth, aHeight);
      grid.appendChild(symbol); // This isn't painted
      grid.appendChild(border);
      grid.appendChild(use);
      x += IMAGE_OFFSET;
    }
  }

  if (aBonusPARVal) {
    // Add one final entry with "bonus" pAR value.
    y += IMAGE_OFFSET;
    x = 0;
    var border = generateBorderRect(x, y, aWidth, aHeight);
    var symbolID = "symbol_Bonus";
    var symbol = generateSymbolElementForParams(symbolID, aHref,
                                                aBonusPARVal, "");
    var use = generateUseElementForParams("#" + symbolID,
                                          x, y, aWidth, aHeight);
    grid.appendChild(symbol); // This isn't painted
    grid.appendChild(border);
    grid.appendChild(use);
  }

  return grid;
}