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);
    }
}
Exemple #5
0
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 */
    }
Exemple #6
0
void CGContextSetShadow_wrap(CGContext *con, float x, float y, float blur) {
  CGContextSetShadow(con, CGSizeMake(x, y), blur);
}