static void paintRepaintRectOverlay(CGContextRef context, WKImageRef image, WKArrayRef repaintRects) { WKSize imageSize = WKImageGetSize(image); CGContextSaveGState(context); // Using a transparency layer is easier than futzing with clipping. CGContextBeginTransparencyLayer(context, 0); // Flip the context. CGContextScaleCTM(context, 1, -1); CGContextTranslateCTM(context, 0, -imageSize.height); CGContextSetRGBFillColor(context, 0, 0, 0, static_cast<CGFloat>(0.66)); CGContextFillRect(context, CGRectMake(0, 0, imageSize.width, imageSize.height)); // Clear the repaint rects. size_t count = WKArrayGetSize(repaintRects); for (size_t i = 0; i < count; ++i) { WKRect rect = WKRectGetValue(static_cast<WKRectRef>(WKArrayGetItemAtIndex(repaintRects, i))); CGRect cgRect = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); CGContextClearRect(context, cgRect); } CGContextEndTransparencyLayer(context); CGContextRestoreGState(context); }
void GiCanvasIos::clearWindow() { if (gs() && m_draw->getContext()) { CGContextClearRect(m_draw->getContext(), CGRectMake(0, 0, m_draw->width(), m_draw->height())); } }
bool GiCanvasIosImpl::createBufferBitmap(float width, float height, float scale) { width *= scale; // 点数宽度转为像素宽度 height *= scale; if (width < 4 || height < 4 || width > 2049 || height > 2049) { return false; } CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); _buffctx = CGBitmapContextCreate(NULL, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedLast); CGColorSpaceRelease(colorSpace); CGContextClearRect(_buffctx, CGRectMake(0, 0, width, height)); // 坐标系改为Y朝下,原点在左上角,这样除了放大倍数为1外,其余就与 _context 坐标系一致 //if (_buffctx && _context) { CGContextTranslateCTM(_buffctx, 0, height); CGContextScaleCTM(_buffctx, scale, - scale); //} //else if (_buffctx) { // CGContextScaleCTM(_buffctx, scale, scale); //} return !!_buffctx; }
FX_BOOL CFX_QuartzDeviceDriver::GetDIBits(CFX_DIBitmap* bitmap, FX_INT32 left, FX_INT32 top, void* pIccTransform, FX_BOOL bDEdge) { if (FXDC_PRINTER == _deviceClass) { return FALSE; } if (bitmap->GetBPP() < 32) { return FALSE; } if (!(_renderCaps | FXRC_GET_BITS)) { return FALSE; } CGPoint pt = CGPointMake(left, top); pt = CGPointApplyAffineTransform(pt, _foxitDevice2User); CGAffineTransform ctm = CGContextGetCTM(_context); pt.x *= FXSYS_fabs(ctm.a); pt.y *= FXSYS_fabs(ctm.d); CGImageRef image = CGBitmapContextCreateImage(_context); if (NULL == image) { return FALSE; } CGFloat width = (CGFloat) bitmap->GetWidth(); CGFloat height = (CGFloat) bitmap->GetHeight(); if (width + pt.x > _width) { width -= (width + pt.x - _width); } if (height + pt.y > _height) { height -= (height + pt.y - _height); } CGImageRef subImage = CGImageCreateWithImageInRect(image, CGRectMake(pt.x, pt.y, width, height)); CGContextRef context = createContextWithBitmap(bitmap); CGRect rect = CGContextGetClipBoundingBox(context); CGContextClearRect(context, rect); CGContextDrawImage(context, rect, subImage); CGContextRelease(context); CGImageRelease(subImage); CGImageRelease(image); if (bitmap->HasAlpha()) { for (int row = 0; row < bitmap->GetHeight(); row ++) { FX_LPBYTE pScanline = (FX_LPBYTE)bitmap->GetScanline(row); for (int col = 0; col < bitmap->GetWidth(); col ++) { if (pScanline[3] > 0) { pScanline[0] = (pScanline[0] * 255.f / pScanline[3] + .5f); pScanline[1] = (pScanline[1] * 255.f / pScanline[3] + .5f); pScanline[2] = (pScanline[2] * 255.f / pScanline[3] + .5f); } pScanline += 4; } } } return TRUE; }
CGContextRef createRGBBitmapContext(size_t width, size_t height, Boolean wantDisplayColorSpace, Boolean needsTransparentBitmap) { /* This routine allocates data for a pixel array that contains width*height pixels where each pixel is 4 bytes. The format is 8-bit ARGB or XRGB, depending on whether needsTransparentBitmap is true. In order to get the recommended pixel alignment, the bytesPerRow is rounded up to the nearest multiple of BEST_BYTE_ALIGNMENT bytes. */ CGContextRef context; size_t bytesPerRow; unsigned char *rasterData; // Minimum bytes per row is 4 bytes per sample * number of samples. bytesPerRow = width*4; // Round to nearest multiple of BEST_BYTE_ALIGNMENT. bytesPerRow = COMPUTE_BEST_BYTES_PER_ROW(bytesPerRow); // Allocate the data for the raster. The total amount of data is bytesPerRow // times the number of rows. The function 'calloc' is used so that the // memory is initialized to 0. rasterData = calloc(1, bytesPerRow * height); if(rasterData == NULL){ fprintf(stderr, "Couldn't allocate the needed amount of memory!\n"); return NULL; } // The wantDisplayColorSpace argument passed to the function determines // whether or not to use the display color space or the generic calibrated // RGB color space. The needsTransparentBitmap argument determines whether // create a context that records alpha or not. context = CGBitmapContextCreate(rasterData, width, height, 8, bytesPerRow, (wantDisplayColorSpace ? getTheDisplayColorSpace(): getTheCalibratedRGBColorSpace()) , (needsTransparentBitmap ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst)); if(context == NULL){ // If the context couldn't be created, release the raster memory. free(rasterData); fprintf(stderr, "Couldn't create the context!\n"); return NULL; } // Either clear the rect or paint with opaque white, depending on // the needs of the caller. if(needsTransparentBitmap){ // Clear the context bits so they are transparent. CGContextClearRect(context, CGRectMake(0, 0, width, height)); }else{ // Since the drawing destination is opaque, first paint // the context bits to white. CGContextSaveGState(context); CGContextSetFillColorWithColor(context, getRGBOpaqueWhiteColor()); CGContextFillRect(context, CGRectMake(0, 0, width, height)); CGContextRestoreGState(context); } return context; }
DRAW_TEST_F(CGContextFlush, FillFlush, WhiteBackgroundTest<>) { CGContextRef context = GetDrawingContext(); CGRect bounds = GetDrawingBounds(); _CGContextPushBeginDraw(context); CGContextSetRGBFillColor(context, 1, 0, 0, 1); CGContextFillRect(context, bounds); // Flush the red fill rect CGContextFlush(context); CGContextSetRGBFillColor(context, 0, 0, 1, 1); CGContextFillRect(context, CGRectMake(0, 0, 300, 300)); // We should still have red & blue rectangle should not show up. 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); CGContextFlush(context); // We should now see the blue fill rect EXPECT_EQ(dataPtr[0], 0xff); EXPECT_EQ(dataPtr[1], 0x00); EXPECT_EQ(dataPtr[2], 0x00); EXPECT_EQ(dataPtr[3], 0xff); // Add some extra drawings CGContextClearRect(context, CGRectMake(100, 100, 200, 300)); CGPoint center = _CGRectGetCenter(bounds); CGMutablePathRef concentricCirclesPath = CGPathCreateMutable(); CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 50, 50 }, center)); CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 100, 100 }, center)); CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 150, 150 }, center)); CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 200, 200 }, center)); CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 0.5); CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); CGContextAddPath(context, concentricCirclesPath); CGContextDrawPath(context, kCGPathFillStroke); CGPathRelease(concentricCirclesPath); _CGContextPopEndDraw(context); }
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 InitButton(unsigned w, unsigned h) { CGColorSpaceRef colorspace; CGContextRef gc; unsigned char *data; float cx, cy; data = (unsigned char *)malloc(w * h * 4); colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); gc = CGBitmapContextCreate(data, w, h, 8, w * 4, colorspace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); cx = CENTERX * w; cy = CENTERY * h; // background CGContextTranslateCTM(gc, 0.0, h); CGContextScaleCTM(gc, 1.0, -1.0); CGContextClearRect(gc, CGRectMake(0, 0, w, h)); CGContextSetRGBFillColor(gc, 0.0, 0.0, 0.0, 0.8); AddRoundedRectToPath(gc, CGRectMake(w*0.05, h*0.5 - 32, w*0.9, 64), 32, 32); CGContextFillPath(gc); CGGradientRef gradient; size_t num_locations = 2; CGFloat locations[2] = { 0.0, 1.0 }; CGFloat components[8] = { 1.0, 1.0, 1.0, 0.5, // Start color 0.0, 0.0, 0.0, 0.0 }; // End color gradient = CGGradientCreateWithColorComponents (colorspace, components, locations, num_locations); // top bevel CGContextSaveGState(gc); AddRoundedRectToPath(gc, CGRectMake(w*0.05, h*0.5 - 32, w*0.9, 64), 32, 32); CGContextEOClip(gc); CGContextDrawLinearGradient (gc, gradient, CGPointMake(cx, cy + 32), CGPointMake(cx, cy), 0); CGContextDrawLinearGradient (gc, gradient, CGPointMake(cx, cy - 32), CGPointMake(cx, cy - 16), 0); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); CGContextRelease(gc); CGColorSpaceRelease(colorspace); free(data); }
//----------------------------------------------------------------------------- void CGDrawContext::clearRect (const CRect& rect) { CGContextRef context = beginCGContext (true, currentState.drawMode.integralMode ()); if (context) { CGRect cgRect; if (currentState.drawMode.integralMode ()) cgRect = CGRectMake (round (rect.left), round (rect.top), round (rect.width ()), round (rect.height ())); else cgRect = CGRectMake (rect.left, rect.top, rect.width (), rect.height ()); CGContextClearRect (context, cgRect); releaseCGContext (context); } }
//----------------------------------------------------------------------------- void CGDrawContext::clearRect (const CRect& rect) { CGContextRef context = beginCGContext (true, getDrawMode ().integralMode ()); if (context) { CGRect cgRect = CGRectFromCRect (rect); if (getDrawMode ().integralMode ()) { cgRect = pixelAlligned (cgRect); } CGContextClearRect (context, cgRect); releaseCGContext (context); } }
void PoofItGood( Point centerPt ) { CGRect box; WindowRef window; Rect bounds; CGContextRef context; CGImageRef image; float windowWidth; float windowHeight; int i; image = GetThePoofImage(); if ( image == NULL ) goto Bail; windowWidth = CGImageGetWidth( image ) / NUMBER_OF_POOF_ANIM_FRAMES; windowHeight = CGImageGetHeight( image ); // Start our animation bounds at the first item in the animation strip box.origin.x = box.origin.y = 0; box.size.width = CGImageGetWidth( image ); box.size.height = CGImageGetHeight( image ); bounds.top = centerPt.v - (SInt16)(windowHeight / 2); bounds.left = centerPt.h - (SInt16)(windowWidth / 2); bounds.bottom = bounds.top + (SInt16)windowHeight; bounds.right = bounds.left + (SInt16)windowWidth; CreateNewWindow( kOverlayWindowClass, 0, &bounds, &window ); CreateCGContextForPort( GetWindowPort( window ), &context ); ShowWindow( window ); for ( i = 1; i <= NUMBER_OF_POOF_ANIM_FRAMES; i++ ) { CGContextClearRect( context, box ); CGContextDrawImage( context, box, image ); CGContextFlush( context ); Delay( EventTimeToTicks( POOF_ANIMATION_DELAY ), NULL ); box.origin.x -= windowWidth; } CGContextRelease( context ); CGImageRelease( image ); DisposeWindow( window ); Bail: return; }
bool UIMachineWindowSeamless::event(QEvent *pEvent) { switch (pEvent->type()) { case QEvent::Paint: { /* Clear the background */ CGContextClearRect(::darwinToCGContextRef(this), ::darwinToCGRect(frameGeometry())); break; } default: break; } return UIMachineWindow::event(pEvent); }
CGImageRef CreatePDFPageImage(CGPDFPageRef page, CGFloat scale, bool transparentBackground) { CGSize pageSize = PDFPageGetSize(page, kCGPDFCropBox); size_t width = scale * floorf(pageSize.width); size_t height = scale * floorf(pageSize.height); size_t bytesPerLine = width * 4; uint64_t size = (uint64_t)height * (uint64_t)bytesPerLine; if ((size == 0) || (size > SIZE_MAX)) return NULL; void *bitmapData = malloc(size); if (!bitmapData) return NULL; #if TARGET_OS_IPHONE CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); #else CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(&kCGColorSpaceSRGB ? kCGColorSpaceSRGB : kCGColorSpaceGenericRGB); #endif CGContextRef context = CGBitmapContextCreate(bitmapData, width, height, 8, bytesPerLine, colorSpace, kCGImageAlphaPremultipliedFirst); if (transparentBackground) { CGContextClearRect(context, CGRectMake(0, 0, width, height)); } else { CGContextSetRGBFillColor(context, 1, 1, 1, 1); // white CGContextFillRect(context, CGRectMake(0, 0, width, height)); } // CGPDFPageGetDrawingTransform unfortunately does not upscale, see http://lists.apple.com/archives/quartz-dev/2005/Mar/msg00112.html CGAffineTransform drawingTransform = PDFPageGetDrawingTransform(page, kCGPDFCropBox, scale); CGContextConcatCTM(context, drawingTransform); CGContextDrawPDFPage(context, page); CGImageRef pdfImage = CGBitmapContextCreateImage(context); CGContextRelease(context); CGColorSpaceRelease(colorSpace); free(bitmapData); return pdfImage; }
static pascal OSStatus OverlayWindowEventHandlerProc( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData ) { #pragma unused( inCallRef ) Rect windowRect; CGRect box; CGContextRef cgContext; UInt32 eventKind = GetEventKind( inEvent ); UInt32 eventClass = GetEventClass( inEvent ); OSStatus err = eventNotHandledErr; WindowStorage *windowStorage = (WindowStorage*) inUserData; switch ( eventClass ) { case kEventClassWindow: if ( eventKind == kEventWindowClose ) { windowStorage->overlayWindow = NULL; // Let the default handler DisposeWindow() for us, just set our WindowRef to NULL } else if ( (eventKind == kEventWindowBoundsChanged) || (eventKind == kEventWindowShown) ) // Draw the overlay window { GetWindowPortBounds( windowStorage->overlayWindow, &windowRect ); //box.origin.x = box.origin.y = 0; //box.size.width = windowRect.right - windowRect.left; //box.size.height = windowRect.bottom - windowRect.top; box = CGRectMake( 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top ); QDBeginCGContext( GetWindowPort(windowStorage->overlayWindow), &cgContext ); CGContextClearRect( cgContext, box ); // Paint a semi-transparent box in the middle of our window box.origin.x = (windowRect.right - windowRect.left) / 4; box.size.width = (windowRect.right - windowRect.left) / 2; CGContextSetRGBFillColor( cgContext, 0.5, 0.75, 0.75, 0.2 ); CGContextFillRect( cgContext, box ); CGContextFlush( cgContext ); QDEndCGContext( GetWindowPort(windowStorage->overlayWindow), &cgContext ); } break; } return( err ); }
static CGContextRef createAlphaOnlyContext(size_t width, size_t height) { /* This routine allocates data for a pixel array that contains width*height pixels, each pixel is 1 byte. The format is 8 bits per pixel, where the data is the alpha value of the pixel. */ CGContextRef context; size_t bytesPerRow; unsigned char *rasterData; // Minimum bytes per row is 1 byte per sample * number of samples. bytesPerRow = width; // Round to nearest multiple of BEST_BYTE_ALIGNMENT. bytesPerRow = COMPUTE_BEST_BYTES_PER_ROW(bytesPerRow); // Allocate the data for the raster. The total amount of data is bytesPerRow // times the number of rows. The function 'calloc' is used so that the // memory is initialized to 0. rasterData = calloc(1, bytesPerRow * height); if(rasterData == NULL){ fprintf(stderr, "Couldn't allocate the needed amount of memory!\n"); return NULL; } // This type of context is only available in Panther and later, otherwise // this fails and returns a NULL context. The color space for an alpha // only context is NULL and the BitmapInfo value is kCGImageAlphaOnly. context = CGBitmapContextCreate(rasterData, width, height, 8, bytesPerRow, NULL, kCGImageAlphaOnly); if(context == NULL){ // If the context couldn't be created then release the raster memory. free(rasterData); fprintf(stderr, "Couldn't create the context!\n"); return NULL; } // Clear the context bits so they are initially transparent. CGContextClearRect(context, CGRectMake(0, 0, width, height)); return context; }
// ImageCodecDrawBand // The base image decompressor calls your image decompressor component's ImageCodecDrawBand function // to decompress a band or frame. Your component must implement this function. If the ImageSubCodecDecompressRecord // structure specifies a progress function or data-loading function, the base image decompressor will never call ImageCodecDrawBand // at interrupt time. If the ImageSubCodecDecompressRecord structure specifies a progress function, the base image decompressor // handles codecProgressOpen and codecProgressClose calls, and your image decompressor component must not implement these functions. // If not, the base image decompressor may call the ImageCodecDrawBand function at interrupt time. // When the base image decompressor calls your ImageCodecDrawBand function, your component must perform the decompression specified // by the fields of the ImageSubCodecDecompressRecord structure. The structure includes any changes your component made to it // when performing the ImageCodecBeginBand function. If your component supports asynchronous scheduled decompression, // it may receive more than one ImageCodecBeginBand call before receiving an ImageCodecDrawBand call. pascal ComponentResult TextSubCodecDrawBand(TextSubGlobals glob, ImageSubCodecDecompressRecord *drp) { TextSubDecompressRecord *myDrp = (TextSubDecompressRecord *)drp->userDecompressRecord; CGImageAlphaInfo alphaFormat = (myDrp->pixelFormat == k32ARGBPixelFormat) ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaPremultipliedLast; CGContextRef c = CGBitmapContextCreate(drp->baseAddr, myDrp->width, myDrp->height, 8, drp->rowBytes, glob->colorSpace, alphaFormat); CGContextClearRect(c, CGRectMake(0,0, myDrp->width, myDrp->height)); CFMutableStringRef buf; if (drp->codecData[0] == '\n' && myDrp->dataSize == 1) goto leave; // skip empty packets if (myDrp->dataSize > kMaxSubPacketSize) goto leave; // skip very large packets, they probably cause stack overflows buf = (CFMutableStringRef)CFStringCreateWithBytesNoCopy(NULL, (UInt8*)drp->codecData, myDrp->dataSize, kCFStringEncodingUTF8, false, kCFAllocatorNull); if (!buf) goto leave; if (glob->translateSRT) { CFStringRef origBuf = buf; buf = CFStringCreateMutableCopy(NULL, 0, buf); CFRelease(origBuf); if (!buf) goto leave; CFStringFindAndReplace(buf, CFSTR("<i>"), CFSTR("{\\i1}"), CFRangeMake(0,CFStringGetLength(buf)), 0); CFStringFindAndReplace(buf, CFSTR("</i>"), CFSTR("{\\i0}"), CFRangeMake(0,CFStringGetLength(buf)), 0); CFStringFindAndReplace(buf, CFSTR("<"), CFSTR("{"), CFRangeMake(0,CFStringGetLength(buf)), 0); CFStringFindAndReplace(buf, CFSTR(">"), CFSTR("}"), CFRangeMake(0,CFStringGetLength(buf)), 0); } SubRendererRenderPacket(glob->ssa, c, buf, myDrp->width, myDrp->height); if (IsTransparentSubtitleHackEnabled()) ConvertImageToQDTransparent(drp->baseAddr, myDrp->pixelFormat, drp->rowBytes, myDrp->width, myDrp->height); CFRelease(buf); leave: CGContextRelease(c); return noErr; }
bool LockTarget(MCStackSurfaceTargetType p_type, void*& r_context) { if (p_type != kMCStackSurfaceTargetCoreGraphics) return false; CGImageRef t_mask; t_mask = nil; if (m_stack -> getwindowshape() != nil) t_mask = (CGImageRef)m_stack -> getwindowshape() -> handle; if (t_mask != nil) { MCRectangle t_card_rect; t_card_rect = m_stack -> getcurcard() -> getrect(); MCRectangle t_rect; t_rect = MCRegionGetBoundingBox(m_region); CGContextClearRect(m_context, CGRectMake(t_rect . x, t_card_rect . height - (t_rect . y + t_rect . height), t_rect . width, t_rect . height)); // MW-2012-07-25: [[ Bug ]] Make sure we use signed arithmetic to // compute the y-origin otherwise it wraps to 2^32! int32_t t_mask_height, t_mask_width; t_mask_width = (int32_t)CGImageGetWidth(t_mask); t_mask_height = (int32_t)CGImageGetHeight(t_mask); CGRect t_dst_rect; t_dst_rect . origin . x = 0; t_dst_rect . origin . y = ((int32_t)t_card_rect . height) - t_mask_height - m_stack -> getscroll(); t_dst_rect . size . width = t_mask_width; t_dst_rect . size . height = t_mask_height; CGContextClipToMask(m_context, t_dst_rect, t_mask); } CGContextSaveGState(m_context); r_context = m_context; return true; }
bool nglImageCGCodec::Feed(nglIStream* pIStream) { if (!mpCGImage) { mpCGImage = ReadInfo(pIStream); ///< shall allocate the buffer } if (!mpCGImage) return false; mpIStream = pIStream; // Use the generic RGB color space. CGColorSpaceRef pCGColors = CGColorSpaceCreateDeviceRGB(); if (pCGColors == NULL) { NGL_OUT(_T("nglImageCGCodec::Feed Error allocating color space\n")); return false; } nglImageInfo info; mpImage->GetInfo(info); NGL_ASSERT(info.mpBuffer); // Create the bitmap context. // The image will be converted to the format specified here by CGBitmapContextCreate. CGContextRef pCGContext = CGBitmapContextCreate(info.mpBuffer, info.mWidth, info.mHeight, info.mBitDepth/4, info.mBytesPerLine, pCGColors, kCGImageAlphaPremultipliedLast);//kCGImageAlphaPremultipliedFirst); CGColorSpaceRelease(pCGColors); CGRect rect = { {0,0}, {info.mWidth, info.mHeight} }; CGContextClearRect(pCGContext, rect); CGContextDrawImage(pCGContext, rect, mpCGImage); CGContextRelease(pCGContext); SendData(1.0f); return (pIStream->GetState()==eStreamWait) || (pIStream->GetState()==eStreamReady);; }
void GraphicsContext::clearRect(const FloatRect& r) { if (paintingDisabled()) return; CGContextClearRect(platformContext(), r); }
bool CBaseTexture::LoadFromFile(const CStdString& texturePath, unsigned int maxWidth, unsigned int maxHeight, bool autoRotate, unsigned int *originalWidth, unsigned int *originalHeight) { if (URIUtils::GetExtension(texturePath).Equals(".dds")) { // special case for DDS images CDDSImage image; if (image.ReadFile(texturePath)) { Update(image.GetWidth(), image.GetHeight(), 0, image.GetFormat(), image.GetData(), false); return true; } return false; } #if defined(__APPLE__) && defined(__arm__) XFILE::CFile file; UInt8 *imageBuff = NULL; int64_t imageBuffSize = 0; //open path and read data to buffer //this handles advancedsettings.xml pathsubstitution //and resulting networking if (file.Open(texturePath, 0)) { imageBuffSize =file.GetLength(); imageBuff = new UInt8[imageBuffSize]; imageBuffSize = file.Read(imageBuff, imageBuffSize); file.Close(); } else { CLog::Log(LOGERROR, "Texture manager unable to open file %s", texturePath.c_str()); return false; } if (imageBuffSize <= 0) { CLog::Log(LOGERROR, "Texture manager read texture file failed."); delete [] imageBuff; return false; } // create the image from buffer; CGImageSourceRef imageSource; // create a CFDataRef using CFDataCreateWithBytesNoCopy and kCFAllocatorNull for deallocator. // this allows us to do a nocopy reference and we handle the free of imageBuff CFDataRef cfdata = CFDataCreateWithBytesNoCopy(NULL, imageBuff, imageBuffSize, kCFAllocatorNull); imageSource = CGImageSourceCreateWithData(cfdata, NULL); if (imageSource == nil) { CLog::Log(LOGERROR, "Texture manager unable to load file: %s", CSpecialProtocol::TranslatePath(texturePath).c_str()); CFRelease(cfdata); delete [] imageBuff; return false; } CGImageRef image = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL); int rotate = 0; if (autoRotate) { // get the orientation of the image for displaying it correctly CFDictionaryRef imagePropertiesDictionary = CGImageSourceCopyPropertiesAtIndex(imageSource,0, NULL); if (imagePropertiesDictionary != nil) { CFNumberRef orientation = (CFNumberRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyOrientation); if (orientation != nil) { int value = 0; CFNumberGetValue(orientation, kCFNumberIntType, &value); if (value) rotate = value - 1; } CFRelease(imagePropertiesDictionary); } } CFRelease(imageSource); unsigned int width = CGImageGetWidth(image); unsigned int height = CGImageGetHeight(image); m_hasAlpha = (CGImageGetAlphaInfo(image) != kCGImageAlphaNone); if (originalWidth) *originalWidth = width; if (originalHeight) *originalHeight = height; // check texture size limits and limit to screen size - preserving aspectratio of image if ( width > g_Windowing.GetMaxTextureSize() || height > g_Windowing.GetMaxTextureSize() ) { float aspect; if ( width > height ) { aspect = (float)width / (float)height; width = g_Windowing.GetWidth(); height = (float)width / (float)aspect; } else { aspect = (float)height / (float)width; height = g_Windowing.GetHeight(); width = (float)height / (float)aspect; } CLog::Log(LOGDEBUG, "Texture manager texture clamp:new texture size: %i x %i", width, height); } // use RGBA to skip swizzling Allocate(width, height, XB_FMT_RGBA8); m_orientation = rotate; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // hw convert jmpeg to RGBA CGContextRef context = CGBitmapContextCreate(m_pixels, width, height, 8, GetPitch(), colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); CGColorSpaceRelease(colorSpace); // Flip so that it isn't upside-down //CGContextTranslateCTM(context, 0, height); //CGContextScaleCTM(context, 1.0f, -1.0f); #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 CGContextClearRect(context, CGRectMake(0, 0, width, height)); #else #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 // (just a way of checking whether we're running in 10.5 or later) if (CGContextDrawLinearGradient == 0) CGContextClearRect(context, CGRectMake(0, 0, width, height)); else #endif CGContextSetBlendMode(context, kCGBlendModeCopy); #endif //CGContextSetBlendMode(context, kCGBlendModeCopy); CGContextDrawImage(context, CGRectMake(0, 0, width, height), image); CGContextRelease(context); CGImageRelease(image); CFRelease(cfdata); delete [] imageBuff; #else DllImageLib dll; if (!dll.Load()) return false; ImageInfo image; memset(&image, 0, sizeof(image)); unsigned int width = maxWidth ? std::min(maxWidth, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize(); unsigned int height = maxHeight ? std::min(maxHeight, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize(); if(!dll.LoadImage(texturePath.c_str(), width, height, &image)) { CLog::Log(LOGERROR, "Texture manager unable to load file: %s", texturePath.c_str()); return false; } m_hasAlpha = NULL != image.alpha; Allocate(image.width, image.height, XB_FMT_A8R8G8B8); if (autoRotate && image.exifInfo.Orientation) m_orientation = image.exifInfo.Orientation - 1; if (originalWidth) *originalWidth = image.originalwidth; if (originalHeight) *originalHeight = image.originalheight; unsigned int dstPitch = GetPitch(); unsigned int srcPitch = ((image.width + 1)* 3 / 4) * 4; // bitmap row length is aligned to 4 bytes unsigned char *dst = m_pixels; unsigned char *src = image.texture + (m_imageHeight - 1) * srcPitch; for (unsigned int y = 0; y < m_imageHeight; y++) { unsigned char *dst2 = dst; unsigned char *src2 = src; for (unsigned int x = 0; x < m_imageWidth; x++, dst2 += 4, src2 += 3) { dst2[0] = src2[0]; dst2[1] = src2[1]; dst2[2] = src2[2]; dst2[3] = 0xff; } src -= srcPitch; dst += dstPitch; } if(image.alpha) { dst = m_pixels + 3; src = image.alpha + (m_imageHeight - 1) * m_imageWidth; for (unsigned int y = 0; y < m_imageHeight; y++) { unsigned char *dst2 = dst; unsigned char *src2 = src; for (unsigned int x = 0; x < m_imageWidth; x++, dst2+=4, src2++) *dst2 = *src2; src -= m_imageWidth; dst += dstPitch; } } dll.ReleaseImage(&image); #endif ClampToEdge(); return true; }
ImageBuffer::ImageBuffer(const FloatSize& size, float resolutionScale, ColorSpace imageColorSpace, RenderingMode renderingMode, bool& success) : m_logicalSize(size) , m_resolutionScale(resolutionScale) { float scaledWidth = ceilf(resolutionScale * size.width()); float scaledHeight = ceilf(resolutionScale * size.height()); // FIXME: Should we automatically use a lower resolution? if (!FloatSize(scaledWidth, scaledHeight).isExpressibleAsIntSize()) return; m_size = IntSize(scaledWidth, scaledHeight); m_data.backingStoreSize = m_size; success = false; // Make early return mean failure. bool accelerateRendering = renderingMode == Accelerated; if (m_size.width() <= 0 || m_size.height() <= 0) return; #if USE(IOSURFACE_CANVAS_BACKING_STORE) Checked<int, RecordOverflow> width = m_size.width(); Checked<int, RecordOverflow> height = m_size.height(); #endif // Prevent integer overflows m_data.bytesPerRow = 4 * Checked<unsigned, RecordOverflow>(m_data.backingStoreSize.width()); Checked<size_t, RecordOverflow> numBytes = Checked<unsigned, RecordOverflow>(m_data.backingStoreSize.height()) * m_data.bytesPerRow; if (numBytes.hasOverflowed()) return; #if USE(IOSURFACE_CANVAS_BACKING_STORE) IntSize maxSize = IOSurface::maximumSize(); if (width.unsafeGet() > maxSize.width() || height.unsafeGet() > maxSize.height()) accelerateRendering = false; #else ASSERT(renderingMode == Unaccelerated); #endif m_data.colorSpace = cachedCGColorSpace(imageColorSpace); RetainPtr<CGContextRef> cgContext; if (accelerateRendering) { #if USE(IOSURFACE_CANVAS_BACKING_STORE) FloatSize userBounds = scaleSizeToUserSpace(FloatSize(width.unsafeGet(), height.unsafeGet()), m_data.backingStoreSize, m_size); m_data.surface = IOSurface::create(m_data.backingStoreSize, IntSize(userBounds), imageColorSpace); cgContext = m_data.surface->ensurePlatformContext(); if (cgContext) CGContextClearRect(cgContext.get(), FloatRect(FloatPoint(), userBounds)); #endif if (!cgContext) accelerateRendering = false; // If allocation fails, fall back to non-accelerated path. } if (!accelerateRendering) { if (!tryFastCalloc(m_data.backingStoreSize.height(), m_data.bytesPerRow.unsafeGet()).getValue(m_data.data)) return; ASSERT(!(reinterpret_cast<intptr_t>(m_data.data) & 3)); #if USE_ARGB32 m_data.bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; #else m_data.bitmapInfo = kCGImageAlphaPremultipliedLast; #endif cgContext = adoptCF(CGBitmapContextCreate(m_data.data, m_data.backingStoreSize.width(), m_data.backingStoreSize.height(), 8, m_data.bytesPerRow.unsafeGet(), m_data.colorSpace, m_data.bitmapInfo)); // Create a live image that wraps the data. m_data.dataProvider = adoptCF(CGDataProviderCreateWithData(0, m_data.data, numBytes.unsafeGet(), releaseImageData)); if (!cgContext) return; m_data.context = std::make_unique<GraphicsContext>(cgContext.get()); } context().scale(FloatSize(1, -1)); context().translate(0, -m_data.backingStoreSize.height()); context().applyDeviceScaleFactor(m_resolutionScale); success = true; }
void wxOverlayImpl::Clear(wxWindowDC* dc) { wxASSERT_MSG( IsOk() , _("You cannot Clear an overlay that is not inited") ); CGRect box = CGRectMake( m_x - 1, m_y - 1 , m_width + 2 , m_height + 2 ); CGContextClearRect( m_overlayContext, box ); }
void LineTool( WindowRef window ) { OSStatus err; Point endPt; MouseTrackingResult trackingResult; Point beginPt; Rect windowRect; WindowRef overlayWindow; CGRect cgRect; CGContextRef cgContext; Boolean isStillDown = true; SetThemeCursor( kThemeCrossCursor ); SetPortWindowPort( window ); GetWindowPortBounds( window, &windowRect ); LocalToGlobalRect( &windowRect ); (void) CreateNewWindow( kOverlayWindowClass, kWindowHideOnSuspendAttribute | kWindowIgnoreClicksAttribute, &windowRect, &overlayWindow ); SetPortWindowPort( overlayWindow ); SetWindowGroup( overlayWindow, GetWindowGroup(window) ); // This assures we draw into the same layer as the window ShowWindow( overlayWindow ); GetMouse( &beginPt ); cgRect = CGRectMake( 0, 0, windowRect.right - windowRect.left+1, windowRect.bottom - windowRect.top+1 ); CreateCGContextForPort( GetWindowPort(overlayWindow), &cgContext ); CGContextSetLineWidth( cgContext, 3 ); // Line is 3 pixels wide CGContextSetRGBStrokeColor( cgContext, 1.0, .45, .3, .4 ); // Make it orange with alpha = 0.4 SyncCGContextOriginWithPort( cgContext, GetWindowPort(overlayWindow) ); CGContextTranslateCTM( cgContext, 0, windowRect.bottom - windowRect.top ); // Flip & rotate the context to use QD coordinates CGContextScaleCTM( cgContext, 1.0, -1.0 ); do { err = TrackMouseLocation( GetWindowPort(window), &endPt, &trackingResult ); switch ( trackingResult ) { case kMouseTrackingMouseDragged: CGContextClearRect( cgContext, cgRect ); // "Erase" the window #if ( 1 ) CGContextMoveToPoint( cgContext, beginPt.h, beginPt.v ); // Draw the line CGContextAddLineToPoint( cgContext, endPt.h, endPt.v ); CGContextStrokePath( cgContext ); #else MoveTo( beginPt.h, beginPt.v ); // We could use QuickDraw and draw opaque lines LineTo( endPt.h, endPt.v ); #endif CGContextFlush( cgContext ); // Flush our drawing to the screen break; case kMouseTrackingMouseDown: break; case kMouseTrackingMouseUp: case kMouseTrackingUserCancelled: isStillDown = false; break; } } while( isStillDown == true ); CGContextRelease( cgContext ); DisposeWindow( overlayWindow ); SetThemeCursor( kThemeArrowCursor ); return; }
static cairo_int_status_t _cairo_quartz_init_glyph_surface (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_image_surface_t *surface = NULL; CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph); int advance; CGRect bbox; double width, height; double xscale, yscale; double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont); CGColorSpaceRef gray; CGContextRef cgContext = NULL; CGAffineTransform textMatrix; CGRect glyphRect, glyphRectInt; CGPoint glyphOrigin; //fprintf (stderr, "scaled_glyph: %p surface: %p\n", scaled_glyph, scaled_glyph->surface); /* Create blank 2x2 image if we don't have this character. * Maybe we should draw a better missing-glyph slug or something, * but this is ok for now. */ if (glyph == INVALID_GLYPH) { surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, 2, 2); status = cairo_surface_status ((cairo_surface_t *) surface); if (status) return status; _cairo_scaled_glyph_set_surface (scaled_glyph, &font->base, surface); return CAIRO_STATUS_SUCCESS; } if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) || !CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox)) { return CAIRO_INT_STATUS_UNSUPPORTED; } status = _cairo_matrix_compute_basis_scale_factors (&font->base.scale, &xscale, &yscale, 1); if (status) return status; textMatrix = CGAffineTransformMake (font->base.scale.xx, -font->base.scale.yx, -font->base.scale.xy, font->base.scale.yy, 0.0f, 0.0f); glyphRect = CGRectMake (bbox.origin.x / emscale, bbox.origin.y / emscale, bbox.size.width / emscale, bbox.size.height / emscale); glyphRect = CGRectApplyAffineTransform (glyphRect, textMatrix); /* Round the rectangle outwards, so that we don't have to deal * with non-integer-pixel origins or dimensions. */ glyphRectInt = CGRectIntegral (glyphRect); #if 0 fprintf (stderr, "glyphRect[o]: %f %f %f %f\n", glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height); fprintf (stderr, "glyphRectInt: %f %f %f %f\n", glyphRectInt.origin.x, glyphRectInt.origin.y, glyphRectInt.size.width, glyphRectInt.size.height); #endif glyphOrigin = glyphRectInt.origin; //textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformInvert (ctm)); width = glyphRectInt.size.width; height = glyphRectInt.size.height; //fprintf (stderr, "glyphRect[n]: %f %f %f %f\n", glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height); surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, width, height); if (surface->base.status) return surface->base.status; gray = CGColorSpaceCreateDeviceGray (); cgContext = CGBitmapContextCreate (surface->data, surface->width, surface->height, 8, surface->stride, gray, kCGImageAlphaNone); CGColorSpaceRelease (gray); CGContextSetFont (cgContext, font_face->cgFont); CGContextSetFontSize (cgContext, 1.0); CGContextSetTextMatrix (cgContext, textMatrix); CGContextClearRect (cgContext, CGRectMake (0.0f, 0.0f, width, height)); if (font->base.options.antialias == CAIRO_ANTIALIAS_NONE) CGContextSetShouldAntialias (cgContext, false); CGContextSetRGBFillColor (cgContext, 1.0, 1.0, 1.0, 1.0); CGContextShowGlyphsAtPoint (cgContext, - glyphOrigin.x, - glyphOrigin.y, &glyph, 1); CGContextRelease (cgContext); cairo_surface_set_device_offset (&surface->base, - glyphOrigin.x, height + glyphOrigin.y); _cairo_scaled_glyph_set_surface (scaled_glyph, &font->base, surface); return status; }
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 */ }
static pascal OSStatus TransparentWindowHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData) { OSStatus status = eventNotHandledErr; switch(GetEventKind(inEvent)) { case kEventWindowGetRegion: { WindowRegionCode code; RgnHandle rgn; // which region code is being queried? GetEventParameter(inEvent, kEventParamWindowRegionCode, typeWindowRegionCode, NULL, sizeof(code), NULL, &code); // if it is the opaque region code then set the region to Empty and return noErr to stop the propagation if (code == kWindowOpaqueRgn) { GetEventParameter(inEvent, kEventParamRgnHandle, typeQDRgnHandle, NULL, sizeof(rgn), NULL, &rgn); SetEmptyRgn(rgn); status = noErr; } break; } case kEventWindowDrawContent: { GrafPtr port; CGContextRef context; Rect portBounds; HIRect bounds; GetPort(&port); GetPortBounds(port, &portBounds); // we need a Quartz context so that we can use transparency QDBeginCGContext(port, &context); // make the whole content transparent bounds = CGRectMake(0, 0, portBounds.right, portBounds.bottom); CGContextClearRect(context, bounds); QDEndCGContext(port, &context); // we need to let the HIToolbox and the regular kEventWindowDrawContent handler do their work, // mainly draw the subviews, so we return eventNotHandledErr to propagate. status = eventNotHandledErr; break; } case kEventControlDraw: { CGContextRef context; HIRect bounds; GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(context), NULL, &context); HIViewGetBounds((HIViewRef)inUserData, &bounds); // make the whole content transparent CGContextClearRect(context, bounds); // we must not let the default draw handler of the content view be called (it would draw the default opaque theme) // so we return noErr to stop the propagation. status = noErr; break; } } return status; }
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_pMachineView->machineLogic()->visualStateType() == UIVisualStateType_Seamless) { /* Determine current visible region: */ RegionRects *pRgnRcts = ASMAtomicXchgPtrT(&mRegion, NULL, RegionRects*); /* Prepare cleanup-region: */ QRegion cleanupRegion(aEvent->rect()); /* Filter out visible-rectangles; * That way we erase *only* invisible-rectangles of paint-region: */ if (pRgnRcts && pRgnRcts->used > 0) { /* Slowly, step-by-step filter our visible-rectangles: */ CGRect *pCgVisibleRect = pRgnRcts->rcts; for (ULONG uVisibleRectIndex = 0; uVisibleRectIndex < pRgnRcts->used; ++uVisibleRectIndex) { /* Prepare Qt visible-rectangle, flipping received CG visible-rectangle: */ CGRect cgVisibleRectFlippedToQt = ::darwinFlipCGRect(*pCgVisibleRect, viewRect.size.height); QRect visibleRect(cgVisibleRectFlippedToQt.origin.x, cgVisibleRectFlippedToQt.origin.y, cgVisibleRectFlippedToQt.size.width, cgVisibleRectFlippedToQt.size.height); /* Filter that rectangle out: */ cleanupRegion -= visibleRect; ++pCgVisibleRect; } } /* Erase cleanup-region: */ if (!cleanupRegion.isEmpty()) { /* Slowly, step-by-step erase cleanup-rectangles: */ foreach (const QRect &cleanupRect, cleanupRegion.rects()) { CGRect cgCleanupRect = ::darwinToCGRect(cleanupRect); CGContextClearRect(ctx, ::darwinFlipCGRect(cgCleanupRect, viewRect.size.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; }
static void initNeedle(unsigned w, unsigned h, unsigned max) { CGColorSpaceRef colorspace; CGContextRef gc; unsigned char *data; float cx, cy; float angle, radius, needle; data = (unsigned char *)malloc(w * h * 4); colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); gc = CGBitmapContextCreate(data, w, h, 8, w * 4, colorspace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); cx = CENTERX * w; cy = CENTERY * h; radius = 0.5 * (w > h ? w : h); needle = radius * 0.85; CGContextTranslateCTM(gc, 0.0, h); CGContextScaleCTM(gc, 1.0, -1.0); CGContextClearRect(gc, CGRectMake(0, 0, w, h)); angle = 0;//angleForValue(0, max); { // draw glow reflecting on inner bevel float dx, dy; dx = -cos(angle) + 1; dy = -sin(angle) + 1; CGGradientRef gradient; size_t num_locations = 2; CGFloat locations[2] = { 0.0, 1.0 }; CGFloat components[8] = { 0.7, 0.7, 1.0, 0.7, // Start color 0.0, 0.0, 0.0, 0.0 }; // End color gradient = CGGradientCreateWithColorComponents (colorspace, components, locations, num_locations); CGContextSaveGState(gc); CGContextAddArc(gc, cx, cy, needle*1.05, 0, 2*M_PI, false); CGContextAddArc(gc, cx, cy, needle*0.96, 0, 2*M_PI, false); CGContextEOClip(gc); CGContextDrawRadialGradient (gc, gradient, CGPointMake(cx*dx, cy*dy), radius*0.1, CGPointMake(cx*1.0, cy*1.0), radius*1.0, 0); CGContextRestoreGState(gc); } CGContextSetRGBFillColor(gc, 0.9, 0.9, 1.0, 1.0); // draw several glow passes, with the content offscreen CGContextTranslateCTM(gc, 0, OFFSCREEN - 10); CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7)); drawNeedle(gc, w, h, angle); CGContextTranslateCTM(gc, 0, 20); CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7)); drawNeedle(gc, w, h, angle); CGContextTranslateCTM(gc, -10, -10); CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7)); drawNeedle(gc, w, h, angle); CGContextTranslateCTM(gc, 20, 0); CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7)); drawNeedle(gc, w, h, angle); CGContextTranslateCTM(gc, -10, -OFFSCREEN); // draw real content CGContextSetShadowWithColor(gc, CGSizeMake(0, 1), 6.0, CGColorCreateGenericRGB(0.0, 0.0, 0.5, 0.7)); drawNeedle(gc, w, h, angle); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); CGContextRelease(gc); CGColorSpaceRelease(colorspace); free(data); }
static void initBackground(unsigned w, unsigned h, unsigned max) { CGColorSpaceRef colorspace; CGContextRef gc; unsigned char *data; float cx, cy; float radius, needle; data = (unsigned char *)malloc(w * h * 4); colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); gc = CGBitmapContextCreate(data, w, h, 8, w * 4, colorspace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); cx = CENTERX * w; cy = CENTERY * h; radius = 0.5 * (w > h ? w : h); needle = radius * 0.85; // background CGContextTranslateCTM(gc, 0.0, h); CGContextScaleCTM(gc, 1.0, -1.0); CGContextClearRect(gc, CGRectMake(0, 0, w, h)); CGContextSetRGBFillColor(gc, 0.0, 0.0, 0.0, 0.7); CGContextAddArc(gc, cx, cy, radius, 0, 2*M_PI, false); CGContextFillPath(gc); CGGradientRef gradient; size_t num_locations = 2; CGFloat locations[2] = { 0.0, 1.0 }; CGFloat components[8] = { 1.0, 1.0, 1.0, 0.5, // Start color 0.0, 0.0, 0.0, 0.0 }; // End color gradient = CGGradientCreateWithColorComponents (colorspace, components, locations, num_locations); // top rim light CGContextSaveGState(gc); CGContextAddArc(gc, cx, cy, radius, 0, 2*M_PI, false); CGContextAddArc(gc, cx, cy, needle*1.05, 0, 2*M_PI, false); CGContextEOClip(gc); CGContextDrawRadialGradient (gc, gradient, CGPointMake(cx, cy*1.00), radius*1.01, CGPointMake(cx, cy*0.96), radius*0.98, 0); // bottom rim light CGContextDrawRadialGradient (gc, gradient, CGPointMake(cx, cy*1.00), radius*1.01, CGPointMake(cx, cy*1.04), radius*0.98, 0); // top bevel CGContextDrawRadialGradient (gc, gradient, CGPointMake(cx, cy*2.2), radius*0.2, CGPointMake(cx, cy*1.0), radius*1.0, 0); // bottom bevel CGContextRestoreGState(gc); CGContextSaveGState(gc); CGContextAddArc(gc, cx, cy, needle*1.05, 0, 2*M_PI, false); CGContextAddArc(gc, cx, cy, needle*0.96, 0, 2*M_PI, false); CGContextEOClip(gc); CGContextDrawRadialGradient (gc, gradient, CGPointMake(cx, cy* -.5), radius*0.2, CGPointMake(cx, cy*1.0), radius*1.0, 0); CGGradientRelease(gradient); CGContextRestoreGState(gc); CGContextSetRGBFillColor(gc, 0.9, 0.9, 1.0, 1.0); CGContextSetRGBStrokeColor(gc, 0.9, 0.9, 1.0, 1.0); CGContextSetLineCap(gc, kCGLineCapRound); // draw several glow passes, with the content offscreen CGContextTranslateCTM(gc, 0, OFFSCREEN - 10); CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7)); drawMarks(gc, w, h, max); CGContextTranslateCTM(gc, 0, 20); CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7)); drawMarks(gc, w, h, max); CGContextTranslateCTM(gc, -10, -10); CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7)); drawMarks(gc, w, h, max); CGContextTranslateCTM(gc, 20, 0); CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7)); drawMarks(gc, w, h, max); CGContextTranslateCTM(gc, -10, -OFFSCREEN); // draw real content CGContextSetShadowWithColor(gc, CGSizeMake(0, 1), 6.0, CGColorCreateGenericRGB(0.7, 0.7, 1.0, 0.9)); drawMarks(gc, w, h, max); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); CGContextRelease(gc); CGColorSpaceRelease(colorspace); free(data); }