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