// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.content.browser;
/**
* Cached copy of all positions and scales (CSS-to-DIP-to-physical pixels)
* reported from the renderer.
* Provides wrappers and a utility class to help with coordinate transforms on the client side.
* Provides the internally-visible set of update methods (called from ContentViewCore).
*
* Unless stated otherwise, all coordinates are in CSS (document) coordinate space.
*/
public class RenderCoordinates {
// Scroll offset from the native in CSS.
private float mScrollXCss;
private float mScrollYCss;
// Content size from native in CSS.
private float mContentWidthCss;
private float mContentHeightCss;
// Last-frame render-reported viewport size in CSS.
private float mLastFrameViewportWidthCss;
private float mLastFrameViewportHeightCss;
// Cached page scale factor from native.
private float mPageScaleFactor = 1.0f;
private float mMinPageScaleFactor = 1.0f;
private float mMaxPageScaleFactor = 1.0f;
// Cached device density.
private float mDeviceScaleFactor;
private float mContentOffsetYPix;
// Internally-visible set of update methods (used by ContentViewCore).
void reset() {
mScrollXCss = mScrollYCss = 0;
mPageScaleFactor = 1.0f;
}
void updateContentSizeCss(float contentWidthCss, float contentHeightCss) {
mContentWidthCss = contentWidthCss;
mContentHeightCss = contentHeightCss;
}
void setDeviceScaleFactor(float deviceScaleFactor) {
mDeviceScaleFactor = deviceScaleFactor;
}
void updateFrameInfo(
float scrollXCss, float scrollYCss,
float contentWidthCss, float contentHeightCss,
float viewportWidthCss, float viewportHeightCss,
float pageScaleFactor, float minPageScaleFactor, float maxPageScaleFactor,
float contentOffsetYPix) {
mScrollXCss = scrollXCss;
mScrollYCss = scrollYCss;
mPageScaleFactor = pageScaleFactor;
mMinPageScaleFactor = minPageScaleFactor;
mMaxPageScaleFactor = maxPageScaleFactor;
mContentOffsetYPix = contentOffsetYPix;
updateContentSizeCss(contentWidthCss, contentHeightCss);
mLastFrameViewportWidthCss = viewportWidthCss;
mLastFrameViewportHeightCss = viewportHeightCss;
}
/**
* Handles conversion of a point from window-relative-local-dip or screen-pix
* to document-absolute-CSS space and vice versa.
*/
public class NormalizedPoint {
private float mXAbsoluteCss, mYAbsoluteCss;
private NormalizedPoint() {
}
/**
* @return Absolute CSS (document) X coordinate of the point.
*/
public float getXAbsoluteCss() { return mXAbsoluteCss; }
/**
* @return Absolute CSS (document) Y coordinate of the point.
*/
public float getYAbsoluteCss() { return mYAbsoluteCss; }
/**
* @return Local device-scale-unadjusted X coordinate of the point.
*/
public float getXLocalDip() { return (mXAbsoluteCss - mScrollXCss) * mPageScaleFactor; }
/**
* @return Local device-scale-unadjusted Y coordinate of the point.
*/
public float getYLocalDip() { return (mYAbsoluteCss - mScrollYCss) * mPageScaleFactor; }
/**
* @return Physical (screen) X coordinate of the point.
*/
public float getXPix() { return getXLocalDip() * mDeviceScaleFactor; }
/**
* @return Physical (screen) Y coordinate of the point.
*/
public float getYPix() { return getYLocalDip() * mDeviceScaleFactor + mContentOffsetYPix; }
/**
* Sets the point to the given absolute CSS (document) coordinates.
*/
public void setAbsoluteCss(float xCss, float yCss) {
mXAbsoluteCss = xCss;
mYAbsoluteCss = yCss;
}
/**
* Sets the point to the given local device-scale-unadjusted coordinates.
*/
public void setLocalDip(float xDip, float yDip) {
setAbsoluteCss(
xDip / mPageScaleFactor + mScrollXCss,
yDip / mPageScaleFactor + mScrollYCss);
}
/**
* Sets the point to the given physical (screen) coordinates.
*/
public void setScreen(float xPix, float yPix) {
setLocalDip(xPix / mDeviceScaleFactor, yPix / mDeviceScaleFactor);
}
}
/**
* @return A helper to convert a point between between absolute CSS and local DIP spaces.
*/
public NormalizedPoint createNormalizedPoint() {
return new NormalizedPoint();
}
/**
* @return Horizontal scroll offset in CSS pixels.
*/
public float getScrollX() { return mScrollXCss; }
/**
* @return Vertical scroll offset in CSS pixels.
*/
public float getScrollY() { return mScrollYCss; }
/**
* @return Horizontal scroll offset in physical pixels.
*/
public float getScrollXPix() { return fromLocalCssToPix(mScrollXCss); }
/**
* @return Vertical scroll offset in physical pixels.
*/
public float getScrollYPix() { return fromLocalCssToPix(mScrollYCss); }
/**
* @return Horizontal scroll offset in physical pixels (approx, integer).
*/
public int getScrollXPixInt() { return (int) Math.floor(getScrollXPix()); }
/**
* @return Vertical scroll offset in physical pixels (approx, integer).
*/
public int getScrollYPixInt() { return (int) Math.floor(getScrollYPix()); }
/**
* @return Width of the content in CSS pixels.
*/
public float getContentWidthCss() { return mContentWidthCss; }
/**
* @return Height of the content in CSS pixels.
*/
public float getContentHeightCss() { return mContentHeightCss; }
/**
* @return Approximate width of the content in physical pixels.
*/
public float getContentWidthPix() { return fromLocalCssToPix(mContentWidthCss); }
/**
* @return Approximate height of the content in physical pixels.
*/
public float getContentHeightPix() { return fromLocalCssToPix(mContentHeightCss); }
/**
* @return Approximate width of the content in physical pixels (integer).
*/
public int getContentWidthPixInt() { return (int) Math.ceil(getContentWidthPix()); }
/**
* @return Approximate height of the content in physical pixels (integer).
*/
public int getContentHeightPixInt() { return (int) Math.ceil(getContentHeightPix()); }
/**
* @return Render-reported width of the viewport in CSS pixels.
*/
public float getLastFrameViewportWidthCss() { return mLastFrameViewportWidthCss; }
/**
* @return Render-reported height of the viewport in CSS pixels.
*/
public float getLastFrameViewportHeightCss() { return mLastFrameViewportHeightCss; }
/**
* @return Render-reported width of the viewport in physical pixels (approximate).
*/
public float getLastFrameViewportWidthPix() {
return fromLocalCssToPix(mLastFrameViewportWidthCss);
}
/**
* @return Render-reported height of the viewport in physical pixels (approximate).
*/
public float getLastFrameViewportHeightPix() {
return fromLocalCssToPix(mLastFrameViewportHeightCss);
}
/**
* @return Render-reported width of the viewport in physical pixels (approx, integer).
*/
public int getLastFrameViewportWidthPixInt() {
return (int) Math.ceil(getLastFrameViewportWidthPix());
}
/**
* @return Render-reported height of the viewport in physical pixels (approx, integer).
*/
public int getLastFrameViewportHeightPixInt() {
return (int) Math.ceil(getLastFrameViewportHeightPix());
}
/**
* @return The Physical on-screen Y offset amount below the top controls.
*/
public float getContentOffsetYPix() {
return mContentOffsetYPix;
}
/**
* @return Current page scale factor (maps CSS pixels to DIP pixels).
*/
public float getPageScaleFactor() { return mPageScaleFactor; }
/**
* @return Minimum page scale factor to be used with the content.
*/
public float getMinPageScaleFactor() { return mMinPageScaleFactor; }
/**
* @return Maximum page scale factor to be used with the content.
*/
public float getMaxPageScaleFactor() { return mMaxPageScaleFactor; }
/**
* @return Current device scale factor (maps DIP pixels to physical pixels).
*/
public float getDeviceScaleFactor() { return mDeviceScaleFactor; }
/**
* @return True if the page doesn't allow zoom-in/zoom-out.
*/
public boolean hasFixedPageScale() { return mMinPageScaleFactor == mMaxPageScaleFactor; }
/**
* @return True if the page has a width=device-width or narrower viewport.
*/
public boolean hasMobileViewport() {
float windowWidthDip = mPageScaleFactor * mLastFrameViewportWidthCss;
return mContentWidthCss <= windowWidthDip;
}
/**
* @return Maximum possible horizontal scroll in physical pixels.
*/
public float getMaxHorizontalScrollPix() {
return getContentWidthPix() - getLastFrameViewportWidthPix();
}
/**
* @return Maximum possible vertical scroll in physical pixels.
*/
public float getMaxVerticalScrollPix() {
return getContentHeightPix() - getLastFrameViewportHeightPix();
}
/**
* @return Maximum possible horizontal scroll in physical pixels (approx, integer).
*/
public int getMaxHorizontalScrollPixInt() {
return (int) Math.floor(getMaxHorizontalScrollPix());
}
/**
* @return Maximum possible vertical scroll in physical pixels (approx, integer).
*/
public int getMaxVerticalScrollPixInt() {
return (int) Math.floor(getMaxVerticalScrollPix());
}
/**
* @return Physical on-screen coordinate converted to local DIP.
*/
public float fromPixToDip(float pix) {
return pix / mDeviceScaleFactor;
}
/**
* @return Local DIP converted to physical coordinates.
*/
public float fromDipToPix(float dip) {
return dip * mDeviceScaleFactor;
}
/**
* @return Physical coordinate converted to local CSS.
*/
public float fromPixToLocalCss(float pix) {
return pix / (mDeviceScaleFactor * mPageScaleFactor);
}
/**
* @return Local CSS converted to physical coordinates.
*/
public float fromLocalCssToPix(float css) {
return css * mPageScaleFactor * mDeviceScaleFactor;
}
}