From de642ad692564510ca8aa05afcaa1678a1a5aa3b Mon Sep 17 00:00:00 2001 From: TZGyn Date: Mon, 24 Aug 2026 09:08:37 +0800 Subject: [PATCH] Fix flipped drawing when copying/saving annotated images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The strokes were stored in top-left image coordinates but drawn into an AppKit CGContext with a bottom-left origin, so exports came out mirrored and offset. Flip Y in the context before stroking so annotations land where they were drawn. 💘 Generated with Crush Assisted-by: Crush:deepseek-v4-flash-0731 --- Sources/Kapture/ResultWindow.swift | 7 +++++++ build-app.sh | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Sources/Kapture/ResultWindow.swift b/Sources/Kapture/ResultWindow.swift index 0530f92..5639d65 100644 --- a/Sources/Kapture/ResultWindow.swift +++ b/Sources/Kapture/ResultWindow.swift @@ -149,6 +149,12 @@ final class CaptureModel: ObservableObject { let ctx = NSGraphicsContext.current!.cgContext // CGImage draws with a flipped Y in NSGraphicsContext ctx.draw(image, in: NSRect(origin: .zero, size: size)) + // Strokes are stored in TOP-LEFT image coordinates (from the SwiftUI + // canvas), but the CGContext uses a BOTTOM-LEFT origin. Flip Y so the + // strokes land where they were drawn. + ctx.saveGState() + ctx.translateBy(x: 0, y: size.height) + ctx.scaleBy(x: 1, y: -1) ctx.setLineCap(.round) ctx.setLineJoin(.round) for stroke in strokes { @@ -162,6 +168,7 @@ final class CaptureModel: ObservableObject { } ctx.strokePath() } + ctx.restoreGState() NSGraphicsContext.restoreGraphicsState() return rep.cgImage ?? image } diff --git a/build-app.sh b/build-app.sh index 84b7f90..d05b6ff 100755 --- a/build-app.sh +++ b/build-app.sh @@ -108,9 +108,9 @@ cat > "$APP/Contents/Info.plist" <<'PLIST' CFBundleIconFile Icon CFBundleShortVersionString - 1.4.2 + 1.4.3 CFBundleVersion - 42 + 43 LSUIElement NSHighResolutionCapable