diff options
author | Derek Sollenberger <djsollen@google.com> | 2009-07-20 09:45:56 -0400 |
---|---|---|
committer | Derek Sollenberger <djsollen@google.com> | 2009-07-20 14:59:53 -0400 |
commit | e0204f4150fd9c321f119dc78d9e23e3164b4b1d (patch) | |
tree | e055b92f3cc9c6a3c28023db2c5e25a3a5094a63 /WebKit | |
parent | 969b05c5249c99a107c8542cdda4a1e47d5a7487 (diff) | |
download | external_webkit-e0204f4150fd9c321f119dc78d9e23e3164b4b1d.zip external_webkit-e0204f4150fd9c321f119dc78d9e23e3164b4b1d.tar.gz external_webkit-e0204f4150fd9c321f119dc78d9e23e3164b4b1d.tar.bz2 |
removing visibleRect event and tracking rectangles instead.
Diffstat (limited to 'WebKit')
-rw-r--r-- | WebKit/android/jni/WebViewCore.cpp | 35 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.h | 4 | ||||
-rw-r--r-- | WebKit/android/plugins/ANPWindowInterface.cpp | 17 | ||||
-rw-r--r-- | WebKit/android/plugins/PluginWidgetAndroid.cpp | 129 | ||||
-rw-r--r-- | WebKit/android/plugins/PluginWidgetAndroid.h | 38 | ||||
-rw-r--r-- | WebKit/android/plugins/android_npapi.h | 27 |
6 files changed, 201 insertions, 49 deletions
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp index d304e79..f9dfa61 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -897,8 +897,8 @@ void WebViewCore::setScrollOffset(int moveGeneration, int dx, int dy) m_scrollOffsetY); m_mainFrame->eventHandler()->sendScrollEvent(); - // update the currently visible window - sendVisibleRectBounds(); + // update the currently visible screen + sendPluginVisibleScreen(); } gCursorBoundsMutex.lock(); bool hasCursorBounds = m_hasCursorBounds; @@ -974,20 +974,8 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height, } } - // update the currently visible window - sendVisibleRectBounds(); -} - -void WebViewCore::sendVisibleRectBounds() -{ - ANPEvent event; - SkANP::InitEvent(&event, kVisibleRect_ANPEventType); - event.data.visibleRect.rect.left = m_scrollOffsetX; - event.data.visibleRect.rect.top = m_scrollOffsetY; - event.data.visibleRect.rect.right = m_scrollOffsetX + m_screenWidth; - event.data.visibleRect.rect.bottom = m_scrollOffsetY + m_screenHeight; - event.data.visibleRect.zoomScale = m_scale; - sendPluginEvent(event, kVisibleRect_ANPEventFlag); + // update the currently visible screen + sendPluginVisibleScreen(); } void WebViewCore::dumpDomTree(bool useFile) @@ -1179,6 +1167,21 @@ void WebViewCore::drawPlugins() } } +void WebViewCore::sendPluginVisibleScreen() +{ + ANPRectI visibleRect; + visibleRect.left = m_scrollOffsetX; + visibleRect.top = m_scrollOffsetY; + visibleRect.right = m_scrollOffsetX + m_screenWidth; + visibleRect.bottom = m_scrollOffsetY + m_screenHeight; + + PluginWidgetAndroid** iter = m_plugins.begin(); + PluginWidgetAndroid** stop = m_plugins.end(); + for (; iter < stop; ++iter) { + (*iter)->setVisibleScreen(visibleRect, m_scale); + } +} + void WebViewCore::sendPluginEvent(const ANPEvent& evt, ANPEventFlag flag) { PluginWidgetAndroid** iter = m_plugins.begin(); diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h index 62189bd..66ef470 100644 --- a/WebKit/android/jni/WebViewCore.h +++ b/WebKit/android/jni/WebViewCore.h @@ -296,6 +296,9 @@ namespace android { void invalPlugin(PluginWidgetAndroid*); void drawPlugins(); + // send the current screen size/zoom to all of the plugins in our list + void sendPluginVisibleScreen(); + // send this event to all of the plugins in our list void sendPluginEvent(const ANPEvent&); @@ -430,7 +433,6 @@ namespace android { SkPicture* rebuildPicture(const SkIRect& inval); void rebuildPictureSet(PictureSet* ); void sendNotifyProgressFinished(); - void sendVisibleRectBounds(); bool handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr); #if DEBUG_NAV_UI uint32_t m_now; diff --git a/WebKit/android/plugins/ANPWindowInterface.cpp b/WebKit/android/plugins/ANPWindowInterface.cpp index 7773e6e..41e00e9 100644 --- a/WebKit/android/plugins/ANPWindowInterface.cpp +++ b/WebKit/android/plugins/ANPWindowInterface.cpp @@ -26,9 +26,9 @@ // must include config.h first for webkit to fiddle with new/delete #include "config.h" #include "SkANP.h" -#include "ScrollView.h" #include "WebViewCore.h" #include "PluginView.h" +#include "PluginWidgetAndroid.h" static bool anp_lockRect(void* window, const ANPRectI* inval, ANPBitmap* bitmap) { @@ -57,10 +57,14 @@ static PluginView* pluginViewForInstance(NPP instance) { return PluginView::currentPluginView(); } -static void anp_scrollTo(NPP instance, int32_t x, int32_t y) { - ScrollView* scrollView = pluginViewForInstance(instance)->parent(); - android::WebViewCore* core = android::WebViewCore::getWebViewCore(scrollView); - core->scrollTo(x,y,true); +static void anp_setVisibleRects(NPP instance, const ANPRectI rects[], int32_t count) { + PluginView* pluginView = pluginViewForInstance(instance); + PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget(); + pluginWidget->setVisibleRects(rects, count); +} + +static void anp_clearVisibleRects(NPP instance) { + anp_setVisibleRects(instance, NULL, 0); } static void anp_showKeyboard(NPP instance, bool value) { @@ -78,7 +82,8 @@ void ANPWindowInterfaceV0_Init(ANPInterface* value) { ASSIGN(i, lockRect); ASSIGN(i, lockRegion); - ASSIGN(i, scrollTo); + ASSIGN(i, setVisibleRects); + ASSIGN(i, clearVisibleRects); ASSIGN(i, showKeyboard); ASSIGN(i, unlock); } diff --git a/WebKit/android/plugins/PluginWidgetAndroid.cpp b/WebKit/android/plugins/PluginWidgetAndroid.cpp index bf9b1bf..7b24e5e 100644 --- a/WebKit/android/plugins/PluginWidgetAndroid.cpp +++ b/WebKit/android/plugins/PluginWidgetAndroid.cpp @@ -32,6 +32,7 @@ #include "PluginSurface.h" #include "PluginView.h" #include "PluginWidgetAndroid.h" +#include "ScrollView.h" #include "SkANP.h" #include "SkFlipPixelRef.h" #include "WebViewCore.h" @@ -42,7 +43,10 @@ PluginWidgetAndroid::PluginWidgetAndroid(WebCore::PluginView* view) m_core = NULL; m_drawingModel = kBitmap_ANPDrawingModel; m_eventFlags = 0; - m_x = m_y = 0; + m_pluginWindow = NULL; + m_requestedVisibleRectCount = 0; + m_requestedFrameRect.setEmpty(); + m_visibleDocRect.setEmpty(); } PluginWidgetAndroid::~PluginWidgetAndroid() { @@ -62,19 +66,17 @@ static SkBitmap::Config computeConfig(bool isTransparent) { : SkBitmap::kRGB_565_Config; } -void PluginWidgetAndroid::setWindow(int x, int y, int width, int height, - bool isTransparent) { - m_x = x; - m_y = y; +void PluginWidgetAndroid::setWindow(NPWindow* window, bool isTransparent) { + m_pluginWindow = window; if (m_drawingModel == kSurface_ANPDrawingModel) { if (m_surface) { - m_surface->attach(x, y, width, height); + m_surface->attach(window->x, window->y, window->width, window->height); } } else { m_flipPixelRef->safeUnref(); m_flipPixelRef = new SkFlipPixelRef(computeConfig(isTransparent), - width, height); + window->width, window->height); } } @@ -84,7 +86,8 @@ bool PluginWidgetAndroid::setDrawingModel(ANPDrawingModel model) { } void PluginWidgetAndroid::localToPageCoords(SkIRect* rect) const { - rect->offset(m_x, m_y); + if (m_pluginWindow) + rect->offset(m_pluginWindow->x, m_pluginWindow->y); } bool PluginWidgetAndroid::isDirty(SkIRect* rect) const { @@ -143,11 +146,11 @@ void PluginWidgetAndroid::draw(SkCanvas* canvas) { bitmap) && pkg->pluginFuncs()->event(instance, &event)) { - if (canvas) { + if (canvas && m_pluginWindow) { SkBitmap bm(bitmap); bm.setPixelRef(m_flipPixelRef); - canvas->drawBitmap(bm, SkIntToScalar(m_x), - SkIntToScalar(m_y), NULL); + canvas->drawBitmap(bm, SkIntToScalar(m_pluginWindow->x), + SkIntToScalar(m_pluginWindow->y), NULL); } } break; @@ -202,3 +205,107 @@ ANPSurface* PluginWidgetAndroid::createSurface(ANPSurfaceType ignored) { surface->type = ignored; return surface; } + +void PluginWidgetAndroid::setVisibleScreen(const ANPRectI& visibleDocRect, float zoom) { + + //TODO send an event to the plugin that communicates the zoom + + int oldScreenW = m_visibleDocRect.width(); + int oldScreenH = m_visibleDocRect.height(); + + m_visibleDocRect.set(visibleDocRect.left, visibleDocRect.top, + visibleDocRect.right, visibleDocRect.bottom); + + int newScreenW = m_visibleDocRect.width(); + int newScreenH = m_visibleDocRect.height(); + + if (oldScreenW != newScreenW || oldScreenH != newScreenH) + computeVisibleFrameRect(); +} + +void PluginWidgetAndroid::setVisibleRects(const ANPRectI rects[], int32_t count) { + + // ensure the count does not exceed our allocated space + if (count > MAX_REQUESTED_RECTS) + count = MAX_REQUESTED_RECTS; + + // store the values in member variables + m_requestedVisibleRectCount = count; + memcpy(m_requestedVisibleRect, rects, count * sizeof(rects[0])); + + computeVisibleFrameRect(); +} + +void PluginWidgetAndroid::computeVisibleFrameRect() { + + // ensure the visibleDocRect has been set (i.e. not equal to zero) + if (m_visibleDocRect.isEmpty()) + return; + + // create a rect that represents the plugin's bounds + SkIRect pluginBounds; + pluginBounds.set(m_pluginWindow->x, m_pluginWindow->y, + m_pluginWindow->x + m_pluginWindow->width, + m_pluginWindow->y + m_pluginWindow->height); + + // create a rect that will contain as many of the rects that will fit on screen + SkIRect visibleRect; + visibleRect.setEmpty(); + + for (int counter = 0; counter < m_requestedVisibleRectCount; counter++) { + + ANPRectI* rect = &m_requestedVisibleRect[counter]; + + // create skia rect for easier manipulation and convert it to frame coordinates + SkIRect pluginRect; + pluginRect.set(rect->left, rect->top, rect->right, rect->bottom); + pluginRect.offset(m_pluginWindow->x, m_pluginWindow->y); + + // ensure the rect falls within the plugin's bounds + if (!pluginBounds.contains(pluginRect)) + continue; + + // combine this new rect with the higher priority rects + pluginRect.join(visibleRect); + + // check to see if the new rect fits within the screen bounds. If this + // is the highest priority rect then attempt to center even if it doesn't + // fit on the screen. + if (counter > 0 && (m_visibleDocRect.width() < pluginRect.width() || + m_visibleDocRect.height() < pluginRect.height())) + break; + + // set the new visible rect + visibleRect = pluginRect; + } + + m_requestedFrameRect = visibleRect; + scrollToVisibleFrameRect(); +} + +void PluginWidgetAndroid::scrollToVisibleFrameRect() { + + if (m_requestedFrameRect.isEmpty() || m_visibleDocRect.isEmpty()) + return; + + // TODO if the entire rect is already visible then we don't need to scroll, + // this requires converting the m_requestedFrameRect from frame to doc coordinates + + // find the center of the visibleRect in document coordinates + ScrollView* scrollView = m_pluginView->parent(); + IntPoint pluginFramePoint = IntPoint(m_requestedFrameRect.fLeft, m_requestedFrameRect.fTop); + IntPoint pluginDocPoint = scrollView->convertToContainingWindow(pluginFramePoint); + int rectCenterX = pluginDocPoint.x() + m_requestedFrameRect.width()/2; + int rectCenterY = pluginDocPoint.y() + m_requestedFrameRect.height()/2; + + // find document coordinates for center of the visible screen + int screenCenterX = m_visibleDocRect.fLeft + m_visibleDocRect.width()/2; + int screenCenterY = m_visibleDocRect.fTop + m_visibleDocRect.height()/2; + + //compute the delta of the two points + int deltaX = rectCenterX - screenCenterX; + int deltaY = rectCenterY - screenCenterY; + + android::WebViewCore* core = android::WebViewCore::getWebViewCore(scrollView); + core->scrollBy(deltaX, deltaY, true); +} diff --git a/WebKit/android/plugins/PluginWidgetAndroid.h b/WebKit/android/plugins/PluginWidgetAndroid.h index 84ac729..1da618f 100644 --- a/WebKit/android/plugins/PluginWidgetAndroid.h +++ b/WebKit/android/plugins/PluginWidgetAndroid.h @@ -27,6 +27,7 @@ #define PluginWidgetAndroid_H #include "android_npapi.h" +#include "SkRect.h" #include <wtf/OwnPtr.h> @@ -64,7 +65,8 @@ struct PluginWidgetAndroid { void init(android::WebViewCore*); /* Called each time the PluginView gets a new size or position. */ - void setWindow(int x, int y, int width, int height, bool isTransparent); + void setWindow(NPWindow* window, bool isTransparent); + /* Called whenever the plugin itself requests a new drawing model. If the hardware does not support the requested model then false is returned, otherwise true is returned. @@ -113,15 +115,45 @@ struct PluginWidgetAndroid { */ ANPSurface* createSurface(ANPSurfaceType type); + /* Notify the plugin of the currently visible screen coordinates (document + space) and the current zoom level. + */ + void setVisibleScreen(const ANPRectI& visibleScreenRect, float zoom); + + /** Registers a set of rectangles that the plugin would like to keep on + screen. The rectangles are listed in order of priority with the highest + priority rectangle in location rects[0]. The browser will attempt to keep + as many of the rectangles on screen as possible and will scroll them into + view in response to the invocation of this method and other various events. + The count specifies how many rectangles are in the array. If the count is + zero it signals the plugin that any existing rectangles should be cleared + and no rectangles will be tracked. + */ + void setVisibleRects(const ANPRectI rects[], int32_t count); + private: + void computeVisibleFrameRect(); + void scrollToVisibleFrameRect(); + WebCore::PluginView* m_pluginView; android::WebViewCore* m_core; SkFlipPixelRef* m_flipPixelRef; ANPDrawingModel m_drawingModel; ANPEventFlags m_eventFlags; - int m_x; - int m_y; + NPWindow* m_pluginWindow; + SkIRect m_visibleDocRect; + SkIRect m_requestedFrameRect; OwnPtr<android::PluginSurface> m_surface; + + /* We limit the number of rectangles to minimize storage and ensure adequate + speed. + */ + enum { + MAX_REQUESTED_RECTS = 5, + }; + + ANPRectI m_requestedVisibleRect[MAX_REQUESTED_RECTS]; + int32_t m_requestedVisibleRectCount; }; #endif diff --git a/WebKit/android/plugins/android_npapi.h b/WebKit/android/plugins/android_npapi.h index cfea681..e50f031 100644 --- a/WebKit/android/plugins/android_npapi.h +++ b/WebKit/android/plugins/android_npapi.h @@ -164,7 +164,6 @@ typedef int32_t ANPDrawingModel; enum ANPEventFlag { kKey_ANPEventFlag = 0x01, kTouch_ANPEventFlag = 0x02, - kVisibleRect_ANPEventFlag = 0x04, }; typedef uint32_t ANPEventFlags; @@ -615,11 +614,20 @@ struct ANPWindowInterfaceV0 : ANPInterface { results. If lock returned false, unlock should not be called. */ void (*unlock)(void* window); - /** Given (x,y) coordinates in the document space the currently visible - window will be shifted so that window's upper left corner will be as - closely aligned to the coordinates as possible. - */ - void (*scrollTo)(NPP instance, int32_t x, int32_t y); + /** Registers a set of rectangles that the plugin would like to keep on + screen. The rectangles are listed in order of priority with the highest + priority rectangle in location rects[0]. The browser will attempt to keep + as many of the rectangles on screen as possible and will scroll them into + view in response to the invocation of this method and other various events. + The count specifies how many rectangles are in the array. If the count is + zero it signals the browser that any existing rectangles should be cleared + and no rectangles will be tracked. + */ + void (*setVisibleRects)(NPP instance, const ANPRectI rects[], int32_t count); + /** Clears any rectangles that are being tracked as a result of a call to + setVisibleRects. This call is equivalent to setVisibleRect(inst, NULL, 0). + */ + void (*clearVisibleRects)(NPP instance); /** Given a boolean value of true the device will be requested to provide a keyboard. A value of false will result in a request to hide the keyboard. Further, the on-screen keyboard will not be displayed if a @@ -716,8 +724,7 @@ enum ANPEventTypes { kTouch_ANPEventType = 3, kDraw_ANPEventType = 4, kLifecycle_ANPEventType = 5, - kVisibleRect_ANPEventType = 6, - kSurface_ANPEventType = 7, + kSurface_ANPEventType = 6, }; typedef int32_t ANPEventType; @@ -815,10 +822,6 @@ struct ANPEvent { } data; } draw; struct { - ANPRectI rect; // in global document coordinates - float zoomScale; // 1.0 means no zoom scale - } visibleRect; - struct { ANPSurfaceAction action; /** This union is based on the value of action and contains data specific to the given action. |