summaryrefslogtreecommitdiffstats
path: root/WebKit/android/nav
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/android/nav')
-rw-r--r--WebKit/android/nav/CacheBuilder.cpp47
-rw-r--r--WebKit/android/nav/CacheBuilder.h4
-rw-r--r--WebKit/android/nav/FindCanvas.cpp197
-rw-r--r--WebKit/android/nav/FindCanvas.h65
-rw-r--r--WebKit/android/nav/WebView.cpp111
5 files changed, 242 insertions, 182 deletions
diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp
index da32898..69d0a06 100644
--- a/WebKit/android/nav/CacheBuilder.cpp
+++ b/WebKit/android/nav/CacheBuilder.cpp
@@ -27,6 +27,7 @@
#include "HTMLAreaElement.h"
#include "HTMLImageElement.h"
#include "HTMLInputElement.h"
+#include "HTMLMapElement.h"
#include "HTMLNames.h"
#include "HTMLOptionElement.h"
#include "HTMLSelectElement.h"
@@ -398,7 +399,7 @@ void CacheBuilder::Debug::groups() {
properties.truncate(properties.length() - 3);
IntRect rect = node->getRect();
if (node->hasTagName(HTMLNames::areaTag))
- rect = static_cast<HTMLAreaElement*>(node)->getAreaRect();
+ rect = Builder(frame)->getAreaRect(static_cast<HTMLAreaElement*>(node));
char buffer[DEBUG_BUFFER_SIZE];
memset(buffer, 0, sizeof(buffer));
mBuffer = buffer;
@@ -1004,12 +1005,20 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
RenderStyle* style = nodeRenderer->style();
if (style->visibility() == HIDDEN)
continue;
-#ifdef ANDROID_NAVIGATE_AREAMAPS
if (nodeRenderer->isImage()) { // set all the area elements to have a link to their images
RenderImage* image = static_cast<RenderImage*>(nodeRenderer);
- image->setImageForAreaElements();
+ HTMLMapElement* map = image->imageMap();
+ if (map) {
+ Node* node;
+ for (node = map->firstChild(); node;
+ node = node->traverseNextNode(map)) {
+ if (!node->hasTagName(HTMLNames::areaTag))
+ continue;
+ HTMLAreaElement* area = static_cast<HTMLAreaElement*>(node);
+ m_areaBoundsMap.set(area, image);
+ }
+ }
}
-#endif
isTransparent = style->hasBackground() == false;
#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
hasFocusRing = style->tapHighlightColor().alpha() > 0;
@@ -1043,10 +1052,9 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
IntRect absBounds;
Node* lastChild = node->lastChild();
WTF::Vector<IntRect>* columns = NULL;
-#ifdef ANDROID_NAVIGATE_AREAMAPS
if (isArea) {
HTMLAreaElement* area = static_cast<HTMLAreaElement*>(node);
- bounds = area->getAreaRect();
+ bounds = getAreaRect(area);
bounds.move(globalOffsetX, globalOffsetY);
absBounds = bounds;
isUnclipped = true; // FIXME: areamaps require more effort to detect
@@ -1054,7 +1062,6 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
takesFocus = true;
goto keepNode;
}
-#endif
if (nodeRenderer == NULL)
continue;
@@ -1183,6 +1190,9 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
if (isFocusable == false) {
if (node->isEventTargetNode() == false)
continue;
+ EventTargetNode* eventTargetNode = (EventTargetNode*) node;
+ if (eventTargetNode->disabled())
+ continue;
bool overOrOut = HasOverOrOut(node);
bool hasTrigger = HasTriggerEvent(node);
if (overOrOut == false && hasTrigger == false)
@@ -1233,9 +1243,6 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
else
clip.intersect(parentClip);
hasClip = true;
- DBG_NAV_LOGD("absBounds={%d,%d,%d,%d} parentClip={%d,%d,%d,%d}\n",
- absBounds.x(), absBounds.y(), absBounds.width(), absBounds.height(),
- parentClip.x(), parentClip.y(), parentClip.width(), parentClip.height());
}
if (hasClip && cachedNode.clip(clip) == false) {
cachedNode.setBounds(clip);
@@ -2365,6 +2372,16 @@ void CacheBuilder::FindResetNumber(FindState* state)
state->mStorePtr = state->mStore;
}
+IntRect CacheBuilder::getAreaRect(const HTMLAreaElement* area) const
+{
+ RenderImage* map = m_areaBoundsMap.get(area);
+ if (!map)
+ return IntRect();
+ if (area->isDefault())
+ return map->absoluteBoundingBoxRect();
+ return area->getRect(map);
+}
+
void CacheBuilder::GetGlobalOffset(Node* node, int* x, int * y)
{
GetGlobalOffset(node->document()->frame(), x, y);
@@ -2459,13 +2476,11 @@ Node* CacheBuilder::findByCenter(int x, int y) const
if (node->isTextNode())
continue;
IntRect bounds;
-#ifdef ANDROID_NAVIGATE_AREAMAPS
if (node->hasTagName(HTMLNames::areaTag)) {
HTMLAreaElement* area = static_cast<HTMLAreaElement*>(node);
- bounds = area->getAreaRect();
+ bounds = getAreaRect(area);
bounds.move(globalOffsetX, globalOffsetY);
} else
-#endif
bounds = node->getRect();
if (bounds.isEmpty())
continue;
@@ -2775,12 +2790,8 @@ bool CacheBuilder::validNode(void* matchFrame, void* matchNode) const
Node* node = frame->document();
while (node != NULL) {
if (node == matchNode) {
-#ifdef ANDROID_NAVIGATE_AREAMAPS
const IntRect& rect = node->hasTagName(HTMLNames::areaTag) ?
- static_cast<HTMLAreaElement*>(node)->getAreaRect() : node->getRect();
-#else
- const IntRect& rect = node->getRect();
-#endif
+ getAreaRect(static_cast<HTMLAreaElement*>(node)) : node->getRect();
// Consider nodes with empty rects that are not at the origin
// to be valid, since news.google.com has valid nodes like this
if (rect.x() == 0 && rect.y() == 0 && rect.isEmpty())
diff --git a/WebKit/android/nav/CacheBuilder.h b/WebKit/android/nav/CacheBuilder.h
index 075042e..4a424a9 100644
--- a/WebKit/android/nav/CacheBuilder.h
+++ b/WebKit/android/nav/CacheBuilder.h
@@ -37,10 +37,12 @@ namespace WebCore {
class Document;
class Frame;
+class HTMLAreaElement;
class InlineTextBox;
class Node;
class PlatformGraphicsContext;
class RenderFlow;
+class RenderImage;
class RenderObject;
class RenderLayer;
class Text;
@@ -193,6 +195,7 @@ private:
static Frame* FrameAnd(CacheBuilder* focusNav);
static Frame* FrameAnd(const CacheBuilder* focusNav);
static CacheBuilder* Builder(Frame* );
+ IntRect getAreaRect(const HTMLAreaElement* area) const;
static Frame* HasFrame(Node* );
static bool HasOverOrOut(Node* );
static bool HasTriggerEvent(Node* );
@@ -208,6 +211,7 @@ private:
Node* mLastKnownFocus;
IntRect mLastKnownFocusBounds;
android::CachedNodeType mAllowableTypes;
+ WTF::HashMap<const HTMLAreaElement* , RenderImage* > m_areaBoundsMap;
#if DUMP_NAV_CACHE
public:
class Debug {
diff --git a/WebKit/android/nav/FindCanvas.cpp b/WebKit/android/nav/FindCanvas.cpp
index 5b6978c..60a7486 100644
--- a/WebKit/android/nav/FindCanvas.cpp
+++ b/WebKit/android/nav/FindCanvas.cpp
@@ -19,6 +19,31 @@
#include "SkRect.h"
+// MatchInfo methods
+////////////////////////////////////////////////////////////////////////////////
+
+MatchInfo::MatchInfo() {
+ m_picture = 0;
+}
+
+MatchInfo::~MatchInfo() {
+ m_picture->safeUnref();
+}
+
+MatchInfo::MatchInfo(const MatchInfo& src) {
+ m_location = src.m_location;
+ m_picture = src.m_picture;
+ m_picture->safeRef();
+}
+
+void MatchInfo::set(const SkRegion& region, SkPicture* pic) {
+ m_picture->safeUnref();
+ m_location = region;
+ m_picture = pic;
+ SkASSERT(pic);
+ pic->ref();
+}
+
// GlyphSet methods
////////////////////////////////////////////////////////////////////////////////
@@ -81,33 +106,17 @@ FindCanvas::FindCanvas(int width, int height, const UChar* lower,
setBounder(&mBounder);
mOutset = -SkIntToScalar(2);
- mRegions = new WTF::Vector<SkRegion>();
-#if RECORD_MATCHES
- mPicture = new SkPicture();
- mRecordingCanvas = mPicture->beginRecording(width, height);
-#endif
+ mMatches = new WTF::Vector<MatchInfo>();
mWorkingIndex = 0;
+ mWorkingCanvas = 0;
+ mWorkingPicture = 0;
}
FindCanvas::~FindCanvas() {
setBounder(NULL);
/* Just in case getAndClear was not called. */
- delete mRegions;
-#if RECORD_MATCHES
- mPicture->unref();
-#endif
-}
-
-// SkPaint.measureText is used to get a rectangle surrounding the specified
-// text. It is a tighter bounds than we want. We want the height to account
-// for the ascent and descent of the font, so that the rectangles will line up,
-// regardless of the characters contained in them.
-static void correctSize(const SkPaint& paint, SkRect& rect)
-{
- SkPaint::FontMetrics fontMetrics;
- paint.getFontMetrics(&fontMetrics);
- rect.fTop = fontMetrics.fAscent;
- rect.fBottom = fontMetrics.fDescent;
+ delete mMatches;
+ mWorkingPicture->safeUnref();
}
// Each version of addMatch returns a rectangle for a match.
@@ -117,21 +126,24 @@ SkRect FindCanvas::addMatchNormal(int index,
const SkScalar pos[], SkScalar y) {
const uint16_t* lineStart = glyphs - index;
/* Use the original paint, since "text" is in glyphs */
- SkScalar before = paint.measureText(lineStart, index * sizeof(uint16_t),
- NULL);
+ SkScalar before = paint.measureText(lineStart, index * sizeof(uint16_t), 0);
SkRect rect;
- int countInBytes = count << 1;
- paint.measureText(glyphs, countInBytes, &rect);
- correctSize(paint, rect);
- rect.offset(pos[0] + before, y);
- getTotalMatrix().mapRect(&rect);
+ rect.fLeft = pos[0] + before;
+ int countInBytes = count * sizeof(uint16_t);
+ rect.fRight = paint.measureText(glyphs, countInBytes, 0) + rect.fLeft;
+ SkPaint::FontMetrics fontMetrics;
+ paint.getFontMetrics(&fontMetrics);
+ SkScalar baseline = y;
+ rect.fTop = baseline + fontMetrics.fAscent;
+ rect.fBottom = baseline + fontMetrics.fDescent;
+ const SkMatrix& matrix = getTotalMatrix();
+ matrix.mapRect(&rect);
// Add the text to our picture.
-#if RECORD_MATCHES
- mRecordingCanvas->setMatrix(getTotalMatrix());
- SkPoint point;
- matrix.mapXY(pos[0] + before, y, &point);
- mRecordingCanvas->drawText(glyphs, countInBytes, point.fX, point.fY, paint);
-#endif
+ SkCanvas* canvas = getWorkingCanvas();
+ int saveCount = canvas->save();
+ canvas->concat(matrix);
+ canvas->drawText(glyphs, countInBytes, pos[0] + before, y, paint);
+ canvas->restoreToCount(saveCount);
return rect;
}
@@ -140,27 +152,31 @@ SkRect FindCanvas::addMatchPos(int index,
const SkScalar xPos[], SkScalar /* y */) {
SkRect r;
r.setEmpty();
- const SkScalar* pos = &xPos[index << 1];
- int countInBytes = count << 1;
+ const SkPoint* temp = reinterpret_cast<const SkPoint*> (xPos);
+ const SkPoint* points = &temp[index];
+ int countInBytes = count * sizeof(uint16_t);
SkPaint::FontMetrics fontMetrics;
paint.getFontMetrics(&fontMetrics);
- for (int j = 0; j < countInBytes; j += 2) {
+ // Need to check each character individually, since the heights may be
+ // different.
+ for (int j = 0; j < count; j++) {
SkRect bounds;
- paint.getTextWidths(&(glyphs[j >> 1]), 2, NULL, &bounds);
- bounds.fTop = fontMetrics.fAscent;
- bounds.fBottom = fontMetrics.fDescent;
- bounds.offset(pos[j], pos[j+1]);
- /* Accumulate and then add the resulting rect to mRegions */
+ bounds.fLeft = points[j].fX;
+ bounds.fRight = bounds.fLeft +
+ paint.measureText(&glyphs[j], sizeof(uint16_t), 0);
+ SkScalar baseline = points[j].fY;
+ bounds.fTop = baseline + fontMetrics.fAscent;
+ bounds.fBottom = baseline + fontMetrics.fDescent;
+ /* Accumulate and then add the resulting rect to mMatches */
r.join(bounds);
}
- getTotalMatrix().mapRect(&r);
- // Add the text to our picture.
-#if RECORD_MATCHES
- mRecordingCanvas->setMatrix(getTotalMatrix());
- // FIXME: Need to do more work to get xPos and constY in the proper
- // coordinates.
- //mRecordingCanvas->drawPosText(glyphs, countInBytes, positions, paint);
-#endif
+ SkMatrix matrix = getTotalMatrix();
+ matrix.mapRect(&r);
+ SkCanvas* canvas = getWorkingCanvas();
+ int saveCount = canvas->save();
+ canvas->concat(matrix);
+ canvas->drawPosText(glyphs, countInBytes, points, paint);
+ canvas->restoreToCount(saveCount);
return r;
}
@@ -168,24 +184,28 @@ SkRect FindCanvas::addMatchPosH(int index,
const SkPaint& paint, int count, const uint16_t* glyphs,
const SkScalar position[], SkScalar constY) {
SkRect r;
- r.setEmpty();
+ // We only care about the positions starting at the index of our match
const SkScalar* xPos = &position[index];
- for (int j = 0; j < count; j++) {
- SkRect bounds;
- paint.getTextWidths(&glyphs[j], 1, NULL, &bounds);
- bounds.offset(xPos[j], constY);
- /* Accumulate and then add the resulting rect to mRegions */
- r.join(bounds);
- }
- correctSize(paint, r);
- getTotalMatrix().mapRect(&r);
- // Add the text to our picture.
-#if RECORD_MATCHES
- mRecordingCanvas->setMatrix(getTotalMatrix());
- // FIXME: Need to do more work to get xPos and constY in the proper
- // coordinates.
- //mRecordingCanvas->drawPosTextH(glyphs, count << 1, xPos, constY, paint);
-#endif
+ // This assumes that the position array is monotonic increasing
+ // The left bounds will be the position of the left most character
+ r.fLeft = xPos[0];
+ // The right bounds will be the position of the last character plus its
+ // width
+ int lastIndex = count - 1;
+ r.fRight = paint.measureText(&glyphs[lastIndex], sizeof(uint16_t), 0)
+ + xPos[lastIndex];
+ // Grab font metrics to determine the top and bottom of the bounds
+ SkPaint::FontMetrics fontMetrics;
+ paint.getFontMetrics(&fontMetrics);
+ r.fTop = constY + fontMetrics.fAscent;
+ r.fBottom = constY + fontMetrics.fDescent;
+ const SkMatrix& matrix = getTotalMatrix();
+ matrix.mapRect(&r);
+ SkCanvas* canvas = getWorkingCanvas();
+ int saveCount = canvas->save();
+ canvas->concat(matrix);
+ canvas->drawPosTextH(glyphs, count * sizeof(uint16_t), xPos, constY, paint);
+ canvas->restoreToCount(saveCount);
return r;
}
@@ -236,10 +256,7 @@ void FindCanvas::findHelper(const void* text, size_t byteLength,
const uint16_t* glyphs,
const SkScalar positions[], SkScalar y)) {
SkASSERT(paint.getTextEncoding() == SkPaint::kGlyphID_TextEncoding);
- SkASSERT(mRegions);
-#if RECORD_MATCHES
- SkASSERT(mRecordingCanvas);
-#endif
+ SkASSERT(mMatches);
GlyphSet* glyphSet = getGlyphs(paint);
const int count = glyphSet->getCount();
int numCharacters = byteLength >> 1;
@@ -249,7 +266,8 @@ void FindCanvas::findHelper(const void* text, size_t byteLength,
if (mWorkingIndex) {
SkPoint newY;
getTotalMatrix().mapXY(0, y, &newY);
- if (mWorkingRegion.getBounds().fBottom < SkScalarRound(newY.fY)) {
+ SkIRect bounds = mWorkingRegion.getBounds();
+ if (bounds.fBottom < SkScalarRound(newY.fY)) {
// Now we know that this line is lower than our partial match.
SkPaint clonePaint(paint);
clonePaint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
@@ -260,14 +278,16 @@ void FindCanvas::findHelper(const void* text, size_t byteLength,
if (mWorkingIndex == count) {
// We already know that it is not clipped out because we
// checked for that before saving the working region.
- mNumFound++;
- mRegions->append(mWorkingRegion);
+ insertMatchInfo(mWorkingRegion);
+
+ resetWorkingCanvas();
mWorkingIndex = 0;
mWorkingRegion.setEmpty();
// We have found a match, so continue on this line from
// scratch.
}
} else {
+ resetWorkingCanvas();
mWorkingIndex = 0;
mWorkingRegion.setEmpty();
}
@@ -288,7 +308,6 @@ void FindCanvas::findHelper(const void* text, size_t byteLength,
}
// The last count characters match, so we found the entire
// search string.
- mNumFound++;
int remaining = count - mWorkingIndex;
int matchIndex = index - remaining + 1;
// Set up a pointer to the matching text in 'chars'.
@@ -325,7 +344,7 @@ void FindCanvas::findHelper(const void* text, size_t byteLength,
// the previous line(s).
regionToAdd.op(mWorkingRegion, SkRegion::kUnion_Op);
}
- mRegions->append(regionToAdd);
+ insertMatchInfo(regionToAdd);
#if INCLUDE_SUBSTRING_MATCHES
// Reset index to the location of the match and reset j to the
// beginning, so that on the next iteration of the loop, index
@@ -338,6 +357,9 @@ void FindCanvas::findHelper(const void* text, size_t byteLength,
// character from our hidden match
index = matchIndex;
}
+ // Whether the clip contained it or not, we need to start over
+ // with our recording canvas
+ resetWorkingCanvas();
} else {
// Index needs to be set to index - j + 1.
// This is a ridiculous case, but imagine the situation where the
@@ -389,6 +411,14 @@ void FindCanvas::findHelper(const void* text, size_t byteLength,
mWorkingIndex = 0;
}
+SkCanvas* FindCanvas::getWorkingCanvas() {
+ if (!mWorkingPicture) {
+ mWorkingPicture = new SkPicture;
+ mWorkingCanvas = mWorkingPicture->beginRecording(0,0);
+ }
+ return mWorkingCanvas;
+}
+
GlyphSet* FindCanvas::getGlyphs(const SkPaint& paint) {
SkTypeface* typeface = paint.getTypeface();
GlyphSet* end = mGlyphSets.end();
@@ -402,3 +432,18 @@ GlyphSet* FindCanvas::getGlyphs(const SkPaint& paint) {
*mGlyphSets.append() = set;
return &(mGlyphSets.top());
}
+
+void FindCanvas::insertMatchInfo(const SkRegion& region) {
+ mNumFound++;
+ mWorkingPicture->endRecording();
+ MatchInfo matchInfo;
+ mMatches->append(matchInfo);
+ mMatches->last().set(region, mWorkingPicture);
+}
+
+void FindCanvas::resetWorkingCanvas() {
+ mWorkingPicture->unref();
+ mWorkingPicture = 0;
+ // Do not need to reset mWorkingCanvas itself because we only access it via
+ // getWorkingCanvas.
+}
diff --git a/WebKit/android/nav/FindCanvas.h b/WebKit/android/nav/FindCanvas.h
index fe1e3d2..5558c8b 100644
--- a/WebKit/android/nav/FindCanvas.h
+++ b/WebKit/android/nav/FindCanvas.h
@@ -17,23 +17,37 @@
#ifndef Find_Canvas_h
#define Find_Canvas_h
-// The code marked with this is used to record the draw calls into an SkPicture,
-// which is passed to the caller to draw the matches on top of the opaque green
-// rectangles. The code is a checkpoint.
-#define RECORD_MATCHES 0
-
#include "SkBounder.h"
#include "SkCanvas.h"
+#include "SkPicture.h"
#include "SkRegion.h"
#include "SkTDArray.h"
#include "icu/unicode/umachine.h"
-#if RECORD_MATCHES
-class SkPicture;
-#endif
class SkRect;
class SkTypeface;
+// Stores both region information and an SkPicture of the match, so that the
+// region can be drawn, followed by drawing the matching text on top of it.
+// This class owns its SkPicture
+class MatchInfo {
+public:
+ MatchInfo();
+ ~MatchInfo();
+ MatchInfo(const MatchInfo& src);
+ const SkRegion& getLocation() const { return m_location; }
+ // Return a pointer to our picture, representing the matching text. Does
+ // not transfer ownership of the picture.
+ SkPicture* getPicture() const { return m_picture; }
+ // This will make a copy of the region, and increase the ref count on the
+ // SkPicture. If this MatchInfo already had one, unref it.
+ void set(const SkRegion& region, SkPicture* pic);
+private:
+ MatchInfo& operator=(MatchInfo& src);
+ SkRegion m_location;
+ SkPicture* m_picture;
+};
+
// A class containing a typeface for reference, the length in glyphs, and
// the upper and lower case representations of the search string.
class GlyphSet {
@@ -113,20 +127,14 @@ public:
int found() const { return mNumFound; }
- // This method detaches our array of regions and passes ownership to
+ // This method detaches our array of matches and passes ownership to
// the caller, who is then responsible for deleting them.
- WTF::Vector<SkRegion>* detachRegions() {
- WTF::Vector<SkRegion>* array = mRegions;
- mRegions = NULL;
+ WTF::Vector<MatchInfo>* detachMatches() {
+ WTF::Vector<MatchInfo>* array = mMatches;
+ mMatches = NULL;
return array;
}
-#if RECORD_MATCHES
- // This SkPicture contains only draw calls for the drawn text. This is
- // used to draw over the highlight rectangle so that it can be seen.
- SkPicture* getDrawnMatches() const { return mPicture; }
-#endif
-
private:
// These calls are made by findHelper to store information about each match
// that is found. They return a rectangle which is used to highlight the
@@ -144,7 +152,7 @@ private:
SkRect addMatchPosH(int index,
const SkPaint& paint, int count, const uint16_t* glyphs,
const SkScalar position[], SkScalar constY);
-
+
// Helper for each of our draw calls
void findHelper(const void* text, size_t byteLength, const SkPaint& paint,
const SkScalar xPos[], SkScalar y,
@@ -152,14 +160,25 @@ private:
const SkPaint& paint, int count, const uint16_t* glyphs,
const SkScalar pos[], SkScalar y));
+ // If we already have a working canvas, grab it. Otherwise, create a new
+ // one.
+ SkCanvas* getWorkingCanvas();
+
// Return the set of glyphs and its count for the text being searched for
// and the parameter paint. If one has already been created and cached
// for this paint, use it. If not, create a new one and cache it.
GlyphSet* getGlyphs(const SkPaint& paint);
+ // Store all the accumulated info about a match in our vector.
+ void insertMatchInfo(const SkRegion& region);
+
+ // Throw away our cumulative information about our working SkCanvas. After
+ // this call, next call to getWorkingCanvas will create a new one.
+ void resetWorkingCanvas();
+
// Since we may transfer ownership of this array (see detachRects()), we
// hold a pointer to the array instead of just the array itself.
- WTF::Vector<SkRegion>* mRegions;
+ WTF::Vector<MatchInfo>* mMatches;
const UChar* mLowerText;
const UChar* mUpperText;
size_t mLength;
@@ -167,11 +186,9 @@ private:
int mNumFound;
SkScalar mOutset;
SkTDArray<GlyphSet> mGlyphSets;
-#if RECORD_MATCHES
- SkPicture* mPicture;
- SkCanvas* mRecordingCanvas;
-#endif
+ SkPicture* mWorkingPicture;
+ SkCanvas* mWorkingCanvas;
SkRegion mWorkingRegion;
int mWorkingIndex;
};
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index 7af96d7..63c6aeb 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -419,10 +419,6 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl)
m_matches = 0;
m_hasCurrentLocation = false;
m_isFindPaintSetUp = false;
-// RECORD_MATCHES is defined in FindCanvas.h
-#if RECORD_MATCHES
- m_matchesPicture = 0;
-#endif
}
~WebView()
@@ -437,10 +433,6 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl)
delete m_navPictureUI;
if (m_matches)
delete m_matches;
-// RECORD_MATCHES is defined in FindCanvas.h
-#if RECORD_MATCHES
- m_matchesPicture->safeUnref();
-#endif
}
void clearFocus(int x, int y, bool inval)
@@ -548,9 +540,7 @@ void setUpFindPaint()
const SkScalar roundiness = SkIntToScalar(2);
SkCornerPathEffect* cornerEffect = new SkCornerPathEffect(roundiness);
m_findPaint.setPathEffect(cornerEffect);
- // FIXME: Would like this to be opaque, but then the user cannot see the
- // text behind it. We will then need to redraw the text on top of it.
- m_findPaint.setARGB(204, 132, 190, 0);
+ m_findPaint.setARGB(255, 132, 190, 0);
// Set up the background blur paint.
m_findBlurPaint.setAntiAlias(true);
@@ -583,26 +573,34 @@ void drawMatch(const SkRegion& region, SkCanvas* canvas, bool focused)
// Offset the path for a blurred shadow
SkPath blurPath;
matchPath.offset(SK_Scalar1, SkIntToScalar(2), &blurPath);
+ int saveCount = 0;
+ if (!focused) {
+ saveCount = canvas->save();
+ canvas->clipPath(matchPath, SkRegion::kDifference_Op);
+ }
// Draw the blurred background
canvas->drawPath(blurPath, m_findBlurPaint);
+ if (!focused) {
+ canvas->restoreToCount(saveCount);
+ }
// Draw the foreground
canvas->drawPath(matchPath, m_findPaint);
}
+// Put a cap on the number of matches to draw. If the current page has more
+// matches than this, only draw the focused match.
+#define MAX_NUMBER_OF_MATCHES_TO_DRAW 101
+
void drawMatches(SkCanvas* canvas)
{
- if (!m_matches || !m_matches->size()
-// RECORD_MATCHES is defined in FindCanvas.h
-#if RECORD_MATCHES
- || !m_matchesPicture
-#endif
- ) {
+ if (!m_matches || !m_matches->size()) {
return;
}
if (m_findIndex >= m_matches->size()) {
m_findIndex = 0;
}
- const SkRegion& currentMatchRegion = (*m_matches)[m_findIndex];
+ const MatchInfo& matchInfo = (*m_matches)[m_findIndex];
+ const SkRegion& currentMatchRegion = matchInfo.getLocation();
const SkIRect& currentMatchBounds = currentMatchRegion.getBounds();
int left = currentMatchBounds.fLeft;
int top = currentMatchBounds.fTop;
@@ -636,36 +634,29 @@ void drawMatches(SkCanvas* canvas)
setUpFindPaint();
// Draw the current match
- drawMatch(currentMatchRegion, canvas, true);
+ drawMatch(currentMatchRegion, canvas, true);
+ // Now draw the picture, so that it shows up on top of the rectangle
+ canvas->drawPicture(*matchInfo.getPicture());
// Draw the rest
unsigned numberOfMatches = m_matches->size();
- int saveCount = 0;
- if (numberOfMatches > 1) {
+ if (numberOfMatches > 1
+ && numberOfMatches < MAX_NUMBER_OF_MATCHES_TO_DRAW) {
+ SkIRect visibleIRect;
+ android_setrect(&visibleIRect, visible);
for(unsigned i = 0; i < numberOfMatches; i++) {
// The current match has already been drawn
if (i == m_findIndex)
continue;
- const SkRegion& region = (*m_matches)[i];
- // Do not draw matches which intersect the current one
- if (currentMatchRegion.intersects(region))
+ const SkRegion& region = (*m_matches)[i].getLocation();
+ // Do not draw matches which intersect the current one, or if it is
+ // offscreen
+ if (currentMatchRegion.intersects(region)
+ || !region.intersects(visibleIRect))
continue;
drawMatch(region, canvas, false);
}
-// RECORD_MATCHES is defined in FindCanvas.h
-#if RECORD_MATCHES
- // Set a clip so we do not draw the text for the other matches.
- saveCount = canvas->save(SkCanvas::kClip_SaveFlag);
- canvas->clipRect(currentMatch);
-#endif
}
-// RECORD_MATCHES is defined in FindCanvas.h
-#if RECORD_MATCHES
- canvas->drawPicture(*m_matchesPicture);
- if (numberOfMatches > 1) {
- canvas->restoreToCount(saveCount);
- }
-#endif
}
void drawFocusRing(SkCanvas* canvas)
@@ -1112,6 +1103,18 @@ bool moveFocus(int keyCode, int count, bool ignoreScroll, bool inval,
void notifyFocusSet(FrameCachePermission inEditingMode)
{
+ CachedRoot* root = getFrameCache(DontAllowNewer);
+ if (root) {
+ // make sure the mFocusData in WebView.java is in sync with WebView.cpp
+ const CachedFrame* frame = 0;
+ const CachedNode* node = root->currentFocus(&frame);
+ const WebCore::IntPoint& focusLocation = root->focusLocation();
+ setFocusData(root->generation(),
+ frame ? (WebCore::Frame*) frame->framePointer() : 0,
+ node ? (WebCore::Node*) node->nodePointer() : 0,
+ focusLocation.x(), focusLocation.y(), false);
+ }
+
if (focusIsTextArea(inEditingMode))
updateTextEntry();
else if (inEditingMode)
@@ -1608,8 +1611,8 @@ void setFocusData(int buildGeneration, WebCore::Frame* framePtr,
// m_currentMatchLocation.
void inline storeCurrentMatchLocation()
{
- SkASSERT(m_findIndex < m_matches->size() && m_findIndex >= 0);
- const SkIRect& bounds = (*m_matches)[m_findIndex].getBounds();
+ SkASSERT(m_findIndex < m_matches->size());
+ const SkIRect& bounds = (*m_matches)[m_findIndex].getLocation().getBounds();
m_currentMatchLocation.set(bounds.fLeft, bounds.fTop);
m_hasCurrentLocation = true;
}
@@ -1635,12 +1638,7 @@ void findNext(bool forward)
// With this call, WebView takes ownership of matches, and is responsible for
// deleting it.
-void setMatches(WTF::Vector<SkRegion>* matches
-// RECORD_MATCHES is defined in FindCanvas.h
-#if RECORD_MATCHES
- , SkPicture* pic
-#endif
- )
+void setMatches(WTF::Vector<MatchInfo>* matches)
{
if (m_matches)
delete m_matches;
@@ -1648,7 +1646,7 @@ void setMatches(WTF::Vector<SkRegion>* matches
if (m_matches->size()) {
if (m_hasCurrentLocation) {
for (unsigned i = 0; i < m_matches->size(); i++) {
- const SkIRect& rect = (*m_matches)[i].getBounds();
+ const SkIRect& rect = (*m_matches)[i].getLocation().getBounds();
if (rect.fLeft == m_currentMatchLocation.fX
&& rect.fTop == m_currentMatchLocation.fY) {
m_findIndex = i;
@@ -1664,12 +1662,6 @@ void setMatches(WTF::Vector<SkRegion>* matches
} else {
m_hasCurrentLocation = false;
}
-// RECORD_MATCHES is defined in FindCanvas.h
-#if RECORD_MATCHES
- m_matchesPicture->safeUnref();
- m_matchesPicture = pic;
- m_matchesPicture->ref();
-#endif
viewInvalidate();
}
@@ -1778,7 +1770,7 @@ private: // local state for WebView
bool m_heightCanMeasure;
int m_lastDx;
SkMSec m_lastDxTime;
- WTF::Vector<SkRegion>* m_matches;
+ WTF::Vector<MatchInfo>* m_matches;
// Stores the location of the current match.
SkIPoint m_currentMatchLocation;
// Tells whether the value in m_currentMatchLocation is valid.
@@ -1789,10 +1781,6 @@ private: // local state for WebView
SkPaint m_findPaint;
// Paint used for the background of our Find matches.
SkPaint m_findBlurPaint;
-// RECORD_MATCHES is defined in FindCanvas.h
-#if RECORD_MATCHES
- SkPicture* m_matchesPicture;
-#endif
unsigned m_findIndex;
}; // end of WebView class
@@ -2096,14 +2084,9 @@ static int nativeFindAll(JNIEnv *env, jobject obj, jstring findLower,
bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
canvas.setBitmapDevice(bitmap);
canvas.drawPicture(*(root->getPicture()));
- WTF::Vector<SkRegion>* matches = canvas.detachRegions();
+ WTF::Vector<MatchInfo>* matches = canvas.detachMatches();
// With setMatches, the WebView takes ownership of matches
- view->setMatches(matches
-// RECORD_MATCHES is defined in FindCanvas.h
-#if RECORD_MATCHES
- , canvas.getDrawnMatches()
-#endif
- );
+ view->setMatches(matches);
env->ReleaseStringChars(findLower, findLowerChars);
env->ReleaseStringChars(findUpper, findUpperChars);