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