Skip to content
This repository was archived by the owner on Aug 13, 2019. It is now read-only.

Commit 8c0ac93

Browse files
vvanpojrick
authored andcommitted
gtk.ImageNewFromPixbuf and gdk gdk.PixbufNew binding
Fix provided by jrick: gdk.Pixbuf.GetPixels() now uses the reflect package to return a non-copied slice of Pixbuf data Implemented gtk.GetPixbuf binding for GtkImage objects Added reference and runtime finalizer to Pixbuf in gdk.Pixbuf.GetPixels() to avoid having the returned byte slice point to freed memory.
1 parent 1096e07 commit 8c0ac93

File tree

2 files changed

+49
-10
lines changed

2 files changed

+49
-10
lines changed

gdk/gdk.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import "C"
2424
import (
2525
"errors"
2626
"github.com/conformal/gotk3/glib"
27+
"reflect"
2728
"runtime"
2829
"unsafe"
2930
)
@@ -550,10 +551,19 @@ func (v *Pixbuf) GetBitsPerSample() int {
550551
// GetPixels is a wrapper around gdk_pixbuf_get_pixels_with_length().
551552
// A Go slice is used to represent the underlying Pixbuf data array, one
552553
// byte per channel.
553-
func (v *Pixbuf) GetPixels() []byte {
554+
func (v *Pixbuf) GetPixels() (channels []byte) {
554555
var length C.guint
555556
c := C.gdk_pixbuf_get_pixels_with_length(v.native(), &length)
556-
return C.GoBytes(unsafe.Pointer(c), (C.int)(length))
557+
sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&channels))
558+
sliceHeader.Data = uintptr(unsafe.Pointer(c))
559+
sliceHeader.Len = int(length)
560+
sliceHeader.Cap = int(length)
561+
// To make sure the slice doesn't outlive the Pixbuf, add a reference
562+
v.Ref()
563+
runtime.SetFinalizer(&channels, func(_ *[]byte) {
564+
v.Unref()
565+
})
566+
return
557567
}
558568

559569
// GetWidth is a wrapper around gdk_pixbuf_get_width().
@@ -592,6 +602,20 @@ func (v *Pixbuf) GetOption(key string) (value string, ok bool) {
592602
return C.GoString((*C.char)(c)), true
593603
}
594604

605+
// PixbufNew is a wrapper around gdk_pixbuf_new().
606+
func PixbufNew(colorspace Colorspace, hasAlpha bool, bitsPerSample, width, height int) (*Pixbuf, error) {
607+
c := C.gdk_pixbuf_new(C.GdkColorspace(colorspace), gbool(hasAlpha),
608+
C.int(bitsPerSample), C.int(width), C.int(height))
609+
if c == nil {
610+
return nil, nilPtrErr
611+
}
612+
obj := &glib.Object{glib.ToGObject(unsafe.Pointer(c))}
613+
p := &Pixbuf{obj}
614+
obj.Ref()
615+
runtime.SetFinalizer(obj, (*glib.Object).Unref)
616+
return p, nil
617+
}
618+
595619
/*
596620
* GdkScreen
597621
*/

gtk/gtk.go

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3942,11 +3942,19 @@ func ImageNewFromResource(resourcePath string) (*Image, error) {
39423942
return i, nil
39433943
}
39443944

3945-
// TODO(jrick) GdkPixbuf
3946-
/*
3947-
func ImageNewFromPixbuf() {
3945+
// ImageNewFromPixbuf is a wrapper around gtk_image_new_from_pixbuf().
3946+
func ImageNewFromPixbuf(pixbuf *gdk.Pixbuf) (*Image, error) {
3947+
ptr := (*C.GdkPixbuf)(unsafe.Pointer(pixbuf.Native()))
3948+
c := C.gtk_image_new_from_pixbuf(ptr)
3949+
if c == nil {
3950+
return nil, nilPtrErr
3951+
}
3952+
obj := &glib.Object{glib.ToGObject(unsafe.Pointer(c))}
3953+
i := wrapImage(obj)
3954+
obj.RefSink()
3955+
runtime.SetFinalizer(obj, (*glib.Object).Unref)
3956+
return i, nil
39483957
}
3949-
*/
39503958

39513959
// TODO(jrick) GtkIconSet
39523960
/*
@@ -4044,11 +4052,18 @@ func (v *Image) GetStorageType() ImageType {
40444052
return ImageType(c)
40454053
}
40464054

4047-
// TODO(jrick) GdkPixbuf
4048-
/*
4049-
func (v *Image) GetPixbuf() {
4055+
// GetPixbuf() is a wrapper around gtk_image_get_pixbuf().
4056+
func (v *Image) GetPixbuf() *gdk.Pixbuf {
4057+
c := C.gtk_image_get_pixbuf(v.native())
4058+
if c == nil {
4059+
return nil
4060+
}
4061+
obj := &glib.Object{glib.ToGObject(unsafe.Pointer(c))}
4062+
pb := &gdk.Pixbuf{obj}
4063+
obj.Ref()
4064+
runtime.SetFinalizer(obj, (*glib.Object).Unref)
4065+
return pb
40504066
}
4051-
*/
40524067

40534068
// TODO(jrick) GtkIconSet
40544069
/*

0 commit comments

Comments
 (0)