UNPKG

@shopify/react-native-skia

Version:

High-performance React Native Graphics using Skia

73 lines (70 loc) 1.83 kB
import { isPathDef, processPath, processTransformProps2, } from "../../../dom/nodes"; import type { ClipDef, CTMProps } from "../../../dom/types"; import type { Skia, SkPath, SkRect, SkRRect } from "../../../skia/types"; import { ClipOp, isRRect } from "../../../skia/types"; import type { DrawingContext } from "../DrawingContext"; const computeClip = ( Skia: Skia, clip: ClipDef | undefined ): | undefined | { clipPath: SkPath } | { clipRect: SkRect } | { clipRRect: SkRRect } => { "worklet"; if (clip) { if (isPathDef(clip)) { return { clipPath: processPath(Skia, clip) }; } else if (isRRect(clip)) { return { clipRRect: clip }; } else { return { clipRect: clip }; } } return undefined; }; export const saveCTM = (ctx: DrawingContext, props: CTMProps) => { "worklet"; const { canvas, Skia } = ctx; const { clip: rawClip, invertClip, matrix, transform, origin, layer, } = props as CTMProps; const hasTransform = matrix !== undefined || transform !== undefined; const clip = computeClip(Skia, rawClip); const hasClip = clip !== undefined; const op = invertClip ? ClipOp.Difference : ClipOp.Intersect; const m3 = processTransformProps2(Skia, { matrix, transform, origin }); const shouldSave = hasTransform || hasClip || !!layer; if (shouldSave) { if (layer) { if (typeof layer === "boolean") { canvas.saveLayer(); } else { canvas.saveLayer(layer); } } else { canvas.save(); } } if (m3) { canvas.concat(m3); } if (clip) { if ("clipRect" in clip) { canvas.clipRect(clip.clipRect, op, true); } else if ("clipRRect" in clip) { canvas.clipRRect(clip.clipRRect, op, true); } else { canvas.clipPath(clip.clipPath, op, true); } } };