Beispiel #1
0
void
PathBuilderCG::Arc(const Point &aOrigin, Float aRadius, Float aStartAngle,
                 Float aEndAngle, bool aAntiClockwise)
{
  if (!aOrigin.IsFinite() || !IsFinite(aRadius) ||
      !IsFinite(aStartAngle) || !IsFinite(aEndAngle)) {
    return;
  }

  // Disabled for now due to a CG bug when using CGPathAddArc with stroke
  // dashing and rotation transforms that are multiples of 90 degrees. See:
  // https://bugzilla.mozilla.org/show_bug.cgi?id=949661#c8
#if 0
  // Core Graphic's initial coordinate system is y-axis up, whereas Moz2D's is
  // y-axis down. Core Graphics therefore considers "clockwise" to mean "sweep
  // in the direction of decreasing angle" whereas Moz2D considers it to mean
  // "sweep in the direction of increasing angle". In other words if this
  // Moz2D method is instructed to sweep anti-clockwise we need to tell
  // CGPathAddArc to sweep clockwise, and vice versa. Hence why we pass the
  // value of aAntiClockwise directly to CGPathAddArc's "clockwise" bool
  // parameter.
  CGPathAddArc(mCGPath, nullptr,
               aOrigin.x, aOrigin.y,
               aRadius,
               aStartAngle,
               aEndAngle,
               aAntiClockwise);
#endif
  ArcToBezier(this, aOrigin, Size(aRadius, aRadius), aStartAngle, aEndAngle,
              aAntiClockwise);
}
void doRotatedEllipsesWithCGPath(CGContextRef context)
{
	int i, totreps = 144.;
	CGMutablePathRef path = NULL;
	float  tint = 1., tintIncrement = 1./totreps;
	// Create a new transform consisting of a 45 degree rotation.
	CGAffineTransform theTransform = CGAffineTransformMakeRotation(M_PI/4);
	// Apply a scaling transformation to the transform just created.
	theTransform = CGAffineTransformScale(theTransform, 1, 2);
	// Create a mutable CGPath object.
	path = CGPathCreateMutable();
	if(!path){
		fprintf(stderr, "Couldn't create path!\n");
		return;
	}
	// Add a circular arc to the CGPath object, transformed
	// by an affine transform.
	CGPathAddArc(path, &theTransform, 0., 0., 45., 0., 2*M_PI, false); 
	// Close the CGPath object.
	CGPathCloseSubpath(path);
	
	// Place the first ellipse at a good location.	
	CGContextTranslateCTM(context, 100., 100.);
	for (i = 0 ; i < totreps ; i++){
		CGContextBeginPath(context);
		// Add the CGPath object to the current path in the context.
		CGContextAddPath(context, path);
		
		// Set the fill color for this instance of the ellipse.
		CGContextSetRGBFillColor(context, tint, 0., 0., 1.);
		// Filling the path implicitly closes it.
		CGContextFillPath(context);
		// Compute the next tint color.
		tint -= tintIncrement;
		// Move over for the next ellipse.
		CGContextTranslateCTM(context, 1, 0.);
	}
	// Release the path when done with it.
	CGPathRelease(path);
}
DRAW_TEST_P(CGContextFillMode, OverlappedEllipses) {
    CGContextRef context = GetDrawingContext();
    CGRect bounds = GetDrawingBounds();
    bounds = CGRectInset(bounds, 16.f, 16.f);
    CGFloat width = bounds.size.width;
    CGFloat height = bounds.size.height;
    CGFloat xstart = bounds.origin.x;
    CGFloat ystart = bounds.origin.y;

    CGPathDrawingMode fillMode = GetParam();

    CGMutablePathRef leftCircles = CGPathCreateMutable();

    CGPathMoveToPoint(leftCircles, NULL, xstart + .25 * width + .4 * height, ystart + .5 * height);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .4 * height, 0, M_PI, true);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .4 * height, M_PI, 0, true);

    CGPathMoveToPoint(leftCircles, NULL, xstart + .25 * width + .3 * height, ystart + .5 * height);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .3 * height, 0, M_PI, true);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .3 * height, M_PI, 0, true);

    CGPathMoveToPoint(leftCircles, NULL, xstart + .25 * width + .2 * height, ystart + .5 * height);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .2 * height, 0, M_PI, true);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .2 * height, M_PI, 0, true);

    CGPathMoveToPoint(leftCircles, NULL, xstart + .25 * width + .1 * height, ystart + .5 * height);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .1 * height, 0, M_PI, true);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .1 * height, M_PI, 0, true);

    CGPathCloseSubpath(leftCircles);

    CGMutablePathRef rightCircles = CGPathCreateMutable();

    CGPathMoveToPoint(rightCircles, NULL, xstart + .75 * width + .4 * height, ystart + .5 * height);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .4 * height, 0, M_PI, false);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .4 * height, M_PI, 0, false);

    CGPathMoveToPoint(rightCircles, NULL, xstart + .75 * width + .3 * height, ystart + .5 * height);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .3 * height, 0, M_PI, true);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .3 * height, M_PI, 0, true);

    CGPathMoveToPoint(rightCircles, NULL, xstart + .75 * width + .2 * height, ystart + .5 * height);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .2 * height, 0, M_PI, false);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .2 * height, M_PI, 0, false);

    CGPathMoveToPoint(rightCircles, NULL, xstart + .75 * width + .1 * height, ystart + .5 * height);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .1 * height, 0, M_PI, true);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .1 * height, M_PI, 0, true);

    CGPathCloseSubpath(rightCircles);

    CGContextAddPath(context, leftCircles);
    CGContextAddPath(context, rightCircles);
    CGContextSetRGBFillColor(context, 0, 0, 1, 1);
    CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
    CGContextDrawPath(context, fillMode);

    CGPathRelease(leftCircles);
    CGPathRelease(rightCircles);
}
Beispiel #4
0
void Path::addArc(const FloatPoint& p, float r, float sa, float ea, bool clockwise)
{
    // Workaround for <rdar://problem/5189233> CGPathAddArc hangs or crashes when passed inf as start or end angle
    if (isfinite(sa) && isfinite(ea))
        CGPathAddArc(m_path, 0, p.x(), p.y(), r, sa, ea, clockwise);
}