<!DOCTYPE html>
<title>WIP Shaping in JS Demo</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;
  }

  #input {
    height: 300px;
  }

</style>

<h2> (Really Bad) Shaping in JS </h2>
<textarea id=input></textarea>
<canvas id=shaped_text width=300 height=300></canvas>

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

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

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

  const ckLoaded = CanvasKitInit({locateFile: (file) => '/build/'+file});
  const loadFont = fetch(cdn + 'Roboto-Regular.ttf').then((response) => response.arrayBuffer());
  // This font works with interobang.
  //const loadFont = fetch('https://storage.googleapis.com/skia-cdn/google-web-fonts/SourceSansPro-Regular.ttf').then((response) => response.arrayBuffer());

  document.getElementById('input').value = 'An aegis protected the fox!?';

  // Examples requiring external resources.
  Promise.all([ckLoaded, loadFont]).then((results) => {
    ShapingJS(...results);
  });

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

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

    const typeface = CanvasKit.Typeface.MakeFreeTypeFaceFromData(fontData);

    const paint = new CanvasKit.Paint();

    paint.setColor(CanvasKit.BLUE);
    paint.setStyle(CanvasKit.PaintStyle.Stroke);

    const textPaint = new CanvasKit.Paint();
    const textFont = new CanvasKit.Font(typeface, 20);
    textFont.setLinearMetrics(true);
    textFont.setSubpixel(true);
    textFont.setHinting(CanvasKit.FontHinting.Slight);


    // Only care about these characters for now. If we get any unknown characters, we'll replace
    // them with the first glyph here (the replacement glyph).
    // We put the family code point second to make sure we handle >16 bit codes correctly.
    const alphabet = "�👪abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 _.,?!æ‽";
    const ids = textFont.getGlyphIDs(alphabet);
    const unknownCharacterGlyphID = ids[0];
    // char here means "string version of unicode code point". This makes the code below a bit more
    // readable than just integers. We just have to take care when reading these in that we don't
    // grab the second half of a 32 bit code unit.
    const charsToGlyphIDs = {};
    // Indexes in JS correspond to a 16 bit or 32 bit code unit. If a code point is wider than
    // 16 bits, it overflows into the next index. codePointAt will return a >16 bit value if the
    // given index overflows. We need to check for this and skip the next index lest we get a
    // garbage value (the second half of the Unicode code point.
    let glyphIdx = 0;
    for (let i = 0; i < alphabet.length; i++) {
      charsToGlyphIDs[alphabet[i]] = ids[glyphIdx];
      if (alphabet.codePointAt(i) > 65535) {
        i++; // skip the next index because that will be the second half of the code point.
      }
      glyphIdx++;
    }

    // TODO(kjlubick): linear metrics so we get "correct" data (e.g. floats).
    const bounds = textFont.getGlyphBounds(ids, textPaint);
    const widths = textFont.getGlyphWidths(ids, textPaint);
    // See https://www.freetype.org/freetype2/docs/glyphs/glyphs-3.html
    // Note that in Skia, y-down is positive, so it is common to see yMax below be negative.
    const glyphMetricsByGlyphID = {};
    for (let i = 0; i < ids.length; i++) {
      glyphMetricsByGlyphID[ids[i]] = {
        xMin: bounds[i*4],
        yMax: bounds[i*4 + 1],
        xMax: bounds[i*4 + 2],
        yMin: bounds[i*4 + 3],
        xAdvance: widths[i],
      };
    }

    const shapeAndDrawText = (str, canvas, x, y, maxWidth, font, paint) => {
      const LINE_SPACING = 20;

      // This is a conservative estimate - it can be shorter if we have ligatures code points
      // that span multiple 16bit words.
      const glyphs = CanvasKit.MallocGlyphIDs(str.length);
      let glyphArr = glyphs.toTypedArray();

      // Turn the code points into glyphs, accounting for up to 2 ligatures.
      let shapedGlyphIdx = -1;
      for (let i = 0; i < str.length; i++) {
        const char = str[i];
        shapedGlyphIdx++;
        // POC Ligature support.
        if (charsToGlyphIDs['æ'] && char === 'a' && str[i+1] === 'e') {
          glyphArr[shapedGlyphIdx] = charsToGlyphIDs['æ'];
          i++; // skip next code point
          continue;
        }
        if (charsToGlyphIDs['‽'] && (
            (char === '?' && str[i+1] === '!') || (char === '!' && str[i+1] === '?' ))) {
          glyphArr[shapedGlyphIdx] = charsToGlyphIDs['‽'];
          i++; // skip next code point
          continue;
        }
        glyphArr[shapedGlyphIdx] = charsToGlyphIDs[char] || unknownCharacterGlyphID;
        if (str.codePointAt(i) > 65535) {
          i++; // skip the next index because that will be the second half of the code point.
        }
      }
      // Trim down our array of glyphs to only the amount we have after ligatures and code points
      // that are > 16 bits.
      glyphArr = glyphs.subarray(0, shapedGlyphIdx+1);

      // Break our glyphs into runs based on the maxWidth and the xAdvance.
      const glyphRuns = [];
      let currentRunStartIdx = 0;
      let currentWidth = 0;
      for (let i = 0; i < glyphArr.length; i++) {
        const nextGlyphWidth = glyphMetricsByGlyphID[glyphArr[i]].xAdvance;
        if (currentWidth + nextGlyphWidth > maxWidth) {
          glyphRuns.push(glyphs.subarray(currentRunStartIdx, i));
          currentRunStartIdx = i;
          currentWidth = 0;
        }
        currentWidth += nextGlyphWidth;
      }
      glyphRuns.push(glyphs.subarray(currentRunStartIdx, glyphArr.length));

      // Draw all those runs.
      for (let i = 0; i < glyphRuns.length; i++) {
        const blob = CanvasKit.TextBlob.MakeFromGlyphs(glyphRuns[i], font);
        if (blob) {
          canvas.drawTextBlob(blob, x, y + LINE_SPACING*i, paint);
        }
        blob.delete();
      }
      CanvasKit.Free(glyphs);
    }

    const drawFrame = (canvas) => {
      canvas.clear(CanvasKit.WHITE);
      canvas.drawText('a + e = ae (no ligature)',
        5, 30, textPaint, textFont);
      canvas.drawText('a + e = æ (hard-coded ligature)',
        5, 50, textPaint, textFont);

      canvas.drawRect(CanvasKit.LTRBRect(10, 80, 280, 290), paint);
      shapeAndDrawText(document.getElementById('input').value, canvas, 15, 100, 265, textFont, textPaint);

      surface.requestAnimationFrame(drawFrame)
    };
    surface.requestAnimationFrame(drawFrame);
  }
</script>
