Bug 590294, part 6: Add a window.setResolution(xres, yres) API to control the number of backing pixels allocated to scalable content. r=roc sr=dbaron

This commit is contained in:
Chris Jones 2010-09-03 15:10:46 -05:00
parent 26466ba198
commit 3d571692f4
4 changed files with 84 additions and 1 deletions

View File

@ -278,6 +278,18 @@ nsDOMWindowUtils::SetDisplayPort(float aXPx, float aYPx,
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::SetResolution(float aXResolution, float aYResolution)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsIPresShell* presShell = GetPresShell();
return presShell ? presShell->SetResolution(aXResolution, aYResolution)
: NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsDOMWindowUtils::SendMouseEvent(const nsAString& aType,
float aX,

View File

@ -53,7 +53,7 @@ interface nsIDOMEvent;
interface nsITransferable;
interface nsIQueryContentEventResult;
[scriptable, uuid(b6628355-e72f-4d1d-9b83-ffc2740536b5)]
[scriptable, uuid(d0d23c20-16ca-4c0f-b2d2-74ae4c7b858b)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -139,6 +139,32 @@ interface nsIDOMWindowUtils : nsISupports {
void setDisplayPort(in float aXPx, in float aYPx,
in float aWidthPx, in float aHeightPx);
/**
* Get/set the resolution at which rescalable web content is drawn.
* Currently this is only (some) thebes content.
*
* Setting a new resolution does *not* trigger reflow. This API is
* entirely separate from textZoom and fullZoom; a resolution scale
* can be applied together with both textZoom and fullZoom.
*
* The effect of is API for gfx code to allocate more or fewer
* pixels for rescalable content by a factor of |resolution| in
* either or both dimensions. setResolution() together with
* setDisplayport() can be used to implement a non-reflowing
* scale-zoom in concert with another entity that can draw with a
* scale. For example, to scale a content |window| inside a
* <browser> by a factor of 2.0
*
* window.setDisplayport(x, y, oldW / 2.0, oldH / 2.0);
* window.setResolution(2.0, 2.0);
* // elsewhere
* browser.setViewportScale(2.0, 2.0);
*
* The caller of this method must have UniversalXPConnect
* privileges.
*/
void setResolution(in float aXResolution, in float aYResolution);
/** Synthesize a mouse event. The event types supported are:
* mousedown, mouseup, mousemove, mouseover, mouseout, contextmenu
*

View File

@ -1089,6 +1089,19 @@ public:
return mDisplayPort;
}
/**
* Set a "resolution" for the document, which if not 1.0 will
* allocate more or fewer pixels for rescalable content by a factor
* of |resolution| in both dimensions. Return NS_OK iff the
* resolution bounds are sane, and the resolution of this was
* actually updated.
*
* The resolution defaults to 1.0.
*/
virtual nsresult SetResolution(float aXResolution, float aYResolution) = 0;
float GetXResolution() { return mXResolution; }
float GetYResolution() { return mYResolution; }
/**
* Refresh observer management.
*/
@ -1201,6 +1214,11 @@ protected:
// maintain.
nsRect mDisplayPort;
// Used to force allocation and rendering of proportionally more or
// less pixels in the given dimension.
float mXResolution;
float mYResolution;
// Live pres shells, for memory and other tracking
typedef nsPtrHashKey<nsIPresShell> PresShellPtrKey;
static nsTHashtable<PresShellPtrKey> *sLiveShells;

View File

@ -831,6 +831,8 @@ public:
virtual void SetDisplayPort(const nsRect& aDisplayPort);
virtual nsresult SetResolution(float aXResolution, float aYResolution);
//nsIViewObserver interface
NS_IMETHOD Paint(nsIView* aDisplayRoot,
@ -1023,9 +1025,13 @@ protected:
RenderingState(PresShell* aPresShell)
: mRenderFlags(aPresShell->mRenderFlags)
, mDisplayPort(aPresShell->mDisplayPort)
, mXResolution(aPresShell->mXResolution)
, mYResolution(aPresShell->mYResolution)
{ }
PRUint32 mRenderFlags;
nsRect mDisplayPort;
float mXResolution;
float mYResolution;
};
struct AutoSaveRestoreRenderingState {
@ -1038,6 +1044,8 @@ protected:
{
mPresShell->mRenderFlags = mOldState.mRenderFlags;
mPresShell->mDisplayPort = mOldState.mDisplayPort;
mPresShell->mXResolution = mOldState.mXResolution;
mPresShell->mYResolution = mOldState.mYResolution;
}
PresShell* mPresShell;
@ -1651,6 +1659,8 @@ PresShell::PresShell()
mPresArenaAllocCount = 0;
#endif
mRenderFlags = 0;
mXResolution = 1.0;
mYResolution = 1.0;
static bool registeredReporter = false;
if (!registeredReporter) {
@ -5944,6 +5954,21 @@ void PresShell::SetDisplayPort(const nsRect& aDisplayPort)
SetRenderingState(state);
}
nsresult PresShell::SetResolution(float aXResolution, float aYResolution)
{
if (!(aXResolution > 0.0 && aXResolution > 0.0)) {
return NS_ERROR_ILLEGAL_VALUE;
}
if (aXResolution == mXResolution && aYResolution == mYResolution) {
return NS_OK;
}
RenderingState state(this);
state.mXResolution = aXResolution;
state.mYResolution = aYResolution;
SetRenderingState(state);
return NS_OK;
}
void PresShell::SetRenderingState(const RenderingState& aState)
{
if (mRenderFlags != aState.mRenderFlags) {
@ -5961,6 +5986,8 @@ void PresShell::SetRenderingState(const RenderingState& aState)
} else {
mDisplayPort = nsRect();
}
mXResolution = aState.mXResolution;
mYResolution = aState.mYResolution;
nsIFrame* rootFrame = FrameManager()->GetRootFrame();
if (rootFrame) {