summaryrefslogtreecommitdiffstats
path: root/WebKit/android/nav/CachedRoot.cpp
diff options
context:
space:
mode:
authorCary Clark <cary@android.com>2010-10-26 10:56:53 -0400
committerCary Clark <cary@android.com>2010-10-27 11:35:46 -0400
commitaf03a3d6830584ef606be2d1c64845815dadb146 (patch)
treeae2edb24d2deaf62097469d8b1e79b9f4c010b7f /WebKit/android/nav/CachedRoot.cpp
parent43d943757c6b39710fa65034351bc2e84946e8ce (diff)
downloadexternal_webkit-af03a3d6830584ef606be2d1c64845815dadb146.zip
external_webkit-af03a3d6830584ef606be2d1c64845815dadb146.tar.gz
external_webkit-af03a3d6830584ef606be2d1c64845815dadb146.tar.bz2
rewrite select text and others for layers
Layers contain pictures, and draw them offset from the top of the page. Several readers of pictures need to account for this displacement when computing what part of the picture intersects a tap on the screen. The tap may not correspond to the first layer that intersects it, so all layers must be checked to find the best match. The root layer usually draws everywhere, so for a match to correspond to the root, the match must additionally intersect text. Layers may create offscreen bitmaps when drawing to correctly alpha blend the results to the screen, but this causes the items in the bitmap to draw to an unexpected location when the picture is treated as a spatial database. To get around this, call the SkCanvas::save() from the overridden saveLayer() to push and pop the canvas layer state without creating an offscreen. WebCore/platform/graphics/android/LayerAndroid.cpp WebCore/platform/graphics/android/LayerAndroid.h - In find(), iterate through all children, instead of stopping on the first match. - Check to see if the child actually draws at the desired location, and if it draws text there as well. - Specify a slop factor to allow for inaccuracies in touch. - Check the root for text before checking the children. WebKit/android/nav/CachedFrame.cpp WebKit/android/nav/CachedFrame.h - Modify the (x,y) co-ordinate by the layer's offset, when finding the picture corresponding to a point. WebKit/android/nav/CachedLayer.cpp WebKit/android/nav/CachedLayer.h - More plumbing to adjust the point if the picture is contained in an offset layer. WebKit/android/nav/CachedRoot.cpp WebKit/android/nav/CachedRoot.h - Correct the (x,y) locations by the layer offset. - Add some debugging (disabled by default) WebKit/android/nav/ParsedCanvas.h - One stop shopping that calls save() from saveLayer(). - Reset the bounder to null to balance its ref count. WebKit/android/nav/SelectText.cpp WebKit/android/nav/SelectText.h - Rearrange the way pictures are tracked. Record the picture corresponding to the input location when the selection starts, requiring that the picture remain unchanged as the selection extends. - Only draw adornments for when the corresponding picture is drawn. This fixes a Gmail specific problem, where the layers come and go as the page scrolls. - Always use the supplied visible bounds instead of computing it from the canvas. - Correct location points by layer offsets. - Add to the picture ref count so it can't be deleted during selection. WebKit/android/nav/WebView.cpp - Simplify visibleRect code. - Simplify all SelectText interfaces. bug:3114609 Change-Id: I43dc3252fc86c4b6500edcd650126b2559f530e3
Diffstat (limited to 'WebKit/android/nav/CachedRoot.cpp')
-rw-r--r--WebKit/android/nav/CachedRoot.cpp69
1 files changed, 43 insertions, 26 deletions
diff --git a/WebKit/android/nav/CachedRoot.cpp b/WebKit/android/nav/CachedRoot.cpp
index e86999c..3340792 100644
--- a/WebKit/android/nav/CachedRoot.cpp
+++ b/WebKit/android/nav/CachedRoot.cpp
@@ -31,6 +31,7 @@
#include "FindCanvas.h"
#include "FloatRect.h"
#include "LayerAndroid.h"
+#include "ParseCanvas.h"
#include "SkBitmap.h"
#include "SkBounder.h"
#include "SkPixelRef.h"
@@ -225,7 +226,7 @@ public:
SkIRect mLastAll;
};
-class BoundsCanvas : public SkCanvas {
+class BoundsCanvas : public ParseCanvas {
public:
BoundsCanvas(CommonCheck* bounder) : mBounder(*bounder) {
@@ -233,36 +234,32 @@ public:
setBounder(bounder);
}
- virtual ~BoundsCanvas() {
- setBounder(NULL);
- }
-
virtual void drawPaint(const SkPaint& paint) {
mBounder.setType(CommonCheck::kDrawPaint_Type);
- SkCanvas::drawPaint(paint);
+ INHERITED::drawPaint(paint);
}
virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
const SkPaint& paint) {
mBounder.setType(CommonCheck::kDrawPoints_Type);
- SkCanvas::drawPoints(mode, count, pts, paint);
+ INHERITED::drawPoints(mode, count, pts, paint);
}
virtual void drawRect(const SkRect& rect, const SkPaint& paint) {
mBounder.setType(CommonCheck::kDrawRect_Type);
- SkCanvas::drawRect(rect, paint);
+ INHERITED::drawRect(rect, paint);
}
virtual void drawPath(const SkPath& path, const SkPaint& paint) {
mBounder.setType(CommonCheck::kDrawPath_Type);
- SkCanvas::drawPath(path, paint);
+ INHERITED::drawPath(path, paint);
}
virtual void commonDrawBitmap(const SkBitmap& bitmap,
const SkMatrix& matrix, const SkPaint& paint) {
mBounder.setType(CommonCheck::kDrawBitmap_Type);
mBounder.setIsOpaque(bitmap.isOpaque());
- SkCanvas::commonDrawBitmap(bitmap, matrix, paint);
+ INHERITED::commonDrawBitmap(bitmap, matrix, paint);
}
virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
@@ -270,14 +267,14 @@ public:
mBounder.setType(CommonCheck::kDrawSprite_Type);
mBounder.setIsOpaque(bitmap.isOpaque() &&
(!paint || paint->getAlpha() == 255));
- SkCanvas::drawSprite(bitmap, left, top, paint);
+ INHERITED::drawSprite(bitmap, left, top, paint);
}
virtual void drawText(const void* text, size_t byteLength, SkScalar x,
SkScalar y, const SkPaint& paint) {
mBounder.setEmpty();
mBounder.setType(CommonCheck::kDrawGlyph_Type);
- SkCanvas::drawText(text, byteLength, x, y, paint);
+ INHERITED::drawText(text, byteLength, x, y, paint);
mBounder.doRect(CommonCheck::kDrawText_Type);
}
@@ -285,7 +282,7 @@ public:
const SkPoint pos[], const SkPaint& paint) {
mBounder.setEmpty();
mBounder.setType(CommonCheck::kDrawGlyph_Type);
- SkCanvas::drawPosText(text, byteLength, pos, paint);
+ INHERITED::drawPosText(text, byteLength, pos, paint);
mBounder.doRect(CommonCheck::kDrawPosText_Type);
}
@@ -294,7 +291,7 @@ public:
const SkPaint& paint) {
mBounder.setEmpty();
mBounder.setType(CommonCheck::kDrawGlyph_Type);
- SkCanvas::drawPosTextH(text, byteLength, xpos, constY, paint);
+ INHERITED::drawPosTextH(text, byteLength, xpos, constY, paint);
if (mBounder.mUnion.isEmpty()) {
DBG_NAV_LOGD("empty constY=%g", SkScalarToFloat(constY));
return;
@@ -317,18 +314,18 @@ public:
const SkPaint& paint) {
mBounder.setEmpty();
mBounder.setType(CommonCheck::kDrawGlyph_Type);
- SkCanvas::drawTextOnPath(text, byteLength, path, matrix, paint);
+ INHERITED::drawTextOnPath(text, byteLength, path, matrix, paint);
mBounder.doRect(CommonCheck::kDrawTextOnPath_Type);
}
virtual void drawPicture(SkPicture& picture) {
mBounder.setType(CommonCheck::kDrawPicture_Type);
- SkCanvas::drawPicture(picture);
+ INHERITED::drawPicture(picture);
}
virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
SaveFlags flags) {
- int depth = SkCanvas::save(flags);
+ int depth = INHERITED::saveLayer(bounds, paint, flags);
if (mTransparentLayer == 0 && paint && paint->getAlpha() < 255) {
mTransparentLayer = depth;
mBounder.setAllOpaque(false);
@@ -343,11 +340,13 @@ public:
mTransparentLayer = 0;
mBounder.setAllOpaque(true);
}
- SkCanvas::restore();
+ INHERITED::restore();
}
int mTransparentLayer;
CommonCheck& mBounder;
+private:
+ typedef ParseCanvas INHERITED;
};
/*
@@ -591,12 +590,15 @@ protected:
const int mViewRight;
};
-class ImageCanvas : public SkCanvas {
+class ImageCanvas : public ParseCanvas {
public:
ImageCanvas(SkBounder* bounder) : mURI(NULL) {
setBounder(bounder);
}
+ const char* getURI() { return mURI; }
+
+protected:
// Currently webkit's bitmap draws always seem to be cull'd before this entry
// point is called, so we assume that any bitmap that gets here is inside our
// tiny clip (may not be true in the future)
@@ -608,6 +610,7 @@ public:
}
}
+private:
const char* mURI;
};
@@ -1123,6 +1126,7 @@ void CachedRoot::calcBitBounds(const IntRect& nodeBounds, IntRect* bitBounds) co
int CachedRoot::checkForCenter(int x, int y) const
{
int width = mViewBounds.width();
+ SkPicture* picture = pictureAt(&x, &y);
CenterCheck centerCheck(x + width - mViewBounds.x(), y - mViewBounds.y(),
width);
BoundsCanvas checker(&centerCheck);
@@ -1132,7 +1136,7 @@ int CachedRoot::checkForCenter(int x, int y) const
checker.setBitmapDevice(bitmap);
checker.translate(SkIntToScalar(width - mViewBounds.x()),
SkIntToScalar(-mViewBounds.y()));
- checker.drawPicture(*pictureAt(x, y));
+ checker.drawPicture(*picture);
return centerCheck.center();
}
@@ -1148,8 +1152,9 @@ void CachedRoot::checkForJiggle(int* xDeltaPtr) const
checker.setBitmapDevice(bitmap);
int x = -mViewBounds.x() - (xDelta < 0 ? xDelta : 0);
int y = -mViewBounds.y();
+ SkPicture* picture = pictureAt(&x, &y);
checker.translate(SkIntToScalar(x), SkIntToScalar(y));
- checker.drawPicture(*pictureAt(x, y));
+ checker.drawPicture(*picture);
*xDeltaPtr = jiggleCheck.jiggle();
}
@@ -1262,7 +1267,7 @@ int CachedRoot::getBlockLeftEdge(int x, int y, float scale) const
node->isTextInput() ? "text" : "plugin");
return node->bounds(frame).x();
}
- SkPicture* picture = node ? frame->picture(node) : pictureAt(x, y);
+ SkPicture* picture = node ? frame->picture(node, &x, &y) : pictureAt(&x, &y);
if (!picture)
return x;
int halfW = (int) (mViewBounds.width() * scale * 0.5f);
@@ -1490,14 +1495,17 @@ bool CachedRoot::innerUp(const CachedNode* test, BestData* bestData) const
WTF::String CachedRoot::imageURI(int x, int y) const
{
+ DBG_NAV_LOGD("x/y=(%d,%d)", x, y);
ImageCheck imageCheck;
ImageCanvas checker(&imageCheck);
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
checker.setBitmapDevice(bitmap);
+ SkPicture* picture = pictureAt(&x, &y);
checker.translate(SkIntToScalar(-x), SkIntToScalar(-y));
- checker.drawPicture(*pictureAt(x, y));
- return WTF::String(checker.mURI);
+ checker.drawPicture(*picture);
+ DBG_NAV_LOGD("uri=%s", checker.getURI());
+ return WTF::String(checker.getURI());
}
bool CachedRoot::maskIfHidden(BestData* best) const
@@ -1642,18 +1650,27 @@ const CachedNode* CachedRoot::nextTextField(const CachedNode* start,
return CachedFrame::nextTextField(start, framePtr, &startFound);
}
-SkPicture* CachedRoot::pictureAt(int x, int y) const
+SkPicture* CachedRoot::pictureAt(int* xPtr, int* yPtr) const
{
#if USE(ACCELERATED_COMPOSITING)
if (mRootLayer) {
- const LayerAndroid* layer = mRootLayer->find(x, y);
+ const LayerAndroid* layer = mRootLayer->find(*xPtr, *yPtr, mPicture);
if (layer) {
SkPicture* picture = layer->picture();
+ DBG_NAV_LOGD("layer %d picture=%p (%d,%d)", layer->uniqueId(),
+ picture, picture ? picture->width() : 0,
+ picture ? picture->height() : 0);
+ SkRect localBounds;
+ layer->bounds(&localBounds);
+ *xPtr -= localBounds.fLeft;
+ *yPtr -= localBounds.fTop;
if (picture)
return picture;
}
}
#endif
+ DBG_NAV_LOGD("root mPicture=%p (%d,%d)", mPicture, mPicture ?
+ mPicture->width() : 0, mPicture ? mPicture->height() : 0);
return mPicture;
}