Home | History | Annotate | Download | only in browser
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 package org.chromium.content.browser;
      6 
      7 /**
      8  * Cached copy of all positions and scales (CSS-to-DIP-to-physical pixels)
      9  * reported from the renderer.
     10  * Provides wrappers and a utility class to help with coordinate transforms on the client side.
     11  * Provides the internally-visible set of update methods (called from ContentViewCore).
     12  *
     13  * Unless stated otherwise, all coordinates are in CSS (document) coordinate space.
     14  */
     15 public class RenderCoordinates {
     16     // Scroll offset from the native in CSS.
     17     private float mScrollXCss;
     18     private float mScrollYCss;
     19 
     20     // Content size from native in CSS.
     21     private float mContentWidthCss;
     22     private float mContentHeightCss;
     23 
     24     // Last-frame render-reported viewport size in CSS.
     25     private float mLastFrameViewportWidthCss;
     26     private float mLastFrameViewportHeightCss;
     27 
     28     // Cached page scale factor from native.
     29     private float mPageScaleFactor = 1.0f;
     30     private float mMinPageScaleFactor = 1.0f;
     31     private float mMaxPageScaleFactor = 1.0f;
     32 
     33     // Cached device density.
     34     private float mDeviceScaleFactor;
     35 
     36     private float mContentOffsetYPix;
     37 
     38     // Internally-visible set of update methods (used by ContentViewCore).
     39     void reset() {
     40         mScrollXCss = mScrollYCss = 0;
     41         mPageScaleFactor = 1.0f;
     42     }
     43 
     44     void updateContentSizeCss(float contentWidthCss, float contentHeightCss) {
     45         mContentWidthCss = contentWidthCss;
     46         mContentHeightCss = contentHeightCss;
     47     }
     48 
     49     void setDeviceScaleFactor(float deviceScaleFactor) {
     50         mDeviceScaleFactor = deviceScaleFactor;
     51     }
     52 
     53     void updateFrameInfo(
     54             float scrollXCss, float scrollYCss,
     55             float contentWidthCss, float contentHeightCss,
     56             float viewportWidthCss, float viewportHeightCss,
     57             float pageScaleFactor, float minPageScaleFactor, float maxPageScaleFactor,
     58             float contentOffsetYPix) {
     59         mScrollXCss = scrollXCss;
     60         mScrollYCss = scrollYCss;
     61         mPageScaleFactor = pageScaleFactor;
     62         mMinPageScaleFactor = minPageScaleFactor;
     63         mMaxPageScaleFactor = maxPageScaleFactor;
     64         mContentOffsetYPix = contentOffsetYPix;
     65 
     66         updateContentSizeCss(contentWidthCss, contentHeightCss);
     67         mLastFrameViewportWidthCss = viewportWidthCss;
     68         mLastFrameViewportHeightCss = viewportHeightCss;
     69     }
     70 
     71     /**
     72      * Handles conversion of a point from window-relative-local-dip or screen-pix
     73      * to document-absolute-CSS space and vice versa.
     74      */
     75     public class NormalizedPoint {
     76         private float mXAbsoluteCss, mYAbsoluteCss;
     77 
     78         private NormalizedPoint() {
     79         }
     80 
     81         /**
     82          * @return Absolute CSS (document) X coordinate of the point.
     83          */
     84         public float getXAbsoluteCss() { return mXAbsoluteCss; }
     85 
     86         /**
     87          * @return Absolute CSS (document) Y coordinate of the point.
     88          */
     89         public float getYAbsoluteCss() { return mYAbsoluteCss; }
     90 
     91         /**
     92          * @return Local device-scale-unadjusted X coordinate of the point.
     93          */
     94         public float getXLocalDip() { return (mXAbsoluteCss - mScrollXCss) * mPageScaleFactor; }
     95 
     96         /**
     97          * @return Local device-scale-unadjusted Y coordinate of the point.
     98          */
     99         public float getYLocalDip() { return (mYAbsoluteCss - mScrollYCss) * mPageScaleFactor; }
    100 
    101         /**
    102          * @return Physical (screen) X coordinate of the point.
    103          */
    104         public float getXPix() { return getXLocalDip() * mDeviceScaleFactor; }
    105 
    106         /**
    107          * @return Physical (screen) Y coordinate of the point.
    108          */
    109         public float getYPix() { return getYLocalDip() * mDeviceScaleFactor + mContentOffsetYPix; }
    110 
    111         /**
    112          * Sets the point to the given absolute CSS (document) coordinates.
    113          */
    114         public void setAbsoluteCss(float xCss, float yCss) {
    115             mXAbsoluteCss = xCss;
    116             mYAbsoluteCss = yCss;
    117         }
    118 
    119         /**
    120          * Sets the point to the given local device-scale-unadjusted coordinates.
    121          */
    122         public void setLocalDip(float xDip, float yDip) {
    123             setAbsoluteCss(
    124                     xDip / mPageScaleFactor + mScrollXCss,
    125                     yDip / mPageScaleFactor + mScrollYCss);
    126         }
    127 
    128         /**
    129          * Sets the point to the given physical (screen) coordinates.
    130          */
    131         public void setScreen(float xPix, float yPix) {
    132             setLocalDip(xPix / mDeviceScaleFactor, yPix / mDeviceScaleFactor);
    133         }
    134     }
    135 
    136     /**
    137      * @return A helper to convert a point between between absolute CSS and local DIP spaces.
    138      */
    139     public NormalizedPoint createNormalizedPoint() {
    140         return new NormalizedPoint();
    141     }
    142 
    143     /**
    144      * @return Horizontal scroll offset in CSS pixels.
    145      */
    146     public float getScrollX() { return mScrollXCss; }
    147 
    148     /**
    149      * @return Vertical scroll offset in CSS pixels.
    150      */
    151     public float getScrollY() { return mScrollYCss; }
    152 
    153     /**
    154      * @return Horizontal scroll offset in physical pixels.
    155      */
    156     public float getScrollXPix() { return fromLocalCssToPix(mScrollXCss); }
    157 
    158     /**
    159      * @return Vertical scroll offset in physical pixels.
    160      */
    161     public float getScrollYPix() { return fromLocalCssToPix(mScrollYCss); }
    162 
    163     /**
    164      * @return Horizontal scroll offset in physical pixels (approx, integer).
    165      */
    166     public int getScrollXPixInt() { return (int) Math.floor(getScrollXPix()); }
    167 
    168     /**
    169      * @return Vertical scroll offset in physical pixels (approx, integer).
    170      */
    171     public int getScrollYPixInt() { return (int) Math.floor(getScrollYPix()); }
    172 
    173     /**
    174      * @return Width of the content in CSS pixels.
    175      */
    176     public float getContentWidthCss() { return mContentWidthCss; }
    177 
    178     /**
    179      * @return Height of the content in CSS pixels.
    180      */
    181     public float getContentHeightCss() { return mContentHeightCss; }
    182 
    183     /**
    184      * @return Approximate width of the content in physical pixels.
    185      */
    186     public float getContentWidthPix() { return fromLocalCssToPix(mContentWidthCss); }
    187 
    188     /**
    189      * @return Approximate height of the content in physical pixels.
    190      */
    191     public float getContentHeightPix() { return fromLocalCssToPix(mContentHeightCss); }
    192 
    193     /**
    194      * @return Approximate width of the content in physical pixels (integer).
    195      */
    196     public int getContentWidthPixInt() { return (int) Math.ceil(getContentWidthPix()); }
    197 
    198     /**
    199      * @return Approximate height of the content in physical pixels (integer).
    200      */
    201     public int getContentHeightPixInt() { return (int) Math.ceil(getContentHeightPix()); }
    202 
    203     /**
    204      * @return Render-reported width of the viewport in CSS pixels.
    205      */
    206     public float getLastFrameViewportWidthCss() { return mLastFrameViewportWidthCss; }
    207 
    208     /**
    209      * @return Render-reported height of the viewport in CSS pixels.
    210      */
    211     public float getLastFrameViewportHeightCss() { return mLastFrameViewportHeightCss; }
    212 
    213     /**
    214      * @return Render-reported width of the viewport in physical pixels (approximate).
    215      */
    216     public float getLastFrameViewportWidthPix() {
    217         return fromLocalCssToPix(mLastFrameViewportWidthCss);
    218     }
    219 
    220     /**
    221      * @return Render-reported height of the viewport in physical pixels (approximate).
    222      */
    223     public float getLastFrameViewportHeightPix() {
    224         return fromLocalCssToPix(mLastFrameViewportHeightCss);
    225     }
    226 
    227     /**
    228      * @return Render-reported width of the viewport in physical pixels (approx, integer).
    229      */
    230     public int getLastFrameViewportWidthPixInt() {
    231         return (int) Math.ceil(getLastFrameViewportWidthPix());
    232     }
    233 
    234     /**
    235      * @return Render-reported height of the viewport in physical pixels (approx, integer).
    236      */
    237     public int getLastFrameViewportHeightPixInt() {
    238         return (int) Math.ceil(getLastFrameViewportHeightPix());
    239     }
    240 
    241     /**
    242      * @return The Physical on-screen Y offset amount below the top controls.
    243      */
    244     public float getContentOffsetYPix() {
    245         return mContentOffsetYPix;
    246     }
    247 
    248     /**
    249      * @return Current page scale factor (maps CSS pixels to DIP pixels).
    250      */
    251     public float getPageScaleFactor() { return mPageScaleFactor; }
    252 
    253     /**
    254      * @return Minimum page scale factor to be used with the content.
    255      */
    256     public float getMinPageScaleFactor() { return mMinPageScaleFactor; }
    257 
    258     /**
    259      * @return Maximum page scale factor to be used with the content.
    260      */
    261     public float getMaxPageScaleFactor() { return mMaxPageScaleFactor; }
    262 
    263     /**
    264      * @return Current device scale factor (maps DIP pixels to physical pixels).
    265      */
    266     public float getDeviceScaleFactor() { return mDeviceScaleFactor; }
    267 
    268     /**
    269      * @return True if the page doesn't allow zoom-in/zoom-out.
    270      */
    271     public boolean hasFixedPageScale() { return mMinPageScaleFactor == mMaxPageScaleFactor; }
    272 
    273     /**
    274      * @return Maximum possible horizontal scroll in physical pixels.
    275      */
    276     public float getMaxHorizontalScrollPix() {
    277         return getContentWidthPix() - getLastFrameViewportWidthPix();
    278     }
    279 
    280     /**
    281      * @return Maximum possible vertical scroll in physical pixels.
    282      */
    283     public float getMaxVerticalScrollPix() {
    284         return getContentHeightPix() - getLastFrameViewportHeightPix();
    285     }
    286 
    287     /**
    288      * @return Maximum possible horizontal scroll in physical pixels (approx, integer).
    289      */
    290     public int getMaxHorizontalScrollPixInt() {
    291         return (int) Math.floor(getMaxHorizontalScrollPix());
    292     }
    293 
    294     /**
    295      * @return Maximum possible vertical scroll in physical pixels (approx, integer).
    296      */
    297     public int getMaxVerticalScrollPixInt() {
    298         return (int) Math.floor(getMaxVerticalScrollPix());
    299     }
    300 
    301     /**
    302      * @return Physical on-screen coordinate converted to local DIP.
    303      */
    304     public float fromPixToDip(float pix) {
    305         return pix / mDeviceScaleFactor;
    306     }
    307 
    308     /**
    309      * @return Local DIP converted to physical coordinates.
    310      */
    311     public float fromDipToPix(float dip) {
    312         return dip * mDeviceScaleFactor;
    313     }
    314 
    315     /**
    316      * @return Physical coordinate converted to local CSS.
    317      */
    318     public float fromPixToLocalCss(float pix) {
    319         return pix / (mDeviceScaleFactor * mPageScaleFactor);
    320     }
    321 
    322     /**
    323      * @return Local CSS converted to physical coordinates.
    324      */
    325     public float fromLocalCssToPix(float css) {
    326         return css * mPageScaleFactor * mDeviceScaleFactor;
    327     }
    328 }
    329