@@ -3080,40 +3080,47 @@ public void updatePosition(int parentPositionX, int parentPositionY,
30803080 composingTextEnd );
30813081 builder .setComposingText (composingTextStart , composingText );
30823082 }
3083+ // TODO: Optimize this loop by caching the result.
30833084 for (int offset = composingTextStart ; offset < composingTextEnd ; offset ++) {
30843085 if (offset < 0 ) {
30853086 continue ;
30863087 }
3088+ final boolean isRtl = layout .isRtlCharAt (offset );
30873089 final int line = layout .getLineForOffset (offset );
3088- final float left = layout .getPrimaryHorizontal (offset )
3090+ final int nextCharIndex = offset + 1 ;
3091+ final float localLeadingEdgeX = layout .getPrimaryHorizontal (offset );
3092+ final float localTrailingEdgeX ;
3093+ if (nextCharIndex != layout .getLineEnd (line )) {
3094+ localTrailingEdgeX = layout .getPrimaryHorizontal (nextCharIndex );
3095+ } else if (isRtl ) {
3096+ localTrailingEdgeX = layout .getLineLeft (line );
3097+ } else {
3098+ localTrailingEdgeX = layout .getLineRight (line );
3099+ }
3100+ final float leadingEdgeX = localLeadingEdgeX
30893101 + viewportToContentHorizontalOffset ;
3090- final float top = layout .getLineTop (line ) + viewportToContentVerticalOffset ;
3091- // Here we are tentatively passing offset + 1 to calculate the other side of
3092- // the primary horizontal to preserve as many positions as possible so that
3093- // the IME can reconstruct the layout entirely. However, we should revisit this
3094- // to have a clear specification about the relationship between the index of
3095- // the character and its bounding box. See also the TODO comment below.
3096- final float right = layout .getPrimaryHorizontal (offset + 1 )
3102+ final float trailingEdgeX = localTrailingEdgeX
30973103 + viewportToContentHorizontalOffset ;
3104+ final float top = layout .getLineTop (line ) + viewportToContentVerticalOffset ;
30983105 final float bottom = layout .getLineBottom (line )
30993106 + viewportToContentVerticalOffset ;
3100- // Take TextView's padding and scroll into account.
31013107 // TODO: Check right-top and left-bottom as well.
3102- final boolean leftTopVisible = isPositionVisible (left , top );
3103- final boolean rightBottomVisible = isPositionVisible (right , bottom );
3108+ final boolean isLeadingEdgeTopVisible = isPositionVisible (leadingEdgeX , top );
3109+ final boolean isTrailingEdgeBottomVisible =
3110+ isPositionVisible (trailingEdgeX , bottom );
31043111 final int characterRectFlags ;
3105- if (leftTopVisible && rightBottomVisible ) {
3112+ if (isLeadingEdgeTopVisible && isTrailingEdgeBottomVisible ) {
31063113 characterRectFlags = CursorAnchorInfo .CHARACTER_RECT_TYPE_FULLY_VISIBLE ;
3107- } else if (leftTopVisible || rightBottomVisible ) {
3114+ } else if (isLeadingEdgeTopVisible || isTrailingEdgeBottomVisible ) {
31083115 characterRectFlags = CursorAnchorInfo .CHARACTER_RECT_TYPE_PARTIALLY_VISIBLE ;
31093116 } else {
31103117 characterRectFlags = CursorAnchorInfo .CHARACTER_RECT_TYPE_INVISIBLE ;
31113118 }
31123119 // Here offset is the index in Java chars.
31133120 // TODO: We must have a well-defined specification. For example, how
3114- // RTL, surrogate pairs, and composition letters are handled must be
3115- // documented.
3116- builder . addCharacterRect ( offset , left , top , right , bottom , characterRectFlags );
3121+ // surrogate pairs and composition letters are handled must be documented.
3122+ builder . addCharacterRect ( offset , leadingEdgeX , top , trailingEdgeX , bottom ,
3123+ characterRectFlags );
31173124 }
31183125 }
31193126
0 commit comments