Example usage for android.text StaticLayout getLineCount

List of usage examples for android.text StaticLayout getLineCount

Introduction

In this page you can find the example usage for android.text StaticLayout getLineCount.

Prototype

@Override
    public int getLineCount() 

Source Link

Usage

From source file:Main.java

private static int getLineCount(CharSequence text, TextPaint paint, float size, float width,
        DisplayMetrics displayMetrics) {
    paint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, size, displayMetrics));
    StaticLayout layout = new StaticLayout(text, paint, (int) width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f,
            true);/* ww  w.  j  a v  a2  s.c o m*/
    return layout.getLineCount();
}

From source file:Main.java

/**
 * Recursive binary search to find the best size for the text.
 *//*from   w ww. j  a  va 2  s . c o  m*/
private static float getAutofitTextSize(CharSequence text, TextPaint paint, float targetWidth, int maxLines,
        float low, float high, float precision, DisplayMetrics displayMetrics) {
    float mid = (low + high) / 2.0f;
    int lineCount = 1;
    StaticLayout layout = null;

    paint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, mid, displayMetrics));

    if (maxLines != 1) {
        layout = new StaticLayout(text, paint, (int) targetWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f,
                true);
        lineCount = layout.getLineCount();
    }

    if (SPEW)
        Log.d(TAG, "low=" + low + " high=" + high + " mid=" + mid + " target=" + targetWidth + " maxLines="
                + maxLines + " lineCount=" + lineCount);

    if (lineCount > maxLines) {
        // For the case that `text` has more newline characters than `maxLines`.
        if ((high - low) < precision) {
            return low;
        }
        return getAutofitTextSize(text, paint, targetWidth, maxLines, low, mid, precision, displayMetrics);
    } else if (lineCount < maxLines) {
        return getAutofitTextSize(text, paint, targetWidth, maxLines, mid, high, precision, displayMetrics);
    } else {
        float maxLineWidth = 0;
        if (maxLines == 1) {
            maxLineWidth = paint.measureText(text, 0, text.length());
        } else {
            for (int i = 0; i < lineCount; i++) {
                if (layout.getLineWidth(i) > maxLineWidth) {
                    maxLineWidth = layout.getLineWidth(i);
                }
            }
        }

        if ((high - low) < precision) {
            return low;
        } else if (maxLineWidth > targetWidth) {
            return getAutofitTextSize(text, paint, targetWidth, maxLines, low, mid, precision, displayMetrics);
        } else if (maxLineWidth < targetWidth) {
            return getAutofitTextSize(text, paint, targetWidth, maxLines, mid, high, precision, displayMetrics);
        } else {
            return mid;
        }
    }
}

From source file:org.telegram.ui.Cells.SharedLinkCell.java

@Override
protected void onDraw(Canvas canvas) {
    if (titleLayout != null) {
        canvas.save();/*from   w w w . java2  s . c o m*/
        canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline),
                titleY);
        titleLayout.draw(canvas);
        canvas.restore();
    }

    if (descriptionLayout != null) {
        descriptionTextPaint.setColor(TEXT_COLOR);
        canvas.save();
        canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline),
                descriptionY);
        descriptionLayout.draw(canvas);
        canvas.restore();
    }

    if (descriptionLayout2 != null) {
        descriptionTextPaint.setColor(TEXT_COLOR);
        canvas.save();
        canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline),
                description2Y);
        descriptionLayout2.draw(canvas);
        canvas.restore();
    }

    if (!linkLayout.isEmpty()) {
        descriptionTextPaint.setColor(Theme.MSG_LINK_TEXT_COLOR);
        int offset = 0;
        for (int a = 0; a < linkLayout.size(); a++) {
            StaticLayout layout = linkLayout.get(a);
            if (layout.getLineCount() > 0) {
                canvas.save();
                canvas.translate(
                        AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline),
                        linkY + offset);
                if (pressedLink == a) {
                    canvas.drawPath(urlPath, urlPaint);
                }
                layout.draw(canvas);
                canvas.restore();
                offset += layout.getLineBottom(layout.getLineCount() - 1);
            }
        }
    }

    letterDrawable.draw(canvas);
    if (drawLinkImageView) {
        linkImageView.draw(canvas);
    }

    if (needDivider) {
        if (LocaleController.isRTL) {
            canvas.drawLine(0, getMeasuredHeight() - 1,
                    getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline),
                    getMeasuredHeight() - 1, paint);
        } else {
            canvas.drawLine(AndroidUtilities.dp(AndroidUtilities.leftBaseline), getMeasuredHeight() - 1,
                    getMeasuredWidth(), getMeasuredHeight() - 1, paint);
        }
    }
}

From source file:org.telegram.ui.Cells.SharedLinkCell.java

@Override
public boolean onTouchEvent(MotionEvent event) {
    boolean result = false;
    if (message != null && !linkLayout.isEmpty() && delegate != null && delegate.canPerformActions()) {
        if (event.getAction() == MotionEvent.ACTION_DOWN
                || linkPreviewPressed && event.getAction() == MotionEvent.ACTION_UP) {
            int x = (int) event.getX();
            int y = (int) event.getY();
            int offset = 0;
            boolean ok = false;
            for (int a = 0; a < linkLayout.size(); a++) {
                StaticLayout layout = linkLayout.get(a);
                if (layout.getLineCount() > 0) {
                    int height = layout.getLineBottom(layout.getLineCount() - 1);
                    int linkPosX = AndroidUtilities
                            .dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline);
                    if (x >= linkPosX + layout.getLineLeft(0) && x <= linkPosX + layout.getLineWidth(0)
                            && y >= linkY + offset && y <= linkY + offset + height) {
                        ok = true;/*w  ww .  j  a va 2  s  .c  om*/
                        if (event.getAction() == MotionEvent.ACTION_DOWN) {
                            resetPressedLink();
                            pressedLink = a;
                            linkPreviewPressed = true;
                            try {
                                urlPath.setCurrentLayout(layout, 0, 0);
                                layout.getSelectionPath(0, layout.getText().length(), urlPath);
                            } catch (Exception e) {
                                FileLog.e("tmessages", e);
                            }
                            result = true;
                        } else if (linkPreviewPressed) {
                            try {
                                TLRPC.WebPage webPage = pressedLink == 0 && message.messageOwner.media != null
                                        ? message.messageOwner.media.webpage
                                        : null;
                                if (webPage != null && Build.VERSION.SDK_INT >= 16 && webPage.embed_url != null
                                        && webPage.embed_url.length() != 0) {
                                    delegate.needOpenWebView(webPage);
                                } else {
                                    Browser.openUrl(getContext(), links.get(pressedLink));
                                }
                            } catch (Exception e) {
                                FileLog.e("tmessages", e);
                            }
                            resetPressedLink();
                            result = true;
                        }
                        break;
                    }
                    offset += height;
                }
            }
            if (!ok) {
                resetPressedLink();
            }
        } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
            resetPressedLink();
        }
    } else {
        resetPressedLink();
    }
    return result || super.onTouchEvent(event);
}

From source file:org.wikipedia.page.shareafact.SnippetImage.java

/**
 * If the title or text is too long we first reduce the font size.
 * If that is not enough it gets ellipsized.
 *//*w  w w . j  av  a 2s  .  c  o m*/
private static StaticLayout optimizeTextSize(TextLayoutParams params, int maxHeight, int maxLines,
        float maxFontSize, float minFontSize) {
    final float threshold1 = 60.0f;
    final float threshold2 = 40.0f;
    final float extraStep1 = 3.0f;
    final float extraStep2 = 1.0f;
    boolean fits = false;
    StaticLayout textLayout = null;

    // Try decreasing font size first
    for (float fontSize = maxFontSize; fontSize >= minFontSize; fontSize -= 1.0f) {
        params.textPaint.setTextSize(fontSize);
        textLayout = buildLayout(params);
        if (textLayout.getHeight() <= maxHeight) {
            fits = true;
            break;
        }

        // make it go faster at the beginning...
        if (fontSize > threshold1) {
            fontSize -= extraStep1;
        } else if (fontSize > threshold2) {
            fontSize -= extraStep2;
        }
    }

    // Then do own ellipsize: cut text off after last fitting space and add "..."
    // Didn't want to cut off randomly in the middle of a line or word.
    if (!fits) {
        final String textStr = params.text.toString();
        final int ellipsisLength = 3;
        final int ellipsisStart = textLayout != null ? textLayout.getLineStart(maxLines) - ellipsisLength
                : textStr.length();
        final int end = textStr.lastIndexOf(' ', ellipsisStart) + 1;
        if (end > 0) {
            textLayout = buildLayout(new TextLayoutParams(params, textStr.substring(0, end) + "..."));
            if (textLayout.getLineCount() <= maxLines) {
                fits = true;
            }
        }
    }

    // last resort: use TextUtils.ellipsize()
    if (!fits) {
        final float textRatio = .87f;
        final float maxWidth = textRatio * maxLines * params.lineWidth;
        textLayout = buildLayout(new TextLayoutParams(params,
                TextUtils.ellipsize(params.text, params.textPaint, maxWidth, TextUtils.TruncateAt.END)));
    }

    return textLayout;
}

From source file:com.semfapp.adamdilger.semf.Take5PdfDocument.java

public float drawRiskElement(int height, Take5RiskElement element) {
    final float singleLineHeight = 12.5f;
    float totalItemHeight;

    TextPaint textPaint = new TextPaint();
    textPaint.setTypeface(roboto);/*from  www.  j  a va  2 s.c om*/
    textPaint.setTextSize(FONT11);
    textPaint.setColor(Color.BLACK);

    String oneString = "";
    String twoString = "";

    if (element.getOne() != null) {
        oneString = element.getOne();
    }
    if (element.getTwo() != null) {
        twoString = element.getTwo();
    }

    StaticLayout one = new StaticLayout(oneString, textPaint, 235, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f,
            false);
    StaticLayout rating = new StaticLayout(element.getRating().toString(), textPaint, 100,
            Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
    StaticLayout two = new StaticLayout(twoString, textPaint, 250, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f,
            false);

    if (one.getLineCount() > two.getLineCount()) {
        totalItemHeight = singleLineHeight * one.getLineCount();
    } else {
        totalItemHeight = singleLineHeight * two.getLineCount();
    }

    can.save();
    can.translate(15, height);
    one.draw(can);
    can.restore();

    can.save();
    can.translate(320, height);
    two.draw(can);
    can.restore();

    can.save();
    can.translate(270, height);
    rating.draw(can);
    can.restore();

    return totalItemHeight;
}

From source file:com.taobao.weex.dom.WXTextDomObject.java

/**
 * Truncate the source span to the specified lines.
 * Caller of this method must ensure that the lines of text is <strong>greater than desired lines and need truncate</strong>.
 * Otherwise, unexpected behavior may happen.
 * @param source The source span.//from  w w  w. j  a  v  a 2  s  .  c o  m
 * @param paint the textPaint
 * @param desired specified lines.
 * @param truncateAt truncate method, null value means clipping overflow text directly, non-null value means using ellipsis strategy to clip
 * @return The spans after clipped.
 */
private @NonNull Spanned truncate(@Nullable Editable source, @NonNull TextPaint paint, int desired,
        @Nullable TextUtils.TruncateAt truncateAt) {
    Spanned ret = new SpannedString("");
    if (!TextUtils.isEmpty(source) && source.length() > 0) {
        if (truncateAt != null) {
            source.append(ELLIPSIS);
            Object[] spans = source.getSpans(0, source.length(), Object.class);
            for (Object span : spans) {
                int start = source.getSpanStart(span);
                int end = source.getSpanEnd(span);
                if (start == 0 && end == source.length() - 1) {
                    source.removeSpan(span);
                    source.setSpan(span, 0, source.length(), source.getSpanFlags(span));
                }
            }
        }

        StaticLayout layout;
        int startOffset;

        while (source.length() > 1) {
            startOffset = source.length() - 1;
            if (truncateAt != null) {
                startOffset -= 1;
            }
            source.delete(startOffset, startOffset + 1);
            layout = new StaticLayout(source, paint, desired, Layout.Alignment.ALIGN_NORMAL, 1, 0, false);
            if (layout.getLineCount() <= 1) {
                ret = source;
                break;
            }
        }
    }
    return ret;
}

From source file:net.opacapp.multilinecollapsingtoolbar.CollapsingTextHelper.java

private void calculateUsingTextSize(final float textSize) {
    if (mText == null)
        return;//w  ww .ja  va 2 s  .com
    final float availableWidth;
    final float newTextSize;
    boolean updateDrawText = false;
    // BEGIN MODIFICATION: Add maxLines variable
    int maxLines;
    // END MODIFICATION
    if (isClose(textSize, mCollapsedTextSize)) {
        availableWidth = mCollapsedBounds.width();
        newTextSize = mCollapsedTextSize;
        mScale = 1f;
        if (mCurrentTypeface != mCollapsedTypeface) {
            mCurrentTypeface = mCollapsedTypeface;
            updateDrawText = true;
        }
        // BEGIN MODIFICATION: Set maxLines variable
        maxLines = 1;
        // END MODIFICATION
    } else {
        availableWidth = mExpandedBounds.width();
        newTextSize = mExpandedTextSize;
        if (mCurrentTypeface != mExpandedTypeface) {
            mCurrentTypeface = mExpandedTypeface;
            updateDrawText = true;
        }
        if (isClose(textSize, mExpandedTextSize)) {
            // If we're close to the expanded text size, snap to it and use a scale of 1
            mScale = 1f;
        } else {
            // Else, we'll scale down from the expanded text size
            mScale = textSize / mExpandedTextSize;
        }
        // BEGIN MODIFICATION: Set maxLines variable
        maxLines = this.maxLines;
        // END MODIFICATION
    }
    if (availableWidth > 0) {
        updateDrawText = (mCurrentTextSize != newTextSize) || mBoundsChanged || updateDrawText;
        mCurrentTextSize = newTextSize;
        mBoundsChanged = false;
    }
    if (mTextToDraw == null || updateDrawText) {
        mTextPaint.setTextSize(mCurrentTextSize);
        mTextPaint.setTypeface(mCurrentTypeface);

        // BEGIN MODIFICATION: Text layout creation and text truncation
        StaticLayout layout = new StaticLayout(mText, mTextPaint, (int) availableWidth,
                Layout.Alignment.ALIGN_NORMAL, 1, 0, false);
        CharSequence truncatedText;
        if (layout.getLineCount() > maxLines) {
            int lastLine = maxLines - 1;
            CharSequence textBefore = lastLine > 0 ? mText.subSequence(0, layout.getLineEnd(lastLine - 1)) : "";
            CharSequence lineText = mText.subSequence(layout.getLineStart(lastLine),
                    layout.getLineEnd(lastLine));
            // if last char in line is space, move it behind the ellipsis
            CharSequence lineEnd = "";
            if (lineText.charAt(lineText.length() - 1) == ' ') {
                lineEnd = lineText.subSequence(lineText.length() - 1, lineText.length());
                lineText = lineText.subSequence(0, lineText.length() - 1);
            }
            // insert ellipsis character
            lineText = TextUtils.concat(lineText, "\u2026", lineEnd);
            // if the text is too long, truncate it
            CharSequence truncatedLineText = TextUtils.ellipsize(lineText, mTextPaint, availableWidth,
                    TextUtils.TruncateAt.END);
            truncatedText = TextUtils.concat(textBefore, truncatedLineText);

        } else {
            truncatedText = mText;
        }
        if (!TextUtils.equals(truncatedText, mTextToDraw)) {
            mTextToDraw = truncatedText;
            mIsRtl = calculateIsRtl(mTextToDraw);
        }

        final Layout.Alignment alignment;

        // Don't rectify gravity for RTL languages, Layout.Alignment does it already.
        switch (mExpandedTextGravity & GravityCompat.RELATIVE_HORIZONTAL_GRAVITY_MASK) {
        case Gravity.CENTER_HORIZONTAL:
            alignment = Layout.Alignment.ALIGN_CENTER;
            break;
        case Gravity.RIGHT:
        case Gravity.END:
            alignment = Layout.Alignment.ALIGN_OPPOSITE;
            break;
        case Gravity.LEFT:
        case Gravity.START:
        default:
            alignment = Layout.Alignment.ALIGN_NORMAL;
            break;
        }

        mTextLayout = new StaticLayout(mTextToDraw, mTextPaint, (int) availableWidth, alignment, 1, 0, false);
        // END MODIFICATION
    }
}

From source file:android.support.v7.widget.AppCompatTextViewAutoSizeHelper.java

private boolean suggestedSizeFitsInSpace(int suggestedSizeInPx, RectF availableSpace) {
    CharSequence text = mTextView.getText();
    TransformationMethod transformationMethod = mTextView.getTransformationMethod();
    if (transformationMethod != null) {
        CharSequence transformedText = transformationMethod.getTransformation(text, mTextView);
        if (transformedText != null) {
            text = transformedText;/*w  ww .  j a v a 2  s. com*/
        }
    }

    final int maxLines = Build.VERSION.SDK_INT >= 16 ? mTextView.getMaxLines() : -1;
    if (mTempTextPaint == null) {
        mTempTextPaint = new TextPaint();
    } else {
        mTempTextPaint.reset();
    }
    mTempTextPaint.set(mTextView.getPaint());
    mTempTextPaint.setTextSize(suggestedSizeInPx);

    // Needs reflection call due to being private.
    Layout.Alignment alignment = invokeAndReturnWithDefault(mTextView, "getLayoutAlignment",
            Layout.Alignment.ALIGN_NORMAL);
    final StaticLayout layout = Build.VERSION.SDK_INT >= 23
            ? createStaticLayoutForMeasuring(text, alignment, Math.round(availableSpace.right), maxLines)
            : createStaticLayoutForMeasuringPre23(text, alignment, Math.round(availableSpace.right));
    // Lines overflow.
    if (maxLines != -1 && (layout.getLineCount() > maxLines
            || (layout.getLineEnd(layout.getLineCount() - 1)) != text.length())) {
        return false;
    }

    // Height overflow.
    if (layout.getHeight() > availableSpace.bottom) {
        return false;
    }

    return true;
}

From source file:de.tum.in.tumcampus.auxiliary.calendar.DayView.java

private void drawEventText(StaticLayout eventLayout, Rect rect, Canvas canvas, int top, int bottom,
        boolean center) {
    // drawEmptyRect(canvas, rect, 0xFFFF00FF); // for debugging

    int width = rect.right - rect.left;
    int height = rect.bottom - rect.top;

    // If the rectangle is too small for text, then return
    if (eventLayout == null || width < MIN_CELL_WIDTH_FOR_TEXT) {
        return;// w  w w .  j  a va2  s .  com
    }

    int totalLineHeight = 0;
    int lineCount = eventLayout.getLineCount();
    for (int i = 0; i < lineCount; i++) {
        int lineBottom = eventLayout.getLineBottom(i);
        if (lineBottom <= height) {
            totalLineHeight = lineBottom;
        } else {
            break;
        }
    }

    // + 2 is small workaround when the font is slightly bigger then the rect. This will
    // still allow the text to be shown without overflowing into the other all day rects.
    if (totalLineHeight == 0 || rect.top > bottom || rect.top + totalLineHeight + 2 < top) {
        return;
    }

    // Use a StaticLayout to format the string.
    canvas.save();
    //  canvas.translate(rect.left, rect.top + (rect.bottom - rect.top / 2));
    int padding = center ? (rect.bottom - rect.top - totalLineHeight) / 2 : 0;
    canvas.translate(rect.left, rect.top + padding);
    rect.left = 0;
    rect.right = width;
    rect.top = 0;
    rect.bottom = totalLineHeight;

    // There's a bug somewhere. If this rect is outside of a previous
    // cliprect, this becomes a no-op. What happens is that the text draw
    // past the event rect. The current fix is to not draw the staticLayout
    // at all if it is completely out of bound.
    canvas.clipRect(rect);
    eventLayout.draw(canvas);
    canvas.restore();
}