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);
}
void GraphicsContext::drawFocusRing(const Color& color)
{
    if (paintingDisabled())
        return;

    float radius = (focusRingWidth() - 1) / 2.0f;
    int offset = radius + focusRingOffset();
    CGColorRef colorRef = color.isValid() ? cgColor(color) : 0;

    CGMutablePathRef focusRingPath = CGPathCreateMutable();
    const Vector<IntRect>& rects = focusRingRects();
    unsigned rectCount = rects.size();
    for (unsigned i = 0; i < rectCount; i++)
        CGPathAddRect(focusRingPath, 0, CGRectInset(rects[i], -offset, -offset));

    CGContextRef context = platformContext();
    CGContextSaveGState(context);

    CGContextBeginPath(context);
    CGContextAddPath(context, focusRingPath);

    wkDrawFocusRing(context, colorRef, radius);

    CGColorRelease(colorRef);

    CGPathRelease(focusRingPath);

    CGContextRestoreGState(context);
}
Example #3
0
Path& Path::operator=(const Path& other)
{
    CGMutablePathRef path = CGPathCreateMutableCopy(other.m_path);
    CGPathRelease(m_path);
    m_path = path;
    return *this;
}
Example #4
0
bool
PathCG::StrokeContainsPoint(const StrokeOptions &aStrokeOptions,
                            const Point &aPoint,
                            const Matrix &aTransform) const
{
  Matrix inverse = aTransform;
  inverse.Invert();
  Point transformedPoint = inverse*aPoint;
  // We could probably drop the input transform and just transform the point at the caller?
  CGPoint point = {transformedPoint.x, transformedPoint.y};

  CGContextRef cg = ScratchContext();

  CGContextSaveGState(cg);

  CGContextBeginPath(cg);
  CGContextAddPath(cg, mPath);

  SetStrokeOptions(cg, aStrokeOptions);

  CGContextReplacePathWithStrokedPath(cg);
  CGContextRestoreGState(cg);

  CGPathRef sPath = CGContextCopyPath(cg);
  bool inStroke = CGPathContainsPoint(sPath, nullptr, point, false);
  CGPathRelease(sPath);

  return inStroke;
}
Example #5
0
void Path::translate(const FloatSize& size)
{
    CGAffineTransform translation = CGAffineTransformMake(1, 0, 0, 1, size.width(), size.height());
    CGMutablePathRef newPath = CGPathCreateMutable();
    CGPathAddPath(newPath, &translation, m_path);
    CGPathRelease(m_path);
    m_path = newPath;
}
Example #6
0
void Path::clear()
{
    if (isNull())
        return;

    CGPathRelease(m_path);
    m_path = CGPathCreateMutable();
}
Example #7
0
void Path::transform(const AffineTransform& transform)
{
    CGMutablePathRef path = CGPathCreateMutable();
    CGAffineTransform transformCG = transform;
    CGPathAddPath(path, &transformCG, m_path);
    CGPathRelease(m_path);
    m_path = path;
}
Example #8
0
void Path::translate(const FloatSize& size)
{
    CGAffineTransform translation = CGAffineTransformMake(1, 0, 0, 1, size.width(), size.height());
    CGMutablePathRef newPath = CGPathCreateMutable();
    // FIXME: This is potentially wasteful to allocate an empty path only to create a transformed copy.
    CGPathAddPath(newPath, &translation, ensurePlatformPath());
    CGPathRelease(m_path);
    m_path = newPath;
}
static cairo_int_status_t
_cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
			       cairo_scaled_glyph_t *scaled_glyph)
{
    cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
    CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
    CGAffineTransform textMatrix;
    CGPathRef glyphPath;
    CTFontRef ctFont;
    cairo_path_fixed_t *path;

    if (glyph == INVALID_GLYPH) {
	_cairo_scaled_glyph_set_path (scaled_glyph, &font->base, _cairo_path_fixed_create());
	return CAIRO_STATUS_SUCCESS;
    }

    /* scale(1,-1) * font->base.scale */
    textMatrix = CGAffineTransformMake (font->base.scale.xx,
					font->base.scale.yx,
					-font->base.scale.xy,
					-font->base.scale.yy,
					0, 0);

    // glyphPath = CGFontGetGlyphPathPtr (font_face->cgFont, &textMatrix, 0, glyph);
    ctFont = CTFontCreateWithGraphicsFont (font_face->cgFont, 0.0, NULL, NULL);
    glyphPath = CTFontCreatePathForGlyph (ctFont, glyph, &textMatrix);
    CFRelease (ctFont);
    if (!glyphPath)
	return CAIRO_INT_STATUS_UNSUPPORTED;

    path = _cairo_path_fixed_create ();
    if (!path) {
	CGPathRelease (glyphPath);
	return _cairo_error(CAIRO_STATUS_NO_MEMORY);
    }

    CGPathApply (glyphPath, path, _cairo_quartz_path_apply_func);

    CGPathRelease (glyphPath);

    _cairo_scaled_glyph_set_path (scaled_glyph, &font->base, path);

    return CAIRO_STATUS_SUCCESS;
}
//-----------------------------------------------------------------------------------
static void DoTheTracking(EventRef inEvent, MTViewData* data)
{
    MouseTrackingResult	mouseResult;
    ControlPartCode	part;
    Point		qdPt;
    HIPoint		where;
    
    // Extract the mouse location (local coordinates!)
    GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(HIPoint), NULL, &where);

    CGAffineTransform m = CGAffineTransformIdentity;
    // Reset the path
    if (data->thePath != NULL)
	CGPathRelease(data->thePath);
    
    data->thePath = CGPathCreateMutable();
    
#if CG_COORDINATES
    where.y = FlipHIViewYCoordinate(data->theView, where.y);
#endif

    CGPathMoveToPoint(data->thePath, &m, where.x, where.y);
//  fprintf(stderr, "StartPt:  (%g, %g\n", where.x, where.y);
    
    while (true)
    {
	// Watch the mouse for change: qdPt comes back in global coordinates!
	TrackMouseLocation((GrafPtr)(-1), &qdPt, &mouseResult);

	// Bail out when the mouse is released
	if ( mouseResult == kMouseTrackingMouseReleased )
	{
	    HIViewSetNeedsDisplay(data->theView, true);
	    break;
	}
	
	// Need to convert from global
	where = QDGlobalToHIViewLocal(qdPt, data->theView);
#if CG_COORDINATES
	where.y = FlipHIViewYCoordinate(data->theView, where.y);
#endif
	
	CGPathAddLineToPoint(data->thePath, &m, where.x, where.y);
//	fprintf(stderr, "TrackPt:  (%g, %g\n", where.x, where.y);

	part = 0;
	SetEventParameter(inEvent, kEventParamControlPart, typeControlPartCode, sizeof(ControlPartCode), &part); 

	HIViewSetNeedsDisplay(data->theView, true);
    }
    
    // Send back the part upon which the mouse was released
    part = kControlEntireControl;
    SetEventParameter(inEvent, kEventParamControlPart, typeControlPartCode, sizeof(ControlPartCode), &part); 
}
static cairo_int_status_t
_cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
			       cairo_scaled_glyph_t *scaled_glyph)
{
    cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
    CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
    CGAffineTransform textMatrix;
    CGPathRef glyphPath;
    cairo_path_fixed_t *path;

    if (glyph == INVALID_GLYPH) {
	_cairo_scaled_glyph_set_path (scaled_glyph, &font->base, _cairo_path_fixed_create());
	return CAIRO_STATUS_SUCCESS;
    }

    textMatrix = CGAffineTransformMake (font->base.scale.xx,
					-font->base.scale.yx,
					-font->base.scale.xy,
					font->base.scale.yy,
					font->base.scale.x0,
					font->base.scale.y0);

    textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformMake (1.0, 0.0, 0.0, -1.0, 0.0, 0.0));

    glyphPath = CGFontGetGlyphPathPtr (font_face->cgFont, &textMatrix, 0, glyph);
    if (!glyphPath)
	return CAIRO_INT_STATUS_UNSUPPORTED;

    path = _cairo_path_fixed_create ();
    if (!path) {
	CGPathRelease (glyphPath);
	return _cairo_error(CAIRO_STATUS_NO_MEMORY);
    }

    CGPathApply (glyphPath, path, _cairo_quartz_path_apply_func);

    CGPathRelease (glyphPath);

    _cairo_scaled_glyph_set_path (scaled_glyph, &font->base, path);

    return CAIRO_STATUS_SUCCESS;
}
Example #12
0
bool Path::contains(const FloatPoint &point, WindRule rule) const
{
    if (!boundingRect().contains(point))
        return false;

    // CGPathContainsPoint returns false for non-closed paths, as a work-around, we copy and close the path first.  Radar 4758998 asks for a better CG API to use
    CGMutablePathRef path = copyCGPathClosingSubpaths(m_path);
    bool ret = CGPathContainsPoint(path, 0, point, rule == RULE_EVENODD ? true : false);
    CGPathRelease(path);
    return ret;
}
Example #13
0
void Path::transform(const AffineTransform& transform)
{
    if (transform.isIdentity() || isEmpty())
        return;

    CGMutablePathRef path = CGPathCreateMutable();
    CGAffineTransform transformCG = transform;
    CGPathAddPath(path, &transformCG, m_path);
    CGPathRelease(m_path);
    m_path = path;
}
DRAW_TEST_F(CGContextFlush, FillFlush, WhiteBackgroundTest<>) {
    CGContextRef context = GetDrawingContext();
    CGRect bounds = GetDrawingBounds();
    _CGContextPushBeginDraw(context);

    CGContextSetRGBFillColor(context, 1, 0, 0, 1);
    CGContextFillRect(context, bounds);

    // Flush the red fill rect
    CGContextFlush(context);

    CGContextSetRGBFillColor(context, 0, 0, 1, 1);
    CGContextFillRect(context, CGRectMake(0, 0, 300, 300));

    // We should still have red & blue rectangle should not show up.
    unsigned char* dataPtr = static_cast<unsigned char*>(CGBitmapContextGetData(context));
    ASSERT_NE(dataPtr, nullptr);

    // Validate only the red fill rect is executed.
    EXPECT_EQ(dataPtr[0], 0x00);
    EXPECT_EQ(dataPtr[1], 0x00);
    EXPECT_EQ(dataPtr[2], 0xff);
    EXPECT_EQ(dataPtr[3], 0xff);

    CGContextFlush(context);

    // We should now see the blue fill rect
    EXPECT_EQ(dataPtr[0], 0xff);
    EXPECT_EQ(dataPtr[1], 0x00);
    EXPECT_EQ(dataPtr[2], 0x00);
    EXPECT_EQ(dataPtr[3], 0xff);

    // Add some extra drawings
    CGContextClearRect(context, CGRectMake(100, 100, 200, 300));

    CGPoint center = _CGRectGetCenter(bounds);

    CGMutablePathRef concentricCirclesPath = CGPathCreateMutable();

    CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 50, 50 }, center));
    CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 100, 100 }, center));
    CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 150, 150 }, center));
    CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 200, 200 }, center));

    CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 0.5);
    CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);

    CGContextAddPath(context, concentricCirclesPath);
    CGContextDrawPath(context, kCGPathFillStroke);

    CGPathRelease(concentricCirclesPath);

    _CGContextPopEndDraw(context);
}
Example #15
0
TemporaryRef<Path>
ScaledFontMac::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget)
{
  if (aTarget->GetType() == BackendType::COREGRAPHICS || aTarget->GetType() == BackendType::COREGRAPHICS_ACCELERATED) {
      CGMutablePathRef path = CGPathCreateMutable();

      for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) {
          // XXX: we could probably fold both of these transforms together to avoid extra work
          CGAffineTransform flip = CGAffineTransformMakeScale(1, -1);
          CGPathRef glyphPath = ::CGFontGetGlyphPath(mFont, &flip, 0, aBuffer.mGlyphs[i].mIndex);

          CGAffineTransform matrix = CGAffineTransformMake(mSize, 0, 0, mSize,
                                                           aBuffer.mGlyphs[i].mPosition.x,
                                                           aBuffer.mGlyphs[i].mPosition.y);
          CGPathAddPath(path, &matrix, glyphPath);
          CGPathRelease(glyphPath);
      }
      TemporaryRef<Path> ret = new PathCG(path, FillRule::FILL_WINDING);
      CGPathRelease(path);
      return ret;
  }
  return ScaledFontBase::GetPathForGlyphs(aBuffer, aTarget);
}
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);
}
Example #17
0
void
ScaledFontMac::CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, BackendType aBackendType, const Matrix *aTransformHint)
{
  if (!(aBackendType == BackendType::COREGRAPHICS || aBackendType == BackendType::COREGRAPHICS_ACCELERATED)) {
    ScaledFontBase::CopyGlyphsToBuilder(aBuffer, aBuilder, aBackendType, aTransformHint);
    return;
  }

  PathBuilderCG *pathBuilderCG =
    static_cast<PathBuilderCG*>(aBuilder);
  // XXX: check builder type
  for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) {
    // XXX: we could probably fold both of these transforms together to avoid extra work
    CGAffineTransform flip = CGAffineTransformMakeScale(1, -1);
    CGPathRef glyphPath = ::CGFontGetGlyphPath(mFont, &flip, 0, aBuffer.mGlyphs[i].mIndex);

    CGAffineTransform matrix = CGAffineTransformMake(mSize, 0, 0, mSize,
                                                     aBuffer.mGlyphs[i].mPosition.x,
                                                     aBuffer.mGlyphs[i].mPosition.y);
    CGPathAddPath(pathBuilderCG->mCGPath, &matrix, glyphPath);
    CGPathRelease(glyphPath);
  }
}
Example #18
0
CGContextRef BitLockerSkia::cgContext()
{
    SkDevice* device = m_canvas->getDevice();
    ASSERT(device);
    if (!device)
        return 0;
    releaseIfNeeded();
    const SkBitmap& bitmap = device->accessBitmap(true);
    bitmap.lockPixels();
    void* pixels = bitmap.getPixels();
    m_cgContext = CGBitmapContextCreate(pixels, device->width(),
        device->height(), 8, bitmap.rowBytes(), CGColorSpaceCreateDeviceRGB(), 
        kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);

    // Apply device matrix.
    CGAffineTransform contentsTransform = CGAffineTransformMakeScale(1, -1);
    contentsTransform = CGAffineTransformTranslate(contentsTransform, 0, -device->height());
    CGContextConcatCTM(m_cgContext, contentsTransform);

    // Apply clip in device coordinates.
    CGMutablePathRef clipPath = CGPathCreateMutable();
    SkRegion::Iterator iter(m_canvas->getTotalClip());
    for (; !iter.done(); iter.next()) {
        IntRect rect = iter.rect();
        CGPathAddRect(clipPath, 0, rect);
    }
    CGContextAddPath(m_cgContext, clipPath);
    CGContextClip(m_cgContext);
    CGPathRelease(clipPath);

    // Apply content matrix.
    const SkMatrix& skMatrix = m_canvas->getTotalMatrix();
    CGAffineTransform affine = SkMatrixToCGAffineTransform(skMatrix);
    CGContextConcatCTM(m_cgContext, affine);

    return m_cgContext;
}
Example #19
0
PathBuilderCG::~PathBuilderCG()
{
  CGPathRelease(mCGPath);
}
Example #20
0
Path::~Path()
{
    if (m_path)
        CGPathRelease(m_path);
}
Example #21
0
void Path::clear()
{
    CGPathRelease(m_path);
    m_path = CGPathCreateMutable();
}
Example #22
0
/*
	Handle events of kEventClassControl that get sent to the Frame
*/
OSStatus HandleStarFrameControlEvents(
	EventHandlerCallRef inCallRef,
	EventRef inEvent,
	StarFrameData* frameData)
{
	OSStatus retVal = eventNotHandledErr;

	switch(GetEventKind(inEvent)) {
		case kEventControlInitialize :
			retVal = HandleStarFrameInitialize(inCallRef, inEvent, frameData);
		break;

		case kEventControlOwningWindowChanged : {
			// We only want the star-shaped opaque area of our frame view to
			// draw.  Everything else should be transparent.  To accomplish that
			// we change the features of the owning window so that only the
			// content we draw shows up on screen
			WindowRef newWindow = GetControlOwner(frameData->hiSelf);
			HIWindowChangeFeatures(newWindow, 0, kWindowIsOpaque);
		} break;

		case kEventControlBoundsChanged : {
			retVal = HandleStarFrameBoundsChanged(inCallRef, inEvent, frameData);
		} break;

        case kEventControlDraw : {
			HIRect			bounds;
			CGContextRef	cgContext;

			HIViewGetBounds(frameData->hiSelf, &bounds);
			float radius = fmin(CGRectGetWidth(bounds) / 2.0, CGRectGetHeight(bounds) / 2.0);

			GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(cgContext), NULL, &cgContext );
			if(NULL != cgContext) {
				HIThemeMenuDrawInfo drawInfo;
				CGPathRef starPath = CreatePathForStarFrame(frameData, radius);

				drawInfo.version = 0;
				drawInfo.menuType = frameData->menuType;

				// HIThemeDrawMenuBackground is designed to draw the pin striped background
				// of standard menus.  Our menu is a star and so HIThemeDrawMenuBackground may not be
				// appropriate in this case.  Nevertheless, we'll draw the standard menu background for
				// this menu and clip it to a star.
				CGContextClearRect(cgContext, bounds);
				CGContextSaveGState(cgContext);
				CGContextTranslateCTM(cgContext, radius, radius);
				CGContextAddPath(cgContext, starPath);
				CGContextClip(cgContext);
				CGContextTranslateCTM(cgContext, -radius, -radius);
				HIThemeDrawMenuBackground(&bounds, &drawInfo, cgContext, kHIThemeOrientationNormal);
				CGContextRestoreGState(cgContext);

				// The pin striping looks a bit odd sort of floating out by itself.  We'll also add
				// a lovely gray line to help emphasize the boundary
				CGContextTranslateCTM(cgContext, radius, radius);
				CGContextAddPath(cgContext, starPath);
				CGContextSetRGBStrokeColor(cgContext, 0.8, 0.8, 0.8, 1.0);
				CGContextSetLineWidth(cgContext, 1.0);
				CGContextStrokePath(cgContext);
				
				CGPathRelease(starPath);
				starPath = NULL;
			}

			retVal = noErr;
		} break;

		// Mac OS X v10.4 introduced a Window Manager bug.
		// The workaround is to implement the kEventControlGetFrameMetrics handler.
		// Even after the bug is fixed, the workaround will not be harmful.
		case kEventControlGetFrameMetrics: {
			HIViewRef contentView = NULL;

			// If we can find our content view, ask it for our metrics
			verify_noerr(HIViewFindByID(frameData->hiSelf, kHIViewWindowContentID, &contentView));
			if(NULL != contentView) {
				retVal = SendEventToEventTargetWithOptions( inEvent, GetControlEventTarget( contentView ), kEventTargetDontPropagate );
			}
		} break;

		default:
		break;
	}

	return retVal;
}
Example #23
0
Path::~Path()
{
    CGPathRelease(m_path);
}