bool CGRect::CGRectIntersectsRect(const CGRect& rectA, const CGRect& rectB) { return !(CGRectGetMaxX(rectA) < CGRectGetMinX(rectB)|| CGRectGetMaxX(rectB) < CGRectGetMinX(rectA)|| CGRectGetMaxY(rectA) < CGRectGetMinY(rectB)|| CGRectGetMaxY(rectB) < CGRectGetMinY(rectB)); }
int main (int argc, const char * argv[]) { uint32_t displayCount; CGGetActiveDisplayList(0, NULL, &displayCount); if (displayCount != 2) { fprintf(stderr, "Error: expected exactly 2 displays, %d found\n", displayCount); exit(1); } CGDirectDisplayID activeDisplays[displayCount]; CGGetActiveDisplayList(displayCount, activeDisplays, &displayCount); const int32_t xTranslation = -CGRectGetMinX(CGDisplayBounds(activeDisplays[1])); CGDisplayConfigRef config; CGBeginDisplayConfiguration(&config); CGConfigureDisplayFadeEffect(config, 0.2, 0.2, 0, 0, 0); for (int i = 0; i < displayCount; ++i) { CGDirectDisplayID display = activeDisplays[i]; CGRect displayBounds = CGDisplayBounds(display); CGConfigureDisplayOrigin(config, display, CGRectGetMinX(displayBounds) + xTranslation, CGRectGetMinY(displayBounds)); } CGCompleteDisplayConfiguration(config, kCGConfigurePermanently); return 0; }
CGPoint CGLineIntersectsRectAtPoint(CGRect rect, CGLine line) { CGLine top = CGLineMake( CGPointMake( CGRectGetMinX(rect), CGRectGetMinY(rect) ), CGPointMake( CGRectGetMaxX(rect), CGRectGetMinY(rect) ) ); CGLine right = CGLineMake( CGPointMake( CGRectGetMaxX(rect), CGRectGetMinY(rect) ), CGPointMake( CGRectGetMaxX(rect), CGRectGetMaxY(rect) ) ); CGLine bottom = CGLineMake( CGPointMake( CGRectGetMinX(rect), CGRectGetMaxY(rect) ), CGPointMake( CGRectGetMaxX(rect), CGRectGetMaxY(rect) ) ); CGLine left = CGLineMake( CGPointMake( CGRectGetMinX(rect), CGRectGetMinY(rect) ), CGPointMake( CGRectGetMinX(rect), CGRectGetMaxY(rect) ) ); // ensure the line extends beyond outside the rectangle CGFloat topLeftToBottomRight = CGPointDistance(CGRectTopLeftPoint(rect), CGRectBottomRightPoint(rect)); CGFloat bottomLeftToTopRight = CGPointDistance(CGRectBottomLeftPoint(rect), CGRectTopRightPoint(rect)); CGFloat maxDimension = MT_MAX(topLeftToBottomRight, bottomLeftToTopRight); CGFloat scaleFactor = maxDimension / MT_MIN(CGLineLength(line), maxDimension); CGLine extendedLine = CGLineScale(line, scaleFactor + 3); CGPoint points[4] = { CGLinesIntersectAtPoint(top, extendedLine), CGLinesIntersectAtPoint(right, extendedLine), CGLinesIntersectAtPoint(bottom, extendedLine), CGLinesIntersectAtPoint(left, extendedLine) }; for (int i = 0; i < 4; i++) { CGPoint p = points[i]; if (!CGPointEqualToPoint(p, NULL_POINT)) { return p; } } return NULL_POINT; }
void setMainDisplay(CGDirectDisplayID targetDisplay) { int deltaX, deltaY, flag; CGDisplayErr dErr; CGDisplayCount displayCount, i; CGDirectDisplayID mainDisplay; CGDisplayCount maxDisplays = MAX_DISPLAYS; CGDirectDisplayID onlineDisplays[MAX_DISPLAYS]; CGDisplayConfigRef config; mainDisplay = CGMainDisplayID(); if (mainDisplay == targetDisplay) { exit(0); } dErr = CGGetOnlineDisplayList(maxDisplays, onlineDisplays, &displayCount); if (dErr != kCGErrorSuccess) { fprintf(stderr, "CGGetOnlineDisplayList: error %d.\n", dErr); exit(1); } flag = 0; for (i = 0; i < displayCount; i++) { CGDirectDisplayID dID = onlineDisplays[i]; if (dID == targetDisplay) { flag = 1; } } if (flag == 0) { fprintf(stderr, "No such display ID: %10p.\n", targetDisplay); exit(1); } deltaX = -CGRectGetMinX (CGDisplayBounds (targetDisplay)); deltaY = -CGRectGetMinY (CGDisplayBounds (targetDisplay)); CGBeginDisplayConfiguration (&config); for (i = 0; i < displayCount; i++) { CGDirectDisplayID dID = onlineDisplays[i]; CGConfigureDisplayOrigin (config, dID, CGRectGetMinX (CGDisplayBounds (dID)) + deltaX, CGRectGetMinY (CGDisplayBounds (dID)) + deltaY ); } CGCompleteDisplayConfiguration (config, kCGConfigureForSession); exit(0); }
// ----------------------------------------------------------------------------- // HITestViewGetRegion // ----------------------------------------------------------------------------- // OSStatus HITestViewGetRegion( EventRef inEvent, HITestViewData* inData ) { OSStatus err; ControlPartCode part; RgnHandle outRegion; HIRect bounds; Rect qdBounds; err = GetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode, NULL, sizeof( ControlPartCode ), NULL, &part ); require_noerr( err, ParameterMissing ); err = GetEventParameter( inEvent, kEventParamControlRegion, typeQDRgnHandle, NULL, sizeof( RgnHandle ), NULL, &outRegion ); if ( part == kControlContentMetaPart || part == kControlStructureMetaPart /* || part == kControlOpaqueRegionMetaPart */ ) { HIViewGetBounds( inData->view, &bounds ); qdBounds.top = (SInt16) CGRectGetMinY( bounds ); qdBounds.left = (SInt16) CGRectGetMinX( bounds ); qdBounds.bottom = (SInt16) CGRectGetMaxY( bounds ); qdBounds.right = (SInt16) CGRectGetMaxX( bounds ); RectRgn( outRegion, &qdBounds ); } ParameterMissing: return err; }
CGFloat CBRectPointDistance(CGRect rect, CGPoint point) { CGPoint p00 = CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect)); CGPoint p11 = CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect)); if (point.x < p00.x) { if (point.y < p00.y) return CBPointPointDistance(point, p00); else if (point.y > p11.y) return CBPointPointDistance(point, CGPointMake(p00.x, p11.y)); else return p00.x - point.x; } if (point.x > p11.x) { if (point.y < p00.y) return CBPointPointDistance(point, CGPointMake(p11.x, p00.y)); else if (point.y > p11.y) return CBPointPointDistance(point, p11); else return point.x - p11.x; } if (point.y < p00.y) return p00.y - point.y; else if (point.y > p11.y) return point.y - p11.y; return 0.0; }
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); } }
static void ButtonElementSize( void *clientData, void *elementRecord, Tk_Window tkwin, int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) { ThemeButtonParams *params = clientData; const HIThemeButtonDrawInfo info = computeButtonDrawInfo(params, 0); static const CGRect scratchBounds = {{0, 0}, {100, 100}}; CGRect contentBounds; ButtonElementSizeNoPadding( clientData, elementRecord, tkwin, widthPtr, heightPtr, paddingPtr); /* * To compute internal padding, query the appearance manager * for the content bounds of a dummy rectangle, then use * the difference as the padding. */ ChkErr(HIThemeGetButtonContentBounds, &scratchBounds, &info, &contentBounds); paddingPtr->left = CGRectGetMinX(contentBounds); paddingPtr->top = CGRectGetMinY(contentBounds); paddingPtr->right = CGRectGetMaxX(scratchBounds) - CGRectGetMaxX(contentBounds) + 1; paddingPtr->bottom = CGRectGetMaxY(scratchBounds) - CGRectGetMaxY(contentBounds); /* * Now add a little extra padding to account for drop shadows. * @@@ SHOULD: call GetThemeButtonBackgroundBounds() instead. */ *paddingPtr = Ttk_AddPadding(*paddingPtr, ButtonMargins); *widthPtr += Ttk_PaddingWidth(ButtonMargins); *heightPtr += Ttk_PaddingHeight(ButtonMargins); }
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); }
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); }
void drawRoundedRect(CGContextRef context, CGRect rrect) { // Drawing with a white stroke color CGContextSetRGBStrokeColor(context, 0.3, 0.3, 0.3, 1.0); CGContextSetRGBFillColor(context, 0.3, 0.3, 0.3, 1.0); // Add Rect to the current path, then stroke it // CGContextAddRect(context, CGRectMake(10.0, 190.0, 290.0, 73.0)); CGContextSetLineWidth(context, 1); CGFloat radius = 10.0; CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect); CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect); // Next, we will go around the rectangle in the order given by the figure below. // minx midx maxx // miny 2 3 4 // midy 1 9 5 // maxy 8 7 6 // Which gives us a coincident start and end point, which is incidental to this technique, but still doesn't // form a closed path, so we still need to close the path to connect the ends correctly. // Thus we start by moving to point 1, then adding arcs through each pair of points that follows. // You could use a similar tecgnique to create any shape with rounded corners. // Start at 1 CGContextMoveToPoint(context, minx, midy); // Add an arc through 2 to 3 CGContextAddArcToPoint(context, minx, miny, midx, miny, radius); // Add an arc through 4 to 5 CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius); // Add an arc through 6 to 7 CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius); // Add an arc through 8 to 9 CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius); // Close the path CGContextClosePath(context); // Fill & stroke the path CGContextDrawPath(context, kCGPathFillStroke); CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 0.0); CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); CGContextMoveToPoint(context, minx, midy); // Add an arc through 2 to 3 CGContextAddArcToPoint(context, minx, miny, midx, miny, radius); // Add an arc through 4 to 5 CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius); // Add an arc through 6 to 7 CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius); // Add an arc through 8 to 9 CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius); // Close the path CGContextClosePath(context); // Fill & stroke the path CGContextDrawPath(context, kCGPathFillStroke); }
// ----------------------------------------------------------------------------- // ShadeRectColor // ----------------------------------------------------------------------------- // OSStatus ShadeRectColor( const CGRGB* inStartColor, const CGRGB* inEndColor, const HIRect* inRect, CGContextRef inContext ) { OSStatus err = noErr; CGColorSpaceRef colorSpace; CGFunctionCallbacks callbacks = { 0, ColorGradientEvaluate, NULL }; CGFunctionRef function; CGShadingRef shading; ColorShadeData data; // Warning: this stuff is sitting on the stack. Be careful if you move // the shading code around. data.start = *inStartColor; data.range.red = inEndColor->red - inStartColor->red; data.range.green = inEndColor->green - inStartColor->green; data.range.blue = inEndColor->blue - inStartColor->blue; CGContextSaveGState( inContext ); CGContextClipToRect( inContext, *inRect ); colorSpace = CGColorSpaceCreateDeviceRGB(); require_action( colorSpace != NULL, CantCreateColorSpace, err = memFullErr ); function = CGFunctionCreate( &data, // info 1, // domainDimension NULL, // input domain NULL == no range clipping 4, // rangeDimension, NULL, // output domain NULL == no range clipping &callbacks ); // CGFunctionCallbacks require_action( function != NULL, CantCreateFunction, err = memFullErr ); shading = CGShadingCreateAxial( colorSpace, inRect->origin, // start CGPointMake( CGRectGetMinX( *inRect ), CGRectGetMaxY( *inRect ) ), // end function, false, // extendStart false ); // extendEnd require_action( colorSpace != NULL, CantCreateShading, err = memFullErr ); CGContextDrawShading( inContext, shading); CantCreateFunction: CGShadingRelease( shading ); CantCreateShading: CGColorSpaceRelease( colorSpace ); CantCreateColorSpace: CGContextRestoreGState( inContext ); return err; }
bool CGRect::CGRectContainsPoint(const CGRect& rect, const CGPoint& point) { bool bRet = false; if (point.x >= CGRectGetMinX(rect) && point.x <= CGRectGetMaxX(rect) && point.y >= CGRectGetMinY(rect) && point.y <= CGRectGetMaxY(rect)) { bRet = true; } return bRet; }
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); }
void QuartzWindow::get_window_region_rect(int wh, Rect* r) { HIRect bounds; OSStatus err = HIWindowGetBounds(my_window(), wh, kHICoordSpace72DPIGlobal, &bounds); if (err) { lprintf("HIWindowGetBounds failed: %d\n", err); r->left = r->top = 0; r->bottom = r->right = 1; } else { r->left = (short) CGRectGetMinX(bounds); r->top = (short) CGRectGetMinY(bounds); r->bottom = (short) CGRectGetMaxY(bounds); r->right = (short) CGRectGetMaxX(bounds); } }
void addRoundedRectToPath(CGContextRef context, CGRect rect, CGFloat radius) { CGFloat minX = CGRectGetMinX(rect); CGFloat minY = CGRectGetMinY(rect); CGFloat maxX = CGRectGetMaxX(rect); CGFloat maxY = CGRectGetMaxY(rect); CGFloat midX = CGRectGetMidX(rect); CGFloat midY = CGRectGetMidY(rect); CGContextBeginPath(context); CGContextMoveToPoint(context, maxX, midY); CGContextAddArcToPoint(context, maxX, maxY, midX, maxY, radius); CGContextAddArcToPoint(context, minX, maxY, minX, midY, radius); CGContextAddArcToPoint(context, minX, minY, midX, minY, radius); CGContextAddArcToPoint(context, maxX, minY, maxX, midY, radius); CGContextClosePath(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; }
void infoDisplays(void) { CGDisplayErr dErr; CGDisplayCount displayCount, i; CGDirectDisplayID mainDisplay; CGDisplayCount maxDisplays = MAX_DISPLAYS; CGDirectDisplayID onlineDisplays[MAX_DISPLAYS]; CGEventRef ourEvent = CGEventCreate(NULL); CGPoint ourLoc = CGEventGetLocation(ourEvent); CFRelease(ourEvent); mainDisplay = CGMainDisplayID(); dErr = CGGetOnlineDisplayList(maxDisplays, onlineDisplays, &displayCount); if (dErr != kCGErrorSuccess) { fprintf(stderr, "CGGetOnlineDisplayList: error %d.\n", dErr); exit(1); } printf("# Display_ID Resolution ____Display_Bounds____ Rotation\n"); for (i = 0; i < displayCount; i++) { CGDirectDisplayID dID = onlineDisplays[i]; printf("%-2d %10p %4lux%-4lu %5.0f %5.0f %5.0f %5.0f %3.0f %s%s%s", CGDisplayUnitNumber (dID), dID, CGDisplayPixelsWide(dID), CGDisplayPixelsHigh(dID), CGRectGetMinX (CGDisplayBounds (dID)), CGRectGetMinY (CGDisplayBounds (dID)), CGRectGetMaxX (CGDisplayBounds (dID)), CGRectGetMaxY (CGDisplayBounds (dID)), CGDisplayRotation (dID), (CGDisplayIsActive (dID)) ? "" : "[inactive]", (dID == mainDisplay) ? "[main]" : "", (CGDisplayIsBuiltin (dID)) ? "[internal]\n" : "\n"); } printf("Mouse Cursor Position: ( %5.0f , %5.0f )\n", (float)ourLoc.x, (float)ourLoc.y); exit(0); }
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); }
oop GetWindowRegion_wrap( WindowRef w, uint16 reg, void* FH) { // // TODO: GetWindoRegion is deprecated and not avialiable in >=10.7 // For now, we emulate with HIWindowGetBounds // HIRect bounds; OSStatus err = HIWindowGetBounds((WindowRef)w, reg, kHICoordSpace72DPIGlobal, &bounds); if (err) { return (oop)reportOSError(err, "GetWindowRegion", FH); } objVectorOop r = Memory->objVectorObj->cloneSize(4); // r->obj_at_put(0, as_floatOop(CGRectGetMinX(bounds)), false); // r->obj_at_put(1, as_floatOop(CGRectGetMinY(bounds)), false); // r->obj_at_put(2, as_floatOop(CGRectGetMaxX(bounds)), false); // r->obj_at_put(3, as_floatOop(CGRectGetMaxY(bounds)), false); r->obj_at_put(0, as_smiOop((short)CGRectGetMinX(bounds)), false); r->obj_at_put(1, as_smiOop((short)CGRectGetMinY(bounds)), false); r->obj_at_put(2, as_smiOop((short)CGRectGetMaxX(bounds)), false); r->obj_at_put(3, as_smiOop((short)CGRectGetMaxY(bounds)), false); return r; }
CGPoint CGRectBottomLeftPoint(CGRect rect) { return CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect)); }
static pascal OSStatus CustomSpotViewHandler(EventHandlerCallRef inCaller, EventRef inEvent, void* inRefcon) { OSStatus result = eventNotHandledErr; CustomSpotViewData* myData = (CustomSpotViewData*)inRefcon; switch (GetEventClass(inEvent)) { case kEventClassHIObject: switch (GetEventKind(inEvent)) { case kEventHIObjectConstruct: { myData = (CustomSpotViewData*) calloc(1, sizeof(CustomSpotViewData)); GetEventParameter(inEvent, kEventParamHIObjectInstance, typeHIObjectRef, NULL, sizeof(myData->view), NULL, &myData->view); result = SetEventParameter(inEvent, kEventParamHIObjectInstance, typeVoidPtr, sizeof(myData), &myData); break; } case kEventHIObjectInitialize: { HIRect bounds; GetEventParameter(inEvent, kEventParamBounds, typeHIRect, NULL, sizeof(bounds), NULL, &bounds); myData->spot.x = CGRectGetMidX(bounds) - CGRectGetMinX(bounds); myData->spot.y = CGRectGetMidY(bounds) - CGRectGetMinY(bounds); HIViewSetVisible(myData->view, true); break; } case kEventHIObjectDestruct: { free(myData); result = noErr; break; } default: break; } break; case kEventClassControl: switch (GetEventKind(inEvent)) { case kEventControlDraw: { CGContextRef context; HIRect bounds; result = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(context), NULL, &context); HIViewGetBounds(myData->view, &bounds); if (!IsControlActive(myData->view)) { CGContextSetGrayStrokeColor(context, 0.5, 0.3); CGContextSetGrayFillColor(context, 0.5, 0.3); } else { CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 0.7); CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 0.7); } CGContextSetLineWidth(context, 3.0); CGContextStrokeRect(context, bounds); HIRect spot = { {myData->spot.x - 4.0, myData->spot.y - 4.0}, {8.0, 8.0} }; CGContextFillRect(context, spot); result = noErr; break; } case kEventControlBoundsChanged: { HIRect newHIBounds; GetEventParameter(inEvent, kEventParamCurrentBounds, typeHIRect, NULL, sizeof(newHIBounds), NULL, &newHIBounds); myData->spot.x = CGRectGetMidX(newHIBounds) - CGRectGetMinX(newHIBounds); myData->spot.y = CGRectGetMidY(newHIBounds) - CGRectGetMinY(newHIBounds); break; } case kEventControlHitTest: { HIPoint pt; HIRect bounds; GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(pt), NULL, &pt); HIViewGetBounds(myData->view, &bounds); ControlPartCode part = (CGRectContainsPoint(bounds, pt))?kControlButtonPart:kControlNoPart; result = SetEventParameter(inEvent, kEventParamControlPart, typeControlPartCode, sizeof(part), &part); break; } case kEventControlTrack: { Point qdPoint; Rect qdWindowBounds; HIPoint hiPoint; HIRect hiViewBounds; MouseTrackingResult mouseStatus = kMouseTrackingMouseDown; HIViewGetBounds(myData->view, &hiViewBounds); GetWindowBounds(GetControlOwner(myData->view), kWindowStructureRgn, &qdWindowBounds); // handle the first mouseDown before moving GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(hiPoint), NULL, &hiPoint); while (mouseStatus != kMouseTrackingMouseUp) { if (CGRectContainsPoint(hiViewBounds, hiPoint)) { if (hiPoint.x < hiViewBounds.origin.x+4) hiPoint.x = hiViewBounds.origin.x+4; if (hiPoint.x > hiViewBounds.origin.x+hiViewBounds.size.width-4) hiPoint.x = hiViewBounds.origin.x+hiViewBounds.size.width-4; if (hiPoint.y < hiViewBounds.origin.y+4) hiPoint.y = hiViewBounds.origin.y+4; if (hiPoint.y > hiViewBounds.origin.y+hiViewBounds.size.height-4) hiPoint.y = hiViewBounds.origin.y+hiViewBounds.size.height-4; myData->spot = hiPoint; HIViewSetNeedsDisplay(myData->view, true); } // a -1 GrafPtr to TrackMouseLocation yields global coordinates TrackMouseLocation((GrafPtr)-1L, &qdPoint, &mouseStatus); // convert to window-relative coordinates hiPoint.x = qdPoint.h - qdWindowBounds.left; hiPoint.y = qdPoint.v - qdWindowBounds.top; // convert to view-relative coordinates HIViewConvertPoint(&hiPoint, NULL, myData->view); } break; } default: break; } break; default: break; } return result; }
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; }
static cairo_int_status_t _cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font, cairo_scaled_glyph_t *scaled_glyph) { cairo_int_status_t status = CAIRO_STATUS_SUCCESS; cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font); cairo_text_extents_t extents = {0, 0, 0, 0, 0, 0}; CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph); int advance; CGRect bbox; double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont); double xmin, ymin, xmax, ymax; if (glyph == INVALID_GLYPH) goto FAIL; if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) || !CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox)) goto FAIL; /* broken fonts like Al Bayan return incorrect bounds for some null characters, see https://bugzilla.mozilla.org/show_bug.cgi?id=534260 */ if (unlikely (bbox.origin.x == -32767 && bbox.origin.y == -32767 && bbox.size.width == 65534 && bbox.size.height == 65534)) { bbox.origin.x = bbox.origin.y = 0; bbox.size.width = bbox.size.height = 0; } bbox = CGRectMake (bbox.origin.x / emscale, bbox.origin.y / emscale, bbox.size.width / emscale, bbox.size.height / emscale); /* Should we want to always integer-align glyph extents, we can do so in this way */ #if 0 { CGAffineTransform textMatrix; textMatrix = CGAffineTransformMake (font->base.scale.xx, -font->base.scale.yx, -font->base.scale.xy, font->base.scale.yy, 0.0f, 0.0f); bbox = CGRectApplyAffineTransform (bbox, textMatrix); bbox = CGRectIntegral (bbox); bbox = CGRectApplyAffineTransform (bbox, CGAffineTransformInvert (textMatrix)); } #endif #if 0 fprintf (stderr, "[0x%04x] bbox: %f %f %f %f\n", glyph, bbox.origin.x / emscale, bbox.origin.y / emscale, bbox.size.width / emscale, bbox.size.height / emscale); #endif xmin = CGRectGetMinX(bbox); ymin = CGRectGetMinY(bbox); xmax = CGRectGetMaxX(bbox); ymax = CGRectGetMaxY(bbox); extents.x_bearing = xmin; extents.y_bearing = - ymax; extents.width = xmax - xmin; extents.height = ymax - ymin; extents.x_advance = (double) advance / emscale; extents.y_advance = 0.0; #if 0 fprintf (stderr, "[0x%04x] extents: bearings: %f %f dim: %f %f adv: %f\n\n", glyph, extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance); #endif FAIL: _cairo_scaled_glyph_set_metrics (scaled_glyph, &font->base, &extents); return status; }
int OSXWindowCapture::Left() { return CGRectGetMinX( mRect ); }
CGRect CGRectStackedWithinRectFromEdge(CGRect rect, CGSize size, int count, CGRectEdge edge, bool reverse) { int max_columns = floor(rect.size.width / size.width); int max_rows = floor(rect.size.height / size.height); if (edge == CGRectMinYEdge) { int current_row = floor(count / max_columns); int current_col = (count - 1) % max_columns; if (reverse) current_col = max_columns - (current_col + 1); if (current_col > max_columns || current_row > max_rows) { return CGRectNull; } else { CGFloat x = CGRectGetMinX(rect) + (current_col * size.width); CGFloat y = CGRectGetMinY(rect) + (current_row * size.height); return CGRectMake(x, y, size.width, size.height); } } else if (edge == CGRectMaxYEdge) { int current_row = floor(count / max_columns); int current_col = (count - 1) % max_columns; if (!reverse) current_col = max_columns - (current_col + 1); if (current_col > max_columns || current_row > max_rows) { return CGRectNull; } else { CGFloat x = CGRectGetMinX(rect) + (current_col * size.width); CGFloat y = CGRectGetMaxY(rect) - size.height - (current_row * size.height); return CGRectMake(x, y, size.width, size.height); } } else if (edge == CGRectMinXEdge) { int current_col = floor(count / max_columns); int current_row = (count - 1) % max_columns; if (!reverse) current_row = max_rows - (current_row + 1); if (current_col > max_columns || current_row > max_rows) { return CGRectNull; } else { CGFloat x = CGRectGetMinX(rect) + (current_col * size.width); CGFloat y = CGRectGetMinY(rect) + (current_row * size.height); return CGRectMake(x, y, size.width, size.height); } } else if (edge == CGRectMaxXEdge) { int current_col = floor(count / max_columns); int current_row = (count - 1) % max_columns; if (reverse) current_row = max_rows - (current_row + 1); if (current_col > max_columns || current_row > max_rows) { return CGRectNull; } else { CGFloat x = CGRectGetMaxX(rect) - size.width - (current_col * size.width); CGFloat y = CGRectGetMinY(rect) + current_row * size.height; return CGRectMake(x, y, size.width, size.height); } } return CGRectNull; }
CGPoint CGRectTopLeftPoint(CGRect rect) { return CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect)); }
static cairo_int_status_t _cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font, cairo_scaled_glyph_t *scaled_glyph) { cairo_int_status_t status = CAIRO_STATUS_SUCCESS; cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font); cairo_text_extents_t extents = {0, 0, 0, 0, 0, 0}; CGAffineTransform textMatrix; CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph); int advance; CGRect bbox; double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont); double xscale, yscale; double xmin, ymin, xmax, ymax; if (glyph == INVALID_GLYPH) goto FAIL; if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) || !CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox)) goto FAIL; status = _cairo_matrix_compute_basis_scale_factors (&font->base.scale, &xscale, &yscale, 1); if (status) goto FAIL; bbox = CGRectMake (bbox.origin.x / emscale, bbox.origin.y / emscale, bbox.size.width / emscale, bbox.size.height / emscale); /* Should we want to always integer-align glyph extents, we can do so in this way */ #if 0 { CGAffineTransform textMatrix; textMatrix = CGAffineTransformMake (font->base.scale.xx, -font->base.scale.yx, -font->base.scale.xy, font->base.scale.yy, 0.0f, 0.0f); bbox = CGRectApplyAffineTransform (bbox, textMatrix); bbox = CGRectIntegral (bbox); bbox = CGRectApplyAffineTransform (bbox, CGAffineTransformInvert (textMatrix)); } #endif #if 0 fprintf (stderr, "[0x%04x] bbox: %f %f %f %f\n", glyph, bbox.origin.x / emscale, bbox.origin.y / emscale, bbox.size.width / emscale, bbox.size.height / emscale); #endif xmin = CGRectGetMinX(bbox); ymin = CGRectGetMinY(bbox); xmax = CGRectGetMaxX(bbox); ymax = CGRectGetMaxY(bbox); extents.x_bearing = xmin; extents.y_bearing = - ymax; extents.width = xmax - xmin; extents.height = ymax - ymin; extents.x_advance = (double) advance / emscale; extents.y_advance = 0.0; #if 0 fprintf (stderr, "[0x%04x] extents: bearings: %f %f dim: %f %f adv: %f\n\n", glyph, extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance); #endif FAIL: _cairo_scaled_glyph_set_metrics (scaled_glyph, &font->base, &extents); return status; }