<!DOCTYPE html>
<title>CanvasKit Paragraph (with & without ICU)</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">

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

<style>
  canvas {
    border: 1px dashed #AAA;
  }
  #withICU {
    border-color: red;
  }
  #withoutICU {
    border-color: green;
  }
</style>

<table>
  <thead>
    <th><h2 style="color: red;">With ICU</h2></th>
    <th></th>
    <th><h2 style="color: green;">Without ICU</h2></th>
  </thead>
  <tr>
    <td><canvas id="withICU" width=600 height=600></canvas></td>
    <td style="width: 20px;"></td>
    <td><canvas id="withoutICU" width=600 height=600 tabindex='-1'></canvas></td>
  </tr>
</table>

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

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

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

  const loadFonts = [
    fetch(cdn + 'Roboto-Regular.ttf').then((response) => response.arrayBuffer()),
    fetch('https://fonts.gstatic.com/s/notoemoji/v26/bMrnmSyK7YY-MEu6aWjPDs-ar6uWaGWuob-r0jwvS-FGJCMY.ttf').then((response) => response.arrayBuffer()),
    fetch('https://fonts.gstatic.com/s/notosanssymbols/v34/rP2up3q65FkAtHfwd-eIS2brbDN6gxP34F9jRRCe4W3gfQ8gavVFRkzrbQ.ttf').then((response) => response.arrayBuffer()),
    fetch('https://fonts.gstatic.com/s/notosanssymbols2/v15/I_uyMoGduATTei9eI8daxVHDyfisHr71ypPqfX71-AI.ttf').then((response) => response.arrayBuffer()),
    fetch('https://fonts.gstatic.com/s/notosansarabic/v18/nwpxtLGrOAZMl5nJ_wfgRg3DrWFZWsnVBJ_sS6tlqHHFlhQ5l3sQWIHPqzCfyGyvu3CBFQLaig.ttf').then((response) => response.arrayBuffer()),
  ];

  ckLoaded.then((CK) => {
    CanvasKit = CK;
  });

  Promise.all([ckLoaded, Promise.all(loadFonts)]).then((results) => {
    ParagraphWithICU(...results);
    ParagraphWithoutICU(...results);
  });

  const sampleText = 'The لاquick 😠brown\nfox ate a hamburgerfons and got sick.\n';
  const fontFamilies = [
    'Roboto',
    'Noto Emoji',
    'Noto Sans Arabic',
    'Noto Sans Symbols',
    'Noto Sans Symbols 2',
  ];

  function ParagraphWithICU(CanvasKit, fonts) {
    if (!CanvasKit || !fonts) {
      return;
    }

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

    const canvas = surface.getCanvas();
    const fontMgr = CanvasKit.FontMgr.FromData(fonts);

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

    const builder = CanvasKit.ParagraphBuilder.Make(paraStyle, fontMgr);
    builder.addText(sampleText);
    const paragraph = builder.build();

    fontMgr.delete();

    function drawFrame(canvas) {
      drawParagraph(canvas, paragraph);
      surface.requestAnimationFrame(drawFrame);
    }
    surface.requestAnimationFrame(drawFrame);
  }

  function ParagraphWithoutICU(CanvasKit, fonts) {
    if (!CanvasKit || !fonts) {
      return;
    }

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

    const fontMgr = CanvasKit.FontMgr.FromData(fonts);

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

    const builder = CanvasKit.ParagraphBuilder.Make(paraStyle, fontMgr);
    builder.addText(sampleText);

    const text = sampleText;

    // Pass 3 bidi regions. The array is made of triplets {start, end, direction}.
    const mallocedBidis = CanvasKit.Malloc(Uint32Array, 9);
    mallocedBidis.toTypedArray().set([
      0, 4, CanvasKit.TextDirection.LTR.value,
      4, 6, CanvasKit.TextDirection.RTL.value,
      6, text.length, CanvasKit.TextDirection.LTR.value,
    ]);

    // Pass the entire text as one word. It's only used for the method
    // getWords.
    const mallocedWords = CanvasKit.Malloc(Uint32Array, 2);
    mallocedWords.toTypedArray().set([0, text.length]);

    const graphemeBoundaries = getGraphemeBoundaries(text);
    const mallocedGraphemes = CanvasKit.Malloc(Uint32Array, graphemeBoundaries.length);
    mallocedGraphemes.toTypedArray().set(graphemeBoundaries);

    const lineBreaks = getLineBreaks(text);
    const mallocedLineBreaks = CanvasKit.Malloc(Uint32Array, lineBreaks.length);
    mallocedLineBreaks.toTypedArray().set(lineBreaks);

    const paragraph = builder.buildWithClientInfo(
        mallocedBidis,
        mallocedWords,
        mallocedGraphemes,
        mallocedLineBreaks
    );

    fontMgr.delete();

    function drawFrame(canvas) {
      drawParagraph(canvas, paragraph);
      surface.requestAnimationFrame(drawFrame);
    }
    surface.requestAnimationFrame(drawFrame);

    return surface;
  }

  function drawParagraph(canvas, paragraph) {
    const fontPaint = new CanvasKit.Paint();
    fontPaint.setStyle(CanvasKit.PaintStyle.Fill);
    fontPaint.setAntiAlias(true);

    canvas.clear(CanvasKit.WHITE);
    const wrapTo = 350 + 150 * Math.sin(Date.now() / 4000);
    paragraph.layout(wrapTo);

    const rects = [
      ...paragraph.getRectsForRange(2, 8, CanvasKit.RectHeightStyle.Tight, CanvasKit.RectWidthStyle.Tight),
      ...paragraph.getRectsForRange(12, 16, CanvasKit.RectHeightStyle.Tight, CanvasKit.RectWidthStyle.Tight),
    ];
    const rectPaint = new CanvasKit.Paint();
    const colors = [CanvasKit.CYAN, CanvasKit.MAGENTA, CanvasKit.BLUE, CanvasKit.YELLOW];
    for (const rect of rects) {
      rectPaint.setColor(colors.shift() || CanvasKit.RED);
      canvas.drawRect(rect, rectPaint);
    }

    canvas.drawParagraph(paragraph, 0, 0);

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

  const SOFT = 0;
  const HARD = 1;

  function getLineBreaks(text) {
    const breaks = [0, SOFT];

    const iterator = new Intl.v8BreakIterator(['en'], {type: 'line'});
    iterator.adoptText(text);
    iterator.first();

    while (iterator.next() != -1) {
      breaks.push(iterator.current(), getBreakType(iterator.breakType()));
    }

    console.log(breaks);
    return breaks;
  }

  function getBreakType(v8BreakType) {
    return v8BreakType == 'none' ? SOFT : HARD;
  }

  function getGraphemeBoundaries(text) {
    const segmenter = new Intl.Segmenter(['en'], {type: 'grapheme'});
    const segments = segmenter.segment(text);

    const graphemeBoundaries = [];
    for (const segment of segments) {
      graphemeBoundaries.push(segment.index);
    }
    graphemeBoundaries.push(text.length);
    return graphemeBoundaries;
  }
</script>
