diff options
Diffstat (limited to 'Source')
21 files changed, 62 insertions, 6338 deletions
diff --git a/Source/WebCore/platform/android/PopupMenuAndroid.cpp b/Source/WebCore/platform/android/PopupMenuAndroid.cpp index f4c351f..a5758bb 100644 --- a/Source/WebCore/platform/android/PopupMenuAndroid.cpp +++ b/Source/WebCore/platform/android/PopupMenuAndroid.cpp @@ -25,10 +25,13 @@ #include "config.h" #include "PopupMenuAndroid.h" +#include "IntRect.h" #include "PopupMenuClient.h" #include "SkTDArray.h" #include "WebViewCore.h" +using namespace WebCore; + class PopupReply : public android::WebCoreReply { public: PopupReply(const IntRect& rect, android::WebViewCore* view, ListPopupMenuClient* client) diff --git a/Source/WebKit/Android.mk b/Source/WebKit/Android.mk index c6f429b..67da200 100644 --- a/Source/WebKit/Android.mk +++ b/Source/WebKit/Android.mk @@ -76,12 +76,6 @@ LOCAL_SRC_FILES += \ android/jni/WebViewCore.cpp \ android/jni/ViewStateSerializer.cpp \ \ - android/nav/CachedFrame.cpp \ - android/nav/CachedHistory.cpp \ - android/nav/CachedInput.cpp \ - android/nav/CachedLayer.cpp \ - android/nav/CachedNode.cpp \ - android/nav/CachedRoot.cpp \ android/nav/DrawExtra.cpp \ android/nav/SelectText.cpp \ android/nav/WebView.cpp \ diff --git a/Source/WebKit/android/jni/PictureSet.cpp b/Source/WebKit/android/jni/PictureSet.cpp index 1d50074..89b16dc 100644 --- a/Source/WebKit/android/jni/PictureSet.cpp +++ b/Source/WebKit/android/jni/PictureSet.cpp @@ -26,10 +26,10 @@ #define LOG_NDEBUG 0 #define LOG_TAG "pictureset" -//#include <config.h> -#include "CachedPrefix.h" -#include "android_graphics.h" +#include "config.h" #include "PictureSet.h" + +#include "android_graphics.h" #include "SkBounder.h" #include "SkCanvas.h" #include "SkPicture.h" diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index 31e8506..6e899c2 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -32,8 +32,6 @@ #include "AndroidHitTestResult.h" #include "Attribute.h" #include "BaseLayerAndroid.h" -#include "CachedNode.h" -#include "CachedRoot.h" #include "content/address_detector.h" #include "Chrome.h" #include "ChromeClientAndroid.h" @@ -224,7 +222,6 @@ bool validNode(Frame* startFrame, void* matchFrame, } node = node->traverseNextNode(); } - DBG_NAV_LOGD("frame=%p valid node=%p invalid\n", matchFrame, matchNode); return false; } Frame* child = startFrame->tree()->firstChild(); @@ -234,10 +231,6 @@ bool validNode(Frame* startFrame, void* matchFrame, return result; child = child->tree()->nextSibling(); } -#if DEBUG_NAV_UI - if (startFrame->tree()->parent() == NULL) - DBG_NAV_LOGD("frame=%p node=%p false\n", matchFrame, matchNode); -#endif return false; } @@ -396,22 +389,11 @@ static jmethodID GetJMethod(JNIEnv* env, jclass clazz, const char name[], const return m; } -Mutex WebViewCore::gFrameCacheMutex; -Mutex WebViewCore::gCursorBoundsMutex; - WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* mainframe) - : m_frameCacheKit(0) - , m_moveGeneration(0) + : m_moveGeneration(0) , m_touchGeneration(0) , m_lastGeneration(0) - , m_updatedFrameCache(true) , m_findIsUp(false) - , m_hasCursorBounds(false) - , m_cursorBounds(WebCore::IntRect(0, 0, 0, 0)) - , m_cursorHitBounds(WebCore::IntRect(0, 0, 0, 0)) - , m_cursorFrame(0) - , m_cursorLocation(WebCore::IntPoint(0, 0)) - , m_cursorNode(0) , m_javaGlue(new JavaGlue) , m_mainFrame(mainframe) , m_popupReply(0) @@ -550,7 +532,6 @@ WebViewCore::~WebViewCore() m_javaGlue->m_obj = 0; } delete m_javaGlue; - delete m_frameCacheKit; } WebViewCore* WebViewCore::getWebViewCore(const WebCore::FrameView* view) @@ -599,19 +580,13 @@ WebCore::Node* WebViewCore::currentFocus() void WebViewCore::recordPicture(SkPicture* picture) { // if there is no document yet, just return - if (!m_mainFrame->document()) { - DBG_NAV_LOG("no document"); + if (!m_mainFrame->document()) return; - } // Call layout to ensure that the contentWidth and contentHeight are correct - if (!layoutIfNeededRecursive(m_mainFrame)) { - DBG_NAV_LOG("layout failed"); + if (!layoutIfNeededRecursive(m_mainFrame)) return; - } // draw into the picture's recording canvas WebCore::FrameView* view = m_mainFrame->view(); - DBG_NAV_LOGD("view=(w=%d,h=%d)", view->contentsWidth(), - view->contentsHeight()); SkAutoPictureRecord arp(picture, view->contentsWidth(), view->contentsHeight(), PICT_RECORD_FLAGS); SkAutoMemoryUsageProbe mup(__FUNCTION__); @@ -754,35 +729,6 @@ void WebViewCore::recordPictureSet(PictureSet* content) rebuildPictureSet(content); } -// note: updateCursorBounds is called directly by the WebView thread -// This needs to be called each time we call CachedRoot::setCursor() with -// non-null CachedNode/CachedFrame, since otherwise the WebViewCore's data -// about the cursor is incorrect. When we call setCursor(0,0), we need -// to set hasCursorBounds to false. -void WebViewCore::updateCursorBounds(const CachedRoot* root, - const CachedFrame* cachedFrame, const CachedNode* cachedNode) -{ - ALOG_ASSERT(root, "updateCursorBounds: root cannot be null"); - ALOG_ASSERT(cachedNode, "updateCursorBounds: cachedNode cannot be null"); - ALOG_ASSERT(cachedFrame, "updateCursorBounds: cachedFrame cannot be null"); - gCursorBoundsMutex.lock(); - m_hasCursorBounds = !cachedNode->isHidden(); - // If m_hasCursorBounds is false, we never look at the other - // values, so do not bother setting them. - if (m_hasCursorBounds) { - WebCore::IntRect bounds = cachedNode->bounds(cachedFrame); - if (m_cursorBounds != bounds) - DBG_NAV_LOGD("new cursor bounds=(%d,%d,w=%d,h=%d)", - bounds.x(), bounds.y(), bounds.width(), bounds.height()); - m_cursorBounds = bounds; - m_cursorHitBounds = cachedNode->hitBounds(cachedFrame); - m_cursorFrame = cachedFrame->framePointer(); - root->getSimulatedMousePosition(&m_cursorLocation); - m_cursorNode = cachedNode->nodePointer(); - } - gCursorBoundsMutex.unlock(); -} - void WebViewCore::clearContent() { DBG_SET_LOG(""); @@ -1061,7 +1007,6 @@ static int pin_pos(int x, int width, int targetWidth) void WebViewCore::didFirstLayout() { - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); ALOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); @@ -1086,13 +1031,10 @@ void WebViewCore::didFirstLayout() // a newly-loaded page. || loadType == WebCore::FrameLoadTypeSame); checkException(env); - - m_history.setDidFirstLayout(true); } void WebViewCore::updateViewport() { - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); ALOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); @@ -1105,7 +1047,6 @@ void WebViewCore::updateViewport() void WebViewCore::restoreScale(float scale, float textWrapScale) { - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); ALOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); @@ -1118,7 +1059,6 @@ void WebViewCore::restoreScale(float scale, float textWrapScale) void WebViewCore::needTouchEvents(bool need) { - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); ALOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); #if ENABLE(TOUCH_EVENTS) @@ -1139,7 +1079,6 @@ void WebViewCore::needTouchEvents(bool need) void WebViewCore::requestKeyboard(bool showKeyboard) { - DEBUG_NAV_UI_LOGD("%s", __FUNCTION__); ALOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); @@ -1158,8 +1097,6 @@ void WebViewCore::notifyProgressFinished() void WebViewCore::setScrollOffset(int moveGeneration, bool sendScrollEvent, int dx, int dy) { - DBG_NAV_LOGD("{%d,%d} m_scrollOffset=(%d,%d), sendScrollEvent=%d", dx, dy, - m_scrollOffsetX, m_scrollOffsetY, sendScrollEvent); if (m_scrollOffsetX != dx || m_scrollOffsetY != dy) { m_scrollOffsetX = dx; m_scrollOffsetY = dy; @@ -1193,19 +1130,10 @@ void WebViewCore::setScrollOffset(int moveGeneration, bool sendScrollEvent, int // update the currently visible screen sendPluginVisibleScreen(); } - gCursorBoundsMutex.lock(); - bool hasCursorBounds = m_hasCursorBounds; - Frame* frame = (Frame*) m_cursorFrame; - IntPoint location = m_cursorLocation; - gCursorBoundsMutex.unlock(); - if (!hasCursorBounds) - return; - moveMouseIfLatest(moveGeneration, frame, location.x(), location.y()); } void WebViewCore::setGlobalBounds(int x, int y, int h, int v) { - DBG_NAV_LOGD("{%d,%d}", x, y); m_mainFrame->view()->platformWidget()->setWindowBounds(x, y, h, v); } @@ -1225,8 +1153,6 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height, int osh = m_screenHeight; int otw = m_textWrapWidth; float oldScale = m_scale; - DBG_NAV_LOGD("old:(w=%d,h=%d,sw=%d,scale=%g) new:(w=%d,h=%d,sw=%d,scale=%g)", - ow, oh, osw, m_scale, width, height, screenWidth, scale); m_screenWidth = screenWidth; m_screenHeight = screenHeight; m_textWrapWidth = textWrapWidth; @@ -1245,11 +1171,8 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height, if (ow != width || (!ignoreHeight && oh != height) || reflow) { WebCore::RenderObject *r = m_mainFrame->contentRenderer(); - DBG_NAV_LOGD("renderer=%p view=(w=%d,h=%d)", r, - screenWidth, screenHeight); if (r) { WebCore::IntPoint anchorPoint = WebCore::IntPoint(anchorX, anchorY); - DBG_NAV_LOGD("anchorX=%d anchorY=%d", anchorX, anchorY); RefPtr<WebCore::Node> node; WebCore::IntRect bounds; WebCore::IntPoint offset; @@ -1264,8 +1187,6 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height, } if (node) { bounds = node->getRect(); - DBG_NAV_LOGD("ob:(x=%d,y=%d,w=%d,h=%d)", - bounds.x(), bounds.y(), bounds.width(), bounds.height()); // sites like nytimes.com insert a non-standard tag <nyt_text> // in the html. If it is the HitTestResult, it may have zero // width and height. In this case, use its parent node. @@ -1273,8 +1194,6 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height, node = node->parentOrHostNode(); if (node) { bounds = node->getRect(); - DBG_NAV_LOGD("found a zero width node and use its parent, whose ob:(x=%d,y=%d,w=%d,h=%d)", - bounds.x(), bounds.y(), bounds.width(), bounds.height()); } } } @@ -1295,9 +1214,6 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height, // scroll to restore current screen center if (node) { const WebCore::IntRect& newBounds = node->getRect(); - DBG_NAV_LOGD("nb:(x=%d,y=%d,w=%d," - "h=%d)", newBounds.x(), newBounds.y(), - newBounds.width(), newBounds.height()); if ((osw && osh && bounds.width() && bounds.height()) && (bounds != newBounds)) { WebCore::FrameView* view = m_mainFrame->view(); @@ -1396,9 +1312,6 @@ HTMLElement* WebViewCore::retrieveElement(int x, int y, || !element->hasTagName(tagName))) { element = element->parentNode(); } - DBG_NAV_LOGD("node=%p element=%p x=%d y=%d nodeName=%s tagName=%s", node, - element, x, y, node->nodeName().utf8().data(), - element ? ((Element*) element)->tagName().utf8().data() : "<none>"); return static_cast<WebCore::HTMLElement*>(element); } @@ -1948,12 +1861,8 @@ AndroidHitTestResult WebViewCore::hitTestAtPoint(int x, int y, int slop, bool do // adjust m_mousePos if it is not inside the returned highlight rectangle testRect.move(frameAdjust.x(), frameAdjust.y()); testRect.intersect(rect); - if (!testRect.contains(x, y)) { + if (!testRect.contains(x, y)) moveMouse(m_mainFrame, testRect.center().x(), testRect.center().y()); - DBG_NAV_LOGD("Move x/y from (%d, %d) to (%d, %d) scrollOffset is (%d, %d)", - x, y, m_mousePos.x() + m_scrollOffsetX, m_mousePos.y() + m_scrollOffsetY, - m_scrollOffsetX, m_scrollOffsetY); - } } } else { androidHitResult.searchContentDetectors(); @@ -2129,29 +2038,11 @@ static PluginView* nodeIsPlugin(Node* node) { return 0; } -Node* WebViewCore::cursorNodeIsPlugin() { - gCursorBoundsMutex.lock(); - bool hasCursorBounds = m_hasCursorBounds; - Frame* frame = (Frame*) m_cursorFrame; - Node* node = (Node*) m_cursorNode; - gCursorBoundsMutex.unlock(); - if (hasCursorBounds && validNode(m_mainFrame, frame, node) - && nodeIsPlugin(node)) { - return node; - } - return 0; -} - /////////////////////////////////////////////////////////////////////////////// void WebViewCore::moveMouseIfLatest(int moveGeneration, WebCore::Frame* frame, int x, int y) { - DBG_NAV_LOGD("m_moveGeneration=%d moveGeneration=%d" - " frame=%p x=%d y=%d", - m_moveGeneration, moveGeneration, frame, x, y); if (m_moveGeneration > moveGeneration) { - DBG_NAV_LOGD("m_moveGeneration=%d > moveGeneration=%d", - m_moveGeneration, moveGeneration); return; // short-circuit if a newer move has already been generated } m_lastGeneration = moveGeneration; @@ -2160,7 +2051,6 @@ void WebViewCore::moveMouseIfLatest(int moveGeneration, void WebViewCore::moveFocus(WebCore::Frame* frame, WebCore::Node* node) { - DBG_NAV_LOGD("frame=%p node=%p", frame, node); if (!node || !validNode(m_mainFrame, frame, node) || !node->isElementNode()) return; @@ -2180,8 +2070,6 @@ void WebViewCore::moveFocus(WebCore::Frame* frame, WebCore::Node* node) // Update mouse position void WebViewCore::moveMouse(WebCore::Frame* frame, int x, int y, HitTestResult* hoveredNode) { - DBG_NAV_LOGD("frame=%p x=%d y=%d scrollOffset=(%d,%d)", frame, - x, y, m_scrollOffsetX, m_scrollOffsetY); if (!frame || !validNode(m_mainFrame, frame, 0)) frame = m_mainFrame; // mouse event expects the position in the window coordinate @@ -2326,15 +2214,6 @@ String WebViewCore::modifySelectionTextNavigationAxis(DOMSelection* selection, i selection->addRange(rangeRef.get()); } else if (currentFocus()) { selection->setPosition(currentFocus(), 0, ec); - } else if (m_cursorNode - && validNode(m_mainFrame, - m_mainFrame, m_cursorNode)) { - RefPtr<Range> rangeRef = - selection->frame()->document()->createRange(); - rangeRef->selectNode(reinterpret_cast<Node*>(m_cursorNode), ec); - if (ec) - return String(); - selection->addRange(rangeRef.get()); } else { selection->setPosition(body, 0, ec); } @@ -2978,7 +2857,6 @@ void WebViewCore::passToJs(int generation, const WTF::String& current, { WebCore::Node* focus = currentFocus(); if (!focus) { - DBG_NAV_LOG("!focus"); clearTextEntry(); return; } @@ -2997,8 +2875,6 @@ void WebViewCore::passToJs(int generation, const WTF::String& current, if (test != current) { // If the text changed during the key event, update the UI text field. updateTextfield(focus, false, test); - } else { - DBG_NAV_LOG("test == current"); } // Now that the selection has settled down, send it. updateTextSelection(); @@ -3008,21 +2884,17 @@ void WebViewCore::scrollFocusedTextInput(float xPercent, int y) { WebCore::Node* focus = currentFocus(); if (!focus) { - DBG_NAV_LOG("!focus"); clearTextEntry(); return; } WebCore::RenderTextControl* renderText = toRenderTextControl(focus); if (!renderText) { - DBG_NAV_LOGD("renderer==%p || not text", renderer); clearTextEntry(); return; } int x = (int) (xPercent * (renderText->scrollWidth() - renderText->clientWidth())); - DBG_NAV_LOGD("x=%d y=%d xPercent=%g scrollW=%d clientW=%d", x, y, - xPercent, renderText->scrollWidth(), renderText->clientWidth()); renderText->setScrollLeft(x); renderText->setScrollTop(y); } @@ -3184,9 +3056,6 @@ void WebViewCore::click(WebCore::Frame* frame, WebCore::Node* node, bool fake) { hitTestResultAtPoint(pt, false); node = hitTestResult.innerNode(); frame = node->document()->frame(); - DBG_NAV_LOGD("m_mousePos=(%d,%d) m_scrollOffset=(%d,%d) pt=(%d,%d)" - " node=%p", m_mousePos.x(), m_mousePos.y(), - m_scrollOffsetX, m_scrollOffsetY, pt.x(), pt.y(), node); } if (node) { EditorClientAndroid* client @@ -3304,13 +3173,9 @@ void WebViewCore::touchUp(int touchGeneration, frame = node->document()->frame(); else frame = 0; - DBG_NAV_LOGD("touch up on (%d, %d), scrollOffset is (%d, %d), node:%p, frame:%p", m_mousePos.x() + m_scrollOffsetX, m_mousePos.y() + m_scrollOffsetY, m_scrollOffsetX, m_scrollOffsetY, node, frame); } else { - if (m_touchGeneration > touchGeneration) { - DBG_NAV_LOGD("m_touchGeneration=%d > touchGeneration=%d" - " x=%d y=%d", m_touchGeneration, touchGeneration, x, y); + if (m_touchGeneration > touchGeneration) return; // short circuit if a newer touch has been generated - } // This moves m_mousePos to the correct place, and handleMouseClick uses // m_mousePos to determine where the click happens. moveMouse(frame, x, y); @@ -3319,8 +3184,6 @@ void WebViewCore::touchUp(int touchGeneration, if (frame && validNode(m_mainFrame, frame, 0)) { frame->loader()->resetMultipleFormSubmissionProtection(); } - DBG_NAV_LOGD("touchGeneration=%d handleMouseClick frame=%p node=%p" - " x=%d y=%d", touchGeneration, frame, node, x, y); handleMouseClick(frame, node, false); } @@ -3354,7 +3217,6 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node webFrame->setUserInitiatedAction(true); nodePtr->dispatchSimulatedClick(0, true, true); webFrame->setUserInitiatedAction(false); - DBG_NAV_LOG("area"); return true; } } @@ -3375,8 +3237,6 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node // If the user clicked on a textfield, make the focusController active // so we show the blinking cursor. WebCore::Node* focusNode = currentFocus(); - DBG_NAV_LOGD("m_mousePos={%d,%d} focusNode=%p handled=%s", m_mousePos.x(), - m_mousePos.y(), focusNode, handled ? "true" : "false"); if (focusNode) { WebCore::RenderTextControl* rtc = toRenderTextControl(focusNode); if (rtc) { diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h index bf7c36b..c5bb63f 100644 --- a/Source/WebKit/android/jni/WebViewCore.h +++ b/Source/WebKit/android/jni/WebViewCore.h @@ -26,16 +26,18 @@ #ifndef WebViewCore_h #define WebViewCore_h -#include "CachedHistory.h" #include "DeviceMotionAndOrientationManager.h" #include "DOMSelection.h" #include "FileChooser.h" +#include "HitTestResult.h" #include "PictureSet.h" #include "PlatformGraphicsContext.h" #include "Position.h" +#include "ScrollTypes.h" #include "SkColor.h" #include "SkTDArray.h" #include "SkRegion.h" +#include "Text.h" #include "Timer.h" #include "WebCoreRefObject.h" #include "WebCoreJni.h" @@ -68,6 +70,7 @@ namespace WebCore { #if USE(ACCELERATED_COMPOSITING) namespace WebCore { class GraphicsLayerAndroid; + class LayerAndroid; } #endif @@ -80,6 +83,9 @@ class SkPicture; class SkIRect; namespace android { + // TODO: This file hasn't been good about namespace. Remove this temporary + // workaround to build + using namespace WebCore; enum Direction { DIRECTION_BACKWARD = 0, @@ -96,9 +102,6 @@ namespace android { AXIS_DOCUMENT = 6 }; - class CachedFrame; - class CachedNode; - class CachedRoot; class ListBoxReply; class AndroidHitTestResult; class SelectText; @@ -460,9 +463,6 @@ namespace android { // lookup the plugin widget struct given an NPP PluginWidgetAndroid* getPluginWidget(NPP npp); - // return the cursorNode if it is a plugin - Node* cursorNodeIsPlugin(); - // Notify the Java side whether it needs to pass down the touch events void needTouchEvents(bool); @@ -540,8 +540,6 @@ namespace android { float textWrapScale() const { return m_screenWidth * m_scale / m_textWrapWidth; } WebCore::Frame* mainFrame() const { return m_mainFrame; } WebCore::Frame* focusedFrame() const; - void updateCursorBounds(const CachedRoot* root, - const CachedFrame* cachedFrame, const CachedNode* cachedNode); // utility to split slow parts of the picture set void splitContent(PictureSet*); @@ -613,20 +611,10 @@ namespace android { WebCore::VisiblePosition visiblePositionForWindowPoint(int x, int y); // these members are shared with webview.cpp - static Mutex gFrameCacheMutex; - CachedRoot* m_frameCacheKit; // nav data being built by webcore int m_moveGeneration; // copy of state in WebViewNative triggered by move int m_touchGeneration; // copy of state in WebViewNative triggered by touch int m_lastGeneration; // last action using up to date cache - bool m_updatedFrameCache; bool m_findIsUp; - bool m_hasCursorBounds; - WebCore::IntRect m_cursorBounds; - WebCore::IntRect m_cursorHitBounds; - void* m_cursorFrame; - IntPoint m_cursorLocation; - void* m_cursorNode; - static Mutex gCursorBoundsMutex; // end of shared members // internal functions @@ -763,7 +751,6 @@ namespace android { WebCore::IntPoint m_mousePos; bool m_frameCacheOutOfDate; bool m_progressDone; - CachedHistory m_history; int m_screenWidth; // width of the visible rect in document coordinates int m_screenHeight;// height of the visible rect in document coordinates int m_textWrapWidth; diff --git a/Source/WebKit/android/nav/CachedDebug.h b/Source/WebKit/android/nav/CachedDebug.h deleted file mode 100644 index c78254e..0000000 --- a/Source/WebKit/android/nav/CachedDebug.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2007, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CachedDebug_h -#define CachedDebug_h - -#define DUMP_NAV_CACHE 0 -#define DEBUG_NAV_UI 0 -#define DEBUG_NAV_UI_VERBOSE 0 - -#if DEBUG_NAV_UI -#define DBG_NAV_LOG(message) ALOGD("%s %s", __FUNCTION__, message) -#define DBG_NAV_LOGD(format, ...) ALOGD("%s " format, __FUNCTION__, __VA_ARGS__) -#define DEBUG_NAV_UI_LOGD(...) ALOGD(__VA_ARGS__) -#else -#define DBG_NAV_LOG(message) ((void)0) -#define DBG_NAV_LOGD(format, ...) ((void)0) -#define DEBUG_NAV_UI_LOGD(...) ((void)0) -#endif - -#if DEBUG_NAV_UI_VERBOSE -#define DBG_NAV_LOGV(format, ...) ALOGD("%s " format, __FUNCTION__, __VA_ARGS__) -#else -#define DBG_NAV_LOGV(format, ...) ((void)0) -#endif - -#if DUMP_NAV_CACHE != 0 && !defined DUMP_NAV_CACHE_USING_PRINTF && defined NDEBUG -#define DUMP_NAV_CACHE_USING_PRINTF -#endif - -#if DUMP_NAV_CACHE -#ifdef DUMP_NAV_CACHE_USING_PRINTF -#include <stdio.h> -extern FILE* gNavCacheLogFile; -#define NAV_CACHE_LOG_FILE "/data/data/com.android.browser/navlog" -#define DUMP_NAV_LOGD(...) do { if (gNavCacheLogFile) \ - fprintf(gNavCacheLogFile, __VA_ARGS__); else ALOGD(__VA_ARGS__); } while (false) -#define DUMP_NAV_LOGX(format, ...) do { if (gNavCacheLogFile) \ - fprintf(gNavCacheLogFile, format, __VA_ARGS__); \ - else ALOGD("%s " format, __FUNCTION__, __VA_ARGS__); } while (false) -#else -#define DUMP_NAV_LOGD(...) ALOGD(__VA_ARGS__) -#define DUMP_NAV_LOGX(format, ...) ALOGD("%s " format, __FUNCTION__, __VA_ARGS__) -#endif -#else -#define DUMP_NAV_LOGD(...) ((void)0) -#define DUMP_NAV_LOGX(...) ((void)0) -#endif - -#endif diff --git a/Source/WebKit/android/nav/CachedFrame.cpp b/Source/WebKit/android/nav/CachedFrame.cpp deleted file mode 100644 index cdfd8b2..0000000 --- a/Source/WebKit/android/nav/CachedFrame.cpp +++ /dev/null @@ -1,1506 +0,0 @@ -/* - * Copyright 2007, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "CachedPrefix.h" -#include "CachedHistory.h" -#include "CachedNode.h" -#include "CachedRoot.h" -#include "LayerAndroid.h" - -#include "CachedFrame.h" - -#define OFFSETOF(type, field) ((char*)&(((type*)1)->field) - (char*)1) // avoids gnu warning - -#define MIN_OVERLAP 3 // if rects overlap by 2 pixels or fewer, treat them as non-intersecting - -namespace android { - -WebCore::IntRect CachedFrame::adjustBounds(const CachedNode* node, - const WebCore::IntRect& rect) const -{ - DBG_NAV_LOGV("node=%p [%d] rect=(%d,%d,w=%d,h=%d) view=(%d,%d,w=%d,h=%d)" - " local=(%d,%d,w=%d,h=%d) root=(%d,%d,w=%d,h=%d)", - node, node->index(), rect.x(), rect.y(), rect.width(), rect.height(), - mViewBounds.x(), mViewBounds.y(), - mViewBounds.width(), mViewBounds.height(), - mLocalViewBounds.x(), mLocalViewBounds.y(), - mLocalViewBounds.width(), mLocalViewBounds.height(), - mRoot->mViewBounds.x(), mRoot->mViewBounds.y(), - mRoot->mViewBounds.width(), mRoot->mViewBounds.height()); -#if USE(ACCELERATED_COMPOSITING) - if (!mRoot) - return rect; - - const CachedLayer* cachedLayer = layer(node); - if (!cachedLayer) - return rect; - - const WebCore::LayerAndroid* rootLayer = mRoot->rootLayer(); - const LayerAndroid* aLayer = cachedLayer->layer(rootLayer); - if (aLayer) - return cachedLayer->adjustBounds(rootLayer, rect); -#endif - return rect; -} - -bool CachedFrame::CheckBetween(Direction direction, const WebCore::IntRect& bestRect, - const WebCore::IntRect& prior, WebCore::IntRect* result) -{ - int left, top, width, height; - if (direction & UP_DOWN) { - top = direction == UP ? bestRect.maxY() : prior.maxY(); - int bottom = direction == UP ? prior.y() : bestRect.y(); - height = bottom - top; - if (height < 0) - return false; - left = prior.x(); - int testLeft = bestRect.x(); - if (left > testLeft) - left = testLeft; - int right = prior.maxX(); - int testRight = bestRect.maxX(); - if (right < testRight) - right = testRight; - width = right - left; - } else { - left = direction == LEFT ? bestRect.maxX() : prior.maxX(); - int right = direction == LEFT ? prior.x() : bestRect.x(); - width = right - left; - if (width < 0) - return false; - top = prior.y(); - int testTop = bestRect.y(); - if (top > testTop) - top = testTop; - int bottom = prior.maxY(); - int testBottom = bestRect.maxY(); - if (bottom < testBottom) - bottom = testBottom; - height = bottom - top; - } - *result = WebCore::IntRect(left, top, width, height); - return true; -} - -bool CachedFrame::checkBetween(BestData* best, Direction direction) -{ - const WebCore::IntRect& bestRect = best->bounds(); - BestData test; - test.mDistance = INT_MAX; - test.mNode = NULL; - int index = direction; - int limit = index + DIRECTION_COUNT; - do { - WebCore::IntRect edges; - Direction check = (Direction) (index & DIRECTION_MASK); - if (CheckBetween(check, bestRect, - history()->priorBounds(), &edges) == false) - continue; - WebCore::IntRect clip = mRoot->scrolledBounds(); - clip.intersect(edges); - if (clip.isEmpty()) - continue; - findClosest(&test, direction, check, &clip); - if (test.mNode == NULL) - continue; - if (direction == check) - break; - } while (++index < limit); - if (test.mNode == NULL) - return false; - *best = test; - return true; -} - -bool CachedFrame::checkRings(const CachedNode* node, - const WebCore::IntRect& testBounds) const -{ - return mRoot->checkRings(picture(node), node, testBounds); -} - -bool CachedFrame::checkVisited(const CachedNode* node, Direction direction) const -{ - return history()->checkVisited(node, direction); -} - -void CachedFrame::clearCursor() -{ - DBG_NAV_LOGD("mCursorIndex=%d", mCursorIndex); - if (mCursorIndex < CURSOR_SET) - return; - CachedNode& cursor = mCachedNodes[mCursorIndex]; - cursor.clearCursor(this); - mCursorIndex = CURSOR_CLEARED; // initialized and explicitly cleared -} - -// returns 0 if test is preferable to best, 1 if not preferable, or -1 if unknown -int CachedFrame::compare(BestData& testData, const BestData& bestData) const -{ - if (testData.mNode->tabIndex() != bestData.mNode->tabIndex()) { - if (testData.mNode->tabIndex() < bestData.mNode->tabIndex() - || (mRoot->mCursor && mRoot->mCursor->tabIndex() < bestData.mNode->tabIndex())) { - testData.mNode->setCondition(CachedNode::HIGHER_TAB_INDEX); - return REJECT_TEST; - } - return TEST_IS_BEST; - } - // if the test minor axis line intersects the line segment between cursor - // center and best center, choose it - // give more weight to exact major axis alignment (rows, columns) - if (testData.mInNav != bestData.mInNav) { - if (bestData.mInNav) { - testData.mNode->setCondition(CachedNode::IN_CURSOR); - return REJECT_TEST; - } - return TEST_IS_BEST; - } - if (testData.mInNav) { - if (bestData.mMajorDelta < testData.mMajorDelta) { - testData.mNode->setCondition(CachedNode::CLOSER_IN_CURSOR); - return REJECT_TEST; - } - if (testData.mMajorDelta < bestData.mMajorDelta) - return TEST_IS_BEST; - } - if (testData.mMajorDelta < 0 && bestData.mMajorDelta >= 0) { - testData.mNode->setCondition(CachedNode::FURTHER); - return REJECT_TEST; - } - if ((testData.mMajorDelta ^ bestData.mMajorDelta) < 0) // one above, one below (or one left, one right) - return TEST_IS_BEST; - bool bestInWorking = bestData.inOrSubsumesWorking(); - bool testInWorking = testData.inOrSubsumesWorking(); - if (bestInWorking && testData.mWorkingOutside && testData.mNavOutside) { - testData.mNode->setCondition(CachedNode::IN_WORKING); - return REJECT_TEST; - } - if (testInWorking && bestData.mWorkingOutside && bestData.mNavOutside) - return TEST_IS_BEST; - bool bestInNav = directionChange() && bestData.inOrSubsumesNav(); - bool testInNav = directionChange() && testData.inOrSubsumesNav(); - if (bestInWorking == false && testInWorking == false) { - if (bestInNav && testData.mNavOutside) { - testData.mNode->setCondition(CachedNode::IN_UMBRA); - return REJECT_TEST; - } - if (testInNav && bestData.mNavOutside) - return TEST_IS_BEST; - } -#if 01 // hopefully butt test will remove need for this - if (testData.mCursorChild != bestData.mCursorChild) { - if (bestData.mCursorChild) { - testData.mNode->setCondition(CachedNode::IN_CURSOR_CHILDREN); - return REJECT_TEST; - } - return TEST_IS_BEST; - } -#endif - bool bestTestIn = (bestInWorking || bestInNav) && (testInWorking || testInNav); - bool testOverlap = bestTestIn || (testData.mWorkingOverlap != 0 && bestData.mWorkingOverlap == 0); - bool bestOverlap = bestTestIn || (testData.mWorkingOverlap == 0 && bestData.mWorkingOverlap != 0); -#if 01 // this isn't working? - if (testOverlap == bestOverlap) { - if (bestData.mMajorButt < 10 && testData.mMajorButt >= 40) { - testData.mNode->setCondition(CachedNode::BUTTED_UP); - return REJECT_TEST; - } - if (testData.mMajorButt < 10 && bestData.mMajorButt >= 40) - return TEST_IS_BEST; - } -#endif - if (bestOverlap && bestData.mMajorDelta < testData.mMajorDelta) { // choose closest major axis center - testData.mNode->setCondition(CachedNode::CLOSER); - return REJECT_TEST; - } - if (testOverlap && testData.mMajorDelta < bestData.mMajorDelta) - return TEST_IS_BEST; - if (bestOverlap && bestData.mMajorDelta2 < testData.mMajorDelta2) { - testData.mNode->setCondition(CachedNode::CLOSER_TOP); - return REJECT_TEST; - } - if (testOverlap && testData.mMajorDelta2 < bestData.mMajorDelta2) - return TEST_IS_BEST; -#if 01 - if (bestOverlap && ((bestData.mSideDistance <= 0 && testData.mSideDistance > 0) || - abs(bestData.mSideDistance) < abs(testData.mSideDistance))) { - testData.mNode->setCondition(CachedNode::LEFTMOST); - return REJECT_TEST; - } - if (testOverlap && ((testData.mSideDistance <= 0 && bestData.mSideDistance > 0) || - abs(testData.mSideDistance) < abs(bestData.mSideDistance))) - return TEST_IS_BEST; -// fix me : the following ASSERT fires -- not sure if this case should be handled or not -// ASSERT(bestOverlap == false && testOverlap == false); -#endif - SkFixed testMultiplier = testData.mWorkingOverlap > testData.mNavOverlap ? - testData.mWorkingOverlap : testData.mNavOverlap; - SkFixed bestMultiplier = bestData.mWorkingOverlap > bestData.mNavOverlap ? - bestData.mWorkingOverlap : bestData.mNavOverlap; - int testDistance = testData.mDistance; - int bestDistance = bestData.mDistance; -// start here; - // this fails if they're off by 1 - // try once again to implement sliding scale so that off by 1 is nearly like zero, - // and off by a lot causes sideDistance to have little or no effect - // try elliptical distance -- lengthen side contribution - // these ASSERTs should not fire, but do fire on mail.google.com - // can't debug yet, won't reproduce - ASSERT(testDistance >= 0); - ASSERT(bestDistance >= 0); - testDistance += testDistance; // multiply by 2 - testDistance *= testDistance; - bestDistance += bestDistance; // multiply by 2 - bestDistance *= bestDistance; - int side = testData.mSideDistance; - int negative = side < 0 && bestData.mSideDistance > 0; - side *= side; - if (negative) - side = -side; - testDistance += side; - side = bestData.mSideDistance; - negative = side < 0 && testData.mSideDistance > 0; - side *= side; - if (negative) - side = -side; - bestDistance += side; - if (testMultiplier > (SK_Fixed1 >> 1) || bestMultiplier > (SK_Fixed1 >> 1)) { // considerable working overlap? - testDistance = SkFixedMul(testDistance, bestMultiplier); - bestDistance = SkFixedMul(bestDistance, testMultiplier); - } - if (bestDistance < testDistance) { - testData.mNode->setCondition(CachedNode::CLOSER_OVERLAP); - return REJECT_TEST; - } - if (testDistance < bestDistance) - return TEST_IS_BEST; -#if 0 - int distance = testData.mDistance + testData.mSideDistance; - int best = bestData.mDistance + bestData.mSideDistance; - if (distance > best) { - testData.mNode->setCondition(CachedNode::CLOSER_RAW_DISTANCE); - return REJECT_TEST; - } - else if (distance < best) - return TEST_IS_BEST; - best = bestData.mSideDistance; - if (testData.mSideDistance > best) { - testData.mNode->setCondition(CachedNode::SIDE_DISTANCE); - return REJECT_TEST; - } - if (testData.mSideDistance < best) - return TEST_IS_BEST; -#endif - if (testData.mPreferred < bestData.mPreferred) { - testData.mNode->setCondition(CachedNode::PREFERRED); - return REJECT_TEST; - } - if (testData.mPreferred > bestData.mPreferred) - return TEST_IS_BEST; - return UNDECIDED; -} - -const CachedNode* CachedFrame::currentCursor(const CachedFrame** framePtr) const -{ - if (framePtr) - *framePtr = this; - if (mCursorIndex < CURSOR_SET) - return NULL; - const CachedNode* result = &mCachedNodes[mCursorIndex]; - const CachedFrame* frame = hasFrame(result); - if (frame != NULL) - return frame->currentCursor(framePtr); - (const_cast<CachedNode*>(result))->fixUpCursorRects(this); - return result; -} - -const CachedNode* CachedFrame::currentFocus(const CachedFrame** framePtr) const -{ - if (framePtr) - *framePtr = this; - if (mFocusIndex < 0) - return NULL; - const CachedNode* result = &mCachedNodes[mFocusIndex]; - const CachedFrame* frame = hasFrame(result); - if (frame != NULL) - return frame->currentFocus(framePtr); - return result; -} - -bool CachedFrame::directionChange() const -{ - return history()->directionChange(); -} - -#ifdef BROWSER_DEBUG -CachedNode* CachedFrame::find(WebCore::Node* node) // !!! probably debugging only -{ - for (CachedNode* test = mCachedNodes.begin(); test != mCachedNodes.end(); test++) - if (node == test->webCoreNode()) - return test; - for (CachedFrame* frame = mCachedFrames.begin(); frame != mCachedFrames.end(); - frame++) { - CachedNode* result = frame->find(node); - if (result != NULL) - return result; - } - return NULL; -} -#endif - -const CachedNode* CachedFrame::findBestAt(const WebCore::IntRect& rect, - int* best, bool* inside, const CachedNode** directHit, - const CachedFrame** directHitFramePtr, - const CachedFrame** framePtr, int* x, int* y, - bool checkForHiddenStart) const -{ - const CachedNode* result = NULL; - int rectWidth = rect.width(); - WebCore::IntPoint center = WebCore::IntPoint(rect.x() + (rectWidth >> 1), - rect.y() + (rect.height() >> 1)); - mRoot->setupScrolledBounds(); - for (const CachedNode* test = mCachedNodes.begin(); test != mCachedNodes.end(); test++) { - if (test->disabled()) - continue; - size_t parts = test->navableRects(); - BestData testData; - testData.mNode = test; - testData.mFrame = this; - WebCore::IntRect bounds = test->bounds(this); - testData.setMouseBounds(bounds); - testData.setNodeBounds(bounds); - bool checkForHidden = checkForHiddenStart; - for (size_t part = 0; part < parts; part++) { - WebCore::IntRect testRect = test->ring(this, part); - if (testRect.intersects(rect)) { -#if DEBUG_NAV_UI - if (test->isInLayer()) { - DBG_NAV_LOGD("[%d] intersects=%s testRect=(%d,%d,w=%d,h=%d)" - " rect=(%d,%d,w=%d,h=%d)", test->index(), - testRect.intersects(rect) ? "true" : "false", - testRect.x(), testRect.y(), - testRect.width(), testRect.height(), - rect.x(), rect.y(), rect.width(), rect.height()); - } -#endif - if (checkForHidden && mRoot->maskIfHidden(&testData) == true) { - DBG_NAV_LOGD("hidden [%d]", test->index()); - break; - } - checkForHidden = false; - testRect.intersect(testData.mouseBounds()); - if (testRect.contains(center)) { - // We have a direct hit. - if (*directHit == NULL) { - DBG_NAV_LOGD("direct hit 1 [%d]", test->index()); - *directHit = test; - *directHitFramePtr = this; - IntRect r(center, IntSize(0, 0)); - *x = r.x(); - *y = r.y(); - } else { - DBG_NAV_LOGD("direct hit 2 [%d]", test->index()); - // We have hit another one before - const CachedNode* d = *directHit; - if (d->bounds(this).contains(testRect)) { - // This rectangle is inside the other one, so it is - // the best one. - *directHit = test; - *directHitFramePtr = this; - } - } - } - if (NULL != *directHit) { - // If we have a direct hit already, there is no need to - // calculate the distances, or check the other parts - break; - } - DBG_NAV_LOGD("indirect hit [%d]", test->index()); - WebCore::IntRect both = rect; - int smaller = testRect.width() < testRect.height() ? - testRect.width() : testRect.height(); - smaller -= rectWidth; - int inset = smaller < rectWidth ? smaller : rectWidth; - inset >>= 1; // inflate doubles the width decrease - if (inset > 1) - both.inflate(1 - inset); - both.intersect(testRect); - if (both.isEmpty()) - continue; - bool testInside = testRect.contains(center); - if (*inside && !testInside) - continue; - WebCore::IntPoint testCenter = WebCore::IntPoint(testRect.x() + - (testRect.width() >> 1), testRect.y() + (testRect.height() >> 1)); - int dx = testCenter.x() - center.x(); - int dy = testCenter.y() - center.y(); - int distance = dx * dx + dy * dy; - if ((!*inside && testInside) || *best >= distance) { - *best = distance; - *inside = testInside; - result = test; - *framePtr = this; - *x = both.x() + (both.width() >> 1); - *y = both.y() + (both.height() >> 1); - } - } - } - } - for (const CachedFrame* frame = mCachedFrames.begin(); - frame != mCachedFrames.end(); frame++) { - const CachedNode* frameResult = frame->findBestAt(rect, best, inside, - directHit, directHitFramePtr, framePtr, x, y, checkForHiddenStart); - if (NULL != frameResult) - result = frameResult; - } - if (NULL != *directHit) { - result = *directHit; - *framePtr = *directHitFramePtr; - } - return result; -} - -const CachedFrame* CachedFrame::findBestFrameAt(int x, int y) const -{ - if (mLocalViewBounds.contains(x, y) == false) - return NULL; - const CachedFrame* result = this; - for (const CachedFrame* frame = mCachedFrames.begin(); - frame != mCachedFrames.end(); frame++) { - const CachedFrame* frameResult = frame->findBestFrameAt(x, y); - if (NULL != frameResult) - result = frameResult; - } - return result; -} - -const CachedNode* CachedFrame::findBestHitAt(const WebCore::IntRect& rect, - const CachedFrame** framePtr, int* x, int* y) const -{ - mRoot->setupScrolledBounds(); - for (const CachedFrame* frame = mCachedFrames.end() - 1; - frame != mCachedFrames.begin() - 1; frame--) { - const CachedNode* frameResult = frame->findBestHitAt(rect, - framePtr, x, y); - if (NULL != frameResult) - return frameResult; - } - for (const CachedNode* test = mCachedNodes.end() - 1; - test != mCachedNodes.begin() - 1; test--) { - if (test->disabled()) - continue; - WebCore::IntRect testRect = test->hitBounds(this); - if (testRect.intersects(rect) == false) - continue; - BestData testData; - testData.mNode = test; - testData.mFrame = this; - testData.setMouseBounds(testRect); - testData.setNodeBounds(testRect); - if (mRoot->maskIfHidden(&testData) == true) - continue; - DBG_NAV_LOGD("candidate %d rect=(%d,%d,r=%d,b=%d)" - " testRect=(%d,%d,r=%d,b=%d)", - test->index(), rect.x(), rect.y(), rect.maxX(), rect.maxY(), - testRect.x(), testRect.y(), testRect.maxX(), testRect.maxY()); - for (int i = 0; i < test->navableRects(); i++) { - WebCore::IntRect cursorRect = test->ring(this, i); - DBG_NAV_LOGD("candidate %d cursorRect=(%d,%d,r=%d,b=%d)", - i, cursorRect.x(), cursorRect.y(), cursorRect.maxX(), - cursorRect.maxY()); - if (cursorRect.intersects(rect)) { - WebCore::IntRect intersection(cursorRect); - intersection.intersect(rect); - *x = intersection.x() + (intersection.width() >> 1); - *y = intersection.y() + (intersection.height() >> 1); - *framePtr = this; - return test; - } - } - testRect.intersect(rect); - *x = testRect.x() + (testRect.width() >> 1); - *y = testRect.y() + (testRect.height() >> 1); - *framePtr = this; - return test; - } - return NULL; -} - -void CachedFrame::findClosest(BestData* bestData, Direction originalDirection, - Direction direction, WebCore::IntRect* clip) const -{ - const CachedNode* test = mCachedNodes.begin(); - while ((test = test->traverseNextNode()) != NULL) { - const CachedFrame* child = hasFrame(test); - if (child != NULL) { - const CachedNode* childDoc = child->validDocument(); - if (childDoc == NULL) - continue; - child->findClosest(bestData, originalDirection, direction, clip); - } - if (test->noSecondChance()) - continue; - if (test->isNavable(this, *clip) == false) - continue; - if (checkVisited(test, originalDirection) == false) - continue; - size_t partMax = test->navableRects(); - for (size_t part = 0; part < partMax; part++) { - WebCore::IntRect testBounds = test->ring(this, part); - if (clip->intersects(testBounds) == false) - continue; - if (clip->contains(testBounds) == false) { - if (direction & UP_DOWN) { -// if (testBounds.x() > clip->x() || testBounds.right() < clip->right()) -// continue; - testBounds.setX(clip->x()); - testBounds.setWidth(clip->width()); - } else { -// if (testBounds.y() > clip->y() || testBounds.bottom() < clip->bottom()) -// continue; - testBounds.setY(clip->y()); - testBounds.setHeight(clip->height()); - } - if (clip->contains(testBounds) == false) - continue; - } - int distance; - // seems like distance for UP for instance needs to be 'test top closest to - // clip bottom' -- keep the old code but try this instead - switch (direction) { -#if 0 - case LEFT: - distance = testBounds.x() - clip->x(); - break; - case RIGHT: - distance = clip->right() - testBounds.right(); - break; - case UP: - distance = testBounds.y() - clip->y(); - break; - case DOWN: - distance = clip->bottom() - testBounds.bottom(); - break; -#else - case LEFT: - distance = clip->maxX() - testBounds.x(); - break; - case RIGHT: - distance = testBounds.maxX() - clip->x(); - break; - case UP: - distance = clip->maxY() - testBounds.y(); - break; - case DOWN: - distance = testBounds.maxY() - clip->y(); - break; -#endif - default: - distance = 0; - ASSERT(false); - } - if (distance < bestData->mDistance) { - bestData->mNode = test; - bestData->mFrame = this; - bestData->mDistance = distance; - WebCore::IntRect rect = test->ring(this, part); - bestData->setMouseBounds(rect); - bestData->setNodeBounds(rect); - CachedHistory* cachedHistory = history(); - switch (direction) { - case LEFT: - bestData->setLeftDirection(cachedHistory); - break; - case RIGHT: - bestData->setRightDirection(cachedHistory); - break; - case UP: - bestData->setUpDirection(cachedHistory); - break; - case DOWN: - bestData->setDownDirection(cachedHistory); - break; - default: - ASSERT(0); - } - } - } - } -} - -void CachedFrame::finishInit() -{ - CachedNode* lastCached = lastNode(); - lastCached->setLast(); - CachedFrame* child = mCachedFrames.begin(); - while (child != mCachedFrames.end()) { - child->mParent = this; - child->finishInit(); - child++; - } - CachedFrame* frameParent; - if (mFocusIndex >= 0 && (frameParent = parent())) - frameParent->setFocusIndex(indexInParent()); -} - -const CachedNode* CachedFrame::frameDown(const CachedNode* test, - const CachedNode* limit, BestData* bestData) const -{ - BestData originalData = *bestData; - do { - if (moveInFrame(&CachedFrame::frameDown, test, bestData)) - continue; - BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData) == REJECT_TEST) - continue; - if (checkVisited(test, DOWN) == false) - continue; - size_t parts = test->navableRects(); - for (size_t part = 0; part < parts; part++) { - testData.setNodeBounds(test->ring(this, part)); - if (testData.setDownDirection(history())) - continue; - int result = framePartCommon(testData, test, bestData); - if (result == REJECT_TEST) - continue; - if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger - BestData innerData = testData; - frameDown(document(), test, &innerData); - if (checkVisited(innerData.mNode, DOWN)) { - *bestData = innerData; - continue; - } - } - if (checkVisited(test, DOWN)) - *bestData = testData; - } - } while ((test = test->traverseNextNode()) != limit); - ASSERT(mRoot->mCursor == NULL || bestData->mNode != mRoot->mCursor); - // does the best contain something (or, is it contained by an area which is not the cursor?) - // if so, is the conainer/containee should have been chosen, but wasn't -- so there's a better choice - // in the doc list prior to this choice - // - return bestData->mNode; -} - -const CachedNode* CachedFrame::frameLeft(const CachedNode* test, - const CachedNode* limit, BestData* bestData) const -{ - BestData originalData = *bestData; - do { - if (moveInFrame(&CachedFrame::frameLeft, test, bestData)) - continue; - BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData) == REJECT_TEST) - continue; - if (checkVisited(test, LEFT) == false) - continue; - size_t parts = test->navableRects(); - for (size_t part = 0; part < parts; part++) { - testData.setNodeBounds(test->ring(this, part)); - if (testData.setLeftDirection(history())) - continue; - int result = framePartCommon(testData, test, bestData); - if (result == REJECT_TEST) - continue; - if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger - BestData innerData = testData; - frameLeft(document(), test, &innerData); - if (checkVisited(innerData.mNode, LEFT)) { - *bestData = innerData; - continue; - } - } - if (checkVisited(test, LEFT)) - *bestData = testData; - } - } while ((test = test->traverseNextNode()) != limit); // FIXME ??? left and up should use traversePreviousNode to choose reverse document order - ASSERT(mRoot->mCursor == NULL || bestData->mNode != mRoot->mCursor); - return bestData->mNode; -} - -int CachedFrame::frameNodeCommon(BestData& testData, const CachedNode* test, - BestData* bestData, BestData* originalData) const -{ - testData.mFrame = this; - testData.mNode = test; - test->clearCondition(); - if (test->disabled()) { - testData.mNode->setCondition(CachedNode::DISABLED); - return REJECT_TEST; - } - WebCore::IntRect bounds = test->bounds(this); - if (bounds.isEmpty()) { - testData.mNode->setCondition(CachedNode::NAVABLE); - return REJECT_TEST; - } - if (mRoot->scrolledBounds().intersects(bounds) == false) { - testData.mNode->setCondition(CachedNode::NAVABLE); - return REJECT_TEST; - } - if (mRoot->rootLayer() && !test->isInLayer() - && !mRoot->baseUncovered().intersects(bounds)) { - testData.mNode->setCondition(CachedNode::UNDER_LAYER); - return REJECT_TEST; - } -// if (isNavable(test, &testData.mNodeBounds, walk) == false) { -// testData.mNode->setCondition(CachedNode::NAVABLE); -// return REJECT_TEST; -// } -// - if (test == mRoot->mCursor) { - testData.mNode->setCondition(CachedNode::NOT_CURSOR_NODE); - return REJECT_TEST; - } -// if (test->bounds().contains(mRoot->mCursorBounds)) { -// testData.mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); -// return REJECT_TEST; -// } - void* par = mRoot->mCursor ? mRoot->mCursor->parentGroup() : NULL; - testData.mCursorChild = par ? test->parentGroup() == par : false; - if (bestData->mNode == NULL) - return TEST_IS_BEST; - if (mRoot->mCursor && testData.mNode->parentIndex() != bestData->mNode->parentIndex()) { - int cursorParentIndex = mRoot->mCursor->parentIndex(); - if (cursorParentIndex >= 0) { - if (bestData->mNode->parentIndex() == cursorParentIndex) - return REJECT_TEST; - if (testData.mNode->parentIndex() == cursorParentIndex) - return TEST_IS_BEST; - } - } - if (testData.mNode->parent() == bestData->mNode) { - testData.mNode->setCondition(CachedNode::CHILD); - return REJECT_TEST; - } - if (testData.mNode == bestData->mNode->parent()) - return TEST_IS_BEST; - int testInBest = testData.isContainer(bestData); /* -1 pick best over test, 0 no containership, 1 pick test over best */ - if (testInBest == 1) { - if (test->isArea() || bestData->mNode->isArea()) - return UNDECIDED; - bestData->mNode = NULL; // force part tests to be ignored, yet still set up remaining test data for later comparisons - return TEST_IS_BEST; - } - if (testInBest == -1) { - testData.mNode->setCondition(CachedNode::OUTSIDE_OF_BEST); - return REJECT_TEST; - } - if (originalData->mNode != NULL) { // test is best case - testInBest = testData.isContainer(originalData); - if (testInBest == -1) { /* test is inside best */ - testData.mNode->setCondition(CachedNode::OUTSIDE_OF_ORIGINAL); - return REJECT_TEST; - } - } - return UNDECIDED; -} - -int CachedFrame::framePartCommon(BestData& testData, - const CachedNode* test, BestData* bestData) const -{ - if (mRoot->mCursor - && testData.bounds().contains(mRoot->mCursorBounds) - && !test->wantsKeyEvents()) { - testData.mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); - return REJECT_TEST; - } - testData.setDistances(); - if (bestData->mNode != NULL) { - int compared = compare(testData, *bestData); - if (compared == 0 && test->isArea() == false && bestData->mNode->isArea() == false) - goto pickTest; - if (compared >= 0) - return compared; - } -pickTest: - return -1; // pick test -} - -const CachedNode* CachedFrame::frameRight(const CachedNode* test, - const CachedNode* limit, BestData* bestData) const -{ - BestData originalData = *bestData; - do { - if (moveInFrame(&CachedFrame::frameRight, test, bestData)) - continue; - BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData) == REJECT_TEST) - continue; - if (checkVisited(test, RIGHT) == false) - continue; - size_t parts = test->navableRects(); - for (size_t part = 0; part < parts; part++) { - testData.setNodeBounds(test->ring(this, part)); - if (testData.setRightDirection(history())) - continue; - int result = framePartCommon(testData, test, bestData); - if (result == REJECT_TEST) - continue; - if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger - BestData innerData = testData; - frameRight(document(), test, &innerData); - if (checkVisited(innerData.mNode, RIGHT)) { - *bestData = innerData; - continue; - } - } - if (checkVisited(test, RIGHT)) - *bestData = testData; - } - } while ((test = test->traverseNextNode()) != limit); - ASSERT(mRoot->mCursor == NULL || bestData->mNode != mRoot->mCursor); - return bestData->mNode; -} - -const CachedNode* CachedFrame::frameUp(const CachedNode* test, - const CachedNode* limit, BestData* bestData) const -{ - BestData originalData = *bestData; - do { - if (moveInFrame(&CachedFrame::frameUp, test, bestData)) - continue; - BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData) == REJECT_TEST) - continue; - if (checkVisited(test, UP) == false) - continue; - size_t parts = test->navableRects(); - for (size_t part = 0; part < parts; part++) { - testData.setNodeBounds(test->ring(this, part)); - if (testData.setUpDirection(history())) - continue; - int result = framePartCommon(testData, test, bestData); - if (result == REJECT_TEST) - continue; - if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger - BestData innerData = testData; - frameUp(document(), test, &innerData); - if (checkVisited(innerData.mNode, UP)) { - *bestData = innerData; - continue; - } - } - if (checkVisited(test, UP)) - *bestData = testData; - } - } while ((test = test->traverseNextNode()) != limit); // FIXME ??? left and up should use traversePreviousNode to choose reverse document order - ASSERT(mRoot->mCursor == NULL || bestData->mNode != mRoot->mCursor); - return bestData->mNode; -} - -CachedFrame* CachedFrame::hasFrame(const CachedNode* node) -{ - return node->isFrame() ? &mCachedFrames[node->childFrameIndex()] : NULL; -} - -void CachedFrame::hideCursor() -{ - DBG_NAV_LOGD("mCursorIndex=%d", mCursorIndex); - if (mCursorIndex < CURSOR_SET) - return; - CachedNode& cursor = mCachedNodes[mCursorIndex]; - cursor.hideCursor(this); -} - -CachedHistory* CachedFrame::history() const -{ - return mRoot->rootHistory(); -} - -void CachedFrame::init(const CachedRoot* root, int childFrameIndex, - WebCore::Frame* frame) -{ - mContents = WebCore::IntRect(0, 0, 0, 0); // fixed up for real in setData() - mLocalViewBounds = WebCore::IntRect(0, 0, 0, 0); - mViewBounds = WebCore::IntRect(0, 0, 0, 0); - mRoot = root; - mCursorIndex = CURSOR_UNINITIALIZED; // not explicitly cleared - mFocusIndex = -1; - mFrame = frame; - mParent = NULL; // set up parents after stretchy arrays are set up - mIndexInParent = childFrameIndex; -} - -#if USE(ACCELERATED_COMPOSITING) -const CachedLayer* CachedFrame::layer(const CachedNode* node) const -{ - if (!node->isInLayer()) - return 0; - CachedLayer test; - test.setCachedNodeIndex(node->index()); - return std::lower_bound(mCachedLayers.begin(), mCachedLayers.end(), test); -} -#endif - -WebCore::IntRect CachedFrame::localBounds(const CachedNode* node, - const WebCore::IntRect& rect) const -{ - DBG_NAV_LOGD("node=%p [%d] rect=(%d,%d,w=%d,h=%d)", - node, node->index(), rect.x(), rect.y(), rect.width(), rect.height()); -#if USE(ACCELERATED_COMPOSITING) - return layer(node)->localBounds(mRoot->rootLayer(), rect); -#else - return rect; -#endif -} - -int CachedFrame::minWorkingHorizontal() const -{ - return history()->minWorkingHorizontal(); -} - -int CachedFrame::minWorkingVertical() const -{ - return history()->minWorkingVertical(); -} - -int CachedFrame::maxWorkingHorizontal() const -{ - return history()->maxWorkingHorizontal(); -} - -int CachedFrame::maxWorkingVertical() const -{ - return history()->maxWorkingVertical(); -} - -const CachedNode* CachedFrame::nextTextField(const CachedNode* start, - const CachedFrame** framePtr, bool* startFound) const -{ - const CachedNode* test = mCachedNodes.begin(); - while ((test = test->traverseNextNode())) { - const CachedFrame* frame = hasFrame(test); - if (frame) { - if (!frame->validDocument()) - continue; - const CachedNode* node - = frame->nextTextField(start, framePtr, startFound); - if (node) - return node; - } else if (test->isTextInput()) { - if (test == start) - *startFound = true; - else if (*startFound) { - if (framePtr) - *framePtr = this; - return test; - } - } - } - return 0; -} - -bool CachedFrame::moveInFrame(MoveInDirection moveInDirection, - const CachedNode* test, BestData* bestData) const -{ - const CachedFrame* frame = hasFrame(test); - if (frame == NULL) - return false; // if it's not a frame, let the caller have another swing at it - const CachedNode* childDoc = frame->validDocument(); - if (childDoc == NULL) - return true; - (frame->*moveInDirection)(childDoc, NULL, bestData); - return true; -} - -const WebCore::IntRect& CachedFrame::_navBounds() const -{ - return history()->navBounds(); -} - -SkPicture* CachedFrame::picture(const CachedNode* node) const -{ -#if USE(ACCELERATED_COMPOSITING) - if (node->isInLayer()) - return layer(node)->picture(mRoot->rootLayer()); -#endif - return mRoot->mPicture; -} - -SkPicture* CachedFrame::picture(const CachedNode* node, int* xPtr, int* yPtr) const -{ -#if USE(ACCELERATED_COMPOSITING) - if (node->isInLayer()) { - const CachedLayer* cachedLayer = layer(node); - const LayerAndroid* rootLayer = mRoot->rootLayer(); - cachedLayer->toLocal(rootLayer, xPtr, yPtr); - return cachedLayer->picture(rootLayer); - } -#endif - return mRoot->mPicture; -} - -void CachedFrame::resetClippedOut() -{ - for (CachedNode* test = mCachedNodes.begin(); test != mCachedNodes.end(); test++) - { - if (test->clippedOut()) { - test->setDisabled(false); - test->setClippedOut(false); - } - } - for (CachedFrame* frame = mCachedFrames.begin(); frame != mCachedFrames.end(); - frame++) { - frame->resetClippedOut(); - } -} - -void CachedFrame::resetLayers() -{ -#if USE(ACCELERATED_COMPOSITING) - for (CachedFrame* frame = mCachedFrames.begin(); frame != mCachedFrames.end(); - frame++) { - frame->resetLayers(); - } -#endif -} - -bool CachedFrame::sameFrame(const CachedFrame* test) const -{ - ASSERT(test); - if (mIndexInParent != test->mIndexInParent) - return false; - if (mIndexInParent == -1) // index within parent's array of children, or -1 if root - return true; - return mParent->sameFrame(test->mParent); -} - -void CachedFrame::setData() -{ - if (this != mRoot) { - mViewBounds = mLocalViewBounds; - mViewBounds.intersect(mRoot->mViewBounds); - } - int x, y; - if (parent() == NULL) - x = y = 0; - else { - x = mLocalViewBounds.x(); - y = mLocalViewBounds.y(); - } - mContents.setX(x); - mContents.setY(y); - CachedFrame* child = mCachedFrames.begin(); - while (child != mCachedFrames.end()) { - child->setData(); - child++; - } -} - -bool CachedFrame::setCursor(WebCore::Frame* frame, WebCore::Node* node, - int x, int y) -{ - if (NULL == node) { - const_cast<CachedRoot*>(mRoot)->setCursor(NULL, NULL); - return true; - } - if (mFrame != frame) { - for (CachedFrame* testF = mCachedFrames.begin(); testF != mCachedFrames.end(); - testF++) { - if (testF->setCursor(frame, node, x, y)) - return true; - } - DBG_NAV_LOGD("no frame frame=%p node=%p", frame, node); - return false; - } - bool first = true; - CachedNode const * const end = mCachedNodes.end(); - do { - for (CachedNode* test = mCachedNodes.begin(); test != end; test++) { - if (test->nodePointer() != node && first) - continue; - size_t partMax = test->navableRects(); - for (size_t part = 0; part < partMax; part++) { - WebCore::IntRect testBounds = test->ring(this, part); - if (testBounds.contains(x, y) == false) - continue; - if (test->isCursor()) { - DBG_NAV_LOGD("already set? test=%d frame=%p node=%p x=%d y=%d", - test->index(), frame, node, x, y); - return false; - } - const_cast<CachedRoot*>(mRoot)->setCursor(this, test); - return true; - } - } - DBG_NAV_LOGD("moved? frame=%p node=%p x=%d y=%d", frame, node, x, y); - } while ((first ^= true) == false); -failed: - DBG_NAV_LOGD("no match frame=%p node=%p", frame, node); - return false; -} - -const CachedNode* CachedFrame::validDocument() const -{ - const CachedNode* doc = document(); - return doc != NULL && mViewBounds.isEmpty() == false ? doc : NULL; -} - -bool CachedFrame::BestData::canBeReachedByAnotherDirection() -{ - if (mMajorButt > -MIN_OVERLAP) - return false; - mMajorButt = -mMajorButt; - return mNavOutside; -} - -int CachedFrame::BestData::isContainer(CachedFrame::BestData* other) -{ - int _x = x(); - int otherRight = other->right(); - if (_x >= otherRight) - return 0; // does not intersect - int _y = y(); - int otherBottom = other->bottom(); - if (_y >= otherBottom) - return 0; // does not intersect - int _right = right(); - int otherX = other->x(); - if (otherX >= _right) - return 0; // does not intersect - int _bottom = bottom(); - int otherY = other->y(); - if (otherY >= _bottom) - return 0; // does not intersect - int intoX = otherX - _x; - int intoY = otherY - _y; - int intoRight = otherRight - _right; - int intoBottom = otherBottom - _bottom; - bool contains = intoX >= 0 && intoY >= 0 && intoRight <= 0 && intoBottom <= 0; - if (contains && mNode->partRectsContains(other->mNode)) { -// if (mIsArea == false && hasMouseOver()) -// other->mMouseOver = mNode; - return mNode->isArea() ? 1 : -1; - } - bool containedBy = intoX <= 0 && intoY <= 0 && intoRight >= 0 && intoBottom >= 0; - if (containedBy && other->mNode->partRectsContains(mNode)) { -// if (other->mIsArea == false && other->hasMouseOver()) -// mMouseOver = other->mNode; - return other->mNode->isArea() ? -1 : 1; - } - return 0; -} - -// distance scale factor factor as a 16.16 scalar -SkFixed CachedFrame::BestData::Overlap(int span, int left, int right) -{ - unsigned result; - if (left > 0 && left < span && right > span) - result = (unsigned) left; - else if (right > 0 && right < span && left > span) - result = (unsigned) right; - else if (left > 0 && right > 0) - return SK_Fixed1; - else - return 0; - result = (result << 16) / (unsigned) span; // linear proportion, always less than fixed 1 - return (SkFixed) result; -// !!! experiment with weight -- enable if overlaps are preferred too much -// or reverse weighting if overlaps are preferred to little -// return (SkFixed) (result * result >> 16); // but fall off with square -} - -void CachedFrame::BestData::setDistances() -{ - mDistance = abs(mMajorDelta); - int sideDistance = mWorkingDelta; - if (mWorkingOverlap < SK_Fixed1) { - if (mPreferred > 0) - sideDistance = mWorkingDelta2; - } else if (sideDistance >= 0 && mWorkingDelta2 >=- 0) - sideDistance = 0; - else { - ASSERT(sideDistance <= 0 && mWorkingDelta2 <= 0); - if (sideDistance < mWorkingDelta2) - sideDistance = mWorkingDelta2; - } - // if overlap, smaller abs mWorkingDelta is better, smaller abs majorDelta is better - // if not overlap, positive mWorkingDelta is better - mSideDistance = sideDistance; -} - -bool CachedFrame::BestData::setDownDirection(const CachedHistory* history) -{ - const WebCore::IntRect& navBounds = history->navBounds(); - mMajorButt = mNodeBounds.y() - navBounds.maxY(); - int testX = mNodeBounds.x(); - int testRight = mNodeBounds.maxX(); - setNavOverlap(navBounds.width(), navBounds.maxX() - testX, - testRight - navBounds.x()); - if (canBeReachedByAnotherDirection()) { - mNode->setCondition(CachedNode::BEST_DIRECTION); - return REJECT_TEST; - } - int inNavTop = mNodeBounds.y() - navBounds.y(); - mMajorDelta2 = inNavTop; - mMajorDelta = mMajorDelta2 + ((mNodeBounds.height() - - navBounds.height()) >> 1); - if (mMajorDelta2 <= 1 && mMajorDelta <= 1) { - mNode->setCondition(CachedNode::CENTER_FURTHER); // never move up or sideways - return REJECT_TEST; - } - int inNavBottom = navBounds.maxY() - mNodeBounds.maxY(); - setNavInclusion(testRight - navBounds.maxX(), navBounds.x() - testX); - bool subsumes = navBounds.height() > 0 && inOrSubsumesNav(); - if (inNavTop <= 0 && inNavBottom <= 0 && subsumes && !mNode->wantsKeyEvents()) { - mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); - return REJECT_TEST; - } - int maxV = history->maxWorkingVertical(); - int minV = history->minWorkingVertical(); - setWorkingOverlap(testRight - testX, maxV - testX, testRight - minV); - setWorkingInclusion(testRight - maxV, minV - testX); - if (mWorkingOverlap == 0 && mNavOverlap == 0 && inNavBottom >= 0) { - mNode->setCondition(CachedNode::OVERLAP_OR_EDGE_FURTHER); - return REJECT_TEST; - } - mInNav = history->directionChange() && inNavTop >= 0 && - inNavBottom > 0 && subsumes; - return false; -} - -bool CachedFrame::BestData::setLeftDirection(const CachedHistory* history) -{ - const WebCore::IntRect& navBounds = history->navBounds(); - mMajorButt = navBounds.x() - mNodeBounds.maxX(); - int testY = mNodeBounds.y(); - int testBottom = mNodeBounds.maxY(); - setNavOverlap(navBounds.height(), navBounds.maxY() - testY, - testBottom - navBounds.y()); - if (canBeReachedByAnotherDirection()) { - mNode->setCondition(CachedNode::BEST_DIRECTION); - return REJECT_TEST; - } - int inNavRight = navBounds.maxX() - mNodeBounds.maxX(); - mMajorDelta2 = inNavRight; - mMajorDelta = mMajorDelta2 - ((navBounds.width() - - mNodeBounds.width()) >> 1); - if (mMajorDelta2 <= 1 && mMajorDelta <= 1) { - mNode->setCondition(CachedNode::CENTER_FURTHER); // never move right or sideways - return REJECT_TEST; - } - int inNavLeft = mNodeBounds.x() - navBounds.x(); - setNavInclusion(navBounds.y() - testY, testBottom - navBounds.maxY()); - bool subsumes = navBounds.width() > 0 && inOrSubsumesNav(); - if (inNavLeft <= 0 && inNavRight <= 0 && subsumes && !mNode->wantsKeyEvents()) { - mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); - return REJECT_TEST; - } - int maxH = history->maxWorkingHorizontal(); - int minH = history->minWorkingHorizontal(); - setWorkingOverlap(testBottom - testY, maxH - testY, testBottom - minH); - setWorkingInclusion(minH - testY, testBottom - maxH); - if (mWorkingOverlap == 0 && mNavOverlap == 0 && inNavLeft >= 0) { - mNode->setCondition(CachedNode::OVERLAP_OR_EDGE_FURTHER); - return REJECT_TEST; - } - mInNav = history->directionChange() && inNavLeft >= 0 && - inNavRight > 0 && subsumes; /* both L/R in or out */ - return false; -} - -bool CachedFrame::BestData::setRightDirection(const CachedHistory* history) -{ - const WebCore::IntRect& navBounds = history->navBounds(); - mMajorButt = mNodeBounds.x() - navBounds.maxX(); - int testY = mNodeBounds.y(); - int testBottom = mNodeBounds.maxY(); - setNavOverlap(navBounds.height(), navBounds.maxY() - testY, - testBottom - navBounds.y()); - if (canBeReachedByAnotherDirection()) { - mNode->setCondition(CachedNode::BEST_DIRECTION); - return REJECT_TEST; - } - int inNavLeft = mNodeBounds.x() - navBounds.x(); - mMajorDelta2 = inNavLeft; - mMajorDelta = mMajorDelta2 + ((mNodeBounds.width() - - navBounds.width()) >> 1); - if (mMajorDelta2 <= 1 && mMajorDelta <= 1) { - mNode->setCondition(CachedNode::CENTER_FURTHER); // never move left or sideways - return REJECT_TEST; - } - int inNavRight = navBounds.maxX() - mNodeBounds.maxX(); - setNavInclusion(testBottom - navBounds.maxY(), navBounds.y() - testY); - bool subsumes = navBounds.width() > 0 && inOrSubsumesNav(); - if (inNavLeft <= 0 && inNavRight <= 0 && subsumes && !mNode->wantsKeyEvents()) { - mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); - return REJECT_TEST; - } - int maxH = history->maxWorkingHorizontal(); - int minH = history->minWorkingHorizontal(); - setWorkingOverlap(testBottom - testY, testBottom - minH, maxH - testY); - setWorkingInclusion(testBottom - maxH, minH - testY); - if (mWorkingOverlap == 0 && mNavOverlap == 0 && inNavRight >= 0) { - mNode->setCondition(CachedNode::OVERLAP_OR_EDGE_FURTHER); - return REJECT_TEST; - } - mInNav = history->directionChange() && inNavLeft >= 0 && - inNavRight > 0 && subsumes; /* both L/R in or out */ - return false; -} - -bool CachedFrame::BestData::setUpDirection(const CachedHistory* history) -{ - const WebCore::IntRect& navBounds = history->navBounds(); - mMajorButt = navBounds.y() - mNodeBounds.maxY(); - int testX = mNodeBounds.x(); - int testRight = mNodeBounds.maxX(); - setNavOverlap(navBounds.width(), navBounds.maxX() - testX, - testRight - navBounds.x()); - if (canBeReachedByAnotherDirection()) { - mNode->setCondition(CachedNode::BEST_DIRECTION); - return REJECT_TEST; - } - int inNavBottom = navBounds.maxY() - mNodeBounds.maxY(); - mMajorDelta2 = inNavBottom; - mMajorDelta = mMajorDelta2 - ((navBounds.height() - - mNodeBounds.height()) >> 1); - if (mMajorDelta2 <= 1 && mMajorDelta <= 1) { - mNode->setCondition(CachedNode::CENTER_FURTHER); // never move down or sideways - return REJECT_TEST; - } - int inNavTop = mNodeBounds.y() - navBounds.y(); - setNavInclusion(navBounds.x() - testX, testRight - navBounds.maxX()); - bool subsumes = navBounds.height() > 0 && inOrSubsumesNav(); - if (inNavTop <= 0 && inNavBottom <= 0 && subsumes && !mNode->wantsKeyEvents()) { - mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); - return REJECT_TEST; - } - int maxV = history->maxWorkingVertical(); - int minV = history->minWorkingVertical(); - setWorkingOverlap(testRight - testX, testRight - minV, maxV - testX); - setWorkingInclusion(minV - testX, testRight - maxV); - if (mWorkingOverlap == 0 && mNavOverlap == 0 && inNavTop >= 0) { - mNode->setCondition(CachedNode::OVERLAP_OR_EDGE_FURTHER); - return REJECT_TEST; - } - mInNav = history->directionChange() && inNavTop >= 0 && - inNavBottom > 0 && subsumes; /* both L/R in or out */ - return false; -} - -void CachedFrame::BestData::setNavInclusion(int left, int right) -{ - // if left and right <= 0, test node is completely in umbra of cursor - // prefer leftmost center - // if left and right > 0, test node subsumes cursor - mNavDelta = left; - mNavDelta2 = right; -} - -void CachedFrame::BestData::setNavOverlap(int span, int left, int right) -{ - // if left or right < 0, test node is not in umbra of cursor - mNavOutside = left < MIN_OVERLAP || right < MIN_OVERLAP; - mNavOverlap = Overlap(span, left, right); // prefer smallest negative left -} - -void CachedFrame::BestData::setWorkingInclusion(int left, int right) -{ - mWorkingDelta = left; - mWorkingDelta2 = right; -} - -// distance scale factor factor as a 16.16 scalar -void CachedFrame::BestData::setWorkingOverlap(int span, int left, int right) -{ - // if left or right < 0, test node is not in umbra of cursor - mWorkingOutside = left < MIN_OVERLAP || right < MIN_OVERLAP; - mWorkingOverlap = Overlap(span, left, right); - mPreferred = left <= 0 ? 0 : left; -} - -#if DUMP_NAV_CACHE - -#define DEBUG_PRINT_RECT(prefix, debugName, field) \ - { const WebCore::IntRect& r = b->field; \ - DUMP_NAV_LOGD("%s DebugTestRect TEST%s_" #debugName "={%d, %d, %d, %d}; //" #field "\n", \ - prefix, mFrameName, r.x(), r.y(), r.width(), r.height()); } - -CachedFrame* CachedFrame::Debug::base() const { - CachedFrame* nav = (CachedFrame*) ((char*) this - OFFSETOF(CachedFrame, mDebug)); - return nav; -} - -void CachedFrame::Debug::print() const -{ - CachedFrame* b = base(); - DEBUG_PRINT_RECT("//", CONTENTS, mContents); - DEBUG_PRINT_RECT("", BOUNDS, mLocalViewBounds); - DEBUG_PRINT_RECT("//", VIEW, mViewBounds); - - DUMP_NAV_LOGD("// CachedNode mCachedNodes={ // count=%d\n", b->mCachedNodes.size()); - for (CachedNode* node = b->mCachedNodes.begin(); - node != b->mCachedNodes.end(); node++) { - node->mDebug.print(); - const CachedInput* input = b->textInput(node); - if (input) - input->mDebug.print(); - DUMP_NAV_LOGD("\n"); - } - DUMP_NAV_LOGD("// }; // end of nodes\n"); -#if USE(ACCELERATED_COMPOSITING) - DUMP_NAV_LOGD("// CachedLayer mCachedLayers={ // count=%d\n", b->mCachedLayers.size()); - for (CachedLayer* layer = b->mCachedLayers.begin(); - layer != b->mCachedLayers.end(); layer++) { - layer->mDebug.print(); - } - DUMP_NAV_LOGD("// }; // end of layers\n"); -#endif // USE(ACCELERATED_COMPOSITING) - DUMP_NAV_LOGD("// }; // end of colors\n"); - DUMP_NAV_LOGD("// CachedFrame mCachedFrames={ // count=%d\n", b->mCachedFrames.size()); - for (CachedFrame* child = b->mCachedFrames.begin(); - child != b->mCachedFrames.end(); child++) - { - child->mDebug.print(); - } - DUMP_NAV_LOGD("// }; // end of child frames\n"); - DUMP_NAV_LOGD("// void* mFrame=(void*) %p;\n", b->mFrame); - DUMP_NAV_LOGD("// CachedFrame* mParent=%p;\n", b->mParent); - DUMP_NAV_LOGD("// int mIndexInParent=%d;\n", b->mIndexInParent); - DUMP_NAV_LOGD("// const CachedRoot* mRoot=%p;\n", b->mRoot); - DUMP_NAV_LOGD("// int mCursorIndex=%d;\n", b->mCursorIndex); - DUMP_NAV_LOGD("// int mFocusIndex=%d;\n", b->mFocusIndex); -} - -bool CachedFrame::Debug::validate(const CachedNode* node) const -{ - const CachedFrame* b = base(); - if (b->mCachedNodes.size() == 0) - return false; - if (node >= b->mCachedNodes.begin() && node < b->mCachedNodes.end()) - return true; - for (const CachedFrame* child = b->mCachedFrames.begin(); - child != b->mCachedFrames.end(); child++) - if (child->mDebug.validate(node)) - return true; - return false; -} - -#undef DEBUG_PRINT_RECT - -#endif - -} diff --git a/Source/WebKit/android/nav/CachedFrame.h b/Source/WebKit/android/nav/CachedFrame.h deleted file mode 100644 index 40efafe..0000000 --- a/Source/WebKit/android/nav/CachedFrame.h +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright 2007, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// FIXME: A file of this name already exists in WebCore/history. -// This file should be renamed. -#ifndef AndroidCachedFrame_h -#define AndroidCachedFrame_h - -#include "CachedInput.h" -#include "CachedLayer.h" -#include "CachedNode.h" -#include "IntRect.h" -#include "SkFixed.h" -#include "wtf/Vector.h" - -class SkPicture; - -namespace WebCore { - class Frame; - class Node; -} - -namespace android { - -class CachedHistory; -class CachedRoot; - - // first node referenced by cache is always document -class CachedFrame { -public: - enum Direction { - UNINITIALIZED = -1, - LEFT, - RIGHT, - UP, - DOWN, - DIRECTION_COUNT, - DIRECTION_MASK = DIRECTION_COUNT - 1, - UP_DOWN = UP & DOWN, // mask and result - RIGHT_DOWN = RIGHT & DOWN, // mask and result - }; - enum Compare { - UNDECIDED = -1, - TEST_IS_BEST, - REJECT_TEST - }; - enum CursorInit { - CURSOR_UNINITIALIZED = -2, - CURSOR_CLEARED = -1, - CURSOR_SET = 0 - }; - CachedFrame() {} - void add(CachedInput& input) { mCachedTextInputs.append(input); } -#if USE(ACCELERATED_COMPOSITING) - void add(CachedLayer& layer) { mCachedLayers.append(layer); } -#endif - void add(CachedNode& node) { mCachedNodes.append(node); } - void addFrame(CachedFrame& child) { mCachedFrames.append(child); } - WebCore::IntRect adjustBounds(const CachedNode* , - const WebCore::IntRect& ) const; - bool checkRings(const CachedNode* node, - const WebCore::IntRect& testBounds) const; - bool checkVisited(const CachedNode* , CachedFrame::Direction ) const; - size_t childCount() { return mCachedFrames.size(); } - void clearCursor(); - const CachedNode* currentCursor() const { return currentCursor(NULL); } - const CachedNode* currentCursor(const CachedFrame** ) const; - const CachedNode* currentFocus() const { return currentFocus(NULL); } - const CachedNode* currentFocus(const CachedFrame** ) const; - bool directionChange() const; - const CachedNode* document() const { return mCachedNodes.begin(); } - bool empty() const { return mCachedNodes.size() < 2; } // must have 1 past doc - const CachedNode* findBestAt(const WebCore::IntRect& , int* best, - bool* inside, const CachedNode** , const CachedFrame** directFrame, - const CachedFrame** resultFrame, int* x, - int* y, bool checkForHidden) const; - const CachedFrame* findBestFrameAt(int x, int y) const; - const CachedNode* findBestHitAt(const WebCore::IntRect& , - const CachedFrame** , int* x, int* y) const; - void finishInit(); - CachedFrame* firstChild() { return mCachedFrames.begin(); } - const CachedFrame* firstChild() const { return mCachedFrames.begin(); } - void* framePointer() const { return mFrame; } - CachedNode* getIndex(int index) { return index >= 0 ? - &mCachedNodes[index] : NULL; } - const CachedFrame* hasFrame(const CachedNode* node) const { - return const_cast<CachedFrame*>(this)->hasFrame(node); - } - CachedFrame* hasFrame(const CachedNode* node); - void hideCursor(); - int indexInParent() const { return mIndexInParent; } - void init(const CachedRoot* root, int index, WebCore::Frame* frame); - const CachedFrame* lastChild() const { return &mCachedFrames.last(); } -#if USE(ACCELERATED_COMPOSITING) - const CachedLayer* lastLayer() const { return &mCachedLayers.last(); } -#endif - CachedNode* lastNode() { return &mCachedNodes.last(); } - CachedFrame* lastChild() { return &mCachedFrames.last(); } -#if USE(ACCELERATED_COMPOSITING) - const CachedLayer* layer(const CachedNode* ) const; - size_t layerCount() const { return mCachedLayers.size(); } -#endif - WebCore::IntRect localBounds(const CachedNode* , - const WebCore::IntRect& ) const; - const CachedFrame* parent() const { return mParent; } - CachedFrame* parent() { return mParent; } - SkPicture* picture(const CachedNode* ) const; - SkPicture* picture(const CachedNode* , int* xPtr, int* yPtr) const; - void resetLayers(); - bool sameFrame(const CachedFrame* ) const; - void removeLast() { mCachedNodes.removeLast(); } - void resetClippedOut(); - void setContentsSize(int width, int height) { mContents.setWidth(width); - mContents.setHeight(height); } - bool setCursor(WebCore::Frame* , WebCore::Node* , int x, int y); - void setCursorIndex(int index) { mCursorIndex = index; } - void setData(); - bool setFocus(WebCore::Frame* , WebCore::Node* , int x, int y); - void setFocusIndex(int index) { mFocusIndex = index; } - void setIndexInParent(int index) { mIndexInParent = index; } - void setLocalViewBounds(const WebCore::IntRect& bounds) { mLocalViewBounds = bounds; } - int size() { return mCachedNodes.size(); } - const CachedInput* textInput(const CachedNode* node) const { - return node->isTextInput() ? &mCachedTextInputs[node->textInputIndex()] - : 0; - } - const CachedNode* validDocument() const; -protected: - const CachedNode* nextTextField(const CachedNode* start, - const CachedFrame** framePtr, bool* found) const; - struct BestData { - int mDistance; - int mSideDistance; - int mMajorDelta; // difference of center of object - // used only when leading and trailing edges contain another set of edges - int mMajorDelta2; // difference of leading edge (only used when center is same) - int mMajorButt; // checks for next cell butting up against or close to previous one - int mWorkingDelta; - int mWorkingDelta2; - int mNavDelta; - int mNavDelta2; - const CachedFrame* mFrame; - const CachedNode* mNode; - SkFixed mWorkingOverlap; // this and below are fuzzy answers instead of bools - SkFixed mNavOverlap; - SkFixed mPreferred; - bool mCursorChild; - bool mInNav; - bool mNavOutside; - bool mWorkingOutside; - int bottom() const { return bounds().maxY(); } - const WebCore::IntRect& bounds() const { return mNodeBounds; } - bool canBeReachedByAnotherDirection(); - int height() const { return bounds().height(); } - bool inOrSubsumesNav() const { return (mNavDelta ^ mNavDelta2) >= 0; } - bool inOrSubsumesWorking() const { return (mWorkingDelta ^ mWorkingDelta2) >= 0; } - int isContainer(BestData* ); - const WebCore::IntRect& mouseBounds() const { return mMouseBounds; } - static SkFixed Overlap(int span, int left, int right); - void reset() { mNode = NULL; } - int right() const { return bounds().maxX(); } - void setMouseBounds(const WebCore::IntRect& b) { mMouseBounds = b; } - void setNodeBounds(const WebCore::IntRect& b) { mNodeBounds = b; } - void setDistances(); - bool setDownDirection(const CachedHistory* ); - bool setLeftDirection(const CachedHistory* ); - bool setRightDirection(const CachedHistory* ); - bool setUpDirection(const CachedHistory* ); - void setNavInclusion(int left, int right); - void setNavOverlap(int span, int left, int right); - void setWorkingInclusion(int left, int right); - void setWorkingOverlap(int span, int left, int right); - int width() const { return bounds().width(); } - int x() const { return bounds().x(); } - int y() const { return bounds().y(); } -private: // since computing these is complicated, protect them so that the - // are only written by appropriate helpers - WebCore::IntRect mMouseBounds; - WebCore::IntRect mNodeBounds; - }; - typedef const CachedNode* (CachedFrame::*MoveInDirection)( - const CachedNode* test, const CachedNode* limit, BestData* ) const; - void adjustToTextColumn(int* delta) const; - static bool CheckBetween(Direction , const WebCore::IntRect& bestRect, - const WebCore::IntRect& prior, WebCore::IntRect* result); - bool checkBetween(BestData* , Direction ); - int compare(BestData& testData, const BestData& bestData) const; - void findClosest(BestData* , Direction original, Direction test, - WebCore::IntRect* clip) const; - int frameNodeCommon(BestData& testData, const CachedNode* test, - BestData* bestData, BestData* originalData) const; - int framePartCommon(BestData& testData, const CachedNode* test, - BestData* ) const; - const CachedNode* frameDown(const CachedNode* test, const CachedNode* limit, - BestData* ) const; - const CachedNode* frameLeft(const CachedNode* test, const CachedNode* limit, - BestData* ) const; - const CachedNode* frameRight(const CachedNode* test, const CachedNode* limit, - BestData* ) const; - const CachedNode* frameUp(const CachedNode* test, const CachedNode* limit, - BestData* ) const; - int minWorkingHorizontal() const; - int minWorkingVertical() const; - int maxWorkingHorizontal() const; - int maxWorkingVertical() const; - bool moveInFrame(MoveInDirection , const CachedNode* test, BestData* ) const; - const WebCore::IntRect& _navBounds() const; - WebCore::IntRect mContents; - WebCore::IntRect mLocalViewBounds; - WebCore::IntRect mViewBounds; - WTF::Vector<CachedNode> mCachedNodes; - WTF::Vector<CachedFrame> mCachedFrames; - WTF::Vector<CachedInput> mCachedTextInputs; -#if USE(ACCELERATED_COMPOSITING) - WTF::Vector<CachedLayer> mCachedLayers; -#endif - void* mFrame; // WebCore::Frame*, used only to compare pointers - CachedFrame* mParent; - int mCursorIndex; - int mFocusIndex; - int mIndexInParent; // index within parent's array of children, or -1 if root - const CachedRoot* mRoot; -private: - CachedHistory* history() const; -#ifdef BROWSER_DEBUG -public: - CachedNode* find(WebCore::Node* ); // !!! probably debugging only - int mDebugIndex; - int mDebugLoopbackOffset; -#endif -#if !defined NDEBUG || DUMP_NAV_CACHE -public: - class Debug { -public: - Debug() { -#if DUMP_NAV_CACHE - mFrameName[0] = '\0'; -#endif -#if !defined NDEBUG - mInUse = true; -#endif - } -#if !defined NDEBUG - ~Debug() { mInUse = false; } - bool mInUse; -#endif -#if DUMP_NAV_CACHE - CachedFrame* base() const; - void print() const; - bool validate(const CachedNode* ) const; - char mFrameName[256]; -#endif - } mDebug; -#endif -}; - -} - -#endif // AndroidCachedFrame_h diff --git a/Source/WebKit/android/nav/CachedHistory.cpp b/Source/WebKit/android/nav/CachedHistory.cpp deleted file mode 100644 index d132cc3..0000000 --- a/Source/WebKit/android/nav/CachedHistory.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2007, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "CachedPrefix.h" -#include "CachedFrame.h" -#include "CachedNode.h" -#if DUMP_NAV_CACHE -#include "CachedRoot.h" -#endif - -#include "CachedHistory.h" - -namespace android { - -CachedHistory::CachedHistory() { - memset(this, 0, sizeof(CachedHistory)); // this assume the class has no virtuals - mLastMove = CachedFrame::UNINITIALIZED; - mPriorMove = CachedFrame::UNINITIALIZED; -} - - -void CachedHistory::addToVisited(const CachedNode* node, CachedFrame::Direction direction) -{ - memmove(&mVisited[1], &mVisited[0], sizeof(mVisited) - sizeof(mVisited[0])); - mVisited[0].mNode = node; - mVisited[0].mDirection = direction; -} - -bool CachedHistory::checkVisited(const CachedNode* node, CachedFrame::Direction direction) const -{ - // if the direction is unchanged and we've already visited this node, don't visit it again - int index = 0; - while (index < NAVIGATION_VISIT_DEPTH - 1) { - if (direction != mVisited[index].mDirection) - break; - index++; // compare with last direction, previous to last node (where the arrow took us from) - if (node == mVisited[index].mNode) - return false; - } - return true; -} - -void CachedHistory::pinMaxMin(const WebCore::IntRect& viewBounds) -{ - if (mMinWorkingHorizontal < viewBounds.y() || mMinWorkingHorizontal >= viewBounds.maxY()) - mMinWorkingHorizontal = viewBounds.y(); - if (mMaxWorkingHorizontal > viewBounds.maxY() || mMaxWorkingHorizontal <= viewBounds.y()) - mMaxWorkingHorizontal = viewBounds.maxY(); - if (mMinWorkingVertical < viewBounds.x() || mMinWorkingVertical >= viewBounds.maxX()) - mMinWorkingVertical = viewBounds.x(); - if (mMaxWorkingVertical > viewBounds.maxX() || mMaxWorkingVertical <= viewBounds.x()) - mMaxWorkingVertical = viewBounds.maxX(); -} - -void CachedHistory::reset() -{ - memset(mVisited, 0, sizeof(mVisited)); -// mLastScroll = 0; - mPriorBounds = WebCore::IntRect(0, 0, 0, 0); - mDirectionChange = false; - mDidFirstLayout = false; - mPriorMove = mLastMove = CachedFrame::UNINITIALIZED; - mMinWorkingHorizontal = mMinWorkingVertical = INT_MIN; - mMaxWorkingHorizontal = mMaxWorkingVertical = INT_MAX; -} - -void CachedHistory::setWorking(CachedFrame::Direction newMove, - const CachedFrame* cursorFrame, const CachedNode* cursor, - const WebCore::IntRect& viewBounds) -{ - CachedFrame::Direction lastAxis = (CachedFrame::Direction) (mLastMove & ~CachedFrame::RIGHT_DOWN); // up, left or uninitialized - CachedFrame::Direction newAxis = (CachedFrame::Direction) (newMove & ~CachedFrame::RIGHT_DOWN); - bool change = newAxis != lastAxis; - mDirectionChange = change && mLastMove != CachedFrame::UNINITIALIZED; - if (cursor != NULL || mLastMove != CachedFrame::UNINITIALIZED) { - mPriorMove = mLastMove; - mLastMove = newMove; - } - const WebCore::IntRect* navBounds = &mNavBounds; - if (cursor != NULL) { - WebCore::IntRect cursorBounds = cursor->bounds(cursorFrame); - if (cursorBounds.isEmpty() == false) - mNavBounds = cursorBounds; - } - if (change) { // uninitialized or change in direction - if (lastAxis != CachedFrame::LEFT && navBounds->height() > 0) { - mMinWorkingHorizontal = navBounds->y(); - mMaxWorkingHorizontal = navBounds->maxY(); - } - if (lastAxis != CachedFrame::UP && navBounds->width() > 0) { - mMinWorkingVertical = navBounds->x(); - mMaxWorkingVertical = navBounds->maxX(); - } - } - pinMaxMin(viewBounds); -} - -#if DUMP_NAV_CACHE - -#define DEBUG_PRINT_BOOL(field) \ - DUMP_NAV_LOGD("// bool " #field "=%s;\n", b->field ? "true" : "false") - -#define DEBUG_PRINT_RECT(field) \ - { const WebCore::IntRect& r = b->field; \ - DUMP_NAV_LOGD("// IntRect " #field "={%d, %d, %d, %d};\n", \ - r.x(), r.y(), r.width(), r.height()); } - -CachedHistory* CachedHistory::Debug::base() const { - CachedHistory* nav = (CachedHistory*) ((char*) this - OFFSETOF(CachedHistory, mDebug)); - return nav; -} - -const char* CachedHistory::Debug::direction(CachedFrame::Direction d) const -{ - switch (d) { - case CachedFrame::LEFT: return "LEFT"; break; - case CachedFrame::RIGHT: return "RIGHT"; break; - case CachedFrame::UP: return "UP"; break; - case CachedFrame::DOWN: return "DOWN"; break; - default: return "UNINITIALIZED"; - } -} - -void CachedHistory::Debug::print(CachedRoot* root) const -{ - CachedHistory* b = base(); - DUMP_NAV_LOGD("// Visited mVisited[]={\n"); - for (size_t i = 0; i < NAVIGATION_VISIT_DEPTH; i++) { - const Visited& visit = b->mVisited[i]; - const CachedNode* node = visit.mNode; - int index = root != NULL && root->CachedFrame::mDebug.validate(node) ? - node->index() : -1; - DUMP_NAV_LOGD(" // { 0x%p (%d), %s },\n", node, index, direction(visit.mDirection)); - } - DUMP_NAV_LOGD("// };\n"); -// DUMP_NAV_LOGD("// int mLastScroll=%d;\n", b->mLastScroll); - DEBUG_PRINT_RECT(mMouseBounds); - DEBUG_PRINT_RECT(mNavBounds); - DEBUG_PRINT_RECT(mPriorBounds); - DEBUG_PRINT_BOOL(mDirectionChange); - DEBUG_PRINT_BOOL(mDidFirstLayout); - DUMP_NAV_LOGD("// CachedFrame::Direction mLastMove=%s, mPriorMove=%s;\n", - direction(b->mLastMove), direction(b->mPriorMove)); - int max = b->mMaxWorkingHorizontal; - DUMP_NAV_LOGD("static int TEST_MAX_H = %d;\n", max); - int min = b->mMinWorkingHorizontal; - if (min == INT_MIN) - min++; - DUMP_NAV_LOGD("static int TEST_MIN_H = %d;\n", min); - max = b->mMaxWorkingVertical; - DUMP_NAV_LOGD("static int TEST_MAX_V = %d;\n", max); - min = b->mMinWorkingVertical; - if (min == INT_MIN) - min++; - DUMP_NAV_LOGD("static int TEST_MIN_V = %d;\n", min); - DUMP_NAV_LOGD("\n"); -} - -#endif - -} diff --git a/Source/WebKit/android/nav/CachedHistory.h b/Source/WebKit/android/nav/CachedHistory.h deleted file mode 100644 index 96975ca..0000000 --- a/Source/WebKit/android/nav/CachedHistory.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2007, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CachedHistory_h -#define CachedHistory_h - -#include "CachedFrame.h" - -#define NAVIGATION_VISIT_DEPTH 8 // the number of nodes last visited -- used to detect ping-ponging (number should be tuned) - -namespace android { - -class CachedRoot; - -// CachedHistory is maintained even if DOM is rebuilt by running script. -// It uses blind pointers for comparison in the previously visited nodes. -class CachedHistory { -public: - CachedHistory(); - void addToVisited(const CachedNode* , CachedFrame::Direction ); - bool checkVisited(const CachedNode* , CachedFrame::Direction ) const; - bool didFirstLayout() const { return mDidFirstLayout; } - bool directionChange() const { return mDirectionChange; } - int minWorkingHorizontal() const { return mMinWorkingHorizontal; } - int minWorkingVertical() const { return mMinWorkingVertical; } - int maxWorkingHorizontal() const { return mMaxWorkingHorizontal; } - int maxWorkingVertical() const { return mMaxWorkingVertical; } - const WebCore::IntRect& navBounds() const { return mNavBounds; } - const WebCore::IntRect& priorBounds() const { return mPriorBounds; } - void setDidFirstLayout(bool did) { mDidFirstLayout = did; } - void setMouseBounds(const WebCore::IntRect& loc) { mMouseBounds = loc; } - void setNavBounds(const WebCore::IntRect& loc) { mNavBounds = loc; } - void setWorking(CachedFrame::Direction , const CachedFrame* , - const CachedNode* , const WebCore::IntRect& viewBounds); - void reset(); -private: - void pinMaxMin(const WebCore::IntRect& viewBounds); - struct Visited { - const CachedNode* mNode; - CachedFrame::Direction mDirection; - } mVisited[NAVIGATION_VISIT_DEPTH]; - WebCore::IntRect mMouseBounds; // constricted bounds, if cursor ring is partially visible - WebCore::IntRect mNavBounds; // cursor ring bounds plus optional keystroke movement - WebCore::IntRect mPriorBounds; // prior chosen cursor ring (for reversing narrowing) - bool mDirectionChange; - bool mDidFirstLayout; // set true when page is newly laid out - CachedFrame::Direction mLastMove; - CachedFrame::Direction mPriorMove; - int mMinWorkingHorizontal; - int mMaxWorkingHorizontal; - int mMinWorkingVertical; - int mMaxWorkingVertical; - friend class CachedRoot; -#if DUMP_NAV_CACHE -public: - class Debug { -public: - CachedHistory* base() const; - const char* direction(CachedFrame::Direction d) const; - void print(CachedRoot* ) const; - } mDebug; -#endif -}; - -} - -#endif diff --git a/Source/WebKit/android/nav/CachedInput.cpp b/Source/WebKit/android/nav/CachedInput.cpp deleted file mode 100644 index a6a57ef..0000000 --- a/Source/WebKit/android/nav/CachedInput.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "CachedPrefix.h" -#include "CachedInput.h" - -namespace android { - -void CachedInput::init() { - bzero(this, sizeof(CachedInput)); - mName = WTF::String(); -} - -void CachedInput::setTypeFromElement(WebCore::HTMLInputElement* element) -{ - ASSERT(element); - - if (element->isPasswordField()) - mType = PASSWORD; - else if (element->isSearchField()) - mType = SEARCH; - else if (element->isEmailField()) - mType = EMAIL; - else if (element->isNumberField()) - mType = NUMBER; - else if (element->isTelephoneField()) - mType = TELEPHONE; - else if (element->isURLField()) - mType = URL; - else - mType = NORMAL_TEXT_FIELD; -} - -#if DUMP_NAV_CACHE - -#define DEBUG_PRINT_BOOL(field) \ - DUMP_NAV_LOGD("// bool " #field "=%s;\n", b->field ? "true" : "false") - -CachedInput* CachedInput::Debug::base() const { - CachedInput* nav = (CachedInput*) ((char*) this - OFFSETOF(CachedInput, mDebug)); - return nav; -} - -static void printWebCoreString(const char* label, - const WTF::String& string) { - char scratch[256]; - size_t index = snprintf(scratch, sizeof(scratch), label); - const UChar* ch = string.characters(); - while (ch && *ch && index < sizeof(scratch)) { - UChar c = *ch++; - if (c < ' ' || c >= 0x7f) c = ' '; - scratch[index++] = c; - } - DUMP_NAV_LOGD("%.*s\"\n", index, scratch); -} - -void CachedInput::Debug::print() const -{ - CachedInput* b = base(); - DEBUG_PRINT_BOOL(mAutoComplete); - DUMP_NAV_LOGD("// void* mForm=%p;\n", b->mForm); - printWebCoreString("// char* mName=\"", b->mName); - DUMP_NAV_LOGD("// int mMaxLength=%d;\n", b->mMaxLength); - DUMP_NAV_LOGD("// int mPaddingLeft=%d;\n", b->mPaddingLeft); - DUMP_NAV_LOGD("// int mPaddingTop=%d;\n", b->mPaddingTop); - DUMP_NAV_LOGD("// int mPaddingRight=%d;\n", b->mPaddingRight); - DUMP_NAV_LOGD("// int mPaddingBottom=%d;\n", b->mPaddingBottom); - DUMP_NAV_LOGD("// float mTextSize=%f;\n", b->mTextSize); - DUMP_NAV_LOGD("// int mLineHeight=%d;\n", b->mLineHeight); - DUMP_NAV_LOGD("// Type mType=%d;\n", b->mType); - DEBUG_PRINT_BOOL(mIsRtlText); - DEBUG_PRINT_BOOL(mIsTextField); - DEBUG_PRINT_BOOL(mIsTextArea); -} - -#endif - -} diff --git a/Source/WebKit/android/nav/CachedInput.h b/Source/WebKit/android/nav/CachedInput.h deleted file mode 100644 index 77ae57b..0000000 --- a/Source/WebKit/android/nav/CachedInput.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CachedInput_h -#define CachedInput_h - -#include "CachedDebug.h" -#include "HTMLInputElement.h" -#include "PlatformString.h" - -namespace android { - -class CachedInput { -public: - CachedInput() { - // Initiaized to 0 in its array, so nothing to do in the - // constructor - } - - enum Type { - NONE = -1, - NORMAL_TEXT_FIELD = 0, - TEXT_AREA = 1, - PASSWORD = 2, - SEARCH = 3, - EMAIL = 4, - NUMBER = 5, - TELEPHONE = 6, - URL = 7 - }; - - bool autoComplete() const { return mAutoComplete; } - void* formPointer() const { return mForm; } - void init(); - void setTypeFromElement(WebCore::HTMLInputElement*); - Type getType() const { return mType; } - bool isRtlText() const { return mIsRtlText; } - bool isTextField() const { return mIsTextField; } - bool isTextArea() const { return mIsTextArea; } - int lineHeight() const { return mLineHeight; } - int maxLength() const { return mMaxLength; }; - const WTF::String& name() const { return mName; } - int paddingBottom() const { return mPaddingBottom; } - int paddingLeft() const { return mPaddingLeft; } - int paddingRight() const { return mPaddingRight; } - int paddingTop() const { return mPaddingTop; } - void setAutoComplete(bool autoComplete) { mAutoComplete = autoComplete; } - void setFormPointer(void* form) { mForm = form; } - void setIsRtlText(bool isRtlText) { mIsRtlText = isRtlText; } - void setIsTextField(bool isTextField) { mIsTextField = isTextField; } - void setIsTextArea(bool isTextArea) { mIsTextArea = isTextArea; } - void setLineHeight(int height) { mLineHeight = height; } - void setMaxLength(int maxLength) { mMaxLength = maxLength; } - void setName(const WTF::String& name) { mName = name; } - void setPaddingBottom(int bottom) { mPaddingBottom = bottom; } - void setPaddingLeft(int left) { mPaddingLeft = left; } - void setPaddingRight(int right) { mPaddingRight = right; } - void setPaddingTop(int top) { mPaddingTop = top; } - void setSpellcheck(bool spellcheck) { mSpellcheck = spellcheck; } - void setTextSize(float textSize) { mTextSize = textSize; } - bool spellcheck() const { return mSpellcheck; } - float textSize() const { return mTextSize; } - -private: - - void* mForm; - int mLineHeight; - int mMaxLength; - WTF::String mName; - int mPaddingBottom; - int mPaddingLeft; - int mPaddingRight; - int mPaddingTop; - float mTextSize; - Type mType; - bool mAutoComplete : 1; - bool mSpellcheck : 1; - bool mIsRtlText : 1; - bool mIsTextField : 1; - bool mIsTextArea : 1; -#if DUMP_NAV_CACHE -public: - class Debug { -public: - CachedInput* base() const; - void print() const; - } mDebug; -#endif -}; - -} - -#endif diff --git a/Source/WebKit/android/nav/CachedLayer.cpp b/Source/WebKit/android/nav/CachedLayer.cpp deleted file mode 100644 index f6dfb88..0000000 --- a/Source/WebKit/android/nav/CachedLayer.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "CachedPrefix.h" - -#include "CachedLayer.h" -#include "FloatRect.h" -#include "LayerAndroid.h" - -namespace android { - -#if USE(ACCELERATED_COMPOSITING) - -IntRect CachedLayer::adjustBounds(const LayerAndroid* root, - const IntRect& bounds) const -{ - const LayerAndroid* aLayer = layer(root); - if (!aLayer) { - DBG_NAV_LOGD("no layer in root=%p uniqueId=%d", root, mUniqueId); -#if DUMP_NAV_CACHE - if (root) - mDebug.printRootLayerAndroid(root); -#endif - return bounds; - } - FloatRect temp = bounds; - // First, remove the original offset from the bounds. - temp.move(-mOffset.x(), -mOffset.y()); - - // Next, add in the new position of the layer (could be different due to a - // fixed position layer). - FloatPoint position = getGlobalPosition(aLayer); - temp.move(position.x(), position.y()); - - // Add in any layer translation. - // FIXME: Should use bounds() and apply the entire transformation matrix. - const FloatPoint& translation = aLayer->translation(); - temp.move(translation.x(), translation.y()); - - SkRect clip; - aLayer->bounds(&clip); - - // Do not try to traverse the parent chain if this is the root as the parent - // will not be a LayerAndroid. - if (aLayer != root) { - LayerAndroid* parent = static_cast<LayerAndroid*>(aLayer->getParent()); - while (parent) { - SkRect pClip; - parent->bounds(&pClip); - - // Move our position into our parent's coordinate space. - clip.offset(pClip.fLeft, pClip.fTop); - // Clip our visible rectangle to the parent. - clip.intersect(pClip); - - // Stop at the root. - if (parent == root) - break; - parent = static_cast<LayerAndroid*>(parent->getParent()); - } - } - - // Intersect the result with the visible clip. - temp.intersect(clip); - - IntRect result = enclosingIntRect(temp); - - DBG_NAV_LOGV("root=%p aLayer=%p [%d]" - " bounds=(%d,%d,w=%d,h=%d) trans=(%g,%g) pos=(%f,%f)" - " offset=(%d,%d)" - " result=(%d,%d,w=%d,h=%d)", - root, aLayer, aLayer->uniqueId(), - bounds.x(), bounds.y(), bounds.width(), bounds.height(), - translation.x(), translation.y(), position.x(), position.y(), - mOffset.x(), mOffset.y(), - result.x(), result.y(), result.width(), result.height()); - return result; -} - -FloatPoint CachedLayer::getGlobalPosition(const LayerAndroid* aLayer) const -{ - SkPoint result = aLayer->getPosition(); - const Layer* parent = aLayer->getParent(); - while (parent) { - result += parent->getPosition(); - DBG_NAV_LOGV("result=(%g,%g) parent=%p [%d]", result.fX, result.fY, - parent, ((LayerAndroid*) parent)->uniqueId()); - parent = parent->getParent(); - } - return result; -} - -const LayerAndroid* CachedLayer::layer(const LayerAndroid* root) const -{ - if (!root) - return 0; - return root->findById(mUniqueId); -} - -// return bounds relative to the layer as recorded when walking the dom -IntRect CachedLayer::localBounds(const LayerAndroid* root, - const IntRect& bounds) const -{ - IntRect temp = bounds; - // Remove the original offset from the bounds. - temp.move(-mOffset.x(), -mOffset.y()); - -#if DEBUG_NAV_UI - const LayerAndroid* aLayer = layer(root); - DBG_NAV_LOGD("aLayer=%p [%d] bounds=(%d,%d,w=%d,h=%d) offset=(%d,%d)" - " result=(%d,%d,w=%d,h=%d)", - aLayer, aLayer ? aLayer->uniqueId() : 0, - bounds.x(), bounds.y(), bounds.width(), bounds.height(), - mOffset.x(), mOffset.y(), - temp.x(), temp.y(), temp.width(), temp.height()); -#endif - - return temp; -} - -SkPicture* CachedLayer::picture(const LayerAndroid* root) const -{ - const LayerAndroid* aLayer = layer(root); - if (!aLayer) - return 0; - DBG_NAV_LOGD("root=%p aLayer=%p [%d] picture=%p", - root, aLayer, aLayer->uniqueId(), aLayer->picture()); - return aLayer->picture(); -} - -void CachedLayer::toLocal(const LayerAndroid* root, int* xPtr, int* yPtr) const -{ - const LayerAndroid* aLayer = layer(root); - if (!aLayer) - return; - DBG_NAV_LOGD("root=%p aLayer=%p [%d]", root, aLayer, aLayer->uniqueId()); - SkRect localBounds; - aLayer->bounds(&localBounds); - *xPtr -= localBounds.fLeft; - *yPtr -= localBounds.fTop; -} - -#if DUMP_NAV_CACHE - -CachedLayer* CachedLayer::Debug::base() const { - return (CachedLayer*) ((char*) this - OFFSETOF(CachedLayer, mDebug)); -} - -void CachedLayer::Debug::print() const -{ - CachedLayer* b = base(); - DUMP_NAV_LOGD(" // int mCachedNodeIndex=%d;\n", b->mCachedNodeIndex); - DUMP_NAV_LOGD(" // int mOffset=(%d, %d);\n", - b->mOffset.x(), b->mOffset.y()); - DUMP_NAV_LOGD(" // int mUniqueId=%p;\n", b->mUniqueId); - DUMP_NAV_LOGD("%s\n", ""); -} - -#endif - -#if DUMP_NAV_CACHE - -int CachedLayer::Debug::spaces; - -void CachedLayer::Debug::printLayerAndroid(const LayerAndroid* layer) -{ - ++spaces; - SkRect bounds; - layer->bounds(&bounds); - DBG_NAV_LOGD("%.*s layer=%p [%d] (%g,%g,%g,%g)" - " position=(%g,%g) translation=(%g,%g) anchor=(%g,%g)" - " matrix=(%g,%g) childMatrix=(%g,%g) picture=%p clipped=%s" - " scrollable=%s\n", - spaces, " ", layer, layer->uniqueId(), - bounds.fLeft, bounds.fTop, bounds.width(), bounds.height(), - layer->getPosition().fX, layer->getPosition().fY, - layer->translation().x(), layer->translation().y(), - layer->getAnchorPoint().fX, layer->getAnchorPoint().fY, - layer->getMatrix().getTranslateX(), layer->getMatrix().getTranslateY(), - layer->getChildrenMatrix().getTranslateX(), - layer->getChildrenMatrix().getTranslateY(), - layer->picture(), layer->m_haveClip ? "true" : "false", - layer->contentIsScrollable() ? "true" : "false"); - for (int i = 0; i < layer->countChildren(); i++) - printLayerAndroid(layer->getChild(i)); - --spaces; -} - -void CachedLayer::Debug::printRootLayerAndroid(const LayerAndroid* layer) -{ - spaces = 0; - printLayerAndroid(layer); -} -#endif - -#endif // USE(ACCELERATED_COMPOSITING) - -} - diff --git a/Source/WebKit/android/nav/CachedLayer.h b/Source/WebKit/android/nav/CachedLayer.h deleted file mode 100644 index fa427d2..0000000 --- a/Source/WebKit/android/nav/CachedLayer.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CachedLayer_h -#define CachedLayer_h - -#include "CachedDebug.h" -#include "IntRect.h" - -class SkPicture; - -namespace WebCore { - class FloatPoint; - class LayerAndroid; -} - -using namespace WebCore; - -namespace android { - -class CachedLayer { -public: -#if USE(ACCELERATED_COMPOSITING) - bool operator<(const CachedLayer& l) const { - return mCachedNodeIndex < l.mCachedNodeIndex; - } - // FIXME: adjustBounds should be renamed globalBounds or toGlobal - IntRect adjustBounds(const LayerAndroid* root, const IntRect& bounds) const; - int cachedNodeIndex() const { return mCachedNodeIndex; } - FloatPoint getGlobalPosition(const LayerAndroid* ) const; - const LayerAndroid* layer(const LayerAndroid* root) const; - IntRect localBounds(const LayerAndroid* root, const IntRect& bounds) const; - SkPicture* picture(const LayerAndroid* root) const; - void toLocal(const LayerAndroid* root, int* xPtr, int* yPtr) const; - void setCachedNodeIndex(int index) { mCachedNodeIndex = index; } - // Set the global position of the layer. This is recorded by the nav cache - // and corresponds to RenderLayer::absoluteBoundingBox() which is in - // document coordinates. This can be different from the global position of - // the layer if the layer is fixed positioned or scrollable. - void setOffset(const IntPoint& offset) { mOffset = offset; } - void setUniqueId(int uniqueId) { mUniqueId = uniqueId; } - int uniqueId() const { return mUniqueId; } -private: - int mCachedNodeIndex; - IntPoint mOffset; - int mUniqueId; - -#if DUMP_NAV_CACHE -public: - class Debug { -public: - CachedLayer* base() const; - void print() const; - static void printLayerAndroid(const LayerAndroid* ); - static void printRootLayerAndroid(const LayerAndroid* ); - static int spaces; - } mDebug; -#endif -#endif // USE(ACCELERATED_COMPOSITING) -}; - -} - -#endif diff --git a/Source/WebKit/android/nav/CachedNode.cpp b/Source/WebKit/android/nav/CachedNode.cpp deleted file mode 100644 index e291504..0000000 --- a/Source/WebKit/android/nav/CachedNode.cpp +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright 2007, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "CachedPrefix.h" -#include "android_graphics.h" -#include "CachedFrame.h" -#include "CachedHistory.h" -#include "Node.h" -#include "PlatformString.h" - -#include "CachedNode.h" - -namespace android { - -WebCore::IntRect CachedNode::bounds(const CachedFrame* frame) const -{ - return mIsInLayer ? frame->adjustBounds(this, mBounds) : mBounds; -} - -void CachedNode::clearCursor(CachedFrame* parent) -{ - if (isFrame()) { - CachedFrame* child = const_cast<CachedFrame*>(parent->hasFrame(this)); - child->clearCursor(); - } - mIsCursor = false; -} - -bool CachedNode::Clip(const WebCore::IntRect& outer, WebCore::IntRect* inner, - WTF::Vector<WebCore::IntRect>* rings) -{ - if (outer.contains(*inner)) - return true; -// DBG_NAV_LOGD("outer:{%d,%d,%d,%d} does not contain inner:{%d,%d,%d,%d}", -// outer.x(), outer.y(), outer.width(), outer.height(), -// inner->x(), inner->y(), inner->width(), inner->height()); - bool intersects = outer.intersects(*inner); - size_t size = intersects ? rings->size() : 0; - *inner = WebCore::IntRect(0, 0, 0, 0); - if (intersects) { - WebCore::IntRect * const start = rings->begin(); - WebCore::IntRect* ring = start + size - 1; - do { - ring->intersect(outer); - if (ring->isEmpty()) { - if ((size_t) (ring - start) != --size) - *ring = start[size]; - } else - inner->unite(*ring); - } while (ring-- != start); - } - rings->shrink(size); -// DBG_NAV_LOGD("size:%d", size); - return size != 0; -} - -bool CachedNode::clip(const WebCore::IntRect& bounds) -{ - return Clip(bounds, &mBounds, &mCursorRing); -} - - -void CachedNode::cursorRings(const CachedFrame* frame, - WTF::Vector<WebCore::IntRect>* rings) const -{ - rings->clear(); - for (unsigned index = 0; index < mCursorRing.size(); index++) - rings->append(ring(frame, index)); -} - -WebCore::IntRect CachedNode::cursorRingBounds(const CachedFrame* frame) const -{ - int partMax = navableRects(); - WebCore::IntRect bounds; - for (int partIndex = 0; partIndex < partMax; partIndex++) - bounds.unite(mCursorRing[partIndex]); - bounds.inflate(CURSOR_RING_HIT_TEST_RADIUS); - return mIsInLayer ? frame->adjustBounds(this, bounds) : bounds; -} - -#define OVERLAP 3 - -void CachedNode::fixUpCursorRects(const CachedFrame* frame) -{ - if (mFixedUpCursorRects) - return; - mFixedUpCursorRects = true; - // if the hit-test rect doesn't intersect any other rect, use it - if (mHitBounds != mBounds && mHitBounds.contains(mBounds) && - frame->checkRings(this, mHitBounds)) { - DBG_NAV_LOGD("use mHitBounds (%d,%d,%d,%d)", mHitBounds.x(), - mHitBounds.y(), mHitBounds.width(), mHitBounds.height()); - mUseHitBounds = true; - return; - } - if (navableRects() <= 1) - return; - // if there is more than 1 rect, and the bounds doesn't intersect - // any other cursor ring bounds, use it - IntRect sloppyBounds = mBounds; - sloppyBounds.inflate(2); // give it a couple of extra pixels - if (frame->checkRings(this, sloppyBounds)) { - DBG_NAV_LOGD("use mBounds (%d,%d,%d,%d)", mBounds.x(), - mBounds.y(), mBounds.width(), mBounds.height()); - mUseBounds = true; - return; - } -#if DEBUG_NAV_UI - { - WebCore::IntRect* boundsPtr = mCursorRing.begin() - 1; - const WebCore::IntRect* const boundsEnd = mCursorRing.begin() + mCursorRing.size(); - while (++boundsPtr < boundsEnd) - ALOGD("%s %d:(%d, %d, %d, %d)\n", __FUNCTION__, boundsPtr - mCursorRing.begin(), - boundsPtr->x(), boundsPtr->y(), boundsPtr->width(), boundsPtr->height()); - } -#endif - // q: need to know when rects are for drawing and hit-testing, but not mouse down calcs? - bool again; - do { - again = false; - size_t size = mCursorRing.size(); - WebCore::IntRect* unitBoundsPtr = mCursorRing.begin() - 1; - const WebCore::IntRect* const unitBoundsEnd = mCursorRing.begin() + size; - while (++unitBoundsPtr < unitBoundsEnd) { - // any other unitBounds to the left or right of this one? - int unitTop = unitBoundsPtr->y(); - int unitBottom = unitBoundsPtr->maxY(); - int unitLeft = unitBoundsPtr->x(); - int unitRight = unitBoundsPtr->maxX(); - WebCore::IntRect* testBoundsPtr = mCursorRing.begin() - 1; - while (++testBoundsPtr < unitBoundsEnd) { - if (unitBoundsPtr == testBoundsPtr) - continue; - int testTop = testBoundsPtr->y(); - int testBottom = testBoundsPtr->maxY(); - int testLeft = testBoundsPtr->x(); - int testRight = testBoundsPtr->maxX(); - int candidateTop = unitTop > testTop ? unitTop : testTop; - int candidateBottom = unitBottom < testBottom ? unitBottom : testBottom; - int candidateLeft = unitRight < testLeft ? unitRight : testRight; - int candidateRight = unitRight > testLeft ? unitLeft : testLeft; - bool leftRight = true; - if (candidateTop + OVERLAP >= candidateBottom || - candidateLeft + OVERLAP >= candidateRight) { - candidateTop = unitBottom < testTop ? unitBottom : testBottom; - candidateBottom = unitBottom > testTop ? unitTop : testTop; - candidateLeft = unitLeft > testLeft ? unitLeft : testLeft; - candidateRight = unitRight < testRight ? unitRight : testRight; - if (candidateTop + OVERLAP >= candidateBottom || - candidateLeft + OVERLAP >= candidateRight) - continue; - leftRight = false; - } - // construct candidate to add - WebCore::IntRect candidate = WebCore::IntRect(candidateLeft, candidateTop, - candidateRight - candidateLeft, candidateBottom - candidateTop); - // does a different unit bounds intersect the candidate? if so, don't add - WebCore::IntRect* checkBoundsPtr = mCursorRing.begin() - 1; - while (++checkBoundsPtr < unitBoundsEnd) { - if (checkBoundsPtr->intersects(candidate) == false) - continue; - if (leftRight) { - if (candidateTop >= checkBoundsPtr->y() && - candidateBottom > checkBoundsPtr->maxY()) - candidateTop = checkBoundsPtr->maxY(); - else if (candidateTop < checkBoundsPtr->y() && - candidateBottom <= checkBoundsPtr->maxY()) - candidateBottom = checkBoundsPtr->y(); - else - goto nextCheck; - } else { - if (candidateLeft >= checkBoundsPtr->x() && - candidateRight > checkBoundsPtr->maxX()) - candidateLeft = checkBoundsPtr->maxX(); - else if (candidateLeft < checkBoundsPtr->x() && - candidateRight <= checkBoundsPtr->maxX()) - candidateRight = checkBoundsPtr->x(); - else - goto nextCheck; - } - } - candidate = WebCore::IntRect(candidateLeft, candidateTop, - candidateRight - candidateLeft, candidateBottom - candidateTop); - ASSERT(candidate.isEmpty() == false); -#if DEBUG_NAV_UI - ALOGD("%s %d:(%d, %d, %d, %d)\n", __FUNCTION__, mCursorRing.size(), - candidate.x(), candidate.y(), candidate.width(), candidate.height()); -#endif - mCursorRing.append(candidate); - again = true; - goto tryAgain; - nextCheck: - continue; - } - } -tryAgain: - ; - } while (again); -} - - -void CachedNode::hideCursor(CachedFrame* parent) -{ - if (isFrame()) { - CachedFrame* child = const_cast<CachedFrame*>(parent->hasFrame(this)); - child->hideCursor(); - } - mIsHidden = true; -} - -WebCore::IntRect CachedNode::hitBounds(const CachedFrame* frame) const -{ - return mIsInLayer ? frame->adjustBounds(this, mHitBounds) : mHitBounds; -} - -void CachedNode::init(WebCore::Node* node) -{ - bzero(this, sizeof(CachedNode)); - mExport = WTF::String(); - mNode = node; - mParentIndex = mDataIndex = -1; - mType = android::NORMAL_CACHEDNODETYPE; -} - -bool CachedNode::isTextField(const CachedFrame* frame) const -{ - const CachedInput* input = frame->textInput(this); - return input ? input->isTextField() : false; -} - -void CachedNode::localCursorRings(const CachedFrame* frame, - WTF::Vector<WebCore::IntRect>* rings) const -{ - rings->clear(); - for (unsigned index = 0; index < mCursorRing.size(); index++) - rings->append(localRing(frame, index)); -} - -WebCore::IntRect CachedNode::localBounds(const CachedFrame* frame) const -{ - return mIsInLayer ? frame->localBounds(this, mBounds) : mBounds; -} - -WebCore::IntRect CachedNode::localHitBounds(const CachedFrame* frame) const -{ - return mIsInLayer ? frame->localBounds(this, mHitBounds) : mHitBounds; -} - -WebCore::IntRect CachedNode::localRing(const CachedFrame* frame, - size_t part) const -{ - const WebCore::IntRect& rect = mCursorRing.at(part); - return mIsInLayer ? frame->localBounds(this, rect) : rect; -} - -void CachedNode::move(int x, int y) -{ - mBounds.move(x, y); - // mHitTestBounds will be moved by caller - WebCore::IntRect* first = mCursorRing.begin(); - WebCore::IntRect* last = first + mCursorRing.size(); - --first; - while (++first != last) - first->move(x, y); -} - -bool CachedNode::partRectsContains(const CachedNode* other) const -{ - int outerIndex = 0; - int outerMax = navableRects(); - int innerMax = other->navableRects(); - do { - const WebCore::IntRect& outerBounds = mCursorRing[outerIndex]; - int innerIndex = 0; - do { - const WebCore::IntRect& innerBounds = other->mCursorRing[innerIndex]; - if (innerBounds.contains(outerBounds)) - return true; - } while (++innerIndex < innerMax); - } while (++outerIndex < outerMax); - return false; -} - -WebCore::IntRect CachedNode::ring(const CachedFrame* frame, size_t part) const -{ - const WebCore::IntRect& rect = mCursorRing.at(part); - return mIsInLayer ? frame->adjustBounds(this, rect) : rect; -} - -#if DUMP_NAV_CACHE - -#define DEBUG_PRINT_BOOL(field) \ - DUMP_NAV_LOGD("// bool " #field "=%s;\n", b->field ? "true" : "false") - -#define DEBUG_PRINT_RECT(field) \ - { const WebCore::IntRect& r = b->field; \ - DUMP_NAV_LOGD("// IntRect " #field "={%d, %d, %d, %d};\n", \ - r.x(), r.y(), r.width(), r.height()); } - -CachedNode* CachedNode::Debug::base() const { - CachedNode* nav = (CachedNode*) ((char*) this - OFFSETOF(CachedNode, mDebug)); - return nav; -} - -const char* CachedNode::Debug::condition(Condition t) const -{ - switch (t) { - case NOT_REJECTED: return "NOT_REJECTED"; break; - case BUTTED_UP: return "BUTTED_UP"; break; - case CENTER_FURTHER: return "CENTER_FURTHER"; break; - case CLOSER: return "CLOSER"; break; - case CLOSER_IN_CURSOR: return "CLOSER_IN_CURSOR"; break; - case CLOSER_OVERLAP: return "CLOSER_OVERLAP"; break; - case CLOSER_TOP: return "CLOSER_TOP"; break; - case NAVABLE: return "NAVABLE"; break; - case FURTHER: return "FURTHER"; break; - case IN_UMBRA: return "IN_UMBRA"; break; - case IN_WORKING: return "IN_WORKING"; break; - case LEFTMOST: return "LEFTMOST"; break; - case OVERLAP_OR_EDGE_FURTHER: return "OVERLAP_OR_EDGE_FURTHER"; break; - case PREFERRED: return "PREFERRED"; break; - case ANCHOR_IN_ANCHOR: return "ANCHOR_IN_ANCHOR"; break; - case BEST_DIRECTION: return "BEST_DIRECTION"; break; - case CHILD: return "CHILD"; break; - case DISABLED: return "DISABLED"; break; - case HIGHER_TAB_INDEX: return "HIGHER_TAB_INDEX"; break; - case IN_CURSOR: return "IN_CURSOR"; break; - case IN_CURSOR_CHILDREN: return "IN_CURSOR_CHILDREN"; break; - case NOT_ENCLOSING_CURSOR: return "NOT_ENCLOSING_CURSOR"; break; - case NOT_CURSOR_NODE: return "NOT_CURSOR_NODE"; break; - case OUTSIDE_OF_BEST: return "OUTSIDE_OF_BEST"; break; - case OUTSIDE_OF_ORIGINAL: return "OUTSIDE_OF_ORIGINAL"; break; - default: return "???"; - } -} - -const char* CachedNode::Debug::type(android::CachedNodeType t) const -{ - switch (t) { - case NORMAL_CACHEDNODETYPE: return "NORMAL"; break; - case ADDRESS_CACHEDNODETYPE: return "ADDRESS"; break; - case EMAIL_CACHEDNODETYPE: return "EMAIL"; break; - case PHONE_CACHEDNODETYPE: return "PHONE"; break; - case ANCHOR_CACHEDNODETYPE: return "ANCHOR"; break; - case AREA_CACHEDNODETYPE: return "AREA"; break; - case FRAME_CACHEDNODETYPE: return "FRAME"; break; - case PLUGIN_CACHEDNODETYPE: return "PLUGIN"; break; - case TEXT_INPUT_CACHEDNODETYPE: return "INPUT"; break; - case SELECT_CACHEDNODETYPE: return "SELECT"; break; - case CONTENT_EDITABLE_CACHEDNODETYPE: return "CONTENT_EDITABLE"; break; - default: return "???"; - } -} - -void CachedNode::Debug::print() const -{ - CachedNode* b = base(); - char scratch[256]; - size_t index = snprintf(scratch, sizeof(scratch), "// char* mExport=\""); - const UChar* ch = b->mExport.characters(); - while (ch && *ch && index < sizeof(scratch)) { - UChar c = *ch++; - if (c < ' ' || c >= 0x7f) c = ' '; - scratch[index++] = c; - } - DUMP_NAV_LOGD("%.*s\"\n", index, scratch); - DEBUG_PRINT_RECT(mBounds); - DEBUG_PRINT_RECT(mHitBounds); - DEBUG_PRINT_RECT(mOriginalAbsoluteBounds); - const WTF::Vector<WebCore::IntRect>* rects = &b->mCursorRing; - size_t size = rects->size(); - DUMP_NAV_LOGD("// IntRect cursorRings={ // size=%d\n", size); - for (size_t i = 0; i < size; i++) { - const WebCore::IntRect& rect = (*rects)[i]; - DUMP_NAV_LOGD(" // {%d, %d, %d, %d}, // %d\n", rect.x(), rect.y(), - rect.width(), rect.height(), i); - } - DUMP_NAV_LOGD("// };\n"); - DUMP_NAV_LOGD("// void* mNode=%p; // (%d) \n", b->mNode, mNodeIndex); - DUMP_NAV_LOGD("// void* mParentGroup=%p; // (%d) \n", b->mParentGroup, mParentGroupIndex); - DUMP_NAV_LOGD("// int mDataIndex=%d;\n", b->mDataIndex); - DUMP_NAV_LOGD("// int mIndex=%d;\n", b->mIndex); - DUMP_NAV_LOGD("// int navableRects()=%d;\n", b->navableRects()); - DUMP_NAV_LOGD("// int mParentIndex=%d;\n", b->mParentIndex); - DUMP_NAV_LOGD("// int mTabIndex=%d;\n", b->mTabIndex); - DUMP_NAV_LOGD("// int mColorIndex=%d;\n", b->mColorIndex); - DUMP_NAV_LOGD("// Condition mCondition=%s;\n", condition(b->mCondition)); - DUMP_NAV_LOGD("// Type mType=%s;\n", type(b->mType)); - DEBUG_PRINT_BOOL(mClippedOut); - DEBUG_PRINT_BOOL(mDisabled); - DEBUG_PRINT_BOOL(mFixedUpCursorRects); - DEBUG_PRINT_BOOL(mHasCursorRing); - DEBUG_PRINT_BOOL(mHasMouseOver); - DEBUG_PRINT_BOOL(mIsCursor); - DEBUG_PRINT_BOOL(mIsFocus); - DEBUG_PRINT_BOOL(mIsHidden); - DEBUG_PRINT_BOOL(mIsInLayer); - DEBUG_PRINT_BOOL(mIsParentAnchor); - DEBUG_PRINT_BOOL(mIsTransparent); - DEBUG_PRINT_BOOL(mIsUnclipped); - DEBUG_PRINT_BOOL(mLast); - DEBUG_PRINT_BOOL(mUseBounds); - DEBUG_PRINT_BOOL(mUseHitBounds); - DEBUG_PRINT_BOOL(mSingleImage); -} - -#endif - -} diff --git a/Source/WebKit/android/nav/CachedNode.h b/Source/WebKit/android/nav/CachedNode.h deleted file mode 100644 index 82d55ed..0000000 --- a/Source/WebKit/android/nav/CachedNode.h +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright 2007, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CachedNode_h -#define CachedNode_h - -#include "CachedDebug.h" -#include "CachedNodeType.h" -#include "IntRect.h" -#include "PlatformString.h" - -#include <wtf/Vector.h> -#include <wtf/text/AtomicString.h> - -class SkPicture; - -namespace WebCore { - class Node; -} - -namespace android { - -class CachedFrame; -class CachedRoot; - -class CachedNode { -public: -// Nodes are rejected because either they are spacially not the best (first set) -// or because they have the wrong DOM attribute (in focus, a focused child, etc) -// findClosest() gives only spacially rejected nodes a second chance - enum Condition { // if bigger than 32, increase bitfield size below - // rejections that get a second chance - NOT_REJECTED = 0, - SECOND_CHANCE_START = NOT_REJECTED, // must be first in list - BUTTED_UP, - CENTER_FURTHER, - CLOSER, - CLOSER_IN_CURSOR, - CLOSER_OVERLAP, - CLOSER_TOP, - NAVABLE, - FURTHER, - IN_UMBRA, - IN_WORKING, - LEFTMOST, - NOT_ENCLOSING_CURSOR, - OVERLAP_OR_EDGE_FURTHER, - PREFERRED, // better overlap measure - SECOND_CHANCE_END = PREFERRED, // must be last in list - // rejections that don't get a second chance - ANCHOR_IN_ANCHOR, - BEST_DIRECTION, // can be reached by another direction - CHILD, - DISABLED, - HIGHER_TAB_INDEX, - IN_CURSOR, - IN_CURSOR_CHILDREN, - NOT_CURSOR_NODE, - OUTSIDE_OF_BEST, // containership - OUTSIDE_OF_ORIGINAL, // containership - UNDER_LAYER, - CONDITION_SIZE // FIXME: test that CONDITION_SIZE fits in mCondition - }; - CachedNode() { - // The node is initiaized to 0 in its array, so nothing to do in the - // constructor - } - - WebCore::IntRect bounds(const CachedFrame* ) const; - int childFrameIndex() const { return isFrame() ? mDataIndex : -1; } - void clearCondition() const { mCondition = NOT_REJECTED; } - void clearCursor(CachedFrame* ); - static bool Clip(const WebCore::IntRect& outer, WebCore::IntRect* inner, - WTF::Vector<WebCore::IntRect>* rings); - bool clip(const WebCore::IntRect& ); - bool clippedOut() { return mClippedOut; } - int colorIndex() const { return mColorIndex; } - WebCore::IntRect cursorRingBounds(const CachedFrame* ) const; - void cursorRings(const CachedFrame* , WTF::Vector<WebCore::IntRect>* ) const; - bool disabled() const { return mDisabled; } - const CachedNode* document() const { return &this[-mIndex]; } - void fixUpCursorRects(const CachedFrame* frame); - const WTF::String& getExport() const { return mExport; } - bool hasCursorRing() const { return mHasCursorRing; } - bool hasMouseOver() const { return mHasMouseOver; } - void hideCursor(CachedFrame* ); - WebCore::IntRect hitBounds(const CachedFrame* ) const; - int index() const { return mIndex; } - void init(WebCore::Node* node); - bool isAnchor() const { return mType == ANCHOR_CACHEDNODETYPE; } - bool isContentEditable() const { return mType == CONTENT_EDITABLE_CACHEDNODETYPE; } - bool isCursor() const { return mIsCursor; } - bool isArea() const { return mType == AREA_CACHEDNODETYPE; } - bool isFocus() const { return mIsFocus; } - bool isFrame() const { return mType == FRAME_CACHEDNODETYPE; } - bool isHidden() const { return mIsHidden; } - bool isInLayer() const { return mIsInLayer; } - bool isNavable(const CachedFrame* frame, const WebCore::IntRect& clip) const { - return clip.intersects(bounds(frame)); - } - bool isPlugin() const { return mType == PLUGIN_CACHEDNODETYPE; } - bool isSelect() const { return mType == SELECT_CACHEDNODETYPE; } - bool isSyntheticLink() const { - return mType >= ADDRESS_CACHEDNODETYPE && mType <= PHONE_CACHEDNODETYPE; - } - bool isTextField(const CachedFrame*) const; - bool isTextInput() const { return mType == TEXT_INPUT_CACHEDNODETYPE; } - bool isTransparent() const { return mIsTransparent; } - bool isUnclipped() const { return mIsUnclipped; } - // localXXX functions are used only for drawing cursor rings - WebCore::IntRect localBounds(const CachedFrame* ) const; - void localCursorRings(const CachedFrame* , - WTF::Vector<WebCore::IntRect>* ) const; - WebCore::IntRect localHitBounds(const CachedFrame* ) const; - WebCore::IntRect localRing(const CachedFrame* , size_t part) const; - void move(int x, int y); - int navableRects() const { return mCursorRing.size(); } - void* nodePointer() const { return mNode; } - bool noSecondChance() const { return mCondition > SECOND_CHANCE_END; } - const WebCore::IntRect& originalAbsoluteBounds() const { - return mOriginalAbsoluteBounds; } - const CachedNode* parent() const { return document() + mParentIndex; } - void* parentGroup() const { return mParentGroup; } - int parentIndex() const { return mParentIndex; } - bool partRectsContains(const CachedNode* other) const; - const WebCore::IntRect& rawBounds() const { return mBounds; } - void reset(); - WebCore::IntRect ring(const CachedFrame* , size_t part) const; - const WTF::Vector<WebCore::IntRect>& rings() const { return mCursorRing; } - void setBounds(const WebCore::IntRect& bounds) { mBounds = bounds; } - void setClippedOut(bool clipped) { mClippedOut = clipped; } - void setColorIndex(int index) { mColorIndex = index; } - void setCondition(Condition condition) const { mCondition = condition; } - void setDataIndex(int index) { mDataIndex = index; } - void setDisabled(bool disabled) { mDisabled = disabled; } - void setExport(const WTF::String& exported) { mExport = exported; } - void setHasCursorRing(bool hasRing) { mHasCursorRing = hasRing; } - void setHasMouseOver(bool hasMouseOver) { mHasMouseOver = hasMouseOver; } - void setHitBounds(const WebCore::IntRect& bounds) { mHitBounds = bounds; } - void setOriginalAbsoluteBounds(const WebCore::IntRect& bounds) { - mOriginalAbsoluteBounds = bounds; } - void setIndex(int index) { mIndex = index; } - void setIsCursor(bool isCursor) { mIsCursor = isCursor; } - void setIsFocus(bool isFocus) { mIsFocus = isFocus; } - void setIsInLayer(bool isInLayer) { mIsInLayer = isInLayer; } - void setIsParentAnchor(bool isAnchor) { mIsParentAnchor = isAnchor; } - void setIsTransparent(bool isTransparent) { mIsTransparent = isTransparent; } - void setIsUnclipped(bool unclipped) { mIsUnclipped = unclipped; } - void setLast() { mLast = true; } - void setParentGroup(void* group) { mParentGroup = group; } - void setParentIndex(int parent) { mParentIndex = parent; } - void setSingleImage(bool single) { mSingleImage = single; } - void setTabIndex(int index) { mTabIndex = index; } - void setType(CachedNodeType type) { mType = type; } - void show() { mIsHidden = false; } - bool singleImage() const { return mSingleImage; } - int tabIndex() const { return mTabIndex; } - int textInputIndex() const { return isTextInput() ? mDataIndex : -1; } - const CachedNode* traverseNextNode() const { return mLast ? NULL : &this[1]; } - bool useBounds() const { return mUseBounds; } - bool useHitBounds() const { return mUseHitBounds; } - bool wantsKeyEvents() const { return isTextInput() || isPlugin() - || isContentEditable() || isFrame(); } -private: - WTF::String mExport; - WebCore::IntRect mBounds; - WebCore::IntRect mHitBounds; - WebCore::IntRect mOriginalAbsoluteBounds; - WTF::Vector<WebCore::IntRect> mCursorRing; - void* mNode; // WebCore::Node*, only used to match pointers - void* mParentGroup; // WebCore::Node*, only used to match pointers - int mDataIndex; // child frame if a frame; input data index; or -1 - int mIndex; // index of itself, to find first in array (document) - int mParentIndex; - int mTabIndex; - int mColorIndex; // index to ring color and other stylable properties - mutable Condition mCondition : 5; // why the node was not chosen on the first pass - CachedNodeType mType : 4; - bool mClippedOut : 1; - bool mDisabled : 1; - bool mFixedUpCursorRects : 1; - bool mHasCursorRing : 1; - bool mHasMouseOver : 1; - bool mIsCursor : 1; - bool mIsFocus : 1; - bool mIsHidden : 1; - bool mIsInLayer : 1; - bool mIsParentAnchor : 1; - bool mIsTransparent : 1; - bool mIsUnclipped : 1; - bool mLast : 1; // true if this is the last node in a group - bool mSingleImage : 1; - bool mUseBounds : 1; - bool mUseHitBounds : 1; -#ifdef BROWSER_DEBUG -public: - WebCore::Node* webCoreNode() const { return (WebCore::Node*) mNode; } - bool mDisplayMeasure; - mutable bool mInCompare; - int mSideDistance; - int mSecondSide; -#endif -#if DEBUG_NAV_UI || DUMP_NAV_CACHE -public: - class Debug { -public: - CachedNode* base() const; - const char* condition(Condition t) const; - void print() const; - const char* type(CachedNodeType t) const; -#if DUMP_NAV_CACHE - int mNodeIndex; - int mParentGroupIndex; -#endif - } mDebug; - friend class CachedNode::Debug; -#endif -}; - -} - -#endif diff --git a/Source/WebKit/android/nav/CachedNodeType.h b/Source/WebKit/android/nav/CachedNodeType.h deleted file mode 100644 index f922946..0000000 --- a/Source/WebKit/android/nav/CachedNodeType.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2007, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CachedNodeType_h -#define CachedNodeType_h - -namespace android { - -enum CachedNodeType { - NORMAL_CACHEDNODETYPE, - ADDRESS_CACHEDNODETYPE, - EMAIL_CACHEDNODETYPE, - PHONE_CACHEDNODETYPE, - ANCHOR_CACHEDNODETYPE, - AREA_CACHEDNODETYPE, - FRAME_CACHEDNODETYPE, - PLUGIN_CACHEDNODETYPE, - TEXT_INPUT_CACHEDNODETYPE, - SELECT_CACHEDNODETYPE, - CONTENT_EDITABLE_CACHEDNODETYPE -}; - -enum CachedNodeBits { - NORMAL_CACHEDNODE_BITS = 0, - ADDRESS_CACHEDNODE_BIT = 1 << (ADDRESS_CACHEDNODETYPE - 1), - EMAIL_CACHEDNODE_BIT = 1 << (EMAIL_CACHEDNODETYPE - 1), - PHONE_CACHEDNODE_BIT = 1 << (PHONE_CACHEDNODETYPE - 1), - ALL_CACHEDNODE_BITS = ADDRESS_CACHEDNODE_BIT | EMAIL_CACHEDNODE_BIT - | PHONE_CACHEDNODE_BIT -}; - -} - -#endif diff --git a/Source/WebKit/android/nav/CachedPrefix.h b/Source/WebKit/android/nav/CachedPrefix.h deleted file mode 100644 index 576aa4a..0000000 --- a/Source/WebKit/android/nav/CachedPrefix.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2007, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CachedPrefix_h -#define CachedPrefix_h - -#ifndef LOG_TAG -#define LOG_TAG "navcache" -#endif - -#include "config.h" -#include "CachedDebug.h" - -#ifndef _LIBS_CUTILS_LOG_H - #ifdef LOG - #undef LOG - #endif - - #include <utils/Log.h> -#endif - -#define OFFSETOF(type, field) ((char*)&(((type*)1)->field) - (char*)1) // avoids gnu warning - -#ifndef BZERO_DEFINED -#define BZERO_DEFINED -// http://www.opengroup.org/onlinepubs/000095399/functions/bzero.html -// For maximum portability, it is recommended to replace the function call to bzero() as follows: -#define bzero(b,len) (memset((b), '\0', (len)), (void) 0) -#endif - -#endif diff --git a/Source/WebKit/android/nav/CachedRoot.cpp b/Source/WebKit/android/nav/CachedRoot.cpp deleted file mode 100644 index eeb53fd..0000000 --- a/Source/WebKit/android/nav/CachedRoot.cpp +++ /dev/null @@ -1,1814 +0,0 @@ -/* - * Copyright 2007, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "CachedPrefix.h" -#include "android_graphics.h" -#include "CachedHistory.h" -#include "CachedInput.h" -#include "CachedLayer.h" -#include "CachedNode.h" -#include "FloatRect.h" -#include "LayerAndroid.h" -#include "ParseCanvas.h" -#include "SkBitmap.h" -#include "SkBounder.h" -#include "SkPixelRef.h" -#include "SkRegion.h" - -#include "CachedRoot.h" - -#if DEBUG_NAV_UI -#include "wtf/text/CString.h" -#endif - -#define DONT_CENTER_IF_ALREADY_VISIBLE - -using std::min; -using std::max; - -#ifdef DUMP_NAV_CACHE_USING_PRINTF - extern android::Mutex gWriteLogMutex; -#endif - -namespace android { - -class CommonCheck : public SkBounder { -public: - enum Type { - kNo_Type, - kDrawBitmap_Type, - kDrawGlyph_Type, - kDrawPaint_Type, - kDrawPath_Type, - kDrawPicture_Type, - kDrawPoints_Type, - kDrawPosText_Type, - kDrawPosTextH_Type, - kDrawRect_Type, - kDrawSprite_Type, - kDrawText_Type, - kDrawTextOnPath_Type, - kPopLayer_Type, - kPushLayer_Type, - kPushSave_Type - }; - - static bool isTextType(Type t) { - return t == kDrawPosTextH_Type || t == kDrawText_Type; - } - - CommonCheck() : mType(kNo_Type), mAllOpaque(true), mIsOpaque(true) { - setEmpty(); - } - - bool doRect(Type type) { - mType = type; - return doIRect(mUnion); - } - - bool isEmpty() { return mUnion.isEmpty(); } - - bool joinGlyphs(const SkIRect& rect) { - bool isGlyph = mType == kDrawGlyph_Type; - if (isGlyph) - mUnion.join(rect); - return isGlyph; - } - - void setAllOpaque(bool opaque) { mAllOpaque = opaque; } - void setEmpty() { mUnion.setEmpty(); } - void setIsOpaque(bool opaque) { mIsOpaque = opaque; } - void setType(Type type) { mType = type; } - - Type mType; - SkIRect mUnion; - bool mAllOpaque; - bool mIsOpaque; -}; - -#if DEBUG_NAV_UI - static const char* TypeNames[] = { - "kNo_Type", - "kDrawBitmap_Type", - "kDrawGlyph_Type", - "kDrawPaint_Type", - "kDrawPath_Type", - "kDrawPicture_Type", - "kDrawPoints_Type", - "kDrawPosText_Type", - "kDrawPosTextH_Type", - "kDrawRect_Type", - "kDrawSprite_Type", - "kDrawText_Type", - "kDrawTextOnPath_Type", - "kPopLayer_Type", - "kPushLayer_Type", - "kPushSave_Type" - }; -#endif - -#define kMargin 16 -#define kSlop 2 - -class BoundsCanvas : public ParseCanvas { -public: - - BoundsCanvas(CommonCheck* bounder) : mBounder(*bounder) { - mTransparentLayer = 0; - setBounder(bounder); - } - - virtual void drawPaint(const SkPaint& paint) { - mBounder.setType(CommonCheck::kDrawPaint_Type); - INHERITED::drawPaint(paint); - } - - virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], - const SkPaint& paint) { - mBounder.setType(CommonCheck::kDrawPoints_Type); - INHERITED::drawPoints(mode, count, pts, paint); - } - - virtual void drawRect(const SkRect& rect, const SkPaint& paint) { - mBounder.setType(CommonCheck::kDrawRect_Type); - INHERITED::drawRect(rect, paint); - } - - virtual void drawPath(const SkPath& path, const SkPaint& paint) { - mBounder.setType(CommonCheck::kDrawPath_Type); - INHERITED::drawPath(path, paint); - } - - virtual void commonDrawBitmap(const SkBitmap& bitmap, const SkIRect* rect, - const SkMatrix& matrix, const SkPaint& paint) { - mBounder.setType(CommonCheck::kDrawBitmap_Type); - mBounder.setIsOpaque(bitmap.isOpaque()); - INHERITED::commonDrawBitmap(bitmap, rect, matrix, paint); - } - - virtual void drawSprite(const SkBitmap& bitmap, int left, int top, - const SkPaint* paint) { - mBounder.setType(CommonCheck::kDrawSprite_Type); - mBounder.setIsOpaque(bitmap.isOpaque() && - (!paint || paint->getAlpha() == 255)); - 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); - INHERITED::drawText(text, byteLength, x, y, paint); - mBounder.doRect(CommonCheck::kDrawText_Type); - } - - virtual void drawPosText(const void* text, size_t byteLength, - const SkPoint pos[], const SkPaint& paint) { - mBounder.setEmpty(); - mBounder.setType(CommonCheck::kDrawGlyph_Type); - INHERITED::drawPosText(text, byteLength, pos, paint); - if (!mBounder.isEmpty()) - mBounder.doRect(CommonCheck::kDrawPosText_Type); - } - - virtual void drawPosTextH(const void* text, size_t byteLength, - const SkScalar xpos[], SkScalar constY, - const SkPaint& paint) { - mBounder.setEmpty(); - mBounder.setType(CommonCheck::kDrawGlyph_Type); - INHERITED::drawPosTextH(text, byteLength, xpos, constY, paint); - if (mBounder.mUnion.isEmpty()) { - DBG_NAV_LOGD("empty constY=%g", SkScalarToFloat(constY)); - return; - } - SkPaint::FontMetrics metrics; - paint.getFontMetrics(&metrics); - SkPoint upDown[2] = { {xpos[0], constY + metrics.fAscent}, - {xpos[0], constY + metrics.fDescent} }; - const SkMatrix& matrix = getTotalMatrix(); - matrix.mapPoints(upDown, 2); - if (upDown[0].fX == upDown[1].fX) { - mBounder.mUnion.fTop = SkScalarFloor(upDown[0].fY); - mBounder.mUnion.fBottom = SkScalarFloor(upDown[1].fY); - } - mBounder.doRect(CommonCheck::kDrawPosTextH_Type); - } - - virtual void drawTextOnPath(const void* text, size_t byteLength, - const SkPath& path, const SkMatrix* matrix, - const SkPaint& paint) { - mBounder.setEmpty(); - mBounder.setType(CommonCheck::kDrawGlyph_Type); - INHERITED::drawTextOnPath(text, byteLength, path, matrix, paint); - mBounder.doRect(CommonCheck::kDrawTextOnPath_Type); - } - - virtual void drawPicture(SkPicture& picture) { - mBounder.setType(CommonCheck::kDrawPicture_Type); - INHERITED::drawPicture(picture); - } - - virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags) { - int depth = INHERITED::saveLayer(bounds, paint, flags); - if (mTransparentLayer == 0 && paint && paint->getAlpha() < 255) { - mTransparentLayer = depth; - mBounder.setAllOpaque(false); - } - return depth; - } - - virtual void restore() { - mBounder.setType(CommonCheck::kDrawSprite_Type); // for layer draws - int depth = getSaveCount(); - if (depth == mTransparentLayer) { - mTransparentLayer = 0; - mBounder.setAllOpaque(true); - } - INHERITED::restore(); - } - - int mTransparentLayer; - CommonCheck& mBounder; -private: - typedef ParseCanvas INHERITED; -}; - -/* -LeftCheck examines the text in a picture, within a viewable rectangle, -and returns via left() the position of the left edge of the paragraph. -It first looks at the left edge of the test point, then looks above and below -it for more lines of text to determine the div's left edge. -*/ -class LeftCheck : public CommonCheck { -public: - LeftCheck(int x, int y) : mX(x), mY(y), mHitLeft(INT_MAX), - mMostLeft(INT_MAX) { - mHit.set(x - (HIT_SLOP << 1), y - HIT_SLOP, x, y + HIT_SLOP); - mPartial.setEmpty(); - mBounds.setEmpty(); - mPartialType = kNo_Type; - } - - int left() { - if (isTextType(mType)) - doRect(); // process the final line of text - return mMostLeft != INT_MAX ? mMostLeft : mX >> 1; - } - - // FIXME: this is identical to CenterCheck::onIRect() - // refactor so that LeftCheck and CenterCheck inherit common functions - virtual bool onIRect(const SkIRect& rect) { - bool opaqueBitmap = mType == kDrawBitmap_Type && mIsOpaque; - if (opaqueBitmap && rect.contains(mX, mY)) { - mMostLeft = rect.fLeft; - return false; - } - if (joinGlyphs(rect)) // assembles glyphs into a text string - return false; - if (!isTextType(mType) && !opaqueBitmap) - return false; - /* Text on one line may be broken into several parts. Reassemble - the text into a rectangle before considering it. */ - if (rect.fTop < mPartial.fBottom - && rect.fBottom > mPartial.fTop - && mPartial.fRight + JOIN_SLOP_X >= rect.fLeft - && (mPartialType != kDrawBitmap_Type - || mPartial.height() <= rect.height() + JOIN_SLOP_Y)) { - DBG_NAV_LOGD("LeftCheck join mPartial=(%d, %d, %d, %d)" - " rect=(%d, %d, %d, %d)", - mPartial.fLeft, mPartial.fTop, mPartial.fRight, mPartial.fBottom, - rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); - mPartial.join(rect); - return false; - } - if (mPartial.isEmpty() == false) { - doRect(); // process the previous line of text -#if DEBUG_NAV_UI - if (mHitLeft == INT_MAX) - DBG_NAV_LOGD("LeftCheck disabled rect=(%d, %d, %d, %d)", - rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); -#endif - } - mPartial = rect; - mPartialType = mType; - return false; - } - - void doRect() - { - /* Record the outer bounds of the lines of text that intersect the - touch coordinates, given some slop */ - if (SkIRect::Intersects(mPartial, mHit)) { - if (mHitLeft > mPartial.fLeft) - mHitLeft = mPartial.fLeft; - DBG_NAV_LOGD("LeftCheck mHitLeft=%d", mHitLeft); - } else if (mHitLeft == INT_MAX) - return; // wait for intersect success - /* If text is too far away vertically, don't consider it */ - if (!mBounds.isEmpty() && (mPartial.fTop > mBounds.fBottom + HIT_SLOP - || mPartial.fBottom < mBounds.fTop - HIT_SLOP)) { - DBG_NAV_LOGD("LeftCheck stop mPartial=(%d, %d, %d, %d)" - " mBounds=(%d, %d, %d, %d)", - mPartial.fLeft, mPartial.fTop, mPartial.fRight, mPartial.fBottom, - mBounds.fLeft, mBounds.fTop, mBounds.fRight, mBounds.fBottom); - mHitLeft = INT_MAX; // and disable future comparisons - return; - } - /* If the considered text is completely to the left or right of the - touch coordinates, skip it, turn off further detection */ - if (mPartial.fLeft > mX || mPartial.fRight < mX) { - DBG_NAV_LOGD("LeftCheck stop mX=%d mPartial=(%d, %d, %d, %d)", mX, - mPartial.fLeft, mPartial.fTop, mPartial.fRight, mPartial.fBottom); - mHitLeft = INT_MAX; - return; - } - /* record the smallest margins on the left and right */ - if (mMostLeft > mPartial.fLeft) { - DBG_NAV_LOGD("LeftCheck new mMostLeft=%d (old=%d)", mPartial.fLeft, - mMostLeft); - mMostLeft = mPartial.fLeft; - } - if (mBounds.isEmpty()) - mBounds = mPartial; - else if (mPartial.fBottom > mBounds.fBottom) { - DBG_NAV_LOGD("LeftCheck new bottom=%d (old=%d)", mPartial.fBottom, - mBounds.fBottom); - mBounds.fBottom = mPartial.fBottom; - } - } - - static const int JOIN_SLOP_X = 30; // horizontal space between text parts - static const int JOIN_SLOP_Y = 5; // vertical space between text lines - static const int HIT_SLOP = 30; // diameter allowing for tap size - /* const */ SkIRect mHit; // sloppy hit rectangle - SkIRect mBounds; // reference bounds - SkIRect mPartial; // accumulated text bounds, per line - const int mX; // touch location - const int mY; - int mHitLeft; // touched text extremes - int mMostLeft; // paragraph extremes - Type mPartialType; -}; - -/* -CenterCheck examines the text in a picture, within a viewable rectangle, -and returns via center() the optimal amount to scroll in x to display the -paragraph of text. - -The caller of CenterCheck has configured (but not allocated) a bitmap -the height and three times the width of the view. The picture is drawn centered -in the bitmap, so text that would be revealed, if the view was scrolled up to -a view-width to the left or right, is considered. -*/ -class CenterCheck : public CommonCheck { -public: - CenterCheck(int x, int y, int width) : mX(x), mY(y), - mHitLeft(x), mHitRight(x), mMostLeft(INT_MAX), mMostRight(-INT_MAX), - mViewLeft(width), mViewRight(width << 1) { - mHit.set(x - CENTER_SLOP, y - CENTER_SLOP, - x + CENTER_SLOP, y + CENTER_SLOP); - mPartial.setEmpty(); - } - - int center() { - doRect(); // process the final line of text - /* If the touch coordinates aren't near any text, return 0 */ - if (mHitLeft == mHitRight) { - DBG_NAV_LOGD("abort: mHitLeft=%d ==mHitRight", mHitLeft); - return 0; - } - int leftOver = mHitLeft - mViewLeft; - int rightOver = mHitRight - mViewRight; - int center; - /* If the touched text is too large to entirely fit on the screen, - center it. */ - if (leftOver < 0 && rightOver > 0) { - center = (leftOver + rightOver) >> 1; - DBG_NAV_LOGD("overlap: leftOver=%d rightOver=%d center=%d", - leftOver, rightOver, center); - return center; - } - center = (mMostLeft + mMostRight) >> 1; // the paragraph center - if (leftOver > 0 && rightOver >= 0) { // off to the right - if (center > mMostLeft) // move to center loses left-most text? - center = mMostLeft; - } else if (rightOver < 0 && leftOver <= 0) { // off to the left - if (center < mMostRight) // move to center loses right-most text? - center = mMostRight; - } else { -#ifdef DONT_CENTER_IF_ALREADY_VISIBLE - center = 0; // paragraph is already fully visible -#endif - } - DBG_NAV_LOGD("scroll: leftOver=%d rightOver=%d center=%d", - leftOver, rightOver, center); - return center; - } - -protected: - virtual bool onIRect(const SkIRect& rect) { - if (joinGlyphs(rect)) // assembles glyphs into a text string - return false; - if (!isTextType(mType)) - return false; - /* Text on one line may be broken into several parts. Reassemble - the text into a rectangle before considering it. */ - if (rect.fTop < mPartial.fBottom && rect.fBottom > - mPartial.fTop && mPartial.fRight + CENTER_SLOP >= rect.fLeft) { - DBG_NAV_LOGD("join mPartial=(%d, %d, %d, %d) rect=(%d, %d, %d, %d)", - mPartial.fLeft, mPartial.fTop, mPartial.fRight, mPartial.fBottom, - rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); - mPartial.join(rect); - return false; - } - if (mPartial.isEmpty() == false) - doRect(); // process the previous line of text - mPartial = rect; - return false; - } - - void doRect() - { - /* Record the outer bounds of the lines of text that was 'hit' by the - touch coordinates, given some slop */ - if (SkIRect::Intersects(mPartial, mHit)) { - if (mHitLeft > mPartial.fLeft) - mHitLeft = mPartial.fLeft; - if (mHitRight < mPartial.fRight) - mHitRight = mPartial.fRight; - DBG_NAV_LOGD("mHitLeft=%d mHitRight=%d", mHitLeft, mHitRight); - } - /* If the considered text is completely to the left or right of the - touch coordinates, skip it */ - if (mPartial.fLeft > mX || mPartial.fRight < mX) - return; - int leftOver = mPartial.fLeft - mViewLeft; - int rightOver = mPartial.fRight - mViewRight; - /* If leftOver <= 0, the text starts off the screen. - If rightOver >= 0, the text ends off the screen. - */ - if (leftOver <= 0 && rightOver >= 0) // discard wider than screen - return; -#ifdef DONT_CENTER_IF_ALREADY_VISIBLE - if (leftOver > 0 && rightOver < 0) // discard already visible - return; -#endif - /* record the smallest margins on the left and right */ - if (mMostLeft > leftOver) - mMostLeft = leftOver; - if (mMostRight < rightOver) - mMostRight = rightOver; - DBG_NAV_LOGD("leftOver=%d rightOver=%d mMostLeft=%d mMostRight=%d", - leftOver, rightOver, mMostLeft, mMostRight); - } - - static const int CENTER_SLOP = 10; // space between text parts and lines - /* const */ SkIRect mHit; // sloppy hit rectangle - SkIRect mPartial; // accumulated text bounds, per line - const int mX; // touch location - const int mY; - int mHitLeft; // touched text extremes - int mHitRight; - int mMostLeft; // paragraph extremes - int mMostRight; - const int mViewLeft; // middle third of 3x-wide view - const int mViewRight; -}; - -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) - virtual void commonDrawBitmap(const SkBitmap& bitmap, const SkIRect* rect, - const SkMatrix& , const SkPaint& ) { - SkPixelRef* pixelRef = bitmap.pixelRef(); - if (pixelRef != NULL) { - mURI = pixelRef->getURI(); - } - } - -private: - const char* mURI; -}; - -class ImageCheck : public SkBounder { -public: - virtual bool onIRect(const SkIRect& rect) { - return false; - } -}; - -class JiggleCheck : public CommonCheck { -public: - JiggleCheck(int delta, int width) : mDelta(delta), mMaxX(width) { - mMaxJiggle = 0; - mMinX = mMinJiggle = abs(delta); - mMaxWidth = width + mMinX; - } - - int jiggle() { - if (mMinJiggle > mMaxJiggle) - return mDelta; - int avg = (mMinJiggle + mMaxJiggle + 1) >> 1; - return mDelta < 0 ? -avg : avg; - } - - virtual bool onIRect(const SkIRect& rect) { - if (joinGlyphs(rect)) - return false; - if (mType != kDrawBitmap_Type && !isTextType(mType)) - return false; - int min, max; - if (mDelta < 0) { - min = mMinX - rect.fLeft; - max = mMaxWidth - rect.fRight; - } else { - min = rect.fRight - mMaxX; - max = rect.fLeft; - } - if (min <= 0) - return false; - if (max >= mMinX) - return false; - if (mMinJiggle > min) - mMinJiggle = min; - if (mMaxJiggle < max) - mMaxJiggle = max; - return false; - } - - int mDelta; - int mMaxJiggle; - int mMaxX; - int mMinJiggle; - int mMinX; - int mMaxWidth; -}; - -class RingCheck : public CommonCheck { -public: - RingCheck(const WTF::Vector<WebCore::IntRect>& rings, - const WebCore::IntRect& bitBounds, const WebCore::IntRect& testBounds, - bool singleImage) - : mTestBounds(testBounds) - , mBitBounds(bitBounds) - , mPushPop(false) - , mSingleImage(singleImage) - { - const WebCore::IntRect* r; - for (r = rings.begin(); r != rings.end(); r++) { - SkIRect fatter = {r->x(), r->y(), r->maxX(), r->maxY()}; - fatter.inset(-CURSOR_RING_HIT_TEST_RADIUS, -CURSOR_RING_HIT_TEST_RADIUS); - DBG_NAV_LOGD("RingCheck fat=(%d,%d,r=%d,b=%d)", fatter.fLeft, fatter.fTop, - fatter.fRight, fatter.fBottom); - mTextSlop.op(fatter, SkRegion::kUnion_Op); - mTextTest.op(*r, SkRegion::kUnion_Op); - } - int dx = -bitBounds.x(); - int dy = -bitBounds.y(); - DBG_NAV_LOGD("RingCheck translate=(%d,%d)", dx, dy); - mTextSlop.translate(dx, dy); - mTextTest.translate(dx, dy); - mTestBounds.translate(dx, dy); - mEmpty.setEmpty(); - } - - bool hiddenRings(SkRegion* clipped) - { - findBestLayer(); - if (!mBestLayer) { - DBG_NAV_LOG("RingCheck empty"); - clipped->setEmpty(); - return true; - } - const SkRegion* layersEnd = mLayers.end(); - const Type* layerTypes = &mLayerTypes[mBestLayer - mLayers.begin()]; - bool collectGlyphs = true; - bool collectOvers = false; - SkRegion over; - for (const SkRegion* layers = mBestLayer; layers != layersEnd; layers++) { - Type layerType = *layerTypes++; - DBG_NAV_LOGD("RingCheck #%d %s (%d,%d,r=%d,b=%d)", - layers - mLayers.begin(), TypeNames[layerType], - layers->getBounds().fLeft, layers->getBounds().fTop, - layers->getBounds().fRight, layers->getBounds().fBottom); - if (collectGlyphs && (layerType == kDrawGlyph_Type - || ((layerType == kDrawRect_Type && mTextTest.contains(*layers)) - || (layerType == kDrawBitmap_Type && mTextSlop.contains(*layers))))) { - DBG_NAV_LOGD("RingCheck #%d collectOvers", layers - mLayers.begin()); - collectOvers = true; - clipped->op(*layers, SkRegion::kUnion_Op); - continue; - } - collectGlyphs &= layerType != kPushLayer_Type; - if (collectOvers && (layerType == kDrawRect_Type - || layerType == kDrawBitmap_Type - || (!collectGlyphs && layerType == kDrawSprite_Type))) { - DBG_NAV_LOGD("RingCheck #%d over.op", layers - mLayers.begin()); - over.op(*layers, SkRegion::kUnion_Op); - } - } - bool result = !collectOvers || clipped->intersects(over); - const SkIRect t = clipped->getBounds(); - const SkIRect o = over.getBounds(); - clipped->op(over, SkRegion::kDifference_Op); - clipped->translate(mBitBounds.x(), mBitBounds.y()); - const SkIRect c = clipped->getBounds(); - DBG_NAV_LOGD("RingCheck intersects=%s text=(%d,%d,r=%d,b=%d)" - " over=(%d,%d,r=%d,b=%d) clipped=(%d,%d,r=%d,b=%d)", - result ? "true" : "false", - t.fLeft, t.fTop, t.fRight, t.fBottom, - o.fLeft, o.fTop, o.fRight, o.fBottom, - c.fLeft, c.fTop, c.fRight, c.fBottom); - return result; - } - - void push(Type type, const SkIRect& bounds) - { -#if DEBUG_NAV_UI - // this caches the push string and subquently ignores if pushSave - // is immediately followed by popLayer. Push/pop pairs happen - // frequently and just add noise to the log. - static String lastLog; - String currentLog = String("RingCheck append #") - + String::number(mLayers.size()) - + " type=" + TypeNames[type] + " bounds=(" - + String::number(bounds.fLeft) - + "," + String::number(bounds.fTop) + "," - + String::number(bounds.fRight) + "," - + String::number(bounds.fBottom) + ")"; - if (lastLog.length() == 0 || type != kPopLayer_Type) { - if (lastLog.length() != 0) - DBG_NAV_LOGD("%s", lastLog.latin1().data()); - if (type == kPushSave_Type) - lastLog = currentLog; - else - DBG_NAV_LOGD("%s", currentLog.latin1().data()); - } else - lastLog = ""; -#endif - popEmpty(); - mPushPop |= type >= kPopLayer_Type; - if (type == kPopLayer_Type) { - Type last = mLayerTypes.last(); - // remove empty brackets - if (last == kPushLayer_Type || last == kPushSave_Type) { - mLayers.removeLast(); - mLayerTypes.removeLast(); - return; - } - // remove push/pop from push/bitmap/pop - size_t pushIndex = mLayerTypes.size() - 2; - if (last == kDrawBitmap_Type - && mLayerTypes.at(pushIndex) == kPushLayer_Type) { - mLayers.at(pushIndex) = mLayers.last(); - mLayerTypes.at(pushIndex) = kDrawBitmap_Type; - mLayers.removeLast(); - mLayerTypes.removeLast(); - return; - } - // remove non-layer brackets - int stack = 0; - Type* types = mLayerTypes.end(); - while (types != mLayerTypes.begin()) { - Type type = *--types; - if (type == kPopLayer_Type) { - stack++; - continue; - } - if (type != kPushLayer_Type && type != kPushSave_Type) - continue; - if (--stack >= 0) - continue; - if (type == kPushLayer_Type) - break; - int remove = types - mLayerTypes.begin(); - DBG_NAV_LOGD("RingCheck remove=%d mLayers.size=%d" - " mLayerTypes.size=%d", remove, mLayers.size(), - mLayerTypes.size()); - mLayers.remove(remove); - mLayerTypes.remove(remove); - mAppendLikeTypes = false; - return; - } - } - mLayers.append(bounds); - mLayerTypes.append(type); - } - - void startText(const SkPaint& paint) - { - mPaint = &paint; - if (!mLayerTypes.isEmpty() && mLayerTypes.last() == kDrawGlyph_Type - && !mLayers.last().isEmpty()) { - push(kDrawGlyph_Type, mEmpty); - } - } - - bool textOutsideRings() - { - findBestLayer(); - if (!mBestLayer) { - DBG_NAV_LOG("RingCheck empty"); - return false; - } - const SkRegion* layers = mBestLayer; - const Type* layerTypes = &mLayerTypes[layers - mLayers.begin()]; - // back up to include text drawn before the best layer - SkRegion active = SkRegion(mBitBounds); - active.translate(-mBitBounds.x(), -mBitBounds.y()); - while (layers != mLayers.begin()) { - --layers; - Type layerType = *--layerTypes; - DBG_NAV_LOGD("RingCheck #%d %s" - " mTestBounds=(%d,%d,r=%d,b=%d) layers=(%d,%d,r=%d,b=%d)" - " active=(%d,%d,r=%d,b=%d)", - layers - mLayers.begin(), TypeNames[layerType], - mTestBounds.getBounds().fLeft, mTestBounds.getBounds().fTop, - mTestBounds.getBounds().fRight, mTestBounds.getBounds().fBottom, - layers->getBounds().fLeft, layers->getBounds().fTop, - layers->getBounds().fRight, layers->getBounds().fBottom, - active.getBounds().fLeft, active.getBounds().fTop, - active.getBounds().fRight, active.getBounds().fBottom); - if (layerType == kDrawRect_Type || layerType == kDrawBitmap_Type) { - SkRegion temp = *layers; - temp.op(mTestBounds, SkRegion::kIntersect_Op); - active.op(temp, SkRegion::kDifference_Op); - if (active.isEmpty()) { - DBG_NAV_LOGD("RingCheck #%d empty", layers - mLayers.begin()); - break; - } - } else if (layerType == kDrawGlyph_Type) { - SkRegion temp = *layers; - temp.op(active, SkRegion::kIntersect_Op); - if (!mTestBounds.intersects(temp)) - continue; - if (!mTestBounds.contains(temp)) - return false; - } else - break; - } - layers = mBestLayer; - layerTypes = &mLayerTypes[layers - mLayers.begin()]; - bool foundGlyph = false; - bool collectGlyphs = true; - do { - Type layerType = *layerTypes++; - DBG_NAV_LOGD("RingCheck #%d %s mTestBounds=(%d,%d,r=%d,b=%d)" - " layers=(%d,%d,r=%d,b=%d) collects=%s intersects=%s contains=%s", - layers - mLayers.begin(), TypeNames[layerType], - mTestBounds.getBounds().fLeft, mTestBounds.getBounds().fTop, - mTestBounds.getBounds().fRight, mTestBounds.getBounds().fBottom, - layers->getBounds().fLeft, layers->getBounds().fTop, - layers->getBounds().fRight, layers->getBounds().fBottom, - collectGlyphs ? "true" : "false", - mTestBounds.intersects(*layers) ? "true" : "false", - mTextSlop.contains(*layers) ? "true" : "false"); - if (collectGlyphs && layerType == kDrawGlyph_Type) { - if (!mTestBounds.intersects(*layers)) - continue; - if (!mTextSlop.contains(*layers)) - return false; - foundGlyph = true; - } - collectGlyphs &= layerType != kPushLayer_Type; - } while (++layers != mLayers.end()); - DBG_NAV_LOGD("RingCheck foundGlyph=%s", foundGlyph ? "true" : "false"); - return foundGlyph; - } - -protected: - virtual bool onIRect(const SkIRect& rect) - { - joinGlyphs(rect); - if (mType != kDrawGlyph_Type && mType != kDrawRect_Type - && mType != kDrawSprite_Type && mType != kDrawBitmap_Type) - return false; - if (mLayerTypes.isEmpty() || mLayerTypes.last() != mType - || !mAppendLikeTypes || mPushPop || mSingleImage - // if the last and current were not glyphs, - // and the two bounds have a gap between, don't join them -- push - // an empty between them - || (mType != kDrawGlyph_Type && !joinable(rect))) { - push(mType, mEmpty); - } - DBG_NAV_LOGD("RingCheck join %s (%d,%d,r=%d,b=%d) '%c'", - TypeNames[mType], rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, - mCh); - mLayers.last().op(rect, SkRegion::kUnion_Op); - mAppendLikeTypes = true; - mPushPop = false; - return false; - } - - virtual bool onIRectGlyph(const SkIRect& rect, - const SkBounder::GlyphRec& rec) - { - mCh = ' '; - if (mPaint) { - SkUnichar unichar; - SkPaint utfPaint = *mPaint; - utfPaint.setTextEncoding(SkPaint::kUTF16_TextEncoding); - utfPaint.glyphsToUnichars(&rec.fGlyphID, 1, &unichar); - mCh = unichar < 0x7f ? unichar : '?'; - } - return onIRect(rect); - } - -private: - int calcOverlap(SkRegion& testRegion) - { - if (testRegion.isEmpty()) - return INT_MAX; - testRegion.op(mTextTest, SkRegion::kXOR_Op); - SkRegion::Iterator iter(testRegion); - int area = 0; - while (!iter.done()) { - const SkIRect& cr = iter.rect(); - area += cr.width() * cr.height(); - iter.next(); - } - DBG_NAV_LOGD("RingCheck area=%d", area); - return area; - } - - void findBestLayer() - { - popEmpty(); - mBestLayer = 0; - const SkRegion* layers = mLayers.begin(); - const SkRegion* layersEnd = mLayers.end(); - if (layers == layersEnd) { - DBG_NAV_LOG("RingCheck empty"); - return; - } - // find text most like focus rings by xoring found with original - int bestArea = INT_MAX; - const SkRegion* testLayer = 0; - SkRegion testRegion; - const Type* layerTypes = &mLayerTypes[layers - mLayers.begin()]; - for (; layers != mLayers.end(); layers++) { - Type layerType = *layerTypes++; -#if DEBUG_NAV_UI - const SkIRect& gb = layers->getBounds(); - const SkIRect& tb = mTextSlop.getBounds(); - DBG_NAV_LOGD("RingCheck #%d %s mTextSlop=(%d,%d,%d,%d)" - " contains=%s bounds=(%d,%d,%d,%d)", - layers - mLayers.begin(), TypeNames[layerType], - tb.fLeft, tb.fTop, tb.fRight, tb.fBottom, - mTextSlop.contains(*layers) ? "true" : "false", - gb.fLeft, gb.fTop, gb.fRight, gb.fBottom); -#endif - if (((layerType == kDrawGlyph_Type || layerType == kDrawBitmap_Type) - && mTextSlop.contains(*layers)) - || (layerType == kDrawRect_Type - && mTextTest.contains(*layers))) { - if (!testLayer) - testLayer = layers; - testRegion.op(*layers, SkRegion::kUnion_Op); - continue; - } - if (testLayer) { - int area = calcOverlap(testRegion); - if (bestArea > area) { - bestArea = area; - mBestLayer = testLayer; - } - DBG_NAV_LOGD("RingCheck #%d push test=%d best=%d", - layers - mLayers.begin(), testLayer - mLayers.begin(), - mBestLayer ? mBestLayer - mLayers.begin() : -1); - testRegion.setEmpty(); - testLayer = 0; - } - } - if (testLayer && bestArea > calcOverlap(testRegion)) { - DBG_NAV_LOGD("RingCheck last best=%d", testLayer - mLayers.begin()); - mBestLayer = testLayer; - } - } - - bool joinable(const SkIRect& rect) - { - SkRegion region = mLayers.last(); - if (!region.isRect()) - return false; - const SkIRect& bounds1 = region.getBounds(); - int area1 = bounds1.width() * bounds1.height(); - area1 += rect.width() * rect.height(); - region.op(rect, SkRegion::kUnion_Op); - const SkIRect& bounds2 = region.getBounds(); - int area2 = bounds2.width() * bounds2.height(); - return area2 <= area1; - } - - void popEmpty() - { - if (mLayerTypes.size() == 0) - return; - Type last = mLayerTypes.last(); - if (last >= kPopLayer_Type) - return; - const SkRegion& area = mLayers.last(); - if (!area.isEmpty()) - return; - DBG_NAV_LOGD("RingCheck #%d %s", mLayers.size() - 1, TypeNames[last]); - mLayers.removeLast(); - mLayerTypes.removeLast(); - } - - SkRegion mTestBounds; - IntRect mBitBounds; - SkIRect mEmpty; - const SkRegion* mBestLayer; - SkRegion mTextSlop; // outset rects for inclusion test - SkRegion mTextTest; // exact rects for xor area test - Type mLastType; - Vector<SkRegion> mLayers; - Vector<Type> mLayerTypes; - const SkPaint* mPaint; - char mCh; - bool mAppendLikeTypes; - bool mPushPop; - bool mSingleImage; -}; - -class RingCanvas : public BoundsCanvas { -public: - RingCanvas(RingCheck* bounder) - : INHERITED(bounder) - { - } - -protected: - virtual void drawText(const void* text, size_t byteLength, SkScalar x, - SkScalar y, const SkPaint& paint) { - static_cast<RingCheck&>(mBounder).startText(paint); - INHERITED::drawText(text, byteLength, x, y, paint); - } - - virtual void drawPosText(const void* text, size_t byteLength, - const SkPoint pos[], const SkPaint& paint) { - static_cast<RingCheck&>(mBounder).startText(paint); - INHERITED::drawPosText(text, byteLength, pos, paint); - } - - virtual void drawTextOnPath(const void* text, size_t byteLength, - const SkPath& path, const SkMatrix* matrix, - const SkPaint& paint) { - static_cast<RingCheck&>(mBounder).startText(paint); - INHERITED::drawTextOnPath(text, byteLength, path, matrix, paint); - } - - virtual void drawPosTextH(const void* text, size_t byteLength, - const SkScalar xpos[], SkScalar constY, - const SkPaint& paint) { - static_cast<RingCheck&>(mBounder).startText(paint); - INHERITED::drawPosTextH(text, byteLength, xpos, constY, paint); - } - - virtual int save(SaveFlags flags) - { - RingCheck& bounder = static_cast<RingCheck&>(mBounder); - bounder.push(CommonCheck::kPushSave_Type, getTotalClip().getBounds()); - return INHERITED::save(flags); - } - - virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags) - { - RingCheck& bounder = static_cast<RingCheck&>(mBounder); - bounder.push(CommonCheck::kPushLayer_Type, getTotalClip().getBounds()); - return INHERITED::save(flags); - } - - virtual void restore() - { - RingCheck& bounder = static_cast<RingCheck&>(mBounder); - bounder.push(CommonCheck::kPopLayer_Type, getTotalClip().getBounds()); - INHERITED::restore(); - } - -private: - typedef BoundsCanvas INHERITED; -}; - -CachedRoot::CachedRoot() - : mPicture(0) -{ -} - -CachedRoot::~CachedRoot() -{ - SkSafeUnref(mPicture); -} - -bool CachedRoot::adjustForScroll(BestData* best, CachedFrame::Direction direction, - WebCore::IntPoint* scrollPtr, bool findClosest) -{ - WebCore::IntRect newOutset; - const CachedNode* newNode = best->mNode; - // see if there's a middle node - // if the middle node is in the visited list, - // or if none was computed and the newNode is in the visited list, - // treat result as NULL - if (newNode != NULL && findClosest) { - if (best->bounds().intersects(mHistory->mPriorBounds) == false && - checkBetween(best, direction)) - newNode = best->mNode; - if (findClosest && maskIfHidden(best)) { - innerMove(document(), best, direction, scrollPtr, false); - return true; - } - newOutset = newNode->cursorRingBounds(best->mFrame); - } - int delta; - bool newNodeInView = scrollDelta(newOutset, direction, &delta); - if (delta && scrollPtr && (newNode == NULL || newNodeInView == false || - (best->mNavOutside && best->mWorkingOutside))) - *scrollPtr = WebCore::IntPoint(direction & UP_DOWN ? 0 : delta, - direction & UP_DOWN ? delta : 0); - return false; -} - -void CachedRoot::calcBitBounds(const IntRect& nodeBounds, IntRect* bitBounds) const -{ - IntRect contentBounds = IntRect(0, 0, mPicture->width(), mPicture->height()); - IntRect overBounds = nodeBounds; - overBounds.inflate(kMargin); - IntRect viewableBounds = mScrolledBounds; - viewableBounds.unite(mViewBounds); - *bitBounds = contentBounds; - bitBounds->intersect(overBounds); - if (!bitBounds->intersects(viewableBounds)) - *bitBounds = IntRect(0, 0, 0, 0); - DBG_NAV_LOGD("contentBounds=(%d,%d,r=%d,b=%d) overBounds=(%d,%d,r=%d,b=%d)" - " mScrolledBounds=(%d,%d,r=%d,b=%d) mViewBounds=(%d,%d,r=%d,b=%d)" - " bitBounds=(%d,%d,r=%d,b=%d)", - contentBounds.x(), contentBounds.y(), contentBounds.maxX(), - contentBounds.maxY(), - overBounds.x(), overBounds.y(), overBounds.maxX(), overBounds.maxY(), - mScrolledBounds.x(), mScrolledBounds.y(), mScrolledBounds.maxX(), - mScrolledBounds.maxY(), - mViewBounds.x(), mViewBounds.y(), mViewBounds.maxX(), - mViewBounds.maxY(), - bitBounds->x(), bitBounds->y(), bitBounds->maxX(), - bitBounds->maxY()); -} - - -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(¢erCheck); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, width * 3, - mViewBounds.height()); - checker.setBitmapDevice(bitmap); - checker.translate(SkIntToScalar(width - mViewBounds.x()), - SkIntToScalar(-mViewBounds.y())); - checker.drawPicture(*picture); - return centerCheck.center(); -} - -void CachedRoot::checkForJiggle(int* xDeltaPtr) const -{ - int xDelta = *xDeltaPtr; - JiggleCheck jiggleCheck(xDelta, mViewBounds.width()); - BoundsCanvas checker(&jiggleCheck); - SkBitmap bitmap; - int absDelta = abs(xDelta); - bitmap.setConfig(SkBitmap::kARGB_8888_Config, mViewBounds.width() + - absDelta, mViewBounds.height()); - 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(*picture); - *xDeltaPtr = jiggleCheck.jiggle(); -} - -bool CachedRoot::checkRings(SkPicture* picture, const CachedNode* node, - const WebCore::IntRect& testBounds) const -{ - if (!picture) - return false; - const WTF::Vector<WebCore::IntRect>& rings = node->rings(); - const WebCore::IntRect& nodeBounds = node->rawBounds(); - IntRect bitBounds; - calcBitBounds(nodeBounds, &bitBounds); - RingCheck ringCheck(rings, bitBounds, testBounds, node->singleImage()); - RingCanvas checker(&ringCheck); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, bitBounds.width(), - bitBounds.height()); - checker.setBitmapDevice(bitmap); - checker.translate(SkIntToScalar(-bitBounds.x()), - SkIntToScalar(-bitBounds.y())); - checker.drawPicture(*picture); - bool result = ringCheck.textOutsideRings(); - DBG_NAV_LOGD("bitBounds=(%d,%d,r=%d,b=%d) nodeBounds=(%d,%d,r=%d,b=%d)" - " testBounds=(%d,%d,r=%d,b=%d) success=%s", - bitBounds.x(), bitBounds.y(), bitBounds.maxX(), bitBounds.maxY(), - nodeBounds.x(), nodeBounds.y(), nodeBounds.maxX(), nodeBounds.maxY(), - testBounds.x(), testBounds.y(), testBounds.maxX(), testBounds.maxY(), - result ? "true" : "false"); - return result; -} - -const CachedNode* CachedRoot::findAt(const WebCore::IntRect& rect, - const CachedFrame** framePtr, int* x, int* y, bool checkForHidden) const -{ -#if DEBUG_NAV_UI - DBG_NAV_LOGD("rect=(%d,%d,w=%d,h=%d) xy=(%d,%d)", rect.x(), rect.y(), - rect.width(), rect.height(), *x, *y); -#if DUMP_NAV_CACHE - if (mRootLayer) CachedLayer::Debug::printRootLayerAndroid(mRootLayer); -#endif -#endif - int best = INT_MAX; - bool inside = false; - (const_cast<CachedRoot*>(this))->resetClippedOut(); - const CachedFrame* directHitFramePtr; - const CachedNode* directHit = NULL; - const CachedNode* node = findBestAt(rect, &best, &inside, &directHit, - &directHitFramePtr, framePtr, x, y, checkForHidden); - DBG_NAV_LOGD("node=%d (%p) xy=(%d,%d)", node == NULL ? 0 : node->index(), - node == NULL ? NULL : node->nodePointer(), *x, *y); - if (node == NULL) { - node = findBestHitAt(rect, framePtr, x, y); - DBG_NAV_LOGD("node=%d (%p)", node == NULL ? 0 : node->index(), - node == NULL ? NULL : node->nodePointer()); - } - if (node == NULL) { - *framePtr = findBestFrameAt(rect.x() + (rect.width() >> 1), - rect.y() + (rect.height() >> 1)); - } - return node; -} - -WebCore::IntPoint CachedRoot::cursorLocation() const -{ - const WebCore::IntRect& bounds = mHistory->mNavBounds; - return WebCore::IntPoint(bounds.x() + (bounds.width() >> 1), - bounds.y() + (bounds.height() >> 1)); -} - -WebCore::IntPoint CachedRoot::focusLocation() const -{ - return WebCore::IntPoint(mFocusBounds.x() + (mFocusBounds.width() >> 1), - mFocusBounds.y() + (mFocusBounds.height() >> 1)); -} - -// These reset the values because we only want to get the selection the first time. -// After that, the selection is no longer accurate. -int CachedRoot::getAndResetSelectionEnd() -{ - int end = mSelectionEnd; - mSelectionEnd = -1; - return end; -} - -int CachedRoot::getAndResetSelectionStart() -{ - int start = mSelectionStart; - mSelectionStart = -1; - return start; -} - -int CachedRoot::getBlockLeftEdge(int x, int y, float scale) const -{ - DBG_NAV_LOGD("x=%d y=%d scale=%g mViewBounds=(%d,%d,%d,%d)", x, y, scale, - mViewBounds.x(), mViewBounds.y(), mViewBounds.width(), - mViewBounds.height()); - // if (x, y) is in a textArea or textField, return that - const int slop = 1; - WebCore::IntRect rect = WebCore::IntRect(x - slop, y - slop, - slop * 2, slop * 2); - const CachedFrame* frame; - int fx, fy; - const CachedNode* node = findAt(rect, &frame, &fx, &fy, true); - if (node && node->wantsKeyEvents()) { - DBG_NAV_LOGD("x=%d (%s)", node->bounds(frame).x(), - node->isTextInput() ? "text" : "plugin"); - return node->bounds(frame).x(); - } - SkPicture* picture = node ? frame->picture(node, &x, &y) : pictureAt(&x, &y); - if (!picture) - return x; - int halfW = (int) (mViewBounds.width() * scale * 0.5f); - int fullW = halfW << 1; - int halfH = (int) (mViewBounds.height() * scale * 0.5f); - int fullH = halfH << 1; - LeftCheck leftCheck(fullW, halfH); - BoundsCanvas checker(&leftCheck); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, fullW, fullH); - checker.setBitmapDevice(bitmap); - checker.translate(SkIntToScalar(fullW - x), SkIntToScalar(halfH - y)); - checker.drawPicture(*picture); - int result = x + leftCheck.left() - fullW; - DBG_NAV_LOGD("halfW=%d halfH=%d mMostLeft=%d x=%d", - halfW, halfH, leftCheck.mMostLeft, result); - return result; -} - -void CachedRoot::getSimulatedMousePosition(WebCore::IntPoint* point) const -{ -#ifndef NDEBUG - ASSERT(CachedFrame::mDebug.mInUse); -#endif - const WebCore::IntRect& mouseBounds = mHistory->mMouseBounds; - int x = mouseBounds.x(); - int y = mouseBounds.y(); - int width = mouseBounds.width(); - int height = mouseBounds.height(); - point->setX(x + (width >> 1)); // default to box center - point->setY(y + (height >> 1)); -#if DEBUG_NAV_UI - const WebCore::IntRect& navBounds = mHistory->mNavBounds; - DBG_NAV_LOGD("mHistory->mNavBounds={%d,%d,%d,%d} " - "mHistory->mMouseBounds={%d,%d,%d,%d} point={%d,%d}", - navBounds.x(), navBounds.y(), navBounds.width(), navBounds.height(), - mouseBounds.x(), mouseBounds.y(), mouseBounds.width(), - mouseBounds.height(), point->x(), point->y()); -#endif -} - -void CachedRoot::init(WebCore::Frame* frame, CachedHistory* history) -{ - CachedFrame::init(this, -1, frame); - reset(); - mHistory = history; - SkSafeUnref(mPicture); - mPicture = 0; -} - -bool CachedRoot::innerDown(const CachedNode* test, BestData* bestData) const -{ - ASSERT(minWorkingVertical() >= mViewBounds.x()); - ASSERT(maxWorkingVertical() <= mViewBounds.maxX()); - setupScrolledBounds(); - // (line up) - mScrolledBounds.setHeight(mScrolledBounds.height() + mMaxYScroll); - int testTop = mScrolledBounds.y(); - int viewBottom = mViewBounds.maxY(); - const WebCore::IntRect& navBounds = mHistory->mNavBounds; - if (navBounds.isEmpty() == false && - navBounds.maxY() > viewBottom && viewBottom < mContents.height()) - return false; - if (navBounds.isEmpty() == false) { - int navTop = navBounds.y(); - int scrollBottom; - if (testTop < navTop && navTop < (scrollBottom = mScrolledBounds.maxY())) { - mScrolledBounds.setHeight(scrollBottom - navTop); - mScrolledBounds.setY(navTop); - } - } - setCursorCache(0, mMaxYScroll); - frameDown(test, NULL, bestData); - return true; -} - -bool CachedRoot::innerLeft(const CachedNode* test, BestData* bestData) const -{ - ASSERT(minWorkingHorizontal() >= mViewBounds.y()); - ASSERT(maxWorkingHorizontal() <= mViewBounds.maxY()); - setupScrolledBounds(); - mScrolledBounds.setX(mScrolledBounds.x() - mMaxXScroll); - mScrolledBounds.setWidth(mScrolledBounds.width() + mMaxXScroll); - int testRight = mScrolledBounds.maxX(); - int viewLeft = mViewBounds.x(); - const WebCore::IntRect& navBounds = mHistory->mNavBounds; - if (navBounds.isEmpty() == false && - navBounds.x() < viewLeft && viewLeft > mContents.x()) - return false; - if (navBounds.isEmpty() == false) { - int navRight = navBounds.maxX(); - int scrollLeft; - if (testRight > navRight && navRight > (scrollLeft = mScrolledBounds.x())) - mScrolledBounds.setWidth(navRight - scrollLeft); - } - setCursorCache(-mMaxXScroll, 0); - frameLeft(test, NULL, bestData); - return true; -} - - -void CachedRoot::innerMove(const CachedNode* node, BestData* bestData, - Direction direction, WebCore::IntPoint* scroll, bool firstCall) -{ - bestData->reset(); - bool outOfCursor = mCursorIndex == CURSOR_CLEARED; - DBG_NAV_LOGD("mHistory->didFirstLayout()=%s && mCursorIndex=%d", - mHistory->didFirstLayout() ? "true" : "false", mCursorIndex); - if (mHistory->didFirstLayout() && mCursorIndex < CURSOR_SET) { - mHistory->reset(); - outOfCursor = true; - } - const CachedFrame* cursorFrame; - const CachedNode* cursor = currentCursor(&cursorFrame); - mHistory->setWorking(direction, cursorFrame, cursor, mViewBounds); - bool findClosest = false; - if (mScrollOnly == false) { - switch (direction) { - case LEFT: - if (outOfCursor) - mHistory->mNavBounds = WebCore::IntRect(mViewBounds.maxX(), - mViewBounds.y(), 1, mViewBounds.height()); - findClosest = innerLeft(node, bestData); - break; - case RIGHT: - if (outOfCursor) - mHistory->mNavBounds = WebCore::IntRect(mViewBounds.x() - 1, - mViewBounds.y(), 1, mViewBounds.height()); - findClosest = innerRight(node, bestData); - break; - case UP: - if (outOfCursor) - mHistory->mNavBounds = WebCore::IntRect(mViewBounds.x(), - mViewBounds.maxY(), mViewBounds.width(), 1); - findClosest = innerUp(node, bestData); - break; - case DOWN: - if (outOfCursor) - mHistory->mNavBounds = WebCore::IntRect(mViewBounds.x(), - mViewBounds.y() - 1, mViewBounds.width(), 1); - findClosest = innerDown(node, bestData); - break; - case UNINITIALIZED: - default: - ASSERT(0); - } - } - if (firstCall) - mHistory->mPriorBounds = mHistory->mNavBounds; // bounds always advances, even if new node is ultimately NULL - bestData->setMouseBounds(bestData->bounds()); - if (adjustForScroll(bestData, direction, scroll, findClosest)) - return; - if (bestData->mNode != NULL) { - mHistory->addToVisited(bestData->mNode, direction); - mHistory->mNavBounds = bestData->bounds(); - mHistory->mMouseBounds = bestData->mouseBounds(); - } else if (scroll->x() != 0 || scroll->y() != 0) { - WebCore::IntRect newBounds = mHistory->mNavBounds; - int offsetX = scroll->x(); - int offsetY = scroll->y(); - newBounds.move(offsetX, offsetY); - if (mViewBounds.x() > newBounds.x()) - offsetX = mViewBounds.x() - mHistory->mNavBounds.x(); - else if (mViewBounds.maxX() < newBounds.maxX()) - offsetX = mViewBounds.maxX() - mHistory->mNavBounds.maxX(); - if (mViewBounds.y() > newBounds.y()) - offsetY = mViewBounds.y() - mHistory->mNavBounds.y(); - else if (mViewBounds.maxY() < newBounds.maxY()) - offsetY = mViewBounds.maxY() - mHistory->mNavBounds.maxY(); - mHistory->mNavBounds.move(offsetX, offsetY); - } - mHistory->setDidFirstLayout(false); -} - -bool CachedRoot::innerRight(const CachedNode* test, BestData* bestData) const -{ - ASSERT(minWorkingHorizontal() >= mViewBounds.y()); - ASSERT(maxWorkingHorizontal() <= mViewBounds.maxY()); - setupScrolledBounds(); - // (align) - mScrolledBounds.setWidth(mScrolledBounds.width() + mMaxXScroll); - int testLeft = mScrolledBounds.x(); - int viewRight = mViewBounds.maxX(); - const WebCore::IntRect& navBounds = mHistory->mNavBounds; - if (navBounds.isEmpty() == false && - navBounds.maxX() > viewRight && viewRight < mContents.width()) - return false; - if (navBounds.isEmpty() == false) { - int navLeft = navBounds.x(); - int scrollRight; - if (testLeft < navLeft && navLeft < (scrollRight = mScrolledBounds.maxX())) { - mScrolledBounds.setWidth(scrollRight - navLeft); - mScrolledBounds.setX(navLeft); - } - } - setCursorCache(mMaxXScroll, 0); - frameRight(test, NULL, bestData); - return true; -} - -bool CachedRoot::innerUp(const CachedNode* test, BestData* bestData) const -{ - ASSERT(minWorkingVertical() >= mViewBounds.x()); - ASSERT(maxWorkingVertical() <= mViewBounds.maxX()); - setupScrolledBounds(); - mScrolledBounds.setY(mScrolledBounds.y() - mMaxYScroll); - mScrolledBounds.setHeight(mScrolledBounds.height() + mMaxYScroll); - int testBottom = mScrolledBounds.maxY(); - int viewTop = mViewBounds.y(); - const WebCore::IntRect& navBounds = mHistory->mNavBounds; - if (navBounds.isEmpty() == false && - navBounds.y() < viewTop && viewTop > mContents.y()) - return false; - if (navBounds.isEmpty() == false) { - int navBottom = navBounds.maxY(); - int scrollTop; - if (testBottom > navBottom && navBottom > (scrollTop = mScrolledBounds.y())) - mScrolledBounds.setHeight(navBottom - scrollTop); - } - setCursorCache(0, -mMaxYScroll); - frameUp(test, NULL, bestData); - return true; -} - -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(*picture); - DBG_NAV_LOGD("uri=%s", checker.getURI()); - return WTF::String(checker.getURI()); -} - -bool CachedRoot::maskIfHidden(BestData* best) const -{ - const CachedNode* bestNode = best->mNode; - if (bestNode->isUnclipped()) - return false; - const CachedFrame* frame = best->mFrame; - SkPicture* picture = frame->picture(bestNode); - if (picture == NULL) { - DBG_NAV_LOG("missing picture"); - return false; - } - Vector<IntRect> rings; - bestNode->cursorRings(frame, &rings); - const WebCore::IntRect& bounds = bestNode->bounds(frame); - IntRect bitBounds; - calcBitBounds(bounds, &bitBounds); - RingCheck ringCheck(rings, bitBounds, bounds, bestNode->singleImage()); - RingCanvas checker(&ringCheck); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, bitBounds.width(), - bitBounds.height()); - checker.setBitmapDevice(bitmap); - checker.translate(SkIntToScalar(-bitBounds.x()), - SkIntToScalar(-bitBounds.y())); - checker.drawPicture(*picture); - SkRegion clipRgn; - bool clipped = ringCheck.hiddenRings(&clipRgn); - CachedNode* node = const_cast<CachedNode*>(best->mNode); - DBG_NAV_LOGD("clipped=%s clipRgn.isEmpty=%s", clipped ? "true" : "false", - clipRgn.isEmpty() ? "true" : "false"); - if (clipped && clipRgn.isEmpty()) { - node->setDisabled(true); - IntRect clippedBounds = bounds; - clippedBounds.intersect(bitBounds); - node->setClippedOut(clippedBounds != bounds); - return true; - } - // was it partially occluded by later drawing? - // if partially occluded, modify the bounds so that the mouse click has a better x,y - if (clipped) { - DBG_NAV_LOGD("clipped clipRgn={%d,%d,r=%d,b=%d}", - clipRgn.getBounds().fLeft, clipRgn.getBounds().fTop, - clipRgn.getBounds().fRight, clipRgn.getBounds().fBottom); - best->setMouseBounds(clipRgn.getBounds()); - if (!node->clip(best->mouseBounds())) { - node->setDisabled(true); - node->setClippedOut(true); - return true; - } - } else - node->fixUpCursorRects(frame); - return false; -} - -const CachedNode* CachedRoot::moveCursor(Direction direction, const CachedFrame** framePtr, - WebCore::IntPoint* scroll) -{ -#ifndef NDEBUG - ASSERT(CachedFrame::mDebug.mInUse); -#endif - CachedRoot* frame = this; - const CachedNode* node = frame->document(); - if (node == NULL) - return NULL; - if (mViewBounds.isEmpty()) - return NULL; - resetClippedOut(); - setData(); - BestData bestData; - innerMove(node, &bestData, direction, scroll, true); - // if node is partially or fully concealed by layer, scroll it into view - if (mRootLayer && bestData.mNode && !bestData.mNode->isInLayer()) { -#if USE(ACCELERATED_COMPOSITING) -#if DUMP_NAV_CACHE - CachedLayer::Debug::printRootLayerAndroid(mRootLayer); -#endif - SkIRect original = bestData.mNode->cursorRingBounds(bestData.mFrame); - DBG_NAV_LOGD("original=(%d,%d,w=%d,h=%d) scroll=(%d,%d)", - original.fLeft, original.fTop, original.width(), original.height(), - scroll->x(), scroll->y()); - original.offset(-scroll->x(), -scroll->y()); - SkRegion rings(original); - SkTDArray<SkRect> region; - mRootLayer->clipArea(®ion); - SkRegion layers; - for (int index = 0; index < region.count(); index++) { - SkIRect enclosing; - region[index].round(&enclosing); - rings.op(enclosing, SkRegion::kDifference_Op); - layers.op(enclosing, SkRegion::kUnion_Op); - } - SkIRect layerBounds(layers.getBounds()); - SkIRect ringBounds(rings.getBounds()); - int scrollX = scroll->x(); - int scrollY = scroll->y(); - if (rings.getBounds() != original) { - int topOverlap = layerBounds.fBottom - original.fTop; - int bottomOverlap = original.fBottom - layerBounds.fTop; - int leftOverlap = layerBounds.fRight - original.fLeft; - int rightOverlap = original.fRight - layerBounds.fLeft; - if (direction & UP_DOWN) { - if (layerBounds.fLeft < original.fLeft && leftOverlap < 0) - scroll->setX(leftOverlap); - if (original.fRight < layerBounds.fRight && rightOverlap > 0 - && -leftOverlap > rightOverlap) - scroll->setX(rightOverlap); - bool topSet = scrollY > topOverlap && (direction == UP - || !scrollY); - if (topSet) - scroll->setY(topOverlap); - if (scrollY < bottomOverlap && (direction == DOWN || (!scrollY - && (!topSet || -topOverlap > bottomOverlap)))) - scroll->setY(bottomOverlap); - } else { - if (layerBounds.fTop < original.fTop && topOverlap < 0) - scroll->setY(topOverlap); - if (original.fBottom < layerBounds.fBottom && bottomOverlap > 0 - && -topOverlap > bottomOverlap) - scroll->setY(bottomOverlap); - bool leftSet = scrollX > leftOverlap && (direction == LEFT - || !scrollX); - if (leftSet) - scroll->setX(leftOverlap); - if (scrollX < rightOverlap && (direction == RIGHT || (!scrollX - && (!leftSet || -leftOverlap > rightOverlap)))) - scroll->setX(rightOverlap); - } - DBG_NAV_LOGD("rings=(%d,%d,w=%d,h=%d) layers=(%d,%d,w=%d,h=%d)" - " scroll=(%d,%d)", - ringBounds.fLeft, ringBounds.fTop, ringBounds.width(), ringBounds.height(), - layerBounds.fLeft, layerBounds.fTop, layerBounds.width(), layerBounds.height(), - scroll->x(), scroll->y()); - } -#endif - } - *framePtr = bestData.mFrame; - return const_cast<CachedNode*>(bestData.mNode); -} - -const CachedNode* CachedRoot::nextTextField(const CachedNode* start, - const CachedFrame** framePtr) const -{ - bool startFound = false; - return CachedFrame::nextTextField(start, framePtr, &startFound); -} - -SkPicture* CachedRoot::pictureAt(int* xPtr, int* yPtr, int* id) const -{ -#if USE(ACCELERATED_COMPOSITING) - if (mRootLayer) { - 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); - if (picture) { - if (id) - *id = layer->uniqueId(); - return picture; - } - } - } -#endif - DBG_NAV_LOGD("root mPicture=%p (%d,%d)", mPicture, mPicture ? - mPicture->width() : 0, mPicture ? mPicture->height() : 0); - if (id) - *id = -1; - return mPicture; -} - -void CachedRoot::reset() -{ -#ifndef NDEBUG - ASSERT(CachedFrame::mDebug.mInUse); -#endif - mContents = mViewBounds = WebCore::IntRect(0, 0, 0, 0); - mMaxXScroll = mMaxYScroll = 0; - mRootLayer = 0; - mSelectionStart = mSelectionEnd = -1; - mScrollOnly = false; -} - -bool CachedRoot::scrollDelta(WebCore::IntRect& newOutset, Direction direction, int* delta) -{ - switch (direction) { - case LEFT: - *delta = -mMaxXScroll; - return newOutset.x() >= mViewBounds.x(); - case RIGHT: - *delta = mMaxXScroll; - return newOutset.maxX() <= mViewBounds.maxX(); - case UP: - *delta = -mMaxYScroll; - return newOutset.y() >= mViewBounds.y(); - case DOWN: - *delta = mMaxYScroll; - return newOutset.maxY() <= mViewBounds.maxY(); - default: - *delta = 0; - ASSERT(0); - } - return false; -} - -void CachedRoot::setCachedFocus(CachedFrame* frame, CachedNode* node) -{ - mFocusBounds = WebCore::IntRect(0, 0, 0, 0); - if (node == NULL) - return; - node->setIsFocus(true); - mFocusBounds = node->bounds(frame); - frame->setFocusIndex(node - frame->document()); - CachedFrame* parent; - while ((parent = frame->parent()) != NULL) { - parent->setFocusIndex(frame->indexInParent()); - frame = parent; - } -#if DEBUG_NAV_UI - const CachedFrame* focusFrame; - const CachedNode* focus = currentFocus(&focusFrame); - WebCore::IntRect bounds = WebCore::IntRect(0, 0, 0, 0); - if (focus) - bounds = focus->bounds(focusFrame); - DBG_NAV_LOGD("new focus %d (nodePointer=%p) bounds={%d,%d,%d,%d}", - focus ? focus->index() : 0, - focus ? focus->nodePointer() : NULL, bounds.x(), bounds.y(), - bounds.width(), bounds.height()); -#endif -} - -void CachedRoot::setCursor(CachedFrame* frame, CachedNode* node) -{ -#if DEBUG_NAV_UI - const CachedFrame* cursorFrame; - const CachedNode* cursor = currentCursor(&cursorFrame); - WebCore::IntRect bounds; - if (cursor) - bounds = cursor->bounds(cursorFrame); - DBG_NAV_LOGD("old cursor %d (nodePointer=%p) bounds={%d,%d,%d,%d}", - cursor ? cursor->index() : 0, - cursor ? cursor->nodePointer() : NULL, bounds.x(), bounds.y(), - bounds.width(), bounds.height()); -#endif - clearCursor(); - if (node == NULL) - return; - node->setIsCursor(true); - node->show(); - frame->setCursorIndex(node - frame->document()); - CachedFrame* parent; - while ((parent = frame->parent()) != NULL) { - parent->setCursorIndex(frame->indexInParent()); - frame = parent; - } -#if DEBUG_NAV_UI - cursor = currentCursor(&cursorFrame); - bounds = WebCore::IntRect(0, 0, 0, 0); - if (cursor) - bounds = cursor->bounds(cursorFrame); - DBG_NAV_LOGD("new cursor %d (nodePointer=%p) bounds={%d,%d,%d,%d}", - cursor ? cursor->index() : 0, - cursor ? cursor->nodePointer() : NULL, bounds.x(), bounds.y(), - bounds.width(), bounds.height()); -#endif -} - -void CachedRoot::setCursorCache(int scrollX, int scrollY) const -{ - mCursor = currentCursor(); - if (mCursor) - mCursorBounds = mCursor->bounds(this); - if (!mRootLayer) - return; - SkRegion baseScrolled(mScrolledBounds); - mBaseUncovered = SkRegion(mScrolledBounds); -#if USE(ACCELERATED_COMPOSITING) -#if DUMP_NAV_CACHE - CachedLayer::Debug::printRootLayerAndroid(mRootLayer); -#endif - SkTDArray<SkRect> region; - mRootLayer->clipArea(®ion); - WebCore::IntSize offset( - copysign(min(max(0, mContents.width() - mScrolledBounds.width()), - abs(scrollX)), scrollX), - copysign(min(max(0, mContents.height() - mScrolledBounds.height()), - abs(scrollY)), scrollY)); - bool hasOffset = offset.width() || offset.height(); - // restrict scrollBounds to that which is not under layer - for (int index = 0; index < region.count(); index++) { - SkIRect less; - region[index].round(&less); - DBG_NAV_LOGD("less=(%d,%d,w=%d,h=%d)", less.fLeft, less.fTop, - less.width(), less.height()); - mBaseUncovered.op(less, SkRegion::kDifference_Op); - if (!hasOffset) - continue; - less.offset(offset.width(), offset.height()); - baseScrolled.op(less, SkRegion::kDifference_Op); - } - if (hasOffset) - mBaseUncovered.op(baseScrolled, SkRegion::kUnion_Op); -#endif -} - -#if DUMP_NAV_CACHE - -#define DEBUG_PRINT_BOOL(field) \ - DUMP_NAV_LOGD("// bool " #field "=%s;\n", b->field ? "true" : "false") - -#define DEBUG_PRINT_RECT(field) \ - { const WebCore::IntRect& r = b->field; \ - DUMP_NAV_LOGD("// IntRect " #field "={%d, %d, %d, %d};\n", \ - r.x(), r.y(), r.width(), r.height()); } - -CachedRoot* CachedRoot::Debug::base() const { - CachedRoot* nav = (CachedRoot*) ((char*) this - OFFSETOF(CachedRoot, mDebug)); - return nav; -} - -void CachedRoot::Debug::print() const -{ -#ifdef DUMP_NAV_CACHE_USING_PRINTF - gWriteLogMutex.lock(); - ASSERT(gNavCacheLogFile == NULL); - gNavCacheLogFile = fopen(NAV_CACHE_LOG_FILE, "a"); -#endif - CachedRoot* b = base(); - b->CachedFrame::mDebug.print(); - b->mHistory->mDebug.print(b); - DUMP_NAV_LOGD("// int mMaxXScroll=%d, mMaxYScroll=%d;\n", - b->mMaxXScroll, b->mMaxYScroll); - if (b->mRootLayer) - CachedLayer::Debug::printRootLayerAndroid(b->mRootLayer); -#ifdef DUMP_NAV_CACHE_USING_PRINTF - if (gNavCacheLogFile) - fclose(gNavCacheLogFile); - gNavCacheLogFile = NULL; - gWriteLogMutex.unlock(); -#endif -} - -#endif - -} diff --git a/Source/WebKit/android/nav/CachedRoot.h b/Source/WebKit/android/nav/CachedRoot.h deleted file mode 100644 index 362d95b..0000000 --- a/Source/WebKit/android/nav/CachedRoot.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2007, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CachedRoot_h -#define CachedRoot_h - -#include "CachedFrame.h" -#include "IntRect.h" -#include "SkPicture.h" -#include "SkRegion.h" -#include "wtf/Vector.h" - -class SkRect; - -namespace WebCore { - class LayerAndroid; -} - -namespace android { - -class CachedHistory; -class CachedNode; - -class CachedRoot : public CachedFrame { -public: - CachedRoot(); - ~CachedRoot(); - bool adjustForScroll(BestData* , Direction , WebCore::IntPoint* scrollPtr, - bool findClosest); - const SkRegion& baseUncovered() const { return mBaseUncovered; } - void calcBitBounds(const IntRect& , IntRect* ) const; - int checkForCenter(int x, int y) const; - void checkForJiggle(int* ) const; - bool checkRings(SkPicture* , const CachedNode* , - const WebCore::IntRect& testBounds) const; - WebCore::IntPoint cursorLocation() const; - int documentHeight() { return mContents.height(); } - int documentWidth() { return mContents.width(); } - const CachedNode* findAt(const WebCore::IntRect& , const CachedFrame** , - int* x, int* y, bool checkForHidden) const; - const WebCore::IntRect& focusBounds() const { return mFocusBounds; } - WebCore::IntPoint focusLocation() const; - int getAndResetSelectionEnd(); - int getAndResetSelectionStart(); - int getBlockLeftEdge(int x, int y, float scale) const; - void getSimulatedMousePosition(WebCore::IntPoint* ) const; - void init(WebCore::Frame* , CachedHistory* ); - bool innerDown(const CachedNode* , BestData* ) const; - bool innerLeft(const CachedNode* , BestData* ) const; - void innerMove(const CachedNode* ,BestData* bestData, Direction , - WebCore::IntPoint* scroll, bool firstCall); - bool innerRight(const CachedNode* , BestData* ) const; - bool innerUp(const CachedNode* , BestData* ) const; - WTF::String imageURI(int x, int y) const; - bool maskIfHidden(BestData* ) const; - const CachedNode* moveCursor(Direction , const CachedFrame** , WebCore::IntPoint* scroll); - /** - * Find the next textfield/textarea - * @param start The textfield/textarea to search from. - * @param framePtr If non-zero, returns CachedFrame* containing result. - * @return CachedNode* Next textfield/textarea or null (0) if none. - */ - const CachedNode* nextTextField(const CachedNode* start, - const CachedFrame** framePtr) const; - SkPicture* pictureAt(int* xPtr, int* yPtr, int* id) const; - SkPicture* pictureAt(int* xPtr, int* yPtr) const { - return pictureAt(xPtr, yPtr, 0); } - void reset(); - CachedHistory* rootHistory() const { return mHistory; } - WebCore::LayerAndroid* rootLayer() const { return mRootLayer; } - bool scrollDelta(WebCore::IntRect& cursorRingBounds, Direction , int* delta); - const WebCore::IntRect& scrolledBounds() const { return mScrolledBounds; } - void setCursor(CachedFrame* , CachedNode* ); - void setCursorCache(int scrollX, int scrollY) const; // compute cached state used to find next cursor - void setCachedFocus(CachedFrame* , CachedNode* ); - void setFocusBounds(const WebCore::IntRect& r) { mFocusBounds = r; } - void setTextGeneration(int textGeneration) { mTextGeneration = textGeneration; } - void setMaxScroll(int x, int y) { mMaxXScroll = x; mMaxYScroll = y; } - void setPicture(SkPicture* picture) { - SkSafeRef(picture); - SkSafeUnref(mPicture); - mPicture = picture; - } - void setRootLayer(WebCore::LayerAndroid* layer) { - mRootLayer = layer; - resetLayers(); - } - void setScrollOnly(bool state) { mScrollOnly = state; } - void setSelection(int start, int end) { mSelectionStart = start; mSelectionEnd = end; } - void setupScrolledBounds() const { mScrolledBounds = mViewBounds; } - void setVisibleRect(const WebCore::IntRect& r) { mViewBounds = r; } - int textGeneration() const { return mTextGeneration; } - int width() const { return mPicture ? mPicture->width() : 0; } -private: - friend class CachedFrame; - CachedHistory* mHistory; - SkPicture* mPicture; - WebCore::LayerAndroid* mRootLayer; - WebCore::IntRect mFocusBounds; // dom text input focus node bounds - mutable WebCore::IntRect mScrolledBounds; // view bounds + amount visible as result of scroll - int mTextGeneration; - int mMaxXScroll; - int mMaxYScroll; - // These two are ONLY used when the tree is rebuilt and the focus is a textfield/area - int mSelectionStart; - int mSelectionEnd; - // these four set up as cache for use by frameDown/Up/Left/Right etc - mutable WebCore::IntRect mCursorBounds; - mutable const CachedNode* mCursor; - mutable SkRegion mBaseUncovered; - bool mScrollOnly; -#if DUMP_NAV_CACHE -public: - class Debug { -public: - CachedRoot* base() const; - void print() const; - } mDebug; -#endif -}; - -} - -#endif diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index 162d6bd..4a172ea 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -30,9 +30,6 @@ #include "AndroidAnimation.h" #include "AndroidLog.h" #include "BaseLayerAndroid.h" -#include "CachedFrame.h" -#include "CachedNode.h" -#include "CachedRoot.h" #include "DrawExtra.h" #include "Frame.h" #include "GraphicsJNI.h" @@ -187,7 +184,6 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl, WTF::String drawableDir, env->SetIntField(javaWebView, gWebViewField, (jint)this); m_viewImpl = (WebViewCore*) viewImpl; - m_frameCacheUI = 0; m_generation = 0; m_heightCanMeasure = false; m_lastDx = 0; @@ -214,7 +210,6 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl, WTF::String drawableDir, // deallocated base layer. stopGL(); #endif - delete m_frameCacheUI; SkSafeUnref(m_baseLayer); delete m_glDrawFunctor; for (int i = 0; i < DRAW_EXTRAS_SIZE; i++) @@ -240,45 +235,6 @@ WebViewCore* getWebViewCore() const { return m_viewImpl; } -// removes the cursor altogether (e.g., when going to a new page) -void clearCursor() -{ - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) - return; - DBG_NAV_LOG(""); - m_viewImpl->m_hasCursorBounds = false; - root->clearCursor(); - viewInvalidate(); -} - -// leaves the cursor where it is, but suppresses drawing it -void hideCursor() -{ - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) - return; - DBG_NAV_LOG(""); - hideCursor(root); - viewInvalidate(); -} - -void hideCursor(CachedRoot* root) -{ - DBG_NAV_LOG("inner"); - m_viewImpl->m_hasCursorBounds = false; - root->hideCursor(); -} - -#if DUMP_NAV_CACHE -void debugDump() -{ - CachedRoot* root = getFrameCache(DontAllowNewer); - if (root) - root->mDebug.print(); -} -#endif - void scrollRectOnScreen(const IntRect& rect) { if (rect.isEmpty()) @@ -401,157 +357,6 @@ PictureSet* draw(SkCanvas* canvas, SkColor bgColor, DrawExtras extras, bool spli return ret; } - -bool cursorIsTextInput(FrameCachePermission allowNewer) -{ - CachedRoot* root = getFrameCache(allowNewer); - if (!root) { - DBG_NAV_LOG("!root"); - return false; - } - const CachedNode* cursor = root->currentCursor(); - if (!cursor) { - DBG_NAV_LOG("!cursor"); - return false; - } - DBG_NAV_LOGD("%s", cursor->isTextInput() ? "true" : "false"); - return cursor->isTextInput(); -} - -void cursorRingBounds(WebCore::IntRect* bounds) -{ - DBG_NAV_LOGD("%s", ""); - CachedRoot* root = getFrameCache(DontAllowNewer); - if (root) { - const CachedFrame* cachedFrame; - const CachedNode* cachedNode = root->currentCursor(&cachedFrame); - if (cachedNode) { - *bounds = cachedNode->cursorRingBounds(cachedFrame); - DBG_NAV_LOGD("bounds={%d,%d,%d,%d}", bounds->x(), bounds->y(), - bounds->width(), bounds->height()); - return; - } - } - *bounds = WebCore::IntRect(0, 0, 0, 0); -} - -void fixCursor() -{ - m_viewImpl->gCursorBoundsMutex.lock(); - bool hasCursorBounds = m_viewImpl->m_hasCursorBounds; - IntRect bounds = m_viewImpl->m_cursorBounds; - m_viewImpl->gCursorBoundsMutex.unlock(); - if (!hasCursorBounds) - return; - int x, y; - const CachedFrame* frame; - const CachedNode* node = m_frameCacheUI->findAt(bounds, &frame, &x, &y, true); - if (!node) - return; - // require that node have approximately the same bounds (+/- 4) and the same - // center (+/- 2) - IntPoint oldCenter = IntPoint(bounds.x() + (bounds.width() >> 1), - bounds.y() + (bounds.height() >> 1)); - IntRect newBounds = node->bounds(frame); - IntPoint newCenter = IntPoint(newBounds.x() + (newBounds.width() >> 1), - newBounds.y() + (newBounds.height() >> 1)); - DBG_NAV_LOGD("oldCenter=(%d,%d) newCenter=(%d,%d)" - " bounds=(%d,%d,w=%d,h=%d) newBounds=(%d,%d,w=%d,h=%d)", - oldCenter.x(), oldCenter.y(), newCenter.x(), newCenter.y(), - bounds.x(), bounds.y(), bounds.width(), bounds.height(), - newBounds.x(), newBounds.y(), newBounds.width(), newBounds.height()); - if (abs(oldCenter.x() - newCenter.x()) > 2) - return; - if (abs(oldCenter.y() - newCenter.y()) > 2) - return; - if (abs(bounds.x() - newBounds.x()) > 4) - return; - if (abs(bounds.y() - newBounds.y()) > 4) - return; - if (abs(bounds.maxX() - newBounds.maxX()) > 4) - return; - if (abs(bounds.maxY() - newBounds.maxY()) > 4) - return; - DBG_NAV_LOGD("node=%p frame=%p x=%d y=%d bounds=(%d,%d,w=%d,h=%d)", - node, frame, x, y, bounds.x(), bounds.y(), bounds.width(), - bounds.height()); - m_frameCacheUI->setCursor(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(node)); -} - -CachedRoot* getFrameCache(FrameCachePermission allowNewer) -{ - if (!m_viewImpl->m_updatedFrameCache) { - DBG_NAV_LOGV("%s", "!m_viewImpl->m_updatedFrameCache"); - return m_frameCacheUI; - } - if (allowNewer == DontAllowNewer && m_viewImpl->m_lastGeneration < m_generation) { - DBG_NAV_LOGD("allowNewer==DontAllowNewer m_viewImpl->m_lastGeneration=%d" - " < m_generation=%d", m_viewImpl->m_lastGeneration, m_generation); - return m_frameCacheUI; - } - DBG_NAV_LOGD("%s", "m_viewImpl->m_updatedFrameCache == true"); - const CachedFrame* oldCursorFrame; - const CachedNode* oldCursorNode = m_frameCacheUI ? - m_frameCacheUI->currentCursor(&oldCursorFrame) : 0; -#if USE(ACCELERATED_COMPOSITING) - int layerId = -1; - if (oldCursorNode && oldCursorNode->isInLayer()) { - const LayerAndroid* cursorLayer = oldCursorFrame->layer(oldCursorNode) - ->layer(m_frameCacheUI->rootLayer()); - if (cursorLayer) - layerId = cursorLayer->uniqueId(); - } -#endif - // get id from old layer and use to find new layer - bool oldFocusIsTextInput = false; - void* oldFocusNodePointer = 0; - if (m_frameCacheUI) { - const CachedNode* oldFocus = m_frameCacheUI->currentFocus(); - if (oldFocus) { - oldFocusIsTextInput = oldFocus->isTextInput(); - oldFocusNodePointer = oldFocus->nodePointer(); - } - } - m_viewImpl->gFrameCacheMutex.lock(); - delete m_frameCacheUI; - m_viewImpl->m_updatedFrameCache = false; - m_frameCacheUI = m_viewImpl->m_frameCacheKit; - m_viewImpl->m_frameCacheKit = 0; - m_viewImpl->gFrameCacheMutex.unlock(); - if (m_frameCacheUI) - m_frameCacheUI->setRootLayer(compositeRoot()); -#if USE(ACCELERATED_COMPOSITING) - if (layerId >= 0) { - LayerAndroid* layer = const_cast<LayerAndroid*>( - m_frameCacheUI->rootLayer()); - if (layer) { - layer->updateFixedLayersPositions(m_visibleRect); - layer->updatePositions(); - } - } -#endif - fixCursor(); - if (oldFocusIsTextInput) { - const CachedNode* newFocus = m_frameCacheUI->currentFocus(); - if (newFocus && oldFocusNodePointer != newFocus->nodePointer() - && newFocus->isTextInput() - && newFocus != m_frameCacheUI->currentCursor()) { - // The focus has changed. We may need to update things. - ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject javaObject = m_javaGlue.object(env); - if (javaObject.get()) { - env->CallVoidMethod(javaObject.get(), m_javaGlue.m_domChangedFocus); - checkException(env); - } - } - } - if (oldCursorNode && (!m_frameCacheUI || !m_frameCacheUI->currentCursor())) - viewInvalidate(); // redraw in case cursor ring is still visible - return m_frameCacheUI; -} - int getScaledMaxXScroll() { ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); @@ -599,243 +404,9 @@ IntRect getVisibleRect() return rect; } -static CachedFrame::Direction KeyToDirection(int32_t keyCode) -{ - switch (keyCode) { - case AKEYCODE_DPAD_RIGHT: - DBG_NAV_LOGD("keyCode=%s", "right"); - return CachedFrame::RIGHT; - case AKEYCODE_DPAD_LEFT: - DBG_NAV_LOGD("keyCode=%s", "left"); - return CachedFrame::LEFT; - case AKEYCODE_DPAD_DOWN: - DBG_NAV_LOGD("keyCode=%s", "down"); - return CachedFrame::DOWN; - case AKEYCODE_DPAD_UP: - DBG_NAV_LOGD("keyCode=%s", "up"); - return CachedFrame::UP; - default: - DBG_NAV_LOGD("bad key %d sent", keyCode); - return CachedFrame::UNINITIALIZED; - } -} - -WTF::String imageURI(int x, int y) -{ - const CachedRoot* root = getFrameCache(DontAllowNewer); - return root ? root->imageURI(x, y) : WTF::String(); -} - -bool cursorWantsKeyEvents() -{ - const CachedRoot* root = getFrameCache(DontAllowNewer); - if (root) { - const CachedNode* focus = root->currentCursor(); - if (focus) - return focus->wantsKeyEvents(); - } - return false; -} - - -/* returns true if the key had no effect (neither scrolled nor changed cursor) */ -bool moveCursor(int keyCode, int count, bool ignoreScroll) -{ - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) { - DBG_NAV_LOG("!root"); - return true; - } - - m_viewImpl->m_moveGeneration++; - CachedFrame::Direction direction = KeyToDirection(keyCode); - const CachedFrame* cachedFrame, * oldFrame = 0; - const CachedNode* cursor = root->currentCursor(&oldFrame); - WebCore::IntPoint cursorLocation = root->cursorLocation(); - DBG_NAV_LOGD("old cursor %d (nativeNode=%p) cursorLocation={%d, %d}", - cursor ? cursor->index() : 0, - cursor ? cursor->nodePointer() : 0, cursorLocation.x(), cursorLocation.y()); - WebCore::IntRect visibleRect = setVisibleRect(root); - int xMax = getScaledMaxXScroll(); - int yMax = getScaledMaxYScroll(); - root->setMaxScroll(xMax, yMax); - const CachedNode* cachedNode = 0; - int dx = 0; - int dy = 0; - int counter = count; - while (--counter >= 0) { - WebCore::IntPoint scroll = WebCore::IntPoint(0, 0); - cachedNode = root->moveCursor(direction, &cachedFrame, &scroll); - dx += scroll.x(); - dy += scroll.y(); - } - DBG_NAV_LOGD("new cursor %d (nativeNode=%p) cursorLocation={%d, %d}" - "bounds={%d,%d,w=%d,h=%d}", cachedNode ? cachedNode->index() : 0, - cachedNode ? cachedNode->nodePointer() : 0, - root->cursorLocation().x(), root->cursorLocation().y(), - cachedNode ? cachedNode->bounds(cachedFrame).x() : 0, - cachedNode ? cachedNode->bounds(cachedFrame).y() : 0, - cachedNode ? cachedNode->bounds(cachedFrame).width() : 0, - cachedNode ? cachedNode->bounds(cachedFrame).height() : 0); - // If !m_heightCanMeasure (such as in the browser), we want to scroll no - // matter what - if (!ignoreScroll && (!m_heightCanMeasure || - !cachedNode || - (cursor && cursor->nodePointer() == cachedNode->nodePointer()))) - { - if (count == 1 && dx != 0 && dy == 0 && -m_lastDx == dx && - SkTime::GetMSecs() - m_lastDxTime < 1000) - root->checkForJiggle(&dx); - DBG_NAV_LOGD("scrollBy %d,%d", dx, dy); - if ((dx | dy)) - this->scrollBy(dx, dy); - m_lastDx = dx; - m_lastDxTime = SkTime::GetMSecs(); - } - bool result = false; - if (cachedNode) { - m_viewImpl->updateCursorBounds(root, cachedFrame, cachedNode); - root->setCursor(const_cast<CachedFrame*>(cachedFrame), - const_cast<CachedNode*>(cachedNode)); - const CachedNode* focus = root->currentFocus(); - bool clearTextEntry = cachedNode != focus && focus - && cachedNode->nodePointer() != focus->nodePointer() && focus->isTextInput(); - // Stop painting the caret if the old focus was a text input and so is the new cursor. - bool stopPaintingCaret = clearTextEntry && cachedNode->wantsKeyEvents(); - sendMoveMouseIfLatest(clearTextEntry, stopPaintingCaret); - } else { - int docHeight = root->documentHeight(); - int docWidth = root->documentWidth(); - if (visibleRect.maxY() + dy > docHeight) - dy = docHeight - visibleRect.maxY(); - else if (visibleRect.y() + dy < 0) - dy = -visibleRect.y(); - if (visibleRect.maxX() + dx > docWidth) - dx = docWidth - visibleRect.maxX(); - else if (visibleRect.x() < 0) - dx = -visibleRect.x(); - result = direction == CachedFrame::LEFT ? dx >= 0 : - direction == CachedFrame::RIGHT ? dx <= 0 : - direction == CachedFrame::UP ? dy >= 0 : dy <= 0; - } - return result; -} - void notifyProgressFinished() { - DBG_NAV_LOGD("cursorIsTextInput=%d", cursorIsTextInput(DontAllowNewer)); rebuildWebTextView(); -#if DEBUG_NAV_UI - if (m_frameCacheUI) { - const CachedNode* focus = m_frameCacheUI->currentFocus(); - DBG_NAV_LOGD("focus %d (nativeNode=%p)", - focus ? focus->index() : 0, - focus ? focus->nodePointer() : 0); - } -#endif -} - -const CachedNode* findAt(CachedRoot* root, const WebCore::IntRect& rect, - const CachedFrame** framePtr, int* rxPtr, int* ryPtr) -{ - *rxPtr = 0; - *ryPtr = 0; - *framePtr = 0; - if (!root) - return 0; - setVisibleRect(root); - return root->findAt(rect, framePtr, rxPtr, ryPtr, true); -} - -IntRect setVisibleRect(CachedRoot* root) -{ - IntRect visibleRect = getVisibleRect(); - DBG_NAV_LOGD("getVisibleRect %d,%d,%d,%d", - visibleRect.x(), visibleRect.y(), visibleRect.width(), visibleRect.height()); - root->setVisibleRect(visibleRect); - return visibleRect; -} - -void selectBestAt(const WebCore::IntRect& rect) -{ - const CachedFrame* frame; - int rx, ry; - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) - return; - const CachedNode* node = findAt(root, rect, &frame, &rx, &ry); - if (!node) { - DBG_NAV_LOGD("no nodes found root=%p", root); - root->rootHistory()->setMouseBounds(rect); - m_viewImpl->m_hasCursorBounds = false; - root->setCursor(0, 0); - viewInvalidate(); - } else { - DBG_NAV_LOGD("CachedNode:%p (%d)", node, node->index()); - WebCore::IntRect bounds = node->bounds(frame); - root->rootHistory()->setMouseBounds(bounds); - m_viewImpl->updateCursorBounds(root, frame, node); - root->setCursor(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(node)); - } - sendMoveMouseIfLatest(false, false); -} - -const CachedNode* m_cacheHitNode; -const CachedFrame* m_cacheHitFrame; - -bool pointInNavCache(int x, int y, int slop) -{ - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) - return false; - IntRect rect = IntRect(x - slop, y - slop, slop * 2, slop * 2); - int rx, ry; - return (m_cacheHitNode = findAt(root, rect, &m_cacheHitFrame, &rx, &ry)); -} - -bool motionUp(int x, int y, int slop) -{ - bool pageScrolled = false; - IntRect rect = IntRect(x - slop, y - slop, slop * 2, slop * 2); - int rx, ry; - CachedRoot* root = getFrameCache(AllowNewer); - if (!root) - return 0; - const CachedFrame* frame = 0; - const CachedNode* result = findAt(root, rect, &frame, &rx, &ry); - CachedHistory* history = root->rootHistory(); - if (!result) { - DBG_NAV_LOGD("no nodes found root=%p", root); - history->setNavBounds(rect); - m_viewImpl->m_hasCursorBounds = false; - root->hideCursor(); - int dx = root->checkForCenter(x, y); - if (dx) { - scrollBy(dx, 0); - pageScrolled = true; - } - sendMotionUp(frame ? (WebCore::Frame*) frame->framePointer() : 0, - 0, x, y); - viewInvalidate(); - return pageScrolled; - } - DBG_NAV_LOGD("CachedNode:%p (%d) x=%d y=%d rx=%d ry=%d", result, - result->index(), x, y, rx, ry); - WebCore::IntRect navBounds = WebCore::IntRect(rx, ry, 1, 1); - history->setNavBounds(navBounds); - history->setMouseBounds(navBounds); - m_viewImpl->updateCursorBounds(root, frame, result); - root->setCursor(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(result)); - if (result->isSyntheticLink()) - overrideUrlLoading(result->getExport()); - else { - sendMotionUp( - (WebCore::Frame*) frame->framePointer(), - (WebCore::Node*) result->nodePointer(), rx, ry); - } - return pageScrolled; } #if USE(ACCELERATED_COMPOSITING) @@ -896,14 +467,6 @@ void scrollLayer(int layerId, int x, int y) m_glWebViewState->scrollLayer(layerId, x, y); } -int getBlockLeftEdge(int x, int y, float scale) -{ - CachedRoot* root = getFrameCache(AllowNewer); - if (root) - return root->getBlockLeftEdge(x, y, scale); - return -1; -} - void overrideUrlLoading(const WTF::String& url) { JNIEnv* env = JSC::Bindings::getJNIEnv(); @@ -917,7 +480,6 @@ void overrideUrlLoading(const WTF::String& url) void setFindIsUp(bool up) { - DBG_NAV_LOGD("up=%d", up); m_viewImpl->m_findIsUp = up; } @@ -937,7 +499,6 @@ String getSelection() void sendMoveFocus(WebCore::Frame* framePtr, WebCore::Node* nodePtr) { - DBG_NAV_LOGD("framePtr=%p nodePtr=%p", framePtr, nodePtr); JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject javaObject = m_javaGlue.object(env); if (!javaObject.get()) @@ -948,7 +509,6 @@ void sendMoveFocus(WebCore::Frame* framePtr, WebCore::Node* nodePtr) void sendMoveMouse(WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int y) { - DBG_NAV_LOGD("framePtr=%p nodePtr=%p x=%d y=%d", framePtr, nodePtr, x, y); JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject javaObject = m_javaGlue.object(env); if (!javaObject.get()) @@ -970,7 +530,6 @@ void sendMoveMouseIfLatest(bool clearTextEntry, bool stopPaintingCaret) void sendMotionUp(WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int y) { - DBG_NAV_LOGD("m_generation=%d framePtr=%p nodePtr=%p x=%d y=%d", m_generation, framePtr, nodePtr, x, y); ALOG_ASSERT(m_javaGlue.m_obj, "A WebView was not associated with this WebViewNative!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); @@ -1003,34 +562,6 @@ void setIsScrolling(bool isScrolling) #endif } -bool hasCursorNode() -{ - CachedRoot* root = getFrameCache(DontAllowNewer); - if (!root) { - DBG_NAV_LOG("!root"); - return false; - } - const CachedNode* cursorNode = root->currentCursor(); - DBG_NAV_LOGD("cursorNode=%d (nodePointer=%p)", - cursorNode ? cursorNode->index() : -1, - cursorNode ? cursorNode->nodePointer() : 0); - return cursorNode; -} - -bool hasFocusNode() -{ - CachedRoot* root = getFrameCache(DontAllowNewer); - if (!root) { - DBG_NAV_LOG("!root"); - return false; - } - const CachedNode* focusNode = root->currentFocus(); - DBG_NAV_LOGD("focusNode=%d (nodePointer=%p)", - focusNode ? focusNode->index() : -1, - focusNode ? focusNode->nodePointer() : 0); - return focusNode; -} - void rebuildWebTextView() { JNIEnv* env = JSC::Bindings::getJNIEnv(); @@ -1128,11 +659,6 @@ bool setBaseLayer(BaseLayerAndroid* layer, SkRegion& inval, bool showVisualIndic #endif SkSafeUnref(m_baseLayer); m_baseLayer = layer; - CachedRoot* root = getFrameCache(DontAllowNewer); - if (root) { - root->resetLayers(); - root->setRootLayer(compositeRoot()); - } return queueFull; } @@ -1215,7 +741,6 @@ int getHandleLayerId(SelectText::HandleId handleId, SkIRect& cursorRect) { bool m_isDrawingPaused; private: // local state for WebView // private to getFrameCache(); other functions operate in a different thread - CachedRoot* m_frameCacheUI; // navigation data ready for use WebViewCore* m_viewImpl; int m_generation; // associate unique ID with sent kit focus to match with ui // Corresponds to the same-named boolean on the java side. @@ -1323,34 +848,26 @@ static jobject createJavaRect(JNIEnv* env, int x, int y, int right, int bottom) */ static int nativeCacheHitFramePointer(JNIEnv *env, jobject obj) { - return reinterpret_cast<int>(GET_NATIVE_VIEW(env, obj) - ->m_cacheHitFrame->framePointer()); + return 0; } static jobject nativeCacheHitNodeBounds(JNIEnv *env, jobject obj) { - WebCore::IntRect bounds = GET_NATIVE_VIEW(env, obj) - ->m_cacheHitNode->originalAbsoluteBounds(); - return createJavaRect(env, bounds.x(), bounds.y(), - bounds.maxX(), bounds.maxY()); + return 0; } static int nativeCacheHitNodePointer(JNIEnv *env, jobject obj) { - return reinterpret_cast<int>(GET_NATIVE_VIEW(env, obj) - ->m_cacheHitNode->nodePointer()); + return 0; } static bool nativeCacheHitIsPlugin(JNIEnv *env, jobject obj) { - return GET_NATIVE_VIEW(env, obj)->m_cacheHitNode->isPlugin(); + return false; } static void nativeClearCursor(JNIEnv *env, jobject obj) { - WebView* view = GET_NATIVE_VIEW(env, obj); - ALOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->clearCursor(); } static void nativeCreate(JNIEnv *env, jobject obj, int viewImpl, @@ -1364,82 +881,12 @@ static void nativeCreate(JNIEnv *env, jobject obj, int viewImpl, static jint nativeCursorFramePointer(JNIEnv *env, jobject obj) { - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return 0; - const CachedFrame* frame = 0; - (void) root->currentCursor(&frame); - return reinterpret_cast<int>(frame ? frame->framePointer() : 0); -} - -static const CachedNode* getCursorNode(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - return root ? root->currentCursor() : 0; -} - -static const CachedNode* getCursorNode(JNIEnv *env, jobject obj, - const CachedFrame** frame) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - return root ? root->currentCursor(frame) : 0; -} - -static const CachedNode* getFocusCandidate(JNIEnv *env, jobject obj, - const CachedFrame** frame) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return 0; - const CachedNode* cursor = root->currentCursor(frame); - if (cursor && cursor->wantsKeyEvents()) - return cursor; - return root->currentFocus(frame); + return 0; } static bool focusCandidateHasNextTextfield(JNIEnv *env, jobject obj) { - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return false; - const CachedNode* cursor = root->currentCursor(); - if (!cursor || !cursor->isTextInput()) - cursor = root->currentFocus(); - if (!cursor || !cursor->isTextInput()) return false; - return root->nextTextField(cursor, 0); -} - -static const CachedNode* getFocusNode(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - return root ? root->currentFocus() : 0; -} - -static const CachedNode* getFocusNode(JNIEnv *env, jobject obj, - const CachedFrame** frame) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - return root ? root->currentFocus(frame) : 0; -} - -static const CachedInput* getInputCandidate(JNIEnv *env, jobject obj) -{ - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return 0; - const CachedFrame* frame; - const CachedNode* cursor = root->currentCursor(&frame); - if (!cursor || !cursor->wantsKeyEvents()) - cursor = root->currentFocus(&frame); - return cursor ? frame->textInput(cursor) : 0; + return false; } static jboolean nativePageShouldHandleShiftAndArrows(JNIEnv *env, jobject obj) @@ -1449,32 +896,17 @@ static jboolean nativePageShouldHandleShiftAndArrows(JNIEnv *env, jobject obj) static jobject nativeCursorNodeBounds(JNIEnv *env, jobject obj) { - const CachedFrame* frame; - const CachedNode* node = getCursorNode(env, obj, &frame); - WebCore::IntRect bounds = node ? node->bounds(frame) - : WebCore::IntRect(0, 0, 0, 0); - return createJavaRect(env, bounds.x(), bounds.y(), - bounds.maxX(), bounds.maxY()); + return 0; } static jint nativeCursorNodePointer(JNIEnv *env, jobject obj) { - const CachedNode* node = getCursorNode(env, obj); - return reinterpret_cast<int>(node ? node->nodePointer() : 0); + return 0; } static jobject nativeCursorPosition(JNIEnv *env, jobject obj) { - WebView* view = GET_NATIVE_VIEW(env, obj); - const CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - WebCore::IntPoint pos = WebCore::IntPoint(0, 0); - if (root) - root->getSimulatedMousePosition(&pos); - jclass pointClass = env->FindClass("android/graphics/Point"); - jmethodID init = env->GetMethodID(pointClass, "<init>", "(II)V"); - jobject point = env->NewObject(pointClass, init, pos.x(), pos.y()); - env->DeleteLocalRef(pointClass); - return point; + return 0; } static WebCore::IntRect jrect_to_webrect(JNIEnv* env, jobject obj) @@ -1497,40 +929,26 @@ static SkRect jrectf_to_rect(JNIEnv* env, jobject obj) static bool nativeCursorIntersects(JNIEnv *env, jobject obj, jobject visRect) { - const CachedFrame* frame; - const CachedNode* node = getCursorNode(env, obj, &frame); - return node ? node->bounds(frame).intersects( - jrect_to_webrect(env, visRect)) : false; + return false; } static bool nativeCursorIsAnchor(JNIEnv *env, jobject obj) { - const CachedNode* node = getCursorNode(env, obj); - return node ? node->isAnchor() : false; + return false; } static bool nativeCursorIsTextInput(JNIEnv *env, jobject obj) { - const CachedNode* node = getCursorNode(env, obj); - return node ? node->isTextInput() : false; + return false; } static jobject nativeCursorText(JNIEnv *env, jobject obj) { - const CachedNode* node = getCursorNode(env, obj); - if (!node) - return 0; - WTF::String value = node->getExport(); - return wtfStringToJstring(env, value); + return 0; } static void nativeDebugDump(JNIEnv *env, jobject obj) { -#if DUMP_NAV_CACHE - WebView* view = GET_NATIVE_VIEW(env, obj); - ALOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->debugDump(); -#endif } static jint nativeDraw(JNIEnv *env, jobject obj, jobject canv, @@ -1633,204 +1051,120 @@ static bool nativeHasContent(JNIEnv *env, jobject obj) static jobject nativeImageURI(JNIEnv *env, jobject obj, jint x, jint y) { - WebView* view = GET_NATIVE_VIEW(env, obj); - ALOG_ASSERT(view, "view not set in %s", __FUNCTION__); - WTF::String uri = view->imageURI(x, y); - return wtfStringToJstring(env, uri); + return 0; } static jint nativeFocusCandidateFramePointer(JNIEnv *env, jobject obj) { - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return 0; - const CachedFrame* frame = 0; - const CachedNode* cursor = root->currentCursor(&frame); - if (!cursor || !cursor->wantsKeyEvents()) - (void) root->currentFocus(&frame); - return reinterpret_cast<int>(frame ? frame->framePointer() : 0); + return 0; } static bool nativeFocusCandidateIsEditableText(JNIEnv* env, jobject obj, jint nativeClass) { - WebView* view = reinterpret_cast<WebView*>(nativeClass); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - bool isEditable = false; - if (root) { - const CachedFrame* frame = NULL; - const CachedNode* cursor = root->currentCursor(&frame); - const CachedNode* focus = cursor; - if (!cursor || !cursor->wantsKeyEvents()) - focus = root->currentFocus(&frame); - if (focus) { - isEditable = (focus->isTextInput() || focus->isContentEditable()); - } - } - return isEditable; + return false; } static bool nativeFocusCandidateIsPassword(JNIEnv *env, jobject obj) { - const CachedInput* input = getInputCandidate(env, obj); - return input && input->getType() == CachedInput::PASSWORD; + return false; } static bool nativeFocusCandidateIsRtlText(JNIEnv *env, jobject obj) { - const CachedInput* input = getInputCandidate(env, obj); - return input ? input->isRtlText() : false; + return false; } static bool nativeFocusCandidateIsTextInput(JNIEnv *env, jobject obj) { - const CachedNode* node = getFocusCandidate(env, obj, 0); - return node ? node->isTextInput() : false; + return false; } static jint nativeFocusCandidateMaxLength(JNIEnv *env, jobject obj) { - const CachedInput* input = getInputCandidate(env, obj); - return input ? input->maxLength() : false; + return 0; } static jint nativeFocusCandidateIsAutoComplete(JNIEnv *env, jobject obj) { - const CachedInput* input = getInputCandidate(env, obj); - return input ? input->autoComplete() : false; + return 0; } static jobject nativeFocusCandidateName(JNIEnv *env, jobject obj) { - const CachedInput* input = getInputCandidate(env, obj); - if (!input) - return 0; - const WTF::String& name = input->name(); - return wtfStringToJstring(env, name); + return false; } static jobject nativeFocusCandidateNodeBounds(JNIEnv *env, jobject obj) { - const CachedFrame* frame; - const CachedNode* node = getFocusCandidate(env, obj, &frame); - WebCore::IntRect bounds = node ? node->originalAbsoluteBounds() - : WebCore::IntRect(0, 0, 0, 0); - // Inset the rect by 1 unit, so that the focus candidate's border can still - // be seen behind it. - return createJavaRect(env, bounds.x(), bounds.y(), - bounds.maxX(), bounds.maxY()); + return 0; } static jobject nativeFocusCandidatePaddingRect(JNIEnv *env, jobject obj) { - const CachedInput* input = getInputCandidate(env, obj); - if (!input) - return 0; - // Note that the Java Rect is being used to pass four integers, rather than - // being used as an actual rectangle. - return createJavaRect(env, input->paddingLeft(), input->paddingTop(), - input->paddingRight(), input->paddingBottom()); + return 0; } static jint nativeFocusCandidatePointer(JNIEnv *env, jobject obj) { - const CachedNode* node = getFocusCandidate(env, obj, 0); - return reinterpret_cast<int>(node ? node->nodePointer() : 0); + return 0; } static jint nativeFocusCandidateIsSpellcheck(JNIEnv *env, jobject obj) { - const CachedInput* input = getInputCandidate(env, obj); - return input ? input->spellcheck() : false; + return 0; } static jobject nativeFocusCandidateText(JNIEnv *env, jobject obj) { - const CachedNode* node = getFocusCandidate(env, obj, 0); - if (!node) - return 0; - WTF::String value = node->getExport(); - return wtfStringToJstring(env, value); + return 0; } static int nativeFocusCandidateLineHeight(JNIEnv *env, jobject obj) { - const CachedInput* input = getInputCandidate(env, obj); - return input ? input->lineHeight() : 0; + return 0; } static jfloat nativeFocusCandidateTextSize(JNIEnv *env, jobject obj) { - const CachedInput* input = getInputCandidate(env, obj); - return input ? input->textSize() : 0.f; + return 0.f; } static int nativeFocusCandidateType(JNIEnv *env, jobject obj) { - const CachedInput* input = getInputCandidate(env, obj); - if (!input) - return CachedInput::NONE; - - if (input->isTextArea()) - return CachedInput::TEXT_AREA; - - return input->getType(); + return 0; } static int nativeFocusCandidateLayerId(JNIEnv *env, jobject obj) { - const CachedFrame* frame = 0; - const CachedNode* node = getFocusNode(env, obj, &frame); - if (!node || !frame) - return -1; - const CachedLayer* layer = frame->layer(node); - if (!layer) - return -1; - return layer->uniqueId(); + return 0; } static bool nativeFocusIsPlugin(JNIEnv *env, jobject obj) { - const CachedNode* node = getFocusNode(env, obj); - return node ? node->isPlugin() : false; + return false; } static jobject nativeFocusNodeBounds(JNIEnv *env, jobject obj) { - const CachedFrame* frame; - const CachedNode* node = getFocusNode(env, obj, &frame); - WebCore::IntRect bounds = node ? node->bounds(frame) - : WebCore::IntRect(0, 0, 0, 0); - return createJavaRect(env, bounds.x(), bounds.y(), - bounds.maxX(), bounds.maxY()); + return 0; } static jint nativeFocusNodePointer(JNIEnv *env, jobject obj) { - const CachedNode* node = getFocusNode(env, obj); - return node ? reinterpret_cast<int>(node->nodePointer()) : 0; + return 0; } static bool nativeCursorWantsKeyEvents(JNIEnv* env, jobject jwebview) { - WebView* view = GET_NATIVE_VIEW(env, jwebview); - ALOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return view->cursorWantsKeyEvents(); + return false; } static void nativeHideCursor(JNIEnv *env, jobject obj) { - WebView* view = GET_NATIVE_VIEW(env, obj); - ALOG_ASSERT(view, "view not set in %s", __FUNCTION__); - view->hideCursor(); } static void nativeSelectBestAt(JNIEnv *env, jobject obj, jobject jrect) { - WebView* view = GET_NATIVE_VIEW(env, obj); - ALOG_ASSERT(view, "view not set in %s", __FUNCTION__); - WebCore::IntRect rect = jrect_to_webrect(env, jrect); - view->selectBestAt(rect); } static void nativeSelectAt(JNIEnv *env, jobject obj, jint x, jint y) @@ -1878,42 +1212,35 @@ static jobject nativeSubtractLayers(JNIEnv* env, jobject obj, jobject jrect) static jint nativeTextGeneration(JNIEnv *env, jobject obj) { - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - return root ? root->textGeneration() : 0; + return 0; } static bool nativePointInNavCache(JNIEnv *env, jobject obj, int x, int y, int slop) { - return GET_NATIVE_VIEW(env, obj)->pointInNavCache(x, y, slop); + return false; } static bool nativeMotionUp(JNIEnv *env, jobject obj, int x, int y, int slop) { - WebView* view = GET_NATIVE_VIEW(env, obj); - ALOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return view->motionUp(x, y, slop); + return false; } static bool nativeHasCursorNode(JNIEnv *env, jobject obj) { - return GET_NATIVE_VIEW(env, obj)->hasCursorNode(); + return false; } static bool nativeHasFocusNode(JNIEnv *env, jobject obj) { - return GET_NATIVE_VIEW(env, obj)->hasFocusNode(); + return false; } static bool nativeMoveCursor(JNIEnv *env, jobject obj, int key, int count, bool ignoreScroll) { - WebView* view = GET_NATIVE_VIEW(env, obj); - DBG_NAV_LOGD("env=%p obj=%p view=%p", env, obj, view); - ALOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return view->moveCursor(key, count, ignoreScroll); + return false; } static void nativeSetFindIsUp(JNIEnv *env, jobject obj, jboolean isUp) @@ -1936,44 +1263,17 @@ static void nativeSetHeightCanMeasure(JNIEnv *env, jobject obj, bool measure) static jobject nativeGetCursorRingBounds(JNIEnv *env, jobject obj) { - WebView* view = GET_NATIVE_VIEW(env, obj); - ALOG_ASSERT(view, "view not set in %s", __FUNCTION__); - jclass rectClass = env->FindClass("android/graphics/Rect"); - ALOG_ASSERT(rectClass, "Could not find Rect class!"); - jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); - ALOG_ASSERT(init, "Could not find constructor for Rect"); - WebCore::IntRect webRect; - view->cursorRingBounds(&webRect); - jobject rect = env->NewObject(rectClass, init, webRect.x(), - webRect.y(), webRect.maxX(), webRect.maxY()); - env->DeleteLocalRef(rectClass); - return rect; + return 0; } static void nativeUpdateCachedTextfield(JNIEnv *env, jobject obj, jstring updatedText, jint generation) { - WebView* view = GET_NATIVE_VIEW(env, obj); - ALOG_ASSERT(view, "view not set in nativeUpdateCachedTextfield"); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return; - const CachedNode* cachedFocusNode = root->currentFocus(); - if (!cachedFocusNode || !cachedFocusNode->isTextInput()) - return; - WTF::String webcoreString = jstringToWtfString(env, updatedText); - (const_cast<CachedNode*>(cachedFocusNode))->setExport(webcoreString); - root->setTextGeneration(generation); - checkException(env); } static jint nativeGetBlockLeftEdge(JNIEnv *env, jobject obj, jint x, jint y, jfloat scale) { - WebView* view = GET_NATIVE_VIEW(env, obj); - ALOG_ASSERT(view, "view not set in %s", __FUNCTION__); - if (!view) - return -1; - return view->getBlockLeftEdge(x, y, scale); + return -1; } static void nativeDestroy(JNIEnv *env, jobject obj) @@ -1991,30 +1291,7 @@ static void nativeStopGL(JNIEnv *env, jobject obj) static bool nativeMoveCursorToNextTextInput(JNIEnv *env, jobject obj) { - WebView* view = GET_NATIVE_VIEW(env, obj); - CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); - if (!root) - return false; - const CachedNode* current = root->currentCursor(); - if (!current || !current->isTextInput()) - current = root->currentFocus(); - if (!current || !current->isTextInput()) - return false; - const CachedFrame* frame; - const CachedNode* next = root->nextTextField(current, &frame); - if (!next) - return false; - const WebCore::IntRect& bounds = next->bounds(frame); - root->rootHistory()->setMouseBounds(bounds); - view->getWebViewCore()->updateCursorBounds(root, frame, next); - root->setCursor(const_cast<CachedFrame*>(frame), - const_cast<CachedNode*>(next)); - view->sendMoveFocus(static_cast<WebCore::Frame*>(frame->framePointer()), - static_cast<WebCore::Node*>(next->nodePointer())); - if (!next->isInLayer()) - view->scrollRectOnScreen(bounds); - view->getWebViewCore()->m_moveGeneration++; - return true; + return false; } static int nativeMoveGeneration(JNIEnv *env, jobject obj) |