diff --git a/docker/frontend/shared/utils/skiaImage.ts b/docker/frontend/shared/utils/skiaImage.ts index 03a69ab..2883e18 100644 --- a/docker/frontend/shared/utils/skiaImage.ts +++ b/docker/frontend/shared/utils/skiaImage.ts @@ -56,7 +56,20 @@ export function rotateSkImageBy(image: SkImage | null, degrees: number): SkImage canvas.translate(w / 2, h / 2); canvas.rotate(degrees, 0, 0); canvas.scale(k, k); - canvas.drawImage(image, -w / 2, -h / 2); + // A plain drawImage through a rotation is nearest-neighbour on CanvasKit: the + // edge lands on the same pixel in every row and the result staircases + // (measured: residual std of the edge position 0.289 vs 0.048 filtered, see + // straighten-sampling-probe.cjs). Only the *Options/*Cubic call shapes take a + // sampling option, and `drawImageRectOptions` exists in RN Skia too, so the + // shared renderer stays portable. + canvas.drawImageRectOptions( + image, + Skia.XYWHRect(0, 0, w, h), + Skia.XYWHRect(-w / 2, -h / 2, w, h), + Skia.FilterMode.Linear, + Skia.MipmapMode.None, + null + ); return surface.makeImageSnapshot() ?? image; } finally { surface.dispose(); // see rotateSkImage90