Backed out changeset 9eeddb8dc383 (bug 931915)
authorEd Morley <emorley@mozilla.com>
Fri, 01 Nov 2013 14:34:51 +0000
changeset 153069 a750c58e428e166e541647bbe73395057ec3e072
parent 153068 c4f51fe7d6379196464dcb91b8123d0647361408
child 153070 9189b08d7d5eed7a4722a8ae8c361f53c6cde74c
push id35682
push useremorley@mozilla.com
push dateFri, 01 Nov 2013 14:35:38 +0000
treeherdermozilla-inbound@9189b08d7d5e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs931915
milestone28.0a1
backs out9eeddb8dc3838ee66ecd33b92deaa285a8de042e
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
Backed out changeset 9eeddb8dc383 (bug 931915)
gfx/thebes/gfxContext.cpp
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -17,17 +17,16 @@
 #include "gfxColor.h"
 #include "gfxMatrix.h"
 #include "gfxASurface.h"
 #include "gfxPattern.h"
 #include "gfxPlatform.h"
 #include "gfxTeeSurface.h"
 #include "GeckoProfiler.h"
 #include "gfx2DGlue.h"
-#include "mozilla/gfx/PathHelpers.h"
 #include <algorithm>
 
 #if CAIRO_HAS_DWRITE_FONT
 #include "gfxWindowsPlatform.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::gfx;
@@ -1907,21 +1906,72 @@ gfxContext::RoundedRectangle(const gfxRe
         } else {
             cairo_line_to (mCairo, pc.x, pc.y);
         }
     }
 
     cairo_close_path (mCairo);
   } else {
     EnsurePathBuilder();
-    Size radii[] = { ToSize(corners[NS_CORNER_TOP_LEFT]),
-                     ToSize(corners[NS_CORNER_TOP_RIGHT]),
-                     ToSize(corners[NS_CORNER_BOTTOM_RIGHT]),
-                     ToSize(corners[NS_CORNER_BOTTOM_LEFT]) };
-    AppendRoundedRectToPath(mPathBuilder, ToRect(rect), radii, draw_clockwise);
+
+    const gfxFloat alpha = 0.55191497064665766025;
+
+    typedef struct { gfxFloat a, b; } twoFloats;
+
+    twoFloats cwCornerMults[4] = { { -1,  0 },
+                                   {  0, -1 },
+                                   { +1,  0 },
+                                   {  0, +1 } };
+    twoFloats ccwCornerMults[4] = { { +1,  0 },
+                                    {  0, -1 },
+                                    { -1,  0 },
+                                    {  0, +1 } };
+
+    twoFloats *cornerMults = draw_clockwise ? cwCornerMults : ccwCornerMults;
+
+    gfxPoint pc, p0, p1, p2, p3;
+
+    if (draw_clockwise)
+        mPathBuilder->MoveTo(Point(Float(rect.X() + corners[NS_CORNER_TOP_LEFT].width), Float(rect.Y())));
+    else
+        mPathBuilder->MoveTo(Point(Float(rect.X() + rect.Width() - corners[NS_CORNER_TOP_RIGHT].width), Float(rect.Y())));
+
+    NS_FOR_CSS_CORNERS(i) {
+        // the corner index -- either 1 2 3 0 (cw) or 0 3 2 1 (ccw)
+        mozilla::css::Corner c = mozilla::css::Corner(draw_clockwise ? ((i+1) % 4) : ((4-i) % 4));
+
+        // i+2 and i+3 respectively.  These are used to index into the corner
+        // multiplier table, and were deduced by calculating out the long form
+        // of each corner and finding a pattern in the signs and values.
+        int i2 = (i+2) % 4;
+        int i3 = (i+3) % 4;
+
+        pc = rect.AtCorner(c);
+
+        if (corners[c].width > 0.0 && corners[c].height > 0.0) {
+            p0.x = pc.x + cornerMults[i].a * corners[c].width;
+            p0.y = pc.y + cornerMults[i].b * corners[c].height;
+
+            p3.x = pc.x + cornerMults[i3].a * corners[c].width;
+            p3.y = pc.y + cornerMults[i3].b * corners[c].height;
+
+            p1.x = p0.x + alpha * cornerMults[i2].a * corners[c].width;
+            p1.y = p0.y + alpha * cornerMults[i2].b * corners[c].height;
+
+            p2.x = p3.x - alpha * cornerMults[i3].a * corners[c].width;
+            p2.y = p3.y - alpha * cornerMults[i3].b * corners[c].height;
+
+            mPathBuilder->LineTo(ToPoint(p0));
+            mPathBuilder->BezierTo(ToPoint(p1), ToPoint(p2), ToPoint(p3));
+        } else {
+            mPathBuilder->LineTo(ToPoint(pc));
+        }
+    }
+
+    mPathBuilder->Close();
   }
 }
 
 #ifdef MOZ_DUMP_PAINTING
 void
 gfxContext::WriteAsPNG(const char* aFile)
 { 
   nsRefPtr<gfxASurface> surf = CurrentSurface();