Bug 1103623 - Port most remaining gfxContext::Fill() calls to Moz2D. r=mattwoodrow

This commit is contained in:
Jonathan Watt 2014-11-24 00:04:33 +00:00
parent 8cf9f138a9
commit 9910919cdd
13 changed files with 144 additions and 89 deletions

View File

@ -10,6 +10,9 @@
#include "nsGfxCIID.h"
#include "nsWidgetsCID.h"
#include "gfxUtils.h"
#include "mozilla/gfx/2D.h"
//Interfaces Needed
#include "nsReadableUtils.h"
#include "nsIComponentManager.h"
@ -51,6 +54,7 @@
#include "nsXULAppAPI.h"
using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::layers;
static NS_DEFINE_CID(kChildCID, NS_CHILD_CID);
@ -1650,12 +1654,13 @@ static void DrawPaintedLayer(PaintedLayer* aLayer,
const nsIntRegion& aRegionToInvalidate,
void* aCallbackData)
{
nscolor* color = static_cast<nscolor*>(aCallbackData);
aContext->NewPath();
aContext->SetColor(gfxRGBA(*color));
DrawTarget& aDrawTarget = *aContext->GetDrawTarget();
ColorPattern color(ToDeviceColor(*static_cast<nscolor*>(aCallbackData)));
nsIntRect dirtyRect = aRegionToDraw.GetBounds();
aContext->Rectangle(gfxRect(dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height));
aContext->Fill();
aDrawTarget.FillRect(Rect(dirtyRect.x, dirtyRect.y,
dirtyRect.width, dirtyRect.height),
color);
}
void nsWebBrowser::WindowRaised(nsIWidget* aWidget)

View File

@ -9,7 +9,9 @@
#include "ReadbackLayer.h" // for ReadbackLayer, ReadbackSink
#include "gfxColor.h" // for gfxRGBA
#include "gfxContext.h" // for gfxContext
#include "gfxUtils.h"
#include "gfxRect.h" // for gfxRect
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/BasePoint.h" // for BasePoint
#include "mozilla/gfx/BaseRect.h" // for BaseRect
#include "nsAutoPtr.h" // for nsRefPtr, nsAutoPtr
@ -19,6 +21,8 @@
#include "nsRegion.h" // for nsIntRegion
#include "nsSize.h" // for nsIntSize
using namespace mozilla::gfx;
namespace mozilla {
namespace layers {
@ -111,10 +115,10 @@ ReadbackProcessor::BuildUpdatesForLayer(ReadbackLayer* aLayer)
aLayer->mSink->BeginUpdate(aLayer->GetRect(),
aLayer->AllocateSequenceNumber());
if (ctx) {
ctx->SetColor(aLayer->mBackgroundColor);
ColorPattern color(ToDeviceColor(aLayer->mBackgroundColor));
nsIntSize size = aLayer->GetSize();
ctx->Rectangle(gfxRect(0, 0, size.width, size.height));
ctx->Fill();
ctx->GetDrawTarget()->FillRect(Rect(0, 0, size.width, size.height),
color);
aLayer->mSink->EndUpdate(ctx, aLayer->GetRect());
}
}

View File

@ -659,6 +659,15 @@ gfxContext::UpdateSurfaceClip()
{
}
void
gfxContext::PopClip()
{
MOZ_ASSERT(CurrentState().pushedClips.Length() > 0);
CurrentState().pushedClips.RemoveElementAt(CurrentState().pushedClips.Length() - 1);
mDT->PopClip();
}
gfxRect
gfxContext::GetClipExtents()
{

View File

@ -467,6 +467,8 @@ public:
void Clip(const gfxRect& rect); // will clip to a rect
void Clip(Path* aPath);
void PopClip();
/**
* This will ensure that the surface actually has its clip set.
* Useful if you are doing native drawing.

View File

@ -6,6 +6,8 @@
#include "DisplayItemClip.h"
#include "gfxContext.h"
#include "gfxUtils.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/PathHelpers.h"
#include "nsPresContext.h"
#include "nsCSSRendering.h"
@ -118,24 +120,34 @@ DisplayItemClip::ApplyRoundedRectClipsTo(gfxContext* aContext,
}
void
DisplayItemClip::DrawRoundedRectsTo(gfxContext* aContext,
int32_t A2D,
uint32_t aBegin, uint32_t aEnd) const
DisplayItemClip::FillIntersectionOfRoundedRectClips(gfxContext* aContext,
const Color& aColor,
int32_t aAppUnitsPerDevPixel,
uint32_t aBegin,
uint32_t aEnd) const
{
DrawTarget& aDrawTarget = *aContext->GetDrawTarget();
aEnd = std::min<uint32_t>(aEnd, mRoundedClipRects.Length());
if (aEnd - aBegin == 0)
if (aBegin >= aEnd) {
return;
}
// If there is just one rounded rect we can just fill it, if there are more then we
// must clip the rest to get the intersection of clips
ApplyRoundedRectClipsTo(aContext, A2D, aBegin, aEnd - 1);
RefPtr<Path> roundedRect =
MakeRoundedRectPath(aDrawTarget, A2D, mRoundedClipRects[aEnd - 1]);
aContext->SetPath(roundedRect);
aContext->Fill();
// Push clips for any rects that come BEFORE the rect at |aEnd - 1|, if any:
ApplyRoundedRectClipsTo(aContext, aAppUnitsPerDevPixel, aBegin, aEnd - 1);
// Now fill the rect at |aEnd - 1|:
RefPtr<Path> roundedRect = MakeRoundedRectPath(aDrawTarget,
aAppUnitsPerDevPixel,
mRoundedClipRects[aEnd - 1]);
ColorPattern color(ToDeviceColor(aColor));
aDrawTarget.Fill(roundedRect, color);
// Finally, pop any clips that we may have pushed:
for (uint32_t i = aBegin; i < aEnd - 1; ++i) {
aContext->PopClip();
}
}
TemporaryRef<Path>

View File

@ -32,6 +32,7 @@ namespace mozilla {
* SVG clip-path), including no clipping at all.
*/
class DisplayItemClip {
typedef mozilla::gfx::Color Color;
typedef mozilla::gfx::DrawTarget DrawTarget;
typedef mozilla::gfx::Path Path;
@ -85,8 +86,11 @@ public:
uint32_t aBegin, uint32_t aEnd) const;
// Draw (fill) the rounded rects in this clip to aContext
void DrawRoundedRectsTo(gfxContext* aContext, int32_t A2D,
uint32_t aBegin, uint32_t aEnd) const;
void FillIntersectionOfRoundedRectClips(gfxContext* aContext,
const Color& aColor,
int32_t aAppUnitsPerDevPixel,
uint32_t aBegin,
uint32_t aEnd) const;
// 'Draw' (create as a path, does not stroke or fill) aRoundRect to aContext
mozilla::TemporaryRef<Path> MakeRoundedRectPath(DrawTarget& aDrawTarget,
int32_t A2D,

View File

@ -4410,14 +4410,14 @@ static bool ShouldDrawRectsSeparately(gfxContext* aContext, DrawRegionClip aClip
return !dt->SupportsRegionClipping();
}
static void DrawForcedBackgroundColor(gfxContext* aContext, Layer* aLayer, nscolor aBackgroundColor)
static void DrawForcedBackgroundColor(DrawTarget& aDrawTarget,
Layer* aLayer, nscolor
aBackgroundColor)
{
if (NS_GET_A(aBackgroundColor) > 0) {
nsIntRect r = aLayer->GetVisibleRegion().GetBounds();
aContext->NewPath();
aContext->Rectangle(gfxRect(r.x, r.y, r.width, r.height));
aContext->SetColor(gfxRGBA(aBackgroundColor));
aContext->Fill();
ColorPattern color(ToDeviceColor(aBackgroundColor));
aDrawTarget.FillRect(Rect(r.x, r.y, r.width, r.height), color);
}
}
@ -4457,6 +4457,8 @@ FrameLayerBuilder::DrawPaintedLayer(PaintedLayer* aLayer,
const nsIntRegion& aRegionToInvalidate,
void* aCallbackData)
{
DrawTarget& aDrawTarget = *aContext->GetDrawTarget();
PROFILER_LABEL("FrameLayerBuilder", "DrawPaintedLayer",
js::ProfileEntry::Category::GRAPHICS);
@ -4488,7 +4490,8 @@ FrameLayerBuilder::DrawPaintedLayer(PaintedLayer* aLayer,
gfxUtils::ClipToRegion(aContext, aRegionToDraw);
}
DrawForcedBackgroundColor(aContext, aLayer, userData->mForcedBackgroundColor);
DrawForcedBackgroundColor(aDrawTarget, aLayer,
userData->mForcedBackgroundColor);
}
if (NS_GET_A(userData->mFontSmoothingBackgroundColor) > 0) {
@ -4522,7 +4525,8 @@ FrameLayerBuilder::DrawPaintedLayer(PaintedLayer* aLayer,
aContext->Rectangle(*iterRect);
aContext->Clip();
DrawForcedBackgroundColor(aContext, aLayer, userData->mForcedBackgroundColor);
DrawForcedBackgroundColor(aDrawTarget, aLayer,
userData->mForcedBackgroundColor);
// Apply the residual transform if it has been enabled, to ensure that
// snapping when we draw into aContext exactly matches the ideal transform.
@ -4720,11 +4724,11 @@ ContainerState::SetupMaskLayer(Layer *aLayer,
context->Multiply(ThebesMatrix(imageTransform));
// paint the clipping rects with alpha to create the mask
context->SetColor(gfxRGBA(1, 1, 1, 1));
aClip.DrawRoundedRectsTo(context,
newData.mAppUnitsPerDevPixel,
0,
aRoundedRectClipCount);
aClip.FillIntersectionOfRoundedRectClips(context,
Color(1.f, 1.f, 1.f, 1.f),
newData.mAppUnitsPerDevPixel,
0,
aRoundedRectClipCount);
RefPtr<SourceSurface> surface = dt->Snapshot();

View File

@ -632,6 +632,8 @@ nsCSSRendering::PaintBorderWithStyleBorder(nsPresContext* aPresContext,
nsStyleContext* aStyleContext,
Sides aSkipSides)
{
DrawTarget& aDrawTarget = *aRenderingContext.GetDrawTarget();
PrintAsStringNewline("++ PaintBorder");
// Check to see if we have an appearance defined. If so, we let the theme
@ -692,7 +694,7 @@ nsCSSRendering::PaintBorderWithStyleBorder(nsPresContext* aPresContext,
aRenderingContext.ThebesContext()->
Clip(NSRectToSnappedRect(aBorderArea,
aForFrame->PresContext()->AppUnitsPerDevPixel(),
*aRenderingContext.GetDrawTarget()));
aDrawTarget));
}
} else {
MOZ_ASSERT(joinedBorderArea.IsEqualEdges(aBorderArea),
@ -731,14 +733,11 @@ nsCSSRendering::PaintBorderWithStyleBorder(nsPresContext* aPresContext,
#if 0
// this will draw a transparent red backround underneath the border area
ctx->Save();
ctx->Rectangle(ThebesRect(joinedBorderAreaPx));
ctx->SetColor(gfxRGBA(1.0, 0.0, 0.0, 0.5));
ctx->Fill();
ctx->Restore();
ColorPattern color(ToDeviceColor(Color(1.f, 0.f, 0.f, 0.5f)));
aDrawTarget.FillRect(joinedBorderAreaPx, color);
#endif
nsCSSBorderRenderer br(ctx->GetDrawTarget(),
nsCSSBorderRenderer br(&aDrawTarget,
joinedBorderAreaPx,
borderStyles,
borderWidths,

View File

@ -2811,20 +2811,19 @@ void
nsDisplayBackgroundColor::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
{
DrawTarget& aDrawTarget = *aCtx->GetDrawTarget();
if (mColor == NS_RGBA(0, 0, 0, 0)) {
return;
}
gfxContext* ctx = aCtx->ThebesContext();
nsRect borderBox = nsRect(ToReferenceFrame(), mFrame->GetSize());
gfxRect bounds =
nsLayoutUtils::RectToGfxRect(borderBox, mFrame->PresContext()->AppUnitsPerDevPixel());
ctx->SetColor(mColor);
ctx->NewPath();
ctx->Rectangle(bounds, true);
ctx->Fill();
Rect rect = NSRectToSnappedRect(borderBox,
mFrame->PresContext()->AppUnitsPerDevPixel(),
aDrawTarget);
ColorPattern color(ToDeviceColor(mColor));
aDrawTarget.FillRect(rect, color);
}
nsRegion

View File

@ -15,6 +15,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/PathHelpers.h"
#include "nsCOMPtr.h"
#include "nsFrameList.h"
@ -1463,6 +1464,8 @@ private:
void nsDisplaySelectionOverlay::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
{
DrawTarget& aDrawTarget = *aCtx->GetDrawTarget();
LookAndFeel::ColorID colorID;
if (mSelectionValue == nsISelectionController::SELECTION_ON) {
colorID = LookAndFeel::eColorID_TextSelectBackground;
@ -1472,19 +1475,16 @@ void nsDisplaySelectionOverlay::Paint(nsDisplayListBuilder* aBuilder,
colorID = LookAndFeel::eColorID_TextSelectBackgroundDisabled;
}
nscolor color = LookAndFeel::GetColor(colorID, NS_RGB(255, 255, 255));
gfxRGBA c(color);
Color c = Color::FromABGR(LookAndFeel::GetColor(colorID, NS_RGB(255, 255, 255)));
c.a = .5;
gfxContext *ctx = aCtx->ThebesContext();
ctx->SetColor(c);
ColorPattern color(ToDeviceColor(c));
nsIntRect pxRect =
mVisibleRect.ToOutsidePixels(mFrame->PresContext()->AppUnitsPerDevPixel());
ctx->NewPath();
ctx->Rectangle(gfxRect(pxRect.x, pxRect.y, pxRect.width, pxRect.height), true);
ctx->Fill();
Rect rect(pxRect.x, pxRect.y, pxRect.width, pxRect.height);
MaybeSnapToDevicePixels(rect, aDrawTarget);
aDrawTarget.FillRect(rect, color);
}
/********************************************************

View File

@ -2119,9 +2119,9 @@ nsMathMLChar::PaintForeground(nsPresContext* aPresContext,
case DRAW_PARTS: {
// paint by parts
if (NS_STRETCH_DIRECTION_VERTICAL == mDirection)
PaintVertically(aPresContext, thebesContext, r);
PaintVertically(aPresContext, thebesContext, r, fgColor);
else if (NS_STRETCH_DIRECTION_HORIZONTAL == mDirection)
PaintHorizontally(aPresContext, thebesContext, r);
PaintHorizontally(aPresContext, thebesContext, r, fgColor);
break;
}
default:
@ -2167,22 +2167,25 @@ SnapToDevPixels(const gfxContext* aThebesContext, int32_t aAppUnitsPerGfxUnit,
}
static void
PaintRule(gfxContext* aThebesContext,
PaintRule(DrawTarget& aDrawTarget,
int32_t aAppUnitsPerGfxUnit,
nsRect& aRect)
nsRect& aRect,
nscolor aColor)
{
aThebesContext->NewPath();
gfxRect rect = nsLayoutUtils::RectToGfxRect(aRect, aAppUnitsPerGfxUnit);
aThebesContext->SnappedRectangle(rect);
aThebesContext->Fill();
Rect rect = NSRectToSnappedRect(aRect, aAppUnitsPerGfxUnit, aDrawTarget);
ColorPattern color(ToDeviceColor(aColor));
aDrawTarget.FillRect(rect, color);
}
// paint a stretchy char by assembling glyphs vertically
nsresult
nsMathMLChar::PaintVertically(nsPresContext* aPresContext,
gfxContext* aThebesContext,
nsRect& aRect)
nsRect& aRect,
nscolor aColor)
{
DrawTarget& aDrawTarget = *aThebesContext->GetDrawTarget();
// Get the device pixel size in the vertical direction.
// (This makes no effort to optimize for non-translation transformations.)
nscoord oneDevPixel = aPresContext->AppUnitsPerDevPixel();
@ -2306,7 +2309,7 @@ nsMathMLChar::PaintVertically(nsPresContext* aPresContext,
// paint the rule between the parts
nsRect rule(aRect.x + lbearing, end[first],
rbearing - lbearing, start[last] - end[first]);
PaintRule(aThebesContext, oneDevPixel, rule);
PaintRule(aDrawTarget, oneDevPixel, rule, aColor);
first = last;
last++;
}
@ -2355,8 +2358,11 @@ nsMathMLChar::PaintVertically(nsPresContext* aPresContext,
nsresult
nsMathMLChar::PaintHorizontally(nsPresContext* aPresContext,
gfxContext* aThebesContext,
nsRect& aRect)
nsRect& aRect,
nscolor aColor)
{
DrawTarget& aDrawTarget = *aThebesContext->GetDrawTarget();
// Get the device pixel size in the horizontal direction.
// (This makes no effort to optimize for non-translation transformations.)
nscoord oneDevPixel = aPresContext->AppUnitsPerDevPixel();
@ -2473,7 +2479,7 @@ nsMathMLChar::PaintHorizontally(nsPresContext* aPresContext,
// paint the rule between the parts
nsRect rule(end[first], dy - ascent,
start[last] - end[first], ascent + descent);
PaintRule(aThebesContext, oneDevPixel, rule);
PaintRule(aDrawTarget, oneDevPixel, rule, aColor);
first = last;
last++;
}

View File

@ -7,6 +7,7 @@
#define nsMathMLChar_h___
#include "nsAutoPtr.h"
#include "nsColor.h"
#include "nsMathMLOperators.h"
#include "nsPoint.h"
#include "nsRect.h"
@ -258,12 +259,14 @@ private:
nsresult
PaintVertically(nsPresContext* aPresContext,
gfxContext* aThebesContext,
nsRect& aRect);
nsRect& aRect,
nscolor aColor);
nsresult
PaintHorizontally(nsPresContext* aPresContext,
gfxContext* aThebesContext,
nsRect& aRect);
nsRect& aRect,
nscolor aColor);
void
ApplyTransforms(gfxContext* aThebesContext, int32_t aAppUnitsPerGfxUnit,

View File

@ -5,6 +5,11 @@
#include "nsMathMLmfracFrame.h"
#include "gfxUtils.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/RefPtr.h"
#include "nsLayoutUtils.h"
#include "nsPresContext.h"
#include "nsRenderingContext.h"
#include "nsDisplayList.h"
@ -12,6 +17,9 @@
#include "nsMathMLElement.h"
#include <algorithm>
using namespace mozilla;
using namespace mozilla::gfx;
//
// <mfrac> -- form a fraction from two subexpressions - implementation
//
@ -602,32 +610,32 @@ private:
void nsDisplayMathMLSlash::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
{
DrawTarget& aDrawTarget = *aCtx->GetDrawTarget();
// get the gfxRect
nsPresContext* presContext = mFrame->PresContext();
gfxRect rect = presContext->AppUnitsToGfxUnits(mRect + ToReferenceFrame());
Rect rect = NSRectToRect(mRect + ToReferenceFrame(),
presContext->AppUnitsPerDevPixel());
// paint with the current text color
aCtx->ThebesContext()->SetColor(mFrame->GetVisitedDependentColor(eCSSProperty_color));
ColorPattern color(ToDeviceColor(
mFrame->GetVisitedDependentColor(eCSSProperty_color)));
// draw the slash as a parallelogram
gfxContext *gfxCtx = aCtx->ThebesContext();
gfxPoint delta = gfxPoint(presContext->AppUnitsToGfxUnits(mThickness), 0);
gfxCtx->NewPath();
Point delta = Point(presContext->AppUnitsToGfxUnits(mThickness), 0);
RefPtr<PathBuilder> builder = aDrawTarget.CreatePathBuilder();
if (mRTL) {
gfxCtx->MoveTo(rect.TopLeft());
gfxCtx->LineTo(rect.TopLeft() + delta);
gfxCtx->LineTo(rect.BottomRight());
gfxCtx->LineTo(rect.BottomRight() - delta);
builder->MoveTo(rect.TopLeft());
builder->LineTo(rect.TopLeft() + delta);
builder->LineTo(rect.BottomRight());
builder->LineTo(rect.BottomRight() - delta);
} else {
gfxCtx->MoveTo(rect.BottomLeft());
gfxCtx->LineTo(rect.BottomLeft() + delta);
gfxCtx->LineTo(rect.TopRight());
gfxCtx->LineTo(rect.TopRight() - delta);
builder->MoveTo(rect.BottomLeft());
builder->LineTo(rect.BottomLeft() + delta);
builder->LineTo(rect.TopRight());
builder->LineTo(rect.TopRight() - delta);
}
gfxCtx->ClosePath();
gfxCtx->Fill();
RefPtr<Path> path = builder->Finish();
aDrawTarget.Fill(path, color);
}
void