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