blob: b48392003be4cfe6f39ebe13936716b6d3f666e8 [file] [log] [blame]
<!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].index;
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>