<!DOCTYPE html>
<title>CanvasKit Extra features (Skia via Web Assembly)</title>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>
  canvas {
    border: 1px dashed #AAA;
  }
  #sk_legos,#sk_drinks,#sk_party,#sk_onboarding, #sk_animated_gif {
      width: 300px;
      height: 300px;
  }

</style>

<h2> Skottie </h2>
<canvas id=sk_legos width=300 height=300></canvas>
<canvas id=sk_drinks width=500 height=500></canvas>
<canvas id=sk_party width=500 height=500></canvas>
<canvas id=sk_onboarding width=500 height=500></canvas>
<canvas id=sk_animated_gif width=500 height=500
        title='This is an animated gif being animated in Skottie'></canvas>

<h2> RT Shader </h2>
<canvas id=rtshader width=300 height=300></canvas>
<canvas id=rtshader2 width=300 height=300></canvas>

<h2> Particles </h2>
<canvas id=particles width=500 height=500></canvas>

<h2> Paragraph </h2>
<canvas id=para1 width=600 height=600></canvas>
<canvas id=para2 width=600 height=600 tabindex='-1'></canvas>

<h2> CanvasKit can serialize/deserialize .skp files</h2>
<canvas id=skp width=500 height=500></canvas>

<h2> 3D perspective transformations </h2>
<canvas id=glyphgame width=500 height=500></canvas>

<h2> Support for extended color spaces </h2>
<a href="chrome://flags/#force-color-profile">Force P3 profile</a>
<canvas id=colorsupport width=300 height=300></canvas>

<script type="text/javascript" src="/node_modules/canvaskit/bin/canvaskit.js"></script>

<script type="text/javascript" src="textapi_utils.js"></script>

<script type="text/javascript" charset="utf-8">

  var CanvasKit = null;
  var cdn = 'https://storage.googleapis.com/skia-cdn/misc/';

  const ckLoaded = CanvasKitInit({locateFile: (file) => '/node_modules/canvaskit/bin/'+file});

  const loadLegoJSON = fetch(cdn + 'lego_loader.json').then((response) => response.text());
  const loadDrinksJSON = fetch(cdn + 'drinks.json').then((response) => response.text());
  const loadConfettiJSON = fetch(cdn + 'confetti.json').then((response) => response.text());
  const loadOnboardingJSON = fetch(cdn + 'onboarding.json').then((response) => response.text());
  const loadMultiframeJSON = fetch(cdn + 'skottie_sample_multiframe.json').then((response) => response.text());

  const loadFlightGif = fetch(cdn + 'flightAnim.gif').then((response) => response.arrayBuffer());
  const loadSkp = fetch(cdn + 'picture2.skp').then((response) => response.arrayBuffer());
  const loadFont = fetch(cdn + 'Roboto-Regular.ttf').then((response) => response.arrayBuffer());
  const loadDog = fetch(cdn + 'dog.jpg').then((response) => response.arrayBuffer());
  const loadMandrill = fetch(cdn + 'mandrill_256.png').then((response) => response.arrayBuffer());
  const loadBrickTex = fetch(cdn + 'brickwork-texture.jpg').then((response) => response.arrayBuffer());
  const loadBrickBump = fetch(cdn + 'brickwork_normal-map.jpg').then((response) => response.arrayBuffer());

  const curves = {
    "MaxCount": 1000,
    "Drawable": {
      "Type": "SkCircleDrawable",
      "Radius": 2
    },
    "Code": [`
      void effectSpawn(inout Effect effect) {
        effect.rate = 200;
        effect.color = float4(1, 0, 0, 1);
      }
      void spawn(inout Particle p) {
        p.lifetime = 3 + rand(p.seed);
        p.vel.y = -50;
      }

      void update(inout Particle p) {
        float w = mix(15, 3, p.age);
        p.pos.x = sin(radians(p.age * 320)) * mix(25, 10, p.age) + mix(-w, w, rand(p.seed));
        if (rand(p.seed) < 0.5) { p.pos.x = -p.pos.x; }

        p.color.g = (mix(75, 220, p.age) + mix(-30, 30, rand(p.seed))) / 255;
      }
      `
    ],
    "Bindings": []
  };

  const spiralSkSL = `
  uniform float rad_scale;
  uniform float2 in_center;
  uniform float4 in_colors0;
  uniform float4 in_colors1;

  half4 main(float2 p) {
      float2 pp = p - in_center;
      float radius = sqrt(dot(pp, pp));
      radius = sqrt(radius);
      float angle = atan(pp.y / pp.x);
      float t = (angle + 3.1415926/2) / (3.1415926);
      t += radius * rad_scale;
      t = fract(t);
      return half4(mix(in_colors0, in_colors1, t));
  }`;

  // Examples which only require canvaskit
  ckLoaded.then((CK) => {
    CanvasKit = CK;
    ParticlesAPI1(CanvasKit);
    RTShaderAPI1(CanvasKit);
    ColorSupport(CanvasKit);
  });

  // Examples requiring external resources.
  // Set bounds to fix the 4:3 resolution of the legos
  Promise.all([ckLoaded, loadLegoJSON]).then(([ck, jsonstr]) => {
    SkottieExample(ck, 'sk_legos', jsonstr, [-50, 0, 350, 300]);
  });
  // Re-size to fit
  let fullBounds = [0, 0, 500, 500];
  Promise.all([ckLoaded, loadDrinksJSON]).then(([ck, jsonstr]) => {
    SkottieExample(ck, 'sk_drinks', jsonstr, fullBounds);
  });
  Promise.all([ckLoaded, loadConfettiJSON]).then(([ck, jsonstr]) => {
    SkottieExample(ck, 'sk_party', jsonstr, fullBounds);
  });
  Promise.all([ckLoaded, loadOnboardingJSON]).then(([ck, jsonstr]) => {
    SkottieExample(ck, 'sk_onboarding', jsonstr, fullBounds);
  });
  Promise.all([ckLoaded, loadMultiframeJSON, loadFlightGif]).then(([ck, jsonstr, gif]) => {
    SkottieExample(ck, 'sk_animated_gif', jsonstr, fullBounds, {'image_0.png': gif});
  });

  Promise.all([ckLoaded, loadFont]).then((results) => {
    ParagraphAPI1(...results);
    ParagraphAPI2(...results);
    GlyphGame(...results)
  });
  Promise.all([ckLoaded, loadSkp]).then((results) => {SkpExample(...results)});

  const rectLeft = 0;
  const rectTop = 1;
  const rectRight = 2;
  const rectBottom = 3;

  function SkottieExample(CanvasKit, id, jsonStr, bounds, assets) {
    if (!CanvasKit || !jsonStr) {
      return;
    }
    const animation = CanvasKit.MakeManagedAnimation(jsonStr, assets);
    const duration = animation.duration() * 1000;
    const size = animation.size();
    let c = document.getElementById(id);
    bounds = bounds || CanvasKit.LTRBRect(0, 0, size.w, size.h);

    // Basic managed animation test.
    if (id === 'sk_drinks') {
      animation.setColor('BACKGROUND_FILL', CanvasKit.Color(0, 163, 199, 1.0));
    }

    const surface = CanvasKit.MakeCanvasSurface(id);
    if (!surface) {
      console.error('Could not make surface');
      return;
    }

    let firstFrame = Date.now();

    function drawFrame(canvas) {
      let seek = ((Date.now() - firstFrame) / duration) % 1.0;
      let damage = animation.seek(seek);

      if (damage[rectRight] > damage[rectLeft] && damage[rectBottom] > damage[rectTop]) {
        canvas.clear(CanvasKit.WHITE);
        animation.render(canvas, bounds);
      }
      surface.requestAnimationFrame(drawFrame);
    }
    surface.requestAnimationFrame(drawFrame);

    return surface;
  }

  function ParticlesAPI1(CanvasKit) {
    const surface = CanvasKit.MakeCanvasSurface('particles');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }
    const context = CanvasKit.currentContext();
    const canvas = surface.getCanvas();
    canvas.translate(250, 450);

    const particles = CanvasKit.MakeParticles(JSON.stringify(curves));
    particles.start(Date.now() / 1000.0, true);

    function drawFrame(canvas) {
      canvas.clear(CanvasKit.BLACK);

      particles.update(Date.now() / 1000.0);
      particles.draw(canvas);
      surface.requestAnimationFrame(drawFrame);
    }
    surface.requestAnimationFrame(drawFrame);
  }

  function ParagraphAPI1(CanvasKit, fontData) {
    if (!CanvasKit || !fontData) {
      return;
    }

    const surface = CanvasKit.MakeCanvasSurface('para1');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }

    const canvas = surface.getCanvas();
    const fontMgr = CanvasKit.FontMgr.FromData([fontData]);

    const paraStyle = new CanvasKit.ParagraphStyle({
        textStyle: {
            color: CanvasKit.BLACK,
            fontFamilies: ['Roboto'],
            fontSize: 50,
        },
        textAlign: CanvasKit.TextAlign.Left,
        maxLines: 5,
    });

    const builder = CanvasKit.ParagraphBuilder.Make(paraStyle, fontMgr);
    builder.addText('The quick brown fox ate a hamburgerfons and got sick.');
    const paragraph = builder.build();

    let wrapTo = 0;

    let X = 100;
    let Y = 100;

    const tf = fontMgr.MakeTypefaceFromData(fontData);
    const font = new CanvasKit.Font(tf, 50);
    const fontPaint = new CanvasKit.Paint();
    fontPaint.setStyle(CanvasKit.PaintStyle.Fill);
    fontPaint.setAntiAlias(true);

    function drawFrame(canvas) {
      canvas.clear(CanvasKit.WHITE);
      wrapTo = 350 + 150 * Math.sin(Date.now() / 2000);
      paragraph.layout(wrapTo);
      canvas.drawParagraph(paragraph, 0, 0);

      canvas.drawLine(wrapTo, 0, wrapTo, 400, fontPaint);

      surface.requestAnimationFrame(drawFrame);
    }
    surface.requestAnimationFrame(drawFrame);

    let interact = (e) => {
      X = e.offsetX*2; // multiply by 2 because the canvas is 300 css pixels wide,
      Y = e.offsetY*2; // but the canvas itself is 600px wide
    };

    document.getElementById('para1').addEventListener('pointermove', interact);
    return surface;
  }

    function ParagraphAPI2(CanvasKit, fontData) {
      if (!CanvasKit || !fontData) {
        return;
      }

      const surface = CanvasKit.MakeCanvasSurface('para2');
      if (!surface) {
        console.error('Could not make surface');
        return;
      }

      const mouse = MakeMouse();
      const cursor = MakeCursor(CanvasKit);
      const canvas = surface.getCanvas();
      const fontMgr = CanvasKit.FontMgr.FromData([fontData]);

      const paraStyle = new CanvasKit.ParagraphStyle({
          textStyle: {
              color: CanvasKit.GRAY,
              fontFamilies: ['Roboto'],
              fontSize: 40,
          },
          textAlign: CanvasKit.TextAlign.Left,
      });

      const text0 = "In a hole in the ground there lived a hobbit. Not a nasty, dirty, " +
                    "wet hole full of worms and oozy smells. This was a hobbit-hole and " +
                    "that means good food, a warm hearth, and all the comforts of home.";
      const WIDTH = 600;

      const tf = fontMgr.MakeTypefaceFromData(fontData);
      const font = new CanvasKit.Font(tf, 40);
      const fm = font.getMetrics();
      const fontPaint = new CanvasKit.Paint();
      fontPaint.setStyle(CanvasKit.PaintStyle.Fill);
      fontPaint.setAntiAlias(true);

      function mid(a, b) { return (a + b) * 0.5; }

      function runs_x_to_index(runs, x) {
          for (const r of runs) {
              for (let i = 1; i < r.offsets.length; i += 1) {
                  if (x < r.positions[i*2]) {
                      if (x <= mid(r.positions[i*2-2], r.positions[i*2])) {
                          return r.offsets[i-1];
                      } else {
                          return r.offsets[i];
                      }
                  }
              }
          }
          const r = runs[runs.length-1];
          return r.offsets[r.offsets.length-1];
      }

      function lines_pos_to_index(lines, x, y) {
          if (y < lines[0].top) {
              return 0;
          }
          for (const l of lines) {
              if (y <= l.bottom) {
                  return runs_x_to_index(l.runs, x);
              }
          }
          return lines[lines.length - 1].textRange.last + 1;
      }

      function runs_index_to_run(runs, index) {
          for (const r of runs) {
              if (index <= r.offsets[r.offsets.length-1]) {
                  return r;
              }
          }
          return null;
      }

    function runs_index_to_x(runs, index) {
        const r = runs_index_to_run(runs, index);
        for (const i in r.offsets) {
            if (index == r.offsets[i]) {
                return r.positions[i*2];
            }
        }
        return null;
    }

    function lines_index_to_line_index(lines, index) {
        let i = 0;
        for (const l of lines) {
            if (index <= l.textRange.last) {
                return i;
            }
            i += 1;
        }
        return lines.length-1;
    }

    function lines_index_to_line(lines, index) {
        return lines[lines_index_to_line_index(lines, index)];
    }

    function lines_index_to_x(lines, index) {
        for (const l of lines) {
            if (index <= l.textRange.last) {
                return runs_index_to_x(l.runs, index);
            }
        }
    }

    function lines_indices_to_path(lines, a, b, fm, width) {
          if (a == b) {
              return null;
          }
          if (a > b) { [a, b] = [b, a]; }

          const path = new CanvasKit.Path();
          const la = lines_index_to_line(lines, a);
          const lb = lines_index_to_line(lines, b);
          const ax = runs_index_to_x(la.runs, a);
          const bx = runs_index_to_x(lb.runs, b);
          if (la == lb) {
              path.addRect([ax, la.top, bx, la.bottom]);
          } else {
              path.addRect([ax, la.top, width, la.bottom]);
              path.addRect([0, lb.top, bx, lb.bottom]);
              if (la.bottom < lb.top) {
                  path.addRect([0, la.bottom, width, lb.top]);   // extra lines inbetween
              }
          }
          return path;
      }

      const string_del = function(str, start, end) {
          return str.slice(0, start) + str.slice(end, str.length);
      };

      let editor = {
          _text: null,
          _lines: null,
          _cursor: null,
          _width: 1e20,
          _index: { start: 0, end: 0 },

          init: function(text, cursor, width) {
              this._text = text;
              this._cursor = cursor;
              this._width = width;

              this._buildLines();
          },
          getLines: function() { return this._lines; },

          setIndex: function(i) {
              this._index.start = this._index.end = i;
              const l = lines_index_to_line(this._lines, i);
              const x = runs_index_to_x(l.runs, i);
              this._cursor.place(x, l.top, l.bottom);
          },
          setIndices: function(a, b) {
              if (a > b) { [a, b] = [b, a]; }
              this._index.start = a;
              this._index.end = b;
              this._cursor.setPath(lines_indices_to_path(this._lines, a, b, fm, this._width));
          },
          moveDX: function(dx) {
              let index;
              if (this._index.start == this._index.end) {
                  // just adjust and pin
                  index = Math.max(Math.min(this._index.start + dx, this._text.length), 0);
              } else {
                  // 'deselect' the region, and turn it into just a single index
                  index = dx < 0 ? this._index.start : this._index.end;
              }
              this.setIndex(index);
          },
          moveDY: function(dy) {
              let index = (dy < 0) ? this._index.start : this._index.end;
              const i = lines_index_to_line_index(this._lines, index);
              if (dy < 0 && i == 0) {
                  index = 0;
              } else if (dy > 0 && i == this._lines.length - 1) {
                  index = this._text.length;
              } else {
                  const x = runs_index_to_x(this._lines[i].runs, index);
                  // todo: statefully track "original" x when an up/down sequence started,
                  //       so we can avoid drift.
                  index = runs_x_to_index(this._lines[i+dy].runs, x);
              }
              this.setIndex(index);
          },
          _buildLines: function() {
              const builder = CanvasKit.ParagraphBuilder.Make(paraStyle, fontMgr);
              builder.addText(this._text);
              const paragraph = builder.build();
              paragraph.layout(WIDTH);

              const rec = new CanvasKit.PictureRecorder();
              const can = rec.beginRecording([0,0,9999,9999]);
              can.drawParagraph(paragraph, 0, 0);
              rec.delete();

              this._lines = paragraph.getShapedLines();

              paragraph.delete();
              builder.delete();
          },
          deleteSelection: function() {
              let start = this._index.start;
              if (start == this._index.end) {
                  if (start > 0) {
                      this._text = string_del(this._text, start - 1, start);
                      start -= 1;
                  }
              } else {
                  this._text = string_del(this._text,  start, this._index.end);
              }
              this._buildLines();
              this.setIndex(start);
          },
          insert: function(charcode) {
              if (this._index.start != this._index.end) {
                  this.deleteSelection();
              }
              const index = this._index.start;
              this._text = this._text.slice(0, index) + charcode + this._text.slice(index);
              this._buildLines();
              this.setIndex(index + 1);
          },
      };
      editor.init(text0, cursor, WIDTH);

      function drawFrame(canvas) {
        const lines = editor.getLines();

        canvas.clear(CanvasKit.WHITE);

        if (mouse.isActive()) {
            const pos = mouse.getPos();
            const a = lines_pos_to_index(lines, pos[0], pos[1]);
            const b = lines_pos_to_index(lines, pos[2], pos[3]);
            if (a == b) {
                editor.setIndex(a);
            } else {
                editor.setIndices(a, b);
            }
        }

        const bgcolors = [[1,0,0,0.05], [0,1,0,0.05]];
        let lineNo = 0;
        cursor.draw_before(canvas);
        for (const l of lines) {
            if (true) { // test line bounds
                const bounds = [0, l.top, WIDTH, l.bottom];
                fontPaint.setColor(bgcolors[lineNo & 1]);
                canvas.drawRect(bounds, fontPaint);
                fontPaint.setColor([0,0,0,1]);
            }
            for (let r of l.runs) {
                canvas.drawGlyphs(r.glyphs, r.positions, 0, 0, font, fontPaint);
            }
            lineNo += 1;
        }
        cursor.draw_after(canvas);

        surface.requestAnimationFrame(drawFrame);
      }
      surface.requestAnimationFrame(drawFrame);

      function interact(e) {
        const type = e.type;
        if (type === 'pointerup') {
            mouse.setUp(e.offsetX, e.offsetY);
        } else if (type === 'pointermove') {
            mouse.setMove(e.offsetX, e.offsetY);
        } else if (type === 'pointerdown') {
            mouse.setDown(e.offsetX, e.offsetY);
        }
      };

      function keyhandler(e) {
          switch (e.key) {
              case 'ArrowLeft':  editor.moveDX(-1); break;
              case 'ArrowRight': editor.moveDX(1); break;
              case 'ArrowUp':
                e.preventDefault();
                editor.moveDY(-1);
                break;
              case 'ArrowDown':
                e.preventDefault();
                editor.moveDY(1);
                break;
              case 'Backspace':
                editor.deleteSelection();
                break;
              case 'Shift':
                break;
              default:
                if (!e.ctrlKey && !e.metaKey) {
                    editor.insert(e.key);
                }
                break;
          }
      }

      document.getElementById('para2').addEventListener('pointermove', interact);
      document.getElementById('para2').addEventListener('pointerdown', interact);
      document.getElementById('para2').addEventListener('pointerup', interact);
      document.getElementById('para2').addEventListener('keydown', keyhandler);
      return surface;
    }

  function RTShaderAPI1(CanvasKit) {
    if (!CanvasKit) {
      return;
    }

    const surface = CanvasKit.MakeCanvasSurface('rtshader');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }

    const canvas = surface.getCanvas();

    const effect = CanvasKit.RuntimeEffect.Make(spiralSkSL);
    const shader = effect.makeShader([
      0.5,
      150, 150,
      0, 1, 0, 1,
      1, 0, 0, 1], true);
    const paint = new CanvasKit.Paint();
    paint.setShader(shader);
    canvas.drawRect(CanvasKit.LTRBRect(0, 0, 300, 300), paint);

    surface.flush();
    shader.delete();
    paint.delete();
    effect.delete();
  }

  // RTShader2 demo
  Promise.all([ckLoaded, loadDog, loadMandrill]).then((values) => {
    const [CanvasKit, dogData, mandrillData] = values;
    const dogImg = CanvasKit.MakeImageFromEncoded(dogData);
    if (!dogImg) {
      console.error('could not decode dog');
      return;
    }
    const mandrillImg = CanvasKit.MakeImageFromEncoded(mandrillData);
    if (!mandrillImg) {
      console.error('could not decode mandrill');
      return;
    }
    const quadrantSize = 150;

    const dogShader = dogImg.makeShaderCubic(
        CanvasKit.TileMode.Clamp, CanvasKit.TileMode.Clamp,
        1/3, 1/3,
        CanvasKit.Matrix.scaled(quadrantSize/dogImg.width(),
        quadrantSize/dogImg.height()));
    const mandrillShader = mandrillImg.makeShaderCubic(
        CanvasKit.TileMode.Clamp, CanvasKit.TileMode.Clamp,
        1/3, 1/3,
        CanvasKit.Matrix.scaled(
            quadrantSize/mandrillImg.width(),
            quadrantSize/mandrillImg.height()));

    const surface = CanvasKit.MakeCanvasSurface('rtshader2');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }

    const prog = `
      uniform shader before_map;
      uniform shader after_map;
      uniform shader threshold_map;

      uniform float cutoff;
      uniform float slope;

      float smooth_cutoff(float x) {
          x = x * slope + (0.5 - slope * cutoff);
          return clamp(x, 0, 1);
      }

      half4 main(float2 xy) {
          half4 before = sample(before_map, xy);
          half4 after = sample(after_map, xy);

          float m = smooth_cutoff(sample(threshold_map, xy).r);
          return mix(before, after, half(m));
      }`;

    const canvas = surface.getCanvas();

    const thresholdEffect = CanvasKit.RuntimeEffect.Make(prog);
    const spiralEffect = CanvasKit.RuntimeEffect.Make(spiralSkSL);

    const draw = (x, y, shader) => {
      const paint = new CanvasKit.Paint();
      paint.setShader(shader);
      canvas.save();
      canvas.translate(x, y);
      canvas.drawRect(CanvasKit.LTRBRect(0, 0, quadrantSize, quadrantSize), paint);
      canvas.restore();
      paint.delete();
    };

    const offscreenSurface = CanvasKit.MakeSurface(quadrantSize, quadrantSize);
    const getBlurrySpiralShader = (rad_scale) => {
      const oCanvas = offscreenSurface.getCanvas();

      const spiralShader = spiralEffect.makeShader([
      rad_scale,
      quadrantSize/2, quadrantSize/2,
      1, 1, 1, 1,
      0, 0, 0, 1], true);

      return spiralShader;
      // TODO(kjlubick): The raster backend does not like atan or fract, so we can't
      // draw the shader into the offscreen canvas and mess with it. When we can, that
      // would be cool to show off.

      const blur = CanvasKit.ImageFilter.MakeBlur(0.1, 0.1, CanvasKit.TileMode.Clamp, null);

      const paint = new CanvasKit.Paint();
      paint.setShader(spiralShader);
      paint.setImageFilter(blur);
      oCanvas.drawRect(CanvasKit.LTRBRect(0, 0, quadrantSize, quadrantSize), paint);

      paint.delete();
      blur.delete();
      spiralShader.delete();
      return offscreenSurface.makeImageSnapshot()
                             .makeShader(CanvasKit.TileMode.Clamp, CanvasKit.TileMode.Clamp);

    };

    const drawFrame = () => {
      surface.requestAnimationFrame(drawFrame);
      const thresholdShader = getBlurrySpiralShader(Math.sin(Date.now() / 5000) / 2);

      const blendShader = thresholdEffect.makeShaderWithChildren(
        [0.5, 10],
        true, [dogShader, mandrillShader, thresholdShader]);
      draw(0, 0, blendShader);
      draw(quadrantSize, 0, thresholdShader);
      draw(0, quadrantSize, dogShader);
      draw(quadrantSize, quadrantSize, mandrillShader);

      blendShader.delete();
    };

    surface.requestAnimationFrame(drawFrame);
  });

  function SkpExample(CanvasKit, skpData) {
    if (!skpData || !CanvasKit) {
      return;
    }

    const surface = CanvasKit.MakeSWCanvasSurface('skp');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }

    const pic = CanvasKit.MakePicture(skpData);

    function drawFrame(canvas) {
      canvas.clear(CanvasKit.TRANSPARENT);
      // this particular file has a path drawing at (68,582) that's 1300x1300 pixels
      // scale it down to 500x500 and translate it to fit.
      const scale = 500.0/1300;
      canvas.scale(scale, scale);
      canvas.translate(-68, -582);
      canvas.drawPicture(pic);
    }
    // Intentionally just draw frame once
    surface.drawOnce(drawFrame);
  }

  // Shows a hidden message by rotating all the characters in a kind of way that makes you
  // search with your mouse.
  function GlyphGame(canvas, robotoData) {
    const surface = CanvasKit.MakeCanvasSurface('glyphgame');
    if (!surface) {
      console.error('Could not make surface');
      return;
    }
    const sizeX = document.getElementById('glyphgame').width;
    const sizeY = document.getElementById('glyphgame').height;
    const halfDim = Math.min(sizeX, sizeY) / 2;
    const margin = 50;
    const marginTop = 25;
    let rotX = 0; //  expected to be updated in interact()
    let rotY = 0;
    let pointer = [500, 450];
    const radPerPixel = 0.005; // radians of subject rotation per pixel distance moved by mouse.

    const camAngle = Math.PI / 12;
    const cam = {
      'eye'  : [0, 0, 1 / Math.tan(camAngle/2) - 1],
      'coa'  : [0, 0, 0],
      'up'   : [0, 1, 0],
      'near' : 0.02,
      'far'  : 4,
      'angle': camAngle,
    };

    let lastImage = null;

    const fontMgr = CanvasKit.FontMgr.FromData([robotoData]);

    const paraStyle = new CanvasKit.ParagraphStyle({
        textStyle: {
            color: CanvasKit.Color(105, 56, 16), // brown
            fontFamilies: ['Roboto'],
            fontSize: 28,
        },
        textAlign: CanvasKit.TextAlign.Left,
    });
    const hStyle = CanvasKit.RectHeightStyle.Max;
    const wStyle = CanvasKit.RectWidthStyle.Tight;

    const quotes = [
      'Some activities superficially familiar to you are merely stupid and should be avoided for your safety, although they are not illegal as such. These include: giving your bank account details to the son of the Nigerian Minister of Finance; buying title to bridges, skyscrapers, spacecraft, planets, or other real assets; murder; selling your identity; and entering into financial contracts with entities running Economics 2.0 or higher.',
      // Charles Stross - Accelerando
      'If only there were evil people somewhere insidiously committing evil deeds, and it were necessary only to separate them from the rest of us and destroy them. But the line dividing good and evil cuts through the heart of every human being. And who is willing to destroy a piece of his own heart?',
      // Aleksandr Solzhenitsyn - The Gulag Archipelago
      'There is one metaphor of which the moderns are very fond; they are always saying, “You can’t put the clock back.” The simple and obvious answer is “You can.” A clock, being a piece of human construction, can be restored by the human finger to any figure or hour. In the same way society, being a piece of human construction, can be reconstructed upon any plan that has ever existed.',
      // G. K. Chesterton - What's Wrong With The World?
    ];

    // pick one at random
    const text = quotes[Math.floor(Math.random()*3)];
    const builder = CanvasKit.ParagraphBuilder.Make(paraStyle, fontMgr);
    builder.addText(text);
    const paragraph = builder.build();
    const font = new CanvasKit.Font(null, 18);
    // wrap the text to a given width.
    paragraph.layout(sizeX - margin*2);

    // to rotate every glyph individually, calculate the bounding rect of each one,
    // construct an array of rects and paragraphs that would draw each glyph individually.
    const letters = Array(text.length);
    for (let i = 0; i < text.length; i++) {
      const r = paragraph.getRectsForRange(i, i+1, hStyle, wStyle)[0];
      // The character is drawn with drawParagraph so we can pass the paraStyle,
      // and have our character be the exact size and shape the paragraph expected
      // when it wrapped the text. canvas.drawText wouldn't cut it.
      const tmpbuilder = CanvasKit.ParagraphBuilder.Make(paraStyle, fontMgr);
      tmpbuilder.addText(text[i]);
      const para = tmpbuilder.build();
      para.layout(100);
      letters[i] = {
        'r': r,
        'para': para,
      };
    }

    function drawFrame(canvas) {
      // persistence of vision effect is done by drawing the past frame as an image,
      // then covering with semitransparent background color.
      if (lastImage) {
        canvas.drawImage(lastImage, 0, 0, null);
        canvas.drawColor(CanvasKit.Color(171, 244, 255, 0.1)); // sky blue, almost transparent
      } else {
        canvas.clear(CanvasKit.Color(171, 244, 255)); // sky blue, opaque
      }
      canvas.save();
      // Set up 3D view enviroment
      canvas.concat(CanvasKit.M44.setupCamera(
        CanvasKit.LTRBRect(0, 0, sizeX, sizeY), halfDim, cam));

      // Rotate the whole paragraph as a unit.
      const paraRotPoint = [halfDim, halfDim, 1];
      canvas.concat(CanvasKit.M44.multiply(
        CanvasKit.M44.translated(paraRotPoint),
        CanvasKit.M44.rotated([0,1,0], rotX),
        CanvasKit.M44.rotated([1,0,0], rotY * 0.2),
        CanvasKit.M44.translated(CanvasKit.Vector.mulScalar(paraRotPoint, -1)),
      ));

      // Rotate every glyph in the paragraph individually.
      let i = 0;
      for (const letter of letters) {
        canvas.save();
        let r = letter['r'];
        // rotate about the center of the glyph's rect.
        rotationPoint = [
          margin + r[rectLeft] + (r[rectRight] - r[rectLeft]) / 2,
          marginTop + r[rectTop] + (r[rectBottom] - r[rectTop]) / 2,
          0
        ];
        distanceFromPointer = CanvasKit.Vector.dist(pointer, rotationPoint.slice(0, 2));
        // Rotate more around the Y-axis depending on the glyph's distance from the pointer.
        canvas.concat(CanvasKit.M44.multiply(
          CanvasKit.M44.translated(rotationPoint),
          // note that I'm rotating around the x axis first, undoing some of the rotation done to the whole
          // paragraph above, where x came second. If I rotated y first, a lot of letters would end up
          // upside down, which is a bit too hard to unscramble.
          CanvasKit.M44.rotated([1,0,0], rotY * -0.6),
          CanvasKit.M44.rotated([0,1,0], distanceFromPointer * -0.035),
          CanvasKit.M44.translated(CanvasKit.Vector.mulScalar(rotationPoint, -1)),
        ));
        canvas.drawParagraph(letter['para'], margin + r[rectLeft], marginTop + r[rectTop]);
        i++;
        canvas.restore();
      }
      canvas.restore();
      lastImage = surface.makeImageSnapshot();
    }

    function interact(e) {
      pointer = [e.offsetX, e.offsetY]
      rotX = (pointer[0] - halfDim) * radPerPixel;
      rotY = (pointer[1] - halfDim) * radPerPixel * -1;
      surface.requestAnimationFrame(drawFrame);
    };

    document.getElementById('glyphgame').addEventListener('pointermove', interact);
    surface.requestAnimationFrame(drawFrame);
  }

  function ColorSupport(CanvasKit) {
    const surface = CanvasKit.MakeCanvasSurface('colorsupport', CanvasKit.ColorSpace.ADOBE_RGB);
    if (!surface) {
      console.error('Could not make surface');
      return;
    }
    const canvas = surface.getCanvas();

    // If the surface is correctly initialized with a higher bit depth color type,
    // And chrome is compositing it into a buffer with the P3 color space,
    // then the inner round rect should be distinct and less saturated than the full red background.
    // Even if the monitor it is viewed on cannot accurately represent that color space.

    let red = CanvasKit.Color4f(1, 0, 0, 1);
    let paint = new CanvasKit.Paint();
    paint.setColor(red, CanvasKit.ColorSpace.ADOBE_RGB);
    canvas.drawPaint(paint);
    paint.setColor(red, CanvasKit.ColorSpace.DISPLAY_P3);
    canvas.drawRRect(CanvasKit.RRectXY([50, 50, 250, 250], 30, 30), paint);
    paint.setColor(red, CanvasKit.ColorSpace.SRGB);
    canvas.drawRRect(CanvasKit.RRectXY([100, 100, 200, 200], 30, 30), paint);

    surface.flush();
    surface.delete();
  }
</script>
