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