Backout df425bca5665 (bug 893977) for breaking the build on a CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Thu, 18 Jul 2013 21:16:20 -0700
changeset 151496 c99f3b6eecd5baa662984f72fdb847ee03b9d6bf
parent 151495 a7c079a5d18a6352c035210d423ce862a5eb1a75
child 151497 a8aa3006efb903d78f93a817bbc35bf8fef512fc
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs893977
milestone25.0a1
backs outdf425bca56655b64513f2144e9a23f3ef50f36a9
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
Backout df425bca5665 (bug 893977) for breaking the build on a CLOSED TREE
gfx/2d/DrawTargetCG.cpp
--- a/gfx/2d/DrawTargetCG.cpp
+++ b/gfx/2d/DrawTargetCG.cpp
@@ -3,21 +3,18 @@
  * 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 "DrawTargetCG.h"
 #include "SourceSurfaceCG.h"
 #include "Rect.h"
 #include "ScaledFontMac.h"
 #include "Tools.h"
 #include <vector>
-#include <algorithm>
 #include "QuartzSupport.h"
 
-using namespace std;
-
 //CG_EXTERN void CGContextSetCompositeOperation (CGContextRef, PrivateCGCompositeMode);
 
 // A private API that Cairo has been using for a long time
 CG_EXTERN void CGContextSetCTM(CGContextRef, CGAffineTransform);
 
 namespace mozilla {
 namespace gfx {
 
@@ -311,247 +308,85 @@ static CGColorRef ColorToCGColor(CGColor
 }
 
 class GradientStopsCG : public GradientStops
 {
   public:
   //XXX: The skia backend uses a vector and passes in aNumStops. It should do better
   GradientStopsCG(GradientStop* aStops, uint32_t aNumStops, ExtendMode aExtendMode)
   {
-    mExtend = aExtendMode;
-    if (aExtendMode == EXTEND_CLAMP) {
-      //XXX: do the stops need to be in any particular order?
-      // what should we do about the color space here? we certainly shouldn't be
-      // recreating it all the time
-      std::vector<CGFloat> colors;
-      std::vector<CGFloat> offsets;
-      colors.reserve(aNumStops*4);
-      offsets.reserve(aNumStops);
-
-      for (uint32_t i = 0; i < aNumStops; i++) {
-        colors.push_back(aStops[i].color.r);
-        colors.push_back(aStops[i].color.g);
-        colors.push_back(aStops[i].color.b);
-        colors.push_back(aStops[i].color.a);
+    //XXX: do the stops need to be in any particular order?
+    // what should we do about the color space here? we certainly shouldn't be
+    // recreating it all the time
+    std::vector<CGFloat> colors;
+    std::vector<CGFloat> offsets;
+    colors.reserve(aNumStops*4);
+    offsets.reserve(aNumStops);
 
-        offsets.push_back(aStops[i].offset);
-      }
+    for (uint32_t i = 0; i < aNumStops; i++) {
+      colors.push_back(aStops[i].color.r);
+      colors.push_back(aStops[i].color.g);
+      colors.push_back(aStops[i].color.b);
+      colors.push_back(aStops[i].color.a);
 
-      CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
-      mGradient = CGGradientCreateWithColorComponents(colorSpace,
-                                                      &colors.front(),
-                                                      &offsets.front(),
-                                                      aNumStops);
-      CGColorSpaceRelease(colorSpace);
-    } else {
-      mGradient = nullptr;
-      mStops.reserve(aNumStops);
-      for (uint32_t i = 0; i < aNumStops; i++) {
-        mStops.push_back(aStops[i]);
-      }
+      offsets.push_back(aStops[i].offset);
     }
 
+    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+    mGradient = CGGradientCreateWithColorComponents(colorSpace,
+                                                    &colors.front(),
+                                                    &offsets.front(),
+                                                    aNumStops);
+    CGColorSpaceRelease(colorSpace);
   }
   virtual ~GradientStopsCG() {
-    if (mGradient)
-        CGGradientRelease(mGradient);
+    CGGradientRelease(mGradient);
   }
   // Will always report BACKEND_COREGRAPHICS, but it is compatible
   // with BACKEND_COREGRAPHICS_ACCELERATED
   BackendType GetBackendType() const { return BACKEND_COREGRAPHICS; }
-  // XXX this should be a union
   CGGradientRef mGradient;
-  std::vector<GradientStop> mStops;
-  ExtendMode mExtend;
 };
 
 TemporaryRef<GradientStops>
 DrawTargetCG::CreateGradientStops(GradientStop *aStops, uint32_t aNumStops,
                                   ExtendMode aExtendMode) const
 {
   return new GradientStopsCG(aStops, aNumStops, aExtendMode);
 }
 
-
 static void
-DrawLinearRepeatingGradient(CGContextRef cg, const LinearGradientPattern &aPattern, const CGRect &aExtents)
-{
-  GradientStopsCG *stops = static_cast<GradientStopsCG*>(aPattern.mStops.get());
-  CGPoint startPoint = { aPattern.mBegin.x, aPattern.mBegin.y };
-  CGPoint endPoint = { aPattern.mEnd.x, aPattern.mEnd.y };
-
-  // extend the gradient line in multiples of the existing length in both
-  // directions until it crosses an edge of the extents box.
-  double xDiff = aPattern.mEnd.x - aPattern.mBegin.x;
-  double yDiff = aPattern.mEnd.y - aPattern.mBegin.y;
-
-  int repeatCount = 1;
-  // if we don't have a line then we can't extend it
-  if (xDiff || yDiff) {
-    while (startPoint.x > aExtents.origin.x
-           && startPoint.y > aExtents.origin.y
-           && startPoint.x < (aExtents.origin.x+aExtents.size.width)
-           && startPoint.y < (aExtents.origin.y+aExtents.size.height))
-    {
-      startPoint.x -= xDiff;
-      startPoint.y -= yDiff;
-      repeatCount++;
-    }
-    while (endPoint.x > aExtents.origin.x
-           && endPoint.y > aExtents.origin.y
-           && endPoint.x < (aExtents.origin.x+aExtents.size.width)
-           && endPoint.y < (aExtents.origin.y+aExtents.size.height))
-    {
-      endPoint.x += xDiff;
-      endPoint.y += yDiff;
-      repeatCount++;
-    }
-  }
-
-  double scale = 1./repeatCount;
-
-  std::vector<CGFloat> colors;
-  std::vector<CGFloat> offsets;
-  colors.reserve(stops->mStops.size()*repeatCount*4);
-  offsets.reserve(stops->mStops.size()*repeatCount);
-
-  for (int j = 0; j < repeatCount; j++) {
-    for (uint32_t i = 0; i < stops->mStops.size(); i++) {
-      colors.push_back(stops->mStops[i].color.r);
-      colors.push_back(stops->mStops[i].color.g);
-      colors.push_back(stops->mStops[i].color.b);
-      colors.push_back(stops->mStops[i].color.a);
-
-      offsets.push_back((stops->mStops[i].offset + j)*scale);
-    }
-  }
-
-  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
-  CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace,
-                                                               &colors.front(),
-                                                               &offsets.front(),
-                                                               repeatCount*stops->mStops.size());
-  CGColorSpaceRelease(colorSpace);
-
-  CGContextDrawLinearGradient(cg, gradient, startPoint, endPoint,
-                              kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
-  CGGradientRelease(gradient);
-}
-
-static CGPoint CGRectTopLeft(CGRect a)
-{ return a.origin; }
-static CGPoint CGRectBottomLeft(CGRect a)
-{ return CGPointMake(a.origin.x, a.origin.y + a.size.height); }
-static CGPoint CGRectTopRight(CGRect a)
-{ return CGPointMake(a.origin.x + a.size.width, a.origin.y); }
-static CGPoint CGRectBottomRight(CGRect a)
-{ return CGPointMake(a.origin.x + a.size.width, a.origin.y + a.size.height); }
-
-static CGFloat
-CGPointDistance(CGPoint a, CGPoint b)
-{
-  return hypot(a.x-b.x, a.y-b.y);
-}
-
-static void
-DrawRadialRepeatingGradient(CGContextRef cg, const RadialGradientPattern &aPattern, const CGRect &aExtents)
-{
-  GradientStopsCG *stops = static_cast<GradientStopsCG*>(aPattern.mStops.get());
-  CGPoint startCenter = { aPattern.mCenter1.x, aPattern.mCenter1.y };
-  CGFloat startRadius = aPattern.mRadius1;
-  CGPoint endCenter   = { aPattern.mCenter2.x, aPattern.mCenter2.y };
-  CGFloat endRadius   = aPattern.mRadius2;
-
-  // find the maximum distance from endCenter to a corner of aExtents
-  double minimumEndRadius = endRadius;
-  minimumEndRadius = max(minimumEndRadius, CGPointDistance(endCenter, CGRectTopLeft(aExtents)));
-  minimumEndRadius = max(minimumEndRadius, CGPointDistance(endCenter, CGRectBottomLeft(aExtents)));
-  minimumEndRadius = max(minimumEndRadius, CGPointDistance(endCenter, CGRectTopRight(aExtents)));
-  minimumEndRadius = max(minimumEndRadius, CGPointDistance(endCenter, CGRectBottomRight(aExtents)));
-
-  CGFloat length = endRadius - startRadius;
-  int repeatCount = 1;
-  while (endRadius < minimumEndRadius) {
-    endRadius += length;
-    repeatCount++;
-  }
-
-  while (startRadius-length >= 0) {
-    startRadius -= length;
-    repeatCount++;
-  }
-
-  double scale = 1./repeatCount;
-
-  std::vector<CGFloat> colors;
-  std::vector<CGFloat> offsets;
-  colors.reserve(stops->mStops.size()*repeatCount*4);
-  offsets.reserve(stops->mStops.size()*repeatCount);
-  for (int j = 0; j < repeatCount; j++) {
-    for (uint32_t i = 0; i < stops->mStops.size(); i++) {
-      colors.push_back(stops->mStops[i].color.r);
-      colors.push_back(stops->mStops[i].color.g);
-      colors.push_back(stops->mStops[i].color.b);
-      colors.push_back(stops->mStops[i].color.a);
-
-      offsets.push_back((stops->mStops[i].offset + j)*scale);
-    }
-  }
-
-  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
-  CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace,
-                                                               &colors.front(),
-                                                               &offsets.front(),
-                                                               repeatCount*stops->mStops.size());
-  CGColorSpaceRelease(colorSpace);
-
-  //XXX: are there degenerate radial gradients that we should avoid drawing?
-  CGContextDrawRadialGradient(cg, gradient, startCenter, startRadius, endCenter, endRadius,
-                              kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
-  CGGradientRelease(gradient);
-}
-
-static void
-DrawGradient(CGContextRef cg, const Pattern &aPattern, const CGRect &aExtents)
+DrawGradient(CGContextRef cg, const Pattern &aPattern)
 {
   if (aPattern.GetType() == PATTERN_LINEAR_GRADIENT) {
     const LinearGradientPattern& pat = static_cast<const LinearGradientPattern&>(aPattern);
     GradientStopsCG *stops = static_cast<GradientStopsCG*>(pat.mStops.get());
-    if (stops->mExtend == EXTEND_CLAMP) {
-
-      // XXX: we should take the m out of the properties of LinearGradientPatterns
-      CGPoint startPoint = { pat.mBegin.x, pat.mBegin.y };
-      CGPoint endPoint   = { pat.mEnd.x,   pat.mEnd.y };
+    // XXX: we should take the m out of the properties of LinearGradientPatterns
+    CGPoint startPoint = { pat.mBegin.x, pat.mBegin.y };
+    CGPoint endPoint   = { pat.mEnd.x,   pat.mEnd.y };
 
-      // Canvas spec states that we should avoid drawing degenerate gradients (XXX: should this be in common code?)
-      //if (startPoint.x == endPoint.x && startPoint.y == endPoint.y)
-      //  return;
+    // Canvas spec states that we should avoid drawing degenerate gradients (XXX: should this be in common code?)
+    //if (startPoint.x == endPoint.x && startPoint.y == endPoint.y)
+    //  return;
 
-      CGContextDrawLinearGradient(cg, stops->mGradient, startPoint, endPoint,
-                                  kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
-    } else if (stops->mExtend == EXTEND_REPEAT) {
-      DrawLinearRepeatingGradient(cg, pat, aExtents);
-    }
+    CGContextDrawLinearGradient(cg, stops->mGradient, startPoint, endPoint,
+                                kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
   } else if (aPattern.GetType() == PATTERN_RADIAL_GRADIENT) {
     const RadialGradientPattern& pat = static_cast<const RadialGradientPattern&>(aPattern);
     GradientStopsCG *stops = static_cast<GradientStopsCG*>(pat.mStops.get());
-    if (stops->mExtend == EXTEND_CLAMP) {
 
-      // XXX: we should take the m out of the properties of RadialGradientPatterns
-      CGPoint startCenter = { pat.mCenter1.x, pat.mCenter1.y };
-      CGFloat startRadius = pat.mRadius1;
-      CGPoint endCenter   = { pat.mCenter2.x, pat.mCenter2.y };
-      CGFloat endRadius   = pat.mRadius2;
+    // XXX: we should take the m out of the properties of RadialGradientPatterns
+    CGPoint startCenter = { pat.mCenter1.x, pat.mCenter1.y };
+    CGFloat startRadius = pat.mRadius1;
+    CGPoint endCenter   = { pat.mCenter2.x, pat.mCenter2.y };
+    CGFloat endRadius   = pat.mRadius2;
 
-      //XXX: are there degenerate radial gradients that we should avoid drawing?
-      CGContextDrawRadialGradient(cg, stops->mGradient, startCenter, startRadius, endCenter, endRadius,
-                                  kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
-    } else if (stops->mExtend == EXTEND_REPEAT) {
-      DrawRadialRepeatingGradient(cg, pat, aExtents);
-    }
+    //XXX: are there degenerate radial gradients that we should avoid drawing?
+    CGContextDrawRadialGradient(cg, stops->mGradient, startCenter, startRadius, endCenter, endRadius,
+                                kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
   } else {
     assert(0);
   }
 
 }
 
 static void
 drawPattern(void *info, CGContextRef context)
@@ -714,17 +549,17 @@ DrawTargetCG::MaskSurface(const Pattern 
   IntSize size = aMask->GetSize();
 
   CGContextClipToMask(cg, CGRectMake(aOffset.x, -(aOffset.y + size.height), size.width, size.height), image);
 
   CGContextScaleCTM(cg, 1, -1);
   if (isGradient(aSource)) {
     // we shouldn't need to clip to an additional rectangle
     // as the cliping to the mask should be sufficient.
-    DrawGradient(cg, aSource, CGRectMake(aOffset.x, aOffset.y, size.width, size.height));
+    DrawGradient(cg, aSource);
   } else {
     SetFillFromPattern(cg, mColorSpace, aSource);
     CGContextFillRect(cg, CGRectMake(aOffset.x, aOffset.y, size.width, size.height));
   }
 
   fixer.Fix(mCg);
 
   CGContextRestoreGState(mCg);
@@ -745,17 +580,17 @@ DrawTargetCG::FillRect(const Rect &aRect
   CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp);
   CGContextSetAlpha(mCg, aDrawOptions.mAlpha);
   CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
 
   CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
 
   if (isGradient(aPattern)) {
     CGContextClipToRect(cg, RectToCGRect(aRect));
-    DrawGradient(cg, aPattern, RectToCGRect(aRect));
+    DrawGradient(cg, aPattern);
   } else {
     SetFillFromPattern(cg, mColorSpace, aPattern);
     CGContextFillRect(cg, RectToCGRect(aRect));
   }
 
   fixer.Fix(mCg);
   CGContextRestoreGState(mCg);
 }
@@ -777,20 +612,19 @@ DrawTargetCG::StrokeLine(const Point &p1
   CGContextBeginPath(cg);
   CGContextMoveToPoint(cg, p1.x, p1.y);
   CGContextAddLineToPoint(cg, p2.x, p2.y);
 
   SetStrokeOptions(cg, aStrokeOptions);
 
   if (isGradient(aPattern)) {
     CGContextReplacePathWithStrokedPath(cg);
-    CGRect extents = CGContextGetPathBoundingBox(cg);
     //XXX: should we use EO clip here?
     CGContextClip(cg);
-    DrawGradient(cg, aPattern, extents);
+    DrawGradient(cg, aPattern);
   } else {
     SetStrokeFromPattern(cg, mColorSpace, aPattern);
     CGContextStrokePath(cg);
   }
 
   fixer.Fix(mCg);
   CGContextRestoreGState(mCg);
 }
@@ -814,20 +648,19 @@ DrawTargetCG::StrokeRect(const Rect &aRe
 
   SetStrokeOptions(cg, aStrokeOptions);
 
   if (isGradient(aPattern)) {
     // There's no CGContextClipStrokeRect so we do it by hand
     CGContextBeginPath(cg);
     CGContextAddRect(cg, RectToCGRect(aRect));
     CGContextReplacePathWithStrokedPath(cg);
-    CGRect extents = CGContextGetPathBoundingBox(cg);
     //XXX: should we use EO clip here?
     CGContextClip(cg);
-    DrawGradient(cg, aPattern, extents);
+    DrawGradient(cg, aPattern);
   } else {
     SetStrokeFromPattern(cg, mColorSpace, aPattern);
     CGContextStrokeRect(cg, RectToCGRect(aRect));
   }
 
   fixer.Fix(mCg);
   CGContextRestoreGState(mCg);
 }
@@ -866,20 +699,19 @@ DrawTargetCG::Stroke(const Path *aPath, 
   assert(aPath->GetBackendType() == BACKEND_COREGRAPHICS);
   const PathCG *cgPath = static_cast<const PathCG*>(aPath);
   CGContextAddPath(cg, cgPath->GetPath());
 
   SetStrokeOptions(cg, aStrokeOptions);
 
   if (isGradient(aPattern)) {
     CGContextReplacePathWithStrokedPath(cg);
-    CGRect extents = CGContextGetPathBoundingBox(cg);
     //XXX: should we use EO clip here?
     CGContextClip(cg);
-    DrawGradient(cg, aPattern, extents);
+    DrawGradient(cg, aPattern);
   } else {
     // XXX: we could put fill mode into the path fill rule if we wanted
 
     SetStrokeFromPattern(cg, mColorSpace, aPattern);
     CGContextStrokePath(cg);
   }
 
   fixer.Fix(mCg);
@@ -903,70 +735,44 @@ DrawTargetCG::Fill(const Path *aPath, co
   CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
 
   CGContextBeginPath(cg);
   // XXX: we could put fill mode into the path fill rule if we wanted
   const PathCG *cgPath = static_cast<const PathCG*>(aPath);
 
   if (isGradient(aPattern)) {
     // setup a clip to draw the gradient through
-    CGRect extents;
     if (CGPathIsEmpty(cgPath->GetPath())) {
       // Adding an empty path will cause us not to clip
       // so clip everything explicitly
       CGContextClipToRect(mCg, CGRectZero);
-      extents = CGRectZero;
     } else {
       CGContextAddPath(cg, cgPath->GetPath());
-      extents = CGContextGetPathBoundingBox(cg);
       if (cgPath->GetFillRule() == FILL_EVEN_ODD)
         CGContextEOClip(mCg);
       else
         CGContextClip(mCg);
     }
 
-    DrawGradient(cg, aPattern, extents);
+    DrawGradient(cg, aPattern);
   } else {
     CGContextAddPath(cg, cgPath->GetPath());
 
     SetFillFromPattern(cg, mColorSpace, aPattern);
 
     if (cgPath->GetFillRule() == FILL_EVEN_ODD)
       CGContextEOFillPath(cg);
     else
       CGContextFillPath(cg);
   }
 
   fixer.Fix(mCg);
   CGContextRestoreGState(mCg);
 }
 
-CGRect ComputeGlyphsExtents(CGRect *bboxes, CGPoint *positions, CFIndex count, float scale)
-{
-  CGFloat x1, x2, y1, y2;
-  if (count < 1)
-    return CGRectZero;
-
-  x1 = bboxes[0].origin.x + positions[0].x;
-  x2 = bboxes[0].origin.x + positions[0].x + scale*bboxes[0].size.width;
-  y1 = bboxes[0].origin.y + positions[0].y;
-  y2 = bboxes[0].origin.y + positions[0].y + scale*bboxes[0].size.height;
-
-  // accumulate max and minimum coordinates
-  for (int i = 1; i < count; i++) {
-    x1 = min(x1, bboxes[i].origin.x + positions[i].x);
-    y1 = min(y1, bboxes[i].origin.y + positions[i].y);
-    x2 = max(x2, bboxes[i].origin.x + positions[i].x + scale*bboxes[i].size.width);
-    y2 = max(y2, bboxes[i].origin.y + positions[i].y + scale*bboxes[i].size.height);
-  }
-
-  CGRect extents = {{x1, y1}, {x2-x1, y2-y1}};
-  return extents;
-}
-
 
 void
 DrawTargetCG::FillGlyphs(ScaledFont *aFont, const GlyphBuffer &aBuffer, const Pattern &aPattern, const DrawOptions &aDrawOptions,
                          const GlyphRenderingOptions*)
 {
   MarkChanged();
 
   assert(aBuffer.mNumGlyphs);
@@ -1000,37 +806,27 @@ DrawTargetCG::FillGlyphs(ScaledFont *aFo
     // XXX: CGPointMake might not be inlined
     positions[i] = CGPointMake(aBuffer.mGlyphs[i].mPosition.x,
                               -aBuffer.mGlyphs[i].mPosition.y);
   }
 
   //XXX: CGContextShowGlyphsAtPositions is 10.5+ for older versions use CGContextShowGlyphsWithAdvances
   if (isGradient(aPattern)) {
     CGContextSetTextDrawingMode(cg, kCGTextClip);
-    CGRect extents;
     if (ScaledFontMac::CTFontDrawGlyphsPtr != nullptr) {
-      CGRect *bboxes = new CGRect[aBuffer.mNumGlyphs];
-      CTFontGetBoundingRectsForGlyphs(macFont->mCTFont, kCTFontDefaultOrientation,
-                                      &glyphs.front(), bboxes, aBuffer.mNumGlyphs);
-      extents = ComputeGlyphsExtents(bboxes, &positions.front(), aBuffer.mNumGlyphs, 1.0f);
       ScaledFontMac::CTFontDrawGlyphsPtr(macFont->mCTFont, &glyphs.front(),
-                                         &positions.front(), aBuffer.mNumGlyphs, cg);
-      delete bboxes;
+                                         &positions.front(),
+                                         aBuffer.mNumGlyphs, cg);
     } else {
-      CGRect *bboxes = new CGRect[aBuffer.mNumGlyphs];
-      CGFontGetGlyphBBoxes(macFont->mFont, &glyphs.front(), aBuffer.mNumGlyphs, bboxes);
-      extents = ComputeGlyphsExtents(bboxes, &positions.front(), aBuffer.mNumGlyphs, macFont->mSize);
-
       CGContextSetFont(cg, macFont->mFont);
       CGContextSetFontSize(cg, macFont->mSize);
       CGContextShowGlyphsAtPositions(cg, &glyphs.front(), &positions.front(),
                                      aBuffer.mNumGlyphs);
-      delete bboxes;
     }
-    DrawGradient(cg, aPattern, extents);
+    DrawGradient(cg, aPattern);
   } else {
     //XXX: with CoreGraphics we can stroke text directly instead of going
     // through GetPath. It would be nice to add support for using that
     CGContextSetTextDrawingMode(cg, kCGTextFill);
     SetFillFromPattern(cg, mColorSpace, aPattern);
     if (ScaledFontMac::CTFontDrawGlyphsPtr != nullptr) {
       ScaledFontMac::CTFontDrawGlyphsPtr(macFont->mCTFont, &glyphs.front(),
                                          &positions.front(),