OSDN Git Service

allow multiple invals to return first difference
authorCary Clark <cary@android.com>
Fri, 11 Mar 2011 16:05:21 +0000 (11:05 -0500)
committerThe Android Automerger <android-build@android.com>
Fri, 11 Mar 2011 23:58:38 +0000 (15:58 -0800)
The shape of the text selection changed recently, so the
inval computation for the shape area was slightly incorrect.

But most of the problem is caused by multiple calls to
draw the selection area. The old assumption was that
successive calls to compute the inval could each work
from the prior state, since only the difference between
the last inval and the current inval needs to be redrawn.

Now, there are multiple calls to compute the area, and any
of them need to return the last difference computed, only
computing a new difference if the selection changed.

Keep track of the last changed selection, so that the last
position, the current position, and the last drawn position
can be tracked correctly.

bug:4073219
Change-Id: Ic9b9d037329e8f792b5ec09c112e665dbdfd0b81

WebKit/android/nav/SelectText.cpp
WebKit/android/nav/SelectText.h

index bae0feb..f8ea799 100644 (file)
@@ -1308,12 +1308,11 @@ static WTF::String text(const SkPicture& picture, const SkIRect& area,
 #define CONTROL_WIDTH 21
 #define STROKE_WIDTH 1.0f
 #define STROKE_OUTSET 3.5f
-
+#define STROKE_I_OUTSET 4 // (int) ceil(STROKE_OUTSET)
 #define STROKE_COLOR 0x66000000
 #define OUTER_COLOR 0x33000000
 #define INNER_COLOR 0xe6aae300
 
-#define DROP_HEIGHT 4
 #define SLOP 35
 
 SelectText::SelectText()
@@ -1459,18 +1458,18 @@ void SelectText::drawSelectionPointer(SkCanvas* canvas, IntRect* inval)
 static void addStart(SkRegion* diff, const SkIRect& rect)
 {
     SkIRect bounds;
-    bounds.set(rect.fLeft - CONTROL_WIDTH - STROKE_WIDTH,
-        rect.fBottom - STROKE_WIDTH, rect.fLeft + STROKE_WIDTH,
-        rect.fBottom + CONTROL_HEIGHT + DROP_HEIGHT + STROKE_WIDTH);
+    bounds.set(rect.fLeft - CONTROL_WIDTH - STROKE_I_OUTSET,
+        rect.fBottom - STROKE_I_OUTSET, rect.fLeft + STROKE_I_OUTSET,
+        rect.fBottom + CONTROL_HEIGHT + STROKE_I_OUTSET);
     diff->op(bounds, SkRegion::kUnion_Op);
 }
 
 static void addEnd(SkRegion* diff, const SkIRect& rect)
 {
     SkIRect bounds;
-    bounds.set(rect.fLeft - STROKE_WIDTH, rect.fBottom - STROKE_WIDTH,
-        rect.fLeft + CONTROL_WIDTH + STROKE_WIDTH,
-        rect.fBottom + CONTROL_HEIGHT + DROP_HEIGHT + STROKE_WIDTH);
+    bounds.set(rect.fRight - STROKE_I_OUTSET, rect.fBottom - STROKE_I_OUTSET,
+        rect.fRight + CONTROL_WIDTH + STROKE_I_OUTSET,
+        rect.fBottom + CONTROL_HEIGHT + STROKE_I_OUTSET);
     diff->op(bounds, SkRegion::kUnion_Op);
 }
 
@@ -1486,7 +1485,9 @@ void SelectText::drawSelectionRegion(SkCanvas* canvas, IntRect* inval)
         m_selStart.fLeft, m_selStart.fTop, m_selStart.fRight, m_selStart.fBottom,
         m_selEnd.fLeft, m_selEnd.fTop, m_selEnd.fRight, m_selEnd.fBottom,
         ivisBounds.fLeft, ivisBounds.fTop, ivisBounds.fRight, ivisBounds.fBottom);
-    SkRegion diff(m_selRegion);
+    if (m_lastSelRegion != m_selRegion)
+        m_lastSelRegion.set(m_selRegion);
+    SkRegion diff(m_lastSelRegion);
     m_selRegion.setEmpty();
     m_flipped = buildSelection(*m_picture, ivisBounds, m_selStart, m_startBase,
         m_selEnd, m_endBase, &m_selRegion);
@@ -1517,20 +1518,20 @@ void SelectText::drawSelectionRegion(SkCanvas* canvas, IntRect* inval)
     DBG_NAV_LOGD("lastStart=(%d,%d,r=%d,b=%d) m_lastEnd=(%d,%d,r=%d,b=%d)",
         m_lastStart.fLeft, m_lastStart.fTop, m_lastStart.fRight, m_lastStart.fBottom,
         m_lastEnd.fLeft, m_lastEnd.fTop, m_lastEnd.fRight, m_lastEnd.fBottom);
+    if (!m_lastDrawnStart.isEmpty())
+        addStart(&diff, m_lastDrawnStart);
     if (m_lastStart != m_selStart) {
-        if (!m_lastStart.isEmpty()) {
-            addStart(&diff, m_lastStart);
-            m_lastStart = m_selStart;
-        }
-        addStart(&diff, m_selStart);
+        m_lastDrawnStart = m_lastStart;
+        m_lastStart = m_selStart;
     }
+    addStart(&diff, m_selStart);
+    if (!m_lastDrawnEnd.isEmpty())
+        addEnd(&diff, m_lastDrawnEnd);
     if (m_lastEnd != m_selEnd) {
-        if (!m_lastEnd.isEmpty()) {
-            addEnd(&diff, m_lastEnd);
-            m_lastEnd = m_selEnd;
-        }
-        addEnd(&diff, m_selEnd);
+        m_lastDrawnEnd = m_lastEnd;
+        m_lastEnd = m_selEnd;
     }
+    addEnd(&diff, m_selEnd);
     SkIRect iBounds = diff.getBounds();
     DBG_NAV_LOGD("diff=(%d,%d,r=%d,b=%d)",
         iBounds.fLeft, iBounds.fTop, iBounds.fRight, iBounds.fBottom);
@@ -1799,8 +1800,10 @@ void SelectText::reset()
     DBG_NAV_LOG("m_extendSelection=false");
     m_selStart.setEmpty();
     m_lastStart.setEmpty();
+    m_lastDrawnStart.setEmpty();
     m_selEnd.setEmpty();
     m_lastEnd.setEmpty();
+    m_lastDrawnEnd.setEmpty();
     m_extendSelection = false;
     m_startSelection = false;
     SkSafeUnref(m_picture);
index 3b15c0b..42239cf 100644 (file)
@@ -84,11 +84,14 @@ private:
     SkIRect m_selEnd;
     SkIRect m_lastStart;
     SkIRect m_lastEnd;
+    SkIRect m_lastDrawnStart;
+    SkIRect m_lastDrawnEnd;
     SkIRect m_wordBounds;
     int m_startBase;
     int m_endBase;
     int m_layerId;
     SkIRect m_visibleRect; // constrains picture computations to visible area
+    SkRegion m_lastSelRegion;
     SkRegion m_selRegion; // computed from sel start, end
     SkPicture m_startControl;
     SkPicture m_endControl;