hyphenate text fix for desktop
This commit is contained in:
parent
3fd6606077
commit
14c9863a83
@ -26,15 +26,22 @@ import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
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.graphics.Color
|
||||
import androidx.compose.ui.graphics.StrokeCap
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.TextLayoutResult
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
@ -48,6 +55,7 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextDecoration
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.isSpecified
|
||||
import androidx.compose.ui.unit.sp
|
||||
import net.sergeych.toread.fb2.Fb2Block
|
||||
import net.sergeych.toread.fb2.Fb2Book
|
||||
@ -57,6 +65,9 @@ import net.sergeych.toread.fb2.Fb2Text
|
||||
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.max
|
||||
import kotlin.math.min
|
||||
|
||||
@Composable
|
||||
internal fun ContinuousBookReader(
|
||||
@ -343,11 +354,50 @@ private fun ReaderText(
|
||||
textAlign: TextAlign,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val annotatedText = text.toAnnotatedString(language, hyphenation)
|
||||
val needsSoftHyphenPaintWorkaround = isDesktopPlatform()
|
||||
var textLayout by remember(annotatedText) { mutableStateOf<TextLayoutResult?>(null) }
|
||||
val desktopHyphenColor = MaterialTheme.colorScheme.onSurface
|
||||
val desktopHyphenGutter = 8.dp
|
||||
val textModifier = modifier
|
||||
.fillMaxWidth()
|
||||
.then(
|
||||
if (needsSoftHyphenPaintWorkaround) {
|
||||
Modifier.drawWithContent {
|
||||
drawContent()
|
||||
|
||||
val layout = textLayout ?: return@drawWithContent
|
||||
val layoutText = layout.layoutInput.text.text
|
||||
val fontSizePx = if (style.fontSize.isSpecified) style.fontSize.toPx() else 18.sp.toPx()
|
||||
val hyphenLength = fontSizePx * 0.36f
|
||||
val strokeWidth = max(1f, fontSizePx * 0.055f)
|
||||
|
||||
for (line in 0 until layout.lineCount) {
|
||||
if (!layout.endsAtSoftHyphen(layoutText, line)) continue
|
||||
|
||||
val lineRight = layout.getLineRight(line)
|
||||
val x = min(lineRight + hyphenLength * 0.12f, size.width - hyphenLength)
|
||||
val y = layout.getLineBaseline(line) - fontSizePx * 0.32f
|
||||
drawLine(
|
||||
color = desktopHyphenColor,
|
||||
start = Offset(x, y),
|
||||
end = Offset(x + hyphenLength, y),
|
||||
strokeWidth = strokeWidth,
|
||||
cap = StrokeCap.Square,
|
||||
)
|
||||
}
|
||||
}.padding(end = desktopHyphenGutter)
|
||||
} else {
|
||||
Modifier
|
||||
},
|
||||
)
|
||||
|
||||
Text(
|
||||
text = text.toAnnotatedString(language, hyphenation),
|
||||
text = annotatedText,
|
||||
style = style,
|
||||
textAlign = textAlign,
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
modifier = textModifier,
|
||||
onTextLayout = { textLayout = it },
|
||||
)
|
||||
}
|
||||
|
||||
@ -364,6 +414,14 @@ private fun readerParagraphTextStyle(language: String?): TextStyle =
|
||||
private fun isAndroidPlatform(): Boolean =
|
||||
getPlatform().name.startsWith("Android")
|
||||
|
||||
private fun isDesktopPlatform(): Boolean =
|
||||
getPlatform().name.startsWith("Java")
|
||||
|
||||
private fun TextLayoutResult.endsAtSoftHyphen(text: String, line: Int): Boolean {
|
||||
val end = getLineEnd(line, visibleEnd = false)
|
||||
return text.getOrNull(end - 1) == SoftHyphen || text.getOrNull(end) == SoftHyphen
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BookImage(
|
||||
book: Fb2Book,
|
||||
|
||||
@ -11,13 +11,13 @@ androidx-lifecycle = "2.10.0"
|
||||
androidx-testExt = "1.3.0"
|
||||
composeHotReload = "1.1.0"
|
||||
composeMaterialIcons = "1.7.3"
|
||||
composeMultiplatform = "1.10.3"
|
||||
composeMultiplatform = "1.11.0"
|
||||
junit = "4.13.2"
|
||||
kotlin = "2.3.21"
|
||||
kotlinx-coroutines = "1.10.2"
|
||||
ktor = "3.4.3"
|
||||
logback = "1.5.32"
|
||||
material3 = "1.10.0-alpha05"
|
||||
material3 = "1.11.0-alpha07"
|
||||
h2 = "2.4.240"
|
||||
|
||||
[libraries]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user