void TileGrid::drawTileMapContents(CGContextRef context, CGRect layerBounds) const { CGContextSetRGBFillColor(context, 0.3, 0.3, 0.3, 1); CGContextFillRect(context, layerBounds); CGFloat scaleFactor = layerBounds.size.width / m_controller.bounds().width(); CGFloat contextScale = scaleFactor / m_scale; CGContextScaleCTM(context, contextScale, contextScale); for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) { const TileInfo& tileInfo = it->value; PlatformCALayer* tileLayer = tileInfo.layer.get(); CGFloat red = 1; CGFloat green = 1; CGFloat blue = 1; CGFloat alpha = 1; if (tileInfo.hasStaleContent) { red = 0.25; green = 0.125; blue = 0; } else if (m_controller.shouldAggressivelyRetainTiles() && tileInfo.cohort != VisibleTileCohort) { red = 0.8; green = 0.8; blue = 0.8; } TileCohort newestCohort = newestTileCohort(); TileCohort oldestCohort = oldestTileCohort(); if (!m_controller.shouldAggressivelyRetainTiles() && tileInfo.cohort != VisibleTileCohort && newestCohort > oldestCohort) alpha = 1 - (static_cast<float>((newestCohort - tileInfo.cohort)) / (newestCohort - oldestCohort)); CGContextSetRGBFillColor(context, red, green, blue, alpha); if (tileLayer->superlayer()) { CGContextSetLineWidth(context, 0.5 / contextScale); CGContextSetRGBStrokeColor(context, 0, 0, 0, 1); } else { CGContextSetLineWidth(context, 1 / contextScale); CGContextSetRGBStrokeColor(context, 0.2, 0.1, 0.9, 1); } CGRect frame = CGRectMake(tileLayer->position().x(), tileLayer->position().y(), tileLayer->bounds().size().width(), tileLayer->bounds().size().height()); CGContextFillRect(context, frame); CGContextStrokeRect(context, frame); CGContextSetRGBFillColor(context, 0, 0, 0, 0.5); String repaintCount = String::number(m_tileRepaintCounts.get(tileLayer)); CGContextSaveGState(context); tileLayer->drawTextAtPoint(context, frame.origin.x + 64, frame.origin.y + 192, CGSizeMake(3, -3), 58, repaintCount.ascii().data(), repaintCount.length()); CGContextRestoreGState(context); } }
void drawSelectionRect(CGContextRef context, const CGRect& rect) { CGContextSaveGState(context); CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); CGContextStrokeRect(context, rect); CGContextRestoreGState(context); }
static void Quartz_Rect(double x0, double y0, double x1, double y1, R_GE_gcontext *gc, NewDevDesc *dd) { QuartzDesc *xd = (QuartzDesc*)dd->deviceSpecific; CGRect rect; CGPoint origin; CGSize size; origin.x = x0; origin.y = y0; size.width = x1-x0; size.height = y1-y0; rect.size = size; rect.origin = origin; CGContextSaveGState( GetContext(xd) ); Quartz_SetLineProperties(gc, dd); Quartz_SetFill( gc->fill, gc->gamma, dd); CGContextFillRect( GetContext(xd), rect); Quartz_SetStroke( gc->col, gc->gamma, dd); CGContextStrokeRect( GetContext(xd), rect); CGContextRestoreGState( GetContext(xd) ); }
DRAW_TEST_F(CGContextFlush, FillFlushMultipleDrawingCounters, WhiteBackgroundTest<>) { CGContextRef context = GetDrawingContext(); CGRect bounds = GetDrawingBounds(); static int sDrawCount = 5; for (int i = 0; i < sDrawCount; ++i) { _CGContextPushBeginDraw(context); } CGContextSetRGBFillColor(context, 1, 0, 0, 1); CGContextFillRect(context, bounds); for (int i = 0; i < sDrawCount; ++i) { // Multiple flushes should work. CGContextFlush(context); } // Add some extra drawings CGContextClearRect(context, bounds); // We should still have red & clear should not of been executed. 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); for (int i = 0; i < 3; ++i) { // Multiple flushes should work. CGContextFlush(context); } // validate clear EXPECT_EQ(dataPtr[0], 0x00); EXPECT_EQ(dataPtr[1], 0x00); EXPECT_EQ(dataPtr[2], 0x00); EXPECT_EQ(dataPtr[3], 0x00); CGContextSetRGBStrokeColor(context, 0, 1, 0, 1); CGContextStrokeRect(context, CGRectMake(100, 100, 200, 300)); // Still should be clear. EXPECT_EQ(dataPtr[0], 0x00); EXPECT_EQ(dataPtr[1], 0x00); EXPECT_EQ(dataPtr[2], 0x00); EXPECT_EQ(dataPtr[3], 0x00); for (int i = 0; i < sDrawCount; ++i) { _CGContextPopEndDraw(context); } }
void MacVegaPrinterListener::DrawRect(const OpRect& rect, UINT32 width) { if(width != 1) { CGContextSetLineWidth(m_ctx, width); } CGContextStrokeRect(m_ctx, CGRectMake(rect.x, m_winHeight-(rect.y+rect.height), rect.width, rect.height)); if(width != 1) { CGContextSetLineWidth(m_ctx, 1); } }
void PlatformCALayer::drawRepaintIndicator(CGContextRef context, PlatformCALayer* platformCALayer, int repaintCount, CGColorRef customBackgroundColor) { char text[16]; // that's a lot of repaints snprintf(text, sizeof(text), "%d", repaintCount); FloatRect indicatorBox = platformCALayer->bounds();\ indicatorBox.setLocation( { 1, 1 } ); indicatorBox.setSize(FloatSize(12 + 10 * strlen(text), 27)); CGContextStateSaver stateSaver(context); CGContextSetAlpha(context, 0.5f); CGContextBeginTransparencyLayerWithRect(context, indicatorBox, 0); if (customBackgroundColor) CGContextSetFillColorWithColor(context, customBackgroundColor); else CGContextSetRGBFillColor(context, 0, 0.5f, 0.25f, 1); if (platformCALayer->isOpaque()) CGContextFillRect(context, indicatorBox); else { Path boundsPath; boundsPath.moveTo(indicatorBox.maxXMinYCorner()); boundsPath.addLineTo(indicatorBox.maxXMaxYCorner()); boundsPath.addLineTo(indicatorBox.minXMaxYCorner()); const float cornerChunk = 8; boundsPath.addLineTo(FloatPoint(indicatorBox.x(), indicatorBox.y() + cornerChunk)); boundsPath.addLineTo(FloatPoint(indicatorBox.x() + cornerChunk, indicatorBox.y())); boundsPath.closeSubpath(); CGContextAddPath(context, boundsPath.platformPath()); CGContextFillPath(context); } if (platformCALayer->owner()->isUsingDisplayListDrawing(platformCALayer)) { CGContextSetRGBStrokeColor(context, 0, 0, 0, 0.65); CGContextSetLineWidth(context, 2); CGContextStrokeRect(context, indicatorBox); } if (platformCALayer->acceleratesDrawing()) CGContextSetRGBFillColor(context, 1, 0, 0, 1); else CGContextSetRGBFillColor(context, 1, 1, 1, 1); platformCALayer->drawTextAtPoint(context, indicatorBox.x() + 5, indicatorBox.y() + 22, CGSizeMake(1, -1), 22, text, strlen(text)); CGContextEndTransparencyLayer(context); }
DISABLED_DRAW_TEST_F(CGContext, Shadow, WhiteBackgroundTest) { CGContextRef context = GetDrawingContext(); CGRect bounds = GetDrawingBounds(); CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); CGContextSetLineWidth(context, 5); CGContextSetShadow(context, CGSize{ 10.f, 10.f }, 1.0); CGPoint center = _CGRectGetCenter(bounds); CGRect rect = _CGRectCenteredOnPoint({ 150, 150 }, center); CGContextStrokeRect(context, rect); }
bool GiCanvasIos::rawRect(const GiContext* ctx, float x, float y, float w, float h) { bool ret = false; if (m_draw->setPen(ctx)) { CGContextStrokeRect(m_draw->getContext(), CGRectMake(x, y, w, h)); ret = true; } if (m_draw->setBrush(ctx)) { CGContextFillRect(m_draw->getContext(), CGRectMake(x, y, w, h)); ret = true; } return ret; }
// ----------------------------------------------------------------------------- // HITestViewDraw // ----------------------------------------------------------------------------- // Here's the fun stuff. Draw a red box when not hilighted, a blue box // when hilighted. // OSStatus HITestViewDraw( EventRef inEvent, HITestViewData* inData ) { OSStatus err; HIRect bounds; CGContextRef context; float red, green, blue; err = GetEventParameter( inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof( CGContextRef ), NULL, &context ); require_noerr( err, ParameterMissing ); err = HIViewGetBounds( inData->view, &bounds ); red = inData->red; green = inData->green; blue = inData->blue; switch ( GetControlHilite( inData->view ) ) { case kControlNoPart: CGContextSetRGBFillColor( context, red, green, blue, 0.25 ); CGContextSetRGBStrokeColor( context, red, green, blue, 1 ); break; // Handle synthetic highlights, too case kControlInactivePart: case kControlDisabledPart: CGContextSetRGBFillColor( context, red, green, blue, 0.10 ); CGContextSetRGBStrokeColor( context, red, green, blue, 0.10 ); break; default: CGContextSetRGBFillColor( context, 0, 0, 1, 0.25 ); CGContextSetRGBStrokeColor( context, 0, 0, 1, 1 ); break; } CGContextFillRect( context, bounds ); CGContextStrokeRect( context, bounds ); ParameterMissing: return err; }
DISABLED_DRAW_TEST_F(CGContext, ShadowWithRotatedCTM, WhiteBackgroundTest) { CGContextRef context = GetDrawingContext(); CGRect bounds = GetDrawingBounds(); CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); CGContextSetLineWidth(context, 5); CGContextSetShadow(context, CGSize{ 10.f, 10.f }, 1.0); CGPoint center = _CGRectGetCenter(bounds); CGRect rect = _CGRectCenteredOnPoint({ 150, 150 }, center); CGPoint rectCenter = _CGRectGetCenter(rect); CGContextTranslateCTM(context, rectCenter.x, rectCenter.y); CGContextRotateCTM(context, 15.f * M_PI / 180.f); CGContextTranslateCTM(context, -rectCenter.x, -rectCenter.y); CGContextStrokeRect(context, rect); }
static void gdk_quartz_draw_rectangle (GdkDrawable *drawable, GdkGC *gc, gboolean filled, gint x, gint y, gint width, gint height) { CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE); if (!context) return; if(!_gdk_quartz_gc_update_cg_context (gc, drawable, context, filled ? GDK_QUARTZ_CONTEXT_FILL : GDK_QUARTZ_CONTEXT_STROKE)) { gdk_quartz_drawable_release_context (drawable, context); return; } if (filled) { CGRect rect = CGRectMake (x, y, width, height); CGContextFillRect (context, rect); } else { CGRect rect = CGRectMake (x + 0.5, y + 0.5, width, height); CGContextStrokeRect (context, rect); } gdk_quartz_drawable_release_context (drawable, context); }
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; }
/*----------------------------------------------------------------------------------------------------------*/ pascal OSStatus ScrollingTextViewHandler(EventHandlerCallRef inCaller, EventRef inEvent, void* inRefcon) { OSStatus result = eventNotHandledErr; ScrollingTextBoxData* myData = (ScrollingTextBoxData*)inRefcon; switch (GetEventClass(inEvent)) { case kEventClassHIObject: switch (GetEventKind(inEvent)) { case kEventHIObjectConstruct: { // allocate some instance data myData = (ScrollingTextBoxData*) calloc(1, sizeof(ScrollingTextBoxData)); // get our superclass instance HIViewRef epView; GetEventParameter(inEvent, kEventParamHIObjectInstance, typeHIObjectRef, NULL, sizeof(epView), NULL, &epView); // remember our superclass in our instance data and initialize other fields myData->view = epView; // set the control ID so that we can find it later with HIViewFindByID result = SetControlID(myData->view, &kScrollingTextBoxViewID); // store our instance data into the event result = SetEventParameter(inEvent, kEventParamHIObjectInstance, typeVoidPtr, sizeof(myData), &myData); break; } case kEventHIObjectDestruct: { if (myData->theTimer != NULL) RemoveEventLoopTimer(myData->theTimer); CFRelease(myData->theText); free(myData); result = noErr; break; } case kEventHIObjectInitialize: { // always begin kEventHIObjectInitialize by calling through to the previous handler result = CallNextEventHandler(inCaller, inEvent); // if that succeeded, do our own initialization if (result == noErr) { GetEventParameter(inEvent, kEventParamScrollingText, typeCFStringRef, NULL, sizeof(myData->theText), NULL, &myData->theText); CFRetain(myData->theText); GetEventParameter(inEvent, kEventParamAutoScroll, typeBoolean, NULL, sizeof(myData->autoScroll), NULL, &myData->autoScroll); GetEventParameter(inEvent, kEventParamDelayBeforeAutoScroll, typeUInt32, NULL, sizeof(myData->delayBeforeAutoScroll), NULL, &myData->delayBeforeAutoScroll); GetEventParameter(inEvent, kEventParamDelayBetweenAutoScroll, typeUInt32, NULL, sizeof(myData->delayBetweenAutoScroll), NULL, &myData->delayBetweenAutoScroll); GetEventParameter(inEvent, kEventParamAutoScrollAmount, typeSInt16, NULL, sizeof(myData->autoScrollAmount), NULL, &myData->autoScrollAmount); myData->theTimer = NULL; } break; } default: break; } break; case kEventClassScrollable: switch (GetEventKind(inEvent)) { case kEventScrollableGetInfo: { // we're being asked to return information about the scrolled view that we set as Event Parameters HISize imageSize = {50.0, myData->height}; SetEventParameter(inEvent, kEventParamImageSize, typeHISize, sizeof(imageSize), &imageSize); HISize lineSize = {50.0, 20.0}; SetEventParameter(inEvent, kEventParamLineSize, typeHISize, sizeof(lineSize), &lineSize); HIRect bounds; HIViewGetBounds(myData->view, &bounds); SetEventParameter(inEvent, kEventParamViewSize, typeHISize, sizeof(bounds.size), &bounds.size); SetEventParameter(inEvent, kEventParamOrigin, typeHIPoint, sizeof(myData->originPoint), &myData->originPoint); result = noErr; break; } case kEventScrollableScrollTo: { // we're being asked to scroll, we just do a sanity check and ask for a redraw HIPoint where; GetEventParameter(inEvent, kEventParamOrigin, typeHIPoint, NULL, sizeof(where), NULL, &where); HIViewSetNeedsDisplay(myData->view, true); myData->originPoint.y = (where.y < 0.0)?0.0:where.y; HIViewSetBoundsOrigin(myData->view, 0, myData->originPoint.y); break; } default: break; } break; case kEventClassControl: switch (GetEventKind(inEvent)) { // sets the feature of the view. case kEventControlInitialize: { result = CallNextEventHandler(inCaller, inEvent); if (result != noErr) break; UInt32 features = 0; result = GetEventParameter(inEvent, kEventParamControlFeatures, typeUInt32, NULL, sizeof(features), NULL, &features); if (result == noErr) features |= kControlSupportsEmbedding; else features = kControlSupportsEmbedding; result = SetEventParameter(inEvent, kEventParamControlFeatures, typeUInt32, sizeof features, &features); break; } // Our parent view just changed dimensions, so we determined our new height. case kEventControlSetData: CFRelease(myData->theText); CFStringRef *p; GetEventParameter(inEvent, kEventParamControlDataBuffer, typePtr, NULL, sizeof(p), NULL, &p); myData->theText = *p; CFRetain(myData->theText); // fallthrough case kEventControlBoundsChanged: { HIRect bounds; HIViewGetBounds(myData->view, &bounds); // // If we're building on Panther (or later) then HIThemeGetTextDimensions is available, else we use GetThemeTextDimensions // #if PANTHER_BUILD // // Furthermore, if we're running on Panther then we can call HIThemeGetTextDimensions else we call GetThemeTextDimensions // if (GetHIToolboxVersion() >= Panther_HIToolbox_Version) { HIThemeTextInfo textInfo = {0, kThemeStateActive, kScrollingTextBoxFontID, kHIThemeTextHorizontalFlushLeft, kHIThemeTextVerticalFlushTop, kHIThemeTextBoxOptionStronglyVertical, kHIThemeTextTruncationNone, 0, false}; HIThemeGetTextDimensions(myData->theText, bounds.size.width - kMargin - kMargin, &textInfo, NULL, &myData->height, NULL); } else #endif { Point pointBounds; pointBounds.h = (int)(bounds.size.width - kMargin - kMargin); GetThemeTextDimensions(myData->theText, kScrollingTextBoxFontID, kThemeStateActive, true, &pointBounds, NULL); myData->height = pointBounds.v; } myData->height += 2.0 * kMargin; HIViewSetNeedsDisplay(myData->view, true); result = eventNotHandledErr; break; } // Draw the view. case kEventControlDraw: { CGContextRef context; result = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(context), NULL, &context); HIRect bounds; HIViewGetBounds(myData->view, &bounds); CGContextSaveGState(context); CGAffineTransform transform = CGAffineTransformIdentity; // adjust the transform so the text doesn't draw upside down transform = CGAffineTransformScale(transform, 1, -1); CGContextSetTextMatrix(context, transform); // now that the proper parameters and configurations have been dealt with, let's draw result = ScrollingTextBoxDraw(context, &bounds, myData); CGContextRestoreGState(context); if (myData->autoScroll) CGContextStrokeRect(context, bounds); // we postpone starting the autoscroll timer until after we do our first drawing if ( (myData->autoScroll) && (myData->theTimer == NULL) ) InstallEventLoopTimer(GetCurrentEventLoop(), TicksToEventTime(myData->delayBeforeAutoScroll), TicksToEventTime(myData->delayBetweenAutoScroll), myScrollingTextTimeProc, myData, &myData->theTimer); result = noErr; break; } default: break; } break; default: break; } return result; }
void draw__stroke_rect(xy__Rect rect) { CGContextStrokeRect(ctx, cg_rect_from_xy(rect)); }
void UIFrameBufferQuartz2D::paintEvent(QPaintEvent *aEvent) { /* If the machine is NOT in 'running' state, * the link between framebuffer and video memory * is broken, we should go fallback now... */ if (m_fUsesGuestVRAM && !m_pMachineView->uisession()->isRunning() && !m_pMachineView->uisession()->isPaused() && /* Online snapshotting: */ m_pMachineView->uisession()->machineState() != KMachineState_Saving) { /* Simulate fallback through fake resize-event: */ UIResizeEvent event(FramebufferPixelFormat_Opaque, NULL, 0, 0, 640, 480); resizeEvent(&event); } /* For debugging /Developer/Applications/Performance Tools/Quartz * Debug.app is a nice tool to see which parts of the screen are * updated.*/ Assert(m_image); QWidget* viewport = m_pMachineView->viewport(); Assert(VALID_PTR(viewport)); /* Get the dimensions of the viewport */ CGRect viewRect = ::darwinToCGRect(viewport->geometry()); /* Get the context of this window from Qt */ CGContextRef ctx = ::darwinToCGContextRef(viewport); Assert(VALID_PTR(ctx)); /* Flip the context */ CGContextTranslateCTM(ctx, 0, viewRect.size.height); CGContextScaleCTM(ctx, 1.0, -1.0); /* We handle the seamless mode as a special case. */ if (m_pMachineLogic->visualStateType() == UIVisualStateType_Seamless) { /* Clear the background (make the rect fully transparent): */ CGContextClearRect(ctx, viewRect); #ifdef OVERLAY_CLIPRECTS /* Enable overlay above the seamless mask: */ CGContextSetRGBFillColor(ctx, 0.0, 0.0, 5.0, 0.7); CGContextFillRect(ctx, viewRect); #endif /* OVERLAY_CLIPRECTS */ #ifdef COMP_WITH_SHADOW /* Enable shadows: */ CGContextSetShadow(ctx, CGSizeMake (10, -10), 10); CGContextBeginTransparencyLayer(ctx, NULL); #endif /* COMP_WITH_SHADOW */ /* Determine current visible region: */ RegionRects *pRgnRcts = ASMAtomicXchgPtrT(&mRegion, NULL, RegionRects*); if (pRgnRcts) { /* If visible region is determined: */ if (pRgnRcts->used > 0) { /* Add the clipping rects all at once (they are defined in SetVisibleRegion): */ CGContextBeginPath(ctx); CGContextAddRects(ctx, pRgnRcts->rcts, pRgnRcts->used); /* Now convert the path to a clipping path: */ CGContextClip(ctx); } /* Put back the visible region, free if we cannot (2+ SetVisibleRegion calls): */ if ( !ASMAtomicCmpXchgPtr(&mRegion, pRgnRcts, NULL) && !ASMAtomicCmpXchgPtr(&mRegionUnused, pRgnRcts, NULL)) { RTMemFree(pRgnRcts); pRgnRcts = NULL; } } /* If visible region is still determined: */ if (pRgnRcts && pRgnRcts->used > 0) { /* Create a subimage of the current view. * Currently this subimage is the whole screen. */ CGImageRef subImage; if (!m_pMachineView->pauseShot().isNull()) { CGImageRef pauseImg = ::darwinToCGImageRef(&m_pMachineView->pauseShot()); subImage = CGImageCreateWithImageInRect(pauseImg, CGRectMake(m_pMachineView->contentsX(), m_pMachineView->contentsY(), m_pMachineView->visibleWidth(), m_pMachineView->visibleHeight())); CGImageRelease(pauseImg); } else { #ifdef RT_ARCH_AMD64 /* Not sure who to blame, but it seems on 64bit there goes * something terrible wrong (on a second monitor) when directly * using CGImageCreateWithImageInRect without making a copy. We saw * something like this already with the scale mode. */ CGImageRef tmpImage = CGImageCreateWithImageInRect(m_image, CGRectMake(m_pMachineView->contentsX(), m_pMachineView->contentsY(), m_pMachineView->visibleWidth(), m_pMachineView->visibleHeight())); subImage = CGImageCreateCopy(tmpImage); CGImageRelease(tmpImage); #else /* RT_ARCH_AMD64 */ subImage = CGImageCreateWithImageInRect(m_image, CGRectMake(m_pMachineView->contentsX(), m_pMachineView->contentsY(), m_pMachineView->visibleWidth(), m_pMachineView->visibleHeight())); #endif /* !RT_ARCH_AMD64 */ } Assert(VALID_PTR(subImage)); /* In any case clip the drawing to the view window: */ CGContextClipToRect(ctx, viewRect); /* At this point draw the real vm image: */ CGContextDrawImage(ctx, ::darwinFlipCGRect(viewRect, viewRect.size.height), subImage); /* Release the subimage: */ CGImageRelease(subImage); } #ifdef COMP_WITH_SHADOW CGContextEndTransparencyLayer(ctx); #endif /* COMP_WITH_SHADOW */ #ifdef OVERLAY_CLIPRECTS if (pRgnRcts && pRgnRcts->used > 0) { CGContextBeginPath(ctx); CGContextAddRects(ctx, pRgnRcts->rcts, pRgnRcts->used); CGContextSetRGBStrokeColor(ctx, 1.0, 0.0, 0.0, 0.7); CGContextDrawPath(ctx, kCGPathStroke); } CGContextSetRGBStrokeColor(ctx, 0.0, 1.0, 0.0, 0.7); CGContextStrokeRect(ctx, viewRect); #endif /* OVERLAY_CLIPRECTS */ }
/* frameRect : Draws the outline of a rectangle. Parameter Descriptions context : The CG context to render to. r : The CG rectangle that defines the rectangle's boundary. */ void frameRect(CGContextRef context, CGRect r) { CGContextStrokeRect(context, r); }