Beispiel #1
0
//FromImage copies an image into a surface.
//
//The created image surface will have the same size as img,
//the optimal stride for img's width, and FormatARGB32.
//
//Originally cairo_image_surface_create_for_data and
//cairo_format_stride_for_width.
func FromImage(img image.Image) (ImageSurface, error) {
	f := FormatARGB32.c()
	b := img.Bounds()
	w, h := b.Dx(), b.Dy()
	s := int(C.cairo_format_stride_for_width(f, C.int(w)))

	n := s * h
	data := (*C.uchar)(C.calloc(C.size_t(uintptr(n)), 1))
	pseudoslice := (*[1 << 30]C.uchar)(unsafe.Pointer(data))[:n:n]

	i := 0
	for y := b.Min.Y; y < b.Max.Y; y++ {
		for x := b.Min.X; x < b.Max.X; x++ {
			r, g, b, a := img.At(x, y).RGBA()
			pseudoslice[i+oA] = C.uchar(a)
			pseudoslice[i+oR] = C.uchar(r)
			pseudoslice[i+oG] = C.uchar(g)
			pseudoslice[i+oB] = C.uchar(b)
			i += 4
		}
		i += 4 * (s/4 - w)
	}

	is := C.cairo_image_surface_create_for_data(data, f, C.int(w), C.int(h), C.int(s))
	C.cairo_surface_set_user_data(is, imgKey, unsafe.Pointer(data), free)

	return newImg(is, FormatARGB32, w, h, s)
}
Beispiel #2
0
//XtensionRegisterWriter registers the writer wrapped by XtensionWrapWriter
//with the surface so that it does not get garbage collected until libcairo
//releases the surface.
//
//See XtensionWrapWriter for more information.
func (s *XtensionSurface) XtensionRegisterWriter(w unsafe.Pointer) {
	if err := s.Err(); err != nil {
		go_write_callback_reaper(w)
	}
	W := (*writer)(w)
	W.id = s.id()
	C.cairo_surface_set_user_data(s.s, wkey, w, C.wreaper_getter())
	storeWriter(W)
}
Beispiel #3
0
func surfaceSetID(s *C.cairo_surface_t) {
	if C.cairo_surface_get_user_data(s, idkey) != nil {
		return
	}
	C.cairo_surface_set_user_data(s, idkey, generateID(), free)
}