Bug 590294, part 9: Add API to set a <browser> expectation of the content window's viewport, and to draw content pixels in the <browser> at particular scale factors. sr=smaug

This commit is contained in:
Chris Jones 2010-09-03 15:10:46 -05:00
Родитель a2c93af9b1
Коммит 74eea248f2
3 изменённых файлов: 149 добавлений и 1 удалений

Просмотреть файл

@ -46,7 +46,7 @@ interface nsIFrame;
interface nsIChromeFrameMessageManager; interface nsIChromeFrameMessageManager;
interface nsIVariant; interface nsIVariant;
[scriptable, uuid(65d2c9e2-852c-48cf-a95d-9b82f1273c15)] [scriptable, uuid(afb86369-d183-4bc4-9fce-26cd314a4ac0)]
interface nsIFrameLoader : nsISupports interface nsIFrameLoader : nsISupports
{ {
/** /**
@ -127,6 +127,36 @@ interface nsIFrameLoader : nsISupports
attribute boolean delayRemoteDialogs; attribute boolean delayRemoteDialogs;
/**
* Implement viewport scrolling/scaling, used to support
* asynchronous re-paints of content pixels. These interfaces are
* only meaningful for <browser>.
*
* These interfaces do *not* scroll or scale the content document;
* instead they set a "goal" scroll/scale wrt the current content
* viewport. When the content document is painted, the viewport*
* attributes are used to set a compensating transform. If the
* metrics of the content document's current pixels don't match the
* viewport* config, the transform matrix may need to translate
* content pixels and/or perform a "fuzzy-scale" that doesn't
* re-rasterize fonts or intelligently resample images.
*
* The viewport* attrs are allowed to transform content pixels in
* such a way that the <browser>'s visible rect encloses pixels that
* the content document does not (yet) define.
*
* The viewport scroll values are in units of content-document CSS
* pixels.
*
* These APIs are designed to be used with nsIDOMWindowUtils
* setDisplayPort() and setResolution().
*/
void scrollViewportTo(in float xPx, in float yPx);
void scrollViewportBy(in float dxPx, in float dyPx);
void setViewportScale(in float xScale, in float yScale);
readonly attribute float viewportScrollX;
readonly attribute float viewportScrollY;
}; };
native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>); native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);

Просмотреть файл

@ -1529,6 +1529,77 @@ nsFrameLoader::UpdateBaseWindowPositionAndSize(nsIFrame *aIFrame)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsFrameLoader::ScrollViewportTo(float aXpx, float aYpx)
{
ViewportConfig config(mViewportConfig);
config.mScrollOffset = nsPoint(nsPresContext::CSSPixelsToAppUnits(aXpx),
nsPresContext::CSSPixelsToAppUnits(aYpx));
return UpdateViewportConfig(config);
}
NS_IMETHODIMP
nsFrameLoader::ScrollViewportBy(float aDXpx, float aDYpx)
{
ViewportConfig config(mViewportConfig);
config.mScrollOffset.MoveBy(nsPresContext::CSSPixelsToAppUnits(aDXpx),
nsPresContext::CSSPixelsToAppUnits(aDYpx));
return UpdateViewportConfig(config);
}
NS_IMETHODIMP
nsFrameLoader::SetViewportScale(float aXScale, float aYScale)
{
ViewportConfig config(mViewportConfig);
config.mXScale = aXScale;
config.mYScale = aYScale;
return UpdateViewportConfig(config);
}
NS_IMETHODIMP
nsFrameLoader::GetViewportScrollX(float* aViewportScrollX)
{
*aViewportScrollX =
nsPresContext::AppUnitsToFloatCSSPixels(mViewportConfig.mScrollOffset.x);
return NS_OK;
}
NS_IMETHODIMP
nsFrameLoader::GetViewportScrollY(float* aViewportScrollY)
{
*aViewportScrollY =
nsPresContext::AppUnitsToFloatCSSPixels(mViewportConfig.mScrollOffset.y);
return NS_OK;
}
nsresult
nsFrameLoader::UpdateViewportConfig(const ViewportConfig& aNewConfig)
{
if (aNewConfig == mViewportConfig) {
return NS_OK;
}
mViewportConfig = aNewConfig;
// Viewport changed. Try to locate our subdoc frame and invalidate
// it if found.
nsIFrame* frame = GetPrimaryFrameOfOwningContent();
if (!frame) {
// XXX should this be a silent failure?
return NS_ERROR_NOT_AVAILABLE;
}
// XXX could be clever here and compute a smaller invalidation
// rect
nsRect rect = nsRect(nsPoint(0, 0), frame->GetRect().Size());
// NB: we pass INVALIDATE_NO_THEBES_LAYERS here to keep viewport
// semantics the same for both in-process and out-of-process
// <browser>. This is just a transform of the layer subtree in
// both.
frame->InvalidateWithFlags(rect, nsIFrame::INVALIDATE_NO_THEBES_LAYERS);
return NS_OK;
}
nsIntSize nsIntSize
nsFrameLoader::GetSubDocumentSize(const nsIFrame *aIFrame) nsFrameLoader::GetSubDocumentSize(const nsIFrame *aIFrame)
{ {

Просмотреть файл

@ -47,6 +47,7 @@
#include "nsIDocShell.h" #include "nsIDocShell.h"
#include "nsStringFwd.h" #include "nsStringFwd.h"
#include "nsIFrameLoader.h" #include "nsIFrameLoader.h"
#include "nsPoint.h"
#include "nsSize.h" #include "nsSize.h"
#include "nsIURI.h" #include "nsIURI.h"
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
@ -109,6 +110,47 @@ protected:
{} {}
public: public:
/**
* Defines a target configuration for this <browser>'s content
* document's viewport. If the content document's actual viewport
* doesn't match a desired ViewportConfig, then on paints its pixels
* are transformed to compensate for the difference.
*
* Used to support asynchronous re-paints of content pixels; see
* nsIFrameLoader.scrollViewport* and viewportScale.
*/
struct ViewportConfig {
ViewportConfig()
: mScrollOffset(0, 0)
, mXScale(1.0)
, mYScale(1.0)
{}
// Default copy ctor and operator= are fine
PRBool operator==(const ViewportConfig& aOther) const
{
return (mScrollOffset == aOther.mScrollOffset &&
mXScale == aOther.mXScale &&
mYScale == aOther.mYScale);
}
// This is the scroll offset the <browser> user wishes or expects
// its enclosed content document to have. "Scroll offset" here
// means the document pixel at pixel (0,0) within the CSS
// viewport. If the content document's actual scroll offset
// doesn't match |mScrollOffset|, the difference is used to define
// a translation transform when painting the content document.
nsPoint mScrollOffset;
// The scale at which the <browser> user wishes to paint its
// enclosed content document. If content-document layers have a
// lower or higher resolution than the desired scale, then the
// ratio is used to define a scale transform when painting the
// content document.
float mXScale;
float mYScale;
};
~nsFrameLoader() { ~nsFrameLoader() {
mNeedsAsyncDestroy = PR_TRUE; mNeedsAsyncDestroy = PR_TRUE;
if (mMessageManager) { if (mMessageManager) {
@ -206,6 +248,8 @@ public:
#endif #endif
nsFrameMessageManager* GetFrameMessageManager() { return mMessageManager; } nsFrameMessageManager* GetFrameMessageManager() { return mMessageManager; }
const ViewportConfig& GetViewportConfig() { return mViewportConfig; }
private: private:
#ifdef MOZ_IPC #ifdef MOZ_IPC
@ -238,6 +282,8 @@ private:
bool ShowRemoteFrame(const nsIntSize& size); bool ShowRemoteFrame(const nsIntSize& size);
#endif #endif
nsresult UpdateViewportConfig(const ViewportConfig& aNewConfig);
nsCOMPtr<nsIDocShell> mDocShell; nsCOMPtr<nsIDocShell> mDocShell;
nsCOMPtr<nsIURI> mURIToLoad; nsCOMPtr<nsIURI> mURIToLoad;
nsIContent *mOwnerContent; // WEAK nsIContent *mOwnerContent; // WEAK
@ -268,6 +314,7 @@ private:
TabParent* mRemoteBrowser; TabParent* mRemoteBrowser;
#endif #endif
ViewportConfig mViewportConfig;
}; };
#endif #endif