Java Code Examples for android.text.Layout#getLineForOffset()

The following examples show how to use android.text.Layout#getLineForOffset() . 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: EditTextBoldCursor.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
private boolean updateCursorPosition() {
    final Layout layout = getLayout();
    final int offset = getSelectionStart();
    final int line = layout.getLineForOffset(offset);
    final int top = layout.getLineTop(line);
    final int bottom = layout.getLineTop(line + 1);
    updateCursorPosition(top, bottom, layout.getPrimaryHorizontal(offset));
    return true;
}
 
Example 2
Source File: BulletSpan.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void drawLeadingMargin(Canvas canvas, Paint paint, int x, int dir,
                              int top, int baseline, int bottom,
                              CharSequence text, int start, int end,
                              boolean first, Layout layout) {
    if (((Spanned) text).getSpanStart(this) == start) {
        Paint.Style style = paint.getStyle();
        int oldcolor = 0;

        if (mWantColor) {
            oldcolor = paint.getColor();
            paint.setColor(mColor);
        }

        paint.setStyle(Paint.Style.FILL);

        if (layout != null) {
            // "bottom" position might include extra space as a result of line spacing
            // configuration. Subtract extra space in order to show bullet in the vertical
            // center of characters.
            final int line = layout.getLineForOffset(start);
            int spacing = line != layout.getLineCount() - 1 ? (int) layout.getSpacingAdd() : 0;
            bottom = bottom - spacing;
        }

        final float yPosition = (top + bottom) / 2f;
        final float xPosition = x + dir * mBulletRadius;

        canvas.drawCircle(xPosition, yPosition, mBulletRadius, paint);

        if (mWantColor) {
            paint.setColor(oldcolor);
        }

        paint.setStyle(style);
    }
}
 
Example 3
Source File: HighlightEditor.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
@Override
public void onPopupChangePosition() {
    try {
        Layout layout = getLayout();
        if (layout != null) {
            int pos = getSelectionStart();
            int line = layout.getLineForOffset(pos);
            int baseline = layout.getLineBaseline(line);
            int ascent = layout.getLineAscent(line);

            float x = layout.getPrimaryHorizontal(pos);
            float y = baseline + ascent;

            int offsetHorizontal = (int) x + mLinePadding;
            setDropDownHorizontalOffset(offsetHorizontal);

            int heightVisible = getHeightVisible();
            int offsetVertical = 0;
            if (verticalScroll != null) {
                offsetVertical = (int) ((y + mCharHeight) - verticalScroll.getScrollY());
            } else {
                offsetVertical = (int) ((y + mCharHeight) - getScrollY());
            }

            int tmp = offsetVertical + getDropDownHeight() + mCharHeight;
            if (tmp < heightVisible) {
                tmp = offsetVertical + mCharHeight / 2;
                setDropDownVerticalOffset(tmp);
            } else {
                tmp = offsetVertical - getDropDownHeight() - mCharHeight;
                setDropDownVerticalOffset(tmp);
            }
        }
    } catch (Exception ignored) {
    }
}
 
Example 4
Source File: ColorsText.java    From JsDroidEditor with Mozilla Public License 2.0 5 votes vote down vote up
public int getSelectLine() {
    Layout layout = getLayout();
    if (getSelectionStart() != getSelectionEnd()) {
        return -1;
    }
    return layout.getLineForOffset(getSelectionStart());
}
 
Example 5
Source File: ColorsText.java    From JsDroidEditor with Mozilla Public License 2.0 5 votes vote down vote up
Rect getCursorRect() {
        Layout layout = getLayout();
        final int offset = getSelectionStart();
        final int line = layout.getLineForOffset(offset);
        final int top = layout.getLineTop(line);
        final int bottom = layout.getLineTop(line + 1);
        float horizontal = layout.getSecondaryHorizontal(offset);
//        horizontal = Math.max(0.5f, horizontal - 0.5f);
        int left = (int) (horizontal);
        return new Rect(left, top, left + DpiUtils.dip2px(getContext(), 1), bottom);
    }
 
Example 6
Source File: EditTextBoldCursor.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
private boolean updateCursorPosition() {
    final Layout layout = getLayout();
    final int offset = getSelectionStart();
    final int line = layout.getLineForOffset(offset);
    final int top = layout.getLineTop(line);
    final int bottom = layout.getLineTop(line + 1);
    updateCursorPosition(top, bottom, layout.getPrimaryHorizontal(offset));
    return true;
}
 
Example 7
Source File: BulletSpan.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void drawLeadingMargin(Canvas canvas, Paint paint, int x, int dir,
                              int top, int baseline, int bottom,
                              CharSequence text, int start, int end,
                              boolean first, Layout layout) {
    if (((Spanned) text).getSpanStart(this) == start) {
        Paint.Style style = paint.getStyle();
        int oldcolor = 0;

        if (mWantColor) {
            oldcolor = paint.getColor();
            paint.setColor(mColor);
        }

        paint.setStyle(Paint.Style.FILL);

        if (layout != null) {
            // "bottom" position might include extra space as a result of line spacing
            // configuration. Subtract extra space in order to show bullet in the vertical
            // center of characters.
            final int line = layout.getLineForOffset(start);
            int spacing = line != layout.getLineCount() - 1 ? (int) layout.getSpacingAdd() : 0;
            bottom = bottom - spacing;
        }

        final float yPosition = (top + bottom) / 2f;
        final float xPosition = x + dir * mBulletRadius;

        canvas.drawCircle(xPosition, yPosition, mBulletRadius, paint);

        if (mWantColor) {
            paint.setColor(oldcolor);
        }

        paint.setStyle(style);
    }
}
 
Example 8
Source File: BaseKeyListener.java    From android_9.0.0_r45 with Apache License 2.0 5 votes vote down vote up
private boolean deleteLine(View view, Editable content) {
    if (view instanceof TextView) {
        final Layout layout = ((TextView) view).getLayout();
        if (layout != null) {
            final int line = layout.getLineForOffset(Selection.getSelectionStart(content));
            final int start = layout.getLineStart(line);
            final int end = layout.getLineEnd(line);
            if (end != start) {
                content.delete(start, end);
                return true;
            }
        }
    }
    return false;
}
 
Example 9
Source File: SearchableBaseNoteFragment.java    From nextcloud-notes with GNU General Public License v3.0 5 votes vote down vote up
private void jumpToOccurrence() {
    Layout layout = getLayout();
    if (layout == null) {
        Log.w(TAG, "getLayout() is null");
    } else if (getContent() == null || getContent().isEmpty()) {
        Log.w(TAG, "getContent is null or empty");
    } else if (currentOccurrence < 1) {
        // if currentOccurrence is lower than 1, jump to last occurrence
        currentOccurrence = occurrenceCount;
        jumpToOccurrence();
    } else if (searchQuery != null && !searchQuery.isEmpty()) {
        String currentContent = getContent().toLowerCase();
        int indexOfNewText = indexOfNth(currentContent, searchQuery.toLowerCase(), 0, currentOccurrence);
        if (indexOfNewText <= 0) {
            // Search term is not n times in text
            // Go back to first search result
            if (currentOccurrence != 1) {
                currentOccurrence = 1;
                jumpToOccurrence();
            }
            return;
        }
        String textUntilFirstOccurrence = currentContent.substring(0, indexOfNewText);
        int numberLine = layout.getLineForOffset(textUntilFirstOccurrence.length());

        if (numberLine >= 0) {
            ScrollView scrollView = getScrollView();
            if (scrollView != null) {
                scrollView.post(() -> scrollView.smoothScrollTo(0, layout.getLineTop(numberLine)));
            }
        }
    }
}
 
Example 10
Source File: RichEditorView.java    From Spyglass with Apache License 2.0 5 votes vote down vote up
/**
 * @return current line number of the cursor, or -1 if no cursor
 */
public int getCurrentCursorLine() {
    int selectionStart = mMentionsEditText.getSelectionStart();
    Layout layout = mMentionsEditText.getLayout();
    if (layout != null && !(selectionStart == -1)) {
        return layout.getLineForOffset(selectionStart);
    }
    return -1;
}
 
Example 11
Source File: ImprovedBulletSpan.java    From PhoneProfilesPlus with Apache License 2.0 5 votes vote down vote up
public void drawLeadingMargin(Canvas canvas, Paint paint, int x, int dir,
                              int top, int baseline, int bottom, CharSequence text,
                              int start, int end, boolean first, Layout layout) {

    if (((Spanned)text).getSpanStart(this) == start) {
        Style style = paint.getStyle();
        paint.setStyle(Style.FILL);

        float yPosition;
        if (layout != null) {
            int line = layout.getLineForOffset(start);
            yPosition = (float)layout.getLineBaseline(line) - (float)this.bulletRadius * 2.0F;
        } else {
            yPosition = (float)(top + bottom) / 2.0F;
        }

        float xPosition = (float)(x + dir * this.bulletRadius);

        if (canvas.isHardwareAccelerated()) {
            if (this.mBulletPath == null) {
                this.mBulletPath = new Path();
                this.mBulletPath.addCircle(0.0F, 0.0F, (float)this.bulletRadius, Direction.CW);
            }

            canvas.save();
            canvas.translate(xPosition, yPosition);
            canvas.drawPath(this.mBulletPath, paint);
            canvas.restore();
        } else {
            canvas.drawCircle(xPosition, yPosition, (float)this.bulletRadius, paint);
        }

        paint.setStyle(style);
    }

}
 
Example 12
Source File: OverlineSpan.java    From Dashchan with Apache License 2.0 5 votes vote down vote up
public static void draw(TextView textView, Canvas canvas) {
	Layout layout = textView.getLayout();
	if (layout != null) {
		CharSequence text = textView.getText();
		if (text instanceof Spanned) {
			Spanned spanned = (Spanned) text;
			OverlineSpan[] spans = spanned.getSpans(0, spanned.length(), OverlineSpan.class);
			if (spans != null && spans.length > 0) {
				int paddingTop = textView.getTotalPaddingTop();
				int paddingLeft = textView.getPaddingLeft();
				int shift = (int) (textView.getTextSize() * 8f / 9f);
				float thickness = textView.getTextSize() / 15f - 0.25f;
				int color = textView.getCurrentTextColor();
				PAINT.setColor(color);
				PAINT.setStrokeWidth(thickness);
				for (OverlineSpan span : spans) {
					int start = spanned.getSpanStart(span);
					int end = spanned.getSpanEnd(span);
					int lineStart = layout.getLineForOffset(start);
					int lineEnd = layout.getLineForOffset(end);
					for (int i = lineStart; i <= lineEnd; i++) {
						float left = i == lineStart ? layout.getPrimaryHorizontal(start) : layout.getLineLeft(i);
						float right = i == lineEnd ? layout.getPrimaryHorizontal(end) : layout.getLineRight(i);
						float top = layout.getLineBaseline(i) - shift + 0.5f;
						canvas.drawLine(paddingLeft + left, paddingTop + top, paddingLeft + right,
								paddingTop + top, PAINT);
					}
				}
			}
		}
	}
}
 
Example 13
Source File: CodeTextView.java    From Markwon with Apache License 2.0 4 votes vote down vote up
private void draw(
        @NonNull View view,
        @NonNull Canvas canvas,
        @NonNull Layout layout
) {

    final CharSequence cs = layout.getText();
    if (!(cs instanceof Spanned)) {
        return;
    }
    final Spanned spanned = (Spanned) cs;

    final int save = canvas.save();
    try {
        canvas.translate(view.getPaddingLeft(), view.getPaddingTop());

        // TODO: block?
        // TODO: we must remove _original_ spans
        // TODO: cache (attach a listener?)
        // TODO: editor?

        final CodeSpan[] spans = spanned.getSpans(0, spanned.length(), CodeSpan.class);
        if (spans != null && spans.length > 0) {
            for (CodeSpan span : spans) {

                final int startOffset = spanned.getSpanStart(span);
                final int endOffset = spanned.getSpanEnd(span);

                final int startLine = layout.getLineForOffset(startOffset);
                final int endLine = layout.getLineForOffset(endOffset);

                // do we need to round them?
                final float left = layout.getPrimaryHorizontal(startOffset)
                        + (-1 * layout.getParagraphDirection(startLine) * paddingHorizontal);

                final float right = layout.getPrimaryHorizontal(endOffset)
                        + (layout.getParagraphDirection(endLine) * paddingHorizontal);

                final float top = getLineTop(layout, startLine, paddingVertical);
                final float bottom = getLineBottom(layout, endLine, paddingVertical);

                Debug.i(new RectF(left, top, right, bottom).toShortString());

                if (startLine == endLine) {
                    canvas.drawRect(left, top, right, bottom, paint);
                } else {
                    // draw first line (start until the lineEnd)
                    // draw everything in-between (startLine - endLine)
                    // draw last line (lineStart until the end

                    canvas.drawRect(
                            left,
                            top,
                            layout.getLineRight(startLine),
                            getLineBottom(layout, startLine, paddingVertical),
                            paint
                    );

                    for (int line = startLine + 1; line < endLine; line++) {
                        canvas.drawRect(
                                layout.getLineLeft(line),
                                getLineTop(layout, line, paddingVertical),
                                layout.getLineRight(line),
                                getLineBottom(layout, line, paddingVertical),
                                paint
                        );
                    }

                    canvas.drawRect(
                            layout.getLineLeft(endLine),
                            getLineTop(layout, endLine, paddingVertical),
                            right,
                            getLineBottom(layout, endLine, paddingVertical),
                            paint
                    );
                }
            }
        }
    } finally {
        canvas.restoreToCount(save);
    }
}
 
Example 14
Source File: TextSpec.java    From litho with Apache License 2.0 4 votes vote down vote up
@OnPopulateExtraAccessibilityNode
static void onPopulateExtraAccessibilityNode(
    AccessibilityNodeInfoCompat node,
    int extraNodeIndex,
    int componentBoundsLeft,
    int componentBoundsTop,
    @Prop(resType = ResType.STRING) CharSequence text,
    @FromBoundsDefined Layout textLayout,
    @FromBoundsDefined ClickableSpan[] clickableSpans) {
  if (!(text instanceof Spanned)) {
    return;
  }

  final Spanned spanned = (Spanned) text;

  final ClickableSpan span = clickableSpans[extraNodeIndex];
  final int start = spanned.getSpanStart(span);
  final int end = spanned.getSpanEnd(span);
  final int startLine = textLayout.getLineForOffset(start);
  final int endLine = textLayout.getLineForOffset(end);

  // The bounds for multi-line strings should *only* include the first line.  This is because
  // Talkback triggers its click at the center point of these bounds, and if that center point
  // is outside the spannable, it will click on something else.  There is no harm in not outlining
  // the wrapped part of the string, as the text for the whole string will be read regardless of
  // the bounding box.
  final int selectionPathEnd =
      startLine == endLine ? end : textLayout.getLineVisibleEnd(startLine);

  textLayout.getSelectionPath(start, selectionPathEnd, sTempPath);
  sTempPath.computeBounds(sTempRectF, /* unused */ true);

  sTempRect.set(
      componentBoundsLeft + (int) sTempRectF.left,
      componentBoundsTop + (int) sTempRectF.top,
      componentBoundsLeft + (int) sTempRectF.right,
      componentBoundsTop + (int) sTempRectF.bottom);

  if (sTempRect.isEmpty()) {
    // Text is not actually visible.
    // Override bounds so it doesn't crash ExploreByTouchHelper.java
    sTempRect.set(0, 0, 1, 1);
    node.setBoundsInParent(sTempRect);
    node.setContentDescription(""); // make node non-focusable
    return;
  }

  node.setBoundsInParent(sTempRect);

  node.setClickable(true);
  node.setFocusable(true);
  node.setEnabled(true);
  node.setVisibleToUser(true);
  node.setText(spanned.subSequence(start, end));
  if (span instanceof AccessibleClickableSpan) {
    AccessibleClickableSpan accessibleClickableSpan = (AccessibleClickableSpan) span;
    String contentDescription = accessibleClickableSpan.getAccessibilityDescription();
    String role = accessibleClickableSpan.getAccessibilityRole();
    if (contentDescription != null) {
      node.setContentDescription(contentDescription);
    }
    if (role != null) {
      node.setClassName(role);
    } else {
      node.setClassName(AccessibilityRole.BUTTON);
    }
  } else {
    node.setClassName(AccessibilityRole.BUTTON);
  }
}
 
Example 15
Source File: RNLinearTextGradientSpan.java    From react-native-text-gradient with MIT License 4 votes vote down vote up
RNLinearTextGradientSpan(
  float[] locations,
  int[] colors,
  float[] start,
  float[] end,
  boolean useViewFrame,
  Layout layout,
  int textStart,
  int textEnd,
  float maxWidth,
  float maxHeight,
  String text
) {
  if (
    start != null &&
    end != null &&
    colors != null &&
    locations != null &&
    text != null &&
    !YogaConstants.isUndefined(maxWidth) &&
    maxWidth != 0 &&
    maxHeight != 0 &&
    layout != null
  ) {
    Path path = new Path();
    RectF bounds = new RectF();
    layout.getSelectionPath(textStart, textEnd, path);
    path.computeBounds(bounds, true);

    if (layout.getLineForOffset(textEnd - 1) != layout.getLineForOffset(textEnd)) {
      RectF lastSymbolBounds = new RectF();
      layout.getSelectionPath(textEnd - 1, textEnd, path);
      path.computeBounds(lastSymbolBounds, true);

      if (lastSymbolBounds.contains(bounds) && bounds.contains(lastSymbolBounds)) {
        layout.getSelectionPath(textStart, textEnd - 1, path);
        path.computeBounds(bounds, true);
      }
    }

    float width = useViewFrame ? maxWidth : bounds.width();
    float height = useViewFrame ? maxHeight : bounds.height();
    float x0 = (useViewFrame ? 0 : bounds.left) + start[0] * width;
    float y0 = (useViewFrame ? 0 : bounds.top) + start[1] * height;
    float x1 = (useViewFrame ? 0 : bounds.left) + end[0] * width;
    float y1 = (useViewFrame ? 0 : bounds.top) + end[1] * height;

    mGradient = new LinearGradient(x0, y0, x1, y1, colors, locations, Shader.TileMode.CLAMP);
  }
}
 
Example 16
Source File: TextProcessor.java    From CodeEditor with Apache License 2.0 4 votes vote down vote up
@Override
public void onDraw(@NonNull Canvas canvas) {
    if (!isInEditMode()) {
        int top;
        Layout layout = getLayout();
        if (layout != null && codeEditor != null && mHighlightCurrentLine) {
            int currentLineStart = codeEditor.getLineForIndex(getSelectionStart());
            if (currentLineStart == codeEditor.getLineForIndex(getSelectionEnd())) {
                int selectedLineStartIndex = codeEditor.getIndexForStartOfLine(currentLineStart);
                int selectedLineEndIndex = codeEditor.getIndexForEndOfLine(currentLineStart);
                int topVisualLine = layout.getLineForOffset(selectedLineStartIndex);
                int bottomVisualLine = layout.getLineForOffset(selectedLineEndIndex);
                int left = mGutterWidth;
                if (!mShowLineNumbers)
                    left = 0; //убираем отступ для Paint'а если номера строк выключены
                top = layout.getLineTop(topVisualLine) + getPaddingTop();
                int right = (layout.getWidth() + getPaddingLeft()) + getPaddingRight();
                int bottom = layout.getLineBottom(bottomVisualLine) + getPaddingTop();
                canvas.drawRect(left, top, right, bottom, mSelectedLinePaint);
            }
        }
        super.onDraw(canvas);
        if (layout != null && mShowLineNumbers) {
            int prevLineNumber = -1;
            canvas.drawRect(getScrollX(), getScrollY(),
                    mGutterWidth + getScrollX(),
                    getScrollY() + getHeight(), mGutterBackgroundPaint);
            int paddingTop = getPaddingTop();
            int max = mLineUtils.getBottomVisibleLine(this);
            int textRight = (mGutterWidth - mIdealMargin / 2) + getScrollX();
            if (codeEditor != null) {
                int i = mLineUtils.getTopVisibleLine(this);
                if (i >= 2) {
                    i -= 2;
                } else {
                    i = 0;
                }
                while (i <= max) {
                    int number = codeEditor.getLineForIndex(getLayout().getLineStart(i));
                    if (number != prevLineNumber) {
                        canvas.drawText(Integer.toString(number + 1), textRight,
                                layout.getLineBaseline(i) + paddingTop, mLineNumberPaint);
                    }
                    prevLineNumber = number;
                    i++;
                }
                top = getScrollY();
                canvas.drawLine(mGutterWidth + getScrollX(), top,
                        mGutterWidth + getScrollX(), top + getHeight(), mLinePaint);
            }
        }
    }
}
 
Example 17
Source File: TextProcessor.java    From CodeEditor with Apache License 2.0 4 votes vote down vote up
protected void onPopupChangePosition() {
        try {
            Layout layout = getLayout();
            if (layout != null) {

                int pos = getSelectionStart();
                int line = layout.getLineForOffset(pos);
                int baseline = layout.getLineBaseline(line);
                int ascent = layout.getLineAscent(line);

                Rect bounds = new Rect();
                Paint textPaint = getPaint();
                String sample="A";
                textPaint.getTextBounds(sample, 0, sample.length(), bounds);
                int width = bounds.width()/sample.length();


                float x = layout.getPrimaryHorizontal(pos);
                float y = baseline + ascent;

                int offsetHorizontal = (int) x + mGutterWidth;
                setDropDownHorizontalOffset(offsetHorizontal);

                int heightVisible = getHeightVisible();
                int offsetVertical = (int) ((y + mCharHeight) - getScrollY());

                int tmp = offsetVertical + getDropDownHeight() + mCharHeight;
                //if (tmp < heightVisible) {
                    tmp = -h + ((offsetVertical*2 / (mCharHeight)) * (mCharHeight / 2))+(mCharHeight/2);
                    setDropDownVerticalOffset(tmp);
                    //((Activity)(mContext)).setTitle("ov :"+offsetVertical +" ch "+mCharHeight+" tmp"+tmp +"h "+h+"p:"+pos);
//                } else {
//                    tmp = offsetVertical - getDropDownHeight() - mCharHeight;
//                    setDropDownVerticalOffset(tmp);
//                    ((Activity)(mContext)).setTitle(" 2 tmp :"+tmp);
//                }


//                int pos = getSelectionStart();
//                int line = layout.getLineForOffset(pos);
//                int baseline = layout.getLineBaseline(line);
//                int ascent = layout.getLineAscent(line);
//
//                float x = layout.getPrimaryHorizontal(pos);
//                float y = baseline + ascent;
//
//                int offsetHorizontal = (int) x + mGutterWidth;
//                setDropDownHorizontalOffset(offsetHorizontal);
//
//                //    int heightVisible = getHeightVisible();
//                int offsetVertical = (int) ((y + mCharHeight) - getScrollY());
//
//                int tmp = offsetVertical + getDropDownHeight() + mCharHeight;
////                if (tmp < heightVisible) {
//                tmp = -(offsetVertical + mCharHeight) + ((offsetVertical / mCharHeight) * (mCharHeight / 2));
//                setDropDownVerticalOffset(tmp);
////                } else {
////                    tmp = offsetVertical - getDropDownHeight() - mCharHeight;
////                    setDropDownVerticalOffset(tmp);
////                }

            }
        } catch (Exception e) {
            Logger.error(TAG, e);
        }
    }