third_party/cairo/src/cairo-quartz-surface.c
cairo_surface_t *
cairo_quartz_surface_create (cairo_format_t format,
			     unsigned int width,
			     unsigned int height)
{
    cairo_quartz_surface_t *surf;
    CGContextRef cgc;
    CGColorSpaceRef cgColorspace;
    CGBitmapInfo bitinfo;
    void *imageData;
    int stride;
    int bitsPerComponent;

    if (!_cairo_quartz_verify_surface_size (width, height))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));

    if (width == 0 || height == 0) {
	return &_cairo_quartz_surface_create_internal (NULL, _cairo_content_from_format (format),
						       width, height)->base;
    }

    if (format == CAIRO_FORMAT_ARGB32 ||
	format == CAIRO_FORMAT_RGB24)
    {
	cgColorspace = CGColorSpaceCreateDeviceRGB ();
	bitinfo = kCGBitmapByteOrder32Host;
	if (format == CAIRO_FORMAT_ARGB32)
	    bitinfo |= kCGImageAlphaPremultipliedFirst;
	else
	    bitinfo |= kCGImageAlphaNoneSkipFirst;
	bitsPerComponent = 8;
	stride = width * 4;
    } else if (format == CAIRO_FORMAT_A8) {
	cgColorspace = NULL;
	stride = width;
	bitinfo = kCGImageAlphaOnly;
	bitsPerComponent = 8;
    } else if (format == CAIRO_FORMAT_A1) {
	/* I don't think we can usefully support this, as defined by
	 * cairo_format_t -- these are 1-bit pixels stored in 32-bit
	 * quantities.
	 */
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
    } else {
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
    }

    /* The Apple docs say that for best performance, the stride and the data
     * pointer should be 16-byte aligned.  malloc already aligns to 16-bytes,
     * so we don't have to anything special on allocation.
     */
    stride = (stride + 15) & ~15;

    imageData = _cairo_malloc_ab (height, stride);
    if (unlikely (!imageData)) {
	CGColorSpaceRelease (cgColorspace);
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
    }

    /* zero the memory to match the image surface behaviour */
    memset (imageData, 0, height * stride);

    cgc = CGBitmapContextCreate (imageData,
				 width,
				 height,
				 bitsPerComponent,
				 stride,
				 cgColorspace,
				 bitinfo);
    CGColorSpaceRelease (cgColorspace);

    if (!cgc) {
	free (imageData);
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
    }

    /* flip the Y axis */
    CGContextTranslateCTM (cgc, 0.0, height);
    CGContextScaleCTM (cgc, 1.0, -1.0);

    surf = _cairo_quartz_surface_create_internal (cgc, _cairo_content_from_format (format),
						  width, height);
    if (surf->base.status) {
	CGContextRelease (cgc);
	free (imageData);
	// create_internal will have set an error
	return &surf->base;
    }

    surf->base.is_clear = TRUE;

    surf->imageData = imageData;
    surf->imageSurfaceEquiv = cairo_image_surface_create_for_data (imageData, format, width, height, stride);

    return &surf->base;
}
/**
 * cairo_quartz_surface_create:
 * @format: format of pixels in the surface to create
 * @width: width of the surface, in pixels
 * @height: height of the surface, in pixels
 *
 * Creates a Quartz surface backed by a CGBitmap.  The surface is
 * created using the Device RGB (or Device Gray, for A8) color space.
 * All Cairo operations, including those that require software
 * rendering, will succeed on this surface.
 *
 * Return value: the newly created surface.
 *
 * Since: 1.6
 **/
@format: format of pixels in the surface to create
@width: width of the surface, in pixels
@height: height of the surface, in pixels

Creates a Quartz surface backed by a CGBitmap.  The surface is
created using the Device RGB (or Device Gray, for A8) color space.
All Cairo operations, including those that require software
rendering, will succeed on this surface.

Return value: the newly created surface.


@format : format of pixels in the surface to create @width : width of the surface in pixels @height : height of the surface in pixels Creates a Quartz surface backed by a CGBitmap . The surface is created using the Device RGB ( or Device Gray for A8 ) color space . All Cairo operations including those that require software rendering will succeed on this surface . Return value : the newly created surface .
cairo_surface_t *
cairo_quartz_surface_create (cairo_format_t format,
			     unsigned int width,
			     unsigned int height)
{
    cairo_quartz_surface_t *surf;
    CGContextRef cgc;
    CGColorSpaceRef cgColorspace;
    CGBitmapInfo bitinfo;
    void *imageData;
    int stride;
    int bitsPerComponent;
    if (!_cairo_quartz_verify_surface_size (width, height))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
    if (width == 0 || height == 0) {
	return &_cairo_quartz_surface_create_internal (NULL, _cairo_content_from_format (format),
						       width, height)->base;
    }
    if (format == CAIRO_FORMAT_ARGB32 ||
	format == CAIRO_FORMAT_RGB24)
    {
	cgColorspace = CGColorSpaceCreateDeviceRGB ();
	bitinfo = kCGBitmapByteOrder32Host;
	if (format == CAIRO_FORMAT_ARGB32)
	    bitinfo |= kCGImageAlphaPremultipliedFirst;
	else
	    bitinfo |= kCGImageAlphaNoneSkipFirst;
	bitsPerComponent = 8;
	stride = width * 4;
    } else if (format == CAIRO_FORMAT_A8) {
	cgColorspace = NULL;
	stride = width;
	bitinfo = kCGImageAlphaOnly;
	bitsPerComponent = 8;
    } else if (format == CAIRO_FORMAT_A1) {
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
    } else {
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
    }
    stride = (stride + 15) & ~15;
    imageData = _cairo_malloc_ab (height, stride);
    if (unlikely (!imageData)) {
	CGColorSpaceRelease (cgColorspace);
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
    }
    memset (imageData, 0, height * stride);
    cgc = CGBitmapContextCreate (imageData,
				 width,
				 height,
				 bitsPerComponent,
				 stride,
				 cgColorspace,
				 bitinfo);
    CGColorSpaceRelease (cgColorspace);
    if (!cgc) {
	free (imageData);
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
    }
    CGContextTranslateCTM (cgc, 0.0, height);
    CGContextScaleCTM (cgc, 1.0, -1.0);
    surf = _cairo_quartz_surface_create_internal (cgc, _cairo_content_from_format (format),
						  width, height);
    if (surf->base.status) {
	CGContextRelease (cgc);
	free (imageData);
	return &surf->base;
    }
    surf->base.is_clear = TRUE;
    surf->imageData = imageData;
    surf->imageSurfaceEquiv = cairo_image_surface_create_for_data (imageData, format, width, height, stride);
    return &surf->base;
}
cairo_surface_t * cairo_quartz_surface_create ( cairo_format_t format , unsigned int width , unsigned int height ) { cairo_quartz_surface_t * surf ; CGContextRef cgc ; CGColorSpaceRef cgColorspace ; CGBitmapInfo bitinfo ; void * imageData ; int stride ; int bitsPerComponent ; if ( ! _cairo_quartz_verify_surface_size ( width , height ) ) return _cairo_surface_create_in_error ( _cairo_error ( CAIRO_STATUS_INVALID_SIZE ) ) ; if ( width == 0 || height == 0 ) { return & _cairo_quartz_surface_create_internal ( NULL , _cairo_content_from_format ( format ) , width , height ) -> base ; } if ( format == CAIRO_FORMAT_ARGB32 || format == CAIRO_FORMAT_RGB24 ) { cgColorspace = CGColorSpaceCreateDeviceRGB ( ) ; bitinfo = kCGBitmapByteOrder32Host ; if ( format == CAIRO_FORMAT_ARGB32 ) bitinfo |= kCGImageAlphaPremultipliedFirst ; else bitinfo |= kCGImageAlphaNoneSkipFirst ; bitsPerComponent = 8 ; stride = width * 4 ; } else if ( format == CAIRO_FORMAT_A8 ) { cgColorspace = NULL ; stride = width ; bitinfo = kCGImageAlphaOnly ; bitsPerComponent = 8 ; } else if ( format == CAIRO_FORMAT_A1 ) { return _cairo_surface_create_in_error ( _cairo_error ( CAIRO_STATUS_INVALID_FORMAT ) ) ; } else { return _cairo_surface_create_in_error ( _cairo_error ( CAIRO_STATUS_INVALID_FORMAT ) ) ; } stride = ( stride + 15 ) & ~ 15 ; imageData = _cairo_malloc_ab ( height , stride ) ; if ( unlikely ( ! imageData ) ) { CGColorSpaceRelease ( cgColorspace ) ; return _cairo_surface_create_in_error ( _cairo_error ( CAIRO_STATUS_NO_MEMORY ) ) ; } memset ( imageData , 0 , height * stride ) ; cgc = CGBitmapContextCreate ( imageData , width , height , bitsPerComponent , stride , cgColorspace , bitinfo ) ; CGColorSpaceRelease ( cgColorspace ) ; if ( ! cgc ) { free ( imageData ) ; return _cairo_surface_create_in_error ( _cairo_error ( CAIRO_STATUS_NO_MEMORY ) ) ; } CGContextTranslateCTM ( cgc , 0.0 , height ) ; CGContextScaleCTM ( cgc , 1.0 , -1.0 ) ; surf = _cairo_quartz_surface_create_internal ( cgc , _cairo_content_from_format ( format ) , width , height ) ; if ( surf -> base . status ) { CGContextRelease ( cgc ) ; free ( imageData ) ; return & surf -> base ; } surf -> base . is_clear = TRUE ; surf -> imageData = imageData ; surf -> imageSurfaceEquiv = cairo_image_surface_create_for_data ( imageData , format , width , height , stride ) ; return & surf -> base ; }
cairo_quartz_surface_create:
 @format: format of pixels in the surface to create
 @width: width of the surface, in pixels
 @height: height of the surface, in pixels
cairo_quartz_surface_create : @format : format of pixels in the surface to create @width : width of the surface in pixels @height : height of the surface in pixels
/* I don't think we can usefully support this, as defined by
	 * cairo_format_t -- these are 1-bit pixels stored in 32-bit
	 * quantities.
	 */ /* The Apple docs say that for best performance, the stride and the data
     * pointer should be 16-byte aligned.  malloc already aligns to 16-bytes,
     * so we don't have to anything special on allocation.
     */ /* zero the memory to match the image surface behaviour */ /* flip the Y axis */ // create_internal will have set an error