Search code examples
wpfskiaskiasharp

Draw rotated text in SkiaSharp


How to draw rotated text in SkiaSharp.

Currently I'm rotating the SKCanvas, drawing the text and then rotating it back. But I thought may be there is a more efficient way to do this.

canvas.RotateDegrees(45, 20, 20);
canvas.DrawText("Text", 20, 20, paint);
canvas.RotateDegrees(-45, 20, 20);

Solution

  • That is the correct way (the only way, I think).

    It is not that inefficient as you are not really rotating the canvas, but rather adjusting the drawing matrix (an int[9] array). Under the hood it is doing something like this:

    var m = SKMatrix.CreateRotation(45); // simple struct over int[9]
    canvas.CurrentMatrix.Concat(m)       // simple multiplication
    

    and then when you draw, it it just uses the matrix:

    canvas.DrawText(text, matrix);
    

    and when you rotate back, it just does the math again.

    Another way is to save the canvas and then restore:

    canvas.Save();
    canvas.Rotate(45);
    canvas.DrawText(text);
    canvas.Restore();
    

    This just makes a copy of the current matrix during the save. And when you restore, it just reverts it. This is a "better" way in that you can possible do a series of transformations, without having to reverse.

    Or, you can make use of a convenience type:

    // auto save
    using (new SKAutoCanvasRestore(canvas)) {
        // do any transformations
        canvas.Rotate(45);
        // do serious work
        canvas.DrawText(text);
        // auto restore, even on exceptions or errors
    }
    

    Another, totally different way to draw text, is to draw along a path:

    var path = new SKPath();
    // create path ...
    
    // draw using path
    canvas.DrawText("text", path, hOffset: 0, vOffset: 0, paint);