Bug 1093066 - Get rid of gfxContext's Stroke() methods. r=mattwoodrow
authorJonathan Watt <jwatt@jwatt.org>
Wed, 05 Nov 2014 09:16:37 +0000
changeset 214077 d960256cdb805e6f68f23d9fe7f9879e9dc0d5b0
parent 214076 2acbf923b6a82bb6b038c6076bd210c2e52d5a00
child 214078 ef937bcf1a8275e9b5d365d614f378cd6d406806
push id27771
push userryanvm@gmail.com
push dateWed, 05 Nov 2014 19:04:24 +0000
treeherdermozilla-central@305b4fecce99 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1093066
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 1093066 - Get rid of gfxContext's Stroke() methods. r=mattwoodrow
gfx/thebes/gfxContext.cpp
gfx/thebes/gfxContext.h
layout/svg/SVGTextFrame.cpp
layout/svg/nsSVGUtils.h
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -220,40 +220,16 @@ void gfxContext::SetPath(Path* path)
 gfxPoint
 gfxContext::CurrentPoint()
 {
   EnsurePathBuilder();
   return ThebesPoint(mPathBuilder->CurrentPoint());
 }
 
 void
-gfxContext::Stroke()
-{
-  Stroke(PatternFromState(this));
-}
-
-void
-gfxContext::Stroke(const Pattern& aPattern)
-{
-  AzureState &state = CurrentState();
-  if (mPathIsRect) {
-    MOZ_ASSERT(!mTransformChanged);
-
-    mDT->StrokeRect(mRect, aPattern,
-                    state.strokeOptions,
-                    DrawOptions(1.0f, GetOp(), state.aaMode));
-  } else {
-    EnsurePath();
-
-    mDT->Stroke(mPath, aPattern, state.strokeOptions,
-                DrawOptions(1.0f, GetOp(), state.aaMode));
-  }
-}
-
-void
 gfxContext::Fill()
 {
   Fill(PatternFromState(this));
 }
 
 void
 gfxContext::Fill(const Pattern& aPattern)
 {
@@ -519,36 +495,16 @@ gfxContext::SetAntialiasMode(AntialiasMo
 
 AntialiasMode
 gfxContext::CurrentAntialiasMode() const
 {
   return CurrentState().aaMode;
 }
 
 void
-gfxContext::SetDash(gfxLineType ltype)
-{
-  static double dash[] = {5.0, 5.0};
-  static double dot[] = {1.0, 1.0};
-
-  switch (ltype) {
-      case gfxLineDashed:
-          SetDash(dash, 2, 0.0);
-          break;
-      case gfxLineDotted:
-          SetDash(dot, 2, 0.0);
-          break;
-      case gfxLineSolid:
-      default:
-          SetDash(nullptr, 0, 0.0);
-          break;
-  }
-}
-
-void
 gfxContext::SetDash(gfxFloat *dashes, int ndash, gfxFloat offset)
 {
   AzureState &state = CurrentState();
 
   state.dashPattern.SetLength(ndash);
   for (int i = 0; i < ndash; i++) {
     state.dashPattern[i] = Float(dashes[i]);
   }
--- a/gfx/thebes/gfxContext.h
+++ b/gfx/thebes/gfxContext.h
@@ -96,25 +96,16 @@ public:
     void Save();
     void Restore();
 
     /**
      ** Paths & Drawing
      **/
 
     /**
-     * Stroke the current path using the current settings (such as line
-     * width and color).
-     * A path is set up using functions such as Line, Rectangle and Arc.
-     *
-     * Does not consume the current path.
-     */
-    void Stroke();
-    void Stroke(const Pattern& aPattern);
-    /**
      * Fill the current path according to the current settings.
      *
      * Does not consume the current path.
      */
     void Fill();
     void Fill(const Pattern& aPattern);
 
     /**
@@ -363,23 +354,16 @@ public:
      * and calls cairo_fill.
      */
     void DrawSurface(gfxASurface *surface, const gfxSize& size);
 
     /**
      ** Line Properties
      **/
 
-    typedef enum {
-        gfxLineSolid,
-        gfxLineDashed,
-        gfxLineDotted
-    } gfxLineType;
-
-    void SetDash(gfxLineType ltype);
     void SetDash(gfxFloat *dashes, int ndash, gfxFloat offset);
     // Return true if dashing is set, false if it's not enabled or the
     // context is in an error state.  |offset| can be nullptr to mean
     // "don't care".
     bool CurrentDash(FallibleTArray<gfxFloat>& dashes, gfxFloat* offset) const;
     // Returns 0.0 if dashing isn't enabled.
     gfxFloat CurrentDashOffset() const;
 
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -2984,18 +2984,40 @@ SVGTextDrawPathCallbacks::StrokeGeometry
 {
   // We don't paint the stroke when we are filling with a selection color.
   if (mColor == NS_SAME_AS_FOREGROUND_COLOR ||
       mColor == NS_40PERCENT_FOREGROUND_COLOR) {
     if (nsSVGUtils::HasStroke(mFrame, /*aContextPaint*/ nullptr)) {
       GeneralPattern strokePattern;
       nsSVGUtils::MakeStrokePatternFor(mFrame, gfx, &strokePattern, /*aContextPaint*/ nullptr);
       if (strokePattern.GetPattern()) {
-        nsSVGUtils::SetupCairoStrokeGeometry(mFrame, gfx, /*aContextPaint*/ nullptr);
-        gfx->Stroke(strokePattern);
+        if (!mFrame->GetParent()->GetContent()->IsSVG()) {
+          // The cast that follows would be unsafe
+          MOZ_ASSERT(false, "Our nsTextFrame's parent's content should be SVG");
+          return;
+        }
+        nsSVGElement* svgOwner =
+          static_cast<nsSVGElement*>(mFrame->GetParent()->GetContent());
+
+        // Apply any stroke-specific transform
+        gfxMatrix outerSVGToUser;
+        if (nsSVGUtils::GetNonScalingStrokeTransform(mFrame, &outerSVGToUser) &&
+            outerSVGToUser.Invert()) {
+          gfx->Multiply(outerSVGToUser);
+        }
+
+        RefPtr<Path> path = gfx->GetPath();
+        SVGContentUtils::AutoStrokeOptions strokeOptions;
+        SVGContentUtils::GetStrokeOptions(&strokeOptions, svgOwner,
+                                          mFrame->StyleContext(),
+                                          /*aContextPaint*/ nullptr);
+        DrawOptions drawOptions;
+        drawOptions.mAntialiasMode =
+          nsSVGUtils::ToAntialiasMode(mFrame->StyleSVG()->mTextRendering);
+        gfx->GetDrawTarget()->Stroke(path, strokePattern, strokeOptions);
       }
     }
   }
 }
 
 //----------------------------------------------------------------------
 // SVGTextContextPaint methods:
 
--- a/layout/svg/nsSVGUtils.h
+++ b/layout/svg/nsSVGUtils.h
@@ -182,16 +182,17 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsISVGFilt
  * General functions used by all of SVG layout and possibly content code.
  * If a method is used by content and depends only on other content methods
  * it should go in SVGContentUtils instead.
  */
 class nsSVGUtils
 {
 public:
   typedef mozilla::dom::Element Element;
+  typedef mozilla::gfx::AntialiasMode AntialiasMode;
   typedef mozilla::gfx::FillRule FillRule;
   typedef mozilla::gfx::GeneralPattern GeneralPattern;
 
   static void Init();
 
   /**
    * Gets the nearest nsSVGInnerSVGFrame or nsSVGOuterSVGFrame frame. aFrame
    * must be an SVG frame. If aFrame is of type nsGkAtoms::svgOuterSVGFrame,
@@ -528,16 +529,21 @@ public:
    */
   static uint16_t GetGeometryHitTestFlags(nsIFrame* aFrame);
 
   static FillRule ToFillRule(uint8_t aFillRule) {
     return aFillRule == NS_STYLE_FILL_RULE_EVENODD ?
              FillRule::FILL_EVEN_ODD : FillRule::FILL_WINDING;
   }
 
+  static AntialiasMode ToAntialiasMode(uint8_t aTextRendering) {
+    return aTextRendering == NS_STYLE_TEXT_RENDERING_OPTIMIZESPEED ?
+             AntialiasMode::NONE : AntialiasMode::SUBPIXEL;
+  }
+
   /**
    * Render a SVG glyph.
    * @param aElement the SVG glyph element to render
    * @param aContext the thebes aContext to draw to
    * @param aDrawMode fill or stroke or both (see DrawMode)
    * @return true if rendering succeeded
    */
   static bool PaintSVGGlyph(Element* aElement, gfxContext* aContext,