зеркало из https://github.com/mozilla/pjs.git
Bug 534425. Part 6: Let nsIWidgets expose a LayerManager to be used to render into the widget, instead of nsPaintEvent::renderingContext which is removed since it's no longer needed. Currently all widgets fall back to a default BasicLayerManager implementation. Also change nsPaintEvent::region to be an nsIntRegion, and get rid of nsPaintEvent::rect since it's redundant.
This commit is contained in:
Родитель
352babe537
Коммит
31649f159f
|
@ -3313,6 +3313,9 @@ nsCanvasRenderingContext2D::DrawWindow(nsIDOMWindow* aWindow, float aX, float aY
|
|||
if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_VIEW) {
|
||||
renderDocFlags &= ~nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
|
||||
}
|
||||
if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_USE_WIDGET_LAYERS) {
|
||||
renderDocFlags |= nsIPresShell::RENDER_USE_WIDGET_LAYERS;
|
||||
}
|
||||
|
||||
PRBool oldDisableValue = nsLayoutUtils::sDisableGetUsedXAssertions;
|
||||
nsLayoutUtils::sDisableGetUsedXAssertions = oldDisableValue || skipFlush;
|
||||
|
|
|
@ -180,9 +180,13 @@ interface nsIDOMCanvasRenderingContext2D : nsISupports
|
|||
// Don't flush pending layout notifications that could otherwise
|
||||
// be batched up
|
||||
const unsigned long DRAWWINDOW_DO_NOT_FLUSH = 0x02;
|
||||
|
||||
// Draw scrollbars and scroll the viewport if they are present
|
||||
const unsigned long DRAWWINDOW_DRAW_VIEW = 0x04;
|
||||
// Use the widget layer manager if available. This means hardware
|
||||
// acceleration may be used, but it might actually be slower or
|
||||
// lower quality than normal. It will however more accurately reflect
|
||||
// the pixels rendered to the screen.
|
||||
const unsigned long DRAWWINDOW_USE_WIDGET_LAYERS = 0x08;
|
||||
|
||||
/**
|
||||
* Renders a region of a window into the canvas. The contents of
|
||||
|
|
|
@ -52,9 +52,7 @@ GRE_MODULE = 1
|
|||
LIBXUL_LIBRARY = 1
|
||||
|
||||
|
||||
ifeq (,$(filter-out WINCE WINNT,$(OS_ARCH)))
|
||||
EXTRA_DSO_LIBS = gkgfx
|
||||
endif
|
||||
EXTRA_DSO_LIBS = gkgfx thebes
|
||||
|
||||
CPPSRCS = \
|
||||
nsWebBrowserModule.cpp \
|
||||
|
|
|
@ -74,6 +74,8 @@
|
|||
#include "nsIServiceManager.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "Layers.h"
|
||||
#include "gfxContext.h"
|
||||
|
||||
// for painting the background window
|
||||
#include "nsIRenderingContext.h"
|
||||
|
@ -90,6 +92,8 @@
|
|||
// PSM2 includes
|
||||
#include "nsISecureBrowserUI.h"
|
||||
|
||||
using namespace mozilla::layers;
|
||||
|
||||
static NS_DEFINE_IID(kWindowCID, NS_WINDOW_CID);
|
||||
static NS_DEFINE_CID(kChildCID, NS_CHILD_CID);
|
||||
static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
|
||||
|
@ -1667,11 +1671,12 @@ nsEventStatus nsWebBrowser::HandleEvent(nsGUIEvent *aEvent)
|
|||
{
|
||||
nsWebBrowser *browser = nsnull;
|
||||
void *data = nsnull;
|
||||
nsIWidget *widget = aEvent->widget;
|
||||
|
||||
if (!aEvent->widget)
|
||||
if (!widget)
|
||||
return nsEventStatus_eIgnore;
|
||||
|
||||
aEvent->widget->GetClientData(data);
|
||||
widget->GetClientData(data);
|
||||
if (!data)
|
||||
return nsEventStatus_eIgnore;
|
||||
|
||||
|
@ -1680,39 +1685,30 @@ nsEventStatus nsWebBrowser::HandleEvent(nsGUIEvent *aEvent)
|
|||
switch(aEvent->message) {
|
||||
|
||||
case NS_PAINT: {
|
||||
nsPaintEvent *paintEvent = static_cast<nsPaintEvent *>(aEvent);
|
||||
nsIRenderingContext *rc = paintEvent->renderingContext;
|
||||
nscolor oldColor;
|
||||
rc->GetColor(oldColor);
|
||||
rc->SetColor(browser->mBackgroundColor);
|
||||
|
||||
nsCOMPtr<nsIDeviceContext> dx;
|
||||
rc->GetDeviceContext(*getter_AddRefs(dx));
|
||||
PRInt32 appUnitsPerDevPixel = dx->AppUnitsPerDevPixel();
|
||||
LayerManager* layerManager = widget->GetLayerManager();
|
||||
NS_ASSERTION(layerManager, "Must be in paint event");
|
||||
|
||||
nsIRegion *region = paintEvent->region;
|
||||
if (region) {
|
||||
nsRegionRectSet *rects = nsnull;
|
||||
region->GetRects(&rects);
|
||||
if (rects) {
|
||||
for (PRUint32 i = 0; i < rects->mNumRects; ++i) {
|
||||
nsRect r(rects->mRects[i].x*appUnitsPerDevPixel,
|
||||
rects->mRects[i].y*appUnitsPerDevPixel,
|
||||
rects->mRects[i].width*appUnitsPerDevPixel,
|
||||
rects->mRects[i].height*appUnitsPerDevPixel);
|
||||
rc->FillRect(r);
|
||||
}
|
||||
|
||||
region->FreeRects(rects);
|
||||
}
|
||||
} else if (paintEvent->rect) {
|
||||
nsRect r(paintEvent->rect->x*appUnitsPerDevPixel,
|
||||
paintEvent->rect->y*appUnitsPerDevPixel,
|
||||
paintEvent->rect->width*appUnitsPerDevPixel,
|
||||
paintEvent->rect->height*appUnitsPerDevPixel);
|
||||
rc->FillRect(r);
|
||||
layerManager->BeginTransaction();
|
||||
nsRefPtr<ThebesLayer> root = layerManager->CreateThebesLayer();
|
||||
nsPaintEvent* paintEvent = static_cast<nsPaintEvent*>(aEvent);
|
||||
nsIntRect dirtyRect = paintEvent->region.GetBounds();
|
||||
if (root) {
|
||||
root->SetVisibleRegion(dirtyRect);
|
||||
layerManager->SetRoot(root);
|
||||
}
|
||||
rc->SetColor(oldColor);
|
||||
layerManager->EndConstruction();
|
||||
if (root) {
|
||||
nsIntRegion toDraw;
|
||||
gfxContext* ctx = root->BeginDrawing(&toDraw);
|
||||
if (ctx) {
|
||||
ctx->NewPath();
|
||||
ctx->SetColor(gfxRGBA(browser->mBackgroundColor));
|
||||
ctx->Rectangle(gfxRect(dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height));
|
||||
ctx->Fill();
|
||||
}
|
||||
}
|
||||
root->EndDrawing();
|
||||
layerManager->EndTransaction();
|
||||
return nsEventStatus_eConsumeDoDefault;
|
||||
}
|
||||
|
||||
|
|
|
@ -730,16 +730,36 @@ nsDisplayList::BuildLayer(nsDisplayListBuilder* aBuilder,
|
|||
* root of the layer manager, drawing into the ThebesLayers.
|
||||
*/
|
||||
void nsDisplayList::Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx) const {
|
||||
nsIRenderingContext* aCtx,
|
||||
PRUint32 aFlags) const {
|
||||
NS_ASSERTION(mDidComputeVisibility,
|
||||
"Must call ComputeVisibility before calling Paint");
|
||||
|
||||
// To paint a display list, we construct a BasicLayerManager and
|
||||
// a layer tree for it, and ask the BasicLayerManager to render.
|
||||
nsRefPtr<LayerManager> layerManager = new BasicLayerManager();
|
||||
if (!layerManager)
|
||||
return;
|
||||
layerManager->BeginTransactionWithTarget(aCtx->ThebesContext());
|
||||
nsRefPtr<LayerManager> layerManager;
|
||||
if (aFlags & PAINT_USE_WIDGET_LAYERS) {
|
||||
nsIFrame* referenceFrame = aBuilder->ReferenceFrame();
|
||||
NS_ASSERTION(referenceFrame == nsLayoutUtils::GetDisplayRootFrame(referenceFrame),
|
||||
"Reference frame must be a display root for us to use the layer manager");
|
||||
nsIWidget* window = referenceFrame->GetWindow();
|
||||
if (window) {
|
||||
layerManager = window->GetLayerManager();
|
||||
}
|
||||
}
|
||||
if (!layerManager) {
|
||||
if (!aCtx) {
|
||||
NS_WARNING("Nowhere to paint into");
|
||||
return;
|
||||
}
|
||||
layerManager = new BasicLayerManager(aCtx->ThebesContext());
|
||||
if (!layerManager)
|
||||
return;
|
||||
}
|
||||
|
||||
if (aCtx) {
|
||||
layerManager->BeginTransactionWithTarget(aCtx->ThebesContext());
|
||||
} else {
|
||||
layerManager->BeginTransaction();
|
||||
}
|
||||
|
||||
nsAutoTArray<LayerItems,10> layers;
|
||||
nsRefPtr<Layer> root = BuildLayer(aBuilder, layerManager, &layers);
|
||||
|
@ -1829,7 +1849,7 @@ void nsDisplayTransform::Paint(nsDisplayListBuilder *aBuilder,
|
|||
|
||||
/* Now, send the paint call down.
|
||||
*/
|
||||
mStoredList.GetList()->Paint(aBuilder, aCtx);
|
||||
mStoredList.GetList()->Paint(aBuilder, aCtx, nsDisplayList::PAINT_DEFAULT);
|
||||
|
||||
/* The AutoSaveRestore object will clean things up. */
|
||||
}
|
||||
|
|
|
@ -550,6 +550,7 @@ public:
|
|||
/**
|
||||
* Actually paint this item to some rendering context.
|
||||
* Content outside mVisibleRect need not be painted.
|
||||
* aCtx must be set up as for nsDisplayList::Paint.
|
||||
*/
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx) {}
|
||||
/**
|
||||
|
@ -848,9 +849,20 @@ public:
|
|||
* rectangle in aDirtyRect is painted, which *must* be contained in the
|
||||
* dirty rect used to construct the display list.
|
||||
*
|
||||
* If aFlags contains PAINT_USE_WIDGET_LAYERS and
|
||||
* ShouldUseWidgetLayerManager() is set, then we will paint using
|
||||
* the reference frame's widget's layer manager (and ctx may be null),
|
||||
* otherwise we will use a temporary BasicLayerManager and ctx must
|
||||
* not be null.
|
||||
*
|
||||
* ComputeVisibility must be called before Paint.
|
||||
*/
|
||||
void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx) const;
|
||||
enum {
|
||||
PAINT_DEFAULT = 0,
|
||||
PAINT_USE_WIDGET_LAYERS = 0x01
|
||||
};
|
||||
void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx,
|
||||
PRUint32 aFlags) const;
|
||||
/**
|
||||
* Get the bounds. Takes the union of the bounds of all children.
|
||||
*/
|
||||
|
|
|
@ -824,6 +824,13 @@ public:
|
|||
* clipping/scrolling/scrollbar painting due to scrolling in the viewport
|
||||
* set RENDER_CARET to draw the caret if one would be visible
|
||||
* (by default the caret is never drawn)
|
||||
* set RENDER_USE_LAYER_MANAGER to force rendering to go through
|
||||
* the layer manager for the window. This may be unexpectedly slow
|
||||
* (if the layer manager must read back data from the GPU) or low-quality
|
||||
* (if the layer manager reads back pixel data and scales it
|
||||
* instead of rendering using the appropriate scaling). It may also
|
||||
* slow everything down if the area rendered does not correspond to the
|
||||
* normal visible area of the window.
|
||||
* @param aBackgroundColor a background color to render onto
|
||||
* @param aRenderedContext the gfxContext to render to. We render so that
|
||||
* one CSS pixel in the source document is rendered to one unit in the current
|
||||
|
@ -832,7 +839,8 @@ public:
|
|||
enum {
|
||||
RENDER_IS_UNTRUSTED = 0x01,
|
||||
RENDER_IGNORE_VIEWPORT_SCROLLING = 0x02,
|
||||
RENDER_CARET = 0x04
|
||||
RENDER_CARET = 0x04,
|
||||
RENDER_USE_WIDGET_LAYERS = 0x08
|
||||
};
|
||||
NS_IMETHOD RenderDocument(const nsRect& aRect, PRUint32 aFlags,
|
||||
nscolor aBackgroundColor,
|
||||
|
|
|
@ -1192,7 +1192,11 @@ nsLayoutUtils::PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFra
|
|||
}
|
||||
#endif
|
||||
|
||||
list.Paint(&builder, aRenderingContext);
|
||||
PRUint32 flags = nsDisplayList::PAINT_DEFAULT;
|
||||
if (aFlags & PAINT_WIDGET_LAYERS) {
|
||||
flags |= nsDisplayList::PAINT_USE_WIDGET_LAYERS;
|
||||
}
|
||||
list.Paint(&builder, aRenderingContext, flags);
|
||||
// Flush the list so we don't trigger the IsEmpty-on-destruction assertion
|
||||
list.DeleteAll();
|
||||
return NS_OK;
|
||||
|
|
|
@ -477,7 +477,8 @@ public:
|
|||
|
||||
enum {
|
||||
PAINT_IN_TRANSFORM = 0x01,
|
||||
PAINT_SYNC_DECODE_IMAGES = 0x02
|
||||
PAINT_SYNC_DECODE_IMAGES = 0x02,
|
||||
PAINT_WIDGET_LAYERS = 0x04
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -485,14 +486,35 @@ public:
|
|||
* descendants to aRenderingContext.
|
||||
* @param aRenderingContext a rendering context translated so that (0,0)
|
||||
* is the origin of aFrame; for best results, (0,0) should transform
|
||||
* to pixel-aligned coordinates
|
||||
* to pixel-aligned coordinates. This can be null, in which case
|
||||
* aFrame must be a "display root" (root frame for a root document,
|
||||
* or the root of a popup) with an associated widget and we draw using
|
||||
* the layer manager for the frame's widget.
|
||||
* @param aDirtyRegion the region that must be painted, in the coordinates
|
||||
* of aFrame
|
||||
* @param aBackstop paint the dirty area with this color before drawing
|
||||
* the actual content; pass NS_RGBA(0,0,0,0) to draw no background
|
||||
* @param aFlags if PAINT_IN_TRANSFORM is set, then we assume
|
||||
* this is inside a transform or SVG foreignObject. If
|
||||
* PAINT_SYNC_DECODE_IMAGES is set, we force synchronous decode on all images.
|
||||
* PAINT_SYNC_DECODE_IMAGES is set, we force synchronous decode on all
|
||||
* images. If PAINT_WIDGET_LAYERS is set, aFrame must be a display root,
|
||||
* and we will use the frame's widget's layer manager to paint
|
||||
* even if aRenderingContext is non-null. This is useful if you want
|
||||
* to force rendering to use the widget's layer manager for testing
|
||||
* or speed. PAINT_WIDGET_LAYERS must be set if aRenderingContext is null.
|
||||
*
|
||||
* So there are three possible behaviours:
|
||||
* 1) PAINT_WIDGET_LAYERS is set and aRenderingContext is null; we paint
|
||||
* by calling BeginTransaction on the widget's layer manager
|
||||
* 2) PAINT_WIDGET_LAYERS is set and aRenderingContext is non-null; we
|
||||
* paint by calling BeginTransactionWithTarget on the widget's layer
|
||||
* maanger
|
||||
* 3) PAINT_WIDGET_LAYERS is not set and aRenderingContext is non-null;
|
||||
* we paint by construct a BasicLayerManager and calling
|
||||
* BeginTransactionWithTarget on it. This is desirable if we're doing
|
||||
* something like drawWindow in a mode where what gets rendered doesn't
|
||||
* necessarily correspond to what's visible in the window; we don't
|
||||
* want to mess up the widget's layer tree.
|
||||
*/
|
||||
static nsresult PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFrame,
|
||||
const nsRegion& aDirtyRegion, nscolor aBackstop,
|
||||
|
|
|
@ -206,6 +206,8 @@
|
|||
#include "nsContentCID.h"
|
||||
static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
|
||||
|
||||
using namespace mozilla::layers;
|
||||
|
||||
PRBool nsIPresShell::gIsAccessibilityActive = PR_FALSE;
|
||||
CapturingContentInfo nsIPresShell::gCaptureInfo;
|
||||
|
||||
|
@ -784,12 +786,11 @@ public:
|
|||
|
||||
//nsIViewObserver interface
|
||||
|
||||
NS_IMETHOD Paint(nsIView *aView,
|
||||
nsIRenderingContext* aRenderingContext,
|
||||
const nsRegion& aDirtyRegion);
|
||||
NS_IMETHOD PaintDefaultBackground(nsIView *aView,
|
||||
nsIRenderingContext* aRenderingContext,
|
||||
const nsRect& aDirtyRect);
|
||||
NS_IMETHOD Paint(nsIView* aDisplayRoot,
|
||||
nsIView* aViewToPaint,
|
||||
nsIWidget* aWidget,
|
||||
const nsRegion& aDirtyRegion,
|
||||
PRBool aPaintDefaultBackground);
|
||||
NS_IMETHOD ComputeRepaintRegionForCopy(nsIView* aRootView,
|
||||
nsIView* aMovingView,
|
||||
nsPoint aDelta,
|
||||
|
@ -1287,7 +1288,7 @@ private:
|
|||
* widget, otherwise the PresContext default background color. This color is
|
||||
* only visible if the contents of the view as a whole are translucent.
|
||||
*/
|
||||
nscolor ComputeBackstopColor(nsIView* aView);
|
||||
nscolor ComputeBackstopColor(nsIView* aDisplayRoot);
|
||||
|
||||
#ifdef DEBUG
|
||||
// Ensure that every allocation from the PresArena is eventually freed.
|
||||
|
@ -5279,7 +5280,11 @@ PresShell::RenderDocument(const nsRect& aRect, PRUint32 aFlags,
|
|||
devCtx->CreateRenderingContextInstance(*getter_AddRefs(rc));
|
||||
rc->Init(devCtx, aThebesContext);
|
||||
|
||||
list.Paint(&builder, rc);
|
||||
PRUint32 flags = nsDisplayList::PAINT_DEFAULT;
|
||||
if (aFlags & RENDER_USE_WIDGET_LAYERS) {
|
||||
flags |= nsDisplayList::PAINT_USE_WIDGET_LAYERS;
|
||||
}
|
||||
list.Paint(&builder, rc, flags);
|
||||
// Flush the list so we don't trigger the IsEmpty-on-destruction assertion
|
||||
list.DeleteAll();
|
||||
|
||||
|
@ -5572,7 +5577,7 @@ PresShell::PaintRangePaintInfo(nsTArray<nsAutoPtr<RangePaintInfo> >* aItems,
|
|||
aArea.MoveBy(-rangeInfo->mRootOffset.x, -rangeInfo->mRootOffset.y);
|
||||
nsRegion visible(aArea);
|
||||
rangeInfo->mList.ComputeVisibility(&rangeInfo->mBuilder, &visible, nsnull);
|
||||
rangeInfo->mList.Paint(&rangeInfo->mBuilder, rc);
|
||||
rangeInfo->mList.Paint(&rangeInfo->mBuilder, rc, nsDisplayList::PAINT_DEFAULT);
|
||||
aArea.MoveBy(rangeInfo->mRootOffset.x, rangeInfo->mRootOffset.y);
|
||||
}
|
||||
|
||||
|
@ -5716,9 +5721,9 @@ void PresShell::UpdateCanvasBackground()
|
|||
}
|
||||
}
|
||||
|
||||
nscolor PresShell::ComputeBackstopColor(nsIView* aView)
|
||||
nscolor PresShell::ComputeBackstopColor(nsIView* aDisplayRoot)
|
||||
{
|
||||
nsIWidget* widget = aView->GetNearestWidget(nsnull);
|
||||
nsIWidget* widget = aDisplayRoot->GetWidget();
|
||||
if (widget && widget->GetTransparencyMode() != eTransparencyOpaque) {
|
||||
// Within a transparent widget, so the backstop color must be
|
||||
// totally transparent.
|
||||
|
@ -5731,46 +5736,80 @@ nscolor PresShell::ComputeBackstopColor(nsIView* aView)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::Paint(nsIView* aView,
|
||||
nsIRenderingContext* aRenderingContext,
|
||||
const nsRegion& aDirtyRegion)
|
||||
PresShell::Paint(nsIView* aDisplayRoot,
|
||||
nsIView* aViewToPaint,
|
||||
nsIWidget* aWidgetToPaint,
|
||||
const nsRegion& aDirtyRegion,
|
||||
PRBool aPaintDefaultBackground)
|
||||
{
|
||||
AUTO_LAYOUT_PHASE_ENTRY_POINT(GetPresContext(), Paint);
|
||||
nsPresContext* presContext = GetPresContext();
|
||||
AUTO_LAYOUT_PHASE_ENTRY_POINT(presContext, Paint);
|
||||
|
||||
NS_ASSERTION(!mIsDestroying, "painting a destroyed PresShell");
|
||||
NS_ASSERTION(aView, "null view");
|
||||
NS_ASSERTION(aDisplayRoot, "null view");
|
||||
NS_ASSERTION(aViewToPaint, "null view");
|
||||
NS_ASSERTION(aWidgetToPaint, "Can't paint without a widget");
|
||||
|
||||
nscolor bgcolor = ComputeBackstopColor(aView);
|
||||
nscolor bgcolor = ComputeBackstopColor(aDisplayRoot);
|
||||
|
||||
nsIFrame* frame = static_cast<nsIFrame*>(aView->GetClientData());
|
||||
if (frame) {
|
||||
nsLayoutUtils::PaintFrame(aRenderingContext, frame, aDirtyRegion, bgcolor);
|
||||
} else {
|
||||
bgcolor = NS_ComposeColors(bgcolor, mCanvasBackgroundColor);
|
||||
aRenderingContext->SetColor(bgcolor);
|
||||
aRenderingContext->FillRect(aDirtyRegion.GetBounds());
|
||||
nsIFrame* frame = aPaintDefaultBackground
|
||||
? nsnull : static_cast<nsIFrame*>(aDisplayRoot->GetClientData());
|
||||
|
||||
if (frame && aViewToPaint == aDisplayRoot) {
|
||||
// We can paint directly into the widget using its layer manager.
|
||||
// When we get rid of child widgets, this will be the only path we
|
||||
// need. (aPaintDefaultBackground will never be needed since the
|
||||
// chrome can always paint a default background.)
|
||||
nsLayoutUtils::PaintFrame(nsnull, frame, aDirtyRegion, bgcolor,
|
||||
nsLayoutUtils::PAINT_WIDGET_LAYERS);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::PaintDefaultBackground(nsIView* aView,
|
||||
nsIRenderingContext* aRenderingContext,
|
||||
const nsRect& aDirtyRect)
|
||||
{
|
||||
AUTO_LAYOUT_PHASE_ENTRY_POINT(GetPresContext(), Paint);
|
||||
LayerManager* layerManager = aWidgetToPaint->GetLayerManager();
|
||||
NS_ASSERTION(layerManager, "Must be in paint event");
|
||||
|
||||
NS_ASSERTION(!mIsDestroying, "painting a destroyed PresShell");
|
||||
NS_ASSERTION(aView, "null view");
|
||||
layerManager->BeginTransaction();
|
||||
nsRefPtr<ThebesLayer> root = layerManager->CreateThebesLayer();
|
||||
nsIntRect dirtyRect = aDirtyRegion.GetBounds().
|
||||
ToOutsidePixels(presContext->AppUnitsPerDevPixel());
|
||||
if (root) {
|
||||
root->SetVisibleRegion(dirtyRect);
|
||||
layerManager->SetRoot(root);
|
||||
}
|
||||
layerManager->EndConstruction();
|
||||
if (root) {
|
||||
nsIntRegion toDraw;
|
||||
gfxContext* ctx = root->BeginDrawing(&toDraw);
|
||||
if (ctx) {
|
||||
if (frame) {
|
||||
// We're drawing into a child window. Don't pass
|
||||
// nsLayoutUtils::PAINT_WIDGET_LAYERS, since that will draw into
|
||||
// the widget for the display root.
|
||||
nsIDeviceContext* devCtx = GetPresContext()->DeviceContext();
|
||||
nsCOMPtr<nsIRenderingContext> rc;
|
||||
nsresult rv = devCtx->CreateRenderingContextInstance(*getter_AddRefs(rc));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rc->Init(devCtx, ctx);
|
||||
// Offset to add to aView coordinates to get aWidget coordinates
|
||||
nsPoint offsetToRoot = aViewToPaint->GetOffsetTo(aDisplayRoot);
|
||||
nsRegion dirtyRegion = aDirtyRegion;
|
||||
dirtyRegion.MoveBy(offsetToRoot);
|
||||
nsIRenderingContext::AutoPushTranslation
|
||||
push(rc, -offsetToRoot.x, -offsetToRoot.y);
|
||||
nsLayoutUtils::PaintFrame(rc, frame, dirtyRegion, bgcolor);
|
||||
}
|
||||
} else {
|
||||
bgcolor = NS_ComposeColors(bgcolor, mCanvasBackgroundColor);
|
||||
ctx->NewPath();
|
||||
ctx->SetColor(gfxRGBA(bgcolor));
|
||||
ctx->Rectangle(gfxRect(dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height));
|
||||
ctx->Fill();
|
||||
}
|
||||
}
|
||||
root->EndDrawing();
|
||||
}
|
||||
layerManager->EndTransaction();
|
||||
|
||||
// We must not look at the frame tree, so all we have to use is the canvas
|
||||
// default color as set above.
|
||||
|
||||
nscolor bgcolor = NS_ComposeColors(ComputeBackstopColor(aView),
|
||||
mCanvasBackgroundColor);
|
||||
|
||||
aRenderingContext->SetColor(bgcolor);
|
||||
aRenderingContext->FillRect(aDirtyRect);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -209,7 +209,7 @@ public:
|
|||
{
|
||||
nsIRenderingContext* ctx = aContext->GetRenderingContext(aTarget);
|
||||
nsIRenderingContext::AutoPushTranslation push(ctx, -mOffset.x, -mOffset.y);
|
||||
mInnerList->Paint(mBuilder, ctx);
|
||||
mInnerList->Paint(mBuilder, ctx, nsDisplayList::PAINT_DEFAULT);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -302,7 +302,7 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(nsIRenderingContext* aCtx,
|
|||
filterFrame->FilterPaint(&svgContext, aEffectsFrame, &paint, &r);
|
||||
} else {
|
||||
gfx->SetMatrix(savedCTM);
|
||||
aInnerList->Paint(aBuilder, aCtx);
|
||||
aInnerList->Paint(aBuilder, aCtx, nsDisplayList::PAINT_DEFAULT);
|
||||
aCtx->Translate(userSpaceRect.x, userSpaceRect.y);
|
||||
}
|
||||
|
||||
|
|
|
@ -877,7 +877,8 @@ function InitCurrentCanvasWithSnapshot()
|
|||
Math.ceil(gCurrentCanvas.width / scale),
|
||||
Math.ceil(gCurrentCanvas.height / scale),
|
||||
"rgb(255,255,255)",
|
||||
ctx.DRAWWINDOW_DRAW_CARET);
|
||||
ctx.DRAWWINDOW_DRAW_CARET |
|
||||
ctx.DRAWWINDOW_USE_WIDGET_LAYERS);
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
|
|
|
@ -47,8 +47,8 @@ class nsIRenderingContext;
|
|||
class nsGUIEvent;
|
||||
|
||||
#define NS_IVIEWOBSERVER_IID \
|
||||
{ 0xba1357b6, 0xe3c7, 0x426a, \
|
||||
{ 0xb3, 0x68, 0xfe, 0xe8, 0x24, 0x8c, 0x08, 0x38 } }
|
||||
{ 0xac43a985, 0xcae6, 0x499d, \
|
||||
{ 0xae, 0x8f, 0x9c, 0x92, 0xec, 0x6f, 0x2c, 0x47 } }
|
||||
|
||||
class nsIViewObserver : public nsISupports
|
||||
{
|
||||
|
@ -59,36 +59,23 @@ public:
|
|||
/* called when the observer needs to paint. This paints the entire
|
||||
* frame subtree rooted at the view, including frame subtrees from
|
||||
* subdocuments.
|
||||
* @param aRenderingContext rendering context to paint to; the origin
|
||||
* of the view is painted at (0,0) in the rendering context's current
|
||||
* transform. For best results this should transform to pixel-aligned
|
||||
* coordinates.
|
||||
* @param aViewToPaint the view for the widget that is being painted
|
||||
* @param aDirtyRegion the region to be painted, in the coordinates of
|
||||
* aRootView
|
||||
* aViewToPaint
|
||||
* @param aPaintDefaultBackground just paint the default background,
|
||||
* don't try to paint any content. This is set when the observer
|
||||
* needs to paint something, but the view tree is unstable, so it
|
||||
* must *not* paint, or even examine, the frame subtree rooted at the
|
||||
* view. (It is, however, safe to inspect the state of the view itself,
|
||||
* and any associated widget.) The name illustrates the expected behavior,
|
||||
* which is to paint some default background color over the dirty region.
|
||||
* @return error status
|
||||
*/
|
||||
NS_IMETHOD Paint(nsIView* aRootView,
|
||||
nsIRenderingContext* aRenderingContext,
|
||||
const nsRegion& aDirtyRegion) = 0;
|
||||
|
||||
/* called when the observer needs to paint something, but the view
|
||||
* tree is unstable, so it must *not* paint, or even examine, the
|
||||
* frame subtree rooted at the view. (It is, however, safe to inspect
|
||||
* the state of the view itself, and any associated widget.) The name
|
||||
* illustrates the expected behavior, which is to paint some default
|
||||
* background color over the dirty rect.
|
||||
*
|
||||
* @param aRenderingContext rendering context to paint to; the origin
|
||||
* of the view is painted at (0,0) in the rendering context's current
|
||||
* transform. For best results this should transform to pixel-aligned
|
||||
* coordinates.
|
||||
* @param aDirtyRect the rectangle to be painted, in the coordinates
|
||||
* of aRootView
|
||||
* @return error status
|
||||
*/
|
||||
NS_IMETHOD PaintDefaultBackground(nsIView* aRootView,
|
||||
nsIRenderingContext* aRenderingContext,
|
||||
const nsRect& aDirtyRect) = 0;
|
||||
NS_IMETHOD Paint(nsIView* aDisplayRoot,
|
||||
nsIView* aViewToPaint,
|
||||
nsIWidget* aWidgetToPaint,
|
||||
const nsRegion& aDirtyRegion,
|
||||
PRBool aPaintDefaultBackground) = 0;
|
||||
|
||||
/* called when the observer needs to handle an event
|
||||
* @param aView - where to start processing the event; the root view,
|
||||
|
|
|
@ -352,28 +352,20 @@ NS_IMETHODIMP nsViewManager::FlushDelayedResize()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static void ConvertNativeRegionToAppRegion(nsIRegion* aIn, nsRegion* aOut,
|
||||
nsIDeviceContext* context)
|
||||
static nsRegion ConvertDeviceRegionToAppRegion(const nsIntRegion& aIn,
|
||||
nsIDeviceContext* aContext)
|
||||
{
|
||||
nsRegionRectSet* rects = nsnull;
|
||||
aIn->GetRects(&rects);
|
||||
if (!rects)
|
||||
return;
|
||||
PRInt32 p2a = aContext->AppUnitsPerDevPixel();
|
||||
|
||||
PRInt32 p2a = context->AppUnitsPerDevPixel();
|
||||
|
||||
PRUint32 i;
|
||||
for (i = 0; i < rects->mNumRects; i++) {
|
||||
const nsRegionRect& inR = rects->mRects[i];
|
||||
nsRect outR;
|
||||
outR.x = NSIntPixelsToAppUnits(inR.x, p2a);
|
||||
outR.y = NSIntPixelsToAppUnits(inR.y, p2a);
|
||||
outR.width = NSIntPixelsToAppUnits(inR.width, p2a);
|
||||
outR.height = NSIntPixelsToAppUnits(inR.height, p2a);
|
||||
aOut->Or(*aOut, outR);
|
||||
nsRegion out;
|
||||
nsIntRegionRectIterator iter(aIn);
|
||||
for (;;) {
|
||||
const nsIntRect* r = iter.Next();
|
||||
if (!r)
|
||||
break;
|
||||
out.Or(out, r->ToAppUnits(p2a));
|
||||
}
|
||||
|
||||
aIn->FreeRects(rects);
|
||||
return out;
|
||||
}
|
||||
|
||||
static nsView* GetDisplayRootFor(nsView* aView)
|
||||
|
@ -392,12 +384,13 @@ static nsView* GetDisplayRootFor(nsView* aView)
|
|||
|
||||
/**
|
||||
aRegion is given in device coordinates!!
|
||||
aContext may be null, in which case layers should be used for
|
||||
rendering.
|
||||
*/
|
||||
void nsViewManager::Refresh(nsView *aView, nsIRenderingContext *aContext,
|
||||
nsIRegion *aRegion, PRUint32 aUpdateFlags)
|
||||
void nsViewManager::Refresh(nsView *aView, nsIWidget *aWidget,
|
||||
const nsIntRegion& aRegion,
|
||||
PRUint32 aUpdateFlags)
|
||||
{
|
||||
NS_ASSERTION(aRegion != nsnull, "Null aRegion");
|
||||
|
||||
if (! IsRefreshEnabled())
|
||||
return;
|
||||
|
||||
|
@ -406,10 +399,8 @@ void nsViewManager::Refresh(nsView *aView, nsIRenderingContext *aContext,
|
|||
nsPoint vtowoffset = aView->ViewToWidgetOffset();
|
||||
|
||||
// damageRegion is the damaged area, in twips, relative to the view origin
|
||||
nsRegion damageRegion;
|
||||
// convert pixels-relative-to-widget-origin to twips-relative-to-widget-origin
|
||||
ConvertNativeRegionToAppRegion(aRegion, &damageRegion, mContext);
|
||||
// move it from widget coordinates into view coordinates
|
||||
nsRegion damageRegion = ConvertDeviceRegionToAppRegion(aRegion, mContext);
|
||||
// move region from widget coordinates into view coordinates
|
||||
damageRegion.MoveBy(viewRect.TopLeft() - vtowoffset);
|
||||
|
||||
if (damageRegion.IsEmpty()) {
|
||||
|
@ -432,36 +423,7 @@ void nsViewManager::Refresh(nsView *aView, nsIRenderingContext *aContext,
|
|||
nsAutoScriptBlocker scriptBlocker;
|
||||
SetPainting(PR_TRUE);
|
||||
|
||||
nsCOMPtr<nsIRenderingContext> localcx;
|
||||
if (nsnull == aContext)
|
||||
{
|
||||
localcx = CreateRenderingContext(*aView);
|
||||
|
||||
//couldn't get rendering context. this is ok at init time atleast
|
||||
if (nsnull == localcx) {
|
||||
SetPainting(PR_FALSE);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// plain assignment grabs another reference.
|
||||
localcx = aContext;
|
||||
}
|
||||
|
||||
PRInt32 p2a = mContext->AppUnitsPerDevPixel();
|
||||
|
||||
nsRefPtr<gfxContext> ctx = localcx->ThebesContext();
|
||||
|
||||
ctx->Save();
|
||||
|
||||
ctx->Translate(gfxPoint(gfxFloat(vtowoffset.x) / p2a,
|
||||
gfxFloat(vtowoffset.y) / p2a));
|
||||
|
||||
ctx->Translate(gfxPoint(-gfxFloat(viewRect.x) / p2a,
|
||||
-gfxFloat(viewRect.y) / p2a));
|
||||
|
||||
RenderViews(aView, *localcx, damageRegion);
|
||||
|
||||
ctx->Restore();
|
||||
RenderViews(aView, aWidget, damageRegion);
|
||||
|
||||
SetPainting(PR_FALSE);
|
||||
}
|
||||
|
@ -475,25 +437,20 @@ void nsViewManager::Refresh(nsView *aView, nsIRenderingContext *aContext,
|
|||
}
|
||||
|
||||
// aRC and aRegion are in view coordinates
|
||||
void nsViewManager::RenderViews(nsView *aView, nsIRenderingContext& aRC,
|
||||
void nsViewManager::RenderViews(nsView *aView, nsIWidget *aWidget,
|
||||
const nsRegion& aRegion)
|
||||
{
|
||||
nsView* displayRoot = GetDisplayRootFor(aView);
|
||||
// Make sure we call Paint from the view manager that owns displayRoot.
|
||||
// (Bug 485275)
|
||||
nsViewManager* displayRootVM = displayRoot->GetViewManager();
|
||||
if (displayRootVM && displayRootVM != this)
|
||||
return displayRootVM->RenderViews(aView, aRC, aRegion);
|
||||
if (displayRootVM && displayRootVM != this) {
|
||||
displayRootVM->RenderViews(aView, aWidget, aRegion);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mObserver) {
|
||||
nsPoint offsetToRoot = aView->GetOffsetTo(displayRoot);
|
||||
nsRegion damageRegion(aRegion);
|
||||
damageRegion.MoveBy(offsetToRoot);
|
||||
|
||||
aRC.PushState();
|
||||
aRC.Translate(-offsetToRoot.x, -offsetToRoot.y);
|
||||
mObserver->Paint(displayRoot, &aRC, damageRegion);
|
||||
aRC.PopState();
|
||||
mObserver->Paint(displayRoot, aView, aWidget, aRegion, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -839,21 +796,11 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent,
|
|||
|
||||
*aStatus = nsEventStatus_eConsumeNoDefault;
|
||||
|
||||
if (aEvent->message == NS_PAINT && event->region.IsEmpty())
|
||||
break;
|
||||
|
||||
// The rect is in device units, and it's in the coordinate space of its
|
||||
// associated window.
|
||||
nsCOMPtr<nsIRegion> region = event->region;
|
||||
if (aEvent->message == NS_PAINT) {
|
||||
if (!region) {
|
||||
if (NS_FAILED(CreateRegion(getter_AddRefs(region))))
|
||||
break;
|
||||
|
||||
const nsIntRect& damrect = *event->rect;
|
||||
region->SetTo(damrect.x, damrect.y, damrect.width, damrect.height);
|
||||
}
|
||||
|
||||
if (region->IsEmpty())
|
||||
break;
|
||||
}
|
||||
|
||||
// Refresh the view
|
||||
if (IsRefreshEnabled()) {
|
||||
|
@ -926,28 +873,16 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent,
|
|||
}
|
||||
|
||||
if (view && aEvent->message == NS_PAINT) {
|
||||
Refresh(view, event->renderingContext, region,
|
||||
NS_VMREFRESH_DOUBLE_BUFFER);
|
||||
Refresh(view, event->widget,
|
||||
event->region, NS_VMREFRESH_DOUBLE_BUFFER);
|
||||
}
|
||||
}
|
||||
} else if (aEvent->message == NS_PAINT) {
|
||||
// since we got an NS_PAINT event, we need to
|
||||
// draw something so we don't get blank areas,
|
||||
// unless there's no widget or it's transparent.
|
||||
nsIntRect damIntRect;
|
||||
region->GetBoundingBox(&damIntRect.x, &damIntRect.y,
|
||||
&damIntRect.width, &damIntRect.height);
|
||||
nsRect damRect =
|
||||
damIntRect.ToAppUnits(mContext->AppUnitsPerDevPixel());
|
||||
|
||||
nsCOMPtr<nsIRenderingContext> context = event->renderingContext;
|
||||
if (!context)
|
||||
context = CreateRenderingContext(*static_cast<nsView*>(aView));
|
||||
|
||||
if (context)
|
||||
mObserver->PaintDefaultBackground(aView, context, damRect);
|
||||
else
|
||||
NS_WARNING("nsViewManager: no rc for default refresh");
|
||||
nsRegion rgn = ConvertDeviceRegionToAppRegion(event->region, mContext);
|
||||
mObserver->Paint(aView, aView, event->widget, rgn, PR_TRUE);
|
||||
|
||||
// Clients like the editor can trigger multiple
|
||||
// reflows during what the user perceives as a single
|
||||
|
@ -973,7 +908,7 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent,
|
|||
// ScrollingView's viewable area. (See bug 97674 for this
|
||||
// alternate patch.)
|
||||
|
||||
UpdateView(aView, damRect, NS_VMREFRESH_NO_SYNC);
|
||||
UpdateView(aView, rgn.GetBounds(), NS_VMREFRESH_NO_SYNC);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -1550,53 +1485,6 @@ NS_IMETHODIMP nsViewManager::GetDeviceContext(nsIDeviceContext *&aContext)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIRenderingContext>
|
||||
nsViewManager::CreateRenderingContext(nsView &aView)
|
||||
{
|
||||
nsView *par = &aView;
|
||||
nsIWidget* win;
|
||||
nsIRenderingContext *cx = nsnull;
|
||||
nscoord ax = 0, ay = 0;
|
||||
|
||||
do
|
||||
{
|
||||
win = par->GetWidget();
|
||||
if (win)
|
||||
break;
|
||||
|
||||
//get absolute coordinates of view, but don't
|
||||
//add in view pos since the first thing you ever
|
||||
//need to do when painting a view is to translate
|
||||
//the rendering context by the views pos and other parts
|
||||
//of the code do this for us...
|
||||
|
||||
if (par != &aView)
|
||||
{
|
||||
par->ConvertToParentCoords(&ax, &ay);
|
||||
}
|
||||
|
||||
par = par->GetParent();
|
||||
}
|
||||
while (nsnull != par);
|
||||
|
||||
if (nsnull != win)
|
||||
{
|
||||
// XXXkt this has an origin at top-left of win ...
|
||||
mContext->CreateRenderingContext(par, cx);
|
||||
|
||||
// XXXkt ... but the translation is between the origins of views
|
||||
NS_ASSERTION(aView.ViewToWidgetOffset()
|
||||
- aView.GetDimensions().TopLeft() ==
|
||||
par->ViewToWidgetOffset()
|
||||
- par->GetDimensions().TopLeft(),
|
||||
"ViewToWidgetOffset not handled!");
|
||||
if (nsnull != cx)
|
||||
cx->Translate(ax, ay);
|
||||
}
|
||||
|
||||
return cx;
|
||||
}
|
||||
|
||||
void nsViewManager::TriggerRefresh(PRUint32 aUpdateFlags)
|
||||
{
|
||||
if (!IsRootVM()) {
|
||||
|
|
|
@ -179,7 +179,6 @@ private:
|
|||
void CallWillPaintOnObservers();
|
||||
void ReparentChildWidgets(nsIView* aView, nsIWidget *aNewWidget);
|
||||
void ReparentWidgets(nsIView* aView, nsIView *aParent);
|
||||
already_AddRefed<nsIRenderingContext> CreateRenderingContext(nsView &aView);
|
||||
void UpdateWidgetArea(nsView *aWidgetView, nsIWidget* aWidget,
|
||||
const nsRegion &aDamagedRegion,
|
||||
nsView* aIgnoreWidgetView);
|
||||
|
@ -188,9 +187,9 @@ private:
|
|||
|
||||
void TriggerRefresh(PRUint32 aUpdateFlags);
|
||||
|
||||
void Refresh(nsView *aView, nsIRenderingContext *aContext,
|
||||
nsIRegion *region, PRUint32 aUpdateFlags);
|
||||
void RenderViews(nsView *aRootView, nsIRenderingContext& aRC,
|
||||
void Refresh(nsView *aView, nsIWidget *aWidget,
|
||||
const nsIntRegion& aRegion, PRUint32 aUpdateFlags);
|
||||
void RenderViews(nsView *aRootView, nsIWidget *aWidget,
|
||||
const nsRegion& aRegion);
|
||||
|
||||
void InvalidateRectDifference(nsView *aView, const nsRect& aRect, const nsRect& aCutOut, PRUint32 aUpdateFlags);
|
||||
|
|
|
@ -59,7 +59,6 @@
|
|||
#include "nsIVariant.h"
|
||||
|
||||
class nsIRenderingContext;
|
||||
class nsIRegion;
|
||||
class nsIMenuItem;
|
||||
class nsIAccessible;
|
||||
class nsIContent;
|
||||
|
@ -636,17 +635,12 @@ class nsPaintEvent : public nsGUIEvent
|
|||
{
|
||||
public:
|
||||
nsPaintEvent(PRBool isTrusted, PRUint32 msg, nsIWidget *w)
|
||||
: nsGUIEvent(isTrusted, msg, w, NS_PAINT_EVENT),
|
||||
renderingContext(nsnull), region(nsnull), rect(nsnull)
|
||||
: nsGUIEvent(isTrusted, msg, w, NS_PAINT_EVENT)
|
||||
{
|
||||
}
|
||||
|
||||
/// Context to paint in.
|
||||
nsIRenderingContext *renderingContext;
|
||||
/// area to paint (should be used instead of rect)
|
||||
nsIRegion *region;
|
||||
/// x,y, width, height in pixels of area to paint
|
||||
nsIntRect *rect;
|
||||
// area that needs repainting
|
||||
nsIntRegion region;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -66,6 +66,12 @@ class imgIContainer;
|
|||
class gfxASurface;
|
||||
class nsIContent;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
class LayerManager;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function that processes events.
|
||||
*
|
||||
|
@ -103,7 +109,7 @@ typedef nsEventStatus (* EVENT_CALLBACK)(nsGUIEvent *event);
|
|||
#endif
|
||||
|
||||
#define NS_IWIDGET_IID \
|
||||
{ 0x6bdb96ba, 0x1727, 0x40ae, \
|
||||
{ 0x9383831, 0x1039, 0x010f9, \
|
||||
{ 0x85, 0x55, 0x9c, 0x53, 0x4b, 0x95, 0x23, 0x98 } }
|
||||
|
||||
/*
|
||||
|
@ -180,6 +186,7 @@ enum nsTopLevelWidgetZPlacement { // for PlaceBehind()
|
|||
class nsIWidget : public nsISupports {
|
||||
|
||||
public:
|
||||
typedef mozilla::layers::LayerManager LayerManager;
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IWIDGET_IID)
|
||||
|
||||
|
@ -667,6 +674,14 @@ class nsIWidget : public nsISupports {
|
|||
|
||||
virtual nsIToolkit* GetToolkit() = 0;
|
||||
|
||||
/**
|
||||
* Return the widget's LayerManager. The layer tree for that
|
||||
* LayerManager is what gets rendered to the widget.
|
||||
* The layer manager is guaranteed to be the same for the lifetime
|
||||
* of the widget.
|
||||
*/
|
||||
virtual LayerManager* GetLayerManager() = 0;
|
||||
|
||||
/**
|
||||
* Scroll a set of rectangles in this widget and (as simultaneously as
|
||||
* possible) modify the specified child widgets.
|
||||
|
|
|
@ -55,6 +55,7 @@ CPPSRCS = nsWinWidgetFactory.cpp
|
|||
|
||||
EXTRA_DSO_LIBS = gkgfx \
|
||||
thebes \
|
||||
layers \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
|
|
|
@ -106,6 +106,7 @@ EXTRA_DSO_LDOPTS += \
|
|||
$(call EXPAND_LIBNAME_PATH,gkgfx,$(DEPTH)/gfx/src) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
-lthebes \
|
||||
-llayers \
|
||||
$(QCMS_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ PRUint32 nsChildView::sLastInputEventCount = 0;
|
|||
|
||||
+ (NSEvent*)makeNewCocoaEventWithType:(NSEventType)type fromEvent:(NSEvent*)theEvent;
|
||||
|
||||
- (BOOL)beginMaybeResetUnifiedToolbar:(nsIRegion*)aRegion context:(CGContextRef)aContext;
|
||||
- (BOOL)beginMaybeResetUnifiedToolbar:(nsIntRegion*)aRegion context:(CGContextRef)aContext;
|
||||
- (void)endMaybeResetUnifiedToolbar:(BOOL)aReset;
|
||||
|
||||
#if USE_CLICK_HOLD_CONTEXTMENU
|
||||
|
@ -1669,7 +1669,6 @@ void nsChildView::Scroll(const nsIntPoint& aDelta,
|
|||
// to do exactly what we need here.
|
||||
nsIntRegion needsInvalidation;
|
||||
needsInvalidation.Sub(allRects, destRegion);
|
||||
nsIntRegionRectIterator iter(needsInvalidation);
|
||||
const nsIntRect* invalidate;
|
||||
for (nsIntRegionRectIterator iter(needsInvalidation);
|
||||
(invalidate = iter.Next()) != nsnull;) {
|
||||
|
@ -2453,11 +2452,11 @@ static BOOL DrawingAtWindowTop(CGContextRef aContext)
|
|||
return ctm.ty >= [[[[NSView focusView] window] contentView] bounds].size.height;
|
||||
}
|
||||
|
||||
- (BOOL)beginMaybeResetUnifiedToolbar:(nsIRegion*)aRegion context:(CGContextRef)aContext
|
||||
- (BOOL)beginMaybeResetUnifiedToolbar:(nsIntRegion*)aRegion context:(CGContextRef)aContext
|
||||
{
|
||||
if (![[self window] isKindOfClass:[ToolbarWindow class]] ||
|
||||
!DrawingAtWindowTop(aContext) ||
|
||||
!aRegion->ContainsRect(0, 0, (int)[self bounds].size.width, 1))
|
||||
!aRegion->Contains(nsIntRect(0, 0, (int)[self bounds].size.width, 1)))
|
||||
return NO;
|
||||
|
||||
[(ToolbarWindow*)[self window] beginMaybeResetUnifiedToolbar];
|
||||
|
@ -2512,15 +2511,8 @@ static BOOL DrawingAtWindowTop(CGContextRef aContext)
|
|||
|
||||
nsRefPtr<gfxContext> targetContext = new gfxContext(targetSurface);
|
||||
|
||||
nsCOMPtr<nsIRenderingContext> rc;
|
||||
mGeckoChild->GetDeviceContext()->CreateRenderingContextInstance(*getter_AddRefs(rc));
|
||||
rc->Init(mGeckoChild->GetDeviceContext(), targetContext);
|
||||
|
||||
// Build a region.
|
||||
nsCOMPtr<nsIRegion> rgn(do_CreateInstance(kRegionCID));
|
||||
if (!rgn)
|
||||
return;
|
||||
rgn->Init();
|
||||
// Create the event so we can fill in its region
|
||||
nsPaintEvent paintEvent(PR_TRUE, NS_PAINT, mGeckoChild);
|
||||
|
||||
const NSRect *rects;
|
||||
NSInteger count, i;
|
||||
|
@ -2529,10 +2521,12 @@ static BOOL DrawingAtWindowTop(CGContextRef aContext)
|
|||
for (i = 0; i < count; ++i) {
|
||||
// Add the rect to the region.
|
||||
const NSRect& r = [self convertRect:rects[i] fromView:[NSView focusView]];
|
||||
rgn->Union((PRInt32)r.origin.x, (PRInt32)r.origin.y, (PRInt32)r.size.width, (PRInt32)r.size.height);
|
||||
paintEvent.region.Or(paintEvent.region,
|
||||
nsIntRect(r.origin.x, r.origin.y, r.size.width, r.size.height));
|
||||
}
|
||||
} else {
|
||||
rgn->Union(aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height);
|
||||
paintEvent.region =
|
||||
nsIntRect(aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height);
|
||||
}
|
||||
|
||||
// Subtract child view rectangles from the region
|
||||
|
@ -2542,36 +2536,31 @@ static BOOL DrawingAtWindowTop(CGContextRef aContext)
|
|||
if (![view isKindOfClass:[ChildView class]] || [view isHidden])
|
||||
continue;
|
||||
NSRect frame = [view frame];
|
||||
rgn->Subtract(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
|
||||
paintEvent.region.Sub(paintEvent.region,
|
||||
nsIntRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height));
|
||||
}
|
||||
|
||||
// Set up the clip region.
|
||||
nsRegionRectSet* rgnRects = nsnull;
|
||||
rgn->GetRects(&rgnRects);
|
||||
if (!rgnRects)
|
||||
return;
|
||||
|
||||
for (PRUint32 i = 0; i < rgnRects->mNumRects; ++i) {
|
||||
const nsRegionRect& rect = rgnRects->mRects[i];
|
||||
targetContext->Rectangle(gfxRect(rect.x, rect.y, rect.width, rect.height));
|
||||
nsIntRegionRectIterator iter(paintEvent.region);
|
||||
targetContext->NewPath();
|
||||
for (;;) {
|
||||
const nsIntRect* r = iter.Next();
|
||||
if (!r)
|
||||
break;
|
||||
targetContext->Rectangle(gfxRect(r->x, r->y, r->width, r->height));
|
||||
}
|
||||
rgn->FreeRects(rgnRects);
|
||||
targetContext->Clip();
|
||||
|
||||
// bounding box of the dirty area
|
||||
nsIntRect fullRect;
|
||||
NSRectToGeckoRect(aRect, fullRect);
|
||||
|
||||
// Create the event and dispatch it.
|
||||
nsPaintEvent paintEvent(PR_TRUE, NS_PAINT, mGeckoChild);
|
||||
paintEvent.renderingContext = rc;
|
||||
paintEvent.rect = &fullRect;
|
||||
paintEvent.region = rgn;
|
||||
|
||||
BOOL resetUnifiedToolbar = [self beginMaybeResetUnifiedToolbar:rgn context:aContext];
|
||||
BOOL resetUnifiedToolbar =
|
||||
[self beginMaybeResetUnifiedToolbar:&paintEvent.region context:aContext];
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
PRBool painted = mGeckoChild->DispatchWindowEvent(paintEvent);
|
||||
PRBool painted;
|
||||
{
|
||||
nsBaseWidget::AutoLayerManagerSetup setupLayerManager(mGeckoChild, targetContext);
|
||||
painted = mGeckoChild->DispatchWindowEvent(paintEvent);
|
||||
}
|
||||
|
||||
if (!painted && [self isOpaque]) {
|
||||
// Gecko refused to draw, but we've claimed to be opaque, so we have to
|
||||
// draw something--fill with white.
|
||||
|
@ -2582,21 +2571,11 @@ static BOOL DrawingAtWindowTop(CGContextRef aContext)
|
|||
|
||||
[self endMaybeResetUnifiedToolbar:resetUnifiedToolbar];
|
||||
|
||||
if (!mGeckoChild)
|
||||
return;
|
||||
|
||||
paintEvent.renderingContext = nsnull;
|
||||
paintEvent.region = nsnull;
|
||||
|
||||
targetContext = nsnull;
|
||||
targetSurface = nsnull;
|
||||
|
||||
// note that the cairo surface *MUST* be destroyed at this point,
|
||||
// or bad things will happen (since we can't keep the cgContext around
|
||||
// beyond this drawRect message handler)
|
||||
|
||||
#ifdef DEBUG_UPDATE
|
||||
fprintf (stderr, " window coords: [%d %d %d %d]\n", fullRect.x, fullRect.y, fullRect.width, fullRect.height);
|
||||
fprintf (stderr, "---- update done ----\n");
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -247,6 +247,7 @@ public:
|
|||
virtual void Scroll(const nsIntPoint& aDelta,
|
||||
const nsTArray<nsIntRect>& aDestRects,
|
||||
const nsTArray<Configuration>& aConfigurations);
|
||||
virtual LayerManager* GetLayerManager();
|
||||
NS_IMETHOD DispatchEvent(nsGUIEvent* event, nsEventStatus & aStatus) ;
|
||||
NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, nsIMenuRollup * aMenuRollup,
|
||||
PRBool aDoCapture, PRBool aConsumeRollupEvent);
|
||||
|
|
|
@ -71,6 +71,13 @@
|
|||
#include "gfxPlatform.h"
|
||||
#include "qcms.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
class LayerManager;
|
||||
}
|
||||
}
|
||||
using namespace mozilla::layers;
|
||||
|
||||
// defined in nsAppShell.mm
|
||||
extern nsCocoaAppModalWindowList *gCocoaAppModalWindowList;
|
||||
|
||||
|
@ -908,6 +915,15 @@ nsCocoaWindow::Scroll(const nsIntPoint& aDelta,
|
|||
}
|
||||
}
|
||||
|
||||
LayerManager*
|
||||
nsCocoaWindow::GetLayerManager()
|
||||
{
|
||||
if (mPopupContentView) {
|
||||
return mPopupContentView->GetLayerManager();
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsTransparencyMode nsCocoaWindow::GetTransparencyMode()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
#include "nsGTKToolkit.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsIRegion.h"
|
||||
#include "nsIRollupListener.h"
|
||||
#include "nsIMenuRollup.h"
|
||||
#include "nsIDOMNode.h"
|
||||
|
@ -2333,13 +2332,9 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
|
|||
if (!mGdkWindow || mIsFullyObscured || !mHasMappedToplevel)
|
||||
return FALSE;
|
||||
|
||||
static NS_DEFINE_CID(kRegionCID, NS_REGION_CID);
|
||||
|
||||
nsCOMPtr<nsIRegion> updateRegion = do_CreateInstance(kRegionCID);
|
||||
if (!updateRegion)
|
||||
return FALSE;
|
||||
|
||||
updateRegion->Init();
|
||||
nsPaintEvent event(PR_TRUE, NS_PAINT, this);
|
||||
event.refPoint.x = aEvent->area.x;
|
||||
event.refPoint.y = aEvent->area.y;
|
||||
|
||||
GdkRectangle *rects;
|
||||
gint nrects;
|
||||
|
@ -2360,7 +2355,7 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
|
|||
GdkRectangle *r;
|
||||
GdkRectangle *r_end = rects + nrects;
|
||||
for (r = rects; r < r_end; ++r) {
|
||||
updateRegion->Union(r->x, r->y, r->width, r->height);
|
||||
event.region.Or(event.region, nsIntRect(r->x, r->y, r->width, r->height));
|
||||
LOGDRAW(("\t%d %d %d %d\n", r->x, r->y, r->width, r->height));
|
||||
}
|
||||
|
||||
|
@ -2378,33 +2373,33 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
|
|||
kid->GetBounds(bounds);
|
||||
for (PRUint32 i = 0; i < clipRects.Length(); ++i) {
|
||||
nsIntRect r = clipRects[i] + bounds.TopLeft();
|
||||
updateRegion->Subtract(r.x, r.y, r.width, r.height);
|
||||
event.region.Sub(event.region, r);
|
||||
}
|
||||
}
|
||||
children = children->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (updateRegion->IsEmpty()) {
|
||||
if (event.region.IsEmpty()) {
|
||||
g_free(rects);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef MOZ_DFB
|
||||
nsCOMPtr<nsIRenderingContext> rc = getter_AddRefs(GetRenderingContext());
|
||||
if (NS_UNLIKELY(!rc)) {
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(GetThebesSurface());
|
||||
if (NS_UNLIKELY(!ctx)) {
|
||||
g_free(rects);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// do double-buffering and clipping here
|
||||
nsRefPtr<gfxContext> ctx = rc->ThebesContext();
|
||||
// The context that we'll actually paint into. When we're double-
|
||||
// buffering, this can be different from ctx.
|
||||
nsRefPtr<gfxContext> paintCtx = ctx;
|
||||
|
||||
#ifdef MOZ_DFB
|
||||
gfxPlatformGtk::GetPlatform()->SetGdkDrawable(ctx->OriginalSurface(),
|
||||
GDK_DRAWABLE(mGdkWindow));
|
||||
|
||||
// clip to the update region
|
||||
ctx->Save();
|
||||
ctx->NewPath();
|
||||
for (r = rects; r < r_end; ++r) {
|
||||
ctx->Rectangle(gfxRect(r->x, r->y, r->width, r->height));
|
||||
|
@ -2413,25 +2408,13 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
|
|||
#endif
|
||||
|
||||
#ifdef MOZ_X11
|
||||
nsCOMPtr<nsIRenderingContext> rc = getter_AddRefs(GetRenderingContext());
|
||||
if (NS_UNLIKELY(!rc)) {
|
||||
g_free(rects);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nsIntRect boundsRect;
|
||||
nsIntRect boundsRect = event.region.GetBounds();
|
||||
|
||||
GdkPixmap* bufferPixmap = nsnull;
|
||||
gfxIntSize bufferPixmapSize;
|
||||
|
||||
nsRefPtr<gfxASurface> bufferPixmapSurface;
|
||||
|
||||
updateRegion->GetBoundingBox(&boundsRect.x, &boundsRect.y,
|
||||
&boundsRect.width, &boundsRect.height);
|
||||
|
||||
// do double-buffering and clipping here
|
||||
nsRefPtr<gfxContext> ctx = rc->ThebesContext();
|
||||
ctx->Save();
|
||||
ctx->NewPath();
|
||||
if (translucent) {
|
||||
// Collapse update area to the bounding box. This is so we only have to
|
||||
|
@ -2515,18 +2498,11 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
|
|||
GDK_DRAWABLE(bufferPixmap));
|
||||
|
||||
bufferPixmapSurface->SetDeviceOffset(gfxPoint(-boundsRect.x, -boundsRect.y));
|
||||
nsCOMPtr<nsIRenderingContext> newRC;
|
||||
nsresult rv = GetDeviceContext()->
|
||||
CreateRenderingContextInstance(*getter_AddRefs(newRC));
|
||||
if (NS_FAILED(rv)) {
|
||||
bufferPixmapSurface = nsnull;
|
||||
nsRefPtr<gfxContext> newCtx = new gfxContext(bufferPixmapSurface);
|
||||
if (newCtx) {
|
||||
paintCtx = newCtx.forget();
|
||||
} else {
|
||||
rv = newRC->Init(GetDeviceContext(), bufferPixmapSurface);
|
||||
if (NS_FAILED(rv)) {
|
||||
bufferPixmapSurface = nsnull;
|
||||
} else {
|
||||
rc = newRC;
|
||||
}
|
||||
bufferPixmapSurface = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2544,15 +2520,11 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
|
|||
|
||||
#endif // MOZ_X11
|
||||
|
||||
nsPaintEvent event(PR_TRUE, NS_PAINT, this);
|
||||
event.refPoint.x = aEvent->area.x;
|
||||
event.refPoint.y = aEvent->area.y;
|
||||
event.rect = nsnull;
|
||||
event.region = updateRegion;
|
||||
event.renderingContext = rc;
|
||||
|
||||
nsEventStatus status;
|
||||
DispatchEvent(&event, status);
|
||||
{
|
||||
AutoLayerManagerSetup setupLayerManager(this, paintCtx);
|
||||
DispatchEvent(&event, status);
|
||||
}
|
||||
|
||||
#ifdef MOZ_X11
|
||||
// DispatchEvent can Destroy us (bug 378273), avoid doing any paint
|
||||
|
@ -2598,15 +2570,9 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
|
|||
// if we had to allocate a local pixmap, free it here
|
||||
if (bufferPixmap && bufferPixmap != gBufferPixmap)
|
||||
g_object_unref(G_OBJECT(bufferPixmap));
|
||||
|
||||
ctx->Restore();
|
||||
}
|
||||
#endif // MOZ_X11
|
||||
|
||||
#ifdef MOZ_DFB
|
||||
ctx->Restore();
|
||||
#endif
|
||||
|
||||
g_free(rects);
|
||||
|
||||
// check the return value!
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
./* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:expandtab:shiftwidth=4:tabstop=4:
|
||||
*/
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
|
@ -1012,23 +1012,18 @@ nsWindow::DoPaint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption)
|
|||
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(targetSurface);
|
||||
|
||||
nsCOMPtr<nsIRenderingContext> rc;
|
||||
GetDeviceContext()->CreateRenderingContextInstance(*getter_AddRefs(rc));
|
||||
if (NS_UNLIKELY(!rc))
|
||||
return nsEventStatus_eIgnore;
|
||||
|
||||
rc->Init(GetDeviceContext(), ctx);
|
||||
|
||||
nsPaintEvent event(PR_TRUE, NS_PAINT, this);
|
||||
|
||||
nsIntRect rect(r.x(), r.y(), r.width(), r.height());
|
||||
event.refPoint.x = r.x();
|
||||
event.refPoint.y = r.y();
|
||||
event.rect = ▭
|
||||
event.region = nsnull;
|
||||
event.renderingContext = rc;
|
||||
event.region = nsIntRegion(rect);
|
||||
|
||||
nsEventStatus status = DispatchEvent(&event);
|
||||
nsEventStatus status;
|
||||
{
|
||||
AutoLayerManagerSetup setupLayerManager(this, ctx);
|
||||
status = DispatchEvent(&event);
|
||||
}
|
||||
|
||||
// DispatchEvent can Destroy us (bug 378273), avoid doing any paint
|
||||
// operations below if that happened - it will lead to XError and exit().
|
||||
|
|
|
@ -402,7 +402,7 @@ protected:
|
|||
static void SetupKeyModifiersSequence(nsTArray<KeyPair>* aArray, PRUint32 aModifiers);
|
||||
nsresult SetWindowClipRegion(const nsTArray<nsIntRect>& aRects,
|
||||
PRBool aIntersectWithExisting);
|
||||
nsCOMPtr<nsIRegion> GetRegionToPaint(PRBool aForceFullRepaint,
|
||||
nsIntRegion GetRegionToPaint(PRBool aForceFullRepaint,
|
||||
PAINTSTRUCT ps, HDC aDC);
|
||||
#if !defined(WINCE)
|
||||
static void ActivateOtherWindowHelper(HWND aWnd);
|
||||
|
|
|
@ -133,44 +133,34 @@ IsRenderMode(gfxWindowsPlatform::RenderMode rmode)
|
|||
return gfxWindowsPlatform::GetPlatform()->GetRenderMode() == rmode;
|
||||
}
|
||||
|
||||
void
|
||||
nsWindowGfx::AddRECTToRegion(const RECT& aRect, nsIRegion* aRegion)
|
||||
{
|
||||
aRegion->Union(aRect.left, aRect.top, aRect.right - aRect.left, aRect.bottom - aRect.top);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIRegion>
|
||||
nsIntRegion
|
||||
nsWindowGfx::ConvertHRGNToRegion(HRGN aRgn)
|
||||
{
|
||||
NS_ASSERTION(aRgn, "Don't pass NULL region here");
|
||||
|
||||
nsCOMPtr<nsIRegion> region = do_CreateInstance(kRegionCID);
|
||||
if (!region)
|
||||
return nsnull;
|
||||
|
||||
region->Init();
|
||||
nsIntRegion rgn;
|
||||
|
||||
DWORD size = ::GetRegionData(aRgn, 0, NULL);
|
||||
nsAutoTArray<PRUint8,100> buffer;
|
||||
if (!buffer.SetLength(size))
|
||||
return region.forget();
|
||||
return rgn;
|
||||
|
||||
RGNDATA* data = reinterpret_cast<RGNDATA*>(buffer.Elements());
|
||||
if (!::GetRegionData(aRgn, size, data))
|
||||
return region.forget();
|
||||
return rgn;
|
||||
|
||||
if (data->rdh.nCount > MAX_RECTS_IN_REGION) {
|
||||
AddRECTToRegion(data->rdh.rcBound, region);
|
||||
return region.forget();
|
||||
rgn = ToIntRect(data->rdh.rcBound);
|
||||
return rgn;
|
||||
}
|
||||
|
||||
RECT* rects = reinterpret_cast<RECT*>(data->Buffer);
|
||||
for (PRUint32 i = 0; i < data->rdh.nCount; ++i) {
|
||||
RECT* r = rects + i;
|
||||
AddRECTToRegion(*r, region);
|
||||
rgn.Or(rgn, ToIntRect(*r));
|
||||
}
|
||||
|
||||
return region.forget();
|
||||
return rgn;
|
||||
}
|
||||
|
||||
#ifdef CAIRO_HAS_DDRAW_SURFACE
|
||||
|
@ -253,24 +243,17 @@ void nsWindow::SetUpForPaint(HDC aHDC)
|
|||
// it's abstracted out because Windows XP/Vista/7 handles this for us, but
|
||||
// we need to keep track of it our selves for Windows CE and Windows Mobile
|
||||
|
||||
nsCOMPtr<nsIRegion> nsWindow::GetRegionToPaint(PRBool aForceFullRepaint,
|
||||
PAINTSTRUCT ps, HDC aDC)
|
||||
nsIntRegion nsWindow::GetRegionToPaint(PRBool aForceFullRepaint,
|
||||
PAINTSTRUCT ps, HDC aDC)
|
||||
{
|
||||
HRGN paintRgn = NULL;
|
||||
nsCOMPtr<nsIRegion> paintRgnWin;
|
||||
if (aForceFullRepaint) {
|
||||
RECT paintRect;
|
||||
::GetClientRect(mWnd, &paintRect);
|
||||
paintRgn = ::CreateRectRgn(paintRect.left, paintRect.top,
|
||||
paintRect.right, paintRect.bottom);
|
||||
if (paintRgn) {
|
||||
paintRgnWin = nsWindowGfx::ConvertHRGNToRegion(paintRgn);
|
||||
::DeleteObject(paintRgn);
|
||||
return paintRgnWin;
|
||||
}
|
||||
return nsIntRegion(nsWindowGfx::ToIntRect(paintRect));
|
||||
}
|
||||
|
||||
#ifndef WINCE
|
||||
paintRgn = ::CreateRectRgn(0, 0, 0, 0);
|
||||
HRGN paintRgn = ::CreateRectRgn(0, 0, 0, 0);
|
||||
if (paintRgn != NULL) {
|
||||
int result = GetRandomRgn(aDC, paintRgn, SYSRGN);
|
||||
if (result == 1) {
|
||||
|
@ -278,12 +261,13 @@ nsCOMPtr<nsIRegion> nsWindow::GetRegionToPaint(PRBool aForceFullRepaint,
|
|||
::MapWindowPoints(NULL, mWnd, &pt, 1);
|
||||
::OffsetRgn(paintRgn, pt.x, pt.y);
|
||||
}
|
||||
paintRgnWin = nsWindowGfx::ConvertHRGNToRegion(paintRgn);
|
||||
nsIntRegion rgn(nsWindowGfx::ConvertHRGNToRegion(paintRgn));
|
||||
::DeleteObject(paintRgn);
|
||||
return rgn;
|
||||
}
|
||||
#else
|
||||
# ifdef WINCE_WINDOWS_MOBILE
|
||||
paintRgn = ::CreateRectRgn(0, 0, 0, 0);
|
||||
HRGN paintRgn = ::CreateRectRgn(0, 0, 0, 0);
|
||||
if (paintRgn != NULL) {
|
||||
int result = GetUpdateRgn(mWnd, paintRgn, FALSE);
|
||||
if (result == 1) {
|
||||
|
@ -291,18 +275,13 @@ nsCOMPtr<nsIRegion> nsWindow::GetRegionToPaint(PRBool aForceFullRepaint,
|
|||
::MapWindowPoints(NULL, mWnd, &pt, 1);
|
||||
::OffsetRgn(paintRgn, pt.x, pt.y);
|
||||
}
|
||||
paintRgnWin = nsWindowGfx::ConvertHRGNToRegion(paintRgn);
|
||||
nsIntRegion rgn(nsWindowGfx::ConvertHRGNToRegion(paintRgn));
|
||||
::DeleteObject(paintRgn);
|
||||
return rgn;
|
||||
}
|
||||
# endif
|
||||
paintRgn = ::CreateRectRgn(ps.rcPaint.left, ps.rcPaint.top,
|
||||
ps.rcPaint.right, ps.rcPaint.bottom);
|
||||
if (paintRgn) {
|
||||
paintRgnWin = nsWindowGfx::ConvertHRGNToRegion(paintRgn);
|
||||
::DeleteObject(paintRgn);
|
||||
}
|
||||
#endif
|
||||
return paintRgnWin;
|
||||
return nsIntRegion(nsWindowGfx::ToIntRect(ps.rcPaint));
|
||||
}
|
||||
|
||||
#define WORDSSIZE(x) ((x).width * (x).height)
|
||||
|
@ -416,25 +395,19 @@ PRBool nsWindow::OnPaint(HDC aDC)
|
|||
mPaintDC = hDC;
|
||||
}
|
||||
|
||||
// generate the event and call the event callback
|
||||
nsPaintEvent event(PR_TRUE, NS_PAINT, this);
|
||||
InitEvent(event);
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
PRBool forceRepaint = aDC || (eTransparencyTransparent == mTransparencyMode);
|
||||
#else
|
||||
PRBool forceRepaint = NULL != aDC;
|
||||
#endif
|
||||
nsCOMPtr<nsIRegion> paintRgnWin = GetRegionToPaint(forceRepaint, ps, hDC);
|
||||
event.region = GetRegionToPaint(forceRepaint, ps, hDC);
|
||||
|
||||
if (paintRgnWin &&
|
||||
!paintRgnWin->IsEmpty() &&
|
||||
mEventCallback)
|
||||
if (!event.region.IsEmpty() && mEventCallback)
|
||||
{
|
||||
// generate the event and call the event callback
|
||||
nsPaintEvent event(PR_TRUE, NS_PAINT, this);
|
||||
|
||||
InitEvent(event);
|
||||
|
||||
event.region = paintRgnWin;
|
||||
event.rect = nsnull;
|
||||
|
||||
// Should probably pass in a real region here, using GetRandomRgn
|
||||
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/clipping_4q0e.asp
|
||||
|
||||
|
@ -573,23 +546,11 @@ DDRAW_FAILED:
|
|||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRenderingContext> rc;
|
||||
nsresult rv = mContext->CreateRenderingContextInstance (*getter_AddRefs(rc));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CreateRenderingContextInstance failed");
|
||||
return PR_FALSE;
|
||||
{
|
||||
AutoLayerManagerSetup setupLayerManager(this, thebesContext);
|
||||
result = DispatchWindowEvent(&event, eventStatus);
|
||||
}
|
||||
|
||||
rv = rc->Init(mContext, thebesContext);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("RC::Init failed");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
event.renderingContext = rc;
|
||||
result = DispatchWindowEvent(&event, eventStatus);
|
||||
event.renderingContext = nsnull;
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
if (IsRenderMode(gfxWindowsPlatform::RENDER_GDI) &&
|
||||
eTransparencyTransparent == mTransparencyMode) {
|
||||
|
@ -957,9 +918,7 @@ PRBool nsWindow::OnPaintImageDDraw16()
|
|||
gfxIntSize surfaceSize;
|
||||
nsRefPtr<gfxImageSurface> targetSurfaceImage;
|
||||
nsRefPtr<gfxContext> thebesContext;
|
||||
nsCOMPtr<nsIRenderingContext> rc;
|
||||
nsEventStatus eventStatus = nsEventStatus_eIgnore;
|
||||
PRInt32 brx, bry, brw, brh;
|
||||
gfxIntSize newSize;
|
||||
newSize.height = GetSystemMetrics(SM_CYSCREEN);
|
||||
newSize.width = GetSystemMetrics(SM_CXSCREEN);
|
||||
|
@ -967,18 +926,15 @@ PRBool nsWindow::OnPaintImageDDraw16()
|
|||
|
||||
HDC hDC = ::BeginPaint(mWnd, &ps);
|
||||
mPaintDC = hDC;
|
||||
nsCOMPtr<nsIRegion> paintRgnWin = GetRegionToPaint(PR_FALSE, ps, hDC);
|
||||
nsIntRegion paintRgn = GetRegionToPaint(PR_FALSE, ps, hDC);
|
||||
|
||||
if (!paintRgnWin || paintRgnWin->IsEmpty() || !mEventCallback) {
|
||||
if (paintRgn.IsEmpty() || !mEventCallback) {
|
||||
result = PR_TRUE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
InitEvent(event);
|
||||
|
||||
event.region = paintRgnWin;
|
||||
event.rect = nsnull;
|
||||
|
||||
if (!glpDD) {
|
||||
if (!nsWindowGfx::InitDDraw()) {
|
||||
NS_WARNING("DirectDraw init failed. Giving up.");
|
||||
|
@ -1014,7 +970,10 @@ PRBool nsWindow::OnPaintImageDDraw16()
|
|||
}
|
||||
}
|
||||
|
||||
paintRgnWin->GetBoundingBox(&brx, &bry, &brw, &brh);
|
||||
PRInt32 brx = paintRgn.GetBounds().x;
|
||||
PRInt32 bry = paintRgn.GetBounds().y;
|
||||
PRInt32 brw = paintRgn.GetBounds().width;
|
||||
PRInt32 brh = paintRgn.GetBounds().height;
|
||||
surfaceSize = gfxIntSize(brw, brh);
|
||||
|
||||
if (!EnsureSharedSurfaceSize(surfaceSize))
|
||||
|
@ -1034,25 +993,15 @@ PRBool nsWindow::OnPaintImageDDraw16()
|
|||
thebesContext->SetFlag(gfxContext::FLAG_DESTINED_FOR_SCREEN);
|
||||
thebesContext->SetFlag(gfxContext::FLAG_SIMPLIFY_OPERATORS);
|
||||
|
||||
nsresult rv = mContext->CreateRenderingContextInstance (*getter_AddRefs(rc));
|
||||
if (NS_FAILED(rv))
|
||||
goto cleanup;
|
||||
{
|
||||
AutoLayerManagerSetup setupLayerManager(this, thebesContext);
|
||||
event.region = paintRgn;
|
||||
result = DispatchWindowEvent(&event, eventStatus);
|
||||
}
|
||||
|
||||
rv = rc->Init(mContext, thebesContext);
|
||||
if (NS_FAILED(rv))
|
||||
goto cleanup;
|
||||
|
||||
event.renderingContext = rc;
|
||||
PRBool res = DispatchWindowEvent(&event, eventStatus);
|
||||
event.renderingContext = nsnull;
|
||||
|
||||
if (!res && eventStatus == nsEventStatus_eConsumeNoDefault)
|
||||
if (!result && eventStatus == nsEventStatus_eConsumeNoDefault)
|
||||
goto cleanup;
|
||||
|
||||
nsRegionRectSet *rects = nsnull;
|
||||
RECT r;
|
||||
paintRgnWin->GetRects(&rects);
|
||||
|
||||
HRESULT hr = glpDDSecondary->Lock(0, &gDDSDSecondary, DDLOCK_WAITNOTBUSY | DDLOCK_DISCARD, 0);
|
||||
if (FAILED(hr))
|
||||
goto cleanup;
|
||||
|
@ -1070,14 +1019,15 @@ PRBool nsWindow::OnPaintImageDDraw16()
|
|||
gDDSDSecondary.dwWidth * 2);
|
||||
|
||||
|
||||
for (unsigned int i = 0; i < rects->mNumRects; i++) {
|
||||
const nsIntRect* r;
|
||||
for (nsIntRegionRectIterator iter(paintRgn);
|
||||
(r = iter.Next()) != nsnull;) {
|
||||
pixman_image_composite(PIXMAN_OP_SRC, srcPixmanImage, NULL, dstPixmanImage,
|
||||
rects->mRects[i].x - brx, rects->mRects[i].y - bry,
|
||||
0, 0,
|
||||
rects->mRects[i].x, rects->mRects[i].y,
|
||||
rects->mRects[i].width, rects->mRects[i].height);
|
||||
|
||||
}
|
||||
r->x - brx, r->y - bry,
|
||||
0, 0,
|
||||
r->x, r->y,
|
||||
r->width, r->height);
|
||||
}
|
||||
|
||||
pixman_image_unref(dstPixmanImage);
|
||||
pixman_image_unref(srcPixmanImage);
|
||||
|
@ -1090,15 +1040,13 @@ PRBool nsWindow::OnPaintImageDDraw16()
|
|||
if (FAILED(hr))
|
||||
goto cleanup;
|
||||
|
||||
for (unsigned int i = 0; i < rects->mNumRects; i++) {
|
||||
r.left = rects->mRects[i].x;
|
||||
r.top = rects->mRects[i].y;
|
||||
r.right = rects->mRects[i].width + rects->mRects[i].x;
|
||||
r.bottom = rects->mRects[i].height + rects->mRects[i].y;
|
||||
RECT renderRect = r;
|
||||
for (nsIntRegionRectIterator iter(paintRgn);
|
||||
(r = iter.Next()) != nsnull;) {
|
||||
RECT wr = { r->x, r->y, r->XMost(), r->YMost() };
|
||||
RECT renderRect = wr;
|
||||
SetLastError(0); // See http://msdn.microsoft.com/en-us/library/dd145046%28VS.85%29.aspx
|
||||
MapWindowPoints(mWnd, 0, (LPPOINT)&renderRect, 2);
|
||||
hr = glpDDPrimary->Blt(&renderRect, glpDDSecondary, &r, 0, NULL);
|
||||
hr = glpDDPrimary->Blt(&renderRect, glpDDSecondary, &wr, 0, NULL);
|
||||
if (FAILED(hr)) {
|
||||
NS_ERROR("this blt should never fail!");
|
||||
printf("#### %s blt failed: %08lx", __FUNCTION__, hr);
|
||||
|
|
|
@ -56,8 +56,13 @@
|
|||
|
||||
class nsWindowGfx {
|
||||
public:
|
||||
static void AddRECTToRegion(const RECT& aRect, nsIRegion* aRegion);
|
||||
static already_AddRefed<nsIRegion> ConvertHRGNToRegion(HRGN aRgn);
|
||||
static nsIntRect ToIntRect(const RECT& aRect)
|
||||
{
|
||||
return nsIntRect(aRect.left, aRect.top,
|
||||
aRect.right - aRect.left, aRect.bottom - aRect.top);
|
||||
}
|
||||
|
||||
static nsIntRegion ConvertHRGNToRegion(HRGN aRgn);
|
||||
static void OnSettingsChangeGfx(WPARAM wParam);
|
||||
|
||||
#if defined(CAIRO_HAS_DDRAW_SURFACE)
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "nsIServiceManager.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch2.h"
|
||||
#include "BasicLayers.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "nsIObserver.h"
|
||||
|
@ -62,6 +63,8 @@ static PRBool debug_InSecureKeyboardInputMode = PR_FALSE;
|
|||
static PRInt32 gNumWidgets;
|
||||
#endif
|
||||
|
||||
using namespace mozilla::layers;
|
||||
|
||||
nsIContent* nsBaseWidget::mLastRollup = nsnull;
|
||||
|
||||
// nsBaseWidget
|
||||
|
@ -629,6 +632,34 @@ NS_IMETHODIMP nsBaseWidget::MakeFullScreen(PRBool aFullScreen)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsBaseWidget::AutoLayerManagerSetup::AutoLayerManagerSetup(
|
||||
nsBaseWidget* aWidget, gfxContext* aTarget)
|
||||
: mWidget(aWidget)
|
||||
{
|
||||
BasicLayerManager* manager =
|
||||
static_cast<BasicLayerManager*>(mWidget->GetLayerManager());
|
||||
if (manager) {
|
||||
manager->SetDefaultTarget(aTarget);
|
||||
}
|
||||
}
|
||||
|
||||
nsBaseWidget::AutoLayerManagerSetup::~AutoLayerManagerSetup()
|
||||
{
|
||||
BasicLayerManager* manager =
|
||||
static_cast<BasicLayerManager*>(mWidget->GetLayerManager());
|
||||
if (manager) {
|
||||
manager->SetDefaultTarget(nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
LayerManager* nsBaseWidget::GetLayerManager()
|
||||
{
|
||||
if (!mLayerManager) {
|
||||
mLayerManager = new BasicLayerManager(nsnull);
|
||||
}
|
||||
return mLayerManager;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// Create a rendering context from this nsBaseWidget
|
||||
|
@ -1331,20 +1362,6 @@ nsBaseWidget::debug_DumpPaintEvent(FILE * aFileOut,
|
|||
aWidgetName.get(),
|
||||
(void *) aWindowID);
|
||||
|
||||
if (aPaintEvent->rect)
|
||||
{
|
||||
fprintf(aFileOut,
|
||||
"%3d,%-3d %3d,%-3d",
|
||||
aPaintEvent->rect->x,
|
||||
aPaintEvent->rect->y,
|
||||
aPaintEvent->rect->width,
|
||||
aPaintEvent->rect->height);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(aFileOut,"none");
|
||||
}
|
||||
|
||||
fprintf(aFileOut,"\n");
|
||||
}
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
|
||||
class nsIContent;
|
||||
class nsAutoRollup;
|
||||
class gfxContext;
|
||||
|
||||
/**
|
||||
* Common widget implementation used as base class for native
|
||||
|
@ -107,7 +108,8 @@ public:
|
|||
NS_IMETHOD MakeFullScreen(PRBool aFullScreen);
|
||||
virtual nsIRenderingContext* GetRenderingContext();
|
||||
virtual nsIDeviceContext* GetDeviceContext();
|
||||
virtual nsIToolkit* GetToolkit();
|
||||
virtual nsIToolkit* GetToolkit();
|
||||
virtual LayerManager* GetLayerManager();
|
||||
virtual gfxASurface* GetThebesSurface();
|
||||
NS_IMETHOD SetModal(PRBool aModal);
|
||||
NS_IMETHOD SetWindowClass(const nsAString& xulWinType);
|
||||
|
@ -141,6 +143,20 @@ public:
|
|||
NS_IMETHOD OnDefaultButtonLoaded(const nsIntRect &aButtonRect) { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
NS_IMETHOD OverrideSystemMouseScrollSpeed(PRInt32 aOriginalDelta, PRBool aIsHorizontal, PRInt32 &aOverriddenDelta);
|
||||
|
||||
/**
|
||||
* Use this when GetLayerManager() returns a BasicLayerManager
|
||||
* (nsBaseWidget::GetLayerManager() does). This sets up the widget's
|
||||
* layer manager to temporarily render into aTarget.
|
||||
*/
|
||||
class AutoLayerManagerSetup {
|
||||
public:
|
||||
AutoLayerManagerSetup(nsBaseWidget* aWidget, gfxContext* aTarget);
|
||||
~AutoLayerManagerSetup();
|
||||
private:
|
||||
nsBaseWidget* mWidget;
|
||||
};
|
||||
friend class AutoLayerManagerSetup;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void ResolveIconName(const nsAString &aIconName,
|
||||
|
@ -179,8 +195,9 @@ protected:
|
|||
protected:
|
||||
void* mClientData;
|
||||
EVENT_CALLBACK mEventCallback;
|
||||
nsIDeviceContext *mContext;
|
||||
nsIToolkit *mToolkit;
|
||||
nsIDeviceContext* mContext;
|
||||
nsIToolkit* mToolkit;
|
||||
nsRefPtr<LayerManager> mLayerManager;
|
||||
nscolor mBackground;
|
||||
nscolor mForeground;
|
||||
nsCursor mCursor;
|
||||
|
|
Загрузка…
Ссылка в новой задаче