Bug 1083753, part 2 - Port the code that uses nsRenderingContext::FillRect(nsRect) to Moz2D. r=mattwoodrow
authorJonathan Watt <jwatt@jwatt.org>
Sun, 19 Oct 2014 13:22:22 +0100
changeset 211147 2cb4b5b083746d01421f6c38fa71d6212b02ec2d
parent 211146 045556326c7cf9c0dff9430aaa286f0feda8cee6
child 211148 71211c4a4acc7e93d58c8284735aaa3f9ac1a14c
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersmattwoodrow
bugs1083753
milestone36.0a1
Bug 1083753, part 2 - Port the code that uses nsRenderingContext::FillRect(nsRect) to Moz2D. r=mattwoodrow
gfx/src/nsRenderingContext.cpp
gfx/src/nsRenderingContext.h
layout/base/nsCSSRendering.cpp
layout/base/nsCaret.cpp
layout/base/nsDisplayList.cpp
layout/base/nsPresShell.cpp
layout/forms/nsGfxCheckboxControlFrame.cpp
layout/generic/nsCanvasFrame.cpp
layout/generic/nsFrameSetFrame.cpp
layout/generic/nsImageFrame.cpp
layout/mathml/nsMathMLChar.cpp
layout/mathml/nsMathMLContainerFrame.cpp
layout/mathml/nsMathMLFrame.cpp
layout/svg/nsSVGPathGeometryFrame.cpp
layout/xul/nsBoxFrame.cpp
layout/xul/tree/nsTreeBodyFrame.cpp
--- a/gfx/src/nsRenderingContext.cpp
+++ b/gfx/src/nsRenderingContext.cpp
@@ -159,111 +159,16 @@ nsRenderingContext::DrawLine(nscoord aX0
     } else {
         mThebes->NewPath();
         mThebes->Line(p0, p1);
         mThebes->Stroke();
     }
 }
 
 
-/* Clamp r to (0,0) (2^23,2^23)
- * these are to be device coordinates.
- *
- * Returns false if the rectangle is completely out of bounds,
- * true otherwise.
- *
- * This function assumes that it will be called with a rectangle being
- * drawn into a surface with an identity transformation matrix; that
- * is, anything above or to the left of (0,0) will be offscreen.
- *
- * First it checks if the rectangle is entirely beyond
- * CAIRO_COORD_MAX; if so, it can't ever appear on the screen --
- * false is returned.
- *
- * Then it shifts any rectangles with x/y < 0 so that x and y are = 0,
- * and adjusts the width and height appropriately.  For example, a
- * rectangle from (0,-5) with dimensions (5,10) will become a
- * rectangle from (0,0) with dimensions (5,5).
- *
- * If after negative x/y adjustment to 0, either the width or height
- * is negative, then the rectangle is completely offscreen, and
- * nothing is drawn -- false is returned.
- *
- * Finally, if x+width or y+height are greater than CAIRO_COORD_MAX,
- * the width and height are clamped such x+width or y+height are equal
- * to CAIRO_COORD_MAX, and true is returned.
- */
-#define CAIRO_COORD_MAX (double(0x7fffff))
-
-static bool
-ConditionRect(gfxRect& r) {
-    // if either x or y is way out of bounds;
-    // note that we don't handle negative w/h here
-    if (r.X() > CAIRO_COORD_MAX || r.Y() > CAIRO_COORD_MAX)
-        return false;
-
-    if (r.X() < 0.0) {
-        r.width += r.X();
-        if (r.width < 0.0)
-            return false;
-        r.x = 0.0;
-    }
-
-    if (r.XMost() > CAIRO_COORD_MAX) {
-        r.width = CAIRO_COORD_MAX - r.X();
-    }
-
-    if (r.Y() < 0.0) {
-        r.height += r.Y();
-        if (r.Height() < 0.0)
-            return false;
-
-        r.y = 0.0;
-    }
-
-    if (r.YMost() > CAIRO_COORD_MAX) {
-        r.height = CAIRO_COORD_MAX - r.Y();
-    }
-    return true;
-}
-
-void
-nsRenderingContext::FillRect(const nsRect& aRect)
-{
-    gfxRect r(GFX_RECT_FROM_TWIPS_RECT(aRect));
-
-    /* Clamp coordinates to work around a design bug in cairo */
-    nscoord bigval = (nscoord)(CAIRO_COORD_MAX*mP2A);
-    if (aRect.width > bigval ||
-        aRect.height > bigval ||
-        aRect.x < -bigval ||
-        aRect.x > bigval ||
-        aRect.y < -bigval ||
-        aRect.y > bigval)
-    {
-        gfxMatrix mat = mThebes->CurrentMatrix();
-
-        r = mat.Transform(r);
-
-        if (!ConditionRect(r))
-            return;
-
-        mThebes->SetMatrix(gfxMatrix());
-        mThebes->NewPath();
-
-        mThebes->Rectangle(r, true);
-        mThebes->Fill();
-        mThebes->SetMatrix(mat);
-    }
-
-    mThebes->NewPath();
-    mThebes->Rectangle(r, true);
-    mThebes->Fill();
-}
-
 //
 // text
 //
 
 void
 nsRenderingContext::SetTextRunRTL(bool aIsRTL)
 {
     mFontMetrics->SetTextRunRTL(aIsRTL);
--- a/gfx/src/nsRenderingContext.h
+++ b/gfx/src/nsRenderingContext.h
@@ -51,17 +51,16 @@ public:
 
     void IntersectClip(const nsRect& aRect);
     void SetColor(nscolor aColor);
 
     // Shapes
 
     void DrawLine(const nsPoint& aStartPt, const nsPoint& aEndPt);
     void DrawLine(nscoord aX0, nscoord aY0, nscoord aX1, nscoord aY1);
-    void FillRect(const nsRect& aRect);
 
     // Text
 
     void SetFont(nsFontMetrics *aFontMetrics);
     nsFontMetrics *FontMetrics() { return mFontMetrics; } // may be null
 
     void SetTextRunRTL(bool aIsRTL);
 
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -3491,36 +3491,42 @@ DrawSolidBorderSegment(nsRenderingContex
                        nsRect               aRect,
                        nscolor              aColor,
                        nscoord              aTwipsPerPixel,
                        uint8_t              aStartBevelSide = 0,
                        nscoord              aStartBevelOffset = 0,
                        uint8_t              aEndBevelSide = 0,
                        nscoord              aEndBevelOffset = 0)
 {
+  DrawTarget* drawTarget = aContext.GetDrawTarget();
+  int32_t appUnitsPerDevPixel = aContext.AppUnitsPerDevPixel();
+
+  ColorPattern color(ToDeviceColor(aColor));
+  DrawOptions drawOptions(1.f, CompositionOp::OP_OVER, AntialiasMode::NONE);
 
   if ((aRect.width == aTwipsPerPixel) || (aRect.height == aTwipsPerPixel) ||
       ((0 == aStartBevelOffset) && (0 == aEndBevelOffset))) {
     // simple line or rectangle
     if ((NS_SIDE_TOP == aStartBevelSide) || (NS_SIDE_BOTTOM == aStartBevelSide)) {
       if (1 == aRect.height)
         aContext.DrawLine(aRect.TopLeft(), aRect.BottomLeft());
       else
-        aContext.FillRect(aRect);
+        drawTarget->FillRect(NSRectToRect(aRect, appUnitsPerDevPixel, *drawTarget),
+                             color, drawOptions);
     }
     else {
       if (1 == aRect.width)
         aContext.DrawLine(aRect.TopLeft(), aRect.TopRight());
       else
-        aContext.FillRect(aRect);
+        drawTarget->FillRect(NSRectToRect(aRect, appUnitsPerDevPixel, *drawTarget),
+                             color, drawOptions);
     }
   }
   else {
     // polygon with beveling
-    int32_t appUnitsPerDevPixel = aContext.AppUnitsPerDevPixel();
     Point poly[4];
     SetPoly(NSRectToRect(aRect, appUnitsPerDevPixel), poly);
 
     Float startBevelOffset =
       NSAppUnitsToFloatPixels(aStartBevelOffset, appUnitsPerDevPixel);
     switch(aStartBevelSide) {
     case NS_SIDE_TOP:
       poly[0].x += startBevelOffset;
@@ -3546,27 +3552,24 @@ DrawSolidBorderSegment(nsRenderingContex
       break;
     case NS_SIDE_RIGHT:
       poly[2].y -= endBevelOffset;
       break;
     case NS_SIDE_LEFT:
       poly[3].y -= endBevelOffset;
     }
 
-    DrawTarget* drawTarget = aContext.GetDrawTarget();
     RefPtr<PathBuilder> builder = drawTarget->CreatePathBuilder();
     builder->MoveTo(poly[0]);
     builder->LineTo(poly[1]);
     builder->LineTo(poly[2]);
     builder->LineTo(poly[3]);
     builder->Close();
     RefPtr<Path> path = builder->Finish();
-    drawTarget->Fill(path, ColorPattern(ToDeviceColor(aColor)),
-                     DrawOptions(1.f, CompositionOp::OP_OVER,
-                                 AntialiasMode::NONE));
+    drawTarget->Fill(path, color, drawOptions);
   }
 }
 
 static void
 GetDashInfo(nscoord  aBorderLength,
             nscoord  aDashLength,
             nscoord  aTwipsPerPixel,
             int32_t& aNumDashSpaces,
--- a/layout/base/nsCaret.cpp
+++ b/layout/base/nsCaret.cpp
@@ -5,42 +5,46 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* the caret is the text cursor used, e.g., when editing */
 
 #include "nsCaret.h"
 
 #include <algorithm>
 
+#include "gfxUtils.h"
+#include "mozilla/gfx/2D.h"
 #include "nsCOMPtr.h"
 #include "nsITimer.h"
 #include "nsFrameSelection.h"
 #include "nsIFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsIDOMNode.h"
 #include "nsISelection.h"
 #include "nsISelectionPrivate.h"
 #include "nsIContent.h"
 #include "nsIPresShell.h"
+#include "nsLayoutUtils.h"
 #include "nsRenderingContext.h"
 #include "nsPresContext.h"
 #include "nsBlockFrame.h"
 #include "nsISelectionController.h"
 #include "nsTextFrame.h"
 #include "nsXULPopupManager.h"
 #include "nsMenuPopupFrame.h"
 #include "nsTextFragment.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/dom/Selection.h"
 #include "nsIBidiKeyboard.h"
 #include "nsContentUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
+using namespace mozilla::gfx;
 
 // The bidi indicator hangs off the caret to one side, to show which
 // direction the typing is in. It needs to be at least 2x2 to avoid looking like 
 // an insignificant dot
 static const int32_t kMinBidiIndicatorPixels = 2;
 
 /**
  * Find the first frame in an in-order traversal of the frame subtree rooted
@@ -515,25 +519,32 @@ void nsCaret::PaintCaret(nsDisplayListBu
   int32_t contentOffset;
   nsIFrame* frame = GetFrameAndOffset(GetSelectionInternal(),
     mOverrideContent, mOverrideOffset, &contentOffset);
   if (!frame) {
     return;
   }
   NS_ASSERTION(frame == aForFrame, "We're referring different frame");
 
-  nscolor foregroundColor = aForFrame->GetCaretColorAt(contentOffset);
-  aCtx->SetColor(foregroundColor);
+  DrawTarget* drawTarget = aCtx->GetDrawTarget();
+  int32_t appUnitsPerDevPixel = frame->PresContext()->AppUnitsPerDevPixel();
 
   nsRect caretRect;
   nsRect hookRect;
   ComputeCaretRects(frame, contentOffset, &caretRect, &hookRect);
-  aCtx->FillRect(caretRect + aOffset);
+
+  Rect devPxCaretRect =
+    NSRectToRect(caretRect + aOffset, appUnitsPerDevPixel, *drawTarget);
+  Rect devPxHookRect =
+    NSRectToRect(hookRect + aOffset, appUnitsPerDevPixel, *drawTarget);
+  ColorPattern color(ToDeviceColor(frame->GetCaretColorAt(contentOffset)));
+
+  drawTarget->FillRect(devPxCaretRect, color);
   if (!hookRect.IsEmpty()) {
-    aCtx->FillRect(hookRect + aOffset);
+    drawTarget->FillRect(devPxHookRect, color);
   }
 }
 
 NS_IMETHODIMP
 nsCaret::NotifySelectionChanged(nsIDOMDocument *, nsISelection *aDomSel,
                                 int16_t aReason)
 {
   if (aReason & nsISelectionListener::MOUSEUP_REASON)//this wont do
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -10,17 +10,19 @@
  * used during painting and hit testing
  */
 
 #include "nsDisplayList.h"
 
 #include <stdint.h>
 #include <algorithm>
 
+#include "gfxUtils.h"
 #include "mozilla/dom/TabChild.h"
+#include "mozilla/gfx/2D.h"
 #include "mozilla/layers/PLayerTransaction.h"
 #include "nsCSSRendering.h"
 #include "nsRenderingContext.h"
 #include "nsISelectionController.h"
 #include "nsIPresShell.h"
 #include "nsRegion.h"
 #include "nsStyleStructInlines.h"
 #include "nsStyleTransformMatrix.h"
@@ -1781,18 +1783,20 @@ nsDisplaySolidColor::GetBounds(nsDisplay
   *aSnap = true;
   return mBounds;
 }
 
 void
 nsDisplaySolidColor::Paint(nsDisplayListBuilder* aBuilder,
                            nsRenderingContext* aCtx)
 {
-  aCtx->SetColor(mColor);
-  aCtx->FillRect(mVisibleRect);
+  int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
+  DrawTarget* drawTarget = aCtx->GetDrawTarget();
+  Rect rect = NSRectToRect(mVisibleRect, appUnitsPerDevPixel, *drawTarget);
+  drawTarget->FillRect(rect, ColorPattern(ToDeviceColor(mColor)));
 }
 
 #ifdef MOZ_DUMP_PAINTING
 void
 nsDisplaySolidColor::WriteDebugInfo(nsACString& aTo)
 {
   aTo += nsPrintfCString(" (rgba %d,%d,%d,%d)",
                  NS_GET_R(mColor), NS_GET_G(mColor),
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -10048,20 +10048,22 @@ void ReflowCountMgr::PaintCount(const ch
   if (mPaintFrameByFrameCounts &&
       nullptr != mIndiFrameCounts &&
       aFrame != nullptr) {
     char key[KEY_BUF_SIZE_FOR_PTR];
     sprintf(key, "%p", (void*)aFrame);
     IndiReflowCounter * counter =
       (IndiReflowCounter *)PL_HashTableLookup(mIndiFrameCounts, key);
     if (counter != nullptr && counter->mName.EqualsASCII(aName)) {
+      DrawTarget* drawTarget = aRenderingContext->GetDrawTarget();
+      int32_t appUnitsPerDevPixel = aPresContext->AppUnitsPerDevPixel();
+
       aRenderingContext->ThebesContext()->Save();
       gfxPoint devPixelOffset =
-        nsLayoutUtils::PointToGfxPoint(aOffset,
-                                       aPresContext->AppUnitsPerDevPixel());
+        nsLayoutUtils::PointToGfxPoint(aOffset, appUnitsPerDevPixel);
       aRenderingContext->ThebesContext()->SetMatrix(
         aRenderingContext->ThebesContext()->CurrentMatrix().Translate(devPixelOffset));
       nsFont font(eFamily_serif, NS_FONT_STYLE_NORMAL,
                   NS_FONT_WEIGHT_NORMAL, NS_FONT_STRETCH_NORMAL, 0,
                   nsPresContext::CSSPixelsToAppUnits(11));
 
       nsRefPtr<nsFontMetrics> fm;
       aPresContext->DeviceContext()->GetMetricsFor(font,
@@ -10096,18 +10098,20 @@ void ReflowCountMgr::PaintCount(const ch
         } else {
           rc = 255;
         }
         color  = NS_RGB(rc,gc,bc);
         color2 = NS_RGB(rc/2,gc/2,bc/2);
       }
 
       nsRect rect(0,0, width+15, height+15);
-      aRenderingContext->SetColor(NS_RGB(0,0,0));
-      aRenderingContext->FillRect(rect);
+      Rect devPxRect = NSRectToRect(rect, appUnitsPerDevPixel, *drawTarget);
+      ColorPattern black(ToDeviceColor(Color(0.f, 0.f, 0.f, 1.f)));
+      drawTarget->FillRect(devPxRect, black);
+
       aRenderingContext->SetColor(color2);
       aRenderingContext->DrawString(buf, strlen(buf), x+15,y+15);
       aRenderingContext->SetColor(color);
       aRenderingContext->DrawString(buf, strlen(buf), x,y);
 
       aRenderingContext->ThebesContext()->Restore();
     }
   }
--- a/layout/forms/nsGfxCheckboxControlFrame.cpp
+++ b/layout/forms/nsGfxCheckboxControlFrame.cpp
@@ -57,24 +57,28 @@ PaintCheckMark(nsIFrame* aFrame,
 }
 
 static void
 PaintIndeterminateMark(nsIFrame* aFrame,
                        nsRenderingContext* aCtx,
                        const nsRect& aDirtyRect,
                        nsPoint aPt)
 {
+  DrawTarget* drawTarget = aCtx->GetDrawTarget();
+  int32_t appUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
+
   nsRect rect(aPt, aFrame->GetSize());
   rect.Deflate(aFrame->GetUsedBorderAndPadding());
-
   rect.y += (rect.height - rect.height/4) / 2;
   rect.height /= 4;
 
-  aCtx->SetColor(aFrame->StyleColor()->mColor);
-  aCtx->FillRect(rect);
+  Rect devPxRect = NSRectToRect(rect, appUnitsPerDevPixel, *drawTarget);
+
+  drawTarget->FillRect(devPxRect,
+                    ColorPattern(ToDeviceColor(aFrame->StyleColor()->mColor)));
 }
 
 //------------------------------------------------------------
 nsIFrame*
 NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell,
                               nsStyleContext* aContext)
 {
   return new (aPresShell) nsGfxCheckboxControlFrame(aContext);
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -1,16 +1,18 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* rendering object that goes directly inside the document's scrollbars */
 
 #include "nsCanvasFrame.h"
+
+#include "gfxUtils.h"
 #include "nsContainerFrame.h"
 #include "nsCSSRendering.h"
 #include "nsPresContext.h"
 #include "nsStyleContext.h"
 #include "nsRenderingContext.h"
 #include "nsGkAtoms.h"
 #include "nsPresShell.h"
 #include "nsIPresShell.h"
@@ -237,18 +239,20 @@ nsRect nsCanvasFrame::CanvasArea() const
 void
 nsDisplayCanvasBackgroundColor::Paint(nsDisplayListBuilder* aBuilder,
                                       nsRenderingContext* aCtx)
 {
   nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
   nsPoint offset = ToReferenceFrame();
   nsRect bgClipRect = frame->CanvasArea() + offset;
   if (NS_GET_A(mColor) > 0) {
-    aCtx->SetColor(mColor);
-    aCtx->FillRect(bgClipRect);
+    DrawTarget* drawTarget = aCtx->GetDrawTarget();
+    int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
+    Rect devPxRect = NSRectToRect(bgClipRect, appUnitsPerDevPixel, *drawTarget);
+    drawTarget->FillRect(devPxRect, ColorPattern(ToDeviceColor(mColor)));
   }
 }
 
 #ifdef MOZ_DUMP_PAINTING
 void
 nsDisplayCanvasBackgroundColor::WriteDebugInfo(nsACString& aTo)
 {
   aTo += nsPrintfCString(" (rgba %d,%d,%d,%d)",
--- a/layout/generic/nsFrameSetFrame.cpp
+++ b/layout/generic/nsFrameSetFrame.cpp
@@ -3,17 +3,19 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* rendering object for HTML <frameset> elements */
 
 #include "nsFrameSetFrame.h"
 
 #include "gfxContext.h"
+#include "gfxUtils.h"
 #include "mozilla/DebugOnly.h"
+#include "mozilla/gfx/2D.h"
 #include "mozilla/Likely.h"
 
 #include "nsGenericHTMLElement.h"
 #include "nsAttrValueInlines.h"
 #include "nsLeafFrame.h"
 #include "nsContainerFrame.h"
 #include "nsLayoutUtils.h"
 #include "nsPresContext.h"
@@ -35,16 +37,17 @@
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/HTMLFrameSetElement.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/MouseEvents.h"
 #include "nsSubDocumentFrame.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
+using namespace mozilla::gfx;
 
 // masks for mEdgeVisibility
 #define LEFT_VIS   0x0001
 #define RIGHT_VIS  0x0002
 #define TOP_VIS    0x0004
 #define BOTTOM_VIS 0x0008
 #define ALL_VIS    0x000F
 #define NONE_VIS   0x0000
@@ -1686,19 +1689,21 @@ public:
   virtual void Paint(nsDisplayListBuilder* aBuilder,
                      nsRenderingContext* aCtx) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("FramesetBlank", TYPE_FRAMESET_BLANK)
 };
 
 void nsDisplayFramesetBlank::Paint(nsDisplayListBuilder* aBuilder,
                                    nsRenderingContext* aCtx)
 {
-  nscolor white = NS_RGB(255,255,255);
-  aCtx->SetColor(white);
-  aCtx->FillRect(mVisibleRect);
+  DrawTarget* drawTarget = aCtx->GetDrawTarget();
+  int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
+  Rect rect = NSRectToRect(mVisibleRect, appUnitsPerDevPixel, *drawTarget);
+  ColorPattern white(ToDeviceColor(Color(1.f, 1.f, 1.f, 1.f)));
+  drawTarget->FillRect(rect, white);
 }
 
 void
 nsHTMLFramesetBlankFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                            const nsRect&           aDirtyRect,
                                            const nsDisplayListSet& aLists)
 {
   aLists.Content()->AppendNewToTop(
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -1492,25 +1492,24 @@ nsImageFrame::PaintImage(nsRenderingCont
     gfxPoint devPixelOffset =
       nsLayoutUtils::PointToGfxPoint(inner.TopLeft(),
                                      PresContext()->AppUnitsPerDevPixel());
     AutoRestoreTransform autoRestoreTransform(drawTarget);
     drawTarget->SetTransform(
       drawTarget->GetTransform().PreTranslate(ToPoint(devPixelOffset)));
 
     // solid white stroke:
-    Color white(1.f, 1.f, 1.f, 1.f);
-    map->Draw(this, *drawTarget, ColorPattern(ToDeviceColor(white)));
+    ColorPattern white(ToDeviceColor(Color(1.f, 1.f, 1.f, 1.f)));
+    map->Draw(this, *drawTarget, white);
 
     // then dashed black stroke over the top:
+    ColorPattern black(ToDeviceColor(Color(0.f, 0.f, 0.f, 1.f)));
     StrokeOptions strokeOptions;
     nsLayoutUtils::InitDashPattern(strokeOptions, NS_STYLE_BORDER_STYLE_DOTTED);
-    Color black(0.f, 0.f, 0.f, 1.f);
-    map->Draw(this, *drawTarget, ColorPattern(ToDeviceColor(black)),
-              strokeOptions);
+    map->Draw(this, *drawTarget, black, strokeOptions);
   }
 }
 
 void
 nsImageFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                const nsRect&           aDirtyRect,
                                const nsDisplayListSet& aLists)
 {
--- a/layout/mathml/nsMathMLChar.cpp
+++ b/layout/mathml/nsMathMLChar.cpp
@@ -1,18 +1,22 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsMathMLChar.h"
+
+#include "gfxUtils.h"
+#include "mozilla/gfx/2D.h"
 #include "mozilla/MathAlgorithms.h"
 
 #include "nsCOMPtr.h"
 #include "nsIFrame.h"
+#include "nsLayoutUtils.h"
 #include "nsPresContext.h"
 #include "nsStyleContext.h"
 #include "nsUnicharUtils.h"
 #include "nsRenderingContext.h"
 
 #include "mozilla/Preferences.h"
 #include "nsIPersistentProperties2.h"
 #include "nsIObserverService.h"
@@ -27,16 +31,17 @@
 #include "nsDisplayList.h"
 
 #include "nsMathMLOperators.h"
 #include <algorithm>
 
 #include "gfxMathTable.h"
 
 using namespace mozilla;
+using namespace mozilla::gfx;
 
 //#define NOISY_SEARCH 1
 
 // BUG 848725 Drawing failure with stretchy horizontal parenthesis when no fonts
 // are installed. "kMaxScaleFactor" is required to limit the scale for the
 // vertical and horizontal stretchy operators.
 static const float kMaxScaleFactor = 20.0;
 static const float kLargeOpFactor = float(M_SQRT2);
@@ -1822,22 +1827,25 @@ public:
   NS_DISPLAY_DECL_NAME("MathMLSelectionRect", TYPE_MATHML_SELECTION_RECT)
 private:
   nsRect    mRect;
 };
 
 void nsDisplayMathMLSelectionRect::Paint(nsDisplayListBuilder* aBuilder,
                                          nsRenderingContext* aCtx)
 {
+  DrawTarget* drawTarget = aCtx->GetDrawTarget();
+  Rect rect = NSRectToRect(mRect + ToReferenceFrame(),
+                           mFrame->PresContext()->AppUnitsPerDevPixel(),
+                           *drawTarget);
   // get color to use for selection from the look&feel object
   nscolor bgColor =
     LookAndFeel::GetColor(LookAndFeel::eColorID_TextSelectBackground,
                           NS_RGB(0, 0, 0));
-  aCtx->SetColor(bgColor);
-  aCtx->FillRect(mRect + ToReferenceFrame());
+  drawTarget->FillRect(rect, ColorPattern(ToDeviceColor(bgColor)));
 }
 
 class nsDisplayMathMLCharBackground : public nsDisplayItem {
 public:
   nsDisplayMathMLCharBackground(nsDisplayListBuilder* aBuilder,
                                 nsIFrame* aFrame, const nsRect& aRect,
                                 nsStyleContext* aStyleContext)
     : nsDisplayItem(aBuilder, aFrame), mStyleContext(aStyleContext),
--- a/layout/mathml/nsMathMLContainerFrame.cpp
+++ b/layout/mathml/nsMathMLContainerFrame.cpp
@@ -1,30 +1,35 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsMathMLContainerFrame.h"
+
+#include "gfxUtils.h"
+#include "mozilla/gfx/2D.h"
+#include "nsLayoutUtils.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsStyleContext.h"
 #include "nsNameSpaceManager.h"
 #include "nsRenderingContext.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsGkAtoms.h"
 #include "nsAutoPtr.h"
 #include "nsDisplayList.h"
 #include "nsIReflowCallback.h"
 #include "mozilla/Likely.h"
 #include "nsIScriptError.h"
 #include "nsContentUtils.h"
 #include "nsMathMLElement.h"
 
 using namespace mozilla;
+using namespace mozilla::gfx;
 
 //
 // nsMathMLContainerFrame implementation
 //
 
 NS_IMPL_FRAMEARENA_HELPERS(nsMathMLContainerFrame)
 
 NS_QUERYFRAME_HEAD(nsMathMLContainerFrame)
@@ -89,22 +94,25 @@ void nsDisplayMathMLError::Paint(nsDispl
                                  nsRenderingContext* aCtx)
 {
   // Set color and font ...
   nsRefPtr<nsFontMetrics> fm;
   nsLayoutUtils::GetFontMetricsForFrame(mFrame, getter_AddRefs(fm));
   aCtx->SetFont(fm);
 
   nsPoint pt = ToReferenceFrame();
-  aCtx->SetColor(NS_RGB(255,0,0));
-  aCtx->FillRect(nsRect(pt, mFrame->GetSize()));
+  int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
+  DrawTarget* drawTarget = aCtx->GetDrawTarget();
+  Rect rect = NSRectToRect(nsRect(pt, mFrame->GetSize()), appUnitsPerDevPixel,
+                           *drawTarget);
+  ColorPattern red(ToDeviceColor(Color(1.f, 0.f, 0.f, 1.f)));
+  drawTarget->FillRect(rect, red);
+
   aCtx->SetColor(NS_RGB(255,255,255));
-
   nscoord ascent = aCtx->FontMetrics()->MaxAscent();
-
   NS_NAMED_LITERAL_STRING(errorMsg, "invalid-markup");
   aCtx->DrawString(errorMsg.get(), uint32_t(errorMsg.Length()),
                    pt.x, pt.y+ascent);
 }
 
 /* /////////////
  * nsIMathMLFrame - support methods for stretchy elements
  * =============================================================================
--- a/layout/mathml/nsMathMLFrame.cpp
+++ b/layout/mathml/nsMathMLFrame.cpp
@@ -360,18 +360,23 @@ public:
 private:
   nsRect    mRect;
 };
 
 void nsDisplayMathMLBar::Paint(nsDisplayListBuilder* aBuilder,
                                nsRenderingContext* aCtx)
 {
   // paint the bar with the current text color
-  aCtx->SetColor(mFrame->GetVisitedDependentColor(eCSSProperty_color));
-  aCtx->FillRect(mRect + ToReferenceFrame());
+  DrawTarget* drawTarget = aCtx->GetDrawTarget();
+  Rect rect = NSRectToRect(mRect + ToReferenceFrame(),
+                           mFrame->PresContext()->AppUnitsPerDevPixel(),
+                           *drawTarget);
+  ColorPattern color(ToDeviceColor(
+                       mFrame->GetVisitedDependentColor(eCSSProperty_color)));
+  drawTarget->FillRect(rect, color);
 }
 
 void
 nsMathMLFrame::DisplayBar(nsDisplayListBuilder* aBuilder,
                           nsIFrame* aFrame, const nsRect& aRect,
                           const nsDisplayListSet& aLists) {
   if (!aFrame->StyleVisibility()->IsVisible() || aRect.IsEmpty())
     return;
--- a/layout/svg/nsSVGPathGeometryFrame.cpp
+++ b/layout/svg/nsSVGPathGeometryFrame.cpp
@@ -697,18 +697,18 @@ nsSVGPathGeometryFrame::Render(gfxContex
 
   // We wait as late as possible before setting the transform so that we don't
   // set it unnecessarily if we return early (it's an expensive operation for
   // some backends).
   gfxContextMatrixAutoSaveRestore autoRestoreTransform(aContext);
   aContext->SetMatrix(aNewTransform);
 
   if (GetStateBits() & NS_STATE_SVG_CLIPPATH_CHILD) {
-    Color white(1.0f, 1.0f, 1.0f, 1.0f);
-    drawTarget->Fill(path, ColorPattern(ToDeviceColor(white)),
+    ColorPattern white(ToDeviceColor(Color(1.0f, 1.0f, 1.0f, 1.0f)));
+    drawTarget->Fill(path, white,
                      DrawOptions(1.0f, CompositionOp::OP_OVER, aaMode));
     return;
   }
 
   gfxTextContextPaint *contextPaint =
     (gfxTextContextPaint*)drawTarget->
       GetUserData(&gfxTextContextPaint::sUserDataKey);
 
--- a/layout/xul/nsBoxFrame.cpp
+++ b/layout/xul/nsBoxFrame.cpp
@@ -1604,20 +1604,23 @@ nsBoxFrame::DrawLine(nsRenderingContext&
        aRenderingContext.DrawLine(x1,y1,x2,y2);
     else
        aRenderingContext.DrawLine(y1,x1,y2,x2);
 }
 
 void
 nsBoxFrame::FillRect(nsRenderingContext& aRenderingContext, bool aHorizontal, nscoord x, nscoord y, nscoord width, nscoord height)
 {
-    if (aHorizontal)
-       aRenderingContext.FillRect(x,y,width,height);
-    else
-       aRenderingContext.FillRect(y,x,height,width);
+    DrawTarget* drawTarget = aRenderingContext->GetDrawTarget();
+    Rect rect = NSRectToRect(aHorizontal ? nsRect(x, y, width, height) :
+                                           nsRect(y, x, height, width),
+                             PresContext()->AppUnitsPerDevPixel(),
+                             *drawTarget);
+    ColorPattern white(ToDeviceColor(Color(1.f, 1.f, 1.f, 1.f)));
+    drawTarget->FillRect(rect, white);
 }
 
 void 
 nsBoxFrame::DrawSpacer(nsPresContext* aPresContext, nsRenderingContext& aRenderingContext, bool aHorizontal, int32_t flex, nscoord x, nscoord y, nscoord size, nscoord spacerSize)
 {    
          nscoord onePixel = aPresContext->IntScaledPixelsToTwips(1);
 
      // if we do draw the coils
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -3779,17 +3779,22 @@ nsTreeBodyFrame::PaintProgressMeter(int3
       image->GetHeight(&height);
       nsSize size(width*nsDeviceContext::AppUnitsPerCSSPixel(),
                   height*nsDeviceContext::AppUnitsPerCSSPixel());
       nsLayoutUtils::DrawImage(&aRenderingContext, aPresContext, image,
           nsLayoutUtils::GetGraphicsFilterForFrame(this),
           nsRect(meterRect.TopLeft(), size), meterRect, meterRect.TopLeft(),
           aDirtyRect, imgIContainer::FLAG_NONE);
     } else {
-      aRenderingContext.FillRect(meterRect);
+      DrawTarget* drawTarget = aRenderingContext.GetDrawTarget();
+      int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel();
+      Rect rect = NSRectToRect(meterRect, appUnitsPerDevPixel, *drawTarget);
+      ColorPattern color(ToDeviceColor(
+                           GetVisitedDependentColor(eCSSProperty_color)));
+      drawTarget->FillRect(rect, color);
     }
   }
   else if (state == nsITreeView::PROGRESS_UNDETERMINED) {
     // Adjust the rect for its border and padding.
     AdjustForBorderPadding(meterContext, meterRect);
 
     bool useImageRegion = true;
     nsCOMPtr<imgIContainer> image;