Example #1
0
// pdf, ps, and svg surfaces use the current surface (page)
func (g *Graphic) Image() (image.Image, error) {
	var surface *C.cairo_surface_t
	switch g.format {
	case "eps", "pdf", "ps", "svg":
		// map vector surfaces to an image surface
		surface = C.cairo_surface_map_to_image(g.surface, nil)
		defer C.cairo_surface_unmap_image(g.surface, surface)

		status := C.cairo_surface_status(surface)
		err := statusToError(status)
		if err != nil {
			return nil, err
		}
	case "png", "jpeg":
		// no conversion needed
		surface = g.surface
	}

	width := int(C.cairo_image_surface_get_width(surface))
	height := int(C.cairo_image_surface_get_height(surface))
	stride := int(C.cairo_image_surface_get_stride(surface))
	format := C.cairo_image_surface_get_format(surface)
	dataPtr := C.cairo_image_surface_get_data(surface)
	data := C.GoBytes(unsafe.Pointer(dataPtr), C.int(stride*height))

	var img image.Image
	switch format {
	case C.CAIRO_FORMAT_ARGB32:
		img = &extimage.ARGB{
			Pix:    data,
			Stride: stride,
			Rect:   image.Rect(0, 0, width, height),
		}
	case C.CAIRO_FORMAT_RGB24:
		img = &extimage.RGB{
			Pix:    data,
			Stride: stride,
			Rect:   image.Rect(0, 0, width, height),
		}
	case C.CAIRO_FORMAT_A8:
		img = &image.Alpha{
			Pix:    data,
			Stride: stride,
			Rect:   image.Rect(0, 0, width, height),
		}
	default:
		// known unsupported formats:
		// CAIRO_FORMAT_INVALID   = -1,
		// CAIRO_FORMAT_A1        = 3,
		// CAIRO_FORMAT_RGB16_565 = 4,
		// CAIRO_FORMAT_RGB30     = 5
		panic(fmt.Sprintf("unsupported cairo image surface format: %d", int(format)))
	}

	return img, nil
}
Example #2
0
//MapImage returns an image surface that is the most efficient mechanism
//for modifying the backing store of this surface.
//
//If r is Empty, the entire surface is mapped, otherwise, just the region
//described by r is mapped.
//
//Note that r is an image.Rectangle and not a cairo.Rectangle.
//
//It is the callers responsibility to all Close on the returned surface
//in order to upload the content of the mapped image to this surface and
//destroys the image surface.
//
//The returned surface is an ImageSurface with a special Close method.
//
//Warning
//
//Using this surface as a target or source while mapped is undefined.
//
//The result of mapping a surface multiple times is undefined.
//
//Changing the device transform of either surface before the image surface
//is unmapped is undefined.
//
//Originally cairo_surface_map_to_image.
func (e *XtensionSurface) MapImage(r image.Rectangle) (MappedImageSurface, error) {
	var rect C.cairo_rectangle_int_t
	rect.x, rect.y = C.int(r.Min.X), C.int(r.Min.Y)
	rect.width, rect.height = C.int(r.Dx()), C.int(r.Dy())
	rp := &rect
	if r.Empty() {
		//use entire image
		rp = nil
	}
	return newMappedImageSurface(C.cairo_surface_map_to_image(e.s, rp), e.s)
}