diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.com> | 2014-09-27 23:38:19 +0200 |
---|---|---|
committer | Tomaž Vajngerl <tomaz.vajngerl@collabora.com> | 2014-09-28 22:32:48 +0200 |
commit | ebc25c427936708b8e32e563d6735575d6ac9f92 (patch) | |
tree | 0b3d6ddbd38d2651db4d0f599c2c4ff67eb329bb | |
parent | f66ff689d0b3ba5196cac717c7228f541d853e3f (diff) |
android: replace with ImmutableViewportMetrics (Fennec import)
Change-Id: I46509f8be4dc49dac45eb98059dad25e150988dd
10 files changed, 227 insertions, 193 deletions
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java index f16b2da237bc..80210a7e45a8 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 ddc18d4eb885..f808f57b4bbe 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 e3f57933ff67..e847c01c9139 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 5403c80ff42d..35b417593acf 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 ca02e1c784d4..2e6a4a0f20df 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 cdacc317ee13..4eb07a31f147 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 92ea78f8a177..1608e91ad062 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 789bb0bff0b5..f8b5c2e055dc 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 02e45daf3a15..555c7ebe60fa 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 3ebc4f1bb392..fdac874ee6f9 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); |