Bug 962786 - Convert nsDragService to use Moz2D. r=roc

This commit is contained in:
Matt Woodrow 2014-01-29 13:10:33 +13:00
Родитель 90d3ebe5fd
Коммит d8146d0c04
11 изменённых файлов: 141 добавлений и 117 удалений

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

@ -103,9 +103,13 @@ class Touch;
class ShadowRoot; class ShadowRoot;
} // namespace dom } // namespace dom
namespace layers{ namespace layers {
class LayerManager; class LayerManager;
} // namespace layers } // namespace layers
namespace gfx {
class SourceSurface;
} // namespace gfx
} // namespace mozilla } // namespace mozilla
// Flags to pass to SetCapturingContent // Flags to pass to SetCapturingContent
@ -128,11 +132,10 @@ typedef struct CapturingContentInfo {
nsIContent* mContent; nsIContent* mContent;
} CapturingContentInfo; } CapturingContentInfo;
//bccc1c01-5123-4f49-9572-c0bf506b6418
// db8d5e1e-6392-4ec1-9a29-18ee2ec0889b
#define NS_IPRESSHELL_IID \ #define NS_IPRESSHELL_IID \
{ 0xdb8d5e1e, 0x6392, 0x4ec1, \ { 0xbccc1c01, 0x5123, 0x4f49, \
{0x9a, 0x29, 0x18, 0xee, 0x2e, 0xc0, 0x88, 0x9b}} {0x95, 0x72, 0xc0, 0xbf, 0x50, 0x6b, 0x64, 0x18}}
// debug VerifyReflow flags // debug VerifyReflow flags
#define VERIFY_REFLOW_ON 0x01 #define VERIFY_REFLOW_ON 0x01
@ -178,6 +181,7 @@ class nsIPresShell : public nsIPresShell_base
{ {
protected: protected:
typedef mozilla::layers::LayerManager LayerManager; typedef mozilla::layers::LayerManager LayerManager;
typedef mozilla::gfx::SourceSurface SourceSurface;
enum eRenderFlag { enum eRenderFlag {
STATE_IGNORING_VIEWPORT_SCROLLING = 0x1, STATE_IGNORING_VIEWPORT_SCROLLING = 0x1,
@ -1031,10 +1035,11 @@ public:
* edge of the presshell area. The aPoint, aScreenRect and aSurface * edge of the presshell area. The aPoint, aScreenRect and aSurface
* arguments function in a similar manner as RenderSelection. * arguments function in a similar manner as RenderSelection.
*/ */
virtual already_AddRefed<gfxASurface> RenderNode(nsIDOMNode* aNode, virtual mozilla::TemporaryRef<SourceSurface>
nsIntRegion* aRegion, RenderNode(nsIDOMNode* aNode,
nsIntPoint& aPoint, nsIntRegion* aRegion,
nsIntRect* aScreenRect) = 0; nsIntPoint& aPoint,
nsIntRect* aScreenRect) = 0;
/** /**
* Renders a selection to a surface and returns it. This method is primarily * Renders a selection to a surface and returns it. This method is primarily
@ -1051,9 +1056,10 @@ public:
* the original. When scaling does not occur, the mouse point isn't used * the original. When scaling does not occur, the mouse point isn't used
* as the position can be determined from the displayed frames. * as the position can be determined from the displayed frames.
*/ */
virtual already_AddRefed<gfxASurface> RenderSelection(nsISelection* aSelection, virtual mozilla::TemporaryRef<SourceSurface>
nsIntPoint& aPoint, RenderSelection(nsISelection* aSelection,
nsIntRect* aScreenRect) = 0; nsIntPoint& aPoint,
nsIntRect* aScreenRect) = 0;
void AddWeakFrameInternal(nsWeakFrame* aWeakFrame); void AddWeakFrameInternal(nsWeakFrame* aWeakFrame);
virtual void AddWeakFrameExternal(nsWeakFrame* aWeakFrame); virtual void AddWeakFrameExternal(nsWeakFrame* aWeakFrame);

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

@ -165,6 +165,7 @@
#include "nsIDOMHTMLElement.h" #include "nsIDOMHTMLElement.h"
#include "nsIDragSession.h" #include "nsIDragSession.h"
#include "nsIFrameInlines.h" #include "nsIFrameInlines.h"
#include "mozilla/gfx/2D.h"
#ifdef ANDROID #ifdef ANDROID
#include "nsIDocShellTreeOwner.h" #include "nsIDocShellTreeOwner.h"
@ -177,6 +178,7 @@ using namespace mozilla;
using namespace mozilla::css; using namespace mozilla::css;
using namespace mozilla::dom; using namespace mozilla::dom;
using namespace mozilla::layers; using namespace mozilla::layers;
using namespace mozilla::gfx;
CapturingContentInfo nsIPresShell::gCaptureInfo = CapturingContentInfo nsIPresShell::gCaptureInfo =
{ false /* mAllowed */, false /* mPointerLock */, false /* mRetargetToElement */, { false /* mAllowed */, false /* mPointerLock */, false /* mRetargetToElement */,
@ -4809,7 +4811,7 @@ PresShell::CreateRangePaintInfo(nsIDOMRange* aRange,
return info; return info;
} }
already_AddRefed<gfxASurface> TemporaryRef<SourceSurface>
PresShell::PaintRangePaintInfo(nsTArray<nsAutoPtr<RangePaintInfo> >* aItems, PresShell::PaintRangePaintInfo(nsTArray<nsAutoPtr<RangePaintInfo> >* aItems,
nsISelection* aSelection, nsISelection* aSelection,
nsIntRegion* aRegion, nsIntRegion* aRegion,
@ -4878,8 +4880,14 @@ PresShell::PaintRangePaintInfo(nsTArray<nsAutoPtr<RangePaintInfo> >* aItems,
context.Rectangle(gfxRect(0, 0, pixelArea.width, pixelArea.height)); context.Rectangle(gfxRect(0, 0, pixelArea.width, pixelArea.height));
context.Fill(); context.Fill();
RefPtr<DrawTarget> dt =
gfxPlatform::GetPlatform()->
CreateDrawTargetForSurface(surface, gfx::IntSize(pixelArea.width, pixelArea.height));
nsRefPtr<gfxContext> ctx = new gfxContext(dt);
nsRefPtr<nsRenderingContext> rc = new nsRenderingContext(); nsRefPtr<nsRenderingContext> rc = new nsRenderingContext();
rc->Init(deviceContext, surface); rc->Init(deviceContext, ctx);
if (aRegion) { if (aRegion) {
// Convert aRegion from CSS pixels to dev pixels // Convert aRegion from CSS pixels to dev pixels
@ -4927,10 +4935,10 @@ PresShell::PaintRangePaintInfo(nsTArray<nsAutoPtr<RangePaintInfo> >* aItems,
// restore the old selection display state // restore the old selection display state
frameSelection->SetDisplaySelection(oldDisplaySelection); frameSelection->SetDisplaySelection(oldDisplaySelection);
return surface.forget(); return dt->Snapshot();
} }
already_AddRefed<gfxASurface> TemporaryRef<SourceSurface>
PresShell::RenderNode(nsIDOMNode* aNode, PresShell::RenderNode(nsIDOMNode* aNode,
nsIntRegion* aRegion, nsIntRegion* aRegion,
nsIntPoint& aPoint, nsIntPoint& aPoint,
@ -4976,7 +4984,7 @@ PresShell::RenderNode(nsIDOMNode* aNode,
aScreenRect); aScreenRect);
} }
already_AddRefed<gfxASurface> TemporaryRef<SourceSurface>
PresShell::RenderSelection(nsISelection* aSelection, PresShell::RenderSelection(nsISelection* aSelection,
nsIntPoint& aPoint, nsIntPoint& aPoint,
nsIntRect* aScreenRect) nsIntRect* aScreenRect)

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

@ -162,14 +162,16 @@ public:
nscolor aBackgroundColor, nscolor aBackgroundColor,
gfxContext* aThebesContext) MOZ_OVERRIDE; gfxContext* aThebesContext) MOZ_OVERRIDE;
virtual already_AddRefed<gfxASurface> RenderNode(nsIDOMNode* aNode, virtual mozilla::TemporaryRef<SourceSurface>
nsIntRegion* aRegion, RenderNode(nsIDOMNode* aNode,
nsIntPoint& aPoint, nsIntRegion* aRegion,
nsIntRect* aScreenRect) MOZ_OVERRIDE; nsIntPoint& aPoint,
nsIntRect* aScreenRect) MOZ_OVERRIDE;
virtual already_AddRefed<gfxASurface> RenderSelection(nsISelection* aSelection, virtual mozilla::TemporaryRef<SourceSurface>
nsIntPoint& aPoint, RenderSelection(nsISelection* aSelection,
nsIntRect* aScreenRect) MOZ_OVERRIDE; nsIntPoint& aPoint,
nsIntRect* aScreenRect) MOZ_OVERRIDE;
virtual already_AddRefed<nsPIDOMWindow> GetRootWindow() MOZ_OVERRIDE; virtual already_AddRefed<nsPIDOMWindow> GetRootWindow() MOZ_OVERRIDE;
@ -502,7 +504,7 @@ protected:
* aScreenRect - [out] set to the area of the screen the painted area should * aScreenRect - [out] set to the area of the screen the painted area should
* be displayed at * be displayed at
*/ */
already_AddRefed<gfxASurface> mozilla::TemporaryRef<SourceSurface>
PaintRangePaintInfo(nsTArray<nsAutoPtr<RangePaintInfo> >* aItems, PaintRangePaintInfo(nsTArray<nsAutoPtr<RangePaintInfo> >* aItems,
nsISelection* aSelection, nsISelection* aSelection,
nsIntRegion* aRegion, nsIntRegion* aRegion,

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

@ -30,6 +30,11 @@
#include "gfxASurface.h" #include "gfxASurface.h"
#include "gfxContext.h" #include "gfxContext.h"
#include "nsCocoaUtils.h" #include "nsCocoaUtils.h"
#include "mozilla/gfx/2D.h"
#include "gfxPlatform.h"
using namespace mozilla;
using namespace mozilla::gfx;
#ifdef PR_LOGGING #ifdef PR_LOGGING
extern PRLogModuleInfo* sCocoaLog; extern PRLogModuleInfo* sCocoaLog;
@ -141,12 +146,12 @@ nsDragService::ConstructDragImage(nsIDOMNode* aDOMNode,
CGFloat scaleFactor = nsCocoaUtils::GetBackingScaleFactor(gLastDragView); CGFloat scaleFactor = nsCocoaUtils::GetBackingScaleFactor(gLastDragView);
nsRefPtr<gfxASurface> surface; RefPtr<SourceSurface> surface;
nsPresContext* pc; nsPresContext* pc;
nsresult rv = DrawDrag(aDOMNode, aRegion, nsresult rv = DrawDrag(aDOMNode, aRegion,
NSToIntRound(screenPoint.x), NSToIntRound(screenPoint.x),
NSToIntRound(screenPoint.y), NSToIntRound(screenPoint.y),
aDragRect, getter_AddRefs(surface), &pc); aDragRect, &surface, &pc);
if (!aDragRect->width || !aDragRect->height) { if (!aDragRect->width || !aDragRect->height) {
// just use some suitable defaults // just use some suitable defaults
int32_t size = nsCocoaUtils::CocoaPointsToDevPixels(20, scaleFactor); int32_t size = nsCocoaUtils::CocoaPointsToDevPixels(20, scaleFactor);
@ -166,13 +171,15 @@ nsDragService::ConstructDragImage(nsIDOMNode* aDOMNode,
if (!imgSurface) if (!imgSurface)
return nil; return nil;
nsRefPtr<gfxContext> context = new gfxContext(imgSurface); RefPtr<DrawTarget> dt =
if (!context) gfxPlatform::GetPlatform()->
CreateDrawTargetForSurface(imgSurface, IntSize(width, height));
if (!dt)
return nil; return nil;
context->SetOperator(gfxContext::OPERATOR_SOURCE); dt->FillRect(gfx::Rect(0, 0, width, height),
context->SetSource(surface); SurfacePattern(surface, ExtendMode::CLAMP),
context->Paint(); DrawOptions(1.0f, CompositionOp::OP_SOURCE));
uint32_t* imageData = (uint32_t*)imgSurface->Data(); uint32_t* imageData = (uint32_t*)imgSurface->Data();
int32_t stride = imgSurface->Stride(); int32_t stride = imgSurface->Stride();

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

@ -36,6 +36,11 @@
#include "nsViewManager.h" #include "nsViewManager.h"
#include "nsIFrame.h" #include "nsIFrame.h"
#include "nsGtkUtils.h" #include "nsGtkUtils.h"
#include "mozilla/gfx/2D.h"
#include "gfxPlatform.h"
using namespace mozilla;
using namespace mozilla::gfx;
// This sets how opaque the drag image is // This sets how opaque the drag image is
#define DRAG_IMAGE_ALPHA_LEVEL 0.5 #define DRAG_IMAGE_ALPHA_LEVEL 0.5
@ -390,11 +395,11 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode,
} }
bool bool
nsDragService::SetAlphaPixmap(gfxASurface *aSurface, nsDragService::SetAlphaPixmap(SourceSurface *aSurface,
GdkDragContext *aContext, GdkDragContext *aContext,
int32_t aXOffset, int32_t aXOffset,
int32_t aYOffset, int32_t aYOffset,
const nsIntRect& dragRect) const nsIntRect& dragRect)
{ {
#if (MOZ_WIDGET_GTK == 2) #if (MOZ_WIDGET_GTK == 2)
GdkScreen* screen = gtk_widget_get_screen(mHiddenWidget); GdkScreen* screen = gtk_widget_get_screen(mHiddenWidget);
@ -422,16 +427,21 @@ nsDragService::SetAlphaPixmap(gfxASurface *aSurface,
if (!xPixmapSurface) if (!xPixmapSurface)
return false; return false;
nsRefPtr<gfxContext> xPixmapCtx = new gfxContext(xPixmapSurface); RefPtr<DrawTarget> dt =
gfxPlatform::GetPlatform()->
CreateDrawTargetForSurface(xPixmapSurface, IntSize(dragRect.width, dragRect.height));
if (!dt)
return false;
// Clear it... // Clear it...
xPixmapCtx->SetOperator(gfxContext::OPERATOR_CLEAR); dt->ClearRect(Rect(0, 0, dragRect.width, dragRect.height));
xPixmapCtx->Paint();
// ...and paint the drag image with translucency // ...and paint the drag image with translucency
xPixmapCtx->SetOperator(gfxContext::OPERATOR_SOURCE); dt->DrawSurface(aSurface,
xPixmapCtx->SetSource(aSurface); Rect(0, 0, dragRect.width, dragRect.height),
xPixmapCtx->Paint(DRAG_IMAGE_ALPHA_LEVEL); Rect(0, 0, dragRect.width, dragRect.height),
DrawSurfaceOptions(),
DrawOptions(DRAG_IMAGE_ALPHA_LEVEL, CompositionOp::OP_SOURCE));
// The drag transaction addrefs the pixmap, so we can just unref it from us here // The drag transaction addrefs the pixmap, so we can just unref it from us here
gtk_drag_set_icon_pixmap(aContext, alphaColormap, pixmap, nullptr, gtk_drag_set_icon_pixmap(aContext, alphaColormap, pixmap, nullptr,
@ -1565,9 +1575,9 @@ void nsDragService::SetDragIcon(GdkDragContext* aContext)
nsIntRect dragRect; nsIntRect dragRect;
nsPresContext* pc; nsPresContext* pc;
nsRefPtr<gfxASurface> surface; RefPtr<SourceSurface> surface;
DrawDrag(mSourceNode, mSourceRegion, mScreenX, mScreenY, DrawDrag(mSourceNode, mSourceRegion, mScreenX, mScreenY,
&dragRect, getter_AddRefs(surface), &pc); &dragRect, &surface, &pc);
if (!pc) if (!pc)
return; return;
@ -1597,7 +1607,7 @@ void nsDragService::SetDragIcon(GdkDragContext* aContext)
else if (surface) { else if (surface) {
if (!SetAlphaPixmap(surface, aContext, offsetX, offsetY, dragRect)) { if (!SetAlphaPixmap(surface, aContext, offsetX, offsetY, dragRect)) {
GdkPixbuf* dragPixbuf = GdkPixbuf* dragPixbuf =
nsImageToPixbuf::SurfaceToPixbuf(surface, dragRect.width, dragRect.height); nsImageToPixbuf::SourceSurfaceToPixbuf(surface, dragRect.width, dragrect.height);
if (dragPixbuf) { if (dragPixbuf) {
gtk_drag_set_icon_pixbuf(aContext, dragPixbuf, offsetX, offsetY); gtk_drag_set_icon_pixbuf(aContext, dragPixbuf, offsetX, offsetY);
g_object_unref(dragPixbuf); g_object_unref(dragPixbuf);

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

@ -14,6 +14,12 @@
class nsWindow; class nsWindow;
namespace mozilla {
namespace gfx {
class SourceSurface;
}
}
#ifndef HAVE_NSGOBJECTREFTRAITS #ifndef HAVE_NSGOBJECTREFTRAITS
#define HAVE_NSGOBJECTREFTRAITS #define HAVE_NSGOBJECTREFTRAITS
template <class T> template <class T>
@ -183,11 +189,11 @@ private:
// attempts to create a semi-transparent drag image. Returns TRUE if // attempts to create a semi-transparent drag image. Returns TRUE if
// successful, FALSE if not // successful, FALSE if not
bool SetAlphaPixmap(gfxASurface *aPixbuf, bool SetAlphaPixmap(SourceSurface *aPixbuf,
GdkDragContext *aContext, GdkDragContext *aContext,
int32_t aXOffset, int32_t aXOffset,
int32_t aYOffset, int32_t aYOffset,
const nsIntRect &dragRect); const nsIntRect &dragRect);
gboolean Schedule(DragTask aTask, nsWindow *aWindow, gboolean Schedule(DragTask aTask, nsWindow *aWindow,
GdkDragContext *aDragContext, GdkDragContext *aDragContext,

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

@ -129,37 +129,3 @@ nsImageToPixbuf::SourceSurfaceToPixbuf(SourceSurface* aSurface,
return pixbuf; return pixbuf;
} }
GdkPixbuf*
nsImageToPixbuf::SurfaceToPixbuf(gfxASurface* aSurface, int32_t aWidth, int32_t aHeight)
{
if (aSurface->CairoStatus()) {
NS_ERROR("invalid surface");
return nullptr;
}
nsRefPtr<gfxImageSurface> imgSurface;
if (aSurface->GetType() == gfxSurfaceType::Image) {
imgSurface = static_cast<gfxImageSurface*>
(static_cast<gfxASurface*>(aSurface));
} else {
imgSurface = new gfxImageSurface(gfxIntSize(aWidth, aHeight),
gfxImageFormat::ARGB32);
if (!imgSurface)
return nullptr;
nsRefPtr<gfxContext> context = new gfxContext(imgSurface);
if (!context)
return nullptr;
context->SetOperator(gfxContext::OPERATOR_SOURCE);
context->SetSource(aSurface);
context->Paint();
}
RefPtr<SourceSurface> surface =
gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr,
imgSurface);
return SourceSurfaceToPixbuf(surface, aWidth, aHeight);
}

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

@ -33,8 +33,6 @@ class nsImageToPixbuf MOZ_FINAL : public nsIImageToPixbuf {
* released as needed by the caller using g_object_unref. * released as needed by the caller using g_object_unref.
*/ */
static GdkPixbuf* ImageToPixbuf(imgIContainer * aImage); static GdkPixbuf* ImageToPixbuf(imgIContainer * aImage);
static GdkPixbuf* SurfaceToPixbuf(gfxASurface* aSurface,
int32_t aWidth, int32_t aHeight);
static GdkPixbuf* SourceSurfaceToPixbuf(SourceSurface* aSurface, static GdkPixbuf* SourceSurfaceToPixbuf(SourceSurface* aSurface,
int32_t aWidth, int32_t aWidth,
int32_t aHeight); int32_t aHeight);

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

@ -40,6 +40,10 @@
#include "nsRect.h" #include "nsRect.h"
#include "nsMathUtils.h" #include "nsMathUtils.h"
#include "gfxWindowsPlatform.h" #include "gfxWindowsPlatform.h"
#include "mozilla/gfx/2D.h"
using namespace mozilla;
using namespace mozilla::gfx;
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
@ -75,11 +79,11 @@ nsDragService::CreateDragImage(nsIDOMNode *aDOMNode,
// Prepare the drag image // Prepare the drag image
nsIntRect dragRect; nsIntRect dragRect;
nsRefPtr<gfxASurface> surface; RefPtr<SourceSurface> surface;
nsPresContext* pc; nsPresContext* pc;
DrawDrag(aDOMNode, aRegion, DrawDrag(aDOMNode, aRegion,
mScreenX, mScreenY, mScreenX, mScreenY,
&dragRect, getter_AddRefs(surface), &pc); &dragRect, &surface, &pc);
if (!surface) if (!surface)
return false; return false;
@ -90,19 +94,27 @@ nsDragService::CreateDragImage(nsIDOMNode *aDOMNode,
psdi->crColorKey = CLR_NONE; psdi->crColorKey = CLR_NONE;
RefPtr<DataSourceSurface> data = surface->GetDataSurface();
DataSourceSurface::MappedSurface map;
if (!data->Map(DataSourceSurface::READ, &map)) {
return false;
}
nsRefPtr<gfxImageSurface> imgSurface = new gfxImageSurface( nsRefPtr<gfxImageSurface> imgSurface = new gfxImageSurface(
gfxIntSize(bmWidth, bmHeight), gfxIntSize(bmWidth, bmHeight),
gfxImageFormat::ARGB32); gfxImageFormat::ARGB32);
if (!imgSurface) if (!imgSurface)
return false; return false;
nsRefPtr<gfxContext> context = new gfxContext(imgSurface); RefPtr<DrawTarget> dt =
if (!context) gfxPlatform::GetPlatform()->
CreateDrawTargetForSurface(imgSurface, IntSize(bmWidth, bmHeight));
if (!dt)
return false; return false;
context->SetOperator(gfxContext::OPERATOR_SOURCE); dt->FillRect(Rect(0, 0, bmWidth, bmHeight),
context->SetSource(surface); SurfacePattern(surface, ExtendMode::CLAMP),
context->Paint(); DrawOptions(1.0f, CompositionOp::OP_SOURCE));
BITMAPV5HEADER bmih; BITMAPV5HEADER bmih;
memset((void*)&bmih, 0, sizeof(BITMAPV5HEADER)); memset((void*)&bmih, 0, sizeof(BITMAPV5HEADER));
@ -144,6 +156,8 @@ nsDragService::CreateDragImage(nsIDOMNode *aDOMNode,
DeleteDC(hdcSrc); DeleteDC(hdcSrc);
} }
data->Unmap();
return psdi->hbmpDragImage != nullptr; return psdi->hbmpDragImage != nullptr;
} }

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

@ -34,12 +34,14 @@
#include "nsMenuPopupFrame.h" #include "nsMenuPopupFrame.h"
#include "mozilla/MouseEvents.h" #include "mozilla/MouseEvents.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/gfx/2D.h"
#include "gfxContext.h" #include "gfxContext.h"
#include "gfxPlatform.h" #include "gfxPlatform.h"
#include <algorithm> #include <algorithm>
using namespace mozilla; using namespace mozilla;
using namespace mozilla::gfx;
#define DRAGIMAGES_PREF "nglayout.enable_drag_images" #define DRAGIMAGES_PREF "nglayout.enable_drag_images"
@ -426,7 +428,7 @@ nsBaseDragService::DrawDrag(nsIDOMNode* aDOMNode,
nsIScriptableRegion* aRegion, nsIScriptableRegion* aRegion,
int32_t aScreenX, int32_t aScreenY, int32_t aScreenX, int32_t aScreenY,
nsIntRect* aScreenDragRect, nsIntRect* aScreenDragRect,
gfxASurface** aSurface, RefPtr<SourceSurface>* aSurface,
nsPresContext** aPresContext) nsPresContext** aPresContext)
{ {
*aSurface = nullptr; *aSurface = nullptr;
@ -497,9 +499,7 @@ nsBaseDragService::DrawDrag(nsIDOMNode* aDOMNode,
// draw the image for selections // draw the image for selections
if (mSelection) { if (mSelection) {
nsIntPoint pnt(aScreenDragRect->x, aScreenDragRect->y); nsIntPoint pnt(aScreenDragRect->x, aScreenDragRect->y);
nsRefPtr<gfxASurface> surface = presShell->RenderSelection(mSelection, pnt, aScreenDragRect); *aSurface = presShell->RenderSelection(mSelection, pnt, aScreenDragRect);
*aSurface = surface;
NS_IF_ADDREF(*aSurface);
return NS_OK; return NS_OK;
} }
@ -532,7 +532,6 @@ nsBaseDragService::DrawDrag(nsIDOMNode* aDOMNode,
} }
} }
nsRefPtr<gfxASurface> surface;
if (!mDragPopup) { if (!mDragPopup) {
// otherwise, just draw the node // otherwise, just draw the node
nsIntRegion clipRegion; nsIntRegion clipRegion;
@ -541,8 +540,8 @@ nsBaseDragService::DrawDrag(nsIDOMNode* aDOMNode,
} }
nsIntPoint pnt(aScreenDragRect->x, aScreenDragRect->y); nsIntPoint pnt(aScreenDragRect->x, aScreenDragRect->y);
surface = presShell->RenderNode(dragNode, aRegion ? &clipRegion : nullptr, *aSurface = presShell->RenderNode(dragNode, aRegion ? &clipRegion : nullptr,
pnt, aScreenDragRect); pnt, aScreenDragRect);
} }
// if an image was specified, reposition the drag rectangle to // if an image was specified, reposition the drag rectangle to
@ -552,9 +551,6 @@ nsBaseDragService::DrawDrag(nsIDOMNode* aDOMNode,
aScreenDragRect->y = sy - mImageY; aScreenDragRect->y = sy - mImageY;
} }
*aSurface = surface;
NS_IF_ADDREF(*aSurface);
return NS_OK; return NS_OK;
} }
@ -564,7 +560,7 @@ nsBaseDragService::DrawDragForImage(nsPresContext* aPresContext,
nsICanvasElementExternal* aCanvas, nsICanvasElementExternal* aCanvas,
int32_t aScreenX, int32_t aScreenY, int32_t aScreenX, int32_t aScreenY,
nsIntRect* aScreenDragRect, nsIntRect* aScreenDragRect,
gfxASurface** aSurface) RefPtr<SourceSurface>* aSurface)
{ {
nsCOMPtr<imgIContainer> imgContainer; nsCOMPtr<imgIContainer> imgContainer;
if (aImageLoader) { if (aImageLoader) {
@ -620,19 +616,19 @@ nsBaseDragService::DrawDragForImage(nsPresContext* aPresContext,
aScreenDragRect->height = destSize.height; aScreenDragRect->height = destSize.height;
} }
nsRefPtr<gfxASurface> surface = RefPtr<DrawTarget> dt =
gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(destSize.width, destSize.height), gfxPlatform::GetPlatform()->
gfxContentType::COLOR_ALPHA); CreateOffscreenContentDrawTarget(IntSize(destSize.width, destSize.height),
if (!surface)
SurfaceFormat::B8G8R8A8);
if (!dt)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
nsRefPtr<gfxContext> ctx = new gfxContext(surface); nsRefPtr<gfxContext> ctx = new gfxContext(dt);
if (!ctx) if (!ctx)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
*aSurface = surface; nsresult result = NS_OK;
NS_ADDREF(*aSurface);
if (aImageLoader) { if (aImageLoader) {
gfxRect outRect(0, 0, destSize.width, destSize.height); gfxRect outRect(0, 0, destSize.width, destSize.height);
gfxMatrix scale = gfxMatrix scale =
@ -641,10 +637,12 @@ nsBaseDragService::DrawDragForImage(nsPresContext* aPresContext,
imgContainer->Draw(ctx, GraphicsFilter::FILTER_GOOD, scale, outRect, imgSize, imgContainer->Draw(ctx, GraphicsFilter::FILTER_GOOD, scale, outRect, imgSize,
destSize, nullptr, imgIContainer::FRAME_CURRENT, destSize, nullptr, imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_SYNC_DECODE); imgIContainer::FLAG_SYNC_DECODE);
return NS_OK;
} else { } else {
return aCanvas->RenderContextsExternal(ctx, GraphicsFilter::FILTER_GOOD); result = aCanvas->RenderContextsExternal(ctx, GraphicsFilter::FILTER_GOOD);
} }
*aSurface = dt->Snapshot();
return result;
} }
void void

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

@ -13,6 +13,7 @@
#include "nsIDOMDataTransfer.h" #include "nsIDOMDataTransfer.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsPoint.h" #include "nsPoint.h"
#include "mozilla/RefPtr.h"
#include "gfxImageSurface.h" #include "gfxImageSurface.h"
@ -26,6 +27,12 @@ class nsPresContext;
class nsIImageLoadingContent; class nsIImageLoadingContent;
class nsICanvasElementExternal; class nsICanvasElementExternal;
namespace mozilla {
namespace gfx {
class SourceSurface;
}
}
/** /**
* XP DragService wrapper base class * XP DragService wrapper base class
*/ */
@ -35,6 +42,8 @@ class nsBaseDragService : public nsIDragService,
{ {
public: public:
typedef mozilla::gfx::SourceSurface SourceSurface;
nsBaseDragService(); nsBaseDragService();
virtual ~nsBaseDragService(); virtual ~nsBaseDragService();
@ -77,7 +86,7 @@ protected:
nsIScriptableRegion* aRegion, nsIScriptableRegion* aRegion,
int32_t aScreenX, int32_t aScreenY, int32_t aScreenX, int32_t aScreenY,
nsIntRect* aScreenDragRect, nsIntRect* aScreenDragRect,
gfxASurface** aSurface, mozilla::RefPtr<SourceSurface>* aSurface,
nsPresContext **aPresContext); nsPresContext **aPresContext);
/** /**
@ -89,7 +98,7 @@ protected:
nsICanvasElementExternal* aCanvas, nsICanvasElementExternal* aCanvas,
int32_t aScreenX, int32_t aScreenY, int32_t aScreenX, int32_t aScreenY,
nsIntRect* aScreenDragRect, nsIntRect* aScreenDragRect,
gfxASurface** aSurface); mozilla::RefPtr<SourceSurface>* aSurface);
/** /**
* Convert aScreenX and aScreenY from CSS pixels into unscaled device pixels. * Convert aScreenX and aScreenY from CSS pixels into unscaled device pixels.