CGAffineTransform PDFPageGetDrawingTransform(CGPDFPageRef page, CGPDFBox box, float scale) { CGRect boxRect = CGPDFPageGetBoxRect(page, box); int rotation = PDFPageGetRotation(page); CGAffineTransform transform = CGAffineTransformMakeScale(scale, scale); transform = CGAffineTransformRotate(transform, -(rotation * M_PI_2)); switch (rotation) { case 1: transform = CGAffineTransformTranslate(transform, -CGRectGetWidth(boxRect), 0); break; case 2: transform = CGAffineTransformTranslate(transform, -CGRectGetWidth(boxRect), 0); transform = CGAffineTransformTranslate(transform, 0, -CGRectGetHeight(boxRect)); break; case 3: transform = CGAffineTransformTranslate(transform, 0, -CGRectGetHeight(boxRect)); break; default: break; } transform = CGAffineTransformTranslate(transform, -boxRect.origin.x, -boxRect.origin.y); return transform; }
void drawWithColorBlendMode(CGContextRef context, CFURLRef url) { // A pleasant green color. float green[4] = { 0.584, 0.871, 0.318, 1.0 }; CGRect insetRect, pdfRect; // Create a CGPDFDocument object from the URL. CGPDFDocumentRef pdfDoc = CGPDFDocumentCreateWithURL(url); if(pdfDoc == NULL){ fprintf(stderr, "Couldn't create CGPDFDocument from URL!\n"); return; } // Obtain the media box for page 1 of the PDF document. pdfRect = CGPDFDocumentGetMediaBox(pdfDoc, 1); // Set the origin of the rectangle to (0,0). pdfRect.origin.x = pdfRect.origin.y = 0; // Graphic 1, the left portion of the figure. CGContextTranslateCTM(context, 20, 10 + CGRectGetHeight(pdfRect)/2); // Draw the PDF document. CGContextDrawPDFDocument(context, pdfRect, pdfDoc, 1); // Set the fill color space to that returned by getTheCalibratedRGBColorSpace. CGContextSetFillColorSpace(context, getTheCalibratedRGBColorSpace()); // Set the fill color to green. CGContextSetFillColor(context, green); // Graphic 2, the top-right portion of the figure. CGContextTranslateCTM(context, CGRectGetWidth(pdfRect) + 10, CGRectGetHeight(pdfRect)/2 + 10); // Draw the PDF document again. CGContextDrawPDFDocument(context, pdfRect, pdfDoc, 1); // Make a fill rectangle that is the same size as the PDF document // but inset each side by 80 units in x and 20 units in y. insetRect = CGRectInset(pdfRect, 80, 20); // Fill the rectangle with green. Because the fill color is opaque and // the blend mode is Normal, this obscures the drawing underneath. CGContextFillRect(context, insetRect); // Graphic 3, the bottom-right portion of the figure. CGContextTranslateCTM(context, 0, -(10 + CGRectGetHeight(pdfRect))); // Draw the PDF document again. CGContextDrawPDFDocument(context, pdfRect, pdfDoc, 1); // Set the blend mode to kCGBlendModeColor which will // colorize the destination with subsequent drawing. CGContextSetBlendMode(context, kCGBlendModeColor); // Draw the rectangle on top of the PDF document. The portion of the // background that is covered by the rectangle is colorized // with the fill color. CGContextFillRect(context, insetRect); // Release the CGPDFDocumentRef the code created. CGPDFDocumentRelease(pdfDoc); }
CGSize PDFPageGetSize(CGPDFPageRef page, CGPDFBox box) { CGRect boxRect = CGPDFPageGetBoxRect(page, box); int rotation = PDFPageGetRotation(page); bool invertSize = (rotation % 2) == 1; CGFloat width = invertSize ? CGRectGetHeight(boxRect) : CGRectGetWidth(boxRect); CGFloat height = invertSize ? CGRectGetWidth(boxRect) : CGRectGetHeight(boxRect); return CGSizeMake(width, height); }
static void AddRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight) { float fw, fh; if (ovalWidth == 0 || ovalHeight == 0) { CGContextAddRect(context, rect); return; } CGContextSaveGState(context); CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect)); CGContextScaleCTM (context, ovalWidth, ovalHeight); fw = CGRectGetWidth (rect) / ovalWidth; fh = CGRectGetHeight (rect) / ovalHeight; CGContextMoveToPoint(context, fw, fh / 2); CGContextAddArcToPoint(context, fw, fh, fw / 2, fh, 1); CGContextAddArcToPoint(context, 0, fh, 0, fh / 2, 1); CGContextAddArcToPoint(context, 0, 0, fw / 2, 0, 1); CGContextAddArcToPoint(context, fw, 0, fw, fh / 2, 1); CGContextClosePath(context); CGContextRestoreGState(context); }
static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight) { float fw, fh; // If either ovalWidth or ovalHeight is 0, draw a regular rectangle. if (ovalWidth == 0 || ovalHeight == 0) { CGContextAddRect(context, rect); }else{ CGContextSaveGState(context); // Translate to lower-left corner of rectangle. CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect)); // Scale by the oval width and height so that // each rounded corner is 0.5 units in radius. CGContextScaleCTM(context, ovalWidth, ovalHeight); // Unscale the rectangle width by the amount of the X scaling. fw = CGRectGetWidth(rect) / ovalWidth; // Unscale the rectangle height by the amount of the Y scaling. fh = CGRectGetHeight(rect) / ovalHeight; // Start at the right edge of the rect, at the midpoint in Y. CGContextMoveToPoint(context, fw, fh/2); // Segment 1 CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 0.5); // Segment 2 CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 0.5); // Segment 3 CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 0.5); // Segment 4 CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 0.5); // Closing the path adds the last segment. CGContextClosePath(context); CGContextRestoreGState(context); } }
void drawRoundedRect(CGContextRef context, int x, int y){ struct CGRect cgRect; struct CGPoint cgPoint; cgRect.size.width = 640; cgRect.size.height = y+30; cgPoint.x = 0; cgPoint.y = 5; cgRect.origin = cgPoint; //printf("Drawing %f, %f, %f, %f", cgPoint.x, cgPoint.y, cgRect.size.width, cgRect.size.height); CGContextBeginPath(context); float ovalWidth = 10; float ovalHeight = 10; float fw, fh; // If the width or height of the corner oval is zero, then it reduces to a right angle, // so instead of a rounded rectangle we have an ordinary one. if (ovalWidth == 0 || ovalHeight == 0) { CGContextAddRect(context, cgRect); return; } // Save the context's state so that the translate and scale can be undone with a call // to CGContextRestoreGState. CGContextSaveGState(context); // Translate the origin of the contex to the lower left corner of the rectangle. CGContextTranslateCTM(context, CGRectGetMinX(cgRect), CGRectGetMinY(cgRect)); //Normalize the scale of the context so that the width and height of the arcs are 1.0 CGContextScaleCTM(context, ovalWidth, ovalHeight); // Calculate the width and height of the rectangle in the new coordinate system. fw = CGRectGetWidth(cgRect) / ovalWidth; fh = CGRectGetHeight(cgRect) / ovalHeight; // CGContextAddArcToPoint adds an arc of a circle to the context's path (creating the rounded // corners). It also adds a line from the path's last point to the begining of the arc, making // the sides of the rectangle. CGContextMoveToPoint(context, fw, fh/2); // Start at lower right corner CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1); // Top right corner CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1); // Top left corner CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1); // Lower left corner CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); // Back to lower right // Close the path CGContextClosePath(context); CGContextSetRGBFillColor (context, 1, 1, 1, 0.7); CGContextFillPath(context); CGContextRestoreGState(context); }
/*********************************************************************** * create_surface_image * * Caller must hold the surface lock. On input, *rect is the requested * image rect, relative to the window whole_rect, a.k.a. visible_rect. * On output, it's been intersected with that part backed by the surface * and is the actual size of the returned image. copy_data indicates if * the caller will keep the returned image beyond the point where the * surface bits can be guaranteed to remain valid and unchanged. If so, * the bits are copied instead of merely referenced by the image. * * IMPORTANT: This function is called from non-Wine threads, so it * must not use Win32 or Wine functions, including debug * logging. */ CGImageRef create_surface_image(void *window_surface, CGRect *rect, int copy_data) { CGImageRef cgimage = NULL; struct macdrv_window_surface *surface = get_mac_surface(window_surface); int width, height; width = surface->header.rect.right - surface->header.rect.left; height = surface->header.rect.bottom - surface->header.rect.top; *rect = CGRectIntersection(cgrect_from_rect(surface->header.rect), *rect); if (!CGRectIsEmpty(*rect)) { CGRect visrect; CGColorSpaceRef colorspace; CGDataProviderRef provider; int bytes_per_row, offset, size; CGImageAlphaInfo alphaInfo; visrect = CGRectOffset(*rect, -surface->header.rect.left, -surface->header.rect.top); colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); bytes_per_row = get_dib_stride(width, 32); offset = CGRectGetMinX(visrect) * 4 + (height - CGRectGetMaxY(visrect)) * bytes_per_row; size = min(CGRectGetHeight(visrect) * bytes_per_row, surface->info.bmiHeader.biSizeImage - offset); if (copy_data) { CFDataRef data = CFDataCreate(NULL, (UInt8*)surface->bits + offset, size); provider = CGDataProviderCreateWithCFData(data); CFRelease(data); } else provider = CGDataProviderCreateWithData(NULL, surface->bits + offset, size, NULL); alphaInfo = surface->use_alpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst; cgimage = CGImageCreate(CGRectGetWidth(visrect), CGRectGetHeight(visrect), 8, 32, bytes_per_row, colorspace, alphaInfo | kCGBitmapByteOrder32Little, provider, NULL, FALSE, kCGRenderingIntentDefault); CGDataProviderRelease(provider); CGColorSpaceRelease(colorspace); } return cgimage; }
std::string Platform::GetScreenResolution() { CGRect mainMonitor = CGDisplayBounds(CGMainDisplayID()); CGFloat monitorHeight = CGRectGetHeight(mainMonitor); CGFloat monitorWidth = CGRectGetWidth(mainMonitor); std::stringstream ss; ss << int(monitorWidth) << "x" << int(monitorHeight); return ss.str(); }
void DrawSubCGImage (CGContextRef ctx, CGImageRef image, CGRect src, CGRect dst) { float w = (float) CGImageGetWidth(image); float h = (float) CGImageGetHeight(image); CGRect drawRect = CGRectMake(0.0f, 0.0f, w, h); if (!CGRectEqualToRect(src, dst)) { float sx = CGRectGetWidth(dst) / CGRectGetWidth(src); float sy = CGRectGetHeight(dst) / CGRectGetHeight(src); float dx = CGRectGetMinX(dst) - (CGRectGetMinX(src) * sx); float dy = CGRectGetMinY(dst) - (CGRectGetMinY(src) * sy); drawRect = CGRectMake(dx, dy, w * sx, h * sy); } CGContextSaveGState(ctx); CGContextClipToRect(ctx, dst); CGContextDrawImage(ctx, drawRect, image); CGContextRestoreGState(ctx); }
bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output) { size_t size = stream->getLength(); void* ptr = sk_malloc_throw(size); stream->read(ptr, size); CGDataProviderRef data = CGDataProviderCreateWithData(NULL, ptr, size, CGDataProviderReleaseData_FromMalloc); if (NULL == data) { return false; } CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(data); CGDataProviderRelease(data); if (NULL == pdf) { return false; } SkAutoPDFRelease releaseMe(pdf); CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1); if (NULL == page) { return false; } CGRect bounds = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); int w = (int)CGRectGetWidth(bounds); int h = (int)CGRectGetHeight(bounds); SkBitmap bitmap; if (!bitmap.allocPixels(SkImageInfo::MakeN32Premul(w, h))) { return false; } bitmap.eraseColor(SK_ColorWHITE); size_t bitsPerComponent; CGBitmapInfo info; getBitmapInfo(bitmap, &bitsPerComponent, &info, NULL); CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); CGContextRef ctx = CGBitmapContextCreate(bitmap.getPixels(), w, h, bitsPerComponent, bitmap.rowBytes(), cs, info); CGColorSpaceRelease(cs); if (ctx) { CGContextDrawPDFPage(ctx, page); CGContextRelease(ctx); } output->swap(bitmap); return true; }
int main(int argc, char** argv) { if (argc <= 1 || !*(argv[1]) || 0 == strcmp(argv[1], "-")) { fprintf(stderr, "usage:\n\t%s INPUT_PDF_FILE_PATH [OUTPUT_PNG_PATH]\n", argv[0]); return 1; } const char* output = argc > 2 ? argv[2] : nullptr; CGDataProviderRef data = CGDataProviderCreateWithFilename(argv[1]); ASSERT(data); CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(data); CGDataProviderRelease(data); ASSERT(pdf); CGPDFPageRef page = CGPDFDocumentGetPage(pdf, PAGE); ASSERT(page); CGRect bounds = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); int w = (int)CGRectGetWidth(bounds); int h = (int)CGRectGetHeight(bounds); CGBitmapInfo info = kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast; CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); ASSERT(cs); std::unique_ptr<uint32_t[]> bitmap(new uint32_t[w * h]); memset(bitmap.get(), 0xFF, 4 * w * h); CGContextRef ctx = CGBitmapContextCreate(bitmap.get(), w, h, 8, w * 4, cs, info); ASSERT(ctx); CGContextDrawPDFPage(ctx, page); CGPDFDocumentRelease(pdf); CGImageRef image = CGBitmapContextCreateImage(ctx); ASSERT(image); CGDataConsumerCallbacks procs; procs.putBytes = [](void* f, const void* buf, size_t s) { return fwrite(buf, 1, s, (FILE*)f); }; procs.releaseConsumer = [](void* info) { fclose((FILE*)info); }; FILE* ofile = (!output || !output[0] || 0 == strcmp(output, "-")) ? stdout : fopen(output, "wb"); ASSERT(ofile); CGDataConsumerRef consumer = CGDataConsumerCreate(ofile, &procs); ASSERT(consumer); CGImageDestinationRef dst = CGImageDestinationCreateWithDataConsumer(consumer, kUTTypePNG, 1, nullptr); CFRelease(consumer); ASSERT(dst); CGImageDestinationAddImage(dst, image, nullptr); ASSERT(CGImageDestinationFinalize(dst)); CFRelease(dst); CGImageRelease(image); CGColorSpaceRelease(cs); CGContextRelease(ctx); return 0; }
void CGContextDrawLayerInRect(CGContextRef context, CGRect rect, CGLayerRef layer) { QPainter* painter = CGContextGetPainter(context); QTransform tf = painter->worldTransform(); qreal sx, sy; CGSize origSize = CGLayerGetSize(layer); sx = CGRectGetWidth(rect) / origSize.width; sy = CGRectGetHeight(rect) / origSize.height; painter->scale(sx, sy); painter->drawPicture(QPointF(rect.origin.x / sx, rect.origin.y / sy), *layer->picture); painter->setWorldTransform(tf); }
bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output) { CGDataProviderRef data = SkCreateDataProviderFromStream(stream); if (NULL == data) { return false; } CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(data); CGDataProviderRelease(data); if (NULL == pdf) { return false; } SkAutoPDFRelease releaseMe(pdf); CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1); if (NULL == page) { return false; } CGRect bounds = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); int w = (int)CGRectGetWidth(bounds); int h = (int)CGRectGetHeight(bounds); SkBitmap bitmap; if (!bitmap.tryAllocN32Pixels(w, h)) { return false; } bitmap.eraseColor(SK_ColorWHITE); size_t bitsPerComponent; CGBitmapInfo info; getBitmapInfo(bitmap, &bitsPerComponent, &info, NULL); CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); CGContextRef ctx = CGBitmapContextCreate(bitmap.getPixels(), w, h, bitsPerComponent, bitmap.rowBytes(), cs, info); CGColorSpaceRelease(cs); if (ctx) { CGContextDrawPDFPage(ctx, page); CGContextRelease(ctx); } output->swap(bitmap); return true; }
//----------------------------------------------------------------------------- void CGDrawContext::drawEllipse (const CRect &rect, const CDrawStyle drawStyle) { CGContextRef context = beginCGContext (true, currentState.drawMode.integralMode ()); if (context) { CGPathDrawingMode m; switch (drawStyle) { case kDrawFilled : m = kCGPathFill; break; case kDrawFilledAndStroked : m = kCGPathFillStroke; break; default : m = kCGPathStroke; break; } applyLineStyle (context); if (rect.width () != rect.height ()) { CGContextSaveGState (context); CGContextBeginPath (context); CGRect cgRect = CGRectMake (rect.left, rect.top, rect.width (), rect.height ()); CGPoint center = CGPointMake (CGRectGetMidX (cgRect), CGRectGetMidY (cgRect)); CGFloat a = CGRectGetWidth (cgRect) / 2.; CGFloat b = CGRectGetHeight (cgRect) / 2.; CGContextTranslateCTM (context, center.x, center.y); CGContextScaleCTM (context, a, b); CGContextMoveToPoint (context, 1, 0); CGContextAddArc (context, 0, 0, 1, radians (0), radians (360), 0); CGContextClosePath (context); CGContextRestoreGState (context); CGContextDrawPath (context, m); } else { CGFloat radius = rect.width () * 0.5; CGContextBeginPath (context); CGContextAddArc (context, rect.left + radius, rect.top + radius, radius, radians (0), radians (360), 0); CGContextClosePath (context); CGContextDrawPath (context, m); } releaseCGContext (context); } }
CGImageRef getDesktopImage() { /* There are numerous functions to get any display * but we will stick to the main one for this example */ CGDirectDisplayID displayID = CGMainDisplayID(); /* Read out the size of our target display * nothing fancy here */ CGRect mainMonitor = CGDisplayBounds(displayID); CGFloat displayHeight = CGRectGetHeight(mainMonitor); CGFloat displayWidth = CGRectGetWidth(mainMonitor); std::cout << "Main Display ID: " << displayID << "\n"; std::cout << "Display width: " << displayWidth << " Display height: " << displayHeight << "\n"; /* Here we actually 'capture' the screen * the only problem is the data format... */ CGImageRef image = CGDisplayCreateImageForRect(displayID, CGRectMake(0, 0, displayWidth, displayHeight)); return image; }
static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight) { float fw, fh; // If the width or height of the corner oval is zero, then it reduces to a right angle, // so instead of a rounded rectangle we have an ordinary one. if (ovalWidth == 0 || ovalHeight == 0) { CGContextAddRect(context, rect); return; } // Save the context's state so that the translate and scale can be undone with a call // to CGContextRestoreGState. CGContextSaveGState(context); // Translate the origin of the contex to the lower left corner of the rectangle. CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect)); //Normalize the scale of the context so that the width and height of the arcs are 1.0 CGContextScaleCTM(context, ovalWidth, ovalHeight); // Calculate the width and height of the rectangle in the new coordinate system. fw = CGRectGetWidth(rect) / ovalWidth; fh = CGRectGetHeight(rect) / ovalHeight; // CGContextAddArcToPoint adds an arc of a circle to the context's path (creating the rounded // corners). It also adds a line from the path's last point to the begining of the arc, making // the sides of the rectangle. CGContextMoveToPoint(context, fw, fh/2); // Start at lower right corner CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1); // Top right corner CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1); // Top left corner CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1); // Lower left corner CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); // Back to lower right // Close the path CGContextClosePath(context); // Restore the context's state. This removes the translation and scaling // but leaves the path, since the path is not part of the graphics state. CGContextRestoreGState(context); }
int OSXWindowCapture::Height() { int height = CGRectGetHeight( mRect ); return Fullscreen() ? height : std::max< int >( height - OSX_WINDOW_TITLE_BAR_HEIGHT, 0 ); }
bool OSXWindowCapture::Fullscreen() { // this is not the most elegant solution, but I couldn't find a better way return CGRectGetMinX( mRect ) == 0.0f && CGRectGetMinY( mRect ) == 0.0f && ( int( CGRectGetHeight( mRect ) ) & OSX_WINDOW_TITLE_BAR_HEIGHT ) != OSX_WINDOW_TITLE_BAR_HEIGHT; }
/* 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; }