Compare commits

..
1 Commits
Author SHA1 Message Date
TZGyn 26700c59f4 Make exported stroke thickness match the preview
Strokes were sized in view points but exported in image pixels, so on
retina captures the saved/copied annotation looked several times thinner.
Stroke widths are now converted into image pixels when drawn and scaled
back for the preview, keeping preview and export identical.

💘 Generated with Crush

Assisted-by: Crush:deepseek-v4-flash-0731
2026-09-23 17:28:38 +08:00
2 changed files with 11 additions and 9 deletions
+9 -7
View File
@@ -195,14 +195,15 @@ final class CaptureModel: ObservableObject {
return rep.cgImage ?? image
}
func addStroke(_ points: [CGPoint]) {
/// `widthPx` is the stroke thickness in IMAGE PIXELS (the preview
/// converts the slider value so exports match what was drawn).
func addStroke(_ points: [CGPoint], widthPx: CGFloat) {
guard points.count > 1 else { return }
if tool == .redact {
// Redaction: a filled black bar from start to end, as thick as the
// current stroke width (drawn as a rect for clean edges).
strokes.append(Stroke(points: points, width: max(strokeWidth, 12), color: .black, isRedaction: true))
// Redaction: a filled black bar from start to end.
strokes.append(Stroke(points: points, width: max(widthPx, 12), color: .black, isRedaction: true))
} else {
strokes.append(Stroke(points: points, width: strokeWidth, color: drawColor))
strokes.append(Stroke(points: points, width: widthPx, color: drawColor))
}
redoStack = []
}
@@ -575,7 +576,8 @@ struct ScreenshotPane: View {
for point in stroke.points.dropFirst() {
path.addLine(to: CGPoint(x: origin.x + point.x * scale, y: origin.y + point.y * scale))
}
context.stroke(path, with: .color(Color(nsColor: stroke.color)), lineWidth: stroke.width)
// stroke.width is in image pixels; scale to view points
context.stroke(path, with: .color(Color(nsColor: stroke.color)), lineWidth: stroke.width * scale)
}
}
}
@@ -636,7 +638,7 @@ struct ScreenshotPane: View {
.onEnded { _ in
if model.tool != .select {
if currentStroke.count > 1 {
model.addStroke(currentStroke)
model.addStroke(currentStroke, widthPx: model.strokeWidth / max(scale, 0.01))
}
currentStroke = []
} else {
+2 -2
View File
@@ -108,9 +108,9 @@ cat > "$APP/Contents/Info.plist" <<'PLIST'
<key>CFBundleIconFile</key>
<string>Icon</string>
<key>CFBundleShortVersionString</key>
<string>1.9.1</string>
<string>1.9.2</string>
<key>CFBundleVersion</key>
<string>91</string>
<string>92</string>
<key>LSUIElement</key>
<true/>
<key>NSHighResolutionCapable</key>