From 316b10d015f1cb44c5426e7d4f3fa7e8ea4e8ef4 Mon Sep 17 00:00:00 2001 From: sergeych Date: Sun, 24 May 2026 08:57:44 +0300 Subject: [PATCH] nice border around images in the dark theme --- .../net/sergeych/toread/ReaderContent.kt | 68 ++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/composeApp/src/commonMain/kotlin/net/sergeych/toread/ReaderContent.kt b/composeApp/src/commonMain/kotlin/net/sergeych/toread/ReaderContent.kt index 81282c6..53ee16d 100644 --- a/composeApp/src/commonMain/kotlin/net/sergeych/toread/ReaderContent.kt +++ b/composeApp/src/commonMain/kotlin/net/sergeych/toread/ReaderContent.kt @@ -43,8 +43,13 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.BlendMode +import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.CompositingStrategy import androidx.compose.ui.graphics.StrokeCap +import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.input.pointer.PointerEventPass import androidx.compose.ui.input.pointer.PointerType import androidx.compose.ui.input.pointer.pointerInput @@ -81,6 +86,7 @@ import net.sergeych.toread.fb2.Fb2TextSpan import net.sergeych.toread.fb2.Fb2TextStyle import net.sergeych.toread.text.HyphenationRegistry import net.sergeych.toread.text.SoftHyphen +import kotlin.math.min import kotlinx.coroutines.launch import kotlin.math.max import kotlin.math.min @@ -579,6 +585,8 @@ private fun BookImage( } val imageTitle = image?.alt?.ifBlank { null } ?: book.title val imageBackgroundColor = readerImageBackgroundColor() + val imageShape = RoundedCornerShape(8.dp) + val smoothImageEdges = imageBackgroundColor != MaterialTheme.colorScheme.surface val density = LocalDensity.current BoxWithConstraints( modifier = modifier @@ -612,7 +620,12 @@ private fun BookImage( } else { Modifier.fillMaxSize() } - Box(imageModifier.background(imageBackgroundColor)) { + Box( + imageModifier + .then(if (smoothImageEdges) Modifier.softImageEdgeFade() else Modifier) + .clip(imageShape) + .background(imageBackgroundColor), + ) { Image( bitmap = bitmap, contentDescription = imageTitle, @@ -626,6 +639,59 @@ private fun BookImage( } } +private fun Modifier.softImageEdgeFade(): Modifier = + graphicsLayer { + compositingStrategy = CompositingStrategy.Offscreen + }.drawWithContent { + drawContent() + + val fade = min(8.dp.toPx(), min(size.width, size.height) / 4f) + if (fade <= 0f) return@drawWithContent + + drawRect( + brush = Brush.verticalGradient( + 0f to Color.Transparent, + 1f to Color.Black, + startY = 0f, + endY = fade, + ), + size = Size(size.width, fade), + blendMode = BlendMode.DstIn, + ) + drawRect( + brush = Brush.verticalGradient( + 0f to Color.Black, + 1f to Color.Transparent, + startY = size.height - fade, + endY = size.height, + ), + topLeft = Offset(0f, size.height - fade), + size = Size(size.width, fade), + blendMode = BlendMode.DstIn, + ) + drawRect( + brush = Brush.horizontalGradient( + 0f to Color.Transparent, + 1f to Color.Black, + startX = 0f, + endX = fade, + ), + size = Size(fade, size.height), + blendMode = BlendMode.DstIn, + ) + drawRect( + brush = Brush.horizontalGradient( + 0f to Color.Black, + 1f to Color.Transparent, + startX = size.width - fade, + endX = size.width, + ), + topLeft = Offset(size.width - fade, 0f), + size = Size(fade, size.height), + blendMode = BlendMode.DstIn, + ) + } + private fun Fb2Text.toAnnotatedString( language: String?, hyphenation: HyphenationRegistry,