Example usage for android.text SpannableString getSpanEnd

List of usage examples for android.text SpannableString getSpanEnd

Introduction

In this page you can find the example usage for android.text SpannableString getSpanEnd.

Prototype

public int getSpanEnd(Object tag);

Source Link

Document

Return the end of the range of text to which the specified markup object is attached, or -1 if the object is not attached.

Usage

From source file:com.android.screenspeak.menurules.RuleSpannables.java

@Override
public List<ContextMenuItem> getMenuItemsForNode(ScreenSpeakService service,
        ContextMenuItemBuilder menuItemBuilder, AccessibilityNodeInfoCompat node) {
    final SpannableString spannable = (SpannableString) node.getText();
    final URLSpan[] urlSpans = spannable.getSpans(0, spannable.length(), URLSpan.class);
    final LinkedList<ContextMenuItem> result = new LinkedList<>();

    if ((urlSpans == null) || (urlSpans.length == 0)) {
        return result;
    }/*from   ww w  . j  a va  2  s .c o m*/

    for (int i = 0; i < urlSpans.length; i++) {
        final URLSpan urlSpan = urlSpans[i];
        final String url = urlSpan.getURL();
        final int start = spannable.getSpanStart(urlSpan);
        final int end = spannable.getSpanEnd(urlSpan);
        final CharSequence label = spannable.subSequence(start, end);
        if (TextUtils.isEmpty(url) || TextUtils.isEmpty(label)) {
            continue;
        }

        final Uri uri = Uri.parse(url);
        if (uri.isRelative()) {
            // Generally, only absolute URIs are resolvable to an activity
            continue;
        }

        final ContextMenuItem item = menuItemBuilder.createMenuItem(service, Menu.NONE, i, Menu.NONE, label);
        item.setOnMenuItemClickListener(new SpannableMenuClickListener(service, uri));
        result.add(item);
    }

    return result;
}

From source file:com.android.talkback.menurules.RuleSpannables.java

@Override
public List<ContextMenuItem> getMenuItemsForNode(TalkBackService service,
        ContextMenuItemBuilder menuItemBuilder, AccessibilityNodeInfoCompat node) {
    final LinkedList<ContextMenuItem> result = new LinkedList<>();

    final SpannableString spannable = getStringWithUrlSpan(node);
    if (spannable == null) {
        return result;
    }//w  ww  . j a  v a 2s.  c  o  m

    final URLSpan[] urlSpans = spannable.getSpans(0, spannable.length(), URLSpan.class);
    if ((urlSpans == null) || (urlSpans.length == 0)) {
        return result;
    }

    for (int i = 0; i < urlSpans.length; i++) {
        final URLSpan urlSpan = urlSpans[i];
        final String url = urlSpan.getURL();
        final int start = spannable.getSpanStart(urlSpan);
        final int end = spannable.getSpanEnd(urlSpan);
        final CharSequence label = spannable.subSequence(start, end);
        if (TextUtils.isEmpty(url) || TextUtils.isEmpty(label)) {
            continue;
        }

        final Uri uri = Uri.parse(url);
        if (uri.isRelative()) {
            // Generally, only absolute URIs are resolvable to an activity
            continue;
        }

        final ContextMenuItem item = menuItemBuilder.createMenuItem(service, Menu.NONE, i, Menu.NONE, label);
        item.setOnMenuItemClickListener(new SpannableMenuClickListener(service, uri));
        result.add(item);
    }

    return result;
}

From source file:cn.dreamtobe.emoji.ellipsize.helper.SpanEllipsizeEndHelper.java

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static CharSequence matchMaxWidth(SpannableString targetText, TextView textView) {
    if (targetText.length() <= 0) {
        return targetText;
    }/*from  w w  w .  j a  v  a2 s. com*/

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
        return targetText;
    }

    if (textView == null) {
        return targetText;
    }

    final int maxWidth = textView.getMaxWidth();

    if (maxWidth <= 0 || maxWidth >= Integer.MAX_VALUE) {
        return targetText;
    }

    if (textView.getEllipsize() != TextUtils.TruncateAt.END) {
        return targetText;
    }

    //TODO Multi-lines support
    if (textView.getMaxLines() != 1) {
        return targetText;
    }

    final String maxWidthKey = getMaxWidthKey(targetText, textView);
    SpannableString tmpText = SPAN_MAXWIDTH_CACHE.get(maxWidthKey);
    if (tmpText != null) {
        removeClickableSpan(tmpText);
        return tmpText;
    }

    TextPaint textPaint = textView.getPaint();
    if (textPaint == null) {
        return targetText;
    }

    final int totalWidth = (int) textPaint.measureText(targetText, 0, targetText.length());
    if (totalWidth <= maxWidth) {
        return targetText;
    }

    final long startTime = System.currentTimeMillis();
    // deal maxwitdh

    final int dotWidth = (int) textPaint.measureText("...");

    tmpText = targetText;

    int start = 0;
    int end = targetText.length();

    // targetX is maxWidth - "...".length
    int targetX = maxWidth - dotWidth;

    //dichotomy: get x most touch targetX
    int middle = targetText.length();
    int x = 0;
    while (start <= end) {
        // tx = targetX, tl = targetLength

        // width:  0           x
        // length: 0         middle           end
        //         -------------|-------------
        middle = (start + end) / 2;

        int emojiDraW = 0;
        int emojiStrW = 0;

        int emojiExcursion = 1;

        final Object[] tmpSpans = tmpText.getSpans(0, middle, Object.class);
        if (tmpSpans != null) {
            for (Object tmpSpan : tmpSpans) {
                final int tmpStart = tmpText.getSpanStart(tmpSpan);
                final int tmpEnd = tmpText.getSpanEnd(tmpSpan);

                //middle in (tmpStart, tmpEnd)
                if (tmpStart < middle && tmpEnd > middle) {
                    middle = tmpEnd;
                    emojiExcursion = tmpEnd - tmpStart;
                }
            }

            // TextPaint#measure do not attention span, so adjust by ourselves
            for (Object tmpSpan : tmpSpans) {
                final int tmpStart = tmpText.getSpanStart(tmpSpan);
                final int tmpEnd = tmpText.getSpanEnd(tmpSpan);

                // TODO support other span
                if (tmpStart < middle && tmpSpan instanceof ImageSpan) {
                    emojiDraW += ((ImageSpan) tmpSpan).getDrawable().getBounds().width();
                    emojiStrW += textPaint.measureText(tmpText, tmpStart, tmpEnd);
                }
            }

        }

        x = (int) textPaint.measureText(tmpText, 0, middle);
        x = x - emojiStrW + emojiDraW;

        //            x = (int) (textPaint.measureText(pureStr, 0, pureStr.length()) + emojiWidth);

        //            Log.d(TAG, String.format("targetX: %d, currentX: %d, currentLength: %d, totalLength: %d, emojiStrW[%d], emojiDraW[%d]", targetX, x, middle, targetText.length(), emojiStrW, emojiDraW));

        if (x > targetX) {
            // width:  0       tx        x
            // length: start   tl      middle         end
            //             ----|---------|-------------
            // TO:     start   |       *end
            //             ----|--------|--------------
            end = middle - emojiExcursion;
        } else if (x < targetX) {
            // width:  0               x       tx
            // length: start         middle    tl     end
            //           --------------|-------|------
            // TO:                      *start  |       end
            //           ---------------|------|------
            start = middle + 1;
        } else {
            break;
        }
    }

    // adjust x larger targetX
    while (x > targetX && middle > 0) {
        x = (int) textPaint.measureText(tmpText, 0, --middle);
    }

    // adjust x middle emoji span
    final Object[] ajustSpans = tmpText.getSpans(0, tmpText.length(), Object.class);
    for (Object adjustSpan : ajustSpans) {
        final int adjustStart = tmpText.getSpanStart(adjustSpan);
        final int adjustEnd = tmpText.getSpanEnd(adjustSpan);

        //[adjustStart, adjustEnd)
        if (middle >= adjustStart && middle < adjustEnd) {
            middle = adjustStart - 1;
            break;
        }
    }

    // finnal middle

    // sub sequence [0, middle + 1) & remove [middle +1, length] spans
    tmpText = (SpannableString) tmpText.subSequence(0, middle + 1);
    //        Log.d(TAG, String.format("sub Sequence[0, %d), [%s] to [%s]", middle + 1, targetText, tmpText));

    // add ...
    final SpannableString maxWidthSS = new SpannableString(tmpText + "...");

    final Object[] maxWidthSpans = tmpText.getSpans(0, tmpText.length(), Object.class);
    if (maxWidthSpans != null) {
        for (Object maxWidthSpan : maxWidthSpans) {
            final int mwSpanStart = tmpText.getSpanStart(maxWidthSpan);
            final int mwSpanEnd = tmpText.getSpanEnd(maxWidthSpan);
            final int mwSpanFlag = tmpText.getSpanFlags(maxWidth);

            maxWidthSS.setSpan(maxWidthSpan, mwSpanStart, mwSpanEnd, mwSpanFlag);
        }
    }

    targetText = maxWidthSS;

    SPAN_MAXWIDTH_CACHE.put(maxWidthKey, targetText);
    Log.d(TAG, String.format("deal maxWidth %d", System.currentTimeMillis() - startTime));

    return targetText;
}

From source file:me.albertonicoletti.latex.activities.EditorActivity.java

/**
 * Used to maintain the same indentation as the upper line
 * @param editable Text/* w  ww  . j a v  a  2  s.c o  m*/
 * @param spannable Spannable
 * @param span Modified span
 */
private void autoIndentAndTabEditor(Editable editable, SpannableString spannable, RelativeSizeSpan span) {
    int beginIndex = spannable.getSpanStart(span);
    int endIndex = spannable.getSpanEnd(span);
    // If the last written character is a newline
    if (editable.length() > 0) {
        if (editable.charAt(endIndex - 1) == '\n') {
            int lineModified = editor.getLayout().getLineForOffset(beginIndex);
            int modifiedBeginIndex = editor.getLayout().getLineStart(lineModified);
            int modifiedEndIndex = editor.getLayout().getLineEnd(lineModified);
            String str = editable.subSequence(modifiedBeginIndex, modifiedEndIndex).toString();
            // Collects the whitespaces and tabulations in the upper line
            String whitespaces = "";
            int i = 0;
            while (str.charAt(i) == ' ' || str.charAt(i) == '\t') {
                whitespaces += str.charAt(i);
                i++;
            }
            // And inserts them in the newline
            editable.insert(beginIndex + 1, whitespaces);
        }
        if (editable.charAt(endIndex - 1) == '\t') {
            int tabSize = Integer.valueOf(PreferenceManager.getDefaultSharedPreferences(this)
                    .getString(SettingsActivity.TAB_SIZE, ""));
            String whitespaces = "";
            for (int i = 0; i < tabSize; i++) {
                whitespaces += " ";
            }
            editable.replace(beginIndex, beginIndex + 1, whitespaces);
        }
    }
}

From source file:org.thoughtcrime.securesms.ConversationItem.java

private SpannableString linkifyMessageBody(SpannableString messageBody, boolean shouldLinkifyAllLinks) {
    boolean hasLinks = Linkify.addLinks(messageBody, shouldLinkifyAllLinks ? Linkify.ALL : 0);

    if (hasLinks) {
        URLSpan[] urlSpans = messageBody.getSpans(0, messageBody.length(), URLSpan.class);
        for (URLSpan urlSpan : urlSpans) {
            int start = messageBody.getSpanStart(urlSpan);
            int end = messageBody.getSpanEnd(urlSpan);
            messageBody.setSpan(new LongClickCopySpan(urlSpan.getURL()), start, end,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }//from  w  ww.  j  a va2  s  .c om
    }
    return messageBody;
}

From source file:org.de.jmg.learn._MainActivity.java

public void getVokabel(final boolean showBeds, boolean LoadNext, boolean requestFocusEdWord, boolean DontPrompt)
        throws Exception {

    if (iv != null) {
        iv.setVisibility(View.GONE);
    }/* ww w . j  av  a  2s .  com*/
    if (iv2 != null)
        iv2.setVisibility(View.GONE);
    try {
        if (_btnRight == null)
            return;
        EndEdit(DontPrompt);
        setBtnsEnabled(true);
        if (showBeds && _vok.getIndex() >= 1) {
            _btnRight.setEnabled(true);
            _btnWrong.setEnabled(true);
            _btnEdit.setEnabled(true);
            _btnSkip.setEnabled(true);
            _btnView.setEnabled(true);
        } else {
            _btnRight.setEnabled(false);
            _btnWrong.setEnabled(false);
            if (_vok.getIndex() < 1) {
                _btnEdit.setEnabled(false);
                _btnSkip.setEnabled(false);
                _btnView.setEnabled(false);
            }
        }
        if (LoadNext)
            _vok.setLernIndex((short) (_vok.getLernIndex() + 1));

        View v;
        TextView t;
        String txtBed = getString(R.string.cloze);

        if (showBeds) {
            v = findViewById(R.id.txtMeaning1);
            t = (TextView) v;
            assert t != null;
            t.setText(lib.getSpanableString(_vok.getBedeutung1()));
            txtBed = t.getText().toString();
        }

        v = findViewById(R.id.word);
        t = (TextView) v;
        assert t != null;
        String txtWord = getString(R.string.cloze);
        if (!_vok.reverse || showBeds) {
            t.setText(lib.getSpanableString(_vok.getWort()), TextView.BufferType.SPANNABLE);
            txtWord = t.getText().toString();
            txtWord = replaceClozes(txtWord, txtBed);
            speak(txtWord, _vok.getLangWord(), "word", true);
        } else {
            t.setText("");
        }

        if (_vok.getSprache() == EnumSprachen.Hebrew || _vok.getSprache() == EnumSprachen.Griechisch
                || (_vok.getFontWort().getName().equalsIgnoreCase("Cardo"))) {
            t.setTypeface(_vok.TypefaceCardo);
            _txtedWord.setTypeface(_vok.TypefaceCardo);
        } else {
            t.setTypeface(Typeface.DEFAULT);
            _txtedWord.setTypeface(Typeface.DEFAULT);
        }
        t.scrollTo(0, 0);

        v = findViewById(R.id.Comment);
        t = (TextView) v;
        assert t != null;
        t.setVisibility(View.VISIBLE);

        SpannableString tspanKom = lib.getSpanableString(_vok.getKommentar());
        URLSpan[] urlSpans = tspanKom.getSpans(0, tspanKom.length(), URLSpan.class);
        for (final URLSpan span : urlSpans) {
            int start = tspanKom.getSpanStart(span);
            int end = tspanKom.getSpanEnd(span);
            String txt = tspanKom.toString().substring(start, end);
            if (txtIsPicture(txt)) {
                tspanKom.removeSpan(span);
                tspanKom.setSpan(new urlclickablespan(span.getURL()) {
                    @Override
                    public void onClick(View widget) {
                        Bitmap b;
                        try {
                            b = lib.downloadpicture(this.url);
                        } catch (Exception ex) {
                            b = null;
                        }
                        if (b != null) {
                            if (iv == null) {
                                iv = new ImageView(context);
                                SetTouchListener(iv);
                            }
                            b = resizeBM(b);
                            iv.setImageBitmap(b);
                            if (iv.getParent() == null) {
                                try {
                                    LayoutParams p = _txtMeaning1.getLayoutParams();
                                    //p.width = LayoutParams.WRAP_CONTENT;
                                    //p.height = LayoutParams.WRAP_CONTENT;
                                    rellayoutMain.addView(iv, p);
                                } catch (Exception ex) {
                                    Log.e("addImageView", ex.getMessage(), ex);
                                }
                            } else {
                                Log.d("ImageView", "exists");
                            }
                            _txtMeaning1.setVisibility(View.GONE);
                            iv.setVisibility(View.VISIBLE);
                        }
                    }
                }, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
        t.setText(tspanKom, TextView.BufferType.SPANNABLE);

        if (_vok.getSprache() == EnumSprachen.Hebrew || _vok.getSprache() == EnumSprachen.Griechisch
                || (_vok.getFontKom().getName().equalsIgnoreCase("Cardo"))) {
            t.setTypeface(_vok.TypefaceCardo);
            _txtedKom.setTypeface(_vok.TypefaceCardo);
        } else {
            t.setTypeface(Typeface.DEFAULT);
            _txtedKom.setTypeface(Typeface.DEFAULT);
        }
        if (_isSmallDevice && libString.IsNullOrEmpty(t.getText().toString())) {
            t.setVisibility(View.GONE);
        } else {
            t.setVisibility(View.VISIBLE);
        }
        t.scrollTo(0, 0);

        v = findViewById(R.id.txtMeaning1);
        t = (TextView) v;
        assert t != null;
        if (!libString.IsNullOrEmpty(_vok.getBedeutung2())) {
            t.setImeOptions(EditorInfo.IME_ACTION_NEXT);
        }
        if (_vok.reverse || showBeds) {
            SpannableString tspan = lib.getSpanableString(_vok.getBedeutung1());
            //final String picname = _main.getString(R.string.picture);
            t.setVisibility(View.VISIBLE);
            if (txtIsPicture(tspan.toString())) {
                URLSpan urlspn[] = tspan.getSpans(0, tspan.length(), URLSpan.class);
                for (URLSpan url : urlspn) {
                    Bitmap b;
                    try {
                        b = lib.downloadpicture(url.getURL());
                    } catch (Exception ex) {
                        b = null;
                    }
                    if (b != null) {
                        if (iv == null) {
                            iv = new ImageView(context);
                            SetTouchListener(iv);
                        }
                        b = resizeBM(b);
                        iv.setImageBitmap(b);
                        if (iv.getParent() == null) {
                            try {
                                LayoutParams p = t.getLayoutParams();
                                //p.width = LayoutParams.WRAP_CONTENT;
                                //p.height = LayoutParams.WRAP_CONTENT;
                                rellayoutMain.addView(iv, p);
                            } catch (Exception ex) {
                                Log.e("Imagview", ex.getMessage(), ex);
                            }
                        } else {
                            Log.d("ImageView", "exists");
                        }
                        t.setVisibility(View.GONE);
                        iv.setVisibility(View.VISIBLE);
                    }
                }

            } else {
                // iv.setVisibility(View.GONE);
                t.setVisibility(View.VISIBLE);
            }

            t.setText(tspan);
        } else {
            t.setText(Vokabel.getComment(_vok.getBedeutung1()));
        }
        if (_vok.reverse || showBeds) {
            String txt = t.getText().toString();
            txt = replaceClozes(txt, txtWord);
            speak(txt, _vok.getLangMeaning(), "meaning1", _vok.reverse);
        }
        if (_vok.getFontBed().getName().equalsIgnoreCase("Cardo")) {
            t.setTypeface(_vok.TypefaceCardo);
        } else {
            t.setTypeface(Typeface.DEFAULT);
        }
        t.setOnFocusChangeListener(FocusListenerMeaning1);
        t.scrollTo(0, 0);

        v = findViewById(R.id.txtMeaning2);
        t = (TextView) v;
        assert t != null;
        t.setText((_vok.reverse || showBeds ? _vok.getBedeutung2() : Vokabel.getComment(_vok.getBedeutung2())));
        if (_vok.getFontBed().getName().equalsIgnoreCase("Cardo")) {
            t.setTypeface(_vok.TypefaceCardo);
        } else {
            t.setTypeface(Typeface.DEFAULT);
        }
        if (libString.IsNullOrEmpty(_vok.getBedeutung2()) || _vok.getCardMode()) {
            t.setVisibility(View.GONE);
            _txtMeaning1.setImeOptions(EditorInfo.IME_ACTION_DONE);
        } else {
            t.setVisibility(View.VISIBLE);
            _txtMeaning1.setImeOptions(EditorInfo.IME_ACTION_NEXT);
            if (_vok.reverse || showBeds) {
                String txt = t.getText().toString();
                //if (txtWord != null)
                //   txt = txt.replaceAll("_{2,}", txtWord).replaceAll("\\.{4,}", txtWord);
                speak(txt, _vok.getLangMeaning(), "meaning2");
            }
        }

        v = findViewById(R.id.txtMeaning3);
        t = (TextView) v;
        assert t != null;
        t.setText((_vok.reverse || showBeds ? _vok.getBedeutung3() : Vokabel.getComment(_vok.getBedeutung3())));
        if (_vok.getFontBed().getName().equalsIgnoreCase("Cardo")) {
            t.setTypeface(_vok.TypefaceCardo);
        } else {
            t.setTypeface(Typeface.DEFAULT);
        }
        if (libString.IsNullOrEmpty(_vok.getBedeutung3()) || _vok.getCardMode()) {
            t.setVisibility(View.GONE);
            _txtMeaning2.setImeOptions(EditorInfo.IME_ACTION_DONE);
        } else {
            t.setVisibility(View.VISIBLE);
            _txtMeaning2.setImeOptions(EditorInfo.IME_ACTION_NEXT);
            _txtMeaning3.setImeOptions(EditorInfo.IME_ACTION_DONE);
            if (_vok.reverse || showBeds) {
                String txt = t.getText().toString();
                //if (txtWord != null)
                //   txt = txt.replaceAll("_{2,}", txtWord).replaceAll("\\.{4,}", txtWord);
                speak(txt, _vok.getLangMeaning(), "meaning3");
            }
        }

        if (_vok.reverse && showBeds)
            speak(txtWord, _vok.getLangWord(), "word");

        lib.setBgEditText(_txtMeaning1, _MeaningBG);
        lib.setBgEditText(_txtMeaning2, _MeaningBG);
        lib.setBgEditText(_txtMeaning3, _MeaningBG);
        if (!_isSmallDevice && !requestFocusEdWord) {
            _txtMeaning1.requestFocus();
        } else {
            if (!requestFocusEdWord)
                _txtWord.requestFocus();
            else
                _txtedWord.requestFocus();
        }
        SetActionBarTitle();

        _scrollView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {

                lib.removeLayoutListener(_scrollView.getViewTreeObserver(), this);
                hideKeyboard();
                if (showBeds) {
                    _scrollView.scrollTo(0, _txtMeaning1.getTop());
                } else {
                    _txtWord.requestFocus();
                    _scrollView.fullScroll(View.FOCUS_UP);
                }
            }
        });

    } catch (Exception e) {

        lib.ShowException(_main, e);
    }

}

From source file:com.nttec.everychan.ui.presentation.BoardFragment.java

private Point getSpanCoordinates(View widget, ClickableURLSpan span) {
    TextView parentTextView = (TextView) widget;

    Rect parentTextViewRect = new Rect();

    // Initialize values for the computing of clickedText position
    SpannableString completeText = (SpannableString) (parentTextView).getText();
    Layout textViewLayout = parentTextView.getLayout();

    int startOffsetOfClickedText = completeText.getSpanStart(span);
    int endOffsetOfClickedText = completeText.getSpanEnd(span);
    double startXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal(startOffsetOfClickedText);
    double endXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal(endOffsetOfClickedText);

    // Get the rectangle of the clicked text
    int currentLineStartOffset = textViewLayout.getLineForOffset(startOffsetOfClickedText);
    int currentLineEndOffset = textViewLayout.getLineForOffset(endOffsetOfClickedText);
    boolean keywordIsInMultiLine = currentLineStartOffset != currentLineEndOffset;
    textViewLayout.getLineBounds(currentLineStartOffset, parentTextViewRect);

    // Update the rectangle position to his real position on screen
    int[] parentTextViewLocation = { 0, 0 };
    parentTextView.getLocationOnScreen(parentTextViewLocation);

    double parentTextViewTopAndBottomOffset = (parentTextViewLocation[1] - parentTextView.getScrollY()
            + parentTextView.getCompoundPaddingTop());

    Rect windowRect = new Rect();
    activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(windowRect);
    parentTextViewTopAndBottomOffset -= windowRect.top;

    parentTextViewRect.top += parentTextViewTopAndBottomOffset;
    parentTextViewRect.bottom += parentTextViewTopAndBottomOffset;

    parentTextViewRect.left += (parentTextViewLocation[0] + startXCoordinatesOfClickedText
            + parentTextView.getCompoundPaddingLeft() - parentTextView.getScrollX());
    parentTextViewRect.right = (int) (parentTextViewRect.left + endXCoordinatesOfClickedText
            - startXCoordinatesOfClickedText);

    int x = (parentTextViewRect.left + parentTextViewRect.right) / 2;
    int y = (parentTextViewRect.top + parentTextViewRect.bottom) / 2;
    if (keywordIsInMultiLine) {
        x = parentTextViewRect.left;/*w  ww .j  ava  2 s  .  c om*/
    }

    return new Point(x, y);
}