android.text.style.LeadingMarginSpan Java Examples

The following examples show how to use android.text.style.LeadingMarginSpan. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: UtilitiesTest.java    From google-authenticator-android with Apache License 2.0 6 votes vote down vote up
@Test
public void testGetStyledTextFromHtmlWithInputWithBulletList() {
  assertThat(
          Utilities.getStyledTextFromHtml(
              "<ul><li>First<li><li>Second</li><li>Third<li></ul>End").toString())
      .isEqualTo("\n\nFirst\nSecond\nThird\n\nEnd");

  Spanned result = Utilities.getStyledTextFromHtml(
      "Some items:<ul>\n<li>First<li><li>Second</li>\n<li>Third<li>\n\n</ul>End");
  assertThat(result.toString()).isEqualTo("Some items:\n\nFirst\nSecond\nThird\n\nEnd");

  BulletSpan[] bulletSpans = result.getSpans(0, result.length(), BulletSpan.class);
  assertThat(bulletSpans).hasLength(3);
  assertSpanLocation(bulletSpans[0], result, 13, 19);
  assertSpanLocation(bulletSpans[1], result, 19, 26);
  assertSpanLocation(bulletSpans[2], result, 26, 32);

  LeadingMarginSpan.Standard[] leadingMarginSpans =
      result.getSpans(0, result.length(), LeadingMarginSpan.Standard.class);
  assertThat(bulletSpans).hasLength(3);
  assertSpanLocation(leadingMarginSpans[0], result, 13, 19);
  assertSpanLocation(leadingMarginSpans[1], result, 19, 26);
  assertSpanLocation(leadingMarginSpans[2], result, 26, 32);
}
 
Example #2
Source File: MarkdownBuilderTest.java    From user-interface-samples with Apache License 2.0 6 votes vote down vote up
@Test
public void textWithQuote() {
    SpannedString result = builder.markdownToSpans("Text\n> Quote");

    assertEquals("Text\nQuote", result.toString());
    Object[] spans = result.getSpans(0, result.length(), Object.class);
    assertEquals(3, spans.length);

    StyleSpan styleSpan = (StyleSpan) spans[0];
    assertEquals(Typeface.ITALIC, styleSpan.getStyle());
    assertEquals(5, result.getSpanStart(styleSpan));
    assertEquals(10, result.getSpanEnd(styleSpan));
    LeadingMarginSpan leadingMarginSpan = (LeadingMarginSpan) spans[1];
    assertEquals(5, result.getSpanStart(leadingMarginSpan));
    assertEquals(10, result.getSpanEnd(leadingMarginSpan));
    RelativeSizeSpan relativeSizeSpan = (RelativeSizeSpan) spans[2];
    assertEquals(5, result.getSpanStart(relativeSizeSpan));
    assertEquals(10, result.getSpanEnd(relativeSizeSpan));
}
 
Example #3
Source File: GlobalGUIRoutines.java    From PhoneProfilesPlus with Apache License 2.0 6 votes vote down vote up
private static SpannableStringBuilder addNumbers(Spanned htmlSpanned, int numberFrom, int sp) {
    int listItemCount = numberFrom-1;
    SpannableStringBuilder spannableBuilder = new SpannableStringBuilder(htmlSpanned);
    BulletSpan[] spans = spannableBuilder.getSpans(0, spannableBuilder.length(), BulletSpan.class);
    if (spans != null) {
        for (BulletSpan span : spans) {
            int start = spannableBuilder.getSpanStart(span);
            int end  = spannableBuilder.getSpanEnd(span);
            spannableBuilder.removeSpan(span);
            ++listItemCount;
            spannableBuilder.insert(start, listItemCount + ". ");
            spannableBuilder.setSpan(new LeadingMarginSpan.Standard(0, sip(sp)), start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        }
    }
    return spannableBuilder;
}
 
Example #4
Source File: ListTagHandler.java    From zulip-android with Apache License 2.0 6 votes vote down vote up
@Override
protected Object[] getReplaces(final Editable text, final int indentation) {
    // Nested BulletSpans increases distance between BULLET_SPAN and text, so we must prevent it.
    int bulletMargin = INDENT_PX;
    if (indentation > 1) {
        bulletMargin = INDENT_PX - BULLET_SPAN.getLeadingMargin(true);
        if (indentation > 2) {
            // This get's more complicated when we add a LeadingMarginSpan into the same line:
            // we have also counter it's effect to BulletSpan
            bulletMargin -= (indentation - 2) * LIST_ITEM_INDENT_PX;
        }
    }
    return new Object[]{
            new LeadingMarginSpan.Standard(LIST_ITEM_INDENT_PX * (indentation - 1)),
            new BulletSpan(bulletMargin)
    };
}
 
Example #5
Source File: ViewUtils.java    From PowerRecyclerView with Apache License 2.0 6 votes vote down vote up
public static void calculateTag2(TextView tag, TextView title, final String text) {
    ViewTreeObserver observer = tag.getViewTreeObserver();
    observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {
            SpannableString spannableString = new SpannableString(text);
            LeadingMarginSpan.Standard what = new LeadingMarginSpan.Standard(tag.getWidth() + dip2px(tag.getContext(), 10), 0);
            spannableString.setSpan(what, 0, spannableString.length(), SpannableString.SPAN_INCLUSIVE_INCLUSIVE);
            title.setText(spannableString);
            tag.getViewTreeObserver().removeOnPreDrawListener(
                    this);
            return false;
        }
    });

}
 
Example #6
Source File: MarkdownBuilder.java    From user-interface-samples with Apache License 2.0 5 votes vote down vote up
private void buildQuoteSpans(@NonNull Element element, SpannableStringBuilder builder) {
    int startIndex = builder.length();
    builder.append(element.getText());
    // You can set multiple spans for the same text
    builder.setSpan(new StyleSpan(Typeface.ITALIC), startIndex, builder.length(),
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    builder.setSpan(new LeadingMarginSpan.Standard(40), startIndex, builder.length(),
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    builder.setSpan(new RelativeSizeSpan(1.1f), startIndex, builder.length(),
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
 
Example #7
Source File: Utilities.java    From google-authenticator-android with Apache License 2.0 5 votes vote down vote up
@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
  if ("ul".equalsIgnoreCase(tag)) {
    // Ensure there are at least two newlines both before and after the list.
    ensureAtLeastTwoTrailingNewlines(output);
  } else if ("li".equalsIgnoreCase(tag)) {
    appendNewlineIfNoTrailingNewline(output);
    int outputLength = output.length();
    if (opening) {
      // Attach a BulletSpan to the beginning of the list entry. The span will be removed
      // when processing the closing of this tag/entry.
      output.setSpan(new BulletSpan(), outputLength, outputLength, Spannable.SPAN_MARK_MARK);
    } else {
      // Attach a BulletSpan, spanning the whole list entry. This removes the span
      // attached to the start of this list entry when processing the opening of this tag/entry.
      // We also attach a LeadingMarginSpan to the same location to indent the list entries
      // and their bullets.
      BulletSpan[] bulletSpans = output.getSpans(0, outputLength, BulletSpan.class);
      if (bulletSpans.length > 0) {
        BulletSpan startMarkSpan = bulletSpans[bulletSpans.length - 1];
        int startIndex = output.getSpanStart(startMarkSpan);
        output.removeSpan(startMarkSpan);
        if (startIndex != outputLength) {
          output.setSpan(
              new LeadingMarginSpan.Standard(10),
              startIndex,
              outputLength,
              Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
          output.setSpan(
              new BulletSpan(10),
              startIndex,
              outputLength,
              Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
      }
    }
  }
}
 
Example #8
Source File: DefaultDecorator.java    From kaif-android with Apache License 2.0 5 votes vote down vote up
@Override
public void closeOrderedListItem(SpannableStringBuilder out) {
  OrderedList orderedList = getLast(out, OrderedList.class);
  if (orderedList != null) {
    int number = orderedList.getAndIncrement();
    int where = out.getSpanStart(getLast(out, OrderedListItem.class));
    out.insert(where, Integer.toString(number) + ". ");
  }
  //check BulletSpan2
  end(out, OrderedListItem.class, new LeadingMarginSpan.LeadingMarginSpan2.Standard(leading));
}
 
Example #9
Source File: ListTagHandler.java    From zulip-android with Apache License 2.0 5 votes vote down vote up
@Override
protected Object[] getReplaces(final Editable text, final int indentation) {
    int numberMargin = LIST_ITEM_INDENT_PX * (indentation - 1);
    if (indentation > 2) {
        // Same as in ordered lists: counter the effect of nested Spans
        numberMargin -= (indentation - 2) * LIST_ITEM_INDENT_PX;
    }
    return new Object[]{new LeadingMarginSpan.Standard(numberMargin)};
}
 
Example #10
Source File: Layout.java    From android_9.0.0_r45 with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the effective leading margin (unsigned) for this line,
 * taking into account LeadingMarginSpan and LeadingMarginSpan2.
 * @param line the line index
 * @return the leading margin of this line
 */
private int getParagraphLeadingMargin(int line) {
    if (!mSpannedText) {
        return 0;
    }
    Spanned spanned = (Spanned) mText;

    int lineStart = getLineStart(line);
    int lineEnd = getLineEnd(line);
    int spanEnd = spanned.nextSpanTransition(lineStart, lineEnd,
            LeadingMarginSpan.class);
    LeadingMarginSpan[] spans = getParagraphSpans(spanned, lineStart, spanEnd,
                                            LeadingMarginSpan.class);
    if (spans.length == 0) {
        return 0; // no leading margin span;
    }

    int margin = 0;

    boolean useFirstLineMargin = lineStart == 0 || spanned.charAt(lineStart - 1) == '\n';
    for (int i = 0; i < spans.length; i++) {
        if (spans[i] instanceof LeadingMarginSpan2) {
            int spStart = spanned.getSpanStart(spans[i]);
            int spanLine = getLineForOffset(spStart);
            int count = ((LeadingMarginSpan2) spans[i]).getLeadingMarginLineCount();
            // if there is more than one LeadingMarginSpan2, use the count that is greatest
            useFirstLineMargin |= line < spanLine + count;
        }
    }
    for (int i = 0; i < spans.length; i++) {
        LeadingMarginSpan span = spans[i];
        margin += span.getLeadingMargin(useFirstLineMargin);
    }

    return margin;
}
 
Example #11
Source File: ComposedFrame.java    From Tehreer-Android with Apache License 2.0 4 votes vote down vote up
/**
 * Draws this frame onto the given <code>canvas</code> using the given <code>renderer</code>.
 *
 * @param renderer The renderer to use for drawing this frame.
 * @param canvas The canvas onto which to draw this frame.
 * @param x The x- position at which to draw this frame.
 * @param y The y- position at which to draw this frame.
 */
public void draw(@NonNull Renderer renderer, @NonNull Canvas canvas, float x, float y) {
    canvas.translate(x, y);

    drawBackground(canvas);

    int lineCount = lineList.size();
    for (int i = 0; i < lineCount; i++) {
        ComposedLine composedLine = lineList.get(i);
        Object[] lineSpans = composedLine.getSpans();

        int lineLeft = 0;
        int lineRight = (int) (mWidth + 0.5f);

        // Draw leading margins of this line.
        for (Object style : lineSpans) {
            if (style instanceof LeadingMarginSpan) {
                LeadingMarginSpan span = (LeadingMarginSpan) style;

                byte paragraphLevel = composedLine.getParagraphLevel();
                boolean isLTR = (paragraphLevel & 1) == 0;

                Paint paint = lazyPaint();
                int margin = (isLTR ? lineLeft : lineRight);
                int direction = (isLTR ? Layout.DIR_LEFT_TO_RIGHT : Layout.DIR_RIGHT_TO_LEFT);
                int lineTop = (int) (composedLine.getTop() + 0.5f);
                int lineBaseline = (int) (composedLine.getOriginY() + 0.5f);
                int lineBottom = (int) (composedLine.getTop() + composedLine.getHeight() + 0.5f);
                Spanned sourceText = (Spanned) source;
                int lineStart = composedLine.getCharStart();
                int lineEnd = composedLine.getCharEnd();
                boolean isFirst = composedLine.isFirst();

                span.drawLeadingMargin(canvas, paint, margin, direction,
                                       lineTop, lineBaseline, lineBottom,
                                       sourceText, lineStart, lineEnd, isFirst, null);

                if (isLTR) {
                    lineLeft += span.getLeadingMargin(isFirst);
                } else {
                    lineRight -= span.getLeadingMargin(isFirst);
                }
            }
        }

        composedLine.draw(renderer, canvas, composedLine.getOriginX(), composedLine.getOriginY());
    }

    canvas.translate(-x, -y);
}
 
Example #12
Source File: FrameResolver.java    From Tehreer-Android with Apache License 2.0 4 votes vote down vote up
void addParagraphLines() {
    float leadingLineExtent = layoutWidth;
    float trailingLineExtent = layoutWidth;

    // Extract all spans of this paragraph.
    paragraphSpans = mSpanned.getSpans(charStart, charEnd, ParagraphStyle.class);

    // Compute margins for leading and trailing lines.
    for (ParagraphStyle style : paragraphSpans) {
        if (style instanceof LeadingMarginSpan) {
            LeadingMarginSpan span = (LeadingMarginSpan) style;
            leadingLineExtent -= span.getLeadingMargin(true);
            trailingLineExtent -= span.getLeadingMargin(false);

            if (span instanceof LeadingMarginSpan2) {
                LeadingMarginSpan2 span2 = (LeadingMarginSpan2) span;
                int spanTotalLines = span2.getLeadingMarginLineCount();
                if (spanTotalLines > leadingLineCount) {
                    leadingLineCount = spanTotalLines;
                }
            }
        }
    }

    // Extract line height spans and create font metrics if necessary.
    pickHeightSpans = mSpanned.getSpans(charStart, charEnd, LineHeightSpan.class);
    int chooseHeightCount = pickHeightSpans.length;
    if (chooseHeightCount > 0 && fontMetrics == null) {
        fontMetrics = new Paint.FontMetricsInt();
    }

    // Setup array for caching top of first line related to each line height span.
    if (pickHeightTops == null || pickHeightTops.length < chooseHeightCount) {
        pickHeightTops = new int[chooseHeightCount];
    }

    // Compute top of first line related to each line height span.
    for (int i = 0; i < chooseHeightCount; i++) {
        int spanStart = mSpanned.getSpanStart(pickHeightSpans[i]);
        int spanTop = (int) (lineTop + 0.5f);

        // Fix span top in case it starts in a previous paragraph.
        if (spanStart < charStart) {
            int lineIndex = binarySearch(spanStart);
            ComposedLine spanLine = frameLines.get(lineIndex);
            spanTop = (int) (spanLine.getTop() + 0.5f);
        }

        pickHeightTops[i] = spanTop;
    }

    float flushFactor = computeFlushFactor();
    lineExtent = leadingLineExtent;
    resolveLeadingOffset();

    // Iterate over each line of this paragraph.
    int lineStart = charStart;
    while (lineStart != charEnd) {
        int lineEnd = BreakResolver.suggestForwardBreak(mSpanned, mRuns, mBreaks, lineStart, charEnd, lineExtent, BreakMode.LINE);
        ComposedLine composedLine = mLineResolver.createSimpleLine(lineStart, lineEnd);
        prepareLine(composedLine, flushFactor);

        float lineHeight = composedLine.getHeight();

        // Make sure that at least one line is added even if frame is smaller in height.
        if ((lineTop + lineHeight) > layoutHeight && frameLines.size() > 0) {
            filled = true;
            return;
        }

        frameLines.add(composedLine);
        lastFlushFactor = flushFactor;

        // Stop the filling process if maximum lines have been added.
        if (frameLines.size() == maxLines) {
            filled = true;
            return;
        }

        // Find out extent of next line.
        if (--leadingLineCount <= 0) {
            lineExtent = trailingLineExtent;
            resolveLeadingOffset();
        }

        lineStart = lineEnd;
        lineTop += lineHeight;
    }
}
 
Example #13
Source File: MarginHandler.java    From mvvm-template with GNU General Public License v3.0 4 votes vote down vote up
public void handleTagNode(TagNode node, SpannableStringBuilder builder, int start, int end) {
    builder.setSpan(new LeadingMarginSpan.Standard(30), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    this.appendNewLine(builder);
}
 
Example #14
Source File: Span.java    From Android-Spans with Apache License 2.0 4 votes vote down vote up
public static Node leadingMargin(Integer first, Integer rest, Object... nodes) {
    return new SpanNode(new LeadingMarginSpan.Standard(first, rest), nodes);
}
 
Example #15
Source File: Span.java    From Android-Spans with Apache License 2.0 4 votes vote down vote up
public static Node leadingMargin(Integer every, Object... nodes) {
    return new SpanNode(new LeadingMarginSpan.Standard(every), nodes);
}
 
Example #16
Source File: LeadingMarginSpanListener.java    From dante with MIT License 4 votes vote down vote up
@Override
protected Object getStyleSpan() {
    return new LeadingMarginSpan.Standard(margin, 0);
}
 
Example #17
Source File: HtmlTagHandler.java    From android-discourse with Apache License 2.0 4 votes vote down vote up
@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
    if (tag.equalsIgnoreCase("ul")) {
        if (opening) {
            lists.push(tag);
        } else {
            lists.pop();
        }
    } else if (tag.equalsIgnoreCase("ol")) {
        if (opening) {
            lists.push(tag);
            olNextIndex.push(Integer.valueOf(1)).toString();// TODO: add support for lists starting other index than 1
        } else {
            lists.pop();
            olNextIndex.pop().toString();
        }
    } else if (tag.equalsIgnoreCase("li")) {
        if (opening) {
            if (output.length() > 0 && output.charAt(output.length() - 1) != '\n') {
                output.append("\n");
            }
            String parentList = lists.peek();
            if (parentList.equalsIgnoreCase("ol")) {
                start(output, new Ol());
                output.append(olNextIndex.peek().toString() + ". ");
                olNextIndex.push(Integer.valueOf(olNextIndex.pop().intValue() + 1));
            } else if (parentList.equalsIgnoreCase("ul")) {
                start(output, new Ul());
            }
        } else {
            if (lists.peek().equalsIgnoreCase("ul")) {
                if (output.charAt(output.length() - 1) != '\n') {
                    output.append("\n");
                }
                // Nested BulletSpans increases distance between bullet and text, so we must prevent it.
                int bulletMargin = indent;
                if (lists.size() > 1) {
                    bulletMargin = indent - bullet.getLeadingMargin(true);
                    if (lists.size() > 2) {
                        // This get's more complicated when we add a LeadingMarginSpan into the same line:
                        // we have also counter it's effect to BulletSpan
                        bulletMargin -= (lists.size() - 2) * listItemIndent;
                    }
                }
                BulletSpan newBullet = new BulletSpan(bulletMargin);
                end(output, Ul.class, new LeadingMarginSpan.Standard(listItemIndent * (lists.size() - 1)), newBullet);
            } else if (lists.peek().equalsIgnoreCase("ol")) {
                if (output.charAt(output.length() - 1) != '\n') {
                    output.append("\n");
                }
                int numberMargin = listItemIndent * (lists.size() - 1);
                if (lists.size() > 2) {
                    // Same as in ordered lists: counter the effect of nested Spans
                    numberMargin -= (lists.size() - 2) * listItemIndent;
                }
                end(output, Ol.class, new LeadingMarginSpan.Standard(numberMargin));
            }
        }
    } else if (tag.equalsIgnoreCase("code")) {
        if (opening) {
            output.setSpan(new TypefaceSpan("monospace"), output.length(), output.length(), Spannable.SPAN_MARK_MARK);
        } else {
            L.d("Code tag encountered");
            Object obj = getLast(output, TypefaceSpan.class);
            int where = output.getSpanStart(obj);
            output.setSpan(new TypefaceSpan("monospace"), where, output.length(), 0);
            output.setSpan(new BackgroundColorSpan(Color.parseColor("#f1f1ff")), where, output.length(), 0);
        }
    } else {
        if (opening)
            L.d("Found an unsupported tag " + tag);
    }
}
 
Example #18
Source File: CustomHtmlTagHandler.java    From SteamGifts with MIT License 4 votes vote down vote up
/**
 * Processes a single list item.
 *
 * @param opening is this the opening tag?
 * @see <a href="https://bitbucket.org/Kuitsi/android-textview-html-list">Kuitsi/android-textview-html-list</a>
 */
private void processListItem(boolean opening, Editable output) {
    if (opening) {
        if (output.length() > 0 && output.charAt(output.length() - 1) != '\n') {
            output.append("\n");
        }
        String parentList = lists.peek();
        if (parentList.equalsIgnoreCase("ol")) {
            start(output, new Ol());
            output.append(olNextIndex.peek().toString()).append(". ");
            olNextIndex.push(olNextIndex.pop() + 1);
        } else if (parentList.equalsIgnoreCase("ul")) {
            start(output, new Ul());
        }
    } else {
        if (lists.peek().equalsIgnoreCase("ul")) {
            if (output.length() > 0 && output.charAt(output.length() - 1) != '\n') {
                output.append("\n");
            }
            // Nested BulletSpans increases distance between bullet and text, so we must prevent it.
            int bulletMargin = indent;
            if (lists.size() > 1) {
                bulletMargin = indent - bullet.getLeadingMargin(true);
                if (lists.size() > 2) {
                    // This get's more complicated when we add a LeadingMarginSpan into the same line:
                    // we have also counter it's effect to BulletSpan
                    bulletMargin -= (lists.size() - 2) * listItemIndent;
                }
            }
            BulletSpan newBullet = new BulletSpan(bulletMargin);
            end(output,
                    Ul.class,
                    new LeadingMarginSpan.Standard(listItemIndent * (lists.size() - 1)),
                    newBullet);
        } else if (lists.peek().equalsIgnoreCase("ol")) {
            if (output.length() > 0 && output.charAt(output.length() - 1) != '\n') {
                output.append("\n");
            }
            int numberMargin = listItemIndent * (lists.size() - 1);
            if (lists.size() > 2) {
                // Same as in ordered lists: counter the effect of nested Spans
                numberMargin -= (lists.size() - 2) * listItemIndent;
            }
            end(output,
                    Ol.class,
                    new LeadingMarginSpan.Standard(numberMargin));
        }
    }
}
 
Example #19
Source File: SpannableStringUtils.java    From DevUtils with Apache License 2.0 4 votes vote down vote up
/**
 * 更新 CharSequence 字符
 */
private void updateCharCharSequence() {
    if (mText.length() == 0) return;
    int start = mBuilder.length();
    if (start == 0 && lineHeight != -1) { // bug of LineHeightSpan when first line
        mBuilder.append(Character.toString((char) 2)).append("\n")
                .setSpan(new AbsoluteSizeSpan(0), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        start = 2;
    }
    mBuilder.append(mText);
    int end = mBuilder.length();
    if (verticalAlign != -1) {
        mBuilder.setSpan(new VerticalAlignSpan(verticalAlign), start, end, flag);
    }
    if (foregroundColor != COLOR_DEFAULT) {
        mBuilder.setSpan(new ForegroundColorSpan(foregroundColor), start, end, flag);
    }
    if (backgroundColor != COLOR_DEFAULT) {
        mBuilder.setSpan(new BackgroundColorSpan(backgroundColor), start, end, flag);
    }
    if (first != -1) {
        mBuilder.setSpan(new LeadingMarginSpan.Standard(first, rest), start, end, flag);
    }
    if (quoteColor != COLOR_DEFAULT) {
        mBuilder.setSpan(new CustomQuoteSpan(quoteColor, stripeWidth, quoteGapWidth), start, end, flag);
    }
    if (bulletColor != COLOR_DEFAULT) {
        mBuilder.setSpan(new CustomBulletSpan(bulletColor, bulletRadius, bulletGapWidth), start, end, flag);
    }
    if (fontSize != -1) {
        mBuilder.setSpan(new AbsoluteSizeSpan(fontSize, fontSizeIsDp), start, end, flag);
    }
    if (proportion != -1) {
        mBuilder.setSpan(new RelativeSizeSpan(proportion), start, end, flag);
    }
    if (xProportion != -1) {
        mBuilder.setSpan(new ScaleXSpan(xProportion), start, end, flag);
    }
    if (lineHeight != -1) {
        mBuilder.setSpan(new CustomLineHeightSpan(lineHeight, alignLine), start, end, flag);
    }
    if (isStrikethrough) {
        mBuilder.setSpan(new StrikethroughSpan(), start, end, flag);
    }
    if (isUnderline) {
        mBuilder.setSpan(new UnderlineSpan(), start, end, flag);
    }
    if (isSuperscript) {
        mBuilder.setSpan(new SuperscriptSpan(), start, end, flag);
    }
    if (isSubscript) {
        mBuilder.setSpan(new SubscriptSpan(), start, end, flag);
    }
    if (isBold) {
        mBuilder.setSpan(new StyleSpan(Typeface.BOLD), start, end, flag);
    }
    if (isItalic) {
        mBuilder.setSpan(new StyleSpan(Typeface.ITALIC), start, end, flag);
    }
    if (isBoldItalic) {
        mBuilder.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), start, end, flag);
    }
    if (fontFamily != null) {
        mBuilder.setSpan(new TypefaceSpan(fontFamily), start, end, flag);
    }
    if (typeface != null) {
        mBuilder.setSpan(new CustomTypefaceSpan(typeface), start, end, flag);
    }
    if (alignment != null) {
        mBuilder.setSpan(new AlignmentSpan.Standard(alignment), start, end, flag);
    }
    if (clickSpan != null) {
        mBuilder.setSpan(clickSpan, start, end, flag);
    }
    if (url != null) {
        mBuilder.setSpan(new URLSpan(url), start, end, flag);
    }
    if (blurRadius != -1) {
        mBuilder.setSpan(new MaskFilterSpan(new BlurMaskFilter(blurRadius, style)), start, end, flag);
    }
    if (shader != null) {
        mBuilder.setSpan(new ShaderSpan(shader), start, end, flag);
    }
    if (shadowRadius != -1) {
        mBuilder.setSpan(new ShadowSpan(shadowRadius, shadowDx, shadowDy, shadowColor), start, end, flag);
    }
    if (spans != null) {
        for (Object span : spans) {
            mBuilder.setSpan(span, start, end, flag);
        }
    }
}