Canvas-kit text rendering on high-DPI devices

157 views
Skip to first unread message

Denis Rochette

unread,
Oct 15, 2023, 12:31:10 PM10/15/23
to skia-discuss
Hi,

I'm trying to display some text using canvas-kit on my retina screen (window.devicePixelRatio=2). But given a fixed font, the rendering on the canvas-kit canvas is very different from the same text in a <div> with the same font (see image).

I think there's something very basic I don't understand.

Here's the code that compares canvas-kit's canvas, a simple <div> and an html <canvas>:
<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Handlee">
  <script src="https://unpkg.com/canvaskit-wasm@latest/bin/canvaskit.js"></script>
</head>
<body>
  <div>Skia:</div>
  <canvas id="skiaCanvas" width="200" height="30"></canvas>
  <div>HTML:</div>
  <div style='font-size: 24pt; font-family: "Handlee";'>Lorem ipsum</div>
  <div>Canvas:</div>
  <canvas id="htmlCanvas" width="200" height="30"></canvas>
  <script>
    dpr = window.devicePixelRatio;

    loadFont = fetch('https://fonts.gstatic.com/s/handlee/v18/-F6xfjBsISg9aMakPm3wowtKzig.woff2').then((response) => response.arrayBuffer());
    ckLoaded = CanvasKitInit({locateFile: (file) => 'https://unpkg.com/canvaskit-wasm@latest/bin/'+file});
 
    Promise.all([ckLoaded, loadFont]).then(([CanvasKit, handleeData]) => {
        // Skia Canvas
        skiaCanvas = document.getElementById("skiaCanvas");
        skiaCanvasRect = skiaCanvas.getBoundingClientRect();

        skiaCanvas.width = skiaCanvasRect.width * dpr;
        skiaCanvas.height = skiaCanvasRect.height  * dpr;
        skiaCanvas.style.width = skiaCanvasRect.width + 'px';
        skiaCanvas.style.height = skiaCanvasRect.height + 'px';

        skiaSurface = CanvasKit.MakeSWCanvasSurface(skiaCanvas);
        skiaCanvas = skiaSurface.getCanvas();
       
       
        typeFace = CanvasKit.Typeface.MakeFreeTypeFaceFromData(handleeData);
        font = new CanvasKit.Font(typeFace, 24);
        paint = new CanvasKit.Paint();
       
        paint.setColor(CanvasKit.BLACK);
       
        skiaCanvas.scale(dpr, dpr);
        skiaCanvas.clear(CanvasKit.WHITE);
        skiaCanvas.drawText("Lorem ipsum", 0, 25, paint, font);
        skiaSurface.flush();

        // HTML Canvas
        htmlCanvas = document.getElementById("htmlCanvas");
        htmlCanvasRect = htmlCanvas.getBoundingClientRect();
   
        htmlCanvas.width = htmlCanvasRect.width * dpr;
        htmlCanvas.height = htmlCanvasRect.height * dpr;
        htmlCanvas.style.width = htmlCanvasRect.width + "px";
        htmlCanvas.style.height = htmlCanvasRect.height + "px";
   
        ctx = htmlCanvas.getContext("2d");
       
        ctx.scale(dpr, dpr);
        ctx.font = '24pt "Handlee"';
        ctx.fillText("Lorem ipsum", 0, 25);
    });
  </script>
</body>
</html>

(I've simplified my problem here, but ideally I'd like to use canvas.drawGlyphs() for my project)

Capture d’écran 2023-10-15 à 00.06.00.png

Ivan Espinosa

unread,
Apr 9, 2024, 3:47:12 PMApr 9
to skia-discuss
Hi,
Im facing the same issue. Where you able to find how to fix it?

Denis Rochette

unread,
May 19, 2024, 9:00:50 PM (10 days ago) May 19
to skia-discuss
hi,
No, I haven't tried in a while, but I wonder if it's just skia and the browser displaying the font differently for some reason.
Have you fixed it?

Reply all
Reply to author
Forward
0 new messages