static Layout createTextLayout()

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();
  }