summaryrefslogtreecommitdiff
path: root/android
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.com>2014-07-03 14:57:12 +0200
committerTomaž Vajngerl <tomaz.vajngerl@collabora.com>2014-07-03 15:05:10 +0200
commit5ccb510ef7dd6688b86038b37563583f64107936 (patch)
tree2d0378d5f6c5c86c886d6952ced214ae2c60a4c1 /android
parent9948d9566e86b190e74a62e63f273f5fa0eb8929 (diff)
LOAndroid3: (partially) render page with LOKitTileProvider
+ TileProvider & TileIterator interfaces + Clean-up obsolete mozilla stuff Change-Id: Ief56f11bf7f8fd6da383ffc7be3461b765bf0157
Diffstat (limited to 'android')
-rw-r--r--android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java75
-rw-r--r--android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java103
-rw-r--r--android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java6
-rw-r--r--android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java64
-rw-r--r--android/experimental/LOAndroid3/src/java/org/libreoffice/TileIterator.java6
-rw-r--r--android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java14
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java160
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java107
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerClient.java81
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java6
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/Axis.java19
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java512
12 files changed, 506 insertions, 647 deletions
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index abcbe650071e..90825759d21e 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -16,16 +16,10 @@ import java.nio.ByteBuffer;
import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue;
-import org.libreoffice.kit.LibreOfficeKit;
-import org.libreoffice.kit.Office;
-import org.libreoffice.kit.Document;
-
public class LOKitThread extends Thread {
private static final String LOGTAG = "GeckoThread";
private static final int TILE_SIZE = 256;
-
- public Office mOffice;
- public Document mDocument;
+ private TileProvider mTileProvider;
public ConcurrentLinkedQueue<LOEvent> gEvents = new ConcurrentLinkedQueue<LOEvent>();
private ViewportMetrics mViewportMetrics;
@@ -33,55 +27,40 @@ public class LOKitThread extends Thread {
LOKitThread() {
}
- private void openDocument() {
- // enable debugging messages as the first thing
- LibreOfficeKit.putenv("SAL_LOG=+WARN+INFO-INFO.legacy.osl-INFO.i18nlangtag");
- LibreOfficeKit.init(LibreOfficeMainActivity.mAppContext);
-
- mOffice = new Office(LibreOfficeKit.getLibreOfficeKitHandle());
- String input = "/assets/test1.odt";
- mDocument = mOffice.documentLoad(input);
- }
-
- private synchronized boolean draw() throws InterruptedException {
+ private boolean draw() throws InterruptedException {
final LibreOfficeMainActivity application = LibreOfficeMainActivity.mAppContext;
- openDocument();
-
- long height = mDocument.getDocumentHeight();
- long width = mDocument.getDocumentWidth();
+ if (mTileProvider == null)
+ mTileProvider = new LOKitTileProvider(application.getLayerController());
- Log.e(LOGTAG, "Document Size: " + width + " " + height);
+ int pageWidth = mTileProvider.getPageWidth();
+ int pageHeight = mTileProvider.getPageHeight();
- int pageWidth = 1024;
- int pageHeight = 1024;
+ String metadata = createJson(0, 0, pageWidth, pageHeight, pageWidth, pageHeight, 0, 0, 1.0);
+ mViewportMetrics = new ViewportMetrics();
- String metadata = createJson(0, 0, 256, 256, pageWidth, pageHeight, 0, 0, 1.0);
+ boolean shouldContinue = application.getLayerClient().beginDrawing(pageWidth, pageHeight, TILE_SIZE, TILE_SIZE, metadata);
- Rect bufferRect = application.getLayerClient().beginDrawing(256, 256, TILE_SIZE, TILE_SIZE, metadata);
-
- /*if (bufferRect == null) {
- Log.e(LOGTAG, "beginDrawing - false");
+ if (!shouldContinue) {
return false;
- }*/
-
- Log.e(LOGTAG, "Filling tiles..");
-
- ByteBuffer buffer = ByteBuffer.allocateDirect(TILE_SIZE * TILE_SIZE * 4);
-
- Log.e(LOGTAG, "PaintTile..");
-
- mDocument.paintTile(buffer, 256, 256, 1024, 1024, 4096, 4096);
+ }
- Log.e(LOGTAG, "EndPaintTile..");
+ Log.i(LOGTAG, "Filling tiles..");
- Bitmap bitmap = Bitmap.createBitmap(TILE_SIZE, TILE_SIZE, Bitmap.Config.ARGB_8888);
- bitmap.copyPixelsFromBuffer(buffer);
+ int x = 0;
+ int y = 0;
+ for (Bitmap bitmap : mTileProvider.getTileIterator()) {
+ application.getLayerClient().addTile(bitmap, x, y);
+ x += TILE_SIZE;
+ if (x > pageWidth) {
+ x = 0;
+ y += TILE_SIZE;
+ }
+ }
- application.getLayerClient().addTile(bitmap, 0, 0);
+ Log.i(LOGTAG, "End Draw");
- Log.e(LOGTAG, "EndDrawing..");
- application.getLayerClient().endDrawing(0, 0, 256, 256);
+ application.getLayerClient().endDrawing(0, 0, pageWidth, pageHeight);
return true;
}
@@ -143,22 +122,20 @@ public class LOKitThread extends Thread {
try {
boolean drawn = false;
while (true) {
-
if (!gEvents.isEmpty()) {
processEvent(gEvents.poll());
} else {
if (!drawn) {
drawn = draw();
}
- Thread.sleep(2000L);
+ Thread.sleep(100L);
}
}
} catch (InterruptedException ex) {
-
}
}
- private synchronized void processEvent(LOEvent event) throws InterruptedException {
+ private void processEvent(LOEvent event) throws InterruptedException {
switch (event.mType) {
case LOEvent.VIEWPORT:
mViewportMetrics = event.getViewport();
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
new file mode 100644
index 000000000000..4b6d8faac932
--- /dev/null
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -0,0 +1,103 @@
+package org.libreoffice;
+
+import android.graphics.Bitmap;
+import android.util.Log;
+
+import org.mozilla.gecko.gfx.LayerController;
+
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+
+import org.libreoffice.kit.LibreOfficeKit;
+import org.libreoffice.kit.Office;
+import org.libreoffice.kit.Document;
+
+public class LOKitTileProvider implements TileProvider {
+ private final LayerController mLayerController;
+
+ public static int TILE_SIZE = 256;
+
+ public final Office mOffice;
+ public final Document mDocument;
+
+ public LOKitTileProvider(LayerController layerController) {
+ this.mLayerController = layerController;
+ LibreOfficeKit.putenv("SAL_LOG=+WARN+INFO-INFO.legacy.osl-INFO.i18nlangtag");
+ LibreOfficeKit.init(LibreOfficeMainActivity.mAppContext);
+
+ mOffice = new Office(LibreOfficeKit.getLibreOfficeKitHandle());
+ String input = "/assets/test1.odt";
+ mDocument = mOffice.documentLoad(input);
+ }
+
+ @Override
+ public int getPageWidth() {
+ return (int) (mDocument.getDocumentWidth() / 1440.0 * LOKitShell.getDpi());
+ }
+
+ @Override
+ public int getPageHeight() {
+ return (int) (mDocument.getDocumentHeight() / 1440.0 * LOKitShell.getDpi());
+ }
+
+ public TileIterator getTileIterator() {
+ return new LoKitTileIterator();
+ }
+
+ public class LoKitTileIterator implements TileIterator, Iterator<Bitmap> {
+ private final double mTileWidth;
+ private final double mTileHeight;
+
+ private boolean mShouldContinue = true;
+
+ private double mPositionWidth = 0;
+ private double mPositionHeight = 0;
+
+ private double mPageWidth;
+ private double mPageHeight;
+
+ public LoKitTileIterator() {
+ mTileWidth = (TILE_SIZE / (double) LOKitShell.getDpi()) * 1440.0;
+ mTileHeight = (TILE_SIZE / (double) LOKitShell.getDpi()) * 1440.0;
+ mPageWidth = mDocument.getDocumentWidth();
+ mPageHeight = mDocument.getDocumentHeight();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return mShouldContinue;
+ }
+
+ @Override
+ public Bitmap next() {
+ ByteBuffer buffer = ByteBuffer.allocateDirect(TILE_SIZE * TILE_SIZE * 4);
+ Bitmap bitmap = Bitmap.createBitmap(TILE_SIZE, TILE_SIZE, Bitmap.Config.ARGB_8888);
+
+ mDocument.paintTile(buffer, TILE_SIZE, TILE_SIZE, (int) mPositionWidth, (int) mPositionHeight, (int) mTileWidth, (int) mTileHeight);
+
+ mPositionWidth += mTileWidth;
+
+ if (mPositionWidth > mPageWidth) {
+ mPositionHeight += mTileHeight;
+ mPositionWidth = 0;
+ }
+
+ if (mPositionHeight > mPageHeight || mPositionHeight > 20000) {
+ mShouldContinue = false;
+ }
+
+ bitmap.copyPixelsFromBuffer(buffer);
+ return bitmap;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Iterator<Bitmap> iterator() {
+ return this;
+ }
+ }
+}
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
index a3144e16440e..0f12208d885e 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -11,8 +11,6 @@ import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
-import android.os.Environment;
-import java.io.File;
import org.mozilla.gecko.gfx.GeckoSoftwareLayerClient;
import org.mozilla.gecko.gfx.LayerController;
@@ -63,10 +61,12 @@ public class LibreOfficeMainActivity extends Activity {
mAppContext = this;
super.onCreate(savedInstanceState);
-
setContentView(R.layout.activity_main);
+
Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - onCreate");
+ setContentView(R.layout.activity_main);
+
// setup gecko layout
mGeckoLayout = (RelativeLayout) findViewById(R.id.gecko_layout);
mMainLayout = (LinearLayout) findViewById(R.id.main_layout);
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java
new file mode 100644
index 000000000000..04ebfb464a23
--- /dev/null
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java
@@ -0,0 +1,64 @@
+package org.libreoffice;
+
+import android.graphics.Bitmap;
+
+import org.apache.http.MethodNotSupportedException;
+import org.mozilla.gecko.gfx.LayerController;
+
+import java.util.Iterator;
+import java.util.List;
+
+public class MockTileProvider implements TileProvider {
+ private final LayerController layerController;
+
+ public MockTileProvider(LayerController layerController) {
+ this.layerController = layerController;
+ }
+
+ @Override
+ public int getPageWidth() {
+ return 549;
+ }
+
+ @Override
+ public int getPageHeight() {
+ return 630;
+ }
+
+ public TileIterator getTileIterator() {
+ return new MockTileIterator(layerController);
+ }
+
+ public class MockTileIterator implements TileIterator, Iterator<Bitmap> {
+ private final LayerController layerController;
+
+ private int tileNumber = 1;
+
+ public MockTileIterator(LayerController layerController) {
+ this.layerController = layerController;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return tileNumber <= 9;
+ }
+
+ @Override
+ public Bitmap next() {
+ String imageName = "d" + tileNumber;
+ tileNumber++;
+ Bitmap bitmap = layerController.getDrawable(imageName);
+ return bitmap;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Iterator<Bitmap> iterator() {
+ return this;
+ }
+ }
+}
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/TileIterator.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/TileIterator.java
new file mode 100644
index 000000000000..68c39e53bccc
--- /dev/null
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/TileIterator.java
@@ -0,0 +1,6 @@
+package org.libreoffice;
+
+import android.graphics.Bitmap;
+
+public interface TileIterator extends Iterable<Bitmap> {
+}
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java
new file mode 100644
index 000000000000..a405fdf827da
--- /dev/null
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java
@@ -0,0 +1,14 @@
+package org.libreoffice;
+
+
+import android.graphics.Bitmap;
+
+import java.util.List;
+
+public interface TileProvider {
+ int getPageWidth();
+
+ int getPageHeight();
+
+ TileIterator getTileIterator();
+}
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 134c40628d0b..c196cf8e9feb 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
@@ -59,15 +59,7 @@ import org.mozilla.gecko.util.FloatUtils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-//import org.mozilla.gecko.GeckoApp;
-//import org.mozilla.gecko.GeckoAppShell;
-//import org.mozilla.gecko.GeckoEvent;
-
-public abstract class GeckoLayerClient extends LayerClient implements GeckoEventListener {
- public static final int LAYER_CLIENT_TYPE_NONE = 0;
- public static final int LAYER_CLIENT_TYPE_SOFTWARE = 1;
- public static final int LAYER_CLIENT_TYPE_GL = 2;
-
+public abstract class GeckoLayerClient implements GeckoEventListener {
private static final String LOGTAG = "GeckoLayerClient";
private static final long MIN_VIEWPORT_CHANGE_DELAY = 25L;
private static Pattern sColorPattern;
@@ -88,53 +80,26 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
// inside a transaction, so no synchronization is needed.
private boolean mUpdateViewportOnEndDraw;
private String mLastCheckerboardColor;
- /* Used by robocop for testing purposes */
- private DrawListener mDrawListener;
+
+ protected LayerController mLayerController;
public GeckoLayerClient(Context context) {
mScreenSize = new IntSize(0, 0);
}
- // Parses a color from an RGB triple of the form "rgb([0-9]+, [0-9]+, [0-9]+)". If the color
- // cannot be parsed, returns white.
- private static int parseColorFromGecko(String string) {
- if (sColorPattern == null) {
- sColorPattern = Pattern.compile("rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)");
- }
-
- Matcher matcher = sColorPattern.matcher(string);
- if (!matcher.matches()) {
- return Color.WHITE;
- }
-
- int r = Integer.parseInt(matcher.group(1));
- int g = Integer.parseInt(matcher.group(2));
- int b = Integer.parseInt(matcher.group(3));
- return Color.rgb(r, g, b);
- }
-
protected abstract boolean setupLayer();
- protected abstract boolean shouldDrawProceed(int tileWidth, int tileHeight);
-
protected abstract void updateLayerAfterDraw(Rect updatedRect);
protected abstract IntSize getBufferSize();
protected abstract IntSize getTileSize();
- protected abstract void tileLayerUpdated();
-
- public abstract Bitmap getBitmap();
-
- public abstract int getType();
-
/**
* Attaches the root layer to the layer controller so that Gecko appears.
*/
- @Override
public void setLayerController(LayerController layerController) {
- super.setLayerController(layerController);
+ mLayerController = layerController;
layerController.setRoot(mTileLayer);
if (mGeckoViewport != null) {
@@ -144,80 +109,25 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
sendResizeEventIfNecessary();
}
- public Rect beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata) {
-
+ public boolean beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata) {
Log.e(LOGTAG, "### beginDrawing " + width + " " + height + " " + tileWidth + " " + tileHeight);
- if (setupLayer()) {
+ if (setupLayer()) {
Log.e(LOGTAG, "### Cancelling due to layer setup");
- return null;
- }
-
- if (!shouldDrawProceed(tileWidth, tileHeight)) {
- Log.e(LOGTAG, "### Cancelling draw due to shouldDrawProceed()");
- return null;
+ return false;
}
- LayerController controller = getLayerController();
-
try {
JSONObject viewportObject = new JSONObject(metadata);
mNewGeckoViewport = new ViewportMetrics(viewportObject);
-
Log.e(LOGTAG, "### beginDrawing new Gecko viewport " + mNewGeckoViewport);
-
- // Update the background color, if it's present.
- String backgroundColorString = viewportObject.optString("backgroundColor");
- if (backgroundColorString != null && !backgroundColorString.equals(mLastCheckerboardColor)) {
- mLastCheckerboardColor = backgroundColorString;
- controller.setCheckerboardColor(parseColorFromGecko(backgroundColorString));
- }
} catch (JSONException e) {
Log.e(LOGTAG, "Aborting draw, bad viewport description: " + metadata);
- return null;
+ return false;
}
- // Make sure we don't spend time painting areas we aren't interested in.
- // Only do this if the Gecko viewport isn't going to override our viewport.
- Rect bufferRect = new Rect(0, 0, width, height);
-
- if (!mUpdateViewportOnEndDraw) {
- // First, find out our ideal displayport. We do this by taking the
- // clamped viewport origin and taking away the optimum viewport offset.
- // This would be what we would send to Gecko if adjustViewport were
- // called now.
- ViewportMetrics currentMetrics = controller.getViewportMetrics();
- PointF currentBestOrigin = RectUtils.getOrigin(currentMetrics.getClampedViewport());
- PointF viewportOffset = currentMetrics.getOptimumViewportOffset(new IntSize(width, height));
- currentBestOrigin.offset(-viewportOffset.x, -viewportOffset.y);
-
- Rect currentRect = RectUtils.round(new RectF(currentBestOrigin.x, currentBestOrigin.y,
- currentBestOrigin.x + width, currentBestOrigin.y + height));
-
- // Second, store Gecko's displayport.
- PointF currentOrigin = mNewGeckoViewport.getDisplayportOrigin();
- bufferRect = RectUtils.round(new RectF(currentOrigin.x, currentOrigin.y,
- currentOrigin.x + width, currentOrigin.y + height));
-
-
- // Take the intersection of the two as the area we're interested in rendering.
-
- if (!bufferRect.intersect(currentRect)) {
- // If there's no intersection, we have no need to render anything,
- // but make sure to update the viewport size.
- beginTransaction(mTileLayer);
- try {
- updateViewport(true);
- } finally {
- endTransaction(mTileLayer);
- }
- return null;
- }
- bufferRect.offset(Math.round(-currentOrigin.x), Math.round(-currentOrigin.y));
- }
-
- beginTransaction(mTileLayer);
- return bufferRect;
+ mTileLayer.beginTransaction();
+ return true;
}
/*
@@ -225,23 +135,17 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
* a little more JNI magic.
*/
public void endDrawing(int x, int y, int width, int height) {
- synchronized (getLayerController()) {
+ synchronized (mLayerController) {
try {
updateViewport(!mUpdateViewportOnEndDraw);
mUpdateViewportOnEndDraw = false;
-
Rect rect = new Rect(x, y, x + width, y + height);
updateLayerAfterDraw(rect);
} finally {
- endTransaction(mTileLayer);
+ mTileLayer.endTransaction();
}
}
Log.i(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - endDrawing");
-
- /* Used by robocop for testing purposes */
- if (mDrawListener != null) {
- mDrawListener.drawFinished(x, y, width, height);
- }
}
protected void updateViewport(boolean onlyUpdatePageSize) {
@@ -249,27 +153,25 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
// JS-side viewport dimensions override the java-side ones because
// 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 = getLayerController().getViewportSize();
+ FloatSize viewportSize = mLayerController.getViewportSize();
mGeckoViewport = mNewGeckoViewport;
mGeckoViewport.setSize(viewportSize);
- LayerController controller = getLayerController();
PointF displayportOrigin = mGeckoViewport.getDisplayportOrigin();
mTileLayer.setOrigin(PointUtils.round(displayportOrigin));
mTileLayer.setResolution(mGeckoViewport.getZoomFactor());
- this.tileLayerUpdated();
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(controller.getZoomFactor(), mGeckoViewport.getZoomFactor())) {
- controller.setPageSize(mGeckoViewport.getPageSize());
+ if (FloatUtils.fuzzyEquals(mLayerController.getZoomFactor(), mGeckoViewport.getZoomFactor())) {
+ mLayerController.setPageSize(mGeckoViewport.getPageSize());
}
} else {
- controller.setViewportMetrics(mGeckoViewport);
- controller.abortPanZoomAnimation();
+ mLayerController.setViewportMetrics(mGeckoViewport);
+ mLayerController.abortPanZoomAnimation();
}
}
@@ -284,14 +186,15 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
// size is zero (which indicates that the rendering surface hasn't been
// allocated yet).
boolean screenSizeChanged = (metrics.widthPixels != mScreenSize.width || metrics.heightPixels != mScreenSize.height);
- boolean viewportSizeValid = (getLayerController() != null && getLayerController().getViewportSize().isPositive());
+ boolean viewportSizeValid = (mLayerController != null && mLayerController.getViewportSize().isPositive());
if (!(force || (screenSizeChanged && viewportSizeValid))) {
return;
}
mScreenSize = new IntSize(metrics.widthPixels, metrics.heightPixels);
- IntSize bufferSize = getBufferSize(), tileSize = getTileSize();
+ IntSize bufferSize = getBufferSize();
+ IntSize tileSize = getTileSize();
Log.e(LOGTAG, "### Screen-size changed to " + mScreenSize);
@@ -301,13 +204,12 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
LOKitShell.sendEvent(event);
}
- @Override
public void render() {
adjustViewportWithThrottling();
}
private void adjustViewportWithThrottling() {
- if (!getLayerController().getRedrawHint())
+ if (!mLayerController.getRedrawHint())
return;
if (mPendingViewportAdjust)
@@ -315,7 +217,7 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
long timeDelta = System.currentTimeMillis() - mLastViewportChangeTime;
if (timeDelta < MIN_VIEWPORT_CHANGE_DELAY) {
- getLayerController().getView().postDelayed(
+ mLayerController.getView().postDelayed(
new Runnable() {
public void run() {
mPendingViewportAdjust = false;
@@ -330,13 +232,12 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
adjustViewport();
}
- @Override
public void viewportSizeChanged() {
mViewportSizeChanged = true;
}
private void adjustViewport() {
- ViewportMetrics viewportMetrics = new ViewportMetrics(getLayerController().getViewportMetrics());
+ ViewportMetrics viewportMetrics = new ViewportMetrics(mLayerController.getViewportMetrics());
PointF viewportOffset = viewportMetrics.getOptimumViewportOffset(getBufferSize());
viewportMetrics.setViewportOffset(viewportOffset);
@@ -366,7 +267,6 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
}
}
- @Override
public void geometryChanged() {
sendResizeEventIfNecessary();
render();
@@ -381,18 +281,4 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
private void sendResizeEventIfNecessary() {
sendResizeEventIfNecessary(false);
}
-
- /**
- * Used by robocop for testing purposes. Not for production use! This is called via reflection by robocop.
- */
- public void setDrawListener(DrawListener listener) {
- mDrawListener = listener;
- }
-
- /**
- * Used by robocop for testing purposes. Not for production use! This is used via reflection by robocop.
- */
- public interface DrawListener {
- public void drawFinished(int x, int y, int width, int height);
- }
} \ No newline at end of file
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java
index de8076aed4d2..42bc0b6ac52d 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java
@@ -41,7 +41,7 @@ package org.mozilla.gecko.gfx;
import org.libreoffice.LOKitShell;
import org.mozilla.gecko.gfx.CairoImage;
import org.mozilla.gecko.gfx.IntSize;
-import org.mozilla.gecko.gfx.LayerClient;
+import org.mozilla.gecko.gfx.GeckoLayerClient;
import org.mozilla.gecko.gfx.LayerController;
import org.mozilla.gecko.gfx.LayerRenderer;
import org.mozilla.gecko.gfx.MultiTileLayer;
@@ -77,20 +77,11 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
mFormat = CairoImage.FORMAT_ARGB32;
}
- /*protected void finalize() throws Throwable {
- try {
- if (mBuffer != null)
- LOKitShell.freeDirectBuffer(mBuffer);
- mBuffer = null;
- } finally {
- super.finalize();
- }
- }*/
-
public void setLayerController(LayerController layerController) {
super.setLayerController(layerController);
layerController.setRoot(mTileLayer);
+
if (mGeckoViewport != null) {
layerController.setViewportMetrics(mGeckoViewport);
}
@@ -104,7 +95,7 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
if(mTileLayer == null)
mTileLayer = new MultiTileLayer(TILE_SIZE);
- getLayerController().setRoot(mTileLayer);
+ mLayerController.setRoot(mTileLayer);
// Force a resize event to be sent because the results of this
// are different depending on what tile system we're using
@@ -114,22 +105,11 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
}
@Override
- protected boolean shouldDrawProceed(int tileWidth, int tileHeight) {
- // Make sure the tile-size matches. If it doesn't, we could crash trying
- // to access invalid memory.
- if (tileWidth != TILE_SIZE.width || tileHeight != TILE_SIZE.height) {
- Log.e(LOGTAG, "Aborting draw, incorrect tile size of " + tileWidth + "x" + tileHeight);
- return false;
- }
- return true;
- }
-
- @Override
- public Rect beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata) {
- Rect bufferRect = super.beginDrawing(width, height, tileWidth, tileHeight, metadata);
+ public boolean beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata) {
+ boolean shouldContinue = super.beginDrawing(width, height, tileWidth, tileHeight, metadata);
- if (bufferRect == null) {
- return bufferRect;
+ if (!shouldContinue) {
+ return shouldContinue;
}
// If the window size has changed, reallocate the buffer to match.
@@ -137,7 +117,7 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
mBufferSize = new IntSize(width, height);
}
- return bufferRect;
+ return shouldContinue;
}
@Override
@@ -147,76 +127,6 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
}
}
- /*private void copyPixelsFromMultiTileLayer(Bitmap target) {
- Canvas c = new Canvas(target);
- ByteBuffer tileBuffer = mBuffer.slice();
- int bpp = CairoUtils.bitsPerPixelForCairoFormat(mFormat) / 8;
-
- for (int y = 0; y < mBufferSize.height; y += TILE_SIZE.height) {
- for (int x = 0; x < mBufferSize.width; x += TILE_SIZE.width) {
- // Calculate tile size
- IntSize tileSize = new IntSize(Math.min(mBufferSize.width - x, TILE_SIZE.width),
- Math.min(mBufferSize.height - y, TILE_SIZE.height));
-
- // Create a Bitmap from this tile
- Bitmap tile = Bitmap.createBitmap(tileSize.width, tileSize.height,
- CairoUtils.cairoFormatTobitmapConfig(mFormat));
- tile.copyPixelsFromBuffer(tileBuffer.asIntBuffer());
-
- // Copy the tile to the master Bitmap and recycle it
- c.drawBitmap(tile, x, y, null);
- tile.recycle();
-
- // Progress the buffer to the next tile
- tileBuffer.position(tileSize.getArea() * bpp);
- tileBuffer = tileBuffer.slice();
- }
- }
- }*/
-
- @Override
- protected void tileLayerUpdated() {
- /* No-op. */
- }
-
- @Override
- public Bitmap getBitmap() {
- if (mTileLayer == null)
- return null;
-
- // Begin a tile transaction, otherwise the buffer can be destroyed while
- // we're reading from it.
- /*beginTransaction(mTileLayer);
- try {
- if (mBuffer == null || mBufferSize.width <= 0 || mBufferSize.height <= 0)
- return null;
- try {
- Bitmap b = null;
-
- if (mTileLayer instanceof MultiTileLayer) {
- b = Bitmap.createBitmap(mBufferSize.width, mBufferSize.height,CairoUtils.cairoFormatTobitmapConfig(mFormat));
- copyPixelsFromMultiTileLayer(b);
- } else {
- Log.w(LOGTAG, "getBitmap() called on a layer (" + mTileLayer + ") we don't know how to get a bitmap from");
- }
-
- return b;
- } catch (OutOfMemoryError oom) {
- Log.w(LOGTAG, "Unable to create bitmap", oom);
- return null;
- }
- } finally {
- endTransaction(mTileLayer);
- }*/
-
- return null;
- }
-
- @Override
- public int getType() {
- return LAYER_CLIENT_TYPE_SOFTWARE;
- }
-
@Override
protected IntSize getBufferSize() {
return new IntSize(
@@ -235,3 +145,4 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
}
}
}
+
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerClient.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerClient.java
deleted file mode 100644
index 4f461088203e..000000000000
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerClient.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-/**
- * A layer client provides tiles and manages other information used by the layer controller.
- */
-public abstract class LayerClient {
- private LayerController mLayerController;
-
- public abstract void geometryChanged();
-
- public abstract void viewportSizeChanged();
-
- protected abstract void render();
-
- public LayerController getLayerController() {
- return mLayerController;
- }
-
- public void setLayerController(LayerController layerController) {
- mLayerController = layerController;
- }
-
- /**
- * A utility function for calling Layer.beginTransaction with the
- * appropriate LayerView.
- */
- public void beginTransaction(Layer aLayer) {
- if (mLayerController != null) {
- LayerView view = mLayerController.getView();
- if (view != null) {
- aLayer.beginTransaction(view);
- return;
- }
- }
-
- aLayer.beginTransaction();
- }
-
- // Included for symmetry.
- public void endTransaction(Layer aLayer) {
- aLayer.endTransaction();
- }
-}
-
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 250dc84c69fe..e237052976c7 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
@@ -88,7 +88,7 @@ public class LayerController {
private boolean mWaitForTouchListeners;
private PanZoomController mPanZoomController;
private OnTouchListener mOnTouchListener; /* The touch listener. */
- private LayerClient mLayerClient; /* The layer client. */
+ private GeckoLayerClient mLayerClient; /* The layer client. */
/* The new color for the checkerboard. */
private int mCheckerboardColor;
private boolean mCheckerboardShouldShowChecks;
@@ -111,11 +111,11 @@ public class LayerController {
mForceRedraw = true;
}
- public LayerClient getLayerClient() {
+ public GeckoLayerClient getLayerClient() {
return mLayerClient;
}
- public void setLayerClient(LayerClient layerClient) {
+ public void setLayerClient(GeckoLayerClient layerClient) {
mLayerClient = layerClient;
layerClient.setLayerController(this);
}
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 8c0fce4c73b3..521e60a1ecd6 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
@@ -88,7 +88,7 @@ abstract class Axis {
private float mTouchPos; /* Position of the most recent touch event on the current drag. */
private float mLastTouchPos; /* Position of the touch event before touchPos. */
private float mVelocity; /* Velocity in this direction; pixels per animation frame. */
- public boolean mScrollingDisabled; /* Whether movement on this axis is locked. */
+ private boolean mScrollingDisabled; /* Whether movement on this axis is locked. */
private boolean mDisableSnap; /* Whether overscroll snapping is disabled. */
private float mDisplacement;
@@ -147,7 +147,7 @@ abstract class Axis {
}
private Overscroll getOverscroll() {
- boolean minus = (getOrigin() < 0.0f);
+ boolean minus = getOrigin() < 0.0f;
boolean plus = (getViewportEnd() > getPageLength());
if (minus && plus) {
return Overscroll.BOTH;
@@ -164,10 +164,14 @@ 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();
- default: return 0.0f;
+ case MINUS:
+ return -getOrigin();
+ case PLUS:
+ return getViewportEnd() - getPageLength();
+ case BOTH:
+ return getViewportEnd() - getPageLength() - getOrigin();
+ default:
+ return 0.0f;
}
}
@@ -176,8 +180,7 @@ abstract class Axis {
* possible and this axis has not been scroll locked while panning. Otherwise, returns false.
*/
private boolean scrollable() {
- return getViewportLength() <= getPageLength() - MIN_SCROLLABLE_DISTANCE &&
- !mScrollingDisabled;
+ return getViewportLength() <= getPageLength() - MIN_SCROLLABLE_DISTANCE && !mScrollingDisabled;
}
/*
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 c3cacccf805e..066f4cea2630 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
@@ -38,22 +38,23 @@
package org.mozilla.gecko.ui;
+import android.graphics.PointF;
+import android.graphics.RectF;
+import android.util.FloatMath;
+import android.util.Log;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+
import org.json.JSONObject;
-import org.json.JSONException;
import org.libreoffice.LOKitShell;
import org.libreoffice.LibreOfficeMainActivity;
+import org.mozilla.gecko.GeckoEventListener;
import org.mozilla.gecko.gfx.FloatSize;
import org.mozilla.gecko.gfx.LayerController;
import org.mozilla.gecko.gfx.PointUtils;
import org.mozilla.gecko.gfx.ViewportMetrics;
import org.mozilla.gecko.util.FloatUtils;
-import org.mozilla.gecko.GeckoEventListener;
-import android.graphics.PointF;
-import android.graphics.RectF;
-import android.util.FloatMath;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
+
import java.util.Timer;
import java.util.TimerTask;
@@ -65,29 +66,19 @@ import java.util.TimerTask;
*/
public class PanZoomController
extends GestureDetector.SimpleOnGestureListener
- implements SimpleScaleGestureDetector.SimpleScaleGestureListener, GeckoEventListener
-{
+ implements SimpleScaleGestureDetector.SimpleScaleGestureListener, GeckoEventListener {
+ // The distance the user has to pan before we recognize it as such (e.g. to avoid 1-pixel pans
+ // between the touch-down and touch-up of a click). In units of density-independent pixels.
+ public static final float PAN_THRESHOLD = 1 / 16f * LOKitShell.getDpi();
private static final String LOGTAG = "GeckoPanZoomController";
-
- private static String MESSAGE_ZOOM_RECT = "Browser:ZoomToRect";
- private static String MESSAGE_ZOOM_PAGE = "Browser:ZoomToPageWidth";
-
// Animation stops if the velocity is below this value when overscrolled or panning.
private static final float STOPPED_THRESHOLD = 4.0f;
-
// Animation stops is the velocity is below this threshold when flinging.
private static final float FLING_STOPPED_THRESHOLD = 0.1f;
-
- // The distance the user has to pan before we recognize it as such (e.g. to avoid 1-pixel pans
- // between the touch-down and touch-up of a click). In units of density-independent pixels.
- public static final float PAN_THRESHOLD = 1/16f * LOKitShell.getDpi();
-
// Angle from axis within which we stay axis-locked
private static final double AXIS_LOCK_ANGLE = Math.PI / 6.0; // 30 degrees
-
// 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 final float[] EASE_OUT_ANIMATION_FRAMES = {
0.00000f, /* 0 */
@@ -107,27 +98,13 @@ public class PanZoomController
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 */
- TOUCHING, /* one touch-start event received */
- PANNING_LOCKED, /* touch-start followed by move (i.e. panning with axis lock) */
- PANNING, /* panning without axis lock */
- PANNING_HOLD, /* in panning, but not moving.
- * similar to TOUCHING but after starting a pan */
- PANNING_HOLD_LOCKED, /* like PANNING_HOLD, but axis lock still in effect */
- PINCHING, /* nth touch-start, where n > 1. this mode allows pan and zoom */
- ANIMATED_ZOOM /* animated zoom to a new rect */
- }
-
+ private static String MESSAGE_ZOOM_RECT = "Browser:ZoomToRect";
+ private static String MESSAGE_ZOOM_PAGE = "Browser:ZoomToPageWidth";
private final LayerController mController;
private final SubdocumentScrollHelper mSubscroller;
private final Axis mX;
private final Axis mY;
-
private Thread mMainThread;
-
/* The timer that handles flings or bounces. */
private Timer mAnimationTimer;
/* The runnable being scheduled by the animation timer. */
@@ -146,31 +123,19 @@ public class PanZoomController
mY = new AxisY(mSubscroller);
mMainThread = LibreOfficeMainActivity.mAppContext.getMainLooper().getThread();
- checkMainThread();
mState = PanZoomState.NOTHING;
-
- //GeckoAppShell.registerGeckoEventListener(MESSAGE_ZOOM_RECT, this);
- //GeckoAppShell.registerGeckoEventListener(MESSAGE_ZOOM_PAGE, this);
- }
-
- // for debugging bug 713011; it can be taken out once that is resolved.
- private void checkMainThread() {
- if (mMainThread != Thread.currentThread()) {
- // log with full stack trace
- Log.e(LOGTAG, "Uh-oh, we're running on the wrong thread!", new Exception());
- }
}
public void handleMessage(String event, JSONObject message) {
Log.i(LOGTAG, "Got message: " + event);
try {
if (MESSAGE_ZOOM_RECT.equals(event)) {
- float x = (float)message.getDouble("x");
- float y = (float)message.getDouble("y");
+ float x = (float) message.getDouble("x");
+ float y = (float) message.getDouble("y");
final RectF zoomRect = new RectF(x, y,
- x + (float)message.getDouble("w"),
- y + (float)message.getDouble("h"));
+ x + (float) message.getDouble("w"),
+ y + (float) message.getDouble("h"));
mController.post(new Runnable() {
public void run() {
animatedZoomTo(zoomRect);
@@ -185,9 +150,9 @@ public class PanZoomController
float newHeight = viewableRect.height() * pageSize.width / viewableRect.width();
float dh = viewableRect.height() - newHeight; // increase in the height
final RectF r = new RectF(0.0f,
- y + dh/2,
+ y + dh / 2,
pageSize.width,
- y + dh/2 + newHeight);
+ y + dh / 2 + newHeight);
mController.post(new Runnable() {
public void run() {
animatedZoomTo(r);
@@ -201,17 +166,23 @@ public class PanZoomController
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
- case MotionEvent.ACTION_DOWN: return onTouchStart(event);
- case MotionEvent.ACTION_MOVE: return onTouchMove(event);
- case MotionEvent.ACTION_UP: return onTouchEnd(event);
- case MotionEvent.ACTION_CANCEL: return onTouchCancel(event);
- default: return false;
+ case MotionEvent.ACTION_DOWN:
+ return onTouchStart(event);
+ case MotionEvent.ACTION_MOVE:
+ return onTouchMove(event);
+ case MotionEvent.ACTION_UP:
+ return onTouchEnd(event);
+ case MotionEvent.ACTION_CANCEL:
+ return onTouchCancel(event);
+ default:
+ return false;
}
}
- /** This function must be called from the UI thread. */
+ /**
+ * This function must be called from the UI thread.
+ */
public void abortAnimation() {
- checkMainThread();
// this happens when gecko changes the viewport on us or if the device is rotated.
// if that's the case, abort any animation in progress and re-zoom so that the page
// snaps to edges. for other cases (where the user's finger(s) are down) don't do
@@ -235,11 +206,13 @@ public class PanZoomController
}
}
- /** This must be called on the UI thread. */
+ /**
+ * This must be called on the UI thread.
+ */
public void pageSizeUpdated() {
if (mState == PanZoomState.NOTHING) {
ViewportMetrics validated = getValidViewportMetrics();
- if (! mController.getViewportMetrics().fuzzyEquals(validated)) {
+ if (!mController.getViewportMetrics().fuzzyEquals(validated)) {
// page size changed such that we are now in overscroll. snap to the
// the nearest valid viewport
mController.setViewportMetrics(validated);
@@ -248,10 +221,6 @@ public class PanZoomController
}
}
- /*
- * Panning/scrolling
- */
-
private boolean onTouchStart(MotionEvent event) {
Log.d(LOGTAG, "onTouchStart in state " + mState);
// user is taking control of movement, so stop
@@ -279,6 +248,9 @@ public class PanZoomController
return false;
}
+ /*
+ * Panning/scrolling
+ */
private boolean onTouchMove(MotionEvent event) {
Log.d(LOGTAG, "onTouchMove in state " + mState);
@@ -295,8 +267,6 @@ public class PanZoomController
}
cancelTouch();
startPanning(event.getX(0), event.getY(0), event.getEventTime());
- //GeckoApp.mAppContext.hidePlugins(false /* don't hide layers */);
- //GeckoApp.mAutoCompletePopup.hide();
track(event);
return true;
@@ -404,7 +374,7 @@ public class PanZoomController
}
private void track(float x, float y, long time) {
- float timeDelta = (float)(time - mLastEventTime);
+ float timeDelta = (float) (time - mLastEventTime);
if (FloatUtils.fuzzyEquals(timeDelta, 0)) {
// probably a duplicate event, ignore it. using a zero timeDelta will mess
// up our velocity
@@ -490,8 +460,10 @@ public class PanZoomController
mAnimationRunnable = runnable;
mAnimationTimer.scheduleAtFixedRate(new TimerTask() {
@Override
- public void run() { mController.post(runnable); }
- }, 0, 1000L/60L);
+ public void run() {
+ mController.post(runnable);
+ }
+ }, 0, 1000L / 60L);
}
/* Stops the fling or bounce animation. */
@@ -504,14 +476,12 @@ public class PanZoomController
mAnimationRunnable.terminate();
mAnimationRunnable = null;
}
-
- //GeckoApp.mAppContext.showPlugins();
}
private float getVelocity() {
- float xvel = mX.getRealVelocity();
- float yvel = mY.getRealVelocity();
- return FloatMath.sqrt(xvel * xvel + yvel * yvel);
+ float xVelocity = mX.getRealVelocity();
+ float yVelocity = mY.getRealVelocity();
+ return FloatMath.sqrt(xVelocity * xVelocity + yVelocity * yVelocity);
}
private boolean stopped() {
@@ -526,155 +496,18 @@ public class PanZoomController
mX.displace();
mY.displace();
PointF displacement = getDisplacement();
- if (! mSubscroller.scrollBy(displacement)) {
+ if (!mSubscroller.scrollBy(displacement)) {
synchronized (mController) {
mController.scrollBy(displacement);
}
}
}
- private abstract class AnimationRunnable implements Runnable {
- private boolean mAnimationTerminated;
-
- /* This should always run on the UI thread */
- public final void run() {
- /*
- * Since the animation timer queues this runnable on the UI thread, it
- * is possible that even when the animation timer is cancelled, there
- * are multiple instances of this queued, so we need to have another
- * mechanism to abort. This is done by using the mAnimationTerminated flag.
- */
- if (mAnimationTerminated) {
- return;
- }
- animateFrame();
- }
-
- protected abstract void animateFrame();
-
- /* This should always run on the UI thread */
- protected final void terminate() {
- mAnimationTerminated = true;
- }
- }
-
- /* The callback that performs the bounce animation. */
- private class BounceRunnable extends AnimationRunnable {
- /* The current frame of the bounce-back animation */
- private int mBounceFrame;
- /*
- * The viewport metrics that represent the start and end of the bounce-back animation,
- * respectively.
- */
- private ViewportMetrics mBounceStartMetrics;
- private ViewportMetrics mBounceEndMetrics;
-
- BounceRunnable(ViewportMetrics startMetrics, ViewportMetrics endMetrics) {
- mBounceStartMetrics = startMetrics;
- mBounceEndMetrics = endMetrics;
- }
-
- protected void animateFrame() {
- /*
- * The pan/zoom controller might have signaled to us that it wants to abort the
- * animation by setting the state to PanZoomState.NOTHING. Handle this case and bail
- * out.
- */
- if (mState != PanZoomState.FLING) {
- finishAnimation();
- return;
- }
-
- /* Perform the next frame of the bounce-back animation. */
- if (mBounceFrame < EASE_OUT_ANIMATION_FRAMES.length) {
- advanceBounce();
- return;
- }
-
- /* Finally, if there's nothing else to do, complete the animation and go to sleep. */
- finishBounce();
- finishAnimation();
- mState = PanZoomState.NOTHING;
- }
-
- /* Performs one frame of a bounce animation. */
- private void advanceBounce() {
- synchronized (mController) {
- float t = EASE_OUT_ANIMATION_FRAMES[mBounceFrame];
- ViewportMetrics newMetrics = mBounceStartMetrics.interpolate(mBounceEndMetrics, t);
- mController.setViewportMetrics(newMetrics);
- mController.notifyLayerClientOfGeometryChange();
- mBounceFrame++;
- }
- }
-
- /* Concludes a bounce animation and snaps the viewport into place. */
- private void finishBounce() {
- synchronized (mController) {
- mController.setViewportMetrics(mBounceEndMetrics);
- mController.notifyLayerClientOfGeometryChange();
- mBounceFrame = -1;
- }
- }
- }
-
- // The callback that performs the fling animation.
- private class FlingRunnable extends AnimationRunnable {
- protected void animateFrame() {
- /*
- * The pan/zoom controller might have signaled to us that it wants to abort the
- * animation by setting the state to PanZoomState.NOTHING. Handle this case and bail
- * out.
- */
- if (mState != PanZoomState.FLING) {
- finishAnimation();
- return;
- }
-
- /* Advance flings, if necessary. */
- boolean flingingX = mX.advanceFling();
- boolean flingingY = mY.advanceFling();
-
- boolean overscrolled = (mX.overscrolled() || mY.overscrolled());
-
- /* If we're still flinging in any direction, update the origin. */
- if (flingingX || flingingY) {
- updatePosition();
-
- /*
- * Check to see if we're still flinging with an appreciable velocity. The threshold is
- * higher in the case of overscroll, so we bounce back eagerly when overscrolling but
- * coast smoothly to a stop when not. In other words, require a greater velocity to
- * maintain the fling once we enter overscroll.
- */
- float threshold = (overscrolled && !mSubscroller.scrolling() ? STOPPED_THRESHOLD : FLING_STOPPED_THRESHOLD);
- if (getVelocity() >= threshold) {
- // we're still flinging
- return;
- }
-
- mX.stopFling();
- mY.stopFling();
- }
-
- /* Perform a bounce-back animation if overscrolled. */
- if (overscrolled) {
- bounce();
- } else {
- finishAnimation();
- mState = PanZoomState.NOTHING;
- }
- }
- }
-
private void finishAnimation() {
- checkMainThread();
-
Log.d(LOGTAG, "Finishing animation at " + mController.getViewportMetrics());
stopAnimationTimer();
// Force a viewport synchronisation
- //GeckoApp.mAppContext.showPlugins();
mController.setForceRedraw();
mController.notifyLayerClientOfGeometryChange();
}
@@ -726,26 +559,6 @@ public class PanZoomController
return viewportMetrics;
}
- private class AxisX extends Axis {
- AxisX(SubdocumentScrollHelper subscroller) { super(subscroller); }
- @Override
- public float getOrigin() { return mController.getOrigin().x; }
- @Override
- protected float getViewportLength() { return mController.getViewportSize().width; }
- @Override
- protected float getPageLength() { return mController.getPageSize().width; }
- }
-
- private class AxisY extends Axis {
- AxisY(SubdocumentScrollHelper subscroller) { super(subscroller); }
- @Override
- public float getOrigin() { return mController.getOrigin().y; }
- @Override
- protected float getViewportLength() { return mController.getViewportSize().height; }
- @Override
- protected float getPageLength() { return mController.getPageSize().height; }
- }
-
/*
* Zooming
*/
@@ -758,8 +571,7 @@ public class PanZoomController
mState = PanZoomState.PINCHING;
mLastZoomFocus = new PointF(detector.getFocusX(), detector.getFocusY());
- //GeckoApp.mAppContext.hidePlugins(false /* don't hide layers, only views */);
- //GeckoApp.mAutoCompletePopup.hide();
+
cancelTouch();
return true;
@@ -785,10 +597,11 @@ public class PanZoomController
* factor toward 1.0.
*/
float resistance = Math.min(mX.getEdgeResistance(), mY.getEdgeResistance());
- if (spanRatio > 1.0f)
+ if (spanRatio > 1.0f) {
spanRatio = 1.0f + (spanRatio - 1.0f) * resistance;
- else
+ } else {
spanRatio = 1.0f - (1.0f - spanRatio) * resistance;
+ }
synchronized (mController) {
float newZoomFactor = mController.getZoomFactor() * spanRatio;
@@ -797,7 +610,7 @@ public class PanZoomController
// such that it asymptotically reaches MAX_ZOOM + 1.0
// but never exceeds that
float excessZoom = newZoomFactor - MAX_ZOOM;
- excessZoom = 1.0f - (float)Math.exp(-excessZoom);
+ excessZoom = 1.0f - (float) Math.exp(-excessZoom);
newZoomFactor = MAX_ZOOM + excessZoom;
}
@@ -832,55 +645,29 @@ public class PanZoomController
return (mState != PanZoomState.PINCHING && mState != PanZoomState.ANIMATED_ZOOM);
}
- private void sendPointToGecko(String event, MotionEvent motionEvent) {
- String json;
- try {
- PointF point = new PointF(motionEvent.getX(), motionEvent.getY());
- point = mController.convertViewPointToLayerPoint(point);
- if (point == null) {
- return;
- }
- json = PointUtils.toJSON(point).toString();
- } catch (Exception e) {
- Log.e(LOGTAG, "Unable to convert point to JSON for " + event, e);
- return;
- }
-
- //GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(event, json));
- }
-
@Override
public void onLongPress(MotionEvent motionEvent) {
- sendPointToGecko("Gesture:LongPress", motionEvent);
}
@Override
public boolean onDown(MotionEvent motionEvent) {
- sendPointToGecko("Gesture:ShowPress", motionEvent);
return false;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
- //GeckoApp.mAutoCompletePopup.hide();
- sendPointToGecko("Gesture:SingleTap", motionEvent);
return true;
}
@Override
public boolean onDoubleTap(MotionEvent motionEvent) {
- sendPointToGecko("Gesture:DoubleTap", motionEvent);
return true;
}
public void cancelTouch() {
- //GeckoEvent e = GeckoEvent.createBroadcastEvent("Gesture:CancelTouch", "");
- //GeckoAppShell.sendEventToGecko(e);
}
private boolean animatedZoomTo(RectF zoomToRect) {
- //GeckoApp.mAutoCompletePopup.hide();
-
mState = PanZoomState.ANIMATED_ZOOM;
final float startZoom = mController.getZoomFactor();
@@ -918,4 +705,193 @@ public class PanZoomController
bounce(finalMetrics);
return true;
}
+
+ private enum PanZoomState {
+ NOTHING, /* no touch-start events received */
+ FLING, /* all touches removed, but we're still scrolling page */
+ TOUCHING, /* one touch-start event received */
+ PANNING_LOCKED, /* touch-start followed by move (i.e. panning with axis lock) */
+ PANNING, /* panning without axis lock */
+ PANNING_HOLD, /* in panning, but not moving.
+ * similar to TOUCHING but after starting a pan */
+ PANNING_HOLD_LOCKED, /* like PANNING_HOLD, but axis lock still in effect */
+ PINCHING, /* nth touch-start, where n > 1. this mode allows pan and zoom */
+ ANIMATED_ZOOM /* animated zoom to a new rect */
+ }
+
+ private abstract class AnimationRunnable implements Runnable {
+ private boolean mAnimationTerminated;
+
+ /* This should always run on the UI thread */
+ public final void run() {
+ /*
+ * Since the animation timer queues this runnable on the UI thread, it
+ * is possible that even when the animation timer is cancelled, there
+ * are multiple instances of this queued, so we need to have another
+ * mechanism to abort. This is done by using the mAnimationTerminated flag.
+ */
+ if (mAnimationTerminated) {
+ return;
+ }
+ animateFrame();
+ }
+
+ protected abstract void animateFrame();
+
+ /* This should always run on the UI thread */
+ protected final void terminate() {
+ mAnimationTerminated = true;
+ }
+ }
+
+ /* The callback that performs the bounce animation. */
+ private class BounceRunnable extends AnimationRunnable {
+ /* The current frame of the bounce-back animation */
+ private int mBounceFrame;
+ /*
+ * The viewport metrics that represent the start and end of the bounce-back animation,
+ * respectively.
+ */
+ private ViewportMetrics mBounceStartMetrics;
+ private ViewportMetrics mBounceEndMetrics;
+
+ BounceRunnable(ViewportMetrics startMetrics, ViewportMetrics endMetrics) {
+ mBounceStartMetrics = startMetrics;
+ mBounceEndMetrics = endMetrics;
+ }
+
+ protected void animateFrame() {
+ /*
+ * The pan/zoom controller might have signaled to us that it wants to abort the
+ * animation by setting the state to PanZoomState.NOTHING. Handle this case and bail
+ * out.
+ */
+ if (mState != PanZoomState.FLING) {
+ finishAnimation();
+ return;
+ }
+
+ /* Perform the next frame of the bounce-back animation. */
+ if (mBounceFrame < EASE_OUT_ANIMATION_FRAMES.length) {
+ advanceBounce();
+ return;
+ }
+
+ /* Finally, if there's nothing else to do, complete the animation and go to sleep. */
+ finishBounce();
+ finishAnimation();
+ mState = PanZoomState.NOTHING;
+ }
+
+ /* Performs one frame of a bounce animation. */
+ private void advanceBounce() {
+ synchronized (mController) {
+ float t = EASE_OUT_ANIMATION_FRAMES[mBounceFrame];
+ ViewportMetrics newMetrics = mBounceStartMetrics.interpolate(mBounceEndMetrics, t);
+ mController.setViewportMetrics(newMetrics);
+ mController.notifyLayerClientOfGeometryChange();
+ mBounceFrame++;
+ }
+ }
+
+ /* Concludes a bounce animation and snaps the viewport into place. */
+ private void finishBounce() {
+ synchronized (mController) {
+ mController.setViewportMetrics(mBounceEndMetrics);
+ mController.notifyLayerClientOfGeometryChange();
+ mBounceFrame = -1;
+ }
+ }
+ }
+
+ // The callback that performs the fling animation.
+ private class FlingRunnable extends AnimationRunnable {
+ protected void animateFrame() {
+ /*
+ * The pan/zoom controller might have signaled to us that it wants to abort the
+ * animation by setting the state to PanZoomState.NOTHING. Handle this case and bail
+ * out.
+ */
+ if (mState != PanZoomState.FLING) {
+ finishAnimation();
+ return;
+ }
+
+ /* Advance flings, if necessary. */
+ boolean flingingX = mX.advanceFling();
+ boolean flingingY = mY.advanceFling();
+
+ boolean overscrolled = (mX.overscrolled() || mY.overscrolled());
+
+ /* If we're still flinging in any direction, update the origin. */
+ if (flingingX || flingingY) {
+ updatePosition();
+
+ /*
+ * Check to see if we're still flinging with an appreciable velocity. The threshold is
+ * higher in the case of overscroll, so we bounce back eagerly when overscrolling but
+ * coast smoothly to a stop when not. In other words, require a greater velocity to
+ * maintain the fling once we enter overscroll.
+ */
+ float threshold = (overscrolled && !mSubscroller.scrolling() ? STOPPED_THRESHOLD : FLING_STOPPED_THRESHOLD);
+ if (getVelocity() >= threshold) {
+ // we're still flinging
+ return;
+ }
+
+ mX.stopFling();
+ mY.stopFling();
+ }
+
+ /* Perform a bounce-back animation if overscrolled. */
+ if (overscrolled) {
+ bounce();
+ } else {
+ finishAnimation();
+ mState = PanZoomState.NOTHING;
+ }
+ }
+ }
+
+ private class AxisX extends Axis {
+ AxisX(SubdocumentScrollHelper subscroller) {
+ super(subscroller);
+ }
+
+ @Override
+ public float getOrigin() {
+ return mController.getOrigin().x;
+ }
+
+ @Override
+ protected float getViewportLength() {
+ return mController.getViewportSize().width;
+ }
+
+ @Override
+ protected float getPageLength() {
+ return mController.getPageSize().width;
+ }
+ }
+
+ private class AxisY extends Axis {
+ AxisY(SubdocumentScrollHelper subscroller) {
+ super(subscroller);
+ }
+
+ @Override
+ public float getOrigin() {
+ return mController.getOrigin().y;
+ }
+
+ @Override
+ protected float getViewportLength() {
+ return mController.getViewportSize().height;
+ }
+
+ @Override
+ protected float getPageLength() {
+ return mController.getPageSize().height;
+ }
+ }
}