OSDN Git Service

Optimise the hit test algorithm
authorMihai Popa <popam@google.com>
Wed, 9 May 2018 16:31:48 +0000 (17:31 +0100)
committerandroid-build-team Robot <android-build-team-robot@google.com>
Thu, 16 Aug 2018 01:23:20 +0000 (01:23 +0000)
commitf3709a856932ed6fdfa0a8e58dbc01f39343a6ed
tree6a10839626d9ce3c5c1d61f06e773d1ce8e7c1fd
parent4df41c7409015c78c9d2f945507a5fc5ef5b6f62
Optimise the hit test algorithm

Layout#getOffsetForHorizontal was running in O(n^2) time, where n is the
length of the current line. The method is used when a touch event
happens on a text line, to compute the cursor offset (and the character)
where it happened. Although this is not an issue in common usecases,
where the number of characters on a line is relatively small, this can
be very inefficient as a consequence of Unicode containing 0-width
(invisible) characters. Specifically, there are characters defining the
text direction (LTR or RTL), which cause our algorithm to touch the
worst case quadratic runtime. For example, a person is able to send a
message containing a few visible characters, and also a lot of these
direction changing invisible ones. When the receiver touches the message
(causing the Layout#getOffsetForHorizontal method to be called), the
receiver's application would become not responsive.

This CL optimizes the method to run in O(n) worst case. This is achieved
by computing the measurements of all line prefixes at first, which can
be done in a single pass. Then, all the prefix measurement queries will
be answered in O(1), rather than O(n) as it was happening before.

Bug: 79215201
Test: manual testing
Change-Id: Ib66ef392c19c937718e7101f6d48fac3abe51ad0
Merged-In: Ib66ef392c19c937718e7101f6d48fac3abe51ad0
(cherry picked from commit 69b589b21d02cd380a6827c39e56cbd12a804ffd)
core/java/android/text/Layout.java
core/java/android/text/TextLine.java