Backed out 5 changesets (bug 962786, bug 952011) for svg test_text_selection.html bustage

CLOSED TREE

Backed out changeset d7a6a64b42f0 (bug 962786)
Backed out changeset e50ced4f4040 (bug 952011)
Backed out changeset c9e6fd6d5a03 (bug 952011)
Backed out changeset 406540ed9da0 (bug 952011)
Backed out changeset d6f164b6421a (bug 962786)
This commit is contained in:
Phil Ringnalda 2014-01-28 19:37:54 -08:00
parent 88f1a2e0d5
commit b28c502af5
18 changed files with 229 additions and 265 deletions

View File

@ -788,9 +788,10 @@ gfxRect gfx3DMatrix::ProjectRectBounds(const gfxRect& aRect) const
gfxPoint points[4];
points[0] = ProjectPoint(aRect.TopLeft());
points[1] = ProjectPoint(aRect.TopRight());
points[2] = ProjectPoint(aRect.BottomLeft());
points[3] = ProjectPoint(aRect.BottomRight());
points[1] = ProjectPoint(gfxPoint(aRect.X() + aRect.Width(), aRect.Y()));
points[2] = ProjectPoint(gfxPoint(aRect.X(), aRect.Y() + aRect.Height()));
points[3] = ProjectPoint(gfxPoint(aRect.X() + aRect.Width(),
aRect.Y() + aRect.Height()));
gfxFloat min_x, max_x;
gfxFloat min_y, max_y;
@ -808,27 +809,6 @@ gfxRect gfx3DMatrix::ProjectRectBounds(const gfxRect& aRect) const
return gfxRect(min_x, min_y, max_x - min_x, max_y - min_y);
}
gfxRect gfx3DMatrix::UntransformBounds(const gfxRect& aRect, const gfxRect& aChildBounds) const
{
gfxRect bounds = TransformBounds(aChildBounds);
gfxRect rect = aRect.Intersect(bounds);
return Inverse().ProjectRectBounds(rect);
}
bool gfx3DMatrix::UntransformPoint(const gfxPoint& aPoint, const gfxRect& aChildBounds, gfxPoint* aOut) const
{
gfxRect bounds = TransformBounds(aChildBounds);
if (!bounds.Contains(aPoint)) {
return false;
}
*aOut = Inverse().ProjectPoint(aPoint);
return true;
}
gfxPoint3D gfx3DMatrix::GetNormalVector() const
{
// Define a plane in transformed space as the transformations

View File

@ -250,25 +250,6 @@ public:
gfxPoint ProjectPoint(const gfxPoint& aPoint) const;
gfxRect ProjectRectBounds(const gfxRect& aRect) const;
/**
* Transforms a point by the inverse of this matrix. In the case of projective transforms, some screen
* points have no equivalent in the untransformed plane (if they exist past the vanishing point). To
* avoid this, we need to specify the bounds of the untransformed plane to restrict the search area.
*
* @param aPoint Point to untransform.
* @param aChildBounds Bounds of the untransformed plane.
* @param aOut Untransformed point.
* @return Returns true if a point was found within a ChildBounds, false otherwise.
*/
bool UntransformPoint(const gfxPoint& aPoint, const gfxRect& aChildBounds, gfxPoint* aOut) const;
/**
* Same as UntransformPoint, but untransforms a rect and returns the bounding rect of the result.
* Returns an empty rect if the result doesn't intersect aChildBounds.
*/
gfxRect UntransformBounds(const gfxRect& aRect, const gfxRect& aChildBounds) const;
/**
* Inverts this matrix, if possible. Otherwise, the matrix is left

View File

@ -1559,10 +1559,7 @@ SetVisibleRegionForLayer(Layer* aLayer, const nsIntRegion& aLayerVisibleRegion,
// for the layer, so it doesn't really matter what we do here
gfxRect itemVisible(aRestrictToRect.x, aRestrictToRect.y,
aRestrictToRect.width, aRestrictToRect.height);
nsIntRect childBounds = aLayerVisibleRegion.GetBounds();
gfxRect childGfxBounds(childBounds.x, childBounds.y,
childBounds.width, childBounds.height);
gfxRect layerVisible = transform.UntransformBounds(itemVisible, childGfxBounds);
gfxRect layerVisible = transform.Inverse().ProjectRectBounds(itemVisible);
layerVisible.RoundOut();
nsIntRect visibleRect;

View File

@ -1396,7 +1396,7 @@ void nsDisplayList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
if (aRect.width != 1 || aRect.height != 1) {
point = aRect.Center();
}
temp.AppendElement(FramesWithDepth(transform->GetHitDepthAtPoint(aBuilder, point)));
temp.AppendElement(FramesWithDepth(transform->GetHitDepthAtPoint(point)));
writeFrames = &temp[temp.Length() - 1].mFrames;
}
} else {
@ -4450,8 +4450,13 @@ bool nsDisplayTransform::ComputeVisibility(nsDisplayListBuilder *aBuilder,
* think that it's painting in its original rectangular coordinate space.
* If we can't untransform, take the entire overflow rect */
nsRect untransformedVisibleRect;
// GetTransform always operates in dev pixels.
float factor = mFrame->PresContext()->AppUnitsPerDevPixel();
if (ShouldPrerenderTransformedContent(aBuilder, mFrame) ||
!UntransformVisibleRect(aBuilder, &untransformedVisibleRect))
!UntransformRectMatrix(mVisibleRect,
GetTransform(),
factor,
&untransformedVisibleRect))
{
untransformedVisibleRect = mFrame->GetVisualOverflowRectRelativeToSelf();
}
@ -4492,24 +4497,14 @@ void nsDisplayTransform::HitTest(nsDisplayListBuilder *aBuilder,
* Thus we have to invert the matrix, which normally does
* the reverse operation (e.g. regular->transformed)
*/
bool snap;
nsRect childBounds = mStoredList.GetBounds(aBuilder, &snap);
gfxRect childGfxBounds(NSAppUnitsToFloatPixels(childBounds.x, factor),
NSAppUnitsToFloatPixels(childBounds.y, factor),
NSAppUnitsToFloatPixels(childBounds.width, factor),
NSAppUnitsToFloatPixels(childBounds.height, factor));
/* Now, apply the transform and pass it down the channel. */
nsRect resultingRect;
if (aRect.width == 1 && aRect.height == 1) {
// Magic width/height indicating we're hit testing a point, not a rect
gfxPoint point;
if (!matrix.UntransformPoint(gfxPoint(NSAppUnitsToFloatPixels(aRect.x, factor),
NSAppUnitsToFloatPixels(aRect.y, factor)),
childGfxBounds,
&point)) {
return;
}
gfxPoint point = matrix.Inverse().ProjectPoint(
gfxPoint(NSAppUnitsToFloatPixels(aRect.x, factor),
NSAppUnitsToFloatPixels(aRect.y, factor)));
resultingRect = nsRect(NSFloatPixelsToAppUnits(float(point.x), factor),
NSFloatPixelsToAppUnits(float(point.y), factor),
@ -4521,7 +4516,7 @@ void nsDisplayTransform::HitTest(nsDisplayListBuilder *aBuilder,
NSAppUnitsToFloatPixels(aRect.width, factor),
NSAppUnitsToFloatPixels(aRect.height, factor));
gfxRect rect = matrix.UntransformBounds(originalRect, childGfxBounds);
gfxRect rect = matrix.Inverse().ProjectRectBounds(originalRect);;
resultingRect = nsRect(NSFloatPixelsToAppUnits(float(rect.X()), factor),
NSFloatPixelsToAppUnits(float(rect.Y()), factor),
@ -4529,10 +4524,6 @@ void nsDisplayTransform::HitTest(nsDisplayListBuilder *aBuilder,
NSFloatPixelsToAppUnits(float(rect.Height()), factor));
}
if (resultingRect.IsEmpty()) {
return;
}
#ifdef DEBUG_HIT
printf("Frame: %p\n", dynamic_cast<void *>(mFrame));
@ -4552,7 +4543,7 @@ void nsDisplayTransform::HitTest(nsDisplayListBuilder *aBuilder,
}
float
nsDisplayTransform::GetHitDepthAtPoint(nsDisplayListBuilder* aBuilder, const nsPoint& aPoint)
nsDisplayTransform::GetHitDepthAtPoint(const nsPoint& aPoint)
{
// GetTransform always operates in dev pixels.
float factor = mFrame->PresContext()->AppUnitsPerDevPixel();
@ -4560,19 +4551,9 @@ nsDisplayTransform::GetHitDepthAtPoint(nsDisplayListBuilder* aBuilder, const nsP
NS_ASSERTION(IsFrameVisible(mFrame, matrix), "We can't have hit a frame that isn't visible!");
bool snap;
nsRect childBounds = mStoredList.GetBounds(aBuilder, &snap);
gfxRect childGfxBounds(NSAppUnitsToFloatPixels(childBounds.x, factor),
NSAppUnitsToFloatPixels(childBounds.y, factor),
NSAppUnitsToFloatPixels(childBounds.width, factor),
NSAppUnitsToFloatPixels(childBounds.height, factor));
gfxPoint point;
DebugOnly<bool> result = matrix.UntransformPoint(gfxPoint(NSAppUnitsToFloatPixels(aPoint.x, factor),
NSAppUnitsToFloatPixels(aPoint.y, factor)),
childGfxBounds,
&point);
NS_ASSERTION(result, "Why are we trying to get the depth for a point we didn't hit?");
gfxPoint point =
matrix.Inverse().ProjectPoint(gfxPoint(NSAppUnitsToFloatPixels(aPoint.x, factor),
NSAppUnitsToFloatPixels(aPoint.y, factor)));
gfxPoint3D transformed = matrix.Transform3D(gfxPoint3D(point.x, point.y, 0));
return transformed.z;
@ -4616,6 +4597,8 @@ nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
{
*aSnap = false;
nsRect untransformedVisible;
// GetTransform always operates in dev pixels.
float factor = mFrame->PresContext()->AppUnitsPerDevPixel();
// If we're going to prerender all our content, pretend like we
// don't have opqaue content so that everything under us is rendered
// as well. That will increase graphics memory usage if our frame
@ -4623,7 +4606,7 @@ nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
// updated extremely cheaply, without invalidating any other
// content.
if (ShouldPrerenderTransformedContent(aBuilder, mFrame) ||
!UntransformVisibleRect(aBuilder, &untransformedVisible)) {
!UntransformRectMatrix(mVisibleRect, GetTransform(), factor, &untransformedVisible)) {
return nsRegion();
}
@ -4647,7 +4630,9 @@ nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
bool nsDisplayTransform::IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor)
{
nsRect untransformedVisible;
if (!UntransformVisibleRect(aBuilder, &untransformedVisible)) {
// GetTransform always operates in dev pixels.
float factor = mFrame->PresContext()->AppUnitsPerDevPixel();
if (!UntransformRectMatrix(mVisibleRect, GetTransform(), factor, &untransformedVisible)) {
return false;
}
const gfx3DMatrix& matrix = GetTransform();
@ -4743,34 +4728,43 @@ nsRect nsDisplayTransform::TransformRectOut(const nsRect &aUntransformedBounds,
factor);
}
bool nsDisplayTransform::UntransformVisibleRect(nsDisplayListBuilder* aBuilder,
nsRect *aOutRect)
bool nsDisplayTransform::UntransformRectMatrix(const nsRect &aUntransformedBounds,
const gfx3DMatrix& aMatrix,
float aAppUnitsPerPixel,
nsRect *aOutRect)
{
const gfx3DMatrix& matrix = GetTransform();
if (matrix.IsSingular())
if (aMatrix.IsSingular())
return false;
// GetTransform always operates in dev pixels.
float factor = mFrame->PresContext()->AppUnitsPerDevPixel();
gfxRect result(NSAppUnitsToFloatPixels(mVisibleRect.x, factor),
NSAppUnitsToFloatPixels(mVisibleRect.y, factor),
NSAppUnitsToFloatPixels(mVisibleRect.width, factor),
NSAppUnitsToFloatPixels(mVisibleRect.height, factor));
gfxRect result(NSAppUnitsToFloatPixels(aUntransformedBounds.x, aAppUnitsPerPixel),
NSAppUnitsToFloatPixels(aUntransformedBounds.y, aAppUnitsPerPixel),
NSAppUnitsToFloatPixels(aUntransformedBounds.width, aAppUnitsPerPixel),
NSAppUnitsToFloatPixels(aUntransformedBounds.height, aAppUnitsPerPixel));
bool snap;
nsRect childBounds = mStoredList.GetBounds(aBuilder, &snap);
gfxRect childGfxBounds(NSAppUnitsToFloatPixels(childBounds.x, factor),
NSAppUnitsToFloatPixels(childBounds.y, factor),
NSAppUnitsToFloatPixels(childBounds.width, factor),
NSAppUnitsToFloatPixels(childBounds.height, factor));
/* We want to untransform the matrix, so invert the transformation first! */
result = aMatrix.Inverse().ProjectRectBounds(result);
result = matrix.UntransformBounds(result, childGfxBounds);
*aOutRect = nsLayoutUtils::RoundGfxRectToAppRect(result, factor);
*aOutRect = nsLayoutUtils::RoundGfxRectToAppRect(result, aAppUnitsPerPixel);
return true;
}
bool nsDisplayTransform::UntransformRect(const nsRect &aUntransformedBounds,
const nsIFrame* aFrame,
const nsPoint &aOrigin,
nsRect* aOutRect)
{
NS_PRECONDITION(aFrame, "Can't take the transform based on a null frame!");
/* Grab the matrix. If the transform is degenerate, just hand back the
* empty rect.
*/
float factor = aFrame->PresContext()->AppUnitsPerDevPixel();
gfx3DMatrix matrix = GetResultingTransformMatrix(aFrame, aOrigin, factor);
return UntransformRectMatrix(aUntransformedBounds, matrix, factor, aOutRect);
}
nsDisplaySVGEffects::nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList)
: nsDisplayWrapList(aBuilder, aFrame, aList),

View File

@ -3062,7 +3062,7 @@ public:
const gfx3DMatrix& GetTransform();
float GetHitDepthAtPoint(nsDisplayListBuilder* aBuilder, const nsPoint& aPoint);
float GetHitDepthAtPoint(const nsPoint& aPoint);
/**
* TransformRect takes in as parameters a rectangle (in aFrame's coordinate
@ -3095,8 +3095,15 @@ public:
/* UntransformRect is like TransformRect, except that it inverts the
* transform.
*/
bool UntransformVisibleRect(nsDisplayListBuilder* aBuilder,
nsRect* aOutRect);
static bool UntransformRect(const nsRect &aUntransformedBounds,
const nsIFrame* aFrame,
const nsPoint &aOrigin,
nsRect* aOutRect);
static bool UntransformRectMatrix(const nsRect &aUntransformedBounds,
const gfx3DMatrix& aMatrix,
float aAppUnitsPerPixel,
nsRect* aOutRect);
static gfxPoint3D GetDeltaToTransformOrigin(const nsIFrame* aFrame,
float aAppUnitsPerPixel,

View File

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

View File

@ -1820,21 +1820,22 @@ nsLayoutUtils::GetLayerTransformForFrame(nsIFrame* aFrame,
return true;
}
static bool
static gfxPoint
TransformGfxPointFromAncestor(nsIFrame *aFrame,
const gfxPoint &aPoint,
nsIFrame *aAncestor,
gfxPoint* aOut)
nsIFrame *aAncestor)
{
gfx3DMatrix ctm = nsLayoutUtils::GetTransformToAncestor(aFrame, aAncestor);
return ctm.Inverse().ProjectPoint(aPoint);
}
float factor = aFrame->PresContext()->AppUnitsPerDevPixel();
nsRect childBounds = aFrame->GetVisualOverflowRectRelativeToSelf();
gfxRect childGfxBounds(NSAppUnitsToFloatPixels(childBounds.x, factor),
NSAppUnitsToFloatPixels(childBounds.y, factor),
NSAppUnitsToFloatPixels(childBounds.width, factor),
NSAppUnitsToFloatPixels(childBounds.height, factor));
return ctm.UntransformPoint(aPoint, childGfxBounds, aOut);
static gfxRect
TransformGfxRectFromAncestor(nsIFrame *aFrame,
const gfxRect &aRect,
const nsIFrame *aAncestor)
{
gfx3DMatrix ctm = nsLayoutUtils::GetTransformToAncestor(aFrame, aAncestor);
return ctm.Inverse().ProjectRectBounds(aRect);
}
static gfxRect
@ -1876,20 +1877,43 @@ nsLayoutUtils::TransformAncestorPointToFrame(nsIFrame* aFrame,
NSAppUnitsToFloatPixels(aPoint.y, factor));
if (text) {
if (!TransformGfxPointFromAncestor(text, result, aAncestor, &result)) {
return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
}
result = TransformGfxPointFromAncestor(text, result, aAncestor);
result = text->TransformFramePointToTextChild(result, aFrame);
} else {
if (!TransformGfxPointFromAncestor(aFrame, result, nullptr, &result)) {
return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
}
result = TransformGfxPointFromAncestor(aFrame, result, nullptr);
}
return nsPoint(NSFloatPixelsToAppUnits(float(result.x), factor),
NSFloatPixelsToAppUnits(float(result.y), factor));
}
nsRect
nsLayoutUtils::TransformAncestorRectToFrame(nsIFrame* aFrame,
const nsRect &aRect,
const nsIFrame* aAncestor)
{
SVGTextFrame* text = GetContainingSVGTextFrame(aFrame);
float srcAppUnitsPerDevPixel = aAncestor->PresContext()->AppUnitsPerDevPixel();
gfxRect result(NSAppUnitsToFloatPixels(aRect.x, srcAppUnitsPerDevPixel),
NSAppUnitsToFloatPixels(aRect.y, srcAppUnitsPerDevPixel),
NSAppUnitsToFloatPixels(aRect.width, srcAppUnitsPerDevPixel),
NSAppUnitsToFloatPixels(aRect.height, srcAppUnitsPerDevPixel));
if (text) {
result = TransformGfxRectFromAncestor(text, result, aAncestor);
result = text->TransformFrameRectToTextChild(result, aFrame);
} else {
result = TransformGfxRectFromAncestor(aFrame, result, aAncestor);
}
float destAppUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
return nsRect(NSFloatPixelsToAppUnits(float(result.x), destAppUnitsPerDevPixel),
NSFloatPixelsToAppUnits(float(result.y), destAppUnitsPerDevPixel),
NSFloatPixelsToAppUnits(float(result.width), destAppUnitsPerDevPixel),
NSFloatPixelsToAppUnits(float(result.height), destAppUnitsPerDevPixel));
}
nsRect
nsLayoutUtils::TransformFrameRectToAncestor(nsIFrame* aFrame,
const nsRect& aRect,

View File

@ -636,6 +636,14 @@ public:
nsTArray<nsIFrame*> &aOutFrames,
uint32_t aFlags = 0);
/**
* Transform aRect relative to aAncestor down to the coordinate system of
* aFrame. Computes the bounding-box of the true quadrilateral.
*/
static nsRect TransformAncestorRectToFrame(nsIFrame* aFrame,
const nsRect& aRect,
const nsIFrame* aAncestor);
/**
* Transform aRect relative to aFrame up to the coordinate system of
* aAncestor. Computes the bounding-box of the true quadrilateral.
@ -681,9 +689,6 @@ public:
/**
* Transform aPoint relative to aAncestor down to the coordinate system of
* aFrame.
*
* Returns nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if no equivalent
* point exists in the child frame (can happen with projective transforms).
*/
static nsPoint TransformAncestorPointToFrame(nsIFrame* aFrame,
const nsPoint& aPoint,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -129,3 +129,37 @@ nsImageToPixbuf::SourceSurfaceToPixbuf(SourceSurface* aSurface,
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);
}

View File

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

View File

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

View File

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

View File

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