// // Stage 4 - Draw a 2K by 2K source image to an offscreen 512 x 512 CG Layer, // effectively caching the original image. The test measures how fast drawing // the cached layer takes. The cache alleviates the time taken to color match the // image and also time required to downsample the image. // This cache technique is useful when the image has to be repeatedly draw at the // same scale. The difference between this test the previous is that the previous // performed the caching using a bitmap context. This one caches using a CGLayerRef. // Notice that we don't need to know the colorspace or destination context's device // specific information when creating a CG Layer. // The source image is created programattically as a gradient between colors. // Returns: the number of operations per second for this stage // float drawStage4(CGContextRef context, CGRect rect) { size_t numOperations; CGImageRef image; double delta; int i; unsigned char *data; CGLayerRef lyr; CGContextRef lyrContext; data = createGradientARGBBuffer(W, H); if (data == NULL) return 0; // Create the source image from the data provider image = createImage(W, H, data); // Create a layer from the destination context. The layer is the best representation // for the layer. We have to specify the size of the layer we want to create // in default userspace units. lyr = CGLayerCreateWithContext(context,CGSizeMake(ScaledToWidth,ScaledToHeight),NULL); // Now we want to draw in to layer, so get the CGContext for the layer to draw to lyrContext = CGLayerGetContext(lyr); // Draw the 3K x 3K source image once to the layer context CGContextDrawImage(lyrContext, CGRectMake(0,0,ScaledToWidth,ScaledToHeight), image); CFRelease(image); // Done with the image - now cached in the layer ref free(data); // free the source data // Perform the drawing operation once to get an rough idea of how long it will take delta = currentTime(); // Draw the contents of the layer to the destination CGContextDrawLayerAtPoint(context,CGPointMake(0,0),lyr); delta = currentTime() - delta; // Calculate the approximage number of operations needed in one second numOperations = SecsPerTest / delta; // Now run the test again repeatedly delta = currentTime(); for (i = 0 ; i < numOperations; i++) { // Draw the contents of the layer to the destination CGContextDrawLayerAtPoint(context,CGPointMake(0,0),lyr); } delta = currentTime() - delta; CFRelease(lyr); // done with the layer ref return (numOperations / delta); }
void GraphicsContext::fillRect(const FloatRect& rect) { if (paintingDisabled()) return; CGContextRef context = platformContext(); if (m_state.fillGradient) { CGContextSaveGState(context); CGContextConcatCTM(context, m_state.fillGradient->gradientSpaceTransform()); if (hasShadow()) { CGLayerRef layer = CGLayerCreateWithContext(context, CGSizeMake(rect.width(), rect.height()), 0); CGContextRef layerContext = CGLayerGetContext(layer); m_state.fillGradient->paint(layerContext); CGContextDrawLayerAtPoint(context, CGPointMake(rect.left(), rect.top()), layer); CGLayerRelease(layer); } else { CGContextClipToRect(context, rect); m_state.fillGradient->paint(this); } CGContextRestoreGState(context); return; } if (m_state.fillPattern) applyFillPattern(); CGContextFillRect(context, rect); }
void doSimpleCGLayer(CGContextRef context) { int i,j; CGSize s; // Create the layer. CGLayerRef layer = createCGLayerForDrawing(context); if(layer == NULL){ fprintf(stderr, "Couldn't create layer!\n"); return; } // Get the size of the layer created. s = CGLayerGetSize(layer); // Clip to a rect that corresponds to // a grid of 8x8 layer objects. CGContextClipToRect(context, CGRectMake(0, 0, 8*s.width, 8*s.height)); // Paint 8 rows of layer objects. for(j = 0 ; j < 8 ; j++){ CGContextSaveGState(context); // Paint 4 columns of layer objects, moving // across the drawing canvas by skipping a // square on the grid each time across. for(i = 0 ; i < 4 ; i++){ // Draw the layer at the current origin. CGContextDrawLayerAtPoint(context, CGPointZero, layer); // Translate across two layer widths. CGContextTranslateCTM(context, 2*s.width, 0); } CGContextRestoreGState(context); // Translate to the left one layer width on // even loop counts and to the right one // layer width on odd loop counts. Each // time through the outer loop, translate up // one layer height. CGContextTranslateCTM(context, (j % 2) ? s.width: -s.width, s.height); } // Release the layer when done drawing with it. CGLayerRelease(layer); }
void TilePDFWithCGLayer(CGContextRef context, CFURLRef url) { // Again this should really be computed based on // the area intended to be tiled. float fillwidth = 612., fillheight = 792.; CGSize s; float tileX, tileY, tileOffsetX, tileOffsetY; float w, h; CGLayerRef layer = createLayerWithImageForContext(context, url); if(layer == NULL){ fprintf(stderr, "Couldn't create the layer!\n"); return; } // Compute the tile size and offset. s = CGLayerGetSize(layer); tileX = s.width; tileY = s.height; #if DOSCALING // Space the tiles by the tile width and height // plus an extra 2 units in each dimension. tileOffsetX = 2. + tileX; tileOffsetY = 2. + tileY; #else // Add 6 units to the offset in each direction // if there is no scaling of the source PDF document. tileOffsetX = 6. + tileX; tileOffsetY = 6. + tileY; #endif // Now draw the contents of the layer to the context. // The layer is drawn at its true size (the size of // the tile) with its origin located at the corner // of each tile. for(h = 0; h < fillheight ; h += tileOffsetY) for(w = 0; w < fillwidth ; w += tileOffsetX){ CGContextDrawLayerAtPoint(context, CGPointMake(w, h), layer); } // Release the layer when done drawing with it. CGLayerRelease(layer); }
void CGContextDrawLayerAtPoint_wrap( CGContext *con, CGLayer* lay, float x, float y ) { CGContextDrawLayerAtPoint( con, CGPointMake(x, y), lay); }