Beispiel #1
0
  /**
   * Resize the text size with specified width and height
   *
   * @param width
   * @param height
   */
  public void resizeText(int width, int height) {
    CharSequence text = getText();
    // Do not resize if the view does not have dimensions or there is no
    // text
    // or if mTextSize has not been initialized
    if (text == null || text.length() == 0 || height <= 0 || width <= 0 || mTextSize == 0) {
      return;
    }

    // Get the text view's paint object
    TextPaint textPaint = getPaint();

    // Store the current text size
    float oldTextSize = textPaint.getTextSize();

    // If there is a max text size set, use the lesser of that and the
    // default text size
    float targetTextSize = mMaxTextSize > 0 ? Math.min(mTextSize, mMaxTextSize) : mTextSize;

    // Get the required text height
    int textHeight = getTextHeight(text, textPaint, width, targetTextSize);
    int textWidth = getTextWidth(text, textPaint, width, targetTextSize);
    int lineHeight = getTextHeight(text, textPaint, width * 10, targetTextSize);

    // Until we either fit within our text view or we had reached our min
    // text size, incrementally try smaller sizes
    while (((textHeight > height) || (textWidth > width) || (textHeight > lineHeight))
        && targetTextSize > mMinTextSize) {
      targetTextSize = Math.max(targetTextSize - 2, mMinTextSize);
      textHeight = getTextHeight(text, textPaint, width, targetTextSize);
      textWidth = getTextWidth(text, textPaint, width, targetTextSize);
      lineHeight = getTextHeight(text, textPaint, width * 10, targetTextSize);
    }

    // If we had reached our minimum text size and still don't fit, append
    // an ellipsis
    if (mAddEllipsis && targetTextSize == mMinTextSize && textHeight > height) {
      // Draw using a static layout
      StaticLayout layout =
          new StaticLayout(
              text, textPaint, width, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, false);
      layout.draw(sTextResizeCanvas);
      int lastLine = layout.getLineForVertical(height) - 1;
      int start = layout.getLineStart(lastLine);
      int end = layout.getLineEnd(lastLine);
      float lineWidth = layout.getLineWidth(lastLine);
      float ellipseWidth = textPaint.measureText(mEllipsis);

      // Trim characters off until we have enough room to draw the
      // ellipsis
      while (width < lineWidth + ellipseWidth) {
        lineWidth = textPaint.measureText(text.subSequence(start, --end + 1).toString());
      }
      setText(text.subSequence(0, end) + mEllipsis);
    }

    // Some devices try to auto adjust line spacing, so force default line
    // spacing
    // and invalidate the layout as a side effect
    textPaint.setTextSize(targetTextSize);
    setLineSpacing(mSpacingAdd, mSpacingMult);

    // Notify the listener if registered
    if (mTextResizeListener != null) {
      mTextResizeListener.onTextResize(this, oldTextSize, targetTextSize);
    }

    // Reset force resize flag
    mNeedsResize = false;
  }
  /**
   * Resize the text size with specified width and height
   *
   * @param width
   * @param height
   */
  public void resizeText(int width, int height) {
    CharSequence text = getText();
    // Do not resize if the view does not have dimensions or there is no text
    if (text == null || text.length() == 0 || height <= 0 || width <= 0 || mTextSize == 0) {
      return;
    }

    // Get the text view's paint object
    TextPaint textPaint = getPaint();

    // Store the current text size
    float oldTextSize = textPaint.getTextSize();
    // If there is a max text size set, use the lesser of that and the default text size
    float targetTextSize = mMaxTextSize > 0 ? Math.min(mTextSize, mMaxTextSize) : mTextSize;

    // Get the required text height
    int textHeight = getTextHeight(text, textPaint, width, targetTextSize);

    // Until we either fit within our text view or we had reached our min text size, incrementally
    // try smaller sizes
    while (textHeight > height && targetTextSize > mMinTextSize) {
      targetTextSize = Math.max(targetTextSize - 2, mMinTextSize);
      textHeight = getTextHeight(text, textPaint, width, targetTextSize);
    }

    // If we had reached our minimum text size and still don't fit, append an ellipsis
    if (mAddEllipsis && targetTextSize == mMinTextSize && textHeight > height) {
      // Draw using a static layout
      StaticLayout layout =
          new StaticLayout(
              text, textPaint, width, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, false);
      // Check that we have a least one line of rendered text
      if (layout.getLineCount() > 0) {
        // Since the line at the specific vertical position would be cut off,
        // we must trim up to the previous line
        int lastLine = layout.getLineForVertical(height) - 1;
        // If the text would not even fit on a single line, clear it
        if (lastLine < 0) {
          setText("");
        }
        // Otherwise, trim to the previous line and add an ellipsis
        else {
          int start = layout.getLineStart(lastLine);
          int end = layout.getLineEnd(lastLine);
          float lineWidth = layout.getLineWidth(lastLine);
          float ellipseWidth = textPaint.measureText(mEllipsis);

          // Trim characters off until we have enough room to draw the ellipsis
          while (width < lineWidth + ellipseWidth) {
            lineWidth = textPaint.measureText(text.subSequence(start, --end + 1).toString());
          }
          setText(text.subSequence(0, end) + mEllipsis);
        }
      }
    }

    // Some devices try to auto adjust line spacing, so force default line spacing
    // and invalidate the layout as a side effect
    textPaint.setTextSize(targetTextSize);
    setLineSpacing(mSpacingAdd, mSpacingMult);

    // Notify the listener if registered
    if (mTextResizeListener != null) {
      mTextResizeListener.onTextResize(this, oldTextSize, targetTextSize);
    }

    // Reset force resize flag
    mNeedsResize = false;
  }
  public List<Integer> getPageOffsets(CharSequence text, boolean includePageNumbers) {

    if (text == null) {
      return new ArrayList<Integer>();
    }

    List<Integer> pageOffsets = new ArrayList<Integer>();

    TextPaint textPaint = bookView.getInnerView().getPaint();
    int boundedWidth = bookView.getInnerView().getWidth();

    LOG.debug("Page width: " + boundedWidth);

    StaticLayout layout =
        layoutFactory.create(text, textPaint, boundedWidth, bookView.getLineSpacing());
    LOG.debug("Layout height: " + layout.getHeight());

    layout.draw(new Canvas());

    // Subtract the height of the top margin
    int pageHeight = bookView.getHeight() - bookView.getVerticalMargin();

    if (includePageNumbers) {
      String bottomSpace = "0\n";

      StaticLayout numLayout =
          layoutFactory.create(bottomSpace, textPaint, boundedWidth, bookView.getLineSpacing());
      numLayout.draw(new Canvas());

      // Subtract the height needed to show page numbers, or the
      // height of the margin, whichever is more
      pageHeight = pageHeight - Math.max(numLayout.getHeight(), bookView.getVerticalMargin());
    } else {
      // Just subtract the bottom margin
      pageHeight = pageHeight - bookView.getVerticalMargin();
    }

    LOG.debug("Got pageHeight " + pageHeight);

    int totalLines = layout.getLineCount();
    int topLineNextPage = -1;
    int pageStartOffset = 0;

    while (topLineNextPage < totalLines - 1) {

      LOG.debug("Processing line " + topLineNextPage + " / " + totalLines);

      int topLine = layout.getLineForOffset(pageStartOffset);
      topLineNextPage = layout.getLineForVertical(layout.getLineTop(topLine) + pageHeight);

      LOG.debug("topLine " + topLine + " / " + topLineNextPage);
      if (topLineNextPage == topLine) { // If lines are bigger than can fit on a page
        topLineNextPage = topLine + 1;
      }

      int pageEnd = layout.getLineEnd(topLineNextPage - 1);

      LOG.debug("pageStartOffset=" + pageStartOffset + ", pageEnd=" + pageEnd);

      if (pageEnd > pageStartOffset) {
        if (text.subSequence(pageStartOffset, pageEnd).toString().trim().length() > 0) {
          pageOffsets.add(pageStartOffset);
        }
        pageStartOffset = layout.getLineStart(topLineNextPage);
      }
    }

    return pageOffsets;
  }