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); }
void GraphicsContext::setPlatformShadow(const FloatSize& offset, float blur, const Color& color, ColorSpace colorSpace) { if (paintingDisabled()) return; CGFloat xOffset = offset.width(); CGFloat yOffset = offset.height(); CGFloat blurRadius = blur; CGContextRef context = platformContext(); if (!m_state.shadowsIgnoreTransforms) { CGAffineTransform userToBaseCTM = wkGetUserToBaseCTM(context); CGFloat A = userToBaseCTM.a * userToBaseCTM.a + userToBaseCTM.b * userToBaseCTM.b; CGFloat B = userToBaseCTM.a * userToBaseCTM.c + userToBaseCTM.b * userToBaseCTM.d; CGFloat C = B; CGFloat D = userToBaseCTM.c * userToBaseCTM.c + userToBaseCTM.d * userToBaseCTM.d; CGFloat smallEigenvalue = narrowPrecisionToCGFloat(sqrt(0.5 * ((A + D) - sqrt(4 * B * C + (A - D) * (A - D))))); // Extreme "blur" values can make text drawing crash or take crazy long times, so clamp blurRadius = min(blur * smallEigenvalue, narrowPrecisionToCGFloat(1000.0)); CGSize offsetInBaseSpace = CGSizeApplyAffineTransform(offset, userToBaseCTM); xOffset = offsetInBaseSpace.width; yOffset = offsetInBaseSpace.height; } // Work around <rdar://problem/5539388> by ensuring that the offsets will get truncated // to the desired integer. static const CGFloat extraShadowOffset = narrowPrecisionToCGFloat(1.0 / 128); if (xOffset > 0) xOffset += extraShadowOffset; else if (xOffset < 0) xOffset -= extraShadowOffset; if (yOffset > 0) yOffset += extraShadowOffset; else if (yOffset < 0) yOffset -= extraShadowOffset; // Check for an invalid color, as this means that the color was not set for the shadow // and we should therefore just use the default shadow color. if (!color.isValid()) CGContextSetShadow(context, CGSizeMake(xOffset, yOffset), blurRadius); else CGContextSetShadowWithColor(context, CGSizeMake(xOffset, yOffset), blurRadius, cachedCGColor(color, colorSpace)); }
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); }
void GraphicsContext::setShadow(const IntSize& size, int blur, const Color& color) { // Extreme "blur" values can make text drawing crash or take crazy long times, so clamp blur = min(blur, 1000); if (paintingDisabled()) return; // Check for an invalid color, as this means that the color was not set for the shadow // and we should therefore just use the default shadow color. CGContextRef context = platformContext(); if (!color.isValid()) CGContextSetShadow(context, CGSizeMake(size.width(), -size.height()), blur); // y is flipped. else { CGColorRef colorCG = cgColor(color); CGContextSetShadowWithColor(context, CGSizeMake(size.width(), -size.height()), // y is flipped. blur, colorCG); CGColorRelease(colorCG); } }
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 */ }
void CGContextSetShadow_wrap(CGContext *con, float x, float y, float blur) { CGContextSetShadow(con, CGSizeMake(x, y), blur); }