Skip to content

Commit

Permalink
Support lineHeightStyle alignment/topRatio
Browse files Browse the repository at this point in the history
  • Loading branch information
MatkovIvan committed Sep 16, 2024
1 parent 0b31013 commit 4db9062
Showing 1 changed file with 38 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,17 @@ private data class ComputedStyle(
var drawStyle: DrawStyle? = null,
var blendMode: BlendMode = DrawScope.DefaultBlendMode,
var lineHeight: Float? = null,
var topRatio: Float = -1f,
) {
constructor(
density: Density,
spanStyle: SpanStyle,
brushSize: Size = Size.Unspecified,
blendMode: BlendMode = DrawScope.DefaultBlendMode,
lineHeight: TextUnit,
lineHeightStyle: LineHeightStyle?,
) : this() {
set(density, spanStyle, brushSize, blendMode, lineHeight)
set(density, spanStyle, brushSize, blendMode, lineHeight, lineHeightStyle)
}

fun set(
Expand All @@ -120,6 +122,7 @@ private data class ComputedStyle(
brushSize: Size = Size.Unspecified,
blendMode: BlendMode = DrawScope.DefaultBlendMode,
lineHeight: TextUnit,
lineHeightStyle: LineHeightStyle?,
) {
this.textForegroundStyle = spanStyle.textForegroundStyle
this.brushSize = brushSize
Expand All @@ -144,6 +147,8 @@ private data class ComputedStyle(
this.lineHeight = if (lineHeight.isSpecified) {
lineHeight.toPx(density, spanStyle.fontSize)
} else null
val alignment = lineHeightStyle?.alignment ?: LineHeightStyle.Alignment.Proportional
this.topRatio = alignment.topRatio
}

private val _foregroundPaint = SkiaTextPaint()
Expand Down Expand Up @@ -214,6 +219,7 @@ private data class ComputedStyle(
lineHeight?.let {
res.height = it / fontSize
}
res.topRatio = topRatio

return res
}
Expand Down Expand Up @@ -274,7 +280,14 @@ internal class ParagraphBuilder(
initialStyle = textStyle.toSpanStyle().copyWithDefaultFontSize(
drawStyle = drawStyle
)
defaultStyle.set(density, initialStyle, brushSize, blendMode, textStyle.lineHeight)
defaultStyle.set(
density = density,
spanStyle = initialStyle,
brushSize = brushSize,
blendMode = blendMode,
lineHeight = textStyle.lineHeight,
lineHeightStyle = textStyle.lineHeightStyle,
)
}

fun updateForegroundPaint(paragraph: SkParagraph?) {
Expand Down Expand Up @@ -469,7 +482,14 @@ internal class ParagraphBuilder(

private fun mergeStyles(activeStyles: List<SpanStyle>): ComputedStyle {
// there is always at least one active style
val style = ComputedStyle(density, activeStyles[0], brushSize, blendMode, textStyle.lineHeight)
val style = ComputedStyle(
density = density,
spanStyle = activeStyles[0],
brushSize = brushSize,
blendMode = blendMode,
lineHeight = textStyle.lineHeight,
lineHeightStyle = textStyle.lineHeightStyle
)
for (i in 1 until activeStyles.size) {
style.merge(density, activeStyles[i])
}
Expand Down Expand Up @@ -519,8 +539,6 @@ internal class ParagraphBuilder(
pStyle.heightMode = HeightMode.DISABLE_ALL
}

// TODO: Support lineHeightStyle.alignment. Currently it's not exposed in skia

pStyle.direction = textDirection.toSkDirection()
textStyle.textIndent?.run {
with(density) {
Expand All @@ -544,12 +562,22 @@ internal class ParagraphBuilder(
// workaround for https://bugs.chromium.org/p/skia/issues/detail?id=11321 :(
internal fun emptyLineMetrics(paragraph: SkParagraph): Array<LineMetrics> {
val metrics = defaultFont.metrics
val heightMultiplier = defaultStyle.lineHeight?.let {
it / defaultStyle.fontSize.toDouble()
} ?: 1.0
val ascent = metrics.ascent * heightMultiplier // TODO: Support non-proportional alignment
val descent = metrics.descent * heightMultiplier // TODO: Support non-proportional alignment
var ascent = metrics.ascent.toDouble()
var descent = metrics.descent.toDouble()
val baseline = paragraph.alphabeticBaseline.toDouble()
val lineHeight = defaultStyle.lineHeight
if (lineHeight != null) {
val topRatio = defaultStyle.topRatio
if (topRatio in 0.0f..1.0f) {
val extraLeading = lineHeight - defaultStyle.fontSize
ascent -= extraLeading * topRatio
descent += extraLeading * (1.0f - topRatio)
} else {
val multiplier = lineHeight / defaultStyle.fontSize
ascent *= multiplier
descent *= multiplier
}
}
val height = descent - ascent
return arrayOf(
LineMetrics(
Expand Down

0 comments on commit 4db9062

Please sign in to comment.