summaryrefslogtreecommitdiffstats
path: root/WebKit
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2009-07-20 09:45:56 -0400
committerDerek Sollenberger <djsollen@google.com>2009-07-20 14:59:53 -0400
commite0204f4150fd9c321f119dc78d9e23e3164b4b1d (patch)
treee055b92f3cc9c6a3c28023db2c5e25a3a5094a63 /WebKit
parent969b05c5249c99a107c8542cdda4a1e47d5a7487 (diff)
downloadexternal_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.cpp35
-rw-r--r--WebKit/android/jni/WebViewCore.h4
-rw-r--r--WebKit/android/plugins/ANPWindowInterface.cpp17
-rw-r--r--WebKit/android/plugins/PluginWidgetAndroid.cpp129
-rw-r--r--WebKit/android/plugins/PluginWidgetAndroid.h38
-rw-r--r--WebKit/android/plugins/android_npapi.h27
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.