// 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 }
//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) }