RenderCoordinates.java revision 0f1bc08d4cfcc34181b0b5cbf065c40f687bf740
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    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 True if the page has a width=device-width or narrower viewport.
275     */
276    public boolean hasMobileViewport() {
277        float windowWidthDip = mPageScaleFactor * mLastFrameViewportWidthCss;
278        return mContentWidthCss <= windowWidthDip;
279    }
280
281    /**
282     * @return Maximum possible horizontal scroll in physical pixels.
283     */
284    public float getMaxHorizontalScrollPix() {
285        return getContentWidthPix() - getLastFrameViewportWidthPix();
286    }
287
288    /**
289     * @return Maximum possible vertical scroll in physical pixels.
290     */
291    public float getMaxVerticalScrollPix() {
292        return getContentHeightPix() - getLastFrameViewportHeightPix();
293    }
294
295    /**
296     * @return Maximum possible horizontal scroll in physical pixels (approx, integer).
297     */
298    public int getMaxHorizontalScrollPixInt() {
299        return (int) Math.floor(getMaxHorizontalScrollPix());
300    }
301
302    /**
303     * @return Maximum possible vertical scroll in physical pixels (approx, integer).
304     */
305    public int getMaxVerticalScrollPixInt() {
306        return (int) Math.floor(getMaxVerticalScrollPix());
307    }
308
309    /**
310     * @return Physical on-screen coordinate converted to local DIP.
311     */
312    public float fromPixToDip(float pix) {
313        return pix / mDeviceScaleFactor;
314    }
315
316    /**
317     * @return Local DIP converted to physical coordinates.
318     */
319    public float fromDipToPix(float dip) {
320        return dip * mDeviceScaleFactor;
321    }
322
323    /**
324     * @return Physical coordinate converted to local CSS.
325     */
326    public float fromPixToLocalCss(float pix) {
327        return pix / (mDeviceScaleFactor * mPageScaleFactor);
328    }
329
330    /**
331     * @return Local CSS converted to physical coordinates.
332     */
333    public float fromLocalCssToPix(float css) {
334        return css * mPageScaleFactor * mDeviceScaleFactor;
335    }
336}
337