Bug 703141 - Fix plugin positioning and sizing. r=kats, pcwalton

This fixes plugin position/size in the new displayport-viewport scheme.
This commit is contained in:
Chris Lord 2011-11-23 19:08:11 +00:00
parent 5a6d7e467b
commit d30a6066e3
3 changed files with 99 additions and 46 deletions

View File

@ -1049,9 +1049,10 @@ abstract public class GeckoApp
public void run() { public void run() {
PluginLayoutParams lp; PluginLayoutParams lp;
ViewportMetrics geckoViewport = mSoftwareLayerClient.getGeckoViewportMetrics();
if (mGeckoLayout.indexOfChild(view) == -1) { if (mGeckoLayout.indexOfChild(view) == -1) {
lp = new PluginLayoutParams((int) w, (int) h, (int)x, (int)y); lp = PluginLayoutParams.create((int)x, (int)y, (int)w, (int)h, geckoViewport.getZoomFactor());
lp.repositionFromVisibleRect(RectUtils.round(mLayerController.getViewport()), mLayerController.getZoomFactor(), true);
view.setWillNotDraw(false); view.setWillNotDraw(false);
if (view instanceof SurfaceView) { if (view instanceof SurfaceView) {
@ -1065,8 +1066,7 @@ abstract public class GeckoApp
mPluginViews.add(view); mPluginViews.add(view);
} else { } else {
lp = (PluginLayoutParams)view.getLayoutParams(); lp = (PluginLayoutParams)view.getLayoutParams();
lp.reset((int)x, (int)y, (int)w, (int)h); lp.reset((int)x, (int)y, (int)w, (int)h, geckoViewport.getZoomFactor());
lp.repositionFromVisibleRect(RectUtils.round(mLayerController.getViewport()), mLayerController.getZoomFactor(), true);
try { try {
mGeckoLayout.updateViewLayout(view, lp); mGeckoLayout.updateViewLayout(view, lp);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
@ -1098,17 +1098,19 @@ abstract public class GeckoApp
} }
public void showPluginViews() { public void showPluginViews() {
repositionPluginViews(true, true); repositionPluginViews(true);
} }
public void repositionPluginViews(boolean resize) { public void repositionPluginViews(boolean setVisible) {
repositionPluginViews(true, false); ViewportMetrics hostViewport = mSoftwareLayerClient.getGeckoViewportMetrics();
} ViewportMetrics targetViewport = mLayerController.getViewportMetrics();
if (hostViewport == null || targetViewport == null)
return;
public void repositionPluginViews(boolean resize, boolean setVisible) {
for (View view : mPluginViews) { for (View view : mPluginViews) {
PluginLayoutParams lp = (PluginLayoutParams)view.getLayoutParams(); PluginLayoutParams lp = (PluginLayoutParams)view.getLayoutParams();
lp.repositionFromVisibleRect(RectUtils.round(mLayerController.getViewport()), mLayerController.getZoomFactor(), resize); lp.reposition(hostViewport, targetViewport);
if (setVisible) { if (setVisible) {
view.setVisibility(View.VISIBLE); view.setVisibility(View.VISIBLE);
@ -1889,50 +1891,94 @@ abstract public class GeckoApp
} }
}).start(); }).start();
} }
}
private class PluginLayoutParams extends AbsoluteLayout.LayoutParams class PluginLayoutParams extends AbsoluteLayout.LayoutParams
{ {
private static final int MAX_DIMENSION = 2048; private static final int MAX_DIMENSION = 2048;
private static final String LOGTAG = "GeckoApp.PluginLayoutParams";
public int originalX; private int mOriginalX;
public int originalY; private int mOriginalY;
public int originalWidth; private int mOriginalWidth;
public int originalHeight; private int mOriginalHeight;
private float mOriginalResolution;
public PluginLayoutParams(int aWidth, int aHeight, int aX, int aY) { private float mLastResolution;
super(aWidth, aHeight, aX, aY);
originalX = aX; /*
originalY = aY; * This awkward pattern is necessary due to Java's restrictions on when one can call superclass
originalWidth = aWidth; * constructors.
originalHeight = aHeight; */
} private PluginLayoutParams(int aX, int aY, int aWidth, int aHeight, float aResolution) {
super(aWidth, aHeight, aX, aY);
public void reset(int aX, int aY, int aWidth, int aHeight) { Log.i(LOGTAG, "Creating plugin at " + aX + ", " + aY + ", " + aWidth + "x" + aHeight + ", (" + (aResolution * 100) + "%)");
x = originalX = aX;
y = originalY = aY;
width = originalWidth = aWidth;
height = originalHeight = aHeight;
}
public void repositionFromVisibleRect(Rect rect, float zoomFactor, boolean resize) { mOriginalX = aX;
x = (int)((originalX - rect.left) * zoomFactor); mOriginalY = aY;
y = (int)((originalY - rect.top) * zoomFactor); mOriginalWidth = aWidth;
mOriginalHeight = aHeight;
mLastResolution = mOriginalResolution = aResolution;
if (resize) { clampToMaxSize();
width = (int)(originalWidth * zoomFactor); }
height = (int)(originalHeight * zoomFactor);
if (width > MAX_DIMENSION || height > MAX_DIMENSION) { public static PluginLayoutParams create(int aX, int aY, int aWidth, int aHeight, float aResolution) {
if (width > height) { aX = (int)Math.round(aX * aResolution);
height = (int)(((float)height/(float)width) * MAX_DIMENSION); aY = (int)Math.round(aY * aResolution);
width = MAX_DIMENSION; aWidth = (int)Math.round(aWidth * aResolution);
} else { aHeight = (int)Math.round(aHeight * aResolution);
width = (int)(((float)width/(float)height) * MAX_DIMENSION);
height = MAX_DIMENSION; return new PluginLayoutParams(aX, aY, aWidth, aHeight, aResolution);
} }
}
private void clampToMaxSize() {
if (width > MAX_DIMENSION || height > MAX_DIMENSION) {
if (width > height) {
height = (int)(((float)height/(float)width) * MAX_DIMENSION);
width = MAX_DIMENSION;
} else {
width = (int)(((float)width/(float)height) * MAX_DIMENSION);
height = MAX_DIMENSION;
} }
} }
} }
public void reset(int aX, int aY, int aWidth, int aHeight, float aResolution) {
x = mOriginalX = (int)Math.round(aX * aResolution);
y = mOriginalY = (int)Math.round(aY * aResolution);
width = mOriginalWidth = (int)Math.round(aWidth * aResolution);
height = mOriginalHeight = (int)Math.round(aHeight * aResolution);
mLastResolution = mOriginalResolution = aResolution;
clampToMaxSize();
Log.i(LOGTAG, "Resetting plugin to " + x + ", " + y + ", " + width + "x" + height + ", (" + (aResolution * 100) + "%)");
}
private void reposition(Point aOffset, float aResolution) {
Log.i(LOGTAG, "Repositioning plugin by " + aOffset.x + ", " + aOffset.y + ", (" + (aResolution * 100) + "%)");
x = mOriginalX + aOffset.x;
y = mOriginalY + aOffset.y;
if (!FloatUtils.fuzzyEquals(mLastResolution, aResolution)) {
float scaleFactor = aResolution / mOriginalResolution;
width = (int)Math.round(scaleFactor * mOriginalWidth);
height = (int)Math.round(scaleFactor * mOriginalHeight);
mLastResolution = aResolution;
clampToMaxSize();
}
}
public void reposition(ViewportMetrics hostViewport, ViewportMetrics targetViewport) {
PointF targetOrigin = targetViewport.getOrigin();
PointF hostOrigin = hostViewport.getOrigin();
Point offset = new Point((int)Math.round(hostOrigin.x - targetOrigin.x),
(int)Math.round(hostOrigin.y - targetOrigin.y));
reposition(offset, hostViewport.getZoomFactor());
}
} }

View File

@ -178,7 +178,9 @@ public class GeckoSoftwareLayerClient extends LayerClient {
public ViewportMetrics getGeckoViewportMetrics() { public ViewportMetrics getGeckoViewportMetrics() {
// Return a copy, as we modify this inside the Gecko thread // Return a copy, as we modify this inside the Gecko thread
return new ViewportMetrics(mGeckoViewport); if (mGeckoViewport != null)
return new ViewportMetrics(mGeckoViewport);
return null;
} }
public void geckoLoadedNewContent() { public void geckoLoadedNewContent() {

View File

@ -162,6 +162,7 @@ public class LayerController {
mViewportMetrics.setOrigin(point); mViewportMetrics.setOrigin(point);
notifyLayerClientOfGeometryChange(); notifyLayerClientOfGeometryChange();
mPanZoomController.geometryChanged(); mPanZoomController.geometryChanged();
GeckoApp.mAppContext.repositionPluginViews(false);
} }
public void scrollBy(PointF point) { public void scrollBy(PointF point) {
@ -171,12 +172,14 @@ public class LayerController {
notifyLayerClientOfGeometryChange(); notifyLayerClientOfGeometryChange();
mPanZoomController.geometryChanged(); mPanZoomController.geometryChanged();
GeckoApp.mAppContext.repositionPluginViews(false);
} }
public void setViewport(RectF viewport) { public void setViewport(RectF viewport) {
mViewportMetrics.setViewport(viewport); mViewportMetrics.setViewport(viewport);
notifyLayerClientOfGeometryChange(); notifyLayerClientOfGeometryChange();
mPanZoomController.geometryChanged(); mPanZoomController.geometryChanged();
GeckoApp.mAppContext.repositionPluginViews(false);
} }
public void setPageSize(FloatSize size) { public void setPageSize(FloatSize size) {
@ -196,6 +199,7 @@ public class LayerController {
// We assume this was called by the LayerClient (as it includes page // We assume this was called by the LayerClient (as it includes page
// size), so no need to notify it of this change. // size), so no need to notify it of this change.
mPanZoomController.geometryChanged(); mPanZoomController.geometryChanged();
GeckoApp.mAppContext.repositionPluginViews(false);
} }
public void scaleTo(float zoomFactor, PointF focus) { public void scaleTo(float zoomFactor, PointF focus) {
@ -204,6 +208,7 @@ public class LayerController {
// We assume the zoom level will only be modified by the // We assume the zoom level will only be modified by the
// PanZoomController, so no need to notify it of this change. // PanZoomController, so no need to notify it of this change.
notifyLayerClientOfGeometryChange(); notifyLayerClientOfGeometryChange();
GeckoApp.mAppContext.repositionPluginViews(false);
} }
public boolean post(Runnable action) { return mView.post(action); } public boolean post(Runnable action) { return mView.post(action); }