From 9321c2cd39ec05fcc45ab2e13be666d23e81eb2f Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Mon, 6 Jul 2026 03:24:40 +0900 Subject: [PATCH] fix(widget): round iOS cover thumbnail size to whole pixels (#4950) The iOS reading widget downsampled covers to a fractional target size. UIGraphicsImageRenderer allocates a whole-pixel buffer while draw(in:) fills only the exact fractional rect, so for portrait covers whose scaled width rounds up the rightmost pixel column was left partially covered and semi-transparent. Encoded to JPEG that column flattened into a visible bright hairline along the right edge (intermittent, portrait covers only). Round both target dimensions to whole pixels so the draw rect matches the pixel buffer and every edge pixel is fully covered. Android is unaffected because it scales to a fixed 240x360 and center-crops. Co-authored-by: Claude Fable 5 --- .../ios/Sources/ReadingWidgetWriter.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/ios/Sources/ReadingWidgetWriter.swift b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/ios/Sources/ReadingWidgetWriter.swift index d4dd3194..7172822c 100644 --- a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/ios/Sources/ReadingWidgetWriter.swift +++ b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/ios/Sources/ReadingWidgetWriter.swift @@ -41,7 +41,13 @@ enum ReadingWidgetWriter { } let longEdge = max(image.size.width, image.size.height) let scale = longEdge > thumbMaxPixels ? thumbMaxPixels / longEdge : 1 - let target = CGSize(width: image.size.width * scale, height: image.size.height * scale) + // Round to whole pixels: the renderer allocates a whole-pixel buffer, so a + // fractional target would leave the trailing pixel column/row only partially + // covered (semi-transparent). Flattened into JPEG that shows up as a bright + // hairline along the right/bottom edge. Whole-pixel target == full coverage. + let target = CGSize( + width: (image.size.width * scale).rounded(), + height: (image.size.height * scale).rounded()) let format = UIGraphicsImageRendererFormat() format.scale = 1.0 let renderer = UIGraphicsImageRenderer(size: target, format: format)