UNPKG

canvaskit-wasm

Version:

A WASM version of Skia's Canvas API

185 lines (162 loc) 7.05 kB
<!DOCTYPE html> <title>CanvasKit Bidi</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; } #sampleText { width: 400px; height: 200px; } </style> <canvas id="getBidiRegions" width=900 height=800></canvas> <canvas id="reorderVisuals" width=900 height=800></canvas> <canvas id="getCodeUnitFlags" width=900 height=800></canvas> <script type="text/javascript" src="/build/canvaskit.js"></script> <script type="text/javascript" charset="utf-8"> var cdn = 'https://storage.googleapis.com/skia-cdn/misc/'; const ckLoaded = CanvasKitInit({locateFile: (file) => '/build/'+file}); const loadRoboto = fetch(cdn + 'Roboto-Regular.ttf').then((response) => response.arrayBuffer()); const loadEmoji = fetch(cdn + 'NotoEmoji.v26.ttf').then((response) => response.arrayBuffer()); const loadArabic = fetch(cdn + 'NotoSansArabic.v18.ttf').then((response) => response.arrayBuffer()); var mallocedLevels; Promise.all([ckLoaded, loadRoboto]).then(([ck, roboto]) => { GetBidiRegions(ck, roboto); ReorderVisuals(ck, roboto); GetCodeUnitFlags(ck, roboto); }); function GetBidiRegions(CanvasKit, robotoData) { if (!robotoData || !CanvasKit) { return; } const surface = CanvasKit.MakeCanvasSurface('getBidiRegions'); if (!surface) { console.error('Could not make surface'); return; } const sampleText = 'left1 يَهْدِيْكُمُ left2 اللَّه left3 ُ وَيُصْلِحُ left4 بَالَكُم'; const roboto = CanvasKit.Typeface.MakeTypefaceFromData(robotoData); const textPaint = new CanvasKit.Paint(); textPaint.setColor(CanvasKit.RED); textPaint.setAntiAlias(true); const dataPaint = new CanvasKit.Paint(); dataPaint.setColor(CanvasKit.BLACK); dataPaint.setAntiAlias(true); const textFont = new CanvasKit.Font(roboto, 30); const dataFont = new CanvasKit.Font(roboto, 20); function drawFrame(canvas) { let height = 40; canvas.drawText(sampleText, 100, height, textPaint, textFont); height += 80; const regions = CanvasKit.Bidi.getBidiRegions(sampleText, CanvasKit.TextDirection.LTR); mallocedLevels = CanvasKit.Malloc(Uint8Array, regions.length); for (let i = 0; i < regions.length; ++i) { const region = regions[i]; let result = '[' + region.start + ':' + region.end + '): '; result += (region.level.value % 2 === 0 ? 'LTR ' : 'RTL ') + region.level; canvas.drawText(result, 100, height, dataPaint, dataFont); height += 40; mallocedLevels[i] = region.level; } } surface.requestAnimationFrame(drawFrame); return surface; } function ReorderVisuals(CanvasKit, robotoData) { if (!robotoData || !CanvasKit) { return; } const surface = CanvasKit.MakeCanvasSurface('reorderVisuals'); if (!surface) { console.error('Could not make surface'); return; } const roboto = CanvasKit.Typeface.MakeTypefaceFromData(robotoData); const textPaint = new CanvasKit.Paint(); textPaint.setColor(CanvasKit.RED); textPaint.setAntiAlias(true); const dataPaint = new CanvasKit.Paint(); dataPaint.setColor(CanvasKit.BLACK); dataPaint.setAntiAlias(true); const textFont = new CanvasKit.Font(roboto, 30); const dataFont = new CanvasKit.Font(roboto, 20); function drawCase(canvas, height, input, output) { let result = '['; for (let i = 0; i < input.length; ++i) { const logical = input[i]; result += (i === 0 ? '' : ', ') + logical; } result += '] produced: '; const logicals = CanvasKit.Bidi.reorderVisual(input); result += '['; for (let i = 0; i < logicals.length; ++i) { const logical = logicals[i]; result += (i === 0 ? '' : ', ') + logical; } result += '] expected: ' + output; canvas.drawText(result, 100, height, dataPaint, dataFont); } function drawFrame(canvas) { let height = 40; drawCase(canvas, height, [], '[]'); height += 40; drawCase(canvas, height, [0], '[0]'); height += 40; drawCase(canvas, height, [1], '[0]'); height += 40; drawCase(canvas, height, [0, 1, 0, 1], '[0, 1, 2, 3]'); height += 40; } surface.requestAnimationFrame(drawFrame); return surface; } function GetCodeUnitFlags(CanvasKit, robotoData) { if (!robotoData || !CanvasKit) { return; } const surface = CanvasKit.MakeCanvasSurface('getCodeUnitFlags'); if (!surface) { console.error('Could not make surface'); return; } const flagsText = ' |\u{a0}\u{a0}\u{a0}|\u{0a}\u{0a}\u{0a}|満毎行|'; const roboto = CanvasKit.Typeface.MakeTypefaceFromData(robotoData); const textPaint = new CanvasKit.Paint(); textPaint.setColor(CanvasKit.RED); textPaint.setAntiAlias(true); const dataPaint = new CanvasKit.Paint(); dataPaint.setColor(CanvasKit.BLACK); dataPaint.setAntiAlias(true); const textFont = new CanvasKit.Font(roboto, 30); const dataFont = new CanvasKit.Font(roboto, 20); function drawFrame(canvas) { let height = 40; canvas.drawText(flagsText, 100, height, textPaint, textFont); height += 80; const flags = CanvasKit.CodeUnits.compute(flagsText); let result = '0: '; for (let i = 0; i < flags.length; ++i) { const flag = flags[i]; if (flagsText[i] === '|') { canvas.drawText(result, 100, height, dataPaint, dataFont); height += 40; result = '' + (i + 1) + ': '; } else if (flag === 0) { result += flagsText[i]; } else { result += '{'; result += (flag & CanvasKit.CodeUnitFlags.Ideographic.value) !== 0 ? 'I' : ''; result += (flag & CanvasKit.CodeUnitFlags.Whitespace.value) !== 0 ? 'S' : ''; result += (flag & CanvasKit.CodeUnitFlags.Space.value) !== 0 ? 'W' : ''; result += (flag & CanvasKit.CodeUnitFlags.Control.value) !== 0 ? 'C' : ''; result += '}'; } } } surface.requestAnimationFrame(drawFrame); return surface; } </script>