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 211058 2cb4b5b083746d01421f6c38fa71d6212b02ec2d
parent 211057 045556326c7cf9c0dff9430aaa286f0feda8cee6
child 211059 71211c4a4acc7e93d58c8284735aaa3f9ac1a14c
push id50635
push userjwatt@jwatt.org
push dateSun, 19 Oct 2014 12:55:12 +0000
treeherdermozilla-inbound@2cb4b5b08374 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1083753
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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;