From: Cary Clark Date: Tue, 29 Jun 2010 18:11:45 +0000 (-0400) Subject: refine text selection X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=53de43bdc82ec558fea60a19a6da44927e58c3b3;p=android-x86%2Fexternal-webkit.git refine text selection Change 'select all' to begin with the first character and end with the last rather than relying on the top left and bottom right. The old algorithm failed for pages broken into multiple columns. Similarly, capture the text from the beginning selection to the ending selection, rather than relying on the characters contained by the selection region. Reduce the gap required to add a linebreak from twice the lineheight to 1.5x the lineheight. Change-Id: Ib90a719ea3353feeaa3a6cc692d0dd9cff498cb5 http://b/262451 --- diff --git a/WebKit/android/nav/SelectText.cpp b/WebKit/android/nav/SelectText.cpp index 011349e4a..7d2aaa79f 100644 --- a/WebKit/android/nav/SelectText.cpp +++ b/WebKit/android/nav/SelectText.cpp @@ -221,7 +221,8 @@ public: bool addNewLine(const SkBounder::GlyphRec& rec) { SkFixed lineSpacing = SkFixedAbs(mLastGlyph.fLSB.fY - rec.fLSB.fY); - return lineSpacing >= SkIntToFixed((bottom() - top()) * 2); + SkFixed lineHeight = SkIntToFixed(bottom() - top()); + return lineSpacing >= lineHeight + (lineHeight >> 1); // 1.5 } bool addSpace(const SkBounder::GlyphRec& rec) @@ -541,9 +542,7 @@ public: virtual bool onIRect(const SkIRect& rect) { - if (top() > mBestBounds.fTop) - return false; - if (top() < mBestBounds.fTop || rect.fLeft < mBestBounds.fLeft) + if (mBestBounds.isEmpty()) mBestBounds.set(rect.fLeft, top(), rect.fRight, bottom()); return false; } @@ -564,10 +563,7 @@ public: virtual bool onIRect(const SkIRect& rect) { - if (bottom() < mBestBounds.fBottom) - return false; - if (bottom() > mBestBounds.fBottom || rect.fRight > mBestBounds.fRight) - mBestBounds.set(rect.fLeft, top(), rect.fRight, bottom()); + mBestBounds.set(rect.fLeft, top(), rect.fRight, bottom()); return false; } @@ -633,9 +629,11 @@ private: class TextExtractor : public CommonCheck { public: - TextExtractor(const SkRegion& region, const SkIRect& area) + TextExtractor(const SkIRect& start, const SkIRect& end, const SkIRect& area) : INHERITED(area.width(), area.height()) - , mSelectRegion(region) + , mRecord(false) + , mSelectEnd(end) + , mSelectStart(start) , mSkipFirstSpace(true) // don't start with a space { } @@ -645,7 +643,9 @@ public: { SkIRect full; full.set(rect.fLeft, top(), rect.fRight, bottom()); - if (mSelectRegion.contains(full)) { + if (full == mSelectStart) + mRecord = true; + if (mRecord) { if (!mSkipFirstSpace) { if (addNewLine(rec)) { DBG_NAV_LOG("write new line"); @@ -675,6 +675,8 @@ public: DBG_NAV_LOGD("TextExtractor [%02x] skip full=(%d,%d,r=%d,b=%d)", rec.fGlyphID, full.fLeft, full.fTop, full.fRight, full.fBottom); } + if (full == mSelectEnd) + mRecord = false; return false; } @@ -696,7 +698,9 @@ public: } protected: - const SkRegion& mSelectRegion; + bool mRecord; + const SkIRect& mSelectEnd; + const SkIRect& mSelectStart; SkTDArray mSelectText; bool mSkipFirstSpace; private: @@ -865,15 +869,9 @@ static SkIRect findRight(const SkPicture& picture, const SkIRect& area, } static WebCore::String text(const SkPicture& picture, const SkIRect& area, - const SkRegion& region) + const SkIRect& start, const SkIRect& end) { - SkRegion copy = region; - copy.translate(-area.fLeft, -area.fTop); - const SkIRect& bounds = copy.getBounds(); - DBG_NAV_LOGD("area=(%d, %d, %d, %d) region=(%d, %d, %d, %d)", - area.fLeft, area.fTop, area.fRight, area.fBottom, - bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom); - TextExtractor extractor(copy, area); + TextExtractor extractor(start, end, area); TextCanvas checker(&extractor, area); checker.drawPicture(const_cast(picture)); return extractor.text(); @@ -1063,10 +1061,14 @@ void SelectText::extendSelection(const SkPicture* picture, int x, int y) const String SelectText::getSelection() { - SkIRect clipRect = m_selRegion.getBounds(); - DBG_NAV_LOGD("clip=(%d,%d,%d,%d)", clipRect.fLeft, - clipRect.fTop, clipRect.fRight, clipRect.fBottom); - String result = text(*m_picture, clipRect, m_selRegion); + SkIRect clipRect; + clipRect.set(0, 0, m_picture->width(), m_picture->height()); + String result = text(*m_picture, clipRect, m_selStart, m_selEnd); + DBG_NAV_LOGD("clip=(%d,%d,%d,%d)" + " m_selStart=(%d, %d, %d, %d) m_selEnd=(%d, %d, %d, %d)", + clipRect.fLeft, clipRect.fTop, clipRect.fRight, clipRect.fBottom, + m_selStart.fLeft, m_selStart.fTop, m_selStart.fRight, m_selStart.fBottom, + m_selEnd.fLeft, m_selEnd.fTop, m_selEnd.fRight, m_selEnd.fBottom); DBG_NAV_LOGD("text=%s", result.latin1().data()); // uses CString return result; }