ffbfe87887
By passing null into reportSurface, it "crashes" the test, allowing me to visually inspect the results while running locally. However, on production code, it just breaks the tests. Change-Id: I93339f03ee5a9f86959b30353912526a442f6375 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/244677 Reviewed-by: Kevin Lubick <kjlubick@google.com>
257 lines
9.5 KiB
JavaScript
257 lines
9.5 KiB
JavaScript
describe('CanvasKit\'s Path Behavior', function() {
|
|
let container = document.createElement('div');
|
|
document.body.appendChild(container);
|
|
const CANVAS_WIDTH = 600;
|
|
const CANVAS_HEIGHT = 600;
|
|
|
|
beforeEach(function() {
|
|
container.innerHTML = `
|
|
<canvas width=600 height=600 id=test></canvas>
|
|
<canvas width=600 height=600 id=report></canvas>`;
|
|
});
|
|
|
|
afterEach(function() {
|
|
container.innerHTML = '';
|
|
});
|
|
|
|
let notSerifFontBuffer = null;
|
|
// This font is known to support kerning
|
|
const notoSerifFontLoaded = fetch('/assets/NotoSerif-Regular.ttf').then(
|
|
(response) => response.arrayBuffer()).then(
|
|
(buffer) => {
|
|
notSerifFontBuffer = buffer;
|
|
});
|
|
|
|
let bungeeFontBuffer = null;
|
|
// This font has tofu for incorrect null terminators
|
|
// see https://bugs.chromium.org/p/skia/issues/detail?id=9314
|
|
const bungeeFontLoaded = fetch('/assets/Bungee-Regular.ttf').then(
|
|
(response) => response.arrayBuffer()).then(
|
|
(buffer) => {
|
|
bungeeFontBuffer = buffer;
|
|
});
|
|
|
|
it('can draw shaped and unshaped text', function(done) {
|
|
Promise.all([LoadCanvasKit, notoSerifFontLoaded]).then(catchException(done, () => {
|
|
// This is taken from example.html
|
|
const surface = CanvasKit.MakeCanvasSurface('test');
|
|
expect(surface).toBeTruthy('Could not make surface')
|
|
if (!surface) {
|
|
done();
|
|
return;
|
|
}
|
|
const canvas = surface.getCanvas();
|
|
const paint = new CanvasKit.SkPaint();
|
|
|
|
paint.setColor(CanvasKit.BLUE);
|
|
paint.setStyle(CanvasKit.PaintStyle.Stroke);
|
|
|
|
const fontMgr = CanvasKit.SkFontMgr.RefDefault();
|
|
const notoSerif = fontMgr.MakeTypefaceFromData(notSerifFontBuffer);
|
|
|
|
const textPaint = new CanvasKit.SkPaint();
|
|
const textFont = new CanvasKit.SkFont(notoSerif, 20);
|
|
|
|
canvas.drawRect(CanvasKit.LTRBRect(30, 30, 200, 200), paint);
|
|
canvas.drawText('This text is not shaped, and overflows the boundary',
|
|
35, 50, textPaint, textFont);
|
|
|
|
const shapedText = new CanvasKit.ShapedText({
|
|
font: textFont,
|
|
leftToRight: true,
|
|
text: 'This text *is* shaped, and wraps to the right width.',
|
|
width: 160,
|
|
});
|
|
const textBoxX = 35;
|
|
const textBoxY = 55;
|
|
canvas.drawText(shapedText, textBoxX, textBoxY, textPaint);
|
|
const bounds = shapedText.getBounds();
|
|
|
|
bounds.fLeft += textBoxX;
|
|
bounds.fRight += textBoxX;
|
|
bounds.fTop += textBoxY;
|
|
bounds.fBottom += textBoxY
|
|
|
|
canvas.drawRect(bounds, paint);
|
|
const SHAPE_TEST_TEXT = 'VAVAVAVAVAFIfi';
|
|
const textFont2 = new CanvasKit.SkFont(notoSerif, 60);
|
|
const shapedText2 = new CanvasKit.ShapedText({
|
|
font: textFont2,
|
|
leftToRight: true,
|
|
text: SHAPE_TEST_TEXT,
|
|
width: 600,
|
|
});
|
|
|
|
canvas.drawText('no kerning ↓', 10, 240, textPaint, textFont);
|
|
canvas.drawText(SHAPE_TEST_TEXT, 10, 300, textPaint, textFont2);
|
|
canvas.drawText(shapedText2, 10, 300, textPaint);
|
|
canvas.drawText('kerning ↑', 10, 390, textPaint, textFont);
|
|
|
|
surface.flush();
|
|
|
|
paint.delete();
|
|
notoSerif.delete();
|
|
textPaint.delete();
|
|
textFont.delete();
|
|
shapedText.delete();
|
|
textFont2.delete();
|
|
shapedText2.delete();
|
|
fontMgr.delete();
|
|
reportSurface(surface, 'text_shaping', done);
|
|
}));
|
|
});
|
|
|
|
it('can draw text following a path', function(done) {
|
|
LoadCanvasKit.then(catchException(done, () => {
|
|
const surface = CanvasKit.MakeCanvasSurface('test');
|
|
expect(surface).toBeTruthy('Could not make surface')
|
|
if (!surface) {
|
|
done();
|
|
return;
|
|
}
|
|
const canvas = surface.getCanvas();
|
|
const paint = new CanvasKit.SkPaint();
|
|
paint.setAntiAlias(true);
|
|
paint.setStyle(CanvasKit.PaintStyle.Stroke);
|
|
|
|
const font = new CanvasKit.SkFont(null, 24);
|
|
const fontPaint = new CanvasKit.SkPaint();
|
|
fontPaint.setAntiAlias(true);
|
|
fontPaint.setStyle(CanvasKit.PaintStyle.Fill);
|
|
|
|
|
|
const arc = new CanvasKit.SkPath();
|
|
arc.arcTo(CanvasKit.LTRBRect(20, 40, 280, 300), -160, 140, true);
|
|
arc.lineTo(210, 140);
|
|
arc.arcTo(CanvasKit.LTRBRect(20, 0, 280, 260), 160, -140, true);
|
|
|
|
// Only 1 dot should show up in the image, because we run out of path.
|
|
const str = 'This téxt should follow the curve across contours...';
|
|
const textBlob = CanvasKit.SkTextBlob.MakeOnPath(str, arc, font);
|
|
|
|
canvas.drawPath(arc, paint);
|
|
canvas.drawTextBlob(textBlob, 0, 0, fontPaint);
|
|
|
|
surface.flush();
|
|
|
|
textBlob.delete();
|
|
arc.delete();
|
|
paint.delete();
|
|
font.delete();
|
|
fontPaint.delete();
|
|
|
|
reportSurface(surface, 'monospace_text_on_path', done);
|
|
}));
|
|
});
|
|
|
|
it('can draw text following a path with a non-serif font', function(done) {
|
|
Promise.all([LoadCanvasKit, notoSerifFontLoaded]).then(catchException(done, () => {
|
|
const surface = CanvasKit.MakeCanvasSurface('test');
|
|
expect(surface).toBeTruthy('Could not make surface')
|
|
if (!surface) {
|
|
done();
|
|
return;
|
|
}
|
|
const fontMgr = CanvasKit.SkFontMgr.RefDefault();
|
|
const notoSerif = fontMgr.MakeTypefaceFromData(notSerifFontBuffer);
|
|
|
|
const canvas = surface.getCanvas();
|
|
const paint = new CanvasKit.SkPaint();
|
|
paint.setAntiAlias(true);
|
|
paint.setStyle(CanvasKit.PaintStyle.Stroke);
|
|
|
|
const font = new CanvasKit.SkFont(notoSerif, 24);
|
|
const fontPaint = new CanvasKit.SkPaint();
|
|
fontPaint.setAntiAlias(true);
|
|
fontPaint.setStyle(CanvasKit.PaintStyle.Fill);
|
|
|
|
|
|
const arc = new CanvasKit.SkPath();
|
|
arc.arcTo(CanvasKit.LTRBRect(20, 40, 280, 300), -160, 140, true);
|
|
arc.lineTo(210, 140);
|
|
arc.arcTo(CanvasKit.LTRBRect(20, 0, 280, 260), 160, -140, true);
|
|
|
|
const str = 'This téxt should follow the curve across contours...';
|
|
const textBlob = CanvasKit.SkTextBlob.MakeOnPath(str, arc, font, 60.5);
|
|
|
|
canvas.drawPath(arc, paint);
|
|
canvas.drawTextBlob(textBlob, 0, 0, fontPaint);
|
|
|
|
surface.flush();
|
|
|
|
textBlob.delete();
|
|
arc.delete();
|
|
paint.delete();
|
|
notoSerif.delete();
|
|
font.delete();
|
|
fontPaint.delete();
|
|
fontMgr.delete();
|
|
reportSurface(surface, 'serif_text_on_path', done);
|
|
}));
|
|
});
|
|
|
|
// https://bugs.chromium.org/p/skia/issues/detail?id=9314
|
|
it('does not draw tofu for null terminators at end of text', function(done) {
|
|
Promise.all([LoadCanvasKit, bungeeFontLoaded]).then(catchException(done, () => {
|
|
const surface = CanvasKit.MakeCanvasSurface('test');
|
|
expect(surface).toBeTruthy('Could not make surface')
|
|
if (!surface) {
|
|
done();
|
|
return;
|
|
}
|
|
const fontMgr = CanvasKit.SkFontMgr.RefDefault();
|
|
const bungee = fontMgr.MakeTypefaceFromData(bungeeFontBuffer);
|
|
|
|
const canvas = surface.getCanvas();
|
|
// yellow, to make sure tofu is plainly visible
|
|
canvas.clear(CanvasKit.Color(255, 255, 0, 1));
|
|
|
|
const font = new CanvasKit.SkFont(bungee, 24);
|
|
const fontPaint = new CanvasKit.SkPaint();
|
|
fontPaint.setAntiAlias(true);
|
|
fontPaint.setStyle(CanvasKit.PaintStyle.Fill);
|
|
|
|
|
|
const str = 'This is téxt';
|
|
const textBlob = CanvasKit.SkTextBlob.MakeFromText(str + ' text blob', font);
|
|
|
|
canvas.drawTextBlob(textBlob, 10, 50, fontPaint);
|
|
|
|
canvas.drawText(str + ' normal', 10, 100, fontPaint, font);
|
|
|
|
canvas.drawText('null terminator ->\u0000<- on purpose', 10, 150, fontPaint, font);
|
|
|
|
surface.flush();
|
|
|
|
textBlob.delete();
|
|
bungee.delete();
|
|
font.delete();
|
|
fontPaint.delete();
|
|
fontMgr.delete();
|
|
reportSurface(surface, 'nullterminators_skbug_9314', done);
|
|
}));
|
|
});
|
|
|
|
it('can make a font mgr with passed in fonts', function(done) {
|
|
Promise.all([LoadCanvasKit, bungeeFontLoaded, notoSerifFontLoaded]).then(catchException(done, () => {
|
|
const surface = CanvasKit.MakeCanvasSurface('test');
|
|
expect(surface).toBeTruthy('Could not make surface')
|
|
if (!surface) {
|
|
done();
|
|
return;
|
|
}
|
|
// CanvasKit.SkFontMgr.FromData([bungeeFontBuffer, notSerifFontBuffer]) also works
|
|
const fontMgr = CanvasKit.SkFontMgr.FromData(bungeeFontBuffer, notSerifFontBuffer);
|
|
expect(fontMgr).toBeTruthy();
|
|
expect(fontMgr.countFamilies()).toBe(2);
|
|
// in debug mode, let's list them.
|
|
if (fontMgr.dumpFamilies) {
|
|
fontMgr.dumpFamilies();
|
|
}
|
|
fontMgr.delete();
|
|
done();
|
|
}));
|
|
});
|
|
|
|
});
|