Bug 748384 - Back out 330e9c52f9ac, 9ba1078559fe, 2ed39c12d792, f53f05ecacd5 for build bustage. r=bustage

This commit is contained in:
Kartikaya Gupta 2012-05-23 11:08:19 -04:00
parent 25e74247ed
commit 15d02d35fd
30 changed files with 318 additions and 378 deletions

View File

@ -49,7 +49,6 @@
#include "nsIDocShell.h"
#include "nsIContentViewer.h"
#include "nsIMarkupDocumentViewer.h"
#include "nsClientRect.h"
#if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK2)
#include <gdk/gdk.h>
@ -1261,39 +1260,6 @@ nsDOMWindowUtils::GetScrollXY(bool aFlushLayout, PRInt32* aScrollX, PRInt32* aSc
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::GetRootBounds(nsIDOMClientRect** aResult)
{
// Weak ref, since we addref it below
nsClientRect* rect = new nsClientRect();
NS_ADDREF(*aResult = rect);
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
NS_ENSURE_STATE(doc);
nsRect bounds(0, 0, 0, 0);
nsIPresShell* presShell = doc->GetShell();
if (presShell) {
nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
if (sf) {
bounds = sf->GetScrollRange();
bounds.width += sf->GetScrollPortRect().width;
bounds.height += sf->GetScrollPortRect().height;
} else if (presShell->GetRootFrame()) {
bounds = presShell->GetRootFrame()->GetRect();
}
}
rect->SetRect(nsPresContext::AppUnitsToFloatCSSPixels(bounds.x),
nsPresContext::AppUnitsToFloatCSSPixels(bounds.y),
nsPresContext::AppUnitsToFloatCSSPixels(bounds.width),
nsPresContext::AppUnitsToFloatCSSPixels(bounds.height));
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::GetIMEIsOpen(bool *aState)
{

View File

@ -37,9 +37,8 @@ interface nsIDOMBlob;
interface nsIDOMFile;
interface nsIFile;
interface nsIDOMTouch;
interface nsIDOMClientRect;
[scriptable, uuid(2b3ac53c-2a88-421f-af09-f10665c88acf)]
[scriptable, uuid(2e5a1f37-786b-4a52-b0e3-f711ee2268a8)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -595,13 +594,6 @@ interface nsIDOMWindowUtils : nsISupports {
*/
void getScrollXY(in boolean aFlushLayout, out long aScrollX, out long aScrollY);
/**
* Returns the bounds of the window's currently loaded document. This will
* generally be (0, 0, pageWidth, pageHeight) but in some cases (e.g. RTL
* documents) may have a negative left value.
*/
nsIDOMClientRect getRootBounds();
/**
* Get IME open state. TRUE means 'Open', otherwise, 'Close'.
* This property works only when IMEEnabled is IME_STATUS_ENABLED.

View File

@ -77,10 +77,10 @@ public:
FrameMetrics()
: mViewport(0, 0, 0, 0)
, mContentRect(0, 0, 0, 0)
, mContentSize(0, 0)
, mViewportScrollOffset(0, 0)
, mScrollId(NULL_SCROLL_ID)
, mCSSContentRect(0, 0, 0, 0)
, mCSSContentSize(0, 0)
, mResolution(1, 1)
{}
@ -115,14 +115,14 @@ public:
// These are all in layer coordinate space.
nsIntRect mViewport;
nsIntRect mContentRect;
nsIntSize mContentSize;
nsIntPoint mViewportScrollOffset;
nsIntRect mDisplayPort;
ViewID mScrollId;
// Consumers often want to know the origin/size before scaling to pixels
// so we record this as well.
gfx::Rect mCSSContentRect;
// Consumers often want to know the size before scaling to pixels
// so we record this size as well.
gfx::Size mCSSContentSize;
// This represents the resolution at which the associated layer
// will been rendered.

View File

@ -28,9 +28,6 @@ namespace layers {
// avoid the overhead of virtual dispatch, we employ the curiously recurring
// template pattern.
//
// Tiles are aligned to a grid with one of the grid points at (0,0) and other
// grid points spaced evenly in the x- and y-directions by GetTileLength().
//
// This tile buffer stores a valid region, which defines the areas that have
// up-to-date content. The contents of tiles within this region will be reused
// from paint to paint. It also stores the region that was modified in the last

View File

@ -355,15 +355,21 @@ CompositorParent::TransformShadowTree()
float rootScaleY = rootTransform.GetYScale();
if (mIsFirstPaint && metrics) {
mContentRect = metrics->mContentRect;
SetFirstPaintViewport(metrics->mViewportScrollOffset,
nsIntPoint scrollOffset = metrics->mViewportScrollOffset;
mContentSize = metrics->mContentSize;
SetFirstPaintViewport(scrollOffset.x, scrollOffset.y,
1/rootScaleX,
mContentRect,
metrics->mCSSContentRect);
mContentSize.width,
mContentSize.height,
metrics->mCSSContentSize.width,
metrics->mCSSContentSize.height);
mIsFirstPaint = false;
} else if (metrics && !metrics->mContentRect.IsEqualEdges(mContentRect)) {
mContentRect = metrics->mContentRect;
SetPageRect(1/rootScaleX, mContentRect, metrics->mCSSContentRect);
} else if (metrics && (metrics->mContentSize != mContentSize)) {
mContentSize = metrics->mContentSize;
SetPageSize(1/rootScaleX, mContentSize.width,
mContentSize.height,
metrics->mCSSContentSize.width,
metrics->mCSSContentSize.height);
}
// We synchronise the viewport information with Java after sending the above
@ -415,19 +421,24 @@ CompositorParent::TransformShadowTree()
}
void
CompositorParent::SetFirstPaintViewport(const nsIntPoint& aOffset, float aZoom,
const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect)
CompositorParent::SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom,
float aPageWidth, float aPageHeight,
float aCssPageWidth, float aCssPageHeight)
{
#ifdef MOZ_WIDGET_ANDROID
mozilla::AndroidBridge::Bridge()->SetFirstPaintViewport(aOffset, aZoom, aPageRect, aCssPageRect);
mozilla::AndroidBridge::Bridge()->SetFirstPaintViewport(aOffsetX, aOffsetY,
aZoom, aPageWidth, aPageHeight,
aCssPageWidth, aCssPageHeight);
#endif
}
void
CompositorParent::SetPageRect(float aZoom, const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect)
CompositorParent::SetPageSize(float aZoom, float aPageWidth, float aPageHeight,
float aCssPageWidth, float aCssPageHeight)
{
#ifdef MOZ_WIDGET_ANDROID
mozilla::AndroidBridge::Bridge()->SetPageRect(aZoom, aPageRect, aCssPageRect);
mozilla::AndroidBridge::Bridge()->SetPageSize(aZoom, aPageWidth, aPageHeight,
aCssPageWidth, aCssPageHeight);
#endif
}

View File

@ -83,8 +83,9 @@ protected:
virtual void ScheduleTask(CancelableTask*, int);
virtual void Composite();
virtual void ScheduleComposition();
virtual void SetFirstPaintViewport(const nsIntPoint& aOffset, float aZoom, const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect);
virtual void SetPageRect(float aZoom, const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect);
virtual void SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom, float aPageWidth, float aPageHeight,
float aCssPageWidth, float aCssPageHeight);
virtual void SetPageSize(float aZoom, float aPageWidth, float aPageHeight, float aCssPageWidth, float aCssPageHeight);
virtual void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY);
void SetEGLSurfaceSize(int width, int height);
@ -124,7 +125,7 @@ private:
float mXScale;
float mYScale;
nsIntPoint mScrollOffset;
nsIntRect mContentRect;
nsIntSize mContentSize;
nsIntSize mWidgetSize;
// When this flag is set, the next composition will be the first for a

View File

@ -34,9 +34,9 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mCSSContentRect);
WriteParam(aMsg, aParam.mCSSContentSize);
WriteParam(aMsg, aParam.mViewport);
WriteParam(aMsg, aParam.mContentRect);
WriteParam(aMsg, aParam.mContentSize);
WriteParam(aMsg, aParam.mViewportScrollOffset);
WriteParam(aMsg, aParam.mDisplayPort);
WriteParam(aMsg, aParam.mScrollId);
@ -45,9 +45,9 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
{
return (ReadParam(aMsg, aIter, &aResult->mCSSContentRect) &&
return (ReadParam(aMsg, aIter, &aResult->mCSSContentSize) &&
ReadParam(aMsg, aIter, &aResult->mViewport) &&
ReadParam(aMsg, aIter, &aResult->mContentRect) &&
ReadParam(aMsg, aIter, &aResult->mContentSize) &&
ReadParam(aMsg, aIter, &aResult->mViewportScrollOffset) &&
ReadParam(aMsg, aIter, &aResult->mDisplayPort) &&
ReadParam(aMsg, aIter, &aResult->mScrollId) &&

View File

@ -219,9 +219,9 @@ ReusableTileStoreOGL::DrawTiles(TiledThebesLayerOGL* aLayer,
displayPort = parent->GetEffectiveTransform().
TransformBounds(gfxRect(parentMetrics.mDisplayPort));
const FrameMetrics& metrics = scrollableLayer->GetFrameMetrics();
const nsIntSize& contentSize = metrics.mContentRect.Size();
const nsIntPoint& contentOrigin = metrics.mContentRect.TopLeft() - metrics.mViewportScrollOffset;
gfxRect contentRect = gfxRect(contentOrigin.x, contentOrigin.y,
const nsIntSize& contentSize = metrics.mContentSize;
const nsIntPoint& contentOrigin = metrics.mViewportScrollOffset;
gfxRect contentRect = gfxRect(-contentOrigin.x, -contentOrigin.y,
contentSize.width, contentSize.height);
contentBounds = scrollableLayer->GetEffectiveTransform().TransformBounds(contentRect);
break;

View File

@ -760,27 +760,6 @@ struct ParamTraits<mozilla::gfx::Size>
}
};
template<>
struct ParamTraits<mozilla::gfx::Rect>
{
typedef mozilla::gfx::Rect paramType;
static void Write(Message* msg, const paramType& param)
{
WriteParam(msg, param.x);
WriteParam(msg, param.y);
WriteParam(msg, param.width);
WriteParam(msg, param.height);
}
static bool Read(const Message* msg, void** iter, paramType* result)
{
return (ReadParam(msg, iter, &result->x) &&
ReadParam(msg, iter, &result->y) &&
ReadParam(msg, iter, &result->width) &&
ReadParam(msg, iter, &result->height));
}
};
template<>
struct ParamTraits<nsRect>

View File

@ -199,25 +199,21 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
scrollableFrame = aScrollFrame->GetScrollTargetFrame();
if (scrollableFrame) {
nsRect contentBounds = scrollableFrame->GetScrollRange();
contentBounds.width += scrollableFrame->GetScrollPortRect().width;
contentBounds.height += scrollableFrame->GetScrollPortRect().height;
metrics.mCSSContentRect = gfx::Rect(nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.x),
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.y),
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.width),
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.height));
metrics.mContentRect = contentBounds.ScaleToNearestPixels(
nsSize contentSize =
scrollableFrame->GetScrollRange().Size() +
scrollableFrame->GetScrollPortRect().Size();
metrics.mCSSContentSize = gfx::Size(nsPresContext::AppUnitsToFloatCSSPixels(contentSize.width),
nsPresContext::AppUnitsToFloatCSSPixels(contentSize.height));
metrics.mContentSize = contentSize.ScaleToNearestPixels(
aContainerParameters.mXScale, aContainerParameters.mYScale, auPerDevPixel);
metrics.mViewportScrollOffset = scrollableFrame->GetScrollPosition().ScaleToNearestPixels(
aContainerParameters.mXScale, aContainerParameters.mYScale, auPerDevPixel);
}
else {
nsRect contentBounds = aForFrame->GetRect();
metrics.mCSSContentRect = gfx::Rect(nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.x),
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.y),
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.width),
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.height));
metrics.mContentRect = contentBounds.ScaleToNearestPixels(
nsSize contentSize = aForFrame->GetSize();
metrics.mCSSContentSize = gfx::Size(nsPresContext::AppUnitsToFloatCSSPixels(contentSize.width),
nsPresContext::AppUnitsToFloatCSSPixels(contentSize.height));
metrics.mContentSize = contentSize.ScaleToNearestPixels(
aContainerParameters.mXScale, aContainerParameters.mYScale, auPerDevPixel);
}

View File

@ -384,8 +384,8 @@ BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
NSIntPixelsToAppUnits(metrics.mViewport.width, auPerDevPixel) * aXScale,
NSIntPixelsToAppUnits(metrics.mViewport.height, auPerDevPixel) * aYScale);
view->mContentSize = nsSize(
nsPresContext::CSSPixelsToAppUnits(metrics.mCSSContentRect.width) * aXScale,
nsPresContext::CSSPixelsToAppUnits(metrics.mCSSContentRect.height) * aYScale);
nsPresContext::CSSPixelsToAppUnits(metrics.mCSSContentSize.width) * aXScale,
nsPresContext::CSSPixelsToAppUnits(metrics.mCSSContentSize.height) * aYScale);
newContentViews[scrollId] = view;
}

View File

@ -2170,7 +2170,17 @@ public class GeckoAppShell
}
Tab tab = Tabs.getInstance().getSelectedTab();
GeckoAppShell.screenshotWholePage(tab);
ImmutableViewportMetrics viewport = GeckoApp.mAppContext.getLayerController().getViewportMetrics();
/*
if (FloatUtils.fuzzyEquals(sCheckerboardPageWidth, viewport.pageSizeWidth) &&
FloatUtils.fuzzyEquals(sCheckerboardPageHeight, viewport.pageSizeHeight)) {
float width = right - left;
float height = bottom - top;
GeckoAppShell.sendEventToGecko(GeckoEvent.createScreenshotEvent(tab.getId(), (int)top, (int)left, (int)width, (int)height, 0, 0, (int)(sLastCheckerboardWidthRatio * width), (int)(sLastCheckerboardHeightRatio * height), GeckoAppShell.SCREENSHOT_UPDATE));
} else {
*/
GeckoAppShell.screenshotWholePage(tab);
//}
}
void addRectToRepaint(float top, float left, float bottom, float right) {
@ -2218,8 +2228,8 @@ public class GeckoAppShell
ImmutableViewportMetrics viewport = GeckoApp.mAppContext.getLayerController().getViewportMetrics();
Log.i(LOGTAG, "Taking whole-screen screenshot, viewport: " + viewport);
// source width and height to screenshot
float sw = viewport.getPageWidth() / viewport.zoomFactor;
float sh = viewport.getPageHeight() / viewport.zoomFactor;
float sw = viewport.pageSizeWidth / viewport.zoomFactor;
float sh = viewport.pageSizeHeight / viewport.zoomFactor;
int maxPixels = Math.min(ScreenshotLayer.getMaxNumPixels(), sMaxTextureSize * sMaxTextureSize);
// 2Mb of 16bit image data
// may be bumped by up to 4x for power of 2 alignment
@ -2237,9 +2247,6 @@ public class GeckoAppShell
sCheckerboardPageWidth = sw;
sCheckerboardPageHeight = sh;
GeckoAppShell.sendEventToGecko(GeckoEvent.createScreenshotEvent(tab.getId(),
(int)FloatMath.ceil(viewport.pageRectLeft), (int)FloatMath.ceil(viewport.pageRectTop),
(int)FloatMath.floor(viewport.getPageWidth()), (int)FloatMath.floor(viewport.getPageHeight()),
0, 0, dw, dh, GeckoAppShell.SCREENSHOT_WHOLE_PAGE));
GeckoAppShell.sendEventToGecko(GeckoEvent.createScreenshotEvent(tab.getId(), 0, 0, (int)sw, (int)sh, 0, 0, dw, dh, GeckoAppShell.SCREENSHOT_WHOLE_PAGE));
}
}

View File

@ -129,15 +129,15 @@ final class DisplayPortCalculator {
*/
private static FloatSize reshapeForPage(float width, float height, ImmutableViewportMetrics metrics) {
// figure out how much of the desired buffer amount we can actually use on the horizontal axis
float usableWidth = Math.min(width, metrics.getPageWidth());
float usableWidth = Math.min(width, metrics.pageSizeWidth);
// if we reduced the buffer amount on the horizontal axis, we should take that saved memory and
// use it on the vertical axis
float extraUsableHeight = (float)Math.floor(((width - usableWidth) * height) / usableWidth);
float usableHeight = Math.min(height + extraUsableHeight, metrics.getPageHeight());
float usableHeight = Math.min(height + extraUsableHeight, metrics.pageSizeHeight);
if (usableHeight < height && usableWidth == width) {
// and the reverse - if we shrunk the buffer on the vertical axis we can add it to the horizontal
float extraUsableWidth = (float)Math.floor(((height - usableHeight) * width) / usableHeight);
usableWidth = Math.min(width + extraUsableWidth, metrics.getPageWidth());
usableWidth = Math.min(width + extraUsableWidth, metrics.pageSizeWidth);
}
return new FloatSize(usableWidth, usableHeight);
}
@ -153,7 +153,11 @@ final class DisplayPortCalculator {
float dangerZoneY = metrics.getHeight() * dangerZoneYMultiplier;
rect = RectUtils.expand(rect, dangerZoneX, dangerZoneY);
// clamp to page bounds
return clampToPageBounds(rect, metrics);
if (rect.top < 0) rect.top = 0;
if (rect.left < 0) rect.left = 0;
if (rect.right > metrics.pageSizeWidth) rect.right = metrics.pageSizeWidth;
if (rect.bottom > metrics.pageSizeHeight) rect.bottom = metrics.pageSizeHeight;
return rect;
}
/**
@ -167,10 +171,10 @@ final class DisplayPortCalculator {
float top = metrics.viewportRectTop - margins.top;
float right = metrics.viewportRectRight + margins.right;
float bottom = metrics.viewportRectBottom + margins.bottom;
left = Math.max(metrics.pageRectLeft, TILE_SIZE * FloatMath.floor(left / TILE_SIZE));
top = Math.max(metrics.pageRectTop, TILE_SIZE * FloatMath.floor(top / TILE_SIZE));
right = Math.min(metrics.pageRectRight, TILE_SIZE * FloatMath.ceil(right / TILE_SIZE));
bottom = Math.min(metrics.pageRectBottom, TILE_SIZE * FloatMath.ceil(bottom / TILE_SIZE));
left = Math.max(0.0f, TILE_SIZE * FloatMath.floor(left / TILE_SIZE));
top = Math.max(0.0f, TILE_SIZE * FloatMath.floor(top / TILE_SIZE));
right = Math.min(metrics.pageSizeWidth, TILE_SIZE * FloatMath.ceil(right / TILE_SIZE));
bottom = Math.min(metrics.pageSizeHeight, TILE_SIZE * FloatMath.ceil(bottom / TILE_SIZE));
return new DisplayPortMetrics(left, top, right, bottom, zoom);
}
@ -178,16 +182,16 @@ final class DisplayPortCalculator {
* Adjust the given margins so if they are applied on the viewport in the metrics, the resulting rect
* does not exceed the page bounds. This code will maintain the total margin amount for a given axis;
* it assumes that margins.left + metrics.getWidth() + margins.right is less than or equal to
* metrics.getPageWidth(); and the same for the y axis.
* metrics.pageSizeWidth; and the same for the y axis.
*/
private static RectF shiftMarginsForPageBounds(RectF margins, ImmutableViewportMetrics metrics) {
// check how much we're overflowing in each direction. note that at most one of leftOverflow
// and rightOverflow can be greater than zero, and at most one of topOverflow and bottomOverflow
// can be greater than zero, because of the assumption described in the method javadoc.
float leftOverflow = metrics.pageRectLeft - (metrics.viewportRectLeft - margins.left);
float rightOverflow = (metrics.viewportRectRight + margins.right) - metrics.pageRectRight;
float topOverflow = metrics.pageRectTop - (metrics.viewportRectTop - margins.top);
float bottomOverflow = (metrics.viewportRectBottom + margins.bottom) - metrics.pageRectBottom;
float leftOverflow = margins.left - metrics.viewportRectLeft;
float rightOverflow = margins.right - (metrics.pageSizeWidth - metrics.viewportRectRight);
float topOverflow = margins.top - metrics.viewportRectTop;
float bottomOverflow = margins.bottom - (metrics.pageSizeHeight - metrics.viewportRectBottom);
// if the margins overflow the page bounds, shift them to other side on the same axis
if (leftOverflow > 0) {
@ -211,10 +215,10 @@ final class DisplayPortCalculator {
* Clamp the given rect to the page bounds and return it.
*/
private static RectF clampToPageBounds(RectF rect, ImmutableViewportMetrics metrics) {
if (rect.top < metrics.pageRectTop) rect.top = metrics.pageRectTop;
if (rect.left < metrics.pageRectLeft) rect.left = metrics.pageRectLeft;
if (rect.right > metrics.pageRectRight) rect.right = metrics.pageRectRight;
if (rect.bottom > metrics.pageRectBottom) rect.bottom = metrics.pageRectBottom;
rect.left = Math.max(rect.left, 0);
rect.top = Math.max(rect.top, 0);
rect.right = Math.min(rect.right, metrics.pageSizeWidth);
rect.bottom = Math.min(rect.bottom, metrics.pageSizeHeight);
return rect;
}
@ -391,8 +395,8 @@ final class DisplayPortCalculator {
// we need to avoid having a display port that is larger than the page, or we will end up
// painting things outside the page bounds (bug 729169).
displayPortWidth = Math.min(displayPortWidth, metrics.getPageWidth());
displayPortHeight = Math.min(displayPortHeight, metrics.getPageHeight());
displayPortWidth = Math.min(displayPortWidth, metrics.pageSizeWidth);
displayPortHeight = Math.min(displayPortHeight, metrics.pageSizeHeight);
float horizontalBuffer = displayPortWidth - metrics.getWidth();
float verticalBuffer = displayPortHeight - metrics.getHeight();
@ -410,8 +414,8 @@ final class DisplayPortCalculator {
float dangerZoneY = metrics.getHeight() * (DANGER_ZONE_BASE_Y_MULTIPLIER + (velocity.y * DANGER_ZONE_INCR_Y_MULTIPLIER));
// clamp it such that when added to the viewport, they don't exceed page size.
// this is a prerequisite to calling shiftMarginsForPageBounds as we do below.
dangerZoneX = Math.min(dangerZoneX, metrics.getPageWidth() - metrics.getWidth());
dangerZoneY = Math.min(dangerZoneY, metrics.getPageHeight() - metrics.getHeight());
dangerZoneX = Math.min(dangerZoneX, metrics.pageSizeWidth - metrics.getWidth());
dangerZoneY = Math.min(dangerZoneY, metrics.pageSizeHeight - metrics.getHeight());
// split the danger zone into margins based on velocity, and ensure it doesn't exceed
// page bounds.

View File

@ -204,7 +204,7 @@ public class GeckoLayerClient implements GeckoEventResponder,
// and our zoom level (which may have diverged).
float scaleFactor = oldMetrics.zoomFactor / messageMetrics.getZoomFactor();
newMetrics = new ViewportMetrics(oldMetrics);
newMetrics.setPageRect(RectUtils.scale(messageMetrics.getPageRect(), scaleFactor), messageMetrics.getCssPageRect());
newMetrics.setPageSize(messageMetrics.getPageSize().scale(scaleFactor), messageMetrics.getCssPageSize());
break;
}
@ -298,18 +298,15 @@ public class GeckoLayerClient implements GeckoEventResponder,
* The compositor invokes this function just before compositing a frame where the document
* is different from the document composited on the last frame. In these cases, the viewport
* information we have in Java is no longer valid and needs to be replaced with the new
* viewport information provided. setPageRect will never be invoked on the same frame that
* viewport information provided. setPageSize will never be invoked on the same frame that
* this function is invoked on; and this function will always be called prior to syncViewportInfo.
*/
public void setFirstPaintViewport(float offsetX, float offsetY, float zoom,
float pageLeft, float pageTop, float pageRight, float pageBottom,
float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom) {
public void setFirstPaintViewport(float offsetX, float offsetY, float zoom, float pageWidth, float pageHeight, float cssPageWidth, float cssPageHeight) {
synchronized (mLayerController) {
final ViewportMetrics currentMetrics = new ViewportMetrics(mLayerController.getViewportMetrics());
currentMetrics.setOrigin(new PointF(offsetX, offsetY));
currentMetrics.setZoomFactor(zoom);
currentMetrics.setPageRect(new RectF(pageLeft, pageTop, pageRight, pageBottom),
new RectF(cssPageLeft, cssPageTop, cssPageRight, cssPageBottom));
currentMetrics.setPageSize(new FloatSize(pageWidth, pageHeight), new FloatSize(cssPageWidth, cssPageHeight));
// Since we have switched to displaying a different document, we need to update any
// viewport-related state we have lying around. This includes mGeckoViewport and the
// viewport in mLayerController. Usually this information is updated via handleViewportMessage
@ -343,21 +340,20 @@ public class GeckoLayerClient implements GeckoEventResponder,
}
/** This function is invoked by Gecko via JNI; be careful when modifying signature.
* The compositor invokes this function whenever it determines that the page rect
* The compositor invokes this function whenever it determines that the page size
* has changed (based on the information it gets from layout). If setFirstPaintViewport
* is invoked on a frame, then this function will not be. For any given frame, this
* function will be invoked before syncViewportInfo.
*/
public void setPageRect(float zoom, float pageLeft, float pageTop, float pageRight, float pageBottom,
float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom) {
public void setPageSize(float zoom, float pageWidth, float pageHeight, float cssPageWidth, float cssPageHeight) {
synchronized (mLayerController) {
// adjust the page dimensions to account for differences in zoom
// between the rendered content (which is what the compositor tells us)
// and our zoom level (which may have diverged).
RectF pageRect = new RectF(pageLeft, pageTop, pageRight, pageBottom);
RectF cssPageRect = new RectF(cssPageLeft, cssPageTop, cssPageRight, cssPageBottom);
float ourZoom = mLayerController.getZoomFactor();
mLayerController.setPageRect(RectUtils.scale(pageRect, ourZoom / zoom), cssPageRect);
pageWidth = pageWidth * ourZoom / zoom;
pageHeight = pageHeight * ourZoom /zoom;
mLayerController.setPageSize(new FloatSize(pageWidth, pageHeight), new FloatSize(cssPageWidth, cssPageHeight));
// Here the page size of the document has changed, but the document being displayed
// is still the same. Therefore, we don't need to send anything to browser.js; any
// changes we need to make to the display port will get sent the next time we call

View File

@ -17,38 +17,30 @@ public class ImmutableViewportMetrics {
// We need to flatten the RectF and FloatSize structures
// because Java doesn't have the concept of const classes
public final float pageRectLeft;
public final float pageRectTop;
public final float pageRectRight;
public final float pageRectBottom;
public final float cssPageRectLeft;
public final float cssPageRectTop;
public final float cssPageRectRight;
public final float cssPageRectBottom;
public final float viewportRectLeft;
public final float viewportRectTop;
public final float viewportRectRight;
public final float pageSizeWidth;
public final float pageSizeHeight;
public final float cssPageSizeWidth;
public final float cssPageSizeHeight;
public final float viewportRectBottom;
public final float viewportRectLeft;
public final float viewportRectRight;
public final float viewportRectTop;
public final float zoomFactor;
public ImmutableViewportMetrics(ViewportMetrics m) {
RectF viewportRect = m.getViewport();
viewportRectLeft = viewportRect.left;
viewportRectTop = viewportRect.top;
viewportRectRight = viewportRect.right;
viewportRectBottom = viewportRect.bottom;
viewportRectLeft = viewportRect.left;
viewportRectRight = viewportRect.right;
viewportRectTop = viewportRect.top;
RectF pageRect = m.getPageRect();
pageRectLeft = pageRect.left;
pageRectTop = pageRect.top;
pageRectRight = pageRect.right;
pageRectBottom = pageRect.bottom;
FloatSize pageSize = m.getPageSize();
pageSizeWidth = pageSize.width;
pageSizeHeight = pageSize.height;
RectF cssPageRect = m.getCssPageRect();
cssPageRectLeft = cssPageRect.left;
cssPageRectTop = cssPageRect.top;
cssPageRectRight = cssPageRect.right;
cssPageRectBottom = cssPageRect.bottom;
FloatSize cssPageSize = m.getCssPageSize();
cssPageSizeWidth = cssPageSize.width;
cssPageSizeHeight = cssPageSize.height;
zoomFactor = m.getZoomFactor();
}
@ -82,28 +74,18 @@ public class ImmutableViewportMetrics {
return RectUtils.scale(getViewport(), 1/zoomFactor);
}
public RectF getPageRect() {
return new RectF(pageRectLeft, pageRectTop, pageRectRight, pageRectBottom);
public FloatSize getPageSize() {
return new FloatSize(pageSizeWidth, pageSizeHeight);
}
public float getPageWidth() {
return pageRectRight - pageRectLeft;
}
public float getPageHeight() {
return pageRectBottom - pageRectTop;
}
public RectF getCssPageRect() {
return new RectF(cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom);
public FloatSize getCssPageSize() {
return new FloatSize(cssPageSizeWidth, cssPageSizeHeight);
}
@Override
public String toString() {
return "ImmutableViewportMetrics v=(" + viewportRectLeft + "," + viewportRectTop + ","
+ viewportRectRight + "," + viewportRectBottom + ") p=(" + pageRectLeft + ","
+ pageRectTop + "," + pageRectRight + "," + pageRectBottom + ") c=("
+ cssPageRectLeft + "," + cssPageRectTop + "," + cssPageRectRight + ","
+ cssPageRectBottom + ") z=" + zoomFactor;
+ viewportRectRight + "," + viewportRectBottom + ") p=(" + pageSizeWidth + ","
+ pageSizeHeight + ") z=" + zoomFactor;
}
}

View File

@ -155,17 +155,17 @@ public abstract class Layer {
public static class RenderContext {
public final RectF viewport;
public final RectF pageRect;
public final FloatSize pageSize;
public final IntSize screenSize;
public final float zoomFactor;
public final int positionHandle;
public final int textureHandle;
public final FloatBuffer coordBuffer;
public RenderContext(RectF aViewport, RectF aPageRect, IntSize aScreenSize, float aZoomFactor,
public RenderContext(RectF aViewport, FloatSize aPageSize, IntSize aScreenSize, float aZoomFactor,
int aPositionHandle, int aTextureHandle, FloatBuffer aCoordBuffer) {
viewport = aViewport;
pageRect = aPageRect;
pageSize = aPageSize;
screenSize = aScreenSize;
zoomFactor = aZoomFactor;
positionHandle = aPositionHandle;
@ -178,7 +178,7 @@ public abstract class Layer {
return false;
}
return RectUtils.fuzzyEquals(viewport, other.viewport)
&& RectUtils.fuzzyEquals(pageRect, other.pageRect)
&& pageSize.fuzzyEquals(other.pageSize)
&& FloatUtils.fuzzyEquals(zoomFactor, other.zoomFactor);
}
}

View File

@ -103,12 +103,12 @@ public class LayerController {
return mViewportMetrics.getSize();
}
public RectF getPageRect() {
return mViewportMetrics.getPageRect();
public FloatSize getPageSize() {
return mViewportMetrics.getPageSize();
}
public RectF getCssPageRect() {
return mViewportMetrics.getCssPageRect();
public FloatSize getCssPageSize() {
return mViewportMetrics.getCssPageSize();
}
public PointF getOrigin() {
@ -167,16 +167,13 @@ public class LayerController {
mView.requestRender();
}
/** Sets the current page rect. You must hold the monitor while calling this. */
public void setPageRect(RectF rect, RectF cssRect) {
// Since the "rect" is always just a multiple of "cssRect" we don't need to
// check both; this function assumes that both "rect" and "cssRect" are relative
// the zoom factor in mViewportMetrics.
if (mViewportMetrics.getCssPageRect().equals(cssRect))
/** Sets the current page size. You must hold the monitor while calling this. */
public void setPageSize(FloatSize size, FloatSize cssSize) {
if (mViewportMetrics.getCssPageSize().equals(cssSize))
return;
ViewportMetrics viewportMetrics = new ViewportMetrics(mViewportMetrics);
viewportMetrics.setPageRect(rect, cssRect);
viewportMetrics.setPageSize(size, cssSize);
mViewportMetrics = new ImmutableViewportMetrics(viewportMetrics);
// Page size is owned by the layer client, so no need to notify it of
@ -184,7 +181,7 @@ public class LayerController {
mView.post(new Runnable() {
public void run() {
mPanZoomController.pageRectUpdated();
mPanZoomController.pageSizeUpdated();
mView.requestRender();
}
});

View File

@ -311,19 +311,19 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
private RenderContext createScreenContext(ImmutableViewportMetrics metrics) {
RectF viewport = new RectF(0.0f, 0.0f, metrics.getWidth(), metrics.getHeight());
RectF pageRect = new RectF(metrics.getPageRect());
return createContext(viewport, pageRect, 1.0f);
FloatSize pageSize = new FloatSize(metrics.getPageSize());
return createContext(viewport, pageSize, 1.0f);
}
private RenderContext createPageContext(ImmutableViewportMetrics metrics) {
Rect viewport = RectUtils.round(metrics.getViewport());
RectF pageRect = metrics.getPageRect();
FloatSize pageSize = metrics.getPageSize();
float zoomFactor = metrics.zoomFactor;
return createContext(new RectF(viewport), pageRect, zoomFactor);
return createContext(new RectF(viewport), pageSize, zoomFactor);
}
private RenderContext createContext(RectF viewport, RectF pageRect, float zoomFactor) {
return new RenderContext(viewport, pageRect, new IntSize(mSurfaceWidth, mSurfaceHeight), zoomFactor, mPositionHandle, mTextureHandle,
private RenderContext createContext(RectF viewport, FloatSize pageSize, float zoomFactor) {
return new RenderContext(viewport, pageSize, new IntSize(mSurfaceWidth, mSurfaceHeight), zoomFactor, mPositionHandle, mTextureHandle,
mCoordBuffer);
}
@ -490,9 +490,12 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
private Rect getPageRect() {
Point origin = PointUtils.round(mFrameMetrics.getOrigin());
Rect pageRect = RectUtils.round(mFrameMetrics.getPageRect());
pageRect.offset(-origin.x, -origin.y);
return pageRect;
IntSize pageSize = new IntSize(mFrameMetrics.getPageSize());
origin.negate();
return new Rect(origin.x, origin.y,
origin.x + pageSize.width, origin.y + pageSize.height);
}
/** This function is invoked via JNI; be careful when modifying signature. */

View File

@ -52,33 +52,33 @@ public class NinePatchTileLayer extends TileLayer {
* +---+---+---+
*/
// page is the rect of the "missing" center spot in the picture above
RectF page = context.pageRect;
FloatSize size = context.pageSize;
float width = size.width, height = size.height;
drawPatch(context, 0, PATCH_SIZE * 3, /* 0 */
page.left - PATCH_SIZE, page.top - PATCH_SIZE, PATCH_SIZE, PATCH_SIZE);
drawPatch(context, PATCH_SIZE, PATCH_SIZE * 3, /* 1 */
page.left, page.top - PATCH_SIZE, page.width(), PATCH_SIZE);
drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE * 3, /* 2 */
page.right, page.top - PATCH_SIZE, PATCH_SIZE, PATCH_SIZE);
0.0f, 0.0f, PATCH_SIZE, PATCH_SIZE);
drawPatch(context, PATCH_SIZE, PATCH_SIZE*3, /* 1 */
PATCH_SIZE, 0.0f, width, PATCH_SIZE);
drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE*3, /* 2 */
PATCH_SIZE + width, 0.0f, PATCH_SIZE, PATCH_SIZE);
drawPatch(context, 0, PATCH_SIZE * 2, /* 3 */
page.left - PATCH_SIZE, page.top, PATCH_SIZE, page.height());
0.0f, PATCH_SIZE, PATCH_SIZE, height);
drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE * 2, /* 4 */
page.right, page.top, PATCH_SIZE, page.height());
PATCH_SIZE + width, PATCH_SIZE, PATCH_SIZE, height);
drawPatch(context, 0, PATCH_SIZE, /* 5 */
page.left - PATCH_SIZE, page.bottom, PATCH_SIZE, PATCH_SIZE);
0.0f, PATCH_SIZE + height, PATCH_SIZE, PATCH_SIZE);
drawPatch(context, PATCH_SIZE, PATCH_SIZE, /* 6 */
page.left, page.bottom, page.width(), PATCH_SIZE);
PATCH_SIZE, PATCH_SIZE + height, width, PATCH_SIZE);
drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE, /* 7 */
page.right, page.bottom, PATCH_SIZE, PATCH_SIZE);
PATCH_SIZE + width, PATCH_SIZE + height, PATCH_SIZE, PATCH_SIZE);
}
private void drawPatch(RenderContext context, int textureX, int textureY,
float tileX, float tileY, float tileWidth, float tileHeight) {
RectF viewport = context.viewport;
float viewportHeight = viewport.height();
float drawX = tileX - viewport.left;
float drawY = viewportHeight - (tileY + tileHeight - viewport.top);
float drawX = tileX - viewport.left - PATCH_SIZE;
float drawY = viewportHeight - (tileY + tileHeight - viewport.top - PATCH_SIZE);
float[] coords = {
//x, y, z, texture_x, texture_y

View File

@ -421,9 +421,9 @@ public class ScrollbarLayer extends TileLayer {
private RectF getVerticalRect(RenderContext context) {
RectF viewport = context.viewport;
RectF pageRect = context.pageRect;
float barStart = ((viewport.top - pageRect.top) * (viewport.height() / pageRect.height())) + CAP_RADIUS;
float barEnd = ((viewport.bottom - pageRect.top) * (viewport.height() / pageRect.height())) - CAP_RADIUS;
FloatSize pageSize = context.pageSize;
float barStart = (viewport.height() * viewport.top / pageSize.height) + CAP_RADIUS;
float barEnd = (viewport.height() * viewport.bottom / pageSize.height) - CAP_RADIUS;
if (barStart > barEnd) {
float middle = (barStart + barEnd) / 2.0f;
barStart = barEnd = middle;
@ -434,9 +434,9 @@ public class ScrollbarLayer extends TileLayer {
private RectF getHorizontalRect(RenderContext context) {
RectF viewport = context.viewport;
RectF pageRect = context.pageRect;
float barStart = ((viewport.left - pageRect.left) * (viewport.width() / pageRect.width())) + CAP_RADIUS;
float barEnd = ((viewport.right - pageRect.left) * (viewport.width() / pageRect.width())) - CAP_RADIUS;
FloatSize pageSize = context.pageSize;
float barStart = (viewport.width() * viewport.left / pageSize.width) + CAP_RADIUS;
float barEnd = (viewport.width() * viewport.right / pageSize.width) - CAP_RADIUS;
if (barStart > barEnd) {
float middle = (barStart + barEnd) / 2.0f;
barStart = barEnd = middle;

View File

@ -67,7 +67,7 @@ public class SingleTileLayer extends TileLayer {
} else if (stretches()) {
// If we're stretching, we just want the bounds and texture bounds
// to fit to the page.
bounds = new RectF(context.pageRect);
bounds = new RectF(0.0f, 0.0f, context.pageSize.width, context.pageSize.height);
textureBounds = bounds;
} else {
bounds = getBounds(context);

View File

@ -13,6 +13,7 @@ import android.util.DisplayMetrics;
import org.mozilla.gecko.FloatUtils;
import org.mozilla.gecko.GeckoApp;
import org.mozilla.gecko.gfx.FloatSize;
import org.mozilla.gecko.gfx.IntSize;
import org.mozilla.gecko.gfx.LayerController;
import org.mozilla.gecko.gfx.RectUtils;
import org.json.JSONException;
@ -26,8 +27,8 @@ import android.util.Log;
public class ViewportMetrics {
private static final String LOGTAG = "GeckoViewportMetrics";
private RectF mPageRect;
private RectF mCssPageRect;
private FloatSize mPageSize;
private FloatSize mCssPageSize;
private RectF mViewportRect;
private float mZoomFactor;
@ -35,32 +36,26 @@ public class ViewportMetrics {
DisplayMetrics metrics = new DisplayMetrics();
GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
mPageRect = new RectF(0, 0, metrics.widthPixels, metrics.heightPixels);
mCssPageRect = new RectF(0, 0, metrics.widthPixels, metrics.heightPixels);
mPageSize = new FloatSize(metrics.widthPixels, metrics.heightPixels);
mCssPageSize = new FloatSize(metrics.widthPixels, metrics.heightPixels);
mViewportRect = new RectF(0, 0, metrics.widthPixels, metrics.heightPixels);
mZoomFactor = 1.0f;
}
public ViewportMetrics(ViewportMetrics viewport) {
mPageRect = new RectF(viewport.getPageRect());
mCssPageRect = new RectF(viewport.getCssPageRect());
mPageSize = new FloatSize(viewport.getPageSize());
mCssPageSize = new FloatSize(viewport.getCssPageSize());
mViewportRect = new RectF(viewport.getViewport());
mZoomFactor = viewport.getZoomFactor();
}
public ViewportMetrics(ImmutableViewportMetrics viewport) {
mPageRect = new RectF(viewport.pageRectLeft,
viewport.pageRectTop,
viewport.pageRectRight,
viewport.pageRectBottom);
mCssPageRect = new RectF(viewport.cssPageRectLeft,
viewport.cssPageRectTop,
viewport.cssPageRectRight,
viewport.cssPageRectBottom);
mPageSize = new FloatSize(viewport.pageSizeWidth, viewport.pageSizeHeight);
mCssPageSize = new FloatSize(viewport.cssPageSizeWidth, viewport.cssPageSizeHeight);
mViewportRect = new RectF(viewport.viewportRectLeft,
viewport.viewportRectTop,
viewport.viewportRectRight,
viewport.viewportRectBottom);
viewport.viewportRectTop,
viewport.viewportRectRight,
viewport.viewportRectBottom);
mZoomFactor = viewport.zoomFactor;
}
@ -70,18 +65,14 @@ public class ViewportMetrics {
float y = (float)json.getDouble("y");
float width = (float)json.getDouble("width");
float height = (float)json.getDouble("height");
float pageLeft = (float)json.getDouble("pageLeft");
float pageTop = (float)json.getDouble("pageTop");
float pageRight = (float)json.getDouble("pageRight");
float pageBottom = (float)json.getDouble("pageBottom");
float cssPageLeft = (float)json.getDouble("cssPageLeft");
float cssPageTop = (float)json.getDouble("cssPageTop");
float cssPageRight = (float)json.getDouble("cssPageRight");
float cssPageBottom = (float)json.getDouble("cssPageBottom");
float pageWidth = (float)json.getDouble("pageWidth");
float pageHeight = (float)json.getDouble("pageHeight");
float cssPageWidth = (float)json.getDouble("cssPageWidth");
float cssPageHeight = (float)json.getDouble("cssPageHeight");
float zoom = (float)json.getDouble("zoom");
mPageRect = new RectF(pageLeft, pageTop, pageRight, pageBottom);
mCssPageRect = new RectF(cssPageLeft, cssPageTop, cssPageRight, cssPageBottom);
mPageSize = new FloatSize(pageWidth, pageHeight);
mCssPageSize = new FloatSize(cssPageWidth, cssPageHeight);
mViewportRect = new RectF(x, y, x + width, y + height);
mZoomFactor = zoom;
}
@ -106,35 +97,38 @@ public class ViewportMetrics {
public RectF getClampedViewport() {
RectF clampedViewport = new RectF(mViewportRect);
// The viewport bounds ought to never exceed the page bounds.
if (clampedViewport.right > mPageRect.right)
clampedViewport.offset(mPageRect.right - clampedViewport.right, 0);
if (clampedViewport.left < mPageRect.left)
clampedViewport.offset(mPageRect.left - clampedViewport.left, 0);
// While the viewport size ought to never exceed the page size, we
// do the clamping in this order to make sure that the origin is
// never negative.
if (clampedViewport.right > mPageSize.width)
clampedViewport.offset(mPageSize.width - clampedViewport.right, 0);
if (clampedViewport.left < 0)
clampedViewport.offset(-clampedViewport.left, 0);
if (clampedViewport.bottom > mPageRect.bottom)
clampedViewport.offset(0, mPageRect.bottom - clampedViewport.bottom);
if (clampedViewport.top < mPageRect.top)
clampedViewport.offset(0, mPageRect.top - clampedViewport.top);
if (clampedViewport.bottom > mPageSize.height)
clampedViewport.offset(0, mPageSize.height - clampedViewport.bottom);
if (clampedViewport.top < 0)
clampedViewport.offset(0, -clampedViewport.top);
return clampedViewport;
}
public RectF getPageRect() {
return mPageRect;
public FloatSize getPageSize() {
return mPageSize;
}
public RectF getCssPageRect() {
return mCssPageRect;
public FloatSize getCssPageSize() {
return mCssPageSize;
}
public float getZoomFactor() {
return mZoomFactor;
}
public void setPageRect(RectF pageRect, RectF cssPageRect) {
mPageRect = pageRect;
mCssPageRect = cssPageRect;
public void setPageSize(FloatSize pageSize, FloatSize cssPageSize) {
mPageSize = pageSize;
mCssPageSize = cssPageSize;
}
public void setViewport(RectF viewport) {
@ -161,9 +155,9 @@ public class ViewportMetrics {
* after scaling.
*/
public void scaleTo(float newZoomFactor, PointF focus) {
// mCssPageRect is invariant, since we're setting the scale factor
// here. The page rect is based on the CSS page rect.
mPageRect = RectUtils.scale(mCssPageRect, newZoomFactor);
// mCssPageSize is invariant, since we're setting the scale factor
// here. The page size is based on the CSS page size.
mPageSize = mCssPageSize.scale(newZoomFactor);
float scaleFactor = newZoomFactor / mZoomFactor;
PointF origin = getOrigin();
@ -184,16 +178,16 @@ public class ViewportMetrics {
*/
public ViewportMetrics interpolate(ViewportMetrics to, float t) {
ViewportMetrics result = new ViewportMetrics();
result.mPageRect = RectUtils.interpolate(mPageRect, to.mPageRect, t);
result.mCssPageRect = RectUtils.interpolate(mCssPageRect, to.mCssPageRect, t);
result.mPageSize = mPageSize.interpolate(to.mPageSize, t);
result.mCssPageSize = mCssPageSize.interpolate(to.mCssPageSize, t);
result.mZoomFactor = FloatUtils.interpolate(mZoomFactor, to.mZoomFactor, t);
result.mViewportRect = RectUtils.interpolate(mViewportRect, to.mViewportRect, t);
return result;
}
public boolean fuzzyEquals(ViewportMetrics other) {
return RectUtils.fuzzyEquals(mPageRect, other.mPageRect)
&& RectUtils.fuzzyEquals(mCssPageRect, other.mCssPageRect)
return mPageSize.fuzzyEquals(other.mPageSize)
&& mCssPageSize.fuzzyEquals(other.mCssPageSize)
&& RectUtils.fuzzyEquals(mViewportRect, other.mViewportRect)
&& FloatUtils.fuzzyEquals(mZoomFactor, other.mZoomFactor);
}
@ -204,19 +198,15 @@ public class ViewportMetrics {
int height = Math.round(mViewportRect.height());
int width = Math.round(mViewportRect.width());
StringBuffer sb = new StringBuffer(512);
StringBuffer sb = new StringBuffer(256);
sb.append("{ \"x\" : ").append(mViewportRect.left)
.append(", \"y\" : ").append(mViewportRect.top)
.append(", \"width\" : ").append(width)
.append(", \"height\" : ").append(height)
.append(", \"pageLeft\" : ").append(mPageRect.left)
.append(", \"pageTop\" : ").append(mPageRect.top)
.append(", \"pageRight\" : ").append(mPageRect.right)
.append(", \"pageBottom\" : ").append(mPageRect.bottom)
.append(", \"cssPageLeft\" : ").append(mCssPageRect.left)
.append(", \"cssPageTop\" : ").append(mCssPageRect.top)
.append(", \"cssPageRight\" : ").append(mCssPageRect.right)
.append(", \"cssPageBottom\" : ").append(mCssPageRect.bottom)
.append(", \"pageWidth\" : ").append(mPageSize.width)
.append(", \"pageHeight\" : ").append(mPageSize.height)
.append(", \"cssPageWidth\" : ").append(mCssPageSize.width)
.append(", \"cssPageHeight\" : ").append(mCssPageSize.height)
.append(", \"zoom\" : ").append(mZoomFactor)
.append(" }");
return sb.toString();
@ -224,10 +214,10 @@ public class ViewportMetrics {
@Override
public String toString() {
StringBuffer buff = new StringBuffer(256);
StringBuffer buff = new StringBuffer(128);
buff.append("v=").append(mViewportRect.toString())
.append(" p=").append(mPageRect.toString())
.append(" c=").append(mCssPageRect.toString())
.append(" p=").append(mPageSize.toString())
.append(" c=").append(mCssPageSize.toString())
.append(" z=").append(mZoomFactor);
return buff.toString();
}

View File

@ -114,7 +114,6 @@ abstract class Axis {
protected abstract float getOrigin();
protected abstract float getViewportLength();
protected abstract float getPageStart();
protected abstract float getPageLength();
Axis(SubdocumentScrollHelper subscroller) {
@ -125,10 +124,6 @@ abstract class Axis {
return getOrigin() + getViewportLength();
}
private float getPageEnd() {
return getPageStart() + getPageLength();
}
void startTouch(float pos) {
mVelocity = 0.0f;
mScrollingDisabled = false;
@ -170,8 +165,8 @@ abstract class Axis {
}
private Overscroll getOverscroll() {
boolean minus = (getOrigin() < getPageStart());
boolean plus = (getViewportEnd() > getPageEnd());
boolean minus = (getOrigin() < 0.0f);
boolean plus = (getViewportEnd() > getPageLength());
if (minus && plus) {
return Overscroll.BOTH;
} else if (minus) {
@ -187,9 +182,9 @@ abstract class Axis {
// overscrolled on this axis, returns 0.
private float getExcess() {
switch (getOverscroll()) {
case MINUS: return getPageStart() - getOrigin();
case PLUS: return getViewportEnd() - getPageEnd();
case BOTH: return (getViewportEnd() - getPageEnd()) + (getPageStart() - getOrigin());
case MINUS: return -getOrigin();
case PLUS: return getViewportEnd() - getPageLength();
case BOTH: return getViewportEnd() - getPageLength() - getOrigin();
default: return 0.0f;
}
}

View File

@ -165,16 +165,16 @@ public class PanZoomController
}
});
} else if (MESSAGE_ZOOM_PAGE.equals(event)) {
RectF cssPageRect = mController.getCssPageRect();
FloatSize pageSize = mController.getCssPageSize();
RectF viewableRect = mController.getCssViewport();
float y = viewableRect.top;
// attempt to keep zoom keep focused on the center of the viewport
float newHeight = viewableRect.height() * cssPageRect.width() / viewableRect.width();
float newHeight = viewableRect.height() * pageSize.width / viewableRect.width();
float dh = viewableRect.height() - newHeight; // increase in the height
final RectF r = new RectF(0.0f,
y + dh/2,
cssPageRect.width(),
pageSize.width,
y + dh/2 + newHeight);
mController.post(new Runnable() {
public void run() {
@ -294,7 +294,7 @@ public class PanZoomController
}
/** This must be called on the UI thread. */
public void pageRectUpdated() {
public void pageSizeUpdated() {
if (mState == PanZoomState.NOTHING) {
synchronized (mController) {
ViewportMetrics validated = getValidViewportMetrics();
@ -775,7 +775,7 @@ public class PanZoomController
/* First, we adjust the zoom factor so that we can make no overscrolled area visible. */
float zoomFactor = viewportMetrics.getZoomFactor();
RectF pageRect = viewportMetrics.getPageRect();
FloatSize pageSize = viewportMetrics.getPageSize();
RectF viewport = viewportMetrics.getViewport();
float focusX = viewport.width() / 2.0f;
@ -795,16 +795,16 @@ public class PanZoomController
}
// Ensure minZoomFactor keeps the page at least as big as the viewport.
if (pageRect.width() > 0) {
float scaleFactor = viewport.width() / pageRect.width();
if (pageSize.width > 0) {
float scaleFactor = viewport.width() / pageSize.width;
minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor);
if (viewport.width() > pageRect.width())
if (viewport.width() > pageSize.width)
focusX = 0.0f;
}
if (pageRect.height() > 0) {
float scaleFactor = viewport.height() / pageRect.height();
if (pageSize.height > 0) {
float scaleFactor = viewport.height() / pageSize.height;
minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor);
if (viewport.height() > pageRect.height())
if (viewport.height() > pageSize.height)
focusY = 0.0f;
}
@ -837,9 +837,7 @@ public class PanZoomController
@Override
protected float getViewportLength() { return mController.getViewportSize().width; }
@Override
protected float getPageStart() { return mController.getPageRect().left; }
@Override
protected float getPageLength() { return mController.getPageRect().width(); }
protected float getPageLength() { return mController.getPageSize().width; }
}
private class AxisY extends Axis {
@ -849,9 +847,7 @@ public class PanZoomController
@Override
protected float getViewportLength() { return mController.getViewportSize().height; }
@Override
protected float getPageStart() { return mController.getPageRect().top; }
@Override
protected float getPageLength() { return mController.getPageRect().height(); }
protected float getPageLength() { return mController.getPageSize().height; }
}
/*

View File

@ -119,6 +119,14 @@ var Strings = {};
});
});
var MetadataProvider = {
getDrawMetadata: function getDrawMetadata() {
let viewport = BrowserApp.selectedTab.getViewport();
viewport.zoom = BrowserApp.selectedTab._drawZoom;
return JSON.stringify(viewport);
},
};
var BrowserApp = {
_tabs: [],
_selectedTab: null,
@ -133,6 +141,8 @@ var BrowserApp = {
BrowserEventHandler.init();
ViewportHandler.init();
getBridge().setDrawMetadataProvider(MetadataProvider);
getBridge().browserApp = this;
Services.obs.addObserver(this, "Tab:Add", false);
@ -1871,15 +1881,11 @@ Tab.prototype = {
height: gScreenHeight,
cssWidth: gScreenWidth / this._zoom,
cssHeight: gScreenHeight / this._zoom,
pageLeft: 0,
pageTop: 0,
pageRight: gScreenWidth,
pageBottom: gScreenHeight,
pageWidth: gScreenWidth,
pageHeight: gScreenHeight,
// We make up matching css page dimensions
cssPageLeft: 0,
cssPageTop: 0,
cssPageRight: gScreenWidth / this._zoom,
cssPageBottom: gScreenHeight / this._zoom,
cssPageWidth: gScreenWidth / this._zoom,
cssPageHeight: gScreenHeight / this._zoom,
zoom: this._zoom,
};
@ -1893,31 +1899,30 @@ Tab.prototype = {
let doc = this.browser.contentDocument;
if (doc != null) {
let cwu = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
let cssPageRect = cwu.getRootBounds();
let [pageWidth, pageHeight] = this.getPageSize(doc, viewport.cssWidth, viewport.cssHeight);
let cssPageWidth = pageWidth;
let cssPageHeight = pageHeight;
/* Transform the page width and height based on the zoom factor. */
pageWidth *= viewport.zoom;
pageHeight *= viewport.zoom;
/*
* Avoid sending page sizes of less than screen size before we hit DOMContentLoaded, because
* this causes the page size to jump around wildly during page load. After the page is loaded,
* send updates regardless of page size; we'll zoom to fit the content as needed.
*
* In the check below, we floor the viewport size because there might be slight rounding errors
* introduced in the CSS page size due to the conversion to and from app units in Gecko. The
* error should be no more than one app unit so doing the floor is overkill, but safe in the
* sense that the extra page size updates that get sent as a result will be mostly harmless.
* Also, we need to compare the page size returned from getPageSize (in CSS pixels) to the floored
* screen size in CSS pixels because the page size returned from getPageSize may also be floored.
*/
let pageLargerThanScreen = (cssPageRect.width >= Math.floor(viewport.cssWidth))
&& (cssPageRect.height >= Math.floor(viewport.cssHeight));
let pageLargerThanScreen = (cssPageWidth >= Math.floor(viewport.cssWidth))
&& (cssPageHeight >= Math.floor(viewport.cssHeight));
if (doc.readyState === 'complete' || pageLargerThanScreen) {
viewport.cssPageLeft = cssPageRect.left;
viewport.cssPageTop = cssPageRect.top;
viewport.cssPageRight = cssPageRect.right;
viewport.cssPageBottom = cssPageRect.bottom;
/* Transform the page width and height based on the zoom factor. */
viewport.pageLeft = (viewport.cssPageLeft * viewport.zoom);
viewport.pageTop = (viewport.cssPageTop * viewport.zoom);
viewport.pageRight = (viewport.cssPageRight * viewport.zoom);
viewport.pageBottom = (viewport.cssPageBottom * viewport.zoom);
viewport.cssPageWidth = cssPageWidth;
viewport.cssPageHeight = cssPageHeight;
viewport.pageWidth = pageWidth;
viewport.pageHeight = pageHeight;
}
}
@ -2700,13 +2705,13 @@ var BrowserEventHandler = {
let viewport = BrowserApp.selectedTab.getViewport();
let vRect = new Rect(viewport.cssX, viewport.cssY, viewport.cssWidth, viewport.cssHeight);
let bRect = new Rect(Math.max(viewport.cssPageLeft, rect.x - margin),
let bRect = new Rect(Math.max(0,rect.x - margin),
rect.y,
rect.w + 2*margin,
rect.h);
// constrict the rect to the screen's right edge
bRect.width = Math.min(bRect.width, viewport.cssPageRight - bRect.x);
// constrict the rect to the screen width
bRect.width = Math.min(bRect.width, viewport.cssPageWidth - bRect.x);
let overlap = vRect.intersect(bRect);
let overlapArea = overlap.width*overlap.height;

View File

@ -1631,6 +1631,14 @@ AndroidBridge::HandleGeckoMessage(const nsAString &aMessage, nsAString &aRet)
ALOG_BRIDGE("leaving %s", __PRETTY_FUNCTION__);
}
static nsCOMPtr<nsIAndroidDrawMetadataProvider> gDrawMetadataProvider = NULL;
nsCOMPtr<nsIAndroidDrawMetadataProvider>
AndroidBridge::GetDrawMetadataProvider()
{
return gDrawMetadataProvider;
}
void
AndroidBridge::CheckURIVisited(const nsAString& aURI)
{
@ -2032,23 +2040,24 @@ AndroidBridge::IsTablet()
}
void
AndroidBridge::SetFirstPaintViewport(const nsIntPoint& aOffset, float aZoom, const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect)
AndroidBridge::SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom, float aPageWidth, float aPageHeight,
float aCssPageWidth, float aCssPageHeight)
{
AndroidGeckoLayerClient *client = mLayerClient;
if (!client)
return;
client->SetFirstPaintViewport(aOffset, aZoom, aPageRect, aCssPageRect);
client->SetFirstPaintViewport(aOffsetX, aOffsetY, aZoom, aPageWidth, aPageHeight, aCssPageWidth, aCssPageHeight);
}
void
AndroidBridge::SetPageRect(float aZoom, const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect)
AndroidBridge::SetPageSize(float aZoom, float aPageWidth, float aPageHeight, float aCssPageWidth, float aCssPageHeight)
{
AndroidGeckoLayerClient *client = mLayerClient;
if (!client)
return;
client->SetPageRect(aZoom, aPageRect, aCssPageRect);
client->SetPageSize(aZoom, aPageWidth, aPageHeight, aCssPageWidth, aCssPageHeight);
}
void
@ -2089,6 +2098,13 @@ NS_IMETHODIMP nsAndroidBridge::HandleGeckoMessage(const nsAString & message, nsA
return NS_OK;
}
/* void SetDrawMetadataProvider (in nsIAndroidDrawMetadataProvider message); */
NS_IMETHODIMP nsAndroidBridge::SetDrawMetadataProvider(nsIAndroidDrawMetadataProvider *aProvider)
{
gDrawMetadataProvider = aProvider;
return NS_OK;
}
void
AndroidBridge::NotifyDefaultPrevented(bool aDefaultPrevented)
{

View File

@ -304,6 +304,8 @@ public:
void HandleGeckoMessage(const nsAString& message, nsAString &aRet);
nsCOMPtr<nsIAndroidDrawMetadataProvider> GetDrawMetadataProvider();
void CheckURIVisited(const nsAString& uri);
void MarkURIVisited(const nsAString& uri);
@ -330,8 +332,9 @@ public:
void EnableNetworkNotifications();
void DisableNetworkNotifications();
void SetFirstPaintViewport(const nsIntPoint& aOffset, float aZoom, const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect);
void SetPageRect(float aZoom, const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect);
void SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom, float aPageWidth, float aPageHeight,
float aCssPageWidth, float aCssPageHeight);
void SetPageSize(float aZoom, float aPageWidth, float aPageHeight, float aCssPageWidth, float aCssPageHeight);
void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY);

View File

@ -64,7 +64,7 @@ jmethodID AndroidLocation::jGetTimeMethod = 0;
jclass AndroidGeckoLayerClient::jGeckoLayerClientClass = 0;
jmethodID AndroidGeckoLayerClient::jSetFirstPaintViewport = 0;
jmethodID AndroidGeckoLayerClient::jSetPageRect = 0;
jmethodID AndroidGeckoLayerClient::jSetPageSize = 0;
jmethodID AndroidGeckoLayerClient::jSyncViewportInfoMethod = 0;
jmethodID AndroidGeckoLayerClient::jCreateFrameMethod = 0;
jmethodID AndroidGeckoLayerClient::jActivateProgramMethod = 0;
@ -248,8 +248,8 @@ AndroidGeckoLayerClient::InitGeckoLayerClientClass(JNIEnv *jEnv)
jGeckoLayerClientClass = getClassGlobalRef("org/mozilla/gecko/gfx/GeckoLayerClient");
jSetFirstPaintViewport = getMethod("setFirstPaintViewport", "(FFFFFFFFFFF)V");
jSetPageRect = getMethod("setPageRect", "(FFFFFFFFF)V");
jSetFirstPaintViewport = getMethod("setFirstPaintViewport", "(FFFFFFF)V");
jSetPageSize = getMethod("setPageSize", "(FFFFF)V");
jSyncViewportInfoMethod = getMethod("syncViewportInfo",
"(IIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform;");
jCreateFrameMethod = getMethod("createFrame", "()Lorg/mozilla/gecko/gfx/LayerRenderer$Frame;");
@ -651,7 +651,8 @@ AndroidGeckoSurfaceView::Draw2D(jobject buffer, int stride)
}
void
AndroidGeckoLayerClient::SetFirstPaintViewport(const nsIntPoint& aOffset, float aZoom, const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect)
AndroidGeckoLayerClient::SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom, float aPageWidth, float aPageHeight,
float aCssPageWidth, float aCssPageHeight)
{
NS_ASSERTION(!isNull(), "SetFirstPaintViewport called on null layer client!");
JNIEnv *env = GetJNIForThread(); // this is called on the compositor thread
@ -659,23 +660,20 @@ AndroidGeckoLayerClient::SetFirstPaintViewport(const nsIntPoint& aOffset, float
return;
AutoLocalJNIFrame jniFrame(env, 0);
return env->CallVoidMethod(wrapped_obj, jSetFirstPaintViewport, (float)aOffset.x, (float)aOffset.y, aZoom,
(float)aPageRect.x, (float)aPageRect.y, (float)aPageRect.XMost(), (float)aPageRect.YMost(),
aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost());
return env->CallVoidMethod(wrapped_obj, jSetFirstPaintViewport, aOffsetX, aOffsetY, aZoom, aPageWidth, aPageHeight,
aCssPageWidth, aCssPageHeight);
}
void
AndroidGeckoLayerClient::SetPageRect(float aZoom, const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect)
AndroidGeckoLayerClient::SetPageSize(float aZoom, float aPageWidth, float aPageHeight, float aCssPageWidth, float aCssPageHeight)
{
NS_ASSERTION(!isNull(), "SetPageRect called on null layer client!");
NS_ASSERTION(!isNull(), "SetPageSize called on null layer client!");
JNIEnv *env = GetJNIForThread(); // this is called on the compositor thread
if (!env)
return;
AutoLocalJNIFrame jniFrame(env, 0);
return env->CallVoidMethod(wrapped_obj, jSetPageRect, aZoom,
(float)aPageRect.x, (float)aPageRect.y, (float)aPageRect.XMost(), (float)aPageRect.YMost(),
aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost());
return env->CallVoidMethod(wrapped_obj, jSetPageSize, aZoom, aPageWidth, aPageHeight, aCssPageWidth, aCssPageHeight);
}
void

View File

@ -13,7 +13,6 @@
#include "nsPoint.h"
#include "nsRect.h"
#include "nsString.h"
#include "mozilla/gfx/Rect.h"
//#define FORCE_ALOG 1
@ -172,8 +171,9 @@ public:
AndroidGeckoLayerClient() {}
AndroidGeckoLayerClient(jobject jobj) { Init(jobj); }
void SetFirstPaintViewport(const nsIntPoint& aOffset, float aZoom, const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect);
void SetPageRect(float aZoom, const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect);
void SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom, float aPageWidth, float aPageHeight,
float aCssPageWidth, float aCssPageHeight);
void SetPageSize(float aZoom, float aPageWidth, float aPageHeight, float aCssPageWidth, float aCssPageHeight);
void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY);
bool CreateFrame(AutoLocalJNIFrame *jniFrame, AndroidLayerRendererFrame& aFrame);
@ -183,7 +183,7 @@ public:
protected:
static jclass jGeckoLayerClientClass;
static jmethodID jSetFirstPaintViewport;
static jmethodID jSetPageRect;
static jmethodID jSetPageSize;
static jmethodID jSyncViewportInfoMethod;
static jmethodID jCreateFrameMethod;
static jmethodID jActivateProgramMethod;

View File

@ -5,6 +5,11 @@
#include "nsISupports.idl"
#include "nsIDOMWindow.idl"
[scriptable, uuid(56fd8e18-a5cf-4e7a-92ba-4f68b4ad50ac)]
interface nsIAndroidDrawMetadataProvider : nsISupports {
AString getDrawMetadata();
};
[scriptable, uuid(0843f3c1-043e-4c64-9d8c-091370548c05)]
interface nsIBrowserTab : nsISupports {
readonly attribute nsIDOMWindow window;
@ -16,9 +21,10 @@ interface nsIAndroidBrowserApp : nsISupports {
nsIBrowserTab getBrowserTab(in PRInt32 tabId);
};
[scriptable, uuid(bbb8e0d7-5cca-4ad0-88be-538ce6d04f63)]
[scriptable, uuid(7dd8441a-4f38-49b2-bd90-da69d02a96cf)]
interface nsIAndroidBridge : nsISupports
{
AString handleGeckoMessage(in AString message);
void setDrawMetadataProvider(in nsIAndroidDrawMetadataProvider provider);
attribute nsIAndroidBrowserApp browserApp;
};