Bug 748384 - Update all Java code to keep a page rect and CSS page rect instead of just the page size. r=Cwiiis

This commit is contained in:
Kartikaya Gupta 2012-05-23 10:49:52 -04:00
parent d448ef890c
commit 78fc09d742
14 changed files with 210 additions and 180 deletions

View File

@ -28,6 +28,9 @@ namespace layers {
// avoid the overhead of virtual dispatch, we employ the curiously recurring
// template pattern.
//
// Tiles are aligned to a grid with one of the grid points at (0,0) and other
// grid points spaced evenly in the x- and y-directions by GetTileLength().
//
// This tile buffer stores a valid region, which defines the areas that have
// up-to-date content. The contents of tiles within this region will be reused
// from paint to paint. It also stores the region that was modified in the last

View File

@ -2170,17 +2170,7 @@ public class GeckoAppShell
}
Tab tab = Tabs.getInstance().getSelectedTab();
ImmutableViewportMetrics viewport = GeckoApp.mAppContext.getLayerController().getViewportMetrics();
/*
if (FloatUtils.fuzzyEquals(sCheckerboardPageWidth, viewport.pageSizeWidth) &&
FloatUtils.fuzzyEquals(sCheckerboardPageHeight, viewport.pageSizeHeight)) {
float width = right - left;
float height = bottom - top;
GeckoAppShell.sendEventToGecko(GeckoEvent.createScreenshotEvent(tab.getId(), (int)top, (int)left, (int)width, (int)height, 0, 0, (int)(sLastCheckerboardWidthRatio * width), (int)(sLastCheckerboardHeightRatio * height), GeckoAppShell.SCREENSHOT_UPDATE));
} else {
*/
GeckoAppShell.screenshotWholePage(tab);
//}
GeckoAppShell.screenshotWholePage(tab);
}
void addRectToRepaint(float top, float left, float bottom, float right) {
@ -2228,8 +2218,8 @@ public class GeckoAppShell
ImmutableViewportMetrics viewport = GeckoApp.mAppContext.getLayerController().getViewportMetrics();
Log.i(LOGTAG, "Taking whole-screen screenshot, viewport: " + viewport);
// source width and height to screenshot
float sw = viewport.pageSizeWidth / viewport.zoomFactor;
float sh = viewport.pageSizeHeight / viewport.zoomFactor;
float sw = viewport.getPageWidth() / viewport.zoomFactor;
float sh = viewport.getPageHeight() / viewport.zoomFactor;
int maxPixels = Math.min(ScreenshotLayer.getMaxNumPixels(), sMaxTextureSize * sMaxTextureSize);
// 2Mb of 16bit image data
// may be bumped by up to 4x for power of 2 alignment
@ -2247,6 +2237,9 @@ public class GeckoAppShell
sCheckerboardPageWidth = sw;
sCheckerboardPageHeight = sh;
GeckoAppShell.sendEventToGecko(GeckoEvent.createScreenshotEvent(tab.getId(), 0, 0, (int)sw, (int)sh, 0, 0, dw, dh, GeckoAppShell.SCREENSHOT_WHOLE_PAGE));
GeckoAppShell.sendEventToGecko(GeckoEvent.createScreenshotEvent(tab.getId(),
(int)FloatMath.ceil(viewport.pageRectLeft), (int)FloatMath.ceil(viewport.pageRectTop),
(int)FloatMath.floor(viewport.getPageWidth()), (int)FloatMath.floor(viewport.getPageHeight()),
0, 0, dw, dh, GeckoAppShell.SCREENSHOT_WHOLE_PAGE));
}
}

View File

@ -129,15 +129,15 @@ final class DisplayPortCalculator {
*/
private static FloatSize reshapeForPage(float width, float height, ImmutableViewportMetrics metrics) {
// figure out how much of the desired buffer amount we can actually use on the horizontal axis
float usableWidth = Math.min(width, metrics.pageSizeWidth);
float usableWidth = Math.min(width, metrics.getPageWidth());
// if we reduced the buffer amount on the horizontal axis, we should take that saved memory and
// use it on the vertical axis
float extraUsableHeight = (float)Math.floor(((width - usableWidth) * height) / usableWidth);
float usableHeight = Math.min(height + extraUsableHeight, metrics.pageSizeHeight);
float usableHeight = Math.min(height + extraUsableHeight, metrics.getPageHeight());
if (usableHeight < height && usableWidth == width) {
// and the reverse - if we shrunk the buffer on the vertical axis we can add it to the horizontal
float extraUsableWidth = (float)Math.floor(((height - usableHeight) * width) / usableHeight);
usableWidth = Math.min(width + extraUsableWidth, metrics.pageSizeWidth);
usableWidth = Math.min(width + extraUsableWidth, metrics.getPageWidth());
}
return new FloatSize(usableWidth, usableHeight);
}
@ -153,11 +153,7 @@ final class DisplayPortCalculator {
float dangerZoneY = metrics.getHeight() * dangerZoneYMultiplier;
rect = RectUtils.expand(rect, dangerZoneX, dangerZoneY);
// clamp to page bounds
if (rect.top < 0) rect.top = 0;
if (rect.left < 0) rect.left = 0;
if (rect.right > metrics.pageSizeWidth) rect.right = metrics.pageSizeWidth;
if (rect.bottom > metrics.pageSizeHeight) rect.bottom = metrics.pageSizeHeight;
return rect;
return clampToPageBounds(rect, metrics);
}
/**
@ -171,10 +167,10 @@ final class DisplayPortCalculator {
float top = metrics.viewportRectTop - margins.top;
float right = metrics.viewportRectRight + margins.right;
float bottom = metrics.viewportRectBottom + margins.bottom;
left = Math.max(0.0f, TILE_SIZE * FloatMath.floor(left / TILE_SIZE));
top = Math.max(0.0f, TILE_SIZE * FloatMath.floor(top / TILE_SIZE));
right = Math.min(metrics.pageSizeWidth, TILE_SIZE * FloatMath.ceil(right / TILE_SIZE));
bottom = Math.min(metrics.pageSizeHeight, TILE_SIZE * FloatMath.ceil(bottom / TILE_SIZE));
left = Math.max(metrics.pageRectLeft, TILE_SIZE * FloatMath.floor(left / TILE_SIZE));
top = Math.max(metrics.pageRectTop, TILE_SIZE * FloatMath.floor(top / TILE_SIZE));
right = Math.min(metrics.pageRectRight, TILE_SIZE * FloatMath.ceil(right / TILE_SIZE));
bottom = Math.min(metrics.pageRectBottom, TILE_SIZE * FloatMath.ceil(bottom / TILE_SIZE));
return new DisplayPortMetrics(left, top, right, bottom, zoom);
}
@ -182,16 +178,16 @@ final class DisplayPortCalculator {
* Adjust the given margins so if they are applied on the viewport in the metrics, the resulting rect
* does not exceed the page bounds. This code will maintain the total margin amount for a given axis;
* it assumes that margins.left + metrics.getWidth() + margins.right is less than or equal to
* metrics.pageSizeWidth; and the same for the y axis.
* metrics.getPageWidth(); and the same for the y axis.
*/
private static RectF shiftMarginsForPageBounds(RectF margins, ImmutableViewportMetrics metrics) {
// check how much we're overflowing in each direction. note that at most one of leftOverflow
// and rightOverflow can be greater than zero, and at most one of topOverflow and bottomOverflow
// can be greater than zero, because of the assumption described in the method javadoc.
float leftOverflow = margins.left - metrics.viewportRectLeft;
float rightOverflow = margins.right - (metrics.pageSizeWidth - metrics.viewportRectRight);
float topOverflow = margins.top - metrics.viewportRectTop;
float bottomOverflow = margins.bottom - (metrics.pageSizeHeight - metrics.viewportRectBottom);
float leftOverflow = metrics.pageRectLeft - (metrics.viewportRectLeft - margins.left);
float rightOverflow = (metrics.viewportRectRight + margins.right) - metrics.pageRectRight;
float topOverflow = metrics.pageRectTop - (metrics.viewportRectTop - margins.top);
float bottomOverflow = (metrics.viewportRectBottom + margins.bottom) - metrics.pageRectBottom;
// if the margins overflow the page bounds, shift them to other side on the same axis
if (leftOverflow > 0) {
@ -215,10 +211,10 @@ final class DisplayPortCalculator {
* Clamp the given rect to the page bounds and return it.
*/
private static RectF clampToPageBounds(RectF rect, ImmutableViewportMetrics metrics) {
rect.left = Math.max(rect.left, 0);
rect.top = Math.max(rect.top, 0);
rect.right = Math.min(rect.right, metrics.pageSizeWidth);
rect.bottom = Math.min(rect.bottom, metrics.pageSizeHeight);
if (rect.top < metrics.pageRectTop) rect.top = metrics.pageRectTop;
if (rect.left < metrics.pageRectLeft) rect.left = metrics.pageRectLeft;
if (rect.right > metrics.pageRectRight) rect.right = metrics.pageRectRight;
if (rect.bottom > metrics.pageRectBottom) rect.bottom = metrics.pageRectBottom;
return rect;
}
@ -395,8 +391,8 @@ final class DisplayPortCalculator {
// we need to avoid having a display port that is larger than the page, or we will end up
// painting things outside the page bounds (bug 729169).
displayPortWidth = Math.min(displayPortWidth, metrics.pageSizeWidth);
displayPortHeight = Math.min(displayPortHeight, metrics.pageSizeHeight);
displayPortWidth = Math.min(displayPortWidth, metrics.getPageWidth());
displayPortHeight = Math.min(displayPortHeight, metrics.getPageHeight());
float horizontalBuffer = displayPortWidth - metrics.getWidth();
float verticalBuffer = displayPortHeight - metrics.getHeight();
@ -414,8 +410,8 @@ final class DisplayPortCalculator {
float dangerZoneY = metrics.getHeight() * (DANGER_ZONE_BASE_Y_MULTIPLIER + (velocity.y * DANGER_ZONE_INCR_Y_MULTIPLIER));
// clamp it such that when added to the viewport, they don't exceed page size.
// this is a prerequisite to calling shiftMarginsForPageBounds as we do below.
dangerZoneX = Math.min(dangerZoneX, metrics.pageSizeWidth - metrics.getWidth());
dangerZoneY = Math.min(dangerZoneY, metrics.pageSizeHeight - metrics.getHeight());
dangerZoneX = Math.min(dangerZoneX, metrics.getPageWidth() - metrics.getWidth());
dangerZoneY = Math.min(dangerZoneY, metrics.getPageHeight() - metrics.getHeight());
// split the danger zone into margins based on velocity, and ensure it doesn't exceed
// page bounds.

View File

@ -204,7 +204,7 @@ public class GeckoLayerClient implements GeckoEventResponder,
// and our zoom level (which may have diverged).
float scaleFactor = oldMetrics.zoomFactor / messageMetrics.getZoomFactor();
newMetrics = new ViewportMetrics(oldMetrics);
newMetrics.setPageSize(messageMetrics.getPageSize().scale(scaleFactor), messageMetrics.getCssPageSize());
newMetrics.setPageRect(RectUtils.scale(messageMetrics.getPageRect(), scaleFactor), messageMetrics.getCssPageRect());
break;
}
@ -306,7 +306,8 @@ public class GeckoLayerClient implements GeckoEventResponder,
final ViewportMetrics currentMetrics = new ViewportMetrics(mLayerController.getViewportMetrics());
currentMetrics.setOrigin(new PointF(offsetX, offsetY));
currentMetrics.setZoomFactor(zoom);
currentMetrics.setPageSize(new FloatSize(pageWidth, pageHeight), new FloatSize(cssPageWidth, cssPageHeight));
currentMetrics.setPageRect(new RectF(0.0f, 0.0f, pageWidth, pageHeight),
new RectF(0.0f, 0.0f, cssPageWidth, cssPageHeight));
// Since we have switched to displaying a different document, we need to update any
// viewport-related state we have lying around. This includes mGeckoViewport and the
// viewport in mLayerController. Usually this information is updated via handleViewportMessage
@ -350,10 +351,10 @@ public class GeckoLayerClient implements GeckoEventResponder,
// adjust the page dimensions to account for differences in zoom
// between the rendered content (which is what the compositor tells us)
// and our zoom level (which may have diverged).
RectF pageRect = new RectF(0.0f, 0.0f, pageWidth, pageHeight);
RectF cssPageRect = new RectF(0.0f, 0.0f, cssPageWidth, cssPageHeight);
float ourZoom = mLayerController.getZoomFactor();
pageWidth = pageWidth * ourZoom / zoom;
pageHeight = pageHeight * ourZoom /zoom;
mLayerController.setPageSize(new FloatSize(pageWidth, pageHeight), new FloatSize(cssPageWidth, cssPageHeight));
mLayerController.setPageRect(RectUtils.scale(pageRect, ourZoom / zoom), cssPageRect);
// Here the page size of the document has changed, but the document being displayed
// is still the same. Therefore, we don't need to send anything to browser.js; any
// changes we need to make to the display port will get sent the next time we call

View File

@ -17,30 +17,38 @@ public class ImmutableViewportMetrics {
// We need to flatten the RectF and FloatSize structures
// because Java doesn't have the concept of const classes
public final float pageSizeWidth;
public final float pageSizeHeight;
public final float cssPageSizeWidth;
public final float cssPageSizeHeight;
public final float viewportRectBottom;
public final float pageRectLeft;
public final float pageRectTop;
public final float pageRectRight;
public final float pageRectBottom;
public final float cssPageRectLeft;
public final float cssPageRectTop;
public final float cssPageRectRight;
public final float cssPageRectBottom;
public final float viewportRectLeft;
public final float viewportRectRight;
public final float viewportRectTop;
public final float viewportRectRight;
public final float viewportRectBottom;
public final float zoomFactor;
public ImmutableViewportMetrics(ViewportMetrics m) {
RectF viewportRect = m.getViewport();
viewportRectBottom = viewportRect.bottom;
viewportRectLeft = viewportRect.left;
viewportRectRight = viewportRect.right;
viewportRectTop = viewportRect.top;
viewportRectRight = viewportRect.right;
viewportRectBottom = viewportRect.bottom;
FloatSize pageSize = m.getPageSize();
pageSizeWidth = pageSize.width;
pageSizeHeight = pageSize.height;
RectF pageRect = m.getPageRect();
pageRectLeft = pageRect.left;
pageRectTop = pageRect.top;
pageRectRight = pageRect.right;
pageRectBottom = pageRect.bottom;
FloatSize cssPageSize = m.getCssPageSize();
cssPageSizeWidth = cssPageSize.width;
cssPageSizeHeight = cssPageSize.height;
RectF cssPageRect = m.getCssPageRect();
cssPageRectLeft = cssPageRect.left;
cssPageRectTop = cssPageRect.top;
cssPageRectRight = cssPageRect.right;
cssPageRectBottom = cssPageRect.bottom;
zoomFactor = m.getZoomFactor();
}
@ -74,18 +82,28 @@ public class ImmutableViewportMetrics {
return RectUtils.scale(getViewport(), 1/zoomFactor);
}
public FloatSize getPageSize() {
return new FloatSize(pageSizeWidth, pageSizeHeight);
public RectF getPageRect() {
return new RectF(pageRectLeft, pageRectTop, pageRectRight, pageRectBottom);
}
public FloatSize getCssPageSize() {
return new FloatSize(cssPageSizeWidth, cssPageSizeHeight);
public float getPageWidth() {
return pageRectRight - pageRectLeft;
}
public float getPageHeight() {
return pageRectBottom - pageRectTop;
}
public RectF getCssPageRect() {
return new RectF(cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom);
}
@Override
public String toString() {
return "ImmutableViewportMetrics v=(" + viewportRectLeft + "," + viewportRectTop + ","
+ viewportRectRight + "," + viewportRectBottom + ") p=(" + pageSizeWidth + ","
+ pageSizeHeight + ") z=" + zoomFactor;
+ viewportRectRight + "," + viewportRectBottom + ") p=(" + pageRectLeft + ","
+ pageRectTop + "," + pageRectRight + "," + pageRectBottom + ") c=("
+ cssPageRectLeft + "," + cssPageRectTop + "," + cssPageRectRight + ","
+ cssPageRectBottom + ") z=" + zoomFactor;
}
}

View File

@ -155,17 +155,17 @@ public abstract class Layer {
public static class RenderContext {
public final RectF viewport;
public final FloatSize pageSize;
public final RectF pageRect;
public final IntSize screenSize;
public final float zoomFactor;
public final int positionHandle;
public final int textureHandle;
public final FloatBuffer coordBuffer;
public RenderContext(RectF aViewport, FloatSize aPageSize, IntSize aScreenSize, float aZoomFactor,
public RenderContext(RectF aViewport, RectF aPageRect, IntSize aScreenSize, float aZoomFactor,
int aPositionHandle, int aTextureHandle, FloatBuffer aCoordBuffer) {
viewport = aViewport;
pageSize = aPageSize;
pageRect = aPageRect;
screenSize = aScreenSize;
zoomFactor = aZoomFactor;
positionHandle = aPositionHandle;
@ -178,7 +178,7 @@ public abstract class Layer {
return false;
}
return RectUtils.fuzzyEquals(viewport, other.viewport)
&& pageSize.fuzzyEquals(other.pageSize)
&& RectUtils.fuzzyEquals(pageRect, other.pageRect)
&& FloatUtils.fuzzyEquals(zoomFactor, other.zoomFactor);
}
}

View File

@ -103,12 +103,12 @@ public class LayerController {
return mViewportMetrics.getSize();
}
public FloatSize getPageSize() {
return mViewportMetrics.getPageSize();
public RectF getPageRect() {
return mViewportMetrics.getPageRect();
}
public FloatSize getCssPageSize() {
return mViewportMetrics.getCssPageSize();
public RectF getCssPageRect() {
return mViewportMetrics.getCssPageRect();
}
public PointF getOrigin() {
@ -167,13 +167,16 @@ public class LayerController {
mView.requestRender();
}
/** Sets the current page size. You must hold the monitor while calling this. */
public void setPageSize(FloatSize size, FloatSize cssSize) {
if (mViewportMetrics.getCssPageSize().equals(cssSize))
/** Sets the current page rect. You must hold the monitor while calling this. */
public void setPageRect(RectF rect, RectF cssRect) {
// Since the "rect" is always just a multiple of "cssRect" we don't need to
// check both; this function assumes that both "rect" and "cssRect" are relative
// the zoom factor in mViewportMetrics.
if (mViewportMetrics.getCssPageRect().equals(cssRect))
return;
ViewportMetrics viewportMetrics = new ViewportMetrics(mViewportMetrics);
viewportMetrics.setPageSize(size, cssSize);
viewportMetrics.setPageRect(rect, cssRect);
mViewportMetrics = new ImmutableViewportMetrics(viewportMetrics);
// Page size is owned by the layer client, so no need to notify it of
@ -181,7 +184,7 @@ public class LayerController {
mView.post(new Runnable() {
public void run() {
mPanZoomController.pageSizeUpdated();
mPanZoomController.pageRectUpdated();
mView.requestRender();
}
});

View File

@ -311,19 +311,19 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
private RenderContext createScreenContext(ImmutableViewportMetrics metrics) {
RectF viewport = new RectF(0.0f, 0.0f, metrics.getWidth(), metrics.getHeight());
FloatSize pageSize = new FloatSize(metrics.getPageSize());
return createContext(viewport, pageSize, 1.0f);
RectF pageRect = new RectF(metrics.getPageRect());
return createContext(viewport, pageRect, 1.0f);
}
private RenderContext createPageContext(ImmutableViewportMetrics metrics) {
Rect viewport = RectUtils.round(metrics.getViewport());
FloatSize pageSize = metrics.getPageSize();
RectF pageRect = metrics.getPageRect();
float zoomFactor = metrics.zoomFactor;
return createContext(new RectF(viewport), pageSize, zoomFactor);
return createContext(new RectF(viewport), pageRect, zoomFactor);
}
private RenderContext createContext(RectF viewport, FloatSize pageSize, float zoomFactor) {
return new RenderContext(viewport, pageSize, new IntSize(mSurfaceWidth, mSurfaceHeight), zoomFactor, mPositionHandle, mTextureHandle,
private RenderContext createContext(RectF viewport, RectF pageRect, float zoomFactor) {
return new RenderContext(viewport, pageRect, new IntSize(mSurfaceWidth, mSurfaceHeight), zoomFactor, mPositionHandle, mTextureHandle,
mCoordBuffer);
}
@ -490,12 +490,9 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
private Rect getPageRect() {
Point origin = PointUtils.round(mFrameMetrics.getOrigin());
IntSize pageSize = new IntSize(mFrameMetrics.getPageSize());
origin.negate();
return new Rect(origin.x, origin.y,
origin.x + pageSize.width, origin.y + pageSize.height);
Rect pageRect = RectUtils.round(mFrameMetrics.getPageRect());
pageRect.offset(-origin.x, -origin.y);
return pageRect;
}
/** This function is invoked via JNI; be careful when modifying signature. */

View File

@ -52,33 +52,33 @@ public class NinePatchTileLayer extends TileLayer {
* +---+---+---+
*/
FloatSize size = context.pageSize;
float width = size.width, height = size.height;
// page is the rect of the "missing" center spot in the picture above
RectF page = context.pageRect;
drawPatch(context, 0, PATCH_SIZE * 3, /* 0 */
0.0f, 0.0f, PATCH_SIZE, PATCH_SIZE);
drawPatch(context, PATCH_SIZE, PATCH_SIZE*3, /* 1 */
PATCH_SIZE, 0.0f, width, PATCH_SIZE);
drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE*3, /* 2 */
PATCH_SIZE + width, 0.0f, PATCH_SIZE, PATCH_SIZE);
page.left - PATCH_SIZE, page.top - PATCH_SIZE, PATCH_SIZE, PATCH_SIZE);
drawPatch(context, PATCH_SIZE, PATCH_SIZE * 3, /* 1 */
page.left, page.top - PATCH_SIZE, page.width(), PATCH_SIZE);
drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE * 3, /* 2 */
page.right, page.top - PATCH_SIZE, PATCH_SIZE, PATCH_SIZE);
drawPatch(context, 0, PATCH_SIZE * 2, /* 3 */
0.0f, PATCH_SIZE, PATCH_SIZE, height);
page.left - PATCH_SIZE, page.top, PATCH_SIZE, page.height());
drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE * 2, /* 4 */
PATCH_SIZE + width, PATCH_SIZE, PATCH_SIZE, height);
page.right, page.top, PATCH_SIZE, page.height());
drawPatch(context, 0, PATCH_SIZE, /* 5 */
0.0f, PATCH_SIZE + height, PATCH_SIZE, PATCH_SIZE);
page.left - PATCH_SIZE, page.bottom, PATCH_SIZE, PATCH_SIZE);
drawPatch(context, PATCH_SIZE, PATCH_SIZE, /* 6 */
PATCH_SIZE, PATCH_SIZE + height, width, PATCH_SIZE);
page.left, page.bottom, page.width(), PATCH_SIZE);
drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE, /* 7 */
PATCH_SIZE + width, PATCH_SIZE + height, PATCH_SIZE, PATCH_SIZE);
page.right, page.bottom, PATCH_SIZE, PATCH_SIZE);
}
private void drawPatch(RenderContext context, int textureX, int textureY,
float tileX, float tileY, float tileWidth, float tileHeight) {
RectF viewport = context.viewport;
float viewportHeight = viewport.height();
float drawX = tileX - viewport.left - PATCH_SIZE;
float drawY = viewportHeight - (tileY + tileHeight - viewport.top - PATCH_SIZE);
float drawX = tileX - viewport.left;
float drawY = viewportHeight - (tileY + tileHeight - viewport.top);
float[] coords = {
//x, y, z, texture_x, texture_y

View File

@ -421,9 +421,9 @@ public class ScrollbarLayer extends TileLayer {
private RectF getVerticalRect(RenderContext context) {
RectF viewport = context.viewport;
FloatSize pageSize = context.pageSize;
float barStart = (viewport.height() * viewport.top / pageSize.height) + CAP_RADIUS;
float barEnd = (viewport.height() * viewport.bottom / pageSize.height) - CAP_RADIUS;
RectF pageRect = context.pageRect;
float barStart = ((viewport.top - pageRect.top) * (viewport.height() / pageRect.height())) + CAP_RADIUS;
float barEnd = ((viewport.bottom - pageRect.top) * (viewport.height() / pageRect.height())) - CAP_RADIUS;
if (barStart > barEnd) {
float middle = (barStart + barEnd) / 2.0f;
barStart = barEnd = middle;
@ -434,9 +434,9 @@ public class ScrollbarLayer extends TileLayer {
private RectF getHorizontalRect(RenderContext context) {
RectF viewport = context.viewport;
FloatSize pageSize = context.pageSize;
float barStart = (viewport.width() * viewport.left / pageSize.width) + CAP_RADIUS;
float barEnd = (viewport.width() * viewport.right / pageSize.width) - CAP_RADIUS;
RectF pageRect = context.pageRect;
float barStart = ((viewport.left - pageRect.left) * (viewport.width() / pageRect.width())) + CAP_RADIUS;
float barEnd = ((viewport.right - pageRect.left) * (viewport.width() / pageRect.width())) - CAP_RADIUS;
if (barStart > barEnd) {
float middle = (barStart + barEnd) / 2.0f;
barStart = barEnd = middle;

View File

@ -67,7 +67,7 @@ public class SingleTileLayer extends TileLayer {
} else if (stretches()) {
// If we're stretching, we just want the bounds and texture bounds
// to fit to the page.
bounds = new RectF(0.0f, 0.0f, context.pageSize.width, context.pageSize.height);
bounds = new RectF(context.pageRect);
textureBounds = bounds;
} else {
bounds = getBounds(context);

View File

@ -13,7 +13,6 @@ import android.util.DisplayMetrics;
import org.mozilla.gecko.FloatUtils;
import org.mozilla.gecko.GeckoApp;
import org.mozilla.gecko.gfx.FloatSize;
import org.mozilla.gecko.gfx.IntSize;
import org.mozilla.gecko.gfx.LayerController;
import org.mozilla.gecko.gfx.RectUtils;
import org.json.JSONException;
@ -27,8 +26,8 @@ import android.util.Log;
public class ViewportMetrics {
private static final String LOGTAG = "GeckoViewportMetrics";
private FloatSize mPageSize;
private FloatSize mCssPageSize;
private RectF mPageRect;
private RectF mCssPageRect;
private RectF mViewportRect;
private float mZoomFactor;
@ -36,26 +35,32 @@ public class ViewportMetrics {
DisplayMetrics metrics = new DisplayMetrics();
GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
mPageSize = new FloatSize(metrics.widthPixels, metrics.heightPixels);
mCssPageSize = new FloatSize(metrics.widthPixels, metrics.heightPixels);
mPageRect = new RectF(0, 0, metrics.widthPixels, metrics.heightPixels);
mCssPageRect = new RectF(0, 0, metrics.widthPixels, metrics.heightPixels);
mViewportRect = new RectF(0, 0, metrics.widthPixels, metrics.heightPixels);
mZoomFactor = 1.0f;
}
public ViewportMetrics(ViewportMetrics viewport) {
mPageSize = new FloatSize(viewport.getPageSize());
mCssPageSize = new FloatSize(viewport.getCssPageSize());
mPageRect = new RectF(viewport.getPageRect());
mCssPageRect = new RectF(viewport.getCssPageRect());
mViewportRect = new RectF(viewport.getViewport());
mZoomFactor = viewport.getZoomFactor();
}
public ViewportMetrics(ImmutableViewportMetrics viewport) {
mPageSize = new FloatSize(viewport.pageSizeWidth, viewport.pageSizeHeight);
mCssPageSize = new FloatSize(viewport.cssPageSizeWidth, viewport.cssPageSizeHeight);
mPageRect = new RectF(viewport.pageRectLeft,
viewport.pageRectTop,
viewport.pageRectRight,
viewport.pageRectBottom);
mCssPageRect = new RectF(viewport.cssPageRectLeft,
viewport.cssPageRectTop,
viewport.cssPageRectRight,
viewport.cssPageRectBottom);
mViewportRect = new RectF(viewport.viewportRectLeft,
viewport.viewportRectTop,
viewport.viewportRectRight,
viewport.viewportRectBottom);
viewport.viewportRectTop,
viewport.viewportRectRight,
viewport.viewportRectBottom);
mZoomFactor = viewport.zoomFactor;
}
@ -65,14 +70,18 @@ public class ViewportMetrics {
float y = (float)json.getDouble("y");
float width = (float)json.getDouble("width");
float height = (float)json.getDouble("height");
float pageWidth = (float)json.getDouble("pageWidth");
float pageHeight = (float)json.getDouble("pageHeight");
float cssPageWidth = (float)json.getDouble("cssPageWidth");
float cssPageHeight = (float)json.getDouble("cssPageHeight");
float pageLeft = 0.0f;
float pageTop = 0.0f;
float pageRight = (float)json.getDouble("pageWidth");
float pageBottom = (float)json.getDouble("pageHeight");
float cssPageLeft = 0.0f;
float cssPageTop = 0.0f;
float cssPageRight = (float)json.getDouble("cssPageWidth");
float cssPageBottom = (float)json.getDouble("cssPageHeight");
float zoom = (float)json.getDouble("zoom");
mPageSize = new FloatSize(pageWidth, pageHeight);
mCssPageSize = new FloatSize(cssPageWidth, cssPageHeight);
mPageRect = new RectF(pageLeft, pageTop, pageRight, pageBottom);
mCssPageRect = new RectF(cssPageLeft, cssPageTop, cssPageRight, cssPageBottom);
mViewportRect = new RectF(x, y, x + width, y + height);
mZoomFactor = zoom;
}
@ -97,38 +106,35 @@ public class ViewportMetrics {
public RectF getClampedViewport() {
RectF clampedViewport = new RectF(mViewportRect);
// While the viewport size ought to never exceed the page size, we
// do the clamping in this order to make sure that the origin is
// never negative.
if (clampedViewport.right > mPageSize.width)
clampedViewport.offset(mPageSize.width - clampedViewport.right, 0);
if (clampedViewport.left < 0)
clampedViewport.offset(-clampedViewport.left, 0);
// The viewport bounds ought to never exceed the page bounds.
if (clampedViewport.right > mPageRect.right)
clampedViewport.offset(mPageRect.right - clampedViewport.right, 0);
if (clampedViewport.left < mPageRect.left)
clampedViewport.offset(mPageRect.left - clampedViewport.left, 0);
if (clampedViewport.bottom > mPageSize.height)
clampedViewport.offset(0, mPageSize.height - clampedViewport.bottom);
if (clampedViewport.top < 0)
clampedViewport.offset(0, -clampedViewport.top);
if (clampedViewport.bottom > mPageRect.bottom)
clampedViewport.offset(0, mPageRect.bottom - clampedViewport.bottom);
if (clampedViewport.top < mPageRect.top)
clampedViewport.offset(0, mPageRect.top - clampedViewport.top);
return clampedViewport;
}
public FloatSize getPageSize() {
return mPageSize;
public RectF getPageRect() {
return mPageRect;
}
public FloatSize getCssPageSize() {
return mCssPageSize;
public RectF getCssPageRect() {
return mCssPageRect;
}
public float getZoomFactor() {
return mZoomFactor;
}
public void setPageSize(FloatSize pageSize, FloatSize cssPageSize) {
mPageSize = pageSize;
mCssPageSize = cssPageSize;
public void setPageRect(RectF pageRect, RectF cssPageRect) {
mPageRect = pageRect;
mCssPageRect = cssPageRect;
}
public void setViewport(RectF viewport) {
@ -155,9 +161,9 @@ public class ViewportMetrics {
* after scaling.
*/
public void scaleTo(float newZoomFactor, PointF focus) {
// mCssPageSize is invariant, since we're setting the scale factor
// here. The page size is based on the CSS page size.
mPageSize = mCssPageSize.scale(newZoomFactor);
// mCssPageRect is invariant, since we're setting the scale factor
// here. The page rect is based on the CSS page rect.
mPageRect = RectUtils.scale(mCssPageRect, newZoomFactor);
float scaleFactor = newZoomFactor / mZoomFactor;
PointF origin = getOrigin();
@ -178,16 +184,16 @@ public class ViewportMetrics {
*/
public ViewportMetrics interpolate(ViewportMetrics to, float t) {
ViewportMetrics result = new ViewportMetrics();
result.mPageSize = mPageSize.interpolate(to.mPageSize, t);
result.mCssPageSize = mCssPageSize.interpolate(to.mCssPageSize, t);
result.mPageRect = RectUtils.interpolate(mPageRect, to.mPageRect, t);
result.mCssPageRect = RectUtils.interpolate(mCssPageRect, to.mCssPageRect, t);
result.mZoomFactor = FloatUtils.interpolate(mZoomFactor, to.mZoomFactor, t);
result.mViewportRect = RectUtils.interpolate(mViewportRect, to.mViewportRect, t);
return result;
}
public boolean fuzzyEquals(ViewportMetrics other) {
return mPageSize.fuzzyEquals(other.mPageSize)
&& mCssPageSize.fuzzyEquals(other.mCssPageSize)
return RectUtils.fuzzyEquals(mPageRect, other.mPageRect)
&& RectUtils.fuzzyEquals(mCssPageRect, other.mCssPageRect)
&& RectUtils.fuzzyEquals(mViewportRect, other.mViewportRect)
&& FloatUtils.fuzzyEquals(mZoomFactor, other.mZoomFactor);
}
@ -198,15 +204,19 @@ public class ViewportMetrics {
int height = Math.round(mViewportRect.height());
int width = Math.round(mViewportRect.width());
StringBuffer sb = new StringBuffer(256);
StringBuffer sb = new StringBuffer(512);
sb.append("{ \"x\" : ").append(mViewportRect.left)
.append(", \"y\" : ").append(mViewportRect.top)
.append(", \"width\" : ").append(width)
.append(", \"height\" : ").append(height)
.append(", \"pageWidth\" : ").append(mPageSize.width)
.append(", \"pageHeight\" : ").append(mPageSize.height)
.append(", \"cssPageWidth\" : ").append(mCssPageSize.width)
.append(", \"cssPageHeight\" : ").append(mCssPageSize.height)
.append(", \"pageLeft\" : ").append(mPageRect.left)
.append(", \"pageTop\" : ").append(mPageRect.top)
.append(", \"pageRight\" : ").append(mPageRect.right)
.append(", \"pageBottom\" : ").append(mPageRect.bottom)
.append(", \"cssPageLeft\" : ").append(mCssPageRect.left)
.append(", \"cssPageTop\" : ").append(mCssPageRect.top)
.append(", \"cssPageRight\" : ").append(mCssPageRect.right)
.append(", \"cssPageBottom\" : ").append(mCssPageRect.bottom)
.append(", \"zoom\" : ").append(mZoomFactor)
.append(" }");
return sb.toString();
@ -214,10 +224,10 @@ public class ViewportMetrics {
@Override
public String toString() {
StringBuffer buff = new StringBuffer(128);
StringBuffer buff = new StringBuffer(256);
buff.append("v=").append(mViewportRect.toString())
.append(" p=").append(mPageSize.toString())
.append(" c=").append(mCssPageSize.toString())
.append(" p=").append(mPageRect.toString())
.append(" c=").append(mCssPageRect.toString())
.append(" z=").append(mZoomFactor);
return buff.toString();
}

View File

@ -114,6 +114,7 @@ abstract class Axis {
protected abstract float getOrigin();
protected abstract float getViewportLength();
protected abstract float getPageStart();
protected abstract float getPageLength();
Axis(SubdocumentScrollHelper subscroller) {
@ -124,6 +125,10 @@ abstract class Axis {
return getOrigin() + getViewportLength();
}
private float getPageEnd() {
return getPageStart() + getPageLength();
}
void startTouch(float pos) {
mVelocity = 0.0f;
mScrollingDisabled = false;
@ -165,8 +170,8 @@ abstract class Axis {
}
private Overscroll getOverscroll() {
boolean minus = (getOrigin() < 0.0f);
boolean plus = (getViewportEnd() > getPageLength());
boolean minus = (getOrigin() < getPageStart());
boolean plus = (getViewportEnd() > getPageEnd());
if (minus && plus) {
return Overscroll.BOTH;
} else if (minus) {
@ -182,9 +187,9 @@ abstract class Axis {
// overscrolled on this axis, returns 0.
private float getExcess() {
switch (getOverscroll()) {
case MINUS: return -getOrigin();
case PLUS: return getViewportEnd() - getPageLength();
case BOTH: return getViewportEnd() - getPageLength() - getOrigin();
case MINUS: return getPageStart() - getOrigin();
case PLUS: return getViewportEnd() - getPageEnd();
case BOTH: return (getViewportEnd() - getPageEnd()) + (getPageStart() - getOrigin());
default: return 0.0f;
}
}

View File

@ -165,16 +165,16 @@ public class PanZoomController
}
});
} else if (MESSAGE_ZOOM_PAGE.equals(event)) {
FloatSize pageSize = mController.getCssPageSize();
RectF cssPageRect = mController.getCssPageRect();
RectF viewableRect = mController.getCssViewport();
float y = viewableRect.top;
// attempt to keep zoom keep focused on the center of the viewport
float newHeight = viewableRect.height() * pageSize.width / viewableRect.width();
float newHeight = viewableRect.height() * cssPageRect.width() / viewableRect.width();
float dh = viewableRect.height() - newHeight; // increase in the height
final RectF r = new RectF(0.0f,
y + dh/2,
pageSize.width,
cssPageRect.width(),
y + dh/2 + newHeight);
mController.post(new Runnable() {
public void run() {
@ -294,7 +294,7 @@ public class PanZoomController
}
/** This must be called on the UI thread. */
public void pageSizeUpdated() {
public void pageRectUpdated() {
if (mState == PanZoomState.NOTHING) {
synchronized (mController) {
ViewportMetrics validated = getValidViewportMetrics();
@ -775,7 +775,7 @@ public class PanZoomController
/* First, we adjust the zoom factor so that we can make no overscrolled area visible. */
float zoomFactor = viewportMetrics.getZoomFactor();
FloatSize pageSize = viewportMetrics.getPageSize();
RectF pageRect = viewportMetrics.getPageRect();
RectF viewport = viewportMetrics.getViewport();
float focusX = viewport.width() / 2.0f;
@ -795,16 +795,16 @@ public class PanZoomController
}
// Ensure minZoomFactor keeps the page at least as big as the viewport.
if (pageSize.width > 0) {
float scaleFactor = viewport.width() / pageSize.width;
if (pageRect.width() > 0) {
float scaleFactor = viewport.width() / pageRect.width();
minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor);
if (viewport.width() > pageSize.width)
if (viewport.width() > pageRect.width())
focusX = 0.0f;
}
if (pageSize.height > 0) {
float scaleFactor = viewport.height() / pageSize.height;
if (pageRect.height() > 0) {
float scaleFactor = viewport.height() / pageRect.height();
minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor);
if (viewport.height() > pageSize.height)
if (viewport.height() > pageRect.height())
focusY = 0.0f;
}
@ -837,7 +837,9 @@ public class PanZoomController
@Override
protected float getViewportLength() { return mController.getViewportSize().width; }
@Override
protected float getPageLength() { return mController.getPageSize().width; }
protected float getPageStart() { return mController.getPageRect().left; }
@Override
protected float getPageLength() { return mController.getPageRect().width(); }
}
private class AxisY extends Axis {
@ -847,7 +849,9 @@ public class PanZoomController
@Override
protected float getViewportLength() { return mController.getViewportSize().height; }
@Override
protected float getPageLength() { return mController.getPageSize().height; }
protected float getPageStart() { return mController.getPageRect().top; }
@Override
protected float getPageLength() { return mController.getPageRect().height(); }
}
/*