Bug 744939 - Make animatedZoomTo operate in CSS pixels instead of device pixels. r=kats a=blocking-fennec
authorJoe Drew <joe@drew.ca>
Sat, 14 Apr 2012 13:18:10 -0400
changeset 92049 3a1d0f6ebe70240c20d76b483ec4c03f2cbfcdf2
parent 92048 ec943d58604624e088163614fde479f95540109b
child 92050 a12cbe3bf0456b062226487199ec6615c8b06ff3
push id22498
push userphilringnalda@gmail.com
push dateSat, 21 Apr 2012 02:58:04 +0000
treeherdermozilla-central@bce6cabacc88 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats, blocking-fennec
bugs744939
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 744939 - Make animatedZoomTo operate in CSS pixels instead of device pixels. r=kats a=blocking-fennec
mobile/android/base/gfx/ImmutableViewportMetrics.java
mobile/android/base/gfx/LayerController.java
mobile/android/base/gfx/ViewportMetrics.java
mobile/android/base/ui/PanZoomController.java
mobile/android/chrome/content/browser.js
--- a/mobile/android/base/gfx/ImmutableViewportMetrics.java
+++ b/mobile/android/base/gfx/ImmutableViewportMetrics.java
@@ -65,16 +65,20 @@ public class ImmutableViewportMetrics {
 
     public RectF getViewport() {
         return new RectF(viewportRectLeft,
                          viewportRectTop,
                          viewportRectRight,
                          viewportRectBottom);
     }
 
+    public RectF getCssViewport() {
+        return RectUtils.scale(getViewport(), 1/zoomFactor);
+    }
+
     public FloatSize getPageSize() {
         return new FloatSize(pageSizeWidth, pageSizeHeight);
     }
 
     public FloatSize getCssPageSize() {
         return new FloatSize(cssPageSizeWidth, cssPageSizeHeight);
     }
 }
--- a/mobile/android/base/gfx/LayerController.java
+++ b/mobile/android/base/gfx/LayerController.java
@@ -123,16 +123,20 @@ public class LayerController {
     public LayerView getView()                    { return mView; }
     public Context getContext()                   { return mContext; }
     public ImmutableViewportMetrics getViewportMetrics()   { return mViewportMetrics; }
 
     public RectF getViewport() {
         return mViewportMetrics.getViewport();
     }
 
+    public RectF getCssViewport() {
+        return mViewportMetrics.getCssViewport();
+    }
+
     public FloatSize getViewportSize() {
         return mViewportMetrics.getSize();
     }
 
     public FloatSize getPageSize() {
         return mViewportMetrics.getPageSize();
     }
 
--- a/mobile/android/base/gfx/ViewportMetrics.java
+++ b/mobile/android/base/gfx/ViewportMetrics.java
@@ -117,16 +117,20 @@ public class ViewportMetrics {
     public FloatSize getSize() {
         return new FloatSize(mViewportRect.width(), mViewportRect.height());
     }
 
     public RectF getViewport() {
         return mViewportRect;
     }
 
+    public RectF getCssViewport() {
+        return RectUtils.scale(mViewportRect, 1/mZoomFactor);
+    }
+
     /** Returns the viewport rectangle, clamped within the page-size. */
     public RectF getClampedViewport() {
         RectF clampedViewport = new RectF(mViewportRect);
 
         // While the viewport size ought to never exceed the page size, we
         // do the clamping in this order to make sure that the origin is
         // never negative.
         if (clampedViewport.right > mPageSize.width)
--- a/mobile/android/base/ui/PanZoomController.java
+++ b/mobile/android/base/ui/PanZoomController.java
@@ -189,19 +189,19 @@ public class PanZoomController
                                      x + (float)message.getDouble("w"),
                                      y + (float)message.getDouble("h"));
                 mController.post(new Runnable() {
                     public void run() {
                         animatedZoomTo(zoomRect);
                     }
                 });
             } else if (MESSAGE_ZOOM_PAGE.equals(event)) {
-                FloatSize pageSize = mController.getPageSize();
+                FloatSize pageSize = mController.getCssPageSize();
 
-                RectF viewableRect = mController.getViewport();
+                RectF viewableRect = mController.getCssViewport();
                 float y = viewableRect.top;
                 // attempt to keep zoom keep focused on the center of the viewport
                 float newHeight = viewableRect.height() * pageSize.width / viewableRect.width();
                 float dh = viewableRect.height() - newHeight; // increase in the height
                 final RectF r = new RectF(0.0f,
                                     y + dh/2,
                                     pageSize.width,
                                     y + dh/2 + newHeight);
@@ -974,16 +974,22 @@ public class PanZoomController
         return true;
     }
 
     private void cancelTouch() {
         GeckoEvent e = GeckoEvent.createBroadcastEvent("Gesture:CancelTouch", "");
         GeckoAppShell.sendEventToGecko(e);
     }
 
+    /**
+     * Zoom to a specified rect IN CSS PIXELS.
+     *
+     * While we usually use device pixels, @zoomToRect must be specified in CSS
+     * pixels.
+     */
     private boolean animatedZoomTo(RectF zoomToRect) {
         GeckoApp.mFormAssistPopup.hide();
 
         mState = PanZoomState.ANIMATED_ZOOM;
         final float startZoom = mController.getZoomFactor();
 
         RectF viewport = mController.getViewport();
         // 1. adjust the aspect ratio of zoomToRect to match that of the current viewport,
@@ -1001,20 +1007,21 @@ public class PanZoomController
             zoomToRect.bottom = zoomToRect.top + newHeight;
         } else { // targetRatio > rectRatio) {
             // need to increase zoomToRect width
             float newWidth = targetRatio * zoomToRect.height();
             zoomToRect.left -= (newWidth - zoomToRect.width()) / 2;
             zoomToRect.right = zoomToRect.left + newWidth;
         }
 
-        float finalZoom = viewport.width() * startZoom / zoomToRect.width();
+        float finalZoom = viewport.width() / zoomToRect.width();
 
         ViewportMetrics finalMetrics = new ViewportMetrics(mController.getViewportMetrics());
-        finalMetrics.setOrigin(new PointF(zoomToRect.left, zoomToRect.top));
+        finalMetrics.setOrigin(new PointF(zoomToRect.left * finalMetrics.getZoomFactor(),
+                                          zoomToRect.top * finalMetrics.getZoomFactor()));
         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.
         finalMetrics = getValidViewportMetrics(finalMetrics);
 
         bounce(finalMetrics);
         return true;
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1764,35 +1764,37 @@ Tab.prototype = {
               Math.max(body.scrollHeight, html.scrollHeight)];
     }
   },
 
   getViewport: function() {
     let viewport = {
       width: gScreenWidth,
       height: gScreenHeight,
+      cssWidth: gScreenWidth / this._zoom,
+      cssHeight: gScreenHeight / this._zoom,
       pageWidth: gScreenWidth,
       pageHeight: gScreenHeight,
       // We make up matching css page dimensions
       cssPageWidth: gScreenWidth / this._zoom,
       cssPageHeight: gScreenHeight / this._zoom,
       zoom: this._zoom
     };
 
     // Set the viewport offset to current scroll offset
-    viewport.x = this.browser.contentWindow.scrollX || 0;
-    viewport.y = this.browser.contentWindow.scrollY || 0;
+    viewport.cssX = this.browser.contentWindow.scrollX || 0;
+    viewport.cssY = this.browser.contentWindow.scrollY || 0;
 
     // Transform coordinates based on zoom
-    viewport.x = Math.round(viewport.x * viewport.zoom);
-    viewport.y = Math.round(viewport.y * viewport.zoom);
+    viewport.x = Math.round(viewport.cssX * viewport.zoom);
+    viewport.y = Math.round(viewport.cssY * viewport.zoom);
 
     let doc = this.browser.contentDocument;
     if (doc != null) {
-      let [pageWidth, pageHeight] = this.getPageSize(doc, viewport.width, viewport.height);
+      let [pageWidth, pageHeight] = this.getPageSize(doc, viewport.cssWidth, viewport.cssHeight);
 
       let cssPageWidth = pageWidth;
       let cssPageHeight = pageHeight;
 
       /* Transform the page width and height based on the zoom factor. */
       pageWidth *= viewport.zoom;
       pageHeight *= viewport.zoom;
 
@@ -2516,35 +2518,33 @@ var BrowserEventHandler = {
       this._zoomOut();
     } else {
       const margin = 15;
       const minDifference = -20;
       const maxDifference = 20;
       let rect = ElementTouchHelper.getBoundingContentRect(element);
 
       let viewport = BrowserApp.selectedTab.getViewport();
-      let vRect = new Rect(viewport.x, viewport.y, viewport.width, viewport.height);
-
-      let zoom = viewport.zoom;
+      let vRect = new Rect(viewport.cssX, viewport.cssY, viewport.cssWidth, viewport.cssHeight);
       let bRect = new Rect(Math.max(0,rect.x - margin),
                            rect.y,
                            rect.w + 2*margin,
                            rect.h);
+
       // constrict the rect to the screen width
-      bRect.width = Math.min(bRect.width, viewport.pageWidth/zoom - bRect.x);
-      bRect.scale(zoom, zoom);
+      bRect.width = Math.min(bRect.width, viewport.cssPageWidth - bRect.x);
 
       let overlap = vRect.intersect(bRect);
       let overlapArea = overlap.width*overlap.height;
       // we want to know if the area of the element showing is near the max we can show
       // on the screen at any time and if its already stretching the width of the screen
       let availHeight = Math.min(bRect.width*vRect.height/vRect.width, bRect.height);
       let showing = overlapArea/(bRect.width*availHeight);
-      let dw = (bRect.width - vRect.width)/zoom;
-      let dx = (bRect.x - vRect.x)/zoom;
+      let dw = (bRect.width - vRect.width);
+      let dx = (bRect.x - vRect.x);
 
       if (showing > 0.9 &&
           dx > minDifference && dx < maxDifference &&
           dw > minDifference && dw < maxDifference) {
             this._zoomOut();
             return;
       }