xref: /aosp_15_r20/external/skia/modules/canvaskit/htmlcanvas/pattern.js (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1function CanvasPattern(image, repetition) {
2  this._shader = null;
3  // image should be an Image returned from HTMLCanvas.decodeImage()
4  if (image instanceof HTMLImage) {
5    image = image.getSkImage();
6  }
7  this._image = image;
8  this._transform = CanvasKit.Matrix.identity();
9
10  if (repetition === '') {
11    repetition = 'repeat';
12  }
13  switch(repetition) {
14    case 'repeat-x':
15      this._tileX = CanvasKit.TileMode.Repeat;
16      // Skia's 'clamp' mode repeats the last row/column
17      // which looks very very strange.
18      // Decal mode does just transparent copying, which
19      // is exactly what the spec wants.
20      this._tileY = CanvasKit.TileMode.Decal;
21      break;
22    case 'repeat-y':
23      this._tileX = CanvasKit.TileMode.Decal;
24      this._tileY = CanvasKit.TileMode.Repeat;
25      break;
26    case 'repeat':
27      this._tileX = CanvasKit.TileMode.Repeat;
28      this._tileY = CanvasKit.TileMode.Repeat;
29      break;
30    case 'no-repeat':
31      this._tileX = CanvasKit.TileMode.Decal;
32      this._tileY = CanvasKit.TileMode.Decal;
33      break;
34    default:
35      throw 'invalid repetition mode ' + repetition;
36  }
37
38  // Takes a DOMMatrix like object. e.g. the identity would be:
39  // {a:1, b: 0, c: 0, d: 1, e: 0, f: 0}
40  // @param {DOMMatrix} m
41  this.setTransform = function(m) {
42    var t = [m.a, m.c, m.e,
43             m.b, m.d, m.f,
44               0,   0,   1];
45    if (allAreFinite(t)) {
46      this._transform = t;
47    }
48  };
49
50  this._copy = function() {
51    var cp = new CanvasPattern();
52    cp._tileX = this._tileX;
53    cp._tileY = this._tileY;
54    return cp;
55  };
56
57  this._dispose = function() {
58    if (this._shader) {
59      this._shader.delete();
60      this._shader = null;
61    }
62  };
63
64  this._getShader = function(currentTransform) {
65    // Ignore currentTransform since it will be applied later
66    this._dispose();
67    // A shader with cubic sampling options is high quality.
68    this._shader = this._image.makeShaderCubic(this._tileX, this._tileY, 1/3, 1/3, this._transform);
69    return this._shader;
70  }
71
72}
73