Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import com.swmansion.enriched.common.pixelFromSpOrDp
import com.swmansion.enriched.text.spans.EnrichedTextImageSpan
import com.swmansion.enriched.text.spans.interfaces.EnrichedTextClickableSpan
import com.swmansion.enriched.text.spans.interfaces.EnrichedTextSpan
import com.swmansion.enriched.textinput.spans.EnrichedLineHeightSpan
import kotlin.math.ceil

class EnrichedTextView : AppCompatTextView {
Expand All @@ -41,13 +42,15 @@ class EnrichedTextView : AppCompatTextView {
private var fontWeight: Int = ReactConstants.UNSET
private var fontSize: Float = EnrichedConstants.TEXT_DEFAULT_FONT_SIZE
private var fontSizeRaw: Float? = null
private var lineHeight: Float? = null
private var htmlStyleMap: ReadableMap? = null
var allowFontScaling: Boolean = EnrichedConstants.ALLOW_FONT_SCALING_DEFAULT
set(value) {
if (field == value) return
field = value
fontSizeRaw?.let { setFontSize(it) }
htmlStyleMap?.let { setHtmlStyle(it) }
applyLineSpacing()
}

private var enrichedStyle: EnrichedTextStyle? = null
Expand Down Expand Up @@ -185,6 +188,7 @@ class EnrichedTextView : AppCompatTextView {
parsedText = null
this.text = text
}
applyLineSpacing()
}

private fun parseText(
Expand Down Expand Up @@ -305,6 +309,33 @@ class EnrichedTextView : AppCompatTextView {
setTextSize(TypedValue.COMPLEX_UNIT_PX, sizeInt)
}

fun setLineHeight(height: Float) {
lineHeight = if (height == 0f) null else height

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
lineHeight = if (height == 0f) null else height
lineHeight = if (height <= 0f) null else height

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I've noticed the same change would be applicable in EnrichedTextInputView.kt

applyLineSpacing()
}

private fun applyLineSpacing() {
val currentText = text ?: return
val spannable =
currentText as? Spannable ?: SpannableString(currentText)
spannable
.getSpans(0, spannable.length, EnrichedLineHeightSpan::class.java)
.forEach { spannable.removeSpan(it) }

lineHeight?.let {
spannable.setSpan(
EnrichedLineHeightSpan(it, allowFontScaling),
0,
spannable.length,
Spannable.SPAN_INCLUSIVE_INCLUSIVE,
)
}

if (spannable !== currentText) {
setText(spannable, BufferType.SPANNABLE)
}
}

fun setFontFamily(family: String?) {
if (family != fontFamily) {
fontFamily = family
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ class EnrichedTextViewManager :
view?.setFontSize(value)
}

override fun setLineHeight(
view: EnrichedTextView?,
value: Float,
) {
view?.setLineHeight(value)
}

override fun setFontFamily(
view: EnrichedTextView?,
value: String?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import android.content.Context
import android.graphics.Typeface
import android.graphics.text.LineBreaker
import android.os.Build
import android.text.Spannable
import android.text.SpannableString
import android.text.StaticLayout
import android.text.TextPaint
import android.text.TextUtils
Expand All @@ -21,6 +23,7 @@ import com.swmansion.enriched.common.GumboNormalizer
import com.swmansion.enriched.common.allowFontScalingFromProps
import com.swmansion.enriched.common.parser.EnrichedParser
import com.swmansion.enriched.common.pixelFromSpOrDp
import com.swmansion.enriched.textinput.spans.EnrichedLineHeightSpan
import kotlin.math.ceil

object MeasurementStore {
Expand Down Expand Up @@ -134,6 +137,13 @@ object MeasurementStore {
return props.getBoolean("useHtmlNormalizer")
}

private fun lineHeightFromProps(props: ReadableMap?): Float {
if (props == null || !props.hasKey("lineHeight") || props.isNull("lineHeight")) {
return 0f
}
return props.getDouble("lineHeight").toFloat()
}

private fun getInitialFontSize(props: ReadableMap?): Float {
val propsFontSize = props?.getDouble("fontSize")?.toFloat() ?: EnrichedConstants.TEXT_DEFAULT_FONT_SIZE
val fontSize =
Expand All @@ -151,15 +161,31 @@ object MeasurementStore {
props: ReadableMap?,
): Long {
val fontSize = getInitialFontSize(props)
val text = getInitialText(context, fontSize.toInt(), props)
val rawText = getInitialText(context, fontSize.toInt(), props)
val lineHeight = lineHeightFromProps(props)
val allowFontScaling = allowFontScalingFromProps(props)

val measuredText: CharSequence =
if (lineHeight > 0f) {
val spannable = SpannableString(rawText)
spannable.setSpan(
EnrichedLineHeightSpan(lineHeight, allowFontScaling),
0,
spannable.length,
Spannable.SPAN_INCLUSIVE_INCLUSIVE,
)
spannable
} else {
rawText
}

val fontFamily = props?.getString("fontFamily")
val numberOfLines = props?.getInt("numberOfLines") ?: 0
val ellipsizeMode = props?.getString("ellipsizeMode")
val fontStyle = parseFontStyle(props?.getString("fontStyle"))
val fontWeight = parseFontWeight(props?.getString("fontWeight"))
val typeface = applyStyles(null, fontStyle, fontWeight, fontFamily, context.assets)
val size = measure(width, text, typeface, fontSize, numberOfLines, ellipsizeMode)
val size = measure(width, measuredText, typeface, fontSize, numberOfLines, ellipsizeMode)

return size
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@ class EnrichedLineHeightSpan(
v: Int,
fm: Paint.FontMetricsInt,
) {
val spannable = text as? Spannable ?: return
// Do not modify line height for headings
// In the future we may consider adding custom lineHeight support for each paragraph style
if (spannable.getSpans(start, end, EnrichedHeadingSpan::class.java).isNotEmpty()) return

val lineHeightPx = pixelFromSpOrDp(lineHeight, allowFontScaling)
val currentHeight = (fm.descent - fm.ascent).toFloat()
if (lineHeightPx <= currentHeight) return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ inline folly::dynamic toDynamic(const EnrichedTextViewProps &props) {
serializedProps["fontWeight"] = props.fontWeight;
serializedProps["fontStyle"] = props.fontStyle;
serializedProps["fontFamily"] = props.fontFamily;
serializedProps["lineHeight"] = props.lineHeight;
serializedProps["numberOfLines"] = props.numberOfLines;
serializedProps["ellipsizeMode"] = props.ellipsizeMode;
serializedProps["allowFontScaling"] = props.allowFontScaling;
Expand Down
6 changes: 6 additions & 0 deletions ios/EnrichedTextView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,12 @@ - (void)updateProps:(Props::Shared const &)props
stylePropChanged = YES;
}

// lineHeight
if (newViewProps.lineHeight != oldViewProps.lineHeight) {
[newConfig setPrimaryLineHeight:newViewProps.lineHeight];
stylePropChanged = YES;
}

// fontWeight
if (newViewProps.fontWeight != oldViewProps.fontWeight) {
if (!newViewProps.fontWeight.empty()) {
Expand Down
1 change: 1 addition & 0 deletions src/spec/EnrichedTextNativeComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export interface NativeProps extends ViewProps {
// These should not be passed as regular props
color?: ColorValue;
fontSize?: Float;
lineHeight?: Float;
fontFamily?: string;
fontWeight?: string;
fontStyle?: string;
Expand Down
Loading