From 1ca562635117e10fae0888689909e6c39d66b0a4 Mon Sep 17 00:00:00 2001 From: Leon Scroggins Date: Thu, 18 Nov 2010 14:03:03 -0500 Subject: Alter the Layout of WebTextView to match webkit. Bug:3085564 In order to treat the selection handles properly, the text in WebTextView needs to line up with the text in webkit. Use the line spacing style, or the paint if none provided, to determine the spacing for WebTextView's Layout. When no line spacing is provided, use the floating point values of ascent and descent, rather than the rounded result, to determine spacing. Requires a change in external/webkit: https://android-git.corp.google.com/g/#change,80641 Change-Id: I51081835e128a0e938028c7c7aeb5111aa5f072c --- core/java/android/webkit/WebTextView.java | 65 +++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'core/java/android/webkit/WebTextView.java') diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java index 1caa7072dba0..fafb6be38825 100644 --- a/core/java/android/webkit/WebTextView.java +++ b/core/java/android/webkit/WebTextView.java @@ -26,9 +26,12 @@ import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.text.BoringLayout.Metrics; +import android.text.DynamicLayout; import android.text.Editable; import android.text.InputFilter; import android.text.Layout; +import android.text.Layout.Alignment; import android.text.Selection; import android.text.Spannable; import android.text.TextPaint; @@ -359,6 +362,68 @@ import junit.framework.Assert; } } + @Override + protected void makeNewLayout(int w, int hintWidth, Metrics boring, + Metrics hintBoring, int ellipsisWidth, boolean bringIntoView) { + // Necessary to get a Layout to work with, and to do the other work that + // makeNewLayout does. + super.makeNewLayout(w, hintWidth, boring, hintBoring, ellipsisWidth, + bringIntoView); + + // For fields that do not draw, create a layout which is altered so that + // the text lines up. + if (DebugFlags.DRAW_WEBTEXTVIEW || willNotDraw()) { + float lineHeight = -1; + if (mWebView != null) { + float height = mWebView.nativeFocusCandidateLineHeight(); + if (height != -1) { + lineHeight = height * mWebView.getScale(); + } + } + CharSequence text = getText(); + // Copy from the existing Layout. + mLayout = new WebTextViewLayout(text, text, getPaint(), w, + mLayout.getAlignment(), mLayout.getSpacingMultiplier(), + mLayout.getSpacingAdd(), false, null, ellipsisWidth, + lineHeight); + } + } + + /** + * Custom layout which figures out its line spacing. If -1 is passed in for + * the height, it will use the ascent and descent from the paint to + * determine the line spacing. Otherwise it will use the spacing provided. + */ + private static class WebTextViewLayout extends DynamicLayout { + private float mLineHeight; + private float mDifference; + public WebTextViewLayout(CharSequence base, CharSequence display, + TextPaint paint, + int width, Alignment align, + float spacingMult, float spacingAdd, + boolean includepad, + TextUtils.TruncateAt ellipsize, int ellipsizedWidth, + float lineHeight) { + super(base, display, paint, width, align, spacingMult, spacingAdd, + includepad, ellipsize, ellipsizedWidth); + float paintLineHeight = paint.descent() - paint.ascent(); + if (lineHeight == -1f) { + mLineHeight = paintLineHeight; + mDifference = 0f; + } else { + mLineHeight = lineHeight; + // Through trial and error, I found this calculation to improve + // the accuracy of line placement. + mDifference = (lineHeight - paintLineHeight) / 2; + } + } + + @Override + public int getLineTop(int line) { + return Math.round(mLineHeight * line - mDifference); + } + } + @Override public InputConnection onCreateInputConnection( EditorInfo outAttrs) { InputConnection connection = super.onCreateInputConnection(outAttrs); -- cgit v1.2.3