diff --git a/area.go b/area.go index 5dfce26..3fd7cfb 100644 --- a/area.go +++ b/area.go @@ -315,3 +315,12 @@ func (a *Area) setRect(x int, y int, width int, height int, rr *[]resizerequest) func (a *Area) preferredSize() (width int, height int) { return a.sysData.preferredSize() } + +// internal function, but shared by all system implementations: &img.Pix[0] is not necessarily the first pixel in the image +func pixelDataPos(img *image.NRGBA) int { + return img.PixOffset(img.Rect.Min.X, img.Rect.Min.Y) +} + +func pixelData(img *image.NRGBA) *uint8 { + return &img.Pix[pixelDataPos(img)] +} diff --git a/area_darwin.go b/area_darwin.go index 8fc83a2..dcc6941 100644 --- a/area_darwin.go +++ b/area_darwin.go @@ -92,7 +92,7 @@ func areaView_drawRect(self C.id, rect C.struct_xrect) { } i := s.handler.Paint(cliprect) C.drawImage( - unsafe.Pointer(&i.Pix[0]), C.int64_t(i.Rect.Dx()), C.int64_t(i.Rect.Dy()), C.int64_t(i.Stride), + unsafe.Pointer(pixelData(i)), C.int64_t(i.Rect.Dx()), C.int64_t(i.Rect.Dy()), C.int64_t(i.Stride), C.int64_t(cliprect.Min.X), C.int64_t(cliprect.Min.Y)) } diff --git a/area_unix.go b/area_unix.go index d9ca2d2..926166f 100644 --- a/area_unix.go +++ b/area_unix.go @@ -60,7 +60,7 @@ func our_area_draw_callback(widget *C.GtkWidget, cr *C.cairo_t, data C.gpointer) // pixel order is [R G B A] (see Example 1 on https://developer.gnome.org/gdk-pixbuf/2.26/gdk-pixbuf-The-GdkPixbuf-Structure.html) so we don't have to convert anything // gdk-pixbuf is not alpha-premultiplied (thanks to desrt in irc.gimp.net/#gtk+) pixbuf := C.gdk_pixbuf_new_from_data( - (*C.guchar)(unsafe.Pointer(&i.Pix[0])), + (*C.guchar)(unsafe.Pointer(pixelData(i))), C.GDK_COLORSPACE_RGB, C.TRUE, // has alpha channel 8, // bits per sample diff --git a/area_windows.go b/area_windows.go index 5f69b6c..a0b855d 100644 --- a/area_windows.go +++ b/area_windows.go @@ -109,7 +109,7 @@ func paintArea(s *sysData) { // we don't have a choice but to convert it ourselves // TODO make realbits a part of sysData to conserve memory realbits := make([]byte, 4 * i.Rect.Dx() * i.Rect.Dy()) - p := 0 + p := pixelDataPos(i) q := 0 for y := i.Rect.Min.Y; y < i.Rect.Max.Y; y++ { nextp := p + i.Stride diff --git a/todo.md b/todo.md index 14810c7..4940360 100644 --- a/todo.md +++ b/todo.md @@ -71,7 +71,6 @@ super ultra important things: - GTK+ indefinite progress bar animation is choppy: make sure the speed we have now is the conventional speed for GTK+ programs (HIG doesn't list any) and that the choppiness is correct - Message boxes are not application-modal on some platforms - cast all objc_msgSend() direct invocations to the approrpiate types; this is how you're supposed to do things: https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaTouch64BitGuide/ConvertingYourAppto64-Bit/ConvertingYourAppto64-Bit.html http://lists.apple.com/archives/objc-language/2014/Jan/msg00011.html http://lists.apple.com/archives/cocoa-dev/2006/Feb/msg00753.html and many others -- Area drawing assumes that i.Pix[0] is the first pixel; this might not be the case (and the current documentation for AreaHandler.Paint() allows it). Fix it. other things: - on windows 7, progress bars seem to animate from 0 -> pos when you turn off marquee mode and set pos; see if that's documented or if I'm doing something wrong