[Libreoffice-commits] core.git: 11 commits - android/experimental
Tomaž Vajngerl
tomaz.vajngerl at collabora.com
Sun Sep 28 13:31:04 PDT 2014
android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java | 10
android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java | 35 -
android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java | 6
android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java | 3
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ZoomConstraints.java | 46 ++
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java | 20
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ImmutableViewportMetrics.java | 170 ++++++-
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java | 118 +----
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerRenderer.java | 56 +-
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/MultiTileLayer.java | 54 --
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/PointUtils.java | 16
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/RectUtils.java | 35 -
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ScreenshotLayer.java | 60 ++
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ViewportMetrics.java | 95 ----
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/Axis.java | 92 ++--
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java | 214 ++++------
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java | 24 +
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/SubdocumentScrollHelper.java | 16
18 files changed, 589 insertions(+), 481 deletions(-)
New commits:
commit 27953d41222ba0410769b381525c59f4395301e3
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date: Sun Sep 28 22:30:38 2014 +0200
android: minimize the rounding error, clean-up MultiTileLayer
Change-Id: Ib167acf5914596b69ee240255aaab173a0570038
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index f808f57..ba7102e 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -28,10 +28,7 @@ public class LOKitThread extends Thread {
}
private boolean draw() throws InterruptedException {
- int pageWidth = mTileProvider.getPageWidth();
- int pageHeight = mTileProvider.getPageHeight();
-
- RectF rect = new RectF(0, 0, pageWidth, pageHeight);
+ RectF rect = new RectF(0, 0, mTileProvider.getPageWidth(), mTileProvider.getPageHeight());
DisplayMetrics displayMetrics = LibreOfficeMainActivity.mAppContext.getResources().getDisplayMetrics();
mViewportMetrics = new ImmutableViewportMetrics(displayMetrics);
mViewportMetrics = mViewportMetrics.setPageRect(rect, rect);
@@ -72,6 +69,8 @@ public class LOKitThread extends Thread {
boolean isReady = mTileProvider.isReady();
if (isReady) {
updateCheckbardImage();
+ RectF rect = new RectF(0, 0, mTileProvider.getPageWidth(), mTileProvider.getPageHeight());
+ mController.setPageRect(rect, rect);
mController.setForceRedraw();
}
return isReady;
@@ -79,13 +78,9 @@ public class LOKitThread extends Thread {
private void updateCheckbardImage() {
if (!mCheckboardImageSet) {
- Log.i(LOGTAG, "Generate thumbnail!");
Bitmap bitmap = mTileProvider.thumbnail();
- Log.i(LOGTAG, "Done generate thumbnail!");
if (bitmap != null) {
- Log.i(LOGTAG, "Setting checkboard image!");
mApplication.getLayerController().getView().changeCheckerboardBitmap(bitmap, mTileProvider.getPageWidth(), mTileProvider.getPageHeight());
- Log.i(LOGTAG, "Done setting checkboard image!!");
mCheckboardImageSet = true;
}
}
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index 5b1b718..77a833e 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -112,7 +112,11 @@ public class LOKitTileProvider implements TileProvider {
Bitmap bitmap = Bitmap.createBitmap(TILE_SIZE, TILE_SIZE, Bitmap.Config.ARGB_8888);
if (mDocument != null) {
- mDocument.paintTile(buffer, TILE_SIZE, TILE_SIZE, Math.round(pixelToTwip(x, mDPI)/zoom), Math.round(pixelToTwip(y, mDPI)/ zoom), Math.round(mTileWidth / zoom), Math.round(mTileHeight/zoom));
+ float twipX = pixelToTwip(x, mDPI) / zoom;
+ float twipY = pixelToTwip(y, mDPI) / zoom;
+ float twipWidth = mTileWidth / zoom;
+ float twipHeight = mTileHeight / zoom;
+ mDocument.paintTile(buffer, TILE_SIZE, TILE_SIZE, (int) twipX, (int) twipY, (int)twipWidth, (int)twipHeight);
} else {
Log.e(LOGTAG, "Document is null!!");
}
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/MultiTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/MultiTileLayer.java
index c4a445d..14a08e2 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/MultiTileLayer.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/MultiTileLayer.java
@@ -42,7 +42,6 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
-import android.util.Log;
import org.libreoffice.TileProvider;
import org.mozilla.gecko.util.FloatUtils;
@@ -51,23 +50,16 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
-/**
- * Encapsulates the logic needed to draw a layer made of multiple tiles.
- */
public class MultiTileLayer extends Layer {
private static final String LOGTAG = "MultiTileLayer";
private static int TILE_SIZE = 256;
- private final List<SubTile> mTiles;
+ private final List<SubTile> mTiles = new CopyOnWriteArrayList<SubTile>();
private TileProvider tileProvider;
- private float currentZoomFactor;
private RectF tileViewPort = new RectF();
- private boolean shouldRefreshZoom = true;
- private RectF currentPageRect = new RectF();
public MultiTileLayer() {
super();
- mTiles = new CopyOnWriteArrayList<SubTile>();
}
public void invalidate() {
@@ -131,10 +123,10 @@ public class MultiTileLayer extends Layer {
if (origin != null) {
Rect position = layer.getPosition();
- int positionX = origin.x + Math.round(layer.x / layer.zoom);
- int positionY = origin.y + Math.round(layer.y / layer.zoom);
- int tileSize = Math.round(256.0f / layer.zoom);
- position.set(positionX, positionY, positionX + tileSize, positionY + tileSize);
+ float positionX = origin.x + (layer.x / layer.zoom);
+ float positionY = origin.y + (layer.y / layer.zoom);
+ float tileSize = TILE_SIZE / layer.zoom;
+ position.set((int) positionX, (int) positionY, (int) (positionX + tileSize + 1), (int) (positionY + tileSize + 1));
layer.setPosition(position);
}
if (resolution >= 0.0f) {
@@ -170,10 +162,6 @@ public class MultiTileLayer extends Layer {
super.endTransaction();
}
- private RectF normlizeRect(RectF rect, FloatSize pageSize) {
- return new RectF(rect.left / pageSize.width, rect.top / pageSize.height, rect.right / pageSize.width, rect.bottom / pageSize.height);
- }
-
private RectF roundToTileSize(RectF input, int tileSize) {
float minX = (Math.round(input.left) / tileSize) * tileSize;
float minY = (Math.round(input.top) / tileSize) * tileSize;
@@ -198,12 +186,6 @@ public class MultiTileLayer extends Layer {
@Override
public void draw(RenderContext context) {
- if (tileProvider == null) {
- return;
- }
-
- currentPageRect = context.pageRect;
-
for (SubTile layer : mTiles) {
// Avoid work, only draw tiles that intersect with the viewport
RectF layerBounds = layer.getBounds(context);
@@ -229,19 +211,13 @@ public class MultiTileLayer extends Layer {
}
public void reevaluateTiles(ImmutableViewportMetrics viewportMetrics) {
- if (currentZoomFactor != viewportMetrics.zoomFactor) {
- currentZoomFactor = viewportMetrics.zoomFactor;
- }
-
RectF newTileViewPort = inflate(roundToTileSize(viewportMetrics.getViewport(), TILE_SIZE), TILE_SIZE);
- Log.i(LOGTAG, "reevaluateTiles ( " + viewportMetrics + " )");
-
if (tileViewPort != newTileViewPort) {
tileViewPort = newTileViewPort;
cleanTiles();
- addNewTiles();
- markTiles();
+ addNewTiles(viewportMetrics);
+ markTiles(viewportMetrics);
}
}
@@ -256,24 +232,24 @@ public class MultiTileLayer extends Layer {
mTiles.removeAll(tilesToRemove);
}
- private void addNewTiles() {
+ private void addNewTiles(ImmutableViewportMetrics viewportMetrics) {
for (float y = tileViewPort.top; y < tileViewPort.bottom; y += TILE_SIZE) {
- if (y > currentPageRect.height()) {
+ if (y > viewportMetrics.getPageHeight()) {
continue;
}
for (float x = tileViewPort.left; x < tileViewPort.right; x += TILE_SIZE) {
- if (x > currentPageRect.width()) {
+ if (x > viewportMetrics.getPageWidth()) {
continue;
}
boolean contains = false;
for (SubTile tile : mTiles) {
- if (tile.x == x && tile.y == y) {
+ if (tile.x == x && tile.y == y && tile.zoom == viewportMetrics.zoomFactor) {
contains = true;
}
}
if (!contains) {
- CairoImage image = tileProvider.createTile(x, y, currentZoomFactor);
- SubTile tile = new SubTile(image, (int)x, (int)y, currentZoomFactor);
+ CairoImage image = tileProvider.createTile(x, y, viewportMetrics.zoomFactor);
+ SubTile tile = new SubTile(image, (int)x, (int)y, viewportMetrics.zoomFactor);
tile.beginTransaction();
mTiles.add(tile);
}
@@ -281,9 +257,9 @@ public class MultiTileLayer extends Layer {
}
}
- private void markTiles() {
+ private void markTiles(ImmutableViewportMetrics viewportMetrics) {
for (SubTile tile : mTiles) {
- if (FloatUtils.fuzzyEquals(tile.zoom, currentZoomFactor)) {
+ if (FloatUtils.fuzzyEquals(tile.zoom, viewportMetrics.zoomFactor)) {
RectF tileRect = new RectF(tile.x, tile.y, tile.x + TILE_SIZE, tile.y + TILE_SIZE);
if (!RectF.intersects(tileViewPort, tileRect)) {
tile.markForRemoval();
commit 295f3c12dfc76b6faa438074bc77f8ac8ecadf06
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date: Sun Sep 28 21:44:56 2014 +0200
android: LayerRendered - rename member to mScreenShotLayer
Change-Id: I16fbda06c75bbf80e7d2c2b045418297589c6ff7
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerRenderer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerRenderer.java
index 85ef846..dcedaae 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerRenderer.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerRenderer.java
@@ -48,7 +48,7 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
private final LayerView mView;
private final SingleTileLayer mBackgroundLayer;
- private final ScreenshotLayer mCheckerboardLayer;
+ private final ScreenshotLayer mScreenshotLayer;
private final NinePatchTileLayer mShadowLayer;
private TextLayer mFrameRateLayer;
private final ScrollbarLayer mHorizScrollLayer;
@@ -82,9 +82,6 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
private int mSampleHandle;
private int mTMatrixHandle;
- private int mSurfaceWidth;
- private int mSurfaceHeight;
-
// column-major matrix applied to each vertex to shift the viewport from
// one ranging from (-1, -1),(1,1) to (0,0),(1,1) and to scale all sizes by
// a factor of 2 to fill up the screen
@@ -129,33 +126,33 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
"}\n";
public void setCheckerboardBitmap(Bitmap bitmap, float pageWidth, float pageHeight) {
- mCheckerboardLayer.setBitmap(bitmap);
- mCheckerboardLayer.beginTransaction();
+ mScreenshotLayer.setBitmap(bitmap);
+ mScreenshotLayer.beginTransaction();
try {
- mCheckerboardLayer.setPosition(new Rect(0, 0, Math.round(pageWidth),
+ mScreenshotLayer.setPosition(new Rect(0, 0, Math.round(pageWidth),
Math.round(pageHeight)));
- mCheckerboardLayer.invalidate();
+ mScreenshotLayer.invalidate();
} finally {
- mCheckerboardLayer.endTransaction();
+ mScreenshotLayer.endTransaction();
}
}
public void updateCheckerboardBitmap(Bitmap bitmap, float x, float y,
float width, float height,
float pageWidth, float pageHeight) {
- mCheckerboardLayer.updateBitmap(bitmap, x, y, width, height);
- mCheckerboardLayer.beginTransaction();
+ mScreenshotLayer.updateBitmap(bitmap, x, y, width, height);
+ mScreenshotLayer.beginTransaction();
try {
- mCheckerboardLayer.setPosition(new Rect(0, 0, Math.round(pageWidth),
+ mScreenshotLayer.setPosition(new Rect(0, 0, Math.round(pageWidth),
Math.round(pageHeight)));
- mCheckerboardLayer.invalidate();
+ mScreenshotLayer.invalidate();
} finally {
- mCheckerboardLayer.endTransaction();
+ mScreenshotLayer.endTransaction();
}
}
public void resetCheckerboard() {
- mCheckerboardLayer.reset();
+ mScreenshotLayer.reset();
}
public LayerRenderer(LayerView view) {
@@ -166,7 +163,7 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
CairoImage backgroundImage = new BufferedCairoImage(controller.getBackgroundPattern());
mBackgroundLayer = new SingleTileLayer(true, backgroundImage);
- mCheckerboardLayer = ScreenshotLayer.create();
+ mScreenshotLayer = ScreenshotLayer.create();
CairoImage shadowImage = new BufferedCairoImage(controller.getShadowPattern());
mShadowLayer = new NinePatchTileLayer(shadowImage);
@@ -196,6 +193,20 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
}
}
+ public void destroy() {
+ DirectBufferAllocator.free(mCoordByteBuffer);
+ mCoordByteBuffer = null;
+ mCoordBuffer = null;
+ mScreenshotLayer.destroy();
+ mBackgroundLayer.destroy();
+ mShadowLayer.destroy();
+ mHorizScrollLayer.destroy();
+ mVertScrollLayer.destroy();
+ if (mFrameRateLayer != null) {
+ mFrameRateLayer.destroy();
+ }
+ }
+
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
checkMonitoringEnabled();
createDefaultProgram();
@@ -322,9 +333,6 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
}
public void onSurfaceChanged(GL10 gl, final int width, final int height) {
- mSurfaceWidth = width;
- mSurfaceHeight = height;
-
GLES20.glViewport(0, 0, width, height);
if (mFrameRateLayer != null) {
@@ -510,7 +518,7 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
if (rootLayer != null) mUpdated &= rootLayer.update(mPageContext); // called on compositor thread
mUpdated &= mBackgroundLayer.update(mScreenContext); // called on compositor thread
mUpdated &= mShadowLayer.update(mPageContext); // called on compositor thread
- mUpdated &= mCheckerboardLayer.update(mPageContext); // called on compositor thread
+ mUpdated &= mScreenshotLayer.update(mPageContext); // called on compositor thread
if (mFrameRateLayer != null) mUpdated &= mFrameRateLayer.update(mScreenContext); // called on compositor thread
mUpdated &= mVertScrollLayer.update(mPageContext); // called on compositor thread
mUpdated &= mHorizScrollLayer.update(mPageContext); // called on compositor thread
@@ -591,13 +599,13 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
if (mView.getController().checkerboardShouldShowChecks()) {
/* Find the area the root layer will render into, to mask the checkerboard layer */
Rect rootMask = getMaskForLayer(mView.getController().getRoot());
- mCheckerboardLayer.setMask(rootMask);
+ mScreenshotLayer.setMask(rootMask);
/* Scissor around the page-rect, in case the page has shrunk
* since the screenshot layer was last updated.
*/
setScissorRect(); // Calls glEnable(GL_SCISSOR_TEST))
- mCheckerboardLayer.draw(mPageContext);
+ mScreenshotLayer.draw(mPageContext);
}
}
@@ -644,7 +652,7 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
/* restrict the viewport to page bounds so we don't
* count overscroll as checkerboard */
- if (!viewport.intersect(0, 0, mPageRect.width(), mPageRect.height())) {
+ if (!viewport.intersect(mPageRect)) {
/* if the rectangles don't intersect
intersect() doesn't change viewport
so we set it to empty by hand */
commit d935e7be2c8818d028ab5ce718e7c9c5126cbf32
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date: Sun Sep 28 11:58:58 2014 +0200
android: revert ScreenshotLayer draw method back
Own draw method expands the picture correctly but for some reason
the SingleTileLayer draw method does not so revert back.
Change-Id: Ie8e39fc46b84ae410439a781928ff79bc1503d10
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ScreenshotLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ScreenshotLayer.java
index 5f82213..c52b39b 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ScreenshotLayer.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ScreenshotLayer.java
@@ -8,10 +8,13 @@ package org.mozilla.gecko.gfx;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
+import android.graphics.Rect;
+import android.opengl.GLES20;
import org.libreoffice.kit.DirectBufferAllocator;
import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
public class ScreenshotLayer extends SingleTileLayer {
private static final int SCREENSHOT_SIZE_LIMIT = 1048576;
@@ -75,8 +78,61 @@ public class ScreenshotLayer extends SingleTileLayer {
@Override
public void draw(RenderContext context) {
- if (mHasImage)
- super.draw(context);
+ // mTextureIDs may be null here during startup if Layer.java's draw method
+ // failed to acquire the transaction lock and call performUpdates.
+ if (!initialized())
+ return;
+
+ float txl, txr, txb, txt;
+
+ Rect position = getPosition();
+
+ float bw = mBufferSize.width;
+ float bh = mBufferSize.height;
+ float iw = mImageSize.width;
+ float ih = mImageSize.height;
+
+ float pw = context.pageRect.width();
+ float ph = context.pageRect.height();
+
+ float vl = context.viewport.left;
+ float vr = context.viewport.right;
+ float vt = context.viewport.top;
+ float vb = context.viewport.bottom;
+
+ float vw = vr - vl;
+ float vh = vb - vt;
+
+ txl = (iw/bw) * (vl / pw);
+ txr = (iw/bw) * (vr / pw);
+ txt = 1.0f - ((ih/bh) * (vt / ph));
+ txb = 1.0f - ((ih/bh) * (vb / ph));
+
+ float[] coords = {
+ 0.0f, 0.0f, 0.0f, txl, txb,
+ 0.0f, 1.0f, 0.0f, txl, txt,
+ 1.0f, 0.0f, 0.0f, txr, txb,
+ 1.0f, 1.0f, 0.0f, txr, txt,
+ };
+
+ FloatBuffer coordBuffer = context.coordBuffer;
+ int positionHandle = context.positionHandle;
+ int textureHandle = context.textureHandle;
+
+ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, getTextureID());
+
+ // Make sure we are at position zero in the buffer
+ coordBuffer.position(0);
+ coordBuffer.put(coords);
+
+ // Vertex coordinates are x,y,z starting at position 0 into the buffer.
+ coordBuffer.position(0);
+ GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer);
+
+ // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer.
+ coordBuffer.position(3);
+ GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer);
+ GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}
/** A Cairo image that simply saves a buffer of pixel data. */
commit ebc25c427936708b8e32e563d6735575d6ac9f92
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date: Sat Sep 27 23:38:19 2014 +0200
android: replace with ImmutableViewportMetrics (Fennec import)
Change-Id: I46509f8be4dc49dac45eb98059dad25e150988dd
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java
index f16b2da..80210a7 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java
@@ -2,8 +2,8 @@ package org.libreoffice;
import android.graphics.Rect;
+import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
import org.mozilla.gecko.gfx.IntSize;
-import org.mozilla.gecko.gfx.ViewportMetrics;
public class LOEvent {
@@ -15,7 +15,7 @@ public class LOEvent {
public static final int LOAD = 6;
public int mType;
- private ViewportMetrics mViewportMetrics;
+ private ImmutableViewportMetrics mViewportMetrics;
private String mTypeString;
private int mPartIndex;
private String mFilename;
@@ -35,7 +35,7 @@ public class LOEvent {
mTypeString = "Tile size";
}
- public LOEvent(int type, ViewportMetrics viewportMetrics) {
+ public LOEvent(int type, ImmutableViewportMetrics viewportMetrics) {
mType = type;
mTypeString = "Viewport";
mViewportMetrics = viewportMetrics;
@@ -64,7 +64,7 @@ public class LOEvent {
return new LOEvent(TILE_SIZE, tileSize);
}
- public static LOEvent viewport(ViewportMetrics viewportMetrics) {
+ public static LOEvent viewport(ImmutableViewportMetrics viewportMetrics) {
return new LOEvent(VIEWPORT, viewportMetrics);
}
@@ -80,7 +80,7 @@ public class LOEvent {
return mTypeString;
}
- public ViewportMetrics getViewport() {
+ public ImmutableViewportMetrics getViewport() {
return mViewportMetrics;
}
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index ddc18d4..f808f57 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -7,8 +7,8 @@ import android.util.DisplayMetrics;
import android.util.Log;
import org.mozilla.gecko.gfx.GeckoLayerClient;
+import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
import org.mozilla.gecko.gfx.LayerController;
-import org.mozilla.gecko.gfx.ViewportMetrics;
import java.util.concurrent.LinkedBlockingQueue;
@@ -18,7 +18,7 @@ public class LOKitThread extends Thread {
public LinkedBlockingQueue<LOEvent> mEventQueue = new LinkedBlockingQueue<LOEvent>();
private LibreOfficeMainActivity mApplication;
private TileProvider mTileProvider;
- private ViewportMetrics mViewportMetrics;
+ private ImmutableViewportMetrics mViewportMetrics;
private boolean mCheckboardImageSet = false;
private GeckoLayerClient mLayerClient;
private LayerController mController;
@@ -33,8 +33,8 @@ public class LOKitThread extends Thread {
RectF rect = new RectF(0, 0, pageWidth, pageHeight);
DisplayMetrics displayMetrics = LibreOfficeMainActivity.mAppContext.getResources().getDisplayMetrics();
- mViewportMetrics = new ViewportMetrics(displayMetrics);
- mViewportMetrics.setPageRect(rect, rect);
+ mViewportMetrics = new ImmutableViewportMetrics(displayMetrics);
+ mViewportMetrics = mViewportMetrics.setPageRect(rect, rect);
GeckoLayerClient layerClient = mApplication.getLayerClient();
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
index e3f5793..e847c01 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
@@ -65,10 +65,10 @@ public class GeckoLayerClient implements LayerView.Listener {
private MultiTileLayer mRootLayer;
/* The viewport that Gecko is currently displaying. */
- private ViewportMetrics mGeckoViewport;
+ private ImmutableViewportMetrics mGeckoViewport;
/* The viewport that Gecko will display when drawing is finished */
- private ViewportMetrics mNewGeckoViewport;
+ private ImmutableViewportMetrics mNewGeckoViewport;
private Context mContext;
private boolean mPendingViewportAdjust;
private boolean mViewportSizeChanged;
@@ -109,7 +109,7 @@ public class GeckoLayerClient implements LayerView.Listener {
}
- public void endDrawing(ViewportMetrics viewportMetrics) {
+ public void endDrawing(ImmutableViewportMetrics viewportMetrics) {
synchronized (mLayerController) {
try {
mNewGeckoViewport = viewportMetrics;
@@ -128,19 +128,18 @@ public class GeckoLayerClient implements LayerView.Listener {
// java is the One True Source of this information, and allowing JS
// to override can lead to race conditions where this data gets clobbered.
FloatSize viewportSize = mLayerController.getViewportSize();
- mGeckoViewport = mNewGeckoViewport;
- mGeckoViewport.setSize(viewportSize);
+ mGeckoViewport = mNewGeckoViewport.setViewportSize(viewportSize.width, viewportSize.height);
RectF position = mGeckoViewport.getViewport();
mRootLayer.setPosition(RectUtils.round(position));
- mRootLayer.setResolution(mGeckoViewport.getZoomFactor());
+ mRootLayer.setResolution(mGeckoViewport.zoomFactor);
Log.e(LOGTAG, "### updateViewport onlyUpdatePageSize=" + onlyUpdatePageSize + " getTileViewport " + mGeckoViewport);
if (onlyUpdatePageSize) {
// Don't adjust page size when zooming unless zoom levels are
// approximately equal.
- if (FloatUtils.fuzzyEquals(mLayerController.getViewportMetrics().zoomFactor, mGeckoViewport.getZoomFactor())) {
+ if (FloatUtils.fuzzyEquals(mLayerController.getViewportMetrics().zoomFactor, mGeckoViewport.zoomFactor)) {
mLayerController.setPageRect(mGeckoViewport.getPageRect(), mGeckoViewport.getCssPageRect());
}
} else {
@@ -193,8 +192,7 @@ public class GeckoLayerClient implements LayerView.Listener {
void adjustViewport(DisplayPortMetrics displayPort) {
ImmutableViewportMetrics metrics = mLayerController.getViewportMetrics();
- ViewportMetrics clampedMetrics = new ViewportMetrics(metrics);
- clampedMetrics.setViewport(clampedMetrics.getClampedViewport());
+ ImmutableViewportMetrics clampedMetrics = metrics.clamp();
if (displayPort == null) {
displayPort = DisplayPortCalculator.calculate(metrics,
@@ -244,7 +242,7 @@ public class GeckoLayerClient implements LayerView.Listener {
}
}
- public ViewportMetrics getGeckoViewportMetrics() {
+ public ImmutableViewportMetrics getGeckoViewportMetrics() {
return mGeckoViewport;
}
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ImmutableViewportMetrics.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ImmutableViewportMetrics.java
index 5403c80..35b4175 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ImmutableViewportMetrics.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ImmutableViewportMetrics.java
@@ -7,6 +7,9 @@ package org.mozilla.gecko.gfx;
import android.graphics.PointF;
import android.graphics.RectF;
+import android.util.DisplayMetrics;
+
+import org.mozilla.gecko.util.FloatUtils;
/**
* ImmutableViewportMetrics are used to store the viewport metrics
@@ -31,26 +34,33 @@ public class ImmutableViewportMetrics {
public final float viewportRectBottom;
public final float zoomFactor;
- public ImmutableViewportMetrics(ViewportMetrics m) {
- RectF viewportRect = m.getViewport();
- viewportRectLeft = viewportRect.left;
- viewportRectTop = viewportRect.top;
- viewportRectRight = viewportRect.right;
- viewportRectBottom = viewportRect.bottom;
-
- RectF pageRect = m.getPageRect();
- pageRectLeft = pageRect.left;
- pageRectTop = pageRect.top;
- pageRectRight = pageRect.right;
- pageRectBottom = pageRect.bottom;
-
- RectF cssPageRect = m.getCssPageRect();
- cssPageRectLeft = cssPageRect.left;
- cssPageRectTop = cssPageRect.top;
- cssPageRectRight = cssPageRect.right;
- cssPageRectBottom = cssPageRect.bottom;
+ public ImmutableViewportMetrics(DisplayMetrics metrics) {
+ viewportRectLeft = pageRectLeft = cssPageRectLeft = 0;
+ viewportRectTop = pageRectTop = cssPageRectTop = 0;
+ viewportRectRight = pageRectRight = cssPageRectRight = metrics.widthPixels;
+ viewportRectBottom = pageRectBottom = cssPageRectBottom = metrics.heightPixels;
+ zoomFactor = 1.0f;
+ }
- zoomFactor = m.getZoomFactor();
+ private ImmutableViewportMetrics(float aPageRectLeft, float aPageRectTop,
+ float aPageRectRight, float aPageRectBottom, float aCssPageRectLeft,
+ float aCssPageRectTop, float aCssPageRectRight, float aCssPageRectBottom,
+ float aViewportRectLeft, float aViewportRectTop, float aViewportRectRight,
+ float aViewportRectBottom, float aZoomFactor)
+ {
+ pageRectLeft = aPageRectLeft;
+ pageRectTop = aPageRectTop;
+ pageRectRight = aPageRectRight;
+ pageRectBottom = aPageRectBottom;
+ cssPageRectLeft = aCssPageRectLeft;
+ cssPageRectTop = aCssPageRectTop;
+ cssPageRectRight = aCssPageRectRight;
+ cssPageRectBottom = aCssPageRectBottom;
+ viewportRectLeft = aViewportRectLeft;
+ viewportRectTop = aViewportRectTop;
+ viewportRectRight = aViewportRectRight;
+ viewportRectBottom = aViewportRectBottom;
+ zoomFactor = aZoomFactor;
}
public float getWidth() {
@@ -61,8 +71,6 @@ public class ImmutableViewportMetrics {
return viewportRectBottom - viewportRectTop;
}
- // some helpers to make ImmutableViewportMetrics act more like ViewportMetrics
-
public PointF getOrigin() {
return new PointF(viewportRectLeft, viewportRectTop);
}
@@ -98,6 +106,126 @@ public class ImmutableViewportMetrics {
return new RectF(cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom);
}
+ /*
+ * Returns the viewport metrics that represent a linear transition between "this" and "to" at
+ * time "t", which is on the scale [0, 1). This function interpolates all values stored in
+ * the viewport metrics.
+ */
+ public ImmutableViewportMetrics interpolate(ImmutableViewportMetrics to, float t) {
+ return new ImmutableViewportMetrics(
+ FloatUtils.interpolate(pageRectLeft, to.pageRectLeft, t),
+ FloatUtils.interpolate(pageRectTop, to.pageRectTop, t),
+ FloatUtils.interpolate(pageRectRight, to.pageRectRight, t),
+ FloatUtils.interpolate(pageRectBottom, to.pageRectBottom, t),
+ FloatUtils.interpolate(cssPageRectLeft, to.cssPageRectLeft, t),
+ FloatUtils.interpolate(cssPageRectTop, to.cssPageRectTop, t),
+ FloatUtils.interpolate(cssPageRectRight, to.cssPageRectRight, t),
+ FloatUtils.interpolate(cssPageRectBottom, to.cssPageRectBottom, t),
+ FloatUtils.interpolate(viewportRectLeft, to.viewportRectLeft, t),
+ FloatUtils.interpolate(viewportRectTop, to.viewportRectTop, t),
+ FloatUtils.interpolate(viewportRectRight, to.viewportRectRight, t),
+ FloatUtils.interpolate(viewportRectBottom, to.viewportRectBottom, t),
+ FloatUtils.interpolate(zoomFactor, to.zoomFactor, t));
+ }
+
+ public ImmutableViewportMetrics setViewportSize(float width, float height) {
+ return new ImmutableViewportMetrics(
+ pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
+ cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
+ viewportRectLeft, viewportRectTop, viewportRectLeft + width, viewportRectTop + height,
+ zoomFactor);
+ }
+
+ public ImmutableViewportMetrics setViewportOrigin(float newOriginX, float newOriginY) {
+ return new ImmutableViewportMetrics(
+ pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
+ cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
+ newOriginX, newOriginY, newOriginX + getWidth(), newOriginY + getHeight(),
+ zoomFactor);
+ }
+
+ public ImmutableViewportMetrics setZoomFactor(float newZoomFactor) {
+ return new ImmutableViewportMetrics(
+ pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
+ cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
+ viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom,
+ newZoomFactor);
+ }
+
+ public ImmutableViewportMetrics offsetViewportBy(float dx, float dy) {
+ return setViewportOrigin(viewportRectLeft + dx, viewportRectTop + dy);
+ }
+
+ public ImmutableViewportMetrics setPageRect(RectF pageRect, RectF cssPageRect) {
+ return new ImmutableViewportMetrics(
+ pageRect.left, pageRect.top, pageRect.right, pageRect.bottom,
+ cssPageRect.left, cssPageRect.top, cssPageRect.right, cssPageRect.bottom,
+ viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom,
+ zoomFactor);
+ }
+
+ /* This will set the zoom factor and re-scale page-size and viewport offset
+ * accordingly. The given focus will remain at the same point on the screen
+ * after scaling.
+ */
+ public ImmutableViewportMetrics scaleTo(float newZoomFactor, PointF focus) {
+ // cssPageRect* is invariant, since we're setting the scale factor
+ // here. The page rect is based on the CSS page rect.
+ float newPageRectLeft = cssPageRectLeft * newZoomFactor;
+ float newPageRectTop = cssPageRectTop * newZoomFactor;
+ float newPageRectRight = cssPageRectLeft + ((cssPageRectRight - cssPageRectLeft) * newZoomFactor);
+ float newPageRectBottom = cssPageRectTop + ((cssPageRectBottom - cssPageRectTop) * newZoomFactor);
+
+ PointF origin = getOrigin();
+ origin.offset(focus.x, focus.y);
+ origin = PointUtils.scale(origin, newZoomFactor / zoomFactor);
+ origin.offset(-focus.x, -focus.y);
+
+ return new ImmutableViewportMetrics(
+ newPageRectLeft, newPageRectTop, newPageRectRight, newPageRectBottom,
+ cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
+ origin.x, origin.y, origin.x + getWidth(), origin.y + getHeight(),
+ newZoomFactor);
+ }
+
+ /** Clamps the viewport to remain within the page rect. */
+ public ImmutableViewportMetrics clamp() {
+ RectF newViewport = getViewport();
+
+ // The viewport bounds ought to never exceed the page bounds.
+ if (newViewport.right > pageRectRight)
+ newViewport.offset(pageRectRight - newViewport.right, 0);
+ if (newViewport.left < pageRectLeft)
+ newViewport.offset(pageRectLeft - newViewport.left, 0);
+
+ if (newViewport.bottom > pageRectBottom)
+ newViewport.offset(0, pageRectBottom - newViewport.bottom);
+ if (newViewport.top < pageRectTop)
+ newViewport.offset(0, pageRectTop - newViewport.top);
+
+ return new ImmutableViewportMetrics(
+ pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
+ cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
+ newViewport.left, newViewport.top, newViewport.right, newViewport.bottom,
+ zoomFactor);
+ }
+
+ public boolean fuzzyEquals(ImmutableViewportMetrics other) {
+ return FloatUtils.fuzzyEquals(pageRectLeft, other.pageRectLeft)
+ && FloatUtils.fuzzyEquals(pageRectTop, other.pageRectTop)
+ && FloatUtils.fuzzyEquals(pageRectRight, other.pageRectRight)
+ && FloatUtils.fuzzyEquals(pageRectBottom, other.pageRectBottom)
+ && FloatUtils.fuzzyEquals(cssPageRectLeft, other.cssPageRectLeft)
+ && FloatUtils.fuzzyEquals(cssPageRectTop, other.cssPageRectTop)
+ && FloatUtils.fuzzyEquals(cssPageRectRight, other.cssPageRectRight)
+ && FloatUtils.fuzzyEquals(cssPageRectBottom, other.cssPageRectBottom)
+ && FloatUtils.fuzzyEquals(viewportRectLeft, other.viewportRectLeft)
+ && FloatUtils.fuzzyEquals(viewportRectTop, other.viewportRectTop)
+ && FloatUtils.fuzzyEquals(viewportRectRight, other.viewportRectRight)
+ && FloatUtils.fuzzyEquals(viewportRectBottom, other.viewportRectBottom)
+ && FloatUtils.fuzzyEquals(zoomFactor, other.zoomFactor);
+ }
+
@Override
public String toString() {
return "ImmutableViewportMetrics v=(" + viewportRectLeft + "," + viewportRectTop + ","
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java
index ca02e1c..2e6a4a0 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java
@@ -67,7 +67,7 @@ public class LayerController implements PanZoomTarget {
mContext = context;
mForceRedraw = true;
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
- mViewportMetrics = new ImmutableViewportMetrics(new ViewportMetrics(displayMetrics));
+ mViewportMetrics = new ImmutableViewportMetrics(displayMetrics);
mPanZoomController = new PanZoomController(this);
mView = new LayerView(context, this);
mCheckerboardShouldShowChecks = true;
@@ -127,9 +127,7 @@ public class LayerController implements PanZoomTarget {
* result in an infinite loop.
*/
public void setViewportSize(FloatSize size) {
- ViewportMetrics viewportMetrics = new ViewportMetrics(mViewportMetrics);
- viewportMetrics.setSize(size);
- mViewportMetrics = new ImmutableViewportMetrics(viewportMetrics);
+ mViewportMetrics = mViewportMetrics.setViewportSize(size.width, size.height);
if (mLayerClient != null) {
mLayerClient.viewportSizeChanged();
@@ -144,9 +142,7 @@ public class LayerController implements PanZoomTarget {
if (mViewportMetrics.getCssPageRect().equals(cssRect))
return;
- ViewportMetrics viewportMetrics = new ViewportMetrics(mViewportMetrics);
- viewportMetrics.setPageRect(rect, cssRect);
- mViewportMetrics = new ImmutableViewportMetrics(viewportMetrics);
+ mViewportMetrics = mViewportMetrics.setPageRect(rect, cssRect);
// Page size is owned by the layer client, so no need to notify it of
// this change.
@@ -163,20 +159,19 @@ public class LayerController implements PanZoomTarget {
* Sets the entire viewport metrics at once.
* You must hold the monitor while calling this.
*/
- public void setViewportMetrics(ViewportMetrics viewport) {
- mViewportMetrics = new ImmutableViewportMetrics(viewport);
+ public void setViewportMetrics(ImmutableViewportMetrics viewport) {
+ mViewportMetrics = viewport;
mView.requestRender();
notifyLayerClientOfGeometryChange();
}
- public void setAnimationTarget(ViewportMetrics viewport) {
+ public void setAnimationTarget(ImmutableViewportMetrics viewport) {
if (mLayerClient != null) {
// We know what the final viewport of the animation is going to be, so
// immediately request a draw of that area by setting the display port
// accordingly. This way we should have the content pre-rendered by the
// time the animation is done.
- ImmutableViewportMetrics metrics = new ImmutableViewportMetrics(viewport);
- DisplayPortMetrics displayPort = DisplayPortCalculator.calculate(metrics, null);
+ DisplayPortMetrics displayPort = DisplayPortCalculator.calculate(viewport, null);
mLayerClient.adjustViewport(displayPort);
}
}
@@ -232,9 +227,9 @@ public class LayerController implements PanZoomTarget {
ImmutableViewportMetrics viewportMetrics = mViewportMetrics;
PointF origin = viewportMetrics.getOrigin();
float zoom = viewportMetrics.zoomFactor;
- ViewportMetrics geckoViewport = mLayerClient.getGeckoViewportMetrics();
+ ImmutableViewportMetrics geckoViewport = mLayerClient.getGeckoViewportMetrics();
PointF geckoOrigin = geckoViewport.getOrigin();
- float geckoZoom = geckoViewport.getZoomFactor();
+ float geckoZoom = geckoViewport.zoomFactor;
// viewPoint + origin gives the coordinate in device pixels from the top-left corner of the page.
// Divided by zoom, this gives us the coordinate in CSS pixels from the top-left corner of the page.
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/PointUtils.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/PointUtils.java
index cdacc31..4eb07a3 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/PointUtils.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/PointUtils.java
@@ -10,7 +10,6 @@ import android.graphics.PointF;
import org.json.JSONException;
import org.json.JSONObject;
-import org.mozilla.gecko.util.FloatUtils;
public final class PointUtils {
public static PointF add(PointF one, PointF two) {
@@ -29,19 +28,10 @@ public final class PointUtils {
return new Point(Math.round(point.x), Math.round(point.y));
}
- /* Returns a new point that is a linear interpolation between start and end points. weight conrols the weighting
- * of each of the original points (weight = 1 returns endPoint, weight = 0 returns startPoint)
- */
- public static PointF interpolate(PointF startPoint, PointF endPoint, float weight) {
- float x = FloatUtils.interpolate(startPoint.x, endPoint.x, weight);
- float y = FloatUtils.interpolate(startPoint.y, endPoint.y, weight);
- return new PointF(x, y);
- }
-
- /* Computes the magnitude of the given vector. */
- public static float distance(PointF point) {
+ /* Computes the magnitude of the given vector. */
+ public static float distance(PointF point) {
return (float)Math.sqrt(point.x * point.x + point.y * point.y);
- }
+ }
/** Computes the scalar distance between two points. */
public static float distance(PointF one, PointF two) {
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/RectUtils.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/RectUtils.java
index 92ea78f..1608e91 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/RectUtils.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/RectUtils.java
@@ -10,22 +10,10 @@ import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
-import org.json.JSONException;
-import org.json.JSONObject;
import org.mozilla.gecko.util.FloatUtils;
public final class RectUtils {
- public static Rect create(JSONObject json) {
- try {
- int x = json.getInt("x");
- int y = json.getInt("y");
- int width = json.getInt("width");
- int height = json.getInt("height");
- return new Rect(x, y, x + width, y + height);
- } catch (JSONException e) {
- throw new RuntimeException(e);
- }
- }
+ private RectUtils() {}
public static RectF expand(RectF rect, float moreWidth, float moreHeight) {
float halfMoreWidth = moreWidth / 2;
@@ -63,8 +51,14 @@ public final class RectUtils {
/** Returns the nearest integer rect of the given rect. */
public static Rect round(RectF rect) {
- return new Rect(Math.round(rect.left), Math.round(rect.top),
- Math.round(rect.right), Math.round(rect.bottom));
+ Rect r = new Rect();
+ round(rect, r);
+ return r;
+ }
+
+ public static void round(RectF rect, Rect dest) {
+ dest.set(Math.round(rect.left), Math.round(rect.top),
+ Math.round(rect.right), Math.round(rect.bottom));
}
public static Rect roundIn(RectF rect) {
@@ -84,17 +78,6 @@ public final class RectUtils {
return new PointF(rect.left, rect.top);
}
- /*
- * Returns the rect that represents a linear transition between `from` and `to` at time `t`,
- * which is on the scale [0, 1).
- */
- public static RectF interpolate(RectF from, RectF to, float t) {
- return new RectF(FloatUtils.interpolate(from.left, to.left, t),
- FloatUtils.interpolate(from.top, to.top, t),
- FloatUtils.interpolate(from.right, to.right, t),
- FloatUtils.interpolate(from.bottom, to.bottom, t));
- }
-
public static boolean fuzzyEquals(RectF a, RectF b) {
if (a == null && b == null)
return true;
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ViewportMetrics.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ViewportMetrics.java
index 789bb0b..f8b5c2e0 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ViewportMetrics.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ViewportMetrics.java
@@ -11,7 +11,6 @@ import android.util.DisplayMetrics;
import org.json.JSONException;
import org.json.JSONObject;
-import org.mozilla.gecko.util.FloatUtils;
/**
* ViewportMetrics manages state and contains some utility functions related to
@@ -76,6 +75,16 @@ public class ViewportMetrics {
mZoomFactor = zoom;
}
+ public ViewportMetrics(float x, float y, float width, float height,
+ float pageLeft, float pageTop, float pageRight, float pageBottom,
+ float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom,
+ float zoom) {
+ 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;
+ }
+
public PointF getOrigin() {
return new PointF(mViewportRect.left, mViewportRect.top);
}
@@ -92,24 +101,6 @@ public class ViewportMetrics {
return RectUtils.scale(mViewportRect, 1/mZoomFactor);
}
- /** Returns the viewport rectangle, clamped within the page-size. */
- public RectF getClampedViewport() {
- RectF clampedViewport = new RectF(mViewportRect);
-
- // 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 > mPageRect.bottom)
- clampedViewport.offset(0, mPageRect.bottom - clampedViewport.bottom);
- if (clampedViewport.top < mPageRect.top)
- clampedViewport.offset(0, mPageRect.top - clampedViewport.top);
-
- return clampedViewport;
- }
-
public RectF getPageRect() {
return mPageRect;
}
@@ -146,48 +137,6 @@ public class ViewportMetrics {
mZoomFactor = zoomFactor;
}
- /* This will set the zoom factor and re-scale page-size and viewport offset
- * accordingly. The given focus will remain at the same point on the screen
- * after scaling.
- */
- public void scaleTo(float newZoomFactor, PointF focus) {
- // 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();
-
- origin.offset(focus.x, focus.y);
- origin = PointUtils.scale(origin, scaleFactor);
- origin.offset(-focus.x, -focus.y);
-
- setOrigin(origin);
-
- mZoomFactor = newZoomFactor;
- }
-
- /*
- * Returns the viewport metrics that represent a linear transition between `from` and `to` at
- * time `t`, which is on the scale [0, 1). This function interpolates the viewport rect, the
- * page size, the offset, and the zoom factor.
- */
- public ViewportMetrics interpolate(ViewportMetrics to, float t) {
- ViewportMetrics result = new ViewportMetrics(this);
- 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 RectUtils.fuzzyEquals(mPageRect, other.mPageRect)
- && RectUtils.fuzzyEquals(mCssPageRect, other.mCssPageRect)
- && RectUtils.fuzzyEquals(mViewportRect, other.mViewportRect)
- && FloatUtils.fuzzyEquals(mZoomFactor, other.mZoomFactor);
- }
-
public String toJSON() {
// Round off height and width. Since the height and width are the size of the screen, it
// makes no sense to send non-integer coordinates to Gecko.
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
index 02e45da..555c7ebe 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
@@ -16,7 +16,6 @@ import org.libreoffice.LOKitShell;
import org.libreoffice.LibreOfficeMainActivity;
import org.mozilla.gecko.ZoomConstraints;
import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
-import org.mozilla.gecko.gfx.ViewportMetrics;
import org.mozilla.gecko.util.FloatUtils;
import java.util.Timer;
@@ -118,10 +117,6 @@ public class PanZoomController
return mTarget.getViewportMetrics();
}
- private ViewportMetrics getMutableMetrics() {
- return new ViewportMetrics(getMetrics());
- }
-
// for debugging bug 713011; it can be taken out once that is resolved.
private void checkMainThread() {
if (mMainThread != Thread.currentThread()) {
@@ -195,8 +190,8 @@ public class PanZoomController
public void pageRectUpdated() {
if (mState == PanZoomState.NOTHING) {
synchronized (mTarget.getLock()) {
- ViewportMetrics validated = getValidViewportMetrics();
- if (! getMutableMetrics().fuzzyEquals(validated)) {
+ ImmutableViewportMetrics validated = getValidViewportMetrics();
+ if (!getMetrics().fuzzyEquals(validated)) {
// page size changed such that we are now in overscroll. snap to the
// the nearest valid viewport
mTarget.setViewportMetrics(validated);
@@ -421,13 +416,9 @@ public class PanZoomController
updatePosition();
}
- private void scrollBy(PointF point) {
- ViewportMetrics viewportMetrics = getMutableMetrics();
- PointF origin = viewportMetrics.getOrigin();
- origin.offset(point.x, point.y);
- viewportMetrics.setOrigin(origin);
-
- mTarget.setViewportMetrics(viewportMetrics);
+ private void scrollBy(float dx, float dy) {
+ ImmutableViewportMetrics scrolled = getMetrics().offsetViewportBy(dx, dy);
+ mTarget.setViewportMetrics(scrolled);
}
private void fling() {
@@ -443,10 +434,10 @@ public class PanZoomController
}
/* Performs a bounce-back animation to the given viewport metrics. */
- private void bounce(ViewportMetrics metrics) {
+ private void bounce(ImmutableViewportMetrics metrics) {
stopAnimationTimer();
- ViewportMetrics bounceStartMetrics = getMutableMetrics();
+ ImmutableViewportMetrics bounceStartMetrics = getMetrics();
if (bounceStartMetrics.fuzzyEquals(metrics)) {
setState(PanZoomState.NOTHING);
return;
@@ -520,7 +511,7 @@ public class PanZoomController
}
if (! mSubscroller.scrollBy(displacement)) {
synchronized (mTarget.getLock()) {
- scrollBy(displacement);
+ scrollBy(displacement.x, displacement.y);
}
}
}
@@ -558,10 +549,10 @@ public class PanZoomController
* The viewport metrics that represent the start and end of the bounce-back animation,
* respectively.
*/
- private ViewportMetrics mBounceStartMetrics;
- private ViewportMetrics mBounceEndMetrics;
+ private ImmutableViewportMetrics mBounceStartMetrics;
+ private ImmutableViewportMetrics mBounceEndMetrics;
- BounceRunnable(ViewportMetrics startMetrics, ViewportMetrics endMetrics) {
+ BounceRunnable(ImmutableViewportMetrics startMetrics, ImmutableViewportMetrics endMetrics) {
mBounceStartMetrics = startMetrics;
mBounceEndMetrics = endMetrics;
}
@@ -593,7 +584,7 @@ public class PanZoomController
private void advanceBounce() {
synchronized (mTarget.getLock()) {
float t = easeOut(mBounceFrame * Axis.MS_PER_FRAME / 256f);
- ViewportMetrics newMetrics = mBounceStartMetrics.interpolate(mBounceEndMetrics, t);
+ ImmutableViewportMetrics newMetrics = mBounceStartMetrics.interpolate(mBounceEndMetrics, t);
mTarget.setViewportMetrics(newMetrics);
mBounceFrame++;
}
@@ -667,13 +658,13 @@ public class PanZoomController
}
/* Returns the nearest viewport metrics with no overscroll visible. */
- private ViewportMetrics getValidViewportMetrics() {
- return getValidViewportMetrics(getMutableMetrics());
+ private ImmutableViewportMetrics getValidViewportMetrics() {
+ return getValidViewportMetrics(getMetrics());
}
- private ViewportMetrics getValidViewportMetrics(ViewportMetrics viewportMetrics) {
+ private ImmutableViewportMetrics getValidViewportMetrics(ImmutableViewportMetrics viewportMetrics) {
/* First, we adjust the zoom factor so that we can make no overscrolled area visible. */
- float zoomFactor = viewportMetrics.getZoomFactor();
+ float zoomFactor = viewportMetrics.zoomFactor;
RectF pageRect = viewportMetrics.getPageRect();
RectF viewport = viewportMetrics.getViewport();
@@ -718,14 +709,14 @@ public class PanZoomController
// by different scale factors, we end up scrolled to the end on one axis
// after applying the scale
PointF center = new PointF(focusX, focusY);
- viewportMetrics.scaleTo(minZoomFactor, center);
+ viewportMetrics = viewportMetrics.scaleTo(minZoomFactor, center);
} else if (zoomFactor > maxZoomFactor) {
PointF center = new PointF(viewport.width() / 2.0f, viewport.height() / 2.0f);
- viewportMetrics.scaleTo(maxZoomFactor, center);
+ viewportMetrics = viewportMetrics.scaleTo(maxZoomFactor, center);
}
/* Now we pan to the right origin. */
- viewportMetrics.setViewport(viewportMetrics.getClampedViewport());
+ viewportMetrics = viewportMetrics.clamp();
return viewportMetrics;
}
@@ -826,8 +817,8 @@ public class PanZoomController
newZoomFactor = maxZoomFactor + excessZoom;
}
- scrollBy(new PointF(mLastZoomFocus.x - detector.getFocusX(),
- mLastZoomFocus.y - detector.getFocusY()));
+ scrollBy(mLastZoomFocus.x - detector.getFocusX(),
+ mLastZoomFocus.y - detector.getFocusY());
PointF focus = new PointF(detector.getFocusX(), detector.getFocusY());
scaleWithFocus(newZoomFactor, focus);
}
@@ -854,8 +845,8 @@ public class PanZoomController
* scale operation. You must hold the monitor while calling this.
*/
private void scaleWithFocus(float zoomFactor, PointF focus) {
- ViewportMetrics viewportMetrics = getMutableMetrics();
- viewportMetrics.scaleTo(zoomFactor, focus);
+ ImmutableViewportMetrics viewportMetrics = getMetrics();
+ viewportMetrics = viewportMetrics.scaleTo(zoomFactor, focus);
mTarget.setViewportMetrics(viewportMetrics);
}
@@ -931,10 +922,11 @@ public class PanZoomController
float finalZoom = viewport.width() / zoomToRect.width();
- ViewportMetrics finalMetrics = getMutableMetrics();
- finalMetrics.setOrigin(new PointF(zoomToRect.left * finalMetrics.getZoomFactor(),
- zoomToRect.top * finalMetrics.getZoomFactor()));
- finalMetrics.scaleTo(finalZoom, new PointF(0.0f, 0.0f));
+ ImmutableViewportMetrics finalMetrics = getMetrics();
+ finalMetrics = finalMetrics.setViewportOrigin(
+ zoomToRect.left * finalMetrics.zoomFactor,
+ zoomToRect.top * finalMetrics.zoomFactor);
+ finalMetrics = finalMetrics.scaleTo(finalZoom, new PointF(0.0f, 0.0f));
// 2. now run getValidViewportMetrics on it, so that the target viewport is
// clamped down to prevent overscroll, over-zoom, and other bad conditions.
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java
index 3ebc4f1..fdac874 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java
@@ -9,14 +9,13 @@ import android.graphics.PointF;
import org.mozilla.gecko.ZoomConstraints;
import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
-import org.mozilla.gecko.gfx.ViewportMetrics;
public interface PanZoomTarget {
public ImmutableViewportMetrics getViewportMetrics();
public ZoomConstraints getZoomConstraints();
- public void setAnimationTarget(ViewportMetrics viewport);
- public void setViewportMetrics(ViewportMetrics viewport);
+ public void setAnimationTarget(ImmutableViewportMetrics viewport);
+ public void setViewportMetrics(ImmutableViewportMetrics viewport);
public void setForceRedraw();
public boolean post(Runnable action);
commit f66ff689d0b3ba5196cac717c7228f541d853e3f
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date: Sat Sep 27 22:54:20 2014 +0200
android: Improve panning smoothness (Fennec import)
Change-Id: I3983709651548eb97e588ebe2c2de608a4a4dfc7
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/Axis.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/Axis.java
index fcdcd72..7ae8084 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/Axis.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/Axis.java
@@ -6,8 +6,8 @@
package org.mozilla.gecko.ui;
import android.util.Log;
+import android.view.View;
-import org.json.JSONArray;
import org.mozilla.gecko.util.FloatUtils;
import java.util.Map;
@@ -23,7 +23,6 @@ abstract class Axis {
private static final String PREF_SCROLLING_FRICTION_SLOW = "ui.scrolling.friction_slow";
private static final String PREF_SCROLLING_FRICTION_FAST = "ui.scrolling.friction_fast";
- private static final String PREF_SCROLLING_VELOCITY_THRESHOLD = "ui.scrolling.velocity_threshold";
private static final String PREF_SCROLLING_MAX_EVENT_ACCELERATION = "ui.scrolling.max_event_acceleration";
private static final String PREF_SCROLLING_OVERSCROLL_DECEL_RATE = "ui.scrolling.overscroll_decel_rate";
private static final String PREF_SCROLLING_OVERSCROLL_SNAP_LIMIT = "ui.scrolling.overscroll_snap_limit";
@@ -59,22 +58,22 @@ abstract class Axis {
return (value == null || value < 0 ? defaultValue : value);
}
- static void addPrefNames(JSONArray prefs) {
- prefs.put(PREF_SCROLLING_FRICTION_FAST);
- prefs.put(PREF_SCROLLING_FRICTION_SLOW);
- prefs.put(PREF_SCROLLING_VELOCITY_THRESHOLD);
- prefs.put(PREF_SCROLLING_MAX_EVENT_ACCELERATION);
- prefs.put(PREF_SCROLLING_OVERSCROLL_DECEL_RATE);
- prefs.put(PREF_SCROLLING_OVERSCROLL_SNAP_LIMIT);
- prefs.put(PREF_SCROLLING_MIN_SCROLLABLE_DISTANCE);
+ static final float MS_PER_FRAME = 4.0f;
+ private static final float FRAMERATE_MULTIPLIER = (1000f/60f) / MS_PER_FRAME;
+
+ // The values we use for friction are based on a 16.6ms frame, adjust them to MS_PER_FRAME:
+ // FRICTION^1 = FRICTION_ADJUSTED^(16/MS_PER_FRAME)
+ // FRICTION_ADJUSTED = e ^ ((ln(FRICTION))/FRAMERATE_MULTIPLIER)
+ static float getFrameAdjustedFriction(float baseFriction) {
+ return (float)Math.pow(Math.E, (Math.log(baseFriction) / FRAMERATE_MULTIPLIER));
}
static void setPrefs(Map<String, Integer> prefs) {
- FRICTION_SLOW = getFloatPref(prefs, PREF_SCROLLING_FRICTION_SLOW, 850);
- FRICTION_FAST = getFloatPref(prefs, PREF_SCROLLING_FRICTION_FAST, 970);
- VELOCITY_THRESHOLD = getIntPref(prefs, PREF_SCROLLING_VELOCITY_THRESHOLD, 10);
+ FRICTION_SLOW = getFrameAdjustedFriction(getFloatPref(prefs, PREF_SCROLLING_FRICTION_SLOW, 850));
+ FRICTION_FAST = getFrameAdjustedFriction(getFloatPref(prefs, PREF_SCROLLING_FRICTION_FAST, 970));
+ VELOCITY_THRESHOLD = 10 / FRAMERATE_MULTIPLIER;
MAX_EVENT_ACCELERATION = getFloatPref(prefs, PREF_SCROLLING_MAX_EVENT_ACCELERATION, 12);
- OVERSCROLL_DECEL_RATE = getFloatPref(prefs, PREF_SCROLLING_OVERSCROLL_DECEL_RATE, 40);
+ OVERSCROLL_DECEL_RATE = getFrameAdjustedFriction(getFloatPref(prefs, PREF_SCROLLING_OVERSCROLL_DECEL_RATE, 40));
SNAP_LIMIT = getFloatPref(prefs, PREF_SCROLLING_OVERSCROLL_SNAP_LIMIT, 300);
MIN_SCROLLABLE_DISTANCE = getFloatPref(prefs, PREF_SCROLLING_MIN_SCROLLABLE_DISTANCE, 500);
Log.i(LOGTAG, "Prefs: " + FRICTION_SLOW + "," + FRICTION_FAST + "," + VELOCITY_THRESHOLD + ","
@@ -86,9 +85,6 @@ abstract class Axis {
setPrefs(null);
}
- // The number of milliseconds per frame assuming 60 fps
- private static final float MS_PER_FRAME = 1000.0f / 60.0f;
-
private enum FlingStates {
STOPPED,
PANNING,
@@ -104,6 +100,7 @@ abstract class Axis {
private final SubdocumentScrollHelper mSubscroller;
+ private int mOverscrollMode; /* Default to only overscrolling if we're allowed to scroll in a direction */
private float mFirstTouchPos; /* Position of the first touch event on the current drag. */
private float mTouchPos; /* Position of the most recent touch event on the current drag. */
private float mLastTouchPos; /* Position of the touch event before touchPos. */
@@ -121,6 +118,15 @@ abstract class Axis {
Axis(SubdocumentScrollHelper subscroller) {
mSubscroller = subscroller;
+ mOverscrollMode = View.OVER_SCROLL_IF_CONTENT_SCROLLS;
+ }
+
+ public void setOverScrollMode(int overscrollMode) {
+ mOverscrollMode = overscrollMode;
+ }
+
+ public int getOverScrollMode() {
+ return mOverscrollMode;
}
private float getViewportEnd() {
@@ -155,7 +161,7 @@ abstract class Axis {
// If there's a direction change, or current velocity is very low,
// allow setting of the velocity outright. Otherwise, use the current
// velocity and a maximum change factor to set the new velocity.
- boolean curVelocityIsLow = Math.abs(mVelocity) < 1.0f;
+ boolean curVelocityIsLow = Math.abs(mVelocity) < 1.0f / FRAMERATE_MULTIPLIER;
boolean directionChange = (mVelocity > 0) != (newVelocity > 0);
if (curVelocityIsLow || (directionChange && !FloatUtils.fuzzyEquals(newVelocity, 0.0f))) {
mVelocity = newVelocity;
@@ -200,24 +206,31 @@ abstract class Axis {
* Returns true if the page is zoomed in to some degree along this axis such that scrolling is
* possible and this axis has not been scroll locked while panning. Otherwise, returns false.
*/
- private boolean scrollable() {
+ boolean scrollable() {
// If we're scrolling a subdocument, ignore the viewport length restrictions (since those
// apply to the top-level document) and only take into account axis locking.
if (mSubscroller.scrolling()) {
return !mScrollingDisabled;
- } else {
- return getViewportLength() <= getPageLength() - MIN_SCROLLABLE_DISTANCE &&
- !mScrollingDisabled;
}
+
+ // if we are axis locked, return false
+ if (mScrollingDisabled) {
+ return false;
+ }
+
+ // there is scrollable space, and we're not disabled, or the document fits the viewport
+ // but we always allow overscroll anyway
+ return getViewportLength() <= getPageLength() - MIN_SCROLLABLE_DISTANCE ||
+ getOverScrollMode() == View.OVER_SCROLL_ALWAYS;
}
/*
* Returns the resistance, as a multiplier, that should be taken into account when
* tracking or pinching.
*/
- float getEdgeResistance() {
+ float getEdgeResistance(boolean forPinching) {
float excess = getExcess();
- if (excess > 0.0f) {
+ if (excess > 0.0f && (getOverscroll() == Overscroll.BOTH || !forPinching)) {
// excess can be greater than viewport length, but the resistance
// must never drop below 0.0
return Math.max(0.0f, SNAP_LIMIT - excess / getViewportLength());
@@ -257,7 +270,15 @@ abstract class Axis {
}
float excess = getExcess();
- if (mDisableSnap || FloatUtils.fuzzyEquals(excess, 0.0f)) {
+ Overscroll overscroll = getOverscroll();
+ boolean decreasingOverscroll = false;
+ if ((overscroll == Overscroll.MINUS && mVelocity > 0) ||
+ (overscroll == Overscroll.PLUS && mVelocity < 0))
+ {
+ decreasingOverscroll = true;
+ }
+
+ if (mDisableSnap || FloatUtils.fuzzyEquals(excess, 0.0f) || decreasingOverscroll) {
// If we aren't overscrolled, just apply friction.
if (Math.abs(mVelocity) >= VELOCITY_THRESHOLD) {
mVelocity *= FRICTION_FAST;
@@ -268,7 +289,7 @@ abstract class Axis {
} else {
// Otherwise, decrease the velocity linearly.
float elasticity = 1.0f - excess / (getViewportLength() * SNAP_LIMIT);
- if (getOverscroll() == Overscroll.MINUS) {
+ if (overscroll == Overscroll.MINUS) {
mVelocity = Math.min((mVelocity + OVERSCROLL_DECEL_RATE) * elasticity, 0.0f);
} else { // must be Overscroll.PLUS
mVelocity = Math.max((mVelocity - OVERSCROLL_DECEL_RATE) * elasticity, 0.0f);
@@ -285,14 +306,27 @@ abstract class Axis {
// Performs displacement of the viewport position according to the current velocity.
void displace() {
- if (!scrollable()) {
+ // if this isn't scrollable just return
+ if (!scrollable())
return;
- }
if (mFlingState == FlingStates.PANNING)
- mDisplacement += (mLastTouchPos - mTouchPos) * getEdgeResistance();
+ mDisplacement += (mLastTouchPos - mTouchPos) * getEdgeResistance(false);
else
mDisplacement += mVelocity;
+
+ // if overscroll is disabled and we're trying to overscroll, reset the displacement
+ // to remove any excess. Using getExcess alone isn't enough here since it relies on
+ // getOverscroll which doesn't take into account any new displacment being applied
+ if (getOverScrollMode() == View.OVER_SCROLL_NEVER) {
+ if (mDisplacement + getOrigin() < getPageStart()) {
+ mDisplacement = getPageStart() - getOrigin();
+ stopFling();
+ } else if (mDisplacement + getViewportEnd() > getPageEnd()) {
+ mDisplacement = getPageEnd() - getViewportEnd();
+ stopFling();
+ }
+ }
}
float resetDisplacement() {
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
index a6b7d27..02e45da 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
@@ -19,8 +19,6 @@ import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
import org.mozilla.gecko.gfx.ViewportMetrics;
import org.mozilla.gecko.util.FloatUtils;
-import java.util.Arrays;
-import java.util.StringTokenizer;
import java.util.Timer;
import java.util.TimerTask;
@@ -53,26 +51,6 @@ public class PanZoomController
// The maximum amount we allow you to zoom into a page
private static final float MAX_ZOOM = 4.0f;
- /* 16 precomputed frames of the _ease-out_ animation from the CSS Transitions specification. */
- private static float[] ZOOM_ANIMATION_FRAMES = new float[] {
- 0.00000f, /* 0 */
- 0.10211f, /* 1 */
- 0.19864f, /* 2 */
- 0.29043f, /* 3 */
- 0.37816f, /* 4 */
- 0.46155f, /* 5 */
- 0.54054f, /* 6 */
- 0.61496f, /* 7 */
- 0.68467f, /* 8 */
- 0.74910f, /* 9 */
- 0.80794f, /* 10 */
- 0.86069f, /* 11 */
- 0.90651f, /* 12 */
- 0.94471f, /* 13 */
- 0.97401f, /* 14 */
- 0.99309f, /* 15 */
- };
-
private enum PanZoomState {
NOTHING, /* no touch-start events received */
FLING, /* all touches removed, but we're still scrolling page */
@@ -125,6 +103,13 @@ public class PanZoomController
mSubscroller.destroy();
}
+ private final static float easeOut(float t) {
+ // ease-out approx.
+ // -(t-1)^2+1
+ t = t-1;
+ return -t*t+1;
+ }
+
private void setState(PanZoomState state) {
mState = state;
}
@@ -145,23 +130,6 @@ public class PanZoomController
}
}
- private void setZoomAnimationFrames(String frames) {
- try {
- if (frames.length() > 0) {
- StringTokenizer st = new StringTokenizer(frames, ",");
- float[] values = new float[st.countTokens()];
- for (int i = 0; i < values.length; i++) {
- values[i] = Float.parseFloat(st.nextToken());
- }
- ZOOM_ANIMATION_FRAMES = values;
- }
- } catch (NumberFormatException e) {
- Log.e(LOGTAG, "Error setting zoom animation frames", e);
- } finally {
- Log.i(LOGTAG, "Zoom animation frames: " + Arrays.toString(ZOOM_ANIMATION_FRAMES));
- }
- }
-
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: return onTouchStart(event);
@@ -357,6 +325,8 @@ public class PanZoomController
}
private boolean onTouchCancel(MotionEvent event) {
+ cancelTouch();
+
if (mState == PanZoomState.WAITING_LISTENERS) {
// we might get a cancel event from the TouchEventHandler while in the
// WAITING_LISTENERS state if the touch listeners prevent-default the
@@ -367,7 +337,6 @@ public class PanZoomController
return false;
}
- cancelTouch();
// ensure we snap back if we're overscrolled
bounce();
return false;
@@ -392,7 +361,9 @@ public class PanZoomController
mY.startTouch(y);
mLastEventTime = time;
- if (angle < AXIS_LOCK_ANGLE || angle > (Math.PI - AXIS_LOCK_ANGLE)) {
+ if (!mX.scrollable() || !mY.scrollable()) {
+ setState(PanZoomState.PANNING);
+ } else if (angle < AXIS_LOCK_ANGLE || angle > (Math.PI - AXIS_LOCK_ANGLE)) {
mY.setScrollingDisabled(true);
setState(PanZoomState.PANNING_LOCKED);
} else if (Math.abs(angle - (Math.PI / 2)) < AXIS_LOCK_ANGLE) {
@@ -507,7 +478,7 @@ public class PanZoomController
mAnimationTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() { mTarget.post(runnable); }
- }, 0, 1000L/60L);
+ }, 0, (int)Axis.MS_PER_FRAME);
}
/* Stops the fling or bounce animation. */
@@ -607,7 +578,7 @@ public class PanZoomController
}
/* Perform the next frame of the bounce-back animation. */
- if (mBounceFrame < ZOOM_ANIMATION_FRAMES.length) {
+ if (mBounceFrame < (int)(256f/Axis.MS_PER_FRAME)) {
advanceBounce();
return;
}
@@ -621,7 +592,7 @@ public class PanZoomController
/* Performs one frame of a bounce animation. */
private void advanceBounce() {
synchronized (mTarget.getLock()) {
- float t = ZOOM_ANIMATION_FRAMES[mBounceFrame];
+ float t = easeOut(mBounceFrame * Axis.MS_PER_FRAME / 256f);
ViewportMetrics newMetrics = mBounceStartMetrics.interpolate(mBounceEndMetrics, t);
mTarget.setViewportMetrics(newMetrics);
mBounceFrame++;
@@ -818,7 +789,7 @@ public class PanZoomController
* Apply edge resistance if we're zoomed out smaller than the page size by scaling the zoom
* factor toward 1.0.
*/
- float resistance = Math.min(mX.getEdgeResistance(), mY.getEdgeResistance());
+ float resistance = Math.min(mX.getEdgeResistance(true), mY.getEdgeResistance(true));
if (spanRatio > 1.0f)
spanRatio = 1.0f + (spanRatio - 1.0f) * resistance;
else
@@ -978,4 +949,13 @@ public class PanZoomController
checkMainThread();
bounce();
}
+
+ public void setOverScrollMode(int overscrollMode) {
+ mX.setOverScrollMode(overscrollMode);
+ mY.setOverScrollMode(overscrollMode);
+ }
+
+ public int getOverScrollMode() {
+ return mX.getOverScrollMode();
+ }
}
commit 590fdf41164347f113cccc01953eefe6ef1020a8
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date: Sat Sep 27 22:30:57 2014 +0200
android: solve black screen on load - call setForceRedraw
Change-Id: Ia9ae05a14c0c751fde961186be350d57d5308519
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index 349de7b..ddc18d4 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -7,6 +7,7 @@ import android.util.DisplayMetrics;
import android.util.Log;
import org.mozilla.gecko.gfx.GeckoLayerClient;
+import org.mozilla.gecko.gfx.LayerController;
import org.mozilla.gecko.gfx.ViewportMetrics;
import java.util.concurrent.LinkedBlockingQueue;
@@ -19,6 +20,8 @@ public class LOKitThread extends Thread {
private TileProvider mTileProvider;
private ViewportMetrics mViewportMetrics;
private boolean mCheckboardImageSet = false;
+ private GeckoLayerClient mLayerClient;
+ private LayerController mController;
public LOKitThread() {
TileProviderFactory.initialize();
@@ -55,16 +58,21 @@ public class LOKitThread extends Thread {
if (mApplication == null) {
mApplication = LibreOfficeMainActivity.mAppContext;
}
+
+ mController = mApplication.getLayerController();
+ mLayerClient = mApplication.getLayerClient();
+
if (mTileProvider != null) {
mTileProvider.close();
}
- GeckoLayerClient layerClient = mApplication.getLayerClient();
- mTileProvider = TileProviderFactory.create(mApplication.getLayerController(), filename);
- layerClient.setTileProvider(mTileProvider);
+
+ mTileProvider = TileProviderFactory.create(mController, filename);
+ mLayerClient.setTileProvider(mTileProvider);
boolean isReady = mTileProvider.isReady();
if (isReady) {
updateCheckbardImage();
+ mController.setForceRedraw();
}
return isReady;
}
commit 40e919d2a19066bd7bcbbd4ece2eae75a1fd20a5
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date: Sat Sep 27 12:54:47 2014 +0200
android: remove notifyLayerClientOfGeometryChange (Fennec import)
Change-Id: Ibc1f4d11dcfdf177cd45fcf689b518d975b13709
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java
index 0898397..ca02e1c 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java
@@ -87,6 +87,7 @@ public class LayerController implements PanZoomTarget {
public void setForceRedraw() {
mForceRedraw = true;
+ notifyLayerClientOfGeometryChange();
}
public Layer getRoot() { return mRootLayer; }
@@ -159,14 +160,13 @@ public class LayerController implements PanZoomTarget {
}
/**
- * Sets the entire viewport metrics at once. This function does not notify the layer client or
- * the pan/zoom controller, so you will need to call notifyLayerClientOfGeometryChange() or
- * notifyPanZoomControllerOfGeometryChange() after calling this. You must hold the monitor
- * while calling this.
+ * Sets the entire viewport metrics at once.
+ * You must hold the monitor while calling this.
*/
public void setViewportMetrics(ViewportMetrics viewport) {
mViewportMetrics = new ImmutableViewportMetrics(viewport);
mView.requestRender();
+ notifyLayerClientOfGeometryChange();
}
public void setAnimationTarget(ViewportMetrics viewport) {
@@ -183,11 +183,7 @@ public class LayerController implements PanZoomTarget {
public boolean post(Runnable action) { return mView.post(action); }
- /**
- * The view as well as the controller itself use this method to notify the layer client that
- * the geometry changed.
- */
- public void notifyLayerClientOfGeometryChange() {
+ private void notifyLayerClientOfGeometryChange() {
if (mLayerClient != null)
mLayerClient.geometryChanged();
}
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
index 876f626..a6b7d27 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
@@ -195,7 +195,6 @@ public class PanZoomController
// transitions.
synchronized (mTarget.getLock()) {
mTarget.setViewportMetrics(getValidViewportMetrics());
- mTarget.notifyLayerClientOfGeometryChange();
}
break;
}
@@ -233,7 +232,6 @@ public class PanZoomController
// page size changed such that we are now in overscroll. snap to the
// the nearest valid viewport
mTarget.setViewportMetrics(validated);
- mTarget.notifyLayerClientOfGeometryChange();
}
}
}
@@ -254,7 +252,6 @@ public class PanZoomController
// case this touchstart is just a tap that doesn't end up triggering
// a redraw
mTarget.setForceRedraw();
- mTarget.notifyLayerClientOfGeometryChange();
// fall through
case FLING:
case BOUNCE:
@@ -460,7 +457,6 @@ public class PanZoomController
viewportMetrics.setOrigin(origin);
mTarget.setViewportMetrics(viewportMetrics);
- mTarget.notifyLayerClientOfGeometryChange();
}
private void fling() {
@@ -628,7 +624,6 @@ public class PanZoomController
float t = ZOOM_ANIMATION_FRAMES[mBounceFrame];
ViewportMetrics newMetrics = mBounceStartMetrics.interpolate(mBounceEndMetrics, t);
mTarget.setViewportMetrics(newMetrics);
- mTarget.notifyLayerClientOfGeometryChange();
mBounceFrame++;
}
}
@@ -637,7 +632,6 @@ public class PanZoomController
private void finishBounce() {
synchronized (mTarget.getLock()) {
mTarget.setViewportMetrics(mBounceEndMetrics);
- mTarget.notifyLayerClientOfGeometryChange();
mBounceFrame = -1;
}
}
@@ -699,7 +693,6 @@ public class PanZoomController
// Force a viewport synchronisation
mTarget.setForceRedraw();
- mTarget.notifyLayerClientOfGeometryChange();
}
/* Returns the nearest viewport metrics with no overscroll visible. */
@@ -883,7 +876,6 @@ public class PanZoomController
// Force a viewport synchronisation
mTarget.setForceRedraw();
- mTarget.notifyLayerClientOfGeometryChange();
}
/**
@@ -894,7 +886,6 @@ public class PanZoomController
ViewportMetrics viewportMetrics = getMutableMetrics();
viewportMetrics.scaleTo(zoomFactor, focus);
mTarget.setViewportMetrics(viewportMetrics);
- mTarget.notifyLayerClientOfGeometryChange();
}
public boolean getRedrawHint() {
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java
index fcbc00f..3ebc4f1 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java
@@ -17,8 +17,6 @@ public interface PanZoomTarget {
public void setAnimationTarget(ViewportMetrics viewport);
public void setViewportMetrics(ViewportMetrics viewport);
-
- public void notifyLayerClientOfGeometryChange();
public void setForceRedraw();
public boolean post(Runnable action);
commit 0151bf3f28b476a2fd0993c6a60fbf9a9f555c3a
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date: Sat Sep 27 12:47:47 2014 +0200
android: move scrollBy & scaleWithFocus to PZC (Fennec Import)
Change-Id: Ie0d23b302994134f9d382e255b0408f7c9f1c1fb
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java
index db43db2..0898397 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java
@@ -135,18 +135,6 @@ public class LayerController implements PanZoomTarget {
}
}
- /** Scrolls the viewport by the given offset. You must hold the monitor while calling this. */
- public void scrollBy(PointF point) {
- ViewportMetrics viewportMetrics = new ViewportMetrics(mViewportMetrics);
- PointF origin = viewportMetrics.getOrigin();
- origin.offset(point.x, point.y);
- viewportMetrics.setOrigin(origin);
- mViewportMetrics = new ImmutableViewportMetrics(viewportMetrics);
-
- notifyLayerClientOfGeometryChange();
- mView.requestRender();
- }
-
/** 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
@@ -193,21 +181,6 @@ public class LayerController implements PanZoomTarget {
}
}
- /**
- * Scales the viewport, keeping the given focus point in the same place before and after the
- * scale operation. You must hold the monitor while calling this.
- */
- public void scaleWithFocus(float zoomFactor, PointF focus) {
- ViewportMetrics viewportMetrics = new ViewportMetrics(mViewportMetrics);
- viewportMetrics.scaleTo(zoomFactor, focus);
- mViewportMetrics = new ImmutableViewportMetrics(viewportMetrics);
-
- // We assume the zoom level will only be modified by the
- // PanZoomController, so no need to notify it of this change.
- notifyLayerClientOfGeometryChange();
- mView.requestRender();
- }
-
public boolean post(Runnable action) { return mView.post(action); }
/**
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
index ef45fd3..876f626 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
@@ -133,6 +133,10 @@ public class PanZoomController
return mTarget.getViewportMetrics();
}
+ private ViewportMetrics getMutableMetrics() {
+ return new ViewportMetrics(getMetrics());
+ }
+
// for debugging bug 713011; it can be taken out once that is resolved.
private void checkMainThread() {
if (mMainThread != Thread.currentThread()) {
@@ -225,7 +229,7 @@ public class PanZoomController
if (mState == PanZoomState.NOTHING) {
synchronized (mTarget.getLock()) {
ViewportMetrics validated = getValidViewportMetrics();
- if (! (new ViewportMetrics(getMetrics())).fuzzyEquals(validated)) {
+ if (! getMutableMetrics().fuzzyEquals(validated)) {
// page size changed such that we are now in overscroll. snap to the
// the nearest valid viewport
mTarget.setViewportMetrics(validated);
@@ -449,6 +453,16 @@ public class PanZoomController
updatePosition();
}
+ private void scrollBy(PointF point) {
+ ViewportMetrics viewportMetrics = getMutableMetrics();
+ PointF origin = viewportMetrics.getOrigin();
+ origin.offset(point.x, point.y);
+ viewportMetrics.setOrigin(origin);
+
+ mTarget.setViewportMetrics(viewportMetrics);
+ mTarget.notifyLayerClientOfGeometryChange();
+ }
+
private void fling() {
updatePosition();
@@ -465,7 +479,7 @@ public class PanZoomController
private void bounce(ViewportMetrics metrics) {
stopAnimationTimer();
- ViewportMetrics bounceStartMetrics = new ViewportMetrics(getMetrics());
+ ViewportMetrics bounceStartMetrics = getMutableMetrics();
if (bounceStartMetrics.fuzzyEquals(metrics)) {
setState(PanZoomState.NOTHING);
return;
@@ -539,7 +553,7 @@ public class PanZoomController
}
if (! mSubscroller.scrollBy(displacement)) {
synchronized (mTarget.getLock()) {
- mTarget.scrollBy(displacement);
+ scrollBy(displacement);
}
}
}
@@ -690,7 +704,7 @@ public class PanZoomController
/* Returns the nearest viewport metrics with no overscroll visible. */
private ViewportMetrics getValidViewportMetrics() {
- return getValidViewportMetrics(new ViewportMetrics(getMetrics()));
+ return getValidViewportMetrics(getMutableMetrics());
}
private ViewportMetrics getValidViewportMetrics(ViewportMetrics viewportMetrics) {
@@ -848,10 +862,10 @@ public class PanZoomController
newZoomFactor = maxZoomFactor + excessZoom;
}
- mTarget.scrollBy(new PointF(mLastZoomFocus.x - detector.getFocusX(),
+ scrollBy(new PointF(mLastZoomFocus.x - detector.getFocusX(),
mLastZoomFocus.y - detector.getFocusY()));
PointF focus = new PointF(detector.getFocusX(), detector.getFocusY());
- mTarget.scaleWithFocus(newZoomFactor, focus);
+ scaleWithFocus(newZoomFactor, focus);
}
mLastZoomFocus.set(detector.getFocusX(), detector.getFocusY());
@@ -872,6 +886,17 @@ public class PanZoomController
mTarget.notifyLayerClientOfGeometryChange();
}
+ /**
+ * Scales the viewport, keeping the given focus point in the same place before and after the
+ * scale operation. You must hold the monitor while calling this.
+ */
+ private void scaleWithFocus(float zoomFactor, PointF focus) {
+ ViewportMetrics viewportMetrics = getMutableMetrics();
+ viewportMetrics.scaleTo(zoomFactor, focus);
+ mTarget.setViewportMetrics(viewportMetrics);
+ mTarget.notifyLayerClientOfGeometryChange();
+ }
+
public boolean getRedrawHint() {
switch (mState) {
case PINCHING:
@@ -944,7 +969,7 @@ public class PanZoomController
float finalZoom = viewport.width() / zoomToRect.width();
- ViewportMetrics finalMetrics = new ViewportMetrics(getMetrics());
+ ViewportMetrics finalMetrics = getMutableMetrics();
finalMetrics.setOrigin(new PointF(zoomToRect.left * finalMetrics.getZoomFactor(),
zoomToRect.top * finalMetrics.getZoomFactor()));
finalMetrics.scaleTo(finalZoom, new PointF(0.0f, 0.0f));
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java
index 7ab1c56..fcbc00f 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java
@@ -17,8 +17,6 @@ public interface PanZoomTarget {
public void setAnimationTarget(ViewportMetrics viewport);
public void setViewportMetrics(ViewportMetrics viewport);
- public void scrollBy(PointF point);
- public void scaleWithFocus(float zoomFactor, PointF focus);
public void notifyLayerClientOfGeometryChange();
public void setForceRedraw();
commit 94e7296fc51e1e85715bbab91cf233f3d7ce67f3
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date: Sat Sep 27 12:42:39 2014 +0200
android: add PanZoomTarget (Fennec import)
Change-Id: Ib946b7a95cd59833a732e3da6c139e848778e1bc
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java
index 303cb67..db43db2 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java
@@ -17,6 +17,7 @@ import android.view.GestureDetector;
import org.mozilla.gecko.ZoomConstraints;
import org.mozilla.gecko.ui.PanZoomController;
+import org.mozilla.gecko.ui.PanZoomTarget;
import org.mozilla.gecko.ui.SimpleScaleGestureDetector;
/**
@@ -26,7 +27,7 @@ import org.mozilla.gecko.ui.SimpleScaleGestureDetector;
*
* Many methods require that the monitor be held, with a synchronized (controller) { ... } block.
*/
-public class LayerController {
+public class LayerController implements PanZoomTarget {
private static final String LOGTAG = "GeckoLayerController";
private Layer mRootLayer; /* The root layer. */
@@ -92,6 +93,7 @@ public class LayerController {
public LayerView getView() { return mView; }
public Context getContext() { return mContext; }
public ImmutableViewportMetrics getViewportMetrics() { return mViewportMetrics; }
+ public Object getLock() { return this; }
public FloatSize getViewportSize() {
return mViewportMetrics.getSize();
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
index 1d7d52c..ef45fd3 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
@@ -16,7 +16,6 @@ import org.libreoffice.LOKitShell;
import org.libreoffice.LibreOfficeMainActivity;
import org.mozilla.gecko.ZoomConstraints;
import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
-import org.mozilla.gecko.gfx.LayerController;
import org.mozilla.gecko.gfx.ViewportMetrics;
import org.mozilla.gecko.util.FloatUtils;
@@ -92,7 +91,7 @@ public class PanZoomController
prevented the default actions yet. we still need to abort animations. */
}
- private final LayerController mController;
+ private final PanZoomTarget mTarget;
private final SubdocumentScrollHelper mSubscroller;
private final Axis mX;
private final Axis mY;
@@ -110,8 +109,8 @@ public class PanZoomController
/* Current state the pan/zoom UI is in. */
private PanZoomState mState;
- public PanZoomController(LayerController controller) {
- mController = controller;
+ public PanZoomController(PanZoomTarget target) {
+ mTarget = target;
mSubscroller = new SubdocumentScrollHelper();
mX = new AxisX(mSubscroller);
mY = new AxisY(mSubscroller);
@@ -131,7 +130,7 @@ public class PanZoomController
}
private ImmutableViewportMetrics getMetrics() {
- return mController.getViewportMetrics();
+ return mTarget.getViewportMetrics();
}
// for debugging bug 713011; it can be taken out once that is resolved.
@@ -190,9 +189,9 @@ public class PanZoomController
case NOTHING:
// Don't do animations here; they're distracting and can cause flashes on page
// transitions.
- synchronized (mController) {
- mController.setViewportMetrics(getValidViewportMetrics());
- mController.notifyLayerClientOfGeometryChange();
+ synchronized (mTarget.getLock()) {
+ mTarget.setViewportMetrics(getValidViewportMetrics());
+ mTarget.notifyLayerClientOfGeometryChange();
}
break;
}
@@ -224,13 +223,13 @@ public class PanZoomController
/** This must be called on the UI thread. */
public void pageRectUpdated() {
if (mState == PanZoomState.NOTHING) {
- synchronized (mController) {
+ synchronized (mTarget.getLock()) {
ViewportMetrics validated = getValidViewportMetrics();
if (! (new ViewportMetrics(getMetrics())).fuzzyEquals(validated)) {
// page size changed such that we are now in overscroll. snap to the
// the nearest valid viewport
- mController.setViewportMetrics(validated);
- mController.notifyLayerClientOfGeometryChange();
+ mTarget.setViewportMetrics(validated);
+ mTarget.notifyLayerClientOfGeometryChange();
}
}
}
@@ -250,8 +249,8 @@ public class PanZoomController
// We just interrupted a double-tap animation, so force a redraw in
// case this touchstart is just a tap that doesn't end up triggering
// a redraw
- mController.setForceRedraw();
- mController.notifyLayerClientOfGeometryChange();
+ mTarget.setForceRedraw();
+ mTarget.notifyLayerClientOfGeometryChange();
// fall through
case FLING:
case BOUNCE:
@@ -476,7 +475,7 @@ public class PanZoomController
// getRedrawHint() is returning false. This means we can safely call
// setAnimationTarget to set the new final display port and not have it get
// clobbered by display ports from intermediate animation frames.
- mController.setAnimationTarget(metrics);
+ mTarget.setAnimationTarget(metrics);
startAnimationTimer(new BounceRunnable(bounceStartMetrics, metrics));
}
@@ -497,7 +496,7 @@ public class PanZoomController
mAnimationRunnable = runnable;
mAnimationTimer.scheduleAtFixedRate(new TimerTask() {
@Override
- public void run() { mController.post(runnable); }
+ public void run() { mTarget.post(runnable); }
}, 0, 1000L/60L);
}
@@ -539,8 +538,8 @@ public class PanZoomController
return;
}
if (! mSubscroller.scrollBy(displacement)) {
- synchronized (mController) {
- mController.scrollBy(displacement);
+ synchronized (mTarget.getLock()) {
+ mTarget.scrollBy(displacement);
}
}
}
@@ -611,20 +610,20 @@ public class PanZoomController
/* Performs one frame of a bounce animation. */
private void advanceBounce() {
- synchronized (mController) {
+ synchronized (mTarget.getLock()) {
float t = ZOOM_ANIMATION_FRAMES[mBounceFrame];
ViewportMetrics newMetrics = mBounceStartMetrics.interpolate(mBounceEndMetrics, t);
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list