in litho-rendercore-text/src/main/java/com/facebook/rendercore/text/TextMeasurementUtils.java [203:336]
static Layout createTextLayout(
Context context, TextStyle textStyle, int widthSpec, int heightSpec, CharSequence text) {
TextLayoutBuilder layoutBuilder = new TextLayoutBuilder();
layoutBuilder.setShouldCacheLayout(false);
@TextLayoutBuilder.MeasureMode final int textMeasureMode;
switch (View.MeasureSpec.getMode(widthSpec)) {
case View.MeasureSpec.UNSPECIFIED:
textMeasureMode = TextLayoutBuilder.MEASURE_MODE_UNSPECIFIED;
break;
case View.MeasureSpec.EXACTLY:
textMeasureMode = TextLayoutBuilder.MEASURE_MODE_EXACTLY;
break;
case View.MeasureSpec.AT_MOST:
textMeasureMode = TextLayoutBuilder.MEASURE_MODE_AT_MOST;
break;
default:
throw new IllegalStateException(
"Unexpected size mode: " + View.MeasureSpec.getMode(widthSpec));
}
final TextUtils.TruncateAt actualEllipsize;
if (textStyle.ellipsize == null && textStyle.maxLines != Integer.MAX_VALUE) {
// On recent apis (> 24) max lines is no longer considered for calculating layout height if an
// ellipsize method isn't specified. To keep consistent behavior across platforms we default
// to end if you specify maxLines but not ellipsize.
actualEllipsize = TextUtils.TruncateAt.END;
} else {
actualEllipsize = textStyle.ellipsize;
}
final boolean includeFontPadding = textStyle.includeFontPadding && !hasManualSpacing(textStyle);
layoutBuilder
.setDensity(context.getResources().getDisplayMetrics().density)
.setEllipsize(actualEllipsize)
.setMaxLines(textStyle.maxLines)
.setShadowLayer(
textStyle.shadowRadius, textStyle.shadowDx, textStyle.shadowDy, textStyle.shadowColor)
.setSingleLine(textStyle.isSingleLine)
.setText(text)
.setTextSize(textStyle.textSize)
.setWidth(View.MeasureSpec.getSize(widthSpec), textMeasureMode)
.setIncludeFontPadding(includeFontPadding)
.setTextSpacingExtra(textStyle.extraSpacing)
.setTextSpacingMultiplier(textStyle.spacingMultiplier)
.setLinkColor(textStyle.linkColor)
.setJustificationMode(textStyle.justificationMode)
.setBreakStrategy(textStyle.breakStrategy)
.setHyphenationFrequency(textStyle.hyphenationFrequency)
.setShouldLayoutZeroLengthText(textStyle.shouldLayoutEmptyText);
if (textStyle.lineHeight != Float.MAX_VALUE) {
layoutBuilder.setLineHeight(textStyle.lineHeight);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
layoutBuilder.setLetterSpacing(textStyle.letterSpacing);
}
if (textStyle.minEms != TextStyle.UNSET) {
layoutBuilder.setMinEms(textStyle.minEms);
} else {
layoutBuilder.setMinWidth(textStyle.minTextWidth);
}
if (textStyle.maxEms != TextStyle.UNSET) {
layoutBuilder.setMaxEms(textStyle.maxEms);
} else {
layoutBuilder.setMaxWidth(textStyle.maxTextWidth);
}
if (textStyle.textColor != 0) {
layoutBuilder.setTextColor(textStyle.textColor);
} else {
layoutBuilder.setTextColor(textStyle.textColorStateList);
}
if (textStyle.typeface != null) {
layoutBuilder.setTypeface(textStyle.typeface);
} else {
layoutBuilder.setTextStyle(textStyle.textStyle);
}
final boolean isRTL = LayoutUtils.isLayoutDirectionRTL(context);
if (textStyle.textDirection == null) {
textStyle.textDirection =
isRTL
? TextDirectionHeuristicsCompat.FIRSTSTRONG_RTL
: TextDirectionHeuristicsCompat.FIRSTSTRONG_LTR;
}
layoutBuilder.setTextDirection(textStyle.textDirection);
final Layout.Alignment textAlignment;
final boolean textIsRTL;
switch (textStyle.alignment) {
default:
case TEXT_START:
textAlignment = Layout.Alignment.ALIGN_NORMAL;
break;
case TEXT_END:
textAlignment = Layout.Alignment.ALIGN_OPPOSITE;
break;
case LAYOUT_START:
textIsRTL = (textStyle.textDirection.isRtl(text, 0, text.length()));
textAlignment =
(isRTL == textIsRTL) ? Layout.Alignment.ALIGN_NORMAL : Layout.Alignment.ALIGN_OPPOSITE;
break;
case LAYOUT_END:
textIsRTL = (textStyle.textDirection.isRtl(text, 0, text.length()));
textAlignment =
(isRTL == textIsRTL) ? Layout.Alignment.ALIGN_OPPOSITE : Layout.Alignment.ALIGN_NORMAL;
break;
case LEFT:
textAlignment =
textStyle.textDirection.isRtl(text, 0, text.length())
? Layout.Alignment.ALIGN_OPPOSITE
: Layout.Alignment.ALIGN_NORMAL;
break;
case RIGHT:
textAlignment =
textStyle.textDirection.isRtl(text, 0, text.length())
? Layout.Alignment.ALIGN_NORMAL
: Layout.Alignment.ALIGN_OPPOSITE;
break;
case CENTER:
textAlignment = Layout.Alignment.ALIGN_CENTER;
break;
}
layoutBuilder.setAlignment(textAlignment);
return layoutBuilder.build();
}