// CreateImageSurface is a wrapper around cairo_image_surface_create(). func CreateImageSurface(format Format, width, height int) *Surface { c := C.cairo_image_surface_create(C.cairo_format_t(format), C.int(width), C.int(height)) s := wrapSurface(c) runtime.SetFinalizer(s, (*Surface).destroy) return s }
// Format is determined from filename extension // Supported formats: eps, jpeg, pdf, png, ps, svg // // Width and height are in pts for eps, pdf, ps, and svg; pixels for jpeg and png. // Pixel measures will be truncated into integers // // Close the graphic to write the file func Create(filename string, width float64, height float64) (*Graphic, error) { g := &Graphic{} var err error filename = filepath.Clean(filename) g.filename, err = filepath.Abs(filename) if err != nil { return nil, err } g.format = filepath.Ext(filename)[1:] // create the surface switch g.format { case "pdf": g.surface = C.cairo_pdf_surface_create( C.CString(filename), C.double(width), C.double(height), ) case "png", "jpeg": g.surface = C.cairo_image_surface_create( C.CAIRO_FORMAT_ARGB32, C.int(width), C.int(height), ) case "ps", "eps": g.surface = C.cairo_ps_surface_create( C.CString(filename), C.double(width), C.double(height), ) if g.format == "eps" { C.cairo_ps_surface_set_eps(g.surface, 1) } case "svg": g.surface = C.cairo_svg_surface_create( C.CString(filename), C.double(width), C.double(height), ) default: return nil, errors.New("cairo: unsupported format: " + g.format) } err = g.cairoSurfaceStatus() if err != nil { return nil, err } // create the cairo context g.cr = C.cairo_create(g.surface) err = g.cairoStatus() if err != nil { return nil, err } return g, nil }
// Create an image of the given size func Create(w, h int, mode ColorSpace) *Image { var img Image var format C.cairo_format_t switch mode { case MODE_RGB, MODE_G8: format = C.CAIRO_FORMAT_RGB24 case MODE_RGBA: format = C.CAIRO_FORMAT_ARGB32 default: format = C.CAIRO_FORMAT_A8 } img.ColorSpace = mode img.Surf = C.cairo_image_surface_create(format, C.int(w), C.int(h)) img.Ctx = C.cairo_create(img.Surf) img.W, img.H = w, h return &img }
//export our_area_draw_callback func our_area_draw_callback(widget *C.GtkWidget, cr *C.cairo_t, data C.gpointer) C.gboolean { var x0, y0, x1, y1 C.double var maxwid, maxht C.gint s := (*sysData)(unsafe.Pointer(data)) // thanks to desrt in irc.gimp.net/#gtk+ // these are in user coordinates, which match what coordinates we want by default, even out of a draw event handler (thanks johncc3, mclasen, and Company in irc.gimp.net/#gtk+) C.cairo_clip_extents(cr, &x0, &y0, &x1, &y1) // we do not need to clear the cliprect; GtkDrawingArea did it for us beforehand cliprect := image.Rect(int(x0), int(y0), int(x1), int(y1)) // the cliprect can actually fall outside the size of the Area; clip it by intersecting the two rectangles C.gtk_widget_get_size_request(widget, &maxwid, &maxht) cliprect = image.Rect(0, 0, int(maxwid), int(maxht)).Intersect(cliprect) if cliprect.Empty() { // no intersection; nothing to paint return C.FALSE // signals handled without stopping the event chain (thanks to desrt again) } i := s.handler.Paint(cliprect) surface := C.cairo_image_surface_create( C.CAIRO_FORMAT_ARGB32, // alpha-premultiplied; native byte order C.int(i.Rect.Dx()), C.int(i.Rect.Dy())) if status := C.cairo_surface_status(surface); status != C.CAIRO_STATUS_SUCCESS { panic(fmt.Errorf("cairo_create_image_surface() failed: %s\n", C.GoString(C.cairo_status_to_string(status)))) } // the flush and mark_dirty calls are required; see the cairo docs and https://git.gnome.org/browse/gtk+/tree/gdk/gdkcairo.c#n232 (thanks desrt in irc.gimp.net/#gtk+) C.cairo_surface_flush(surface) toARGB(i, uintptr(unsafe.Pointer(C.cairo_image_surface_get_data(surface))), int(C.cairo_image_surface_get_stride(surface))) C.cairo_surface_mark_dirty(surface) C.cairo_set_source_surface(cr, surface, 0, 0) // origin of the surface // that just set the brush that cairo uses: we have to actually draw now // (via https://developer.gnome.org/gtkmm-tutorial/stable/sec-draw-images.html.en) C.cairo_rectangle(cr, x0, y0, x1, y1) // breaking the nrom here since we have the coordinates as a C double already C.cairo_fill(cr) C.cairo_surface_destroy(surface) // free surface return C.FALSE // signals handled without stopping the event chain (thanks to desrt again) }
func (i *imagelist) Append(img *image.RGBA) { var width, height C.gint surface := C.cairo_image_surface_create(C.CAIRO_FORMAT_ARGB32, C.int(img.Rect.Dx()), C.int(img.Rect.Dy())) if status := C.cairo_surface_status(surface); status != C.CAIRO_STATUS_SUCCESS { panic(fmt.Errorf("cairo_create_image_surface() failed in ImageList.Append(): %s\n", C.GoString(C.cairo_status_to_string(status)))) } C.cairo_surface_flush(surface) toARGB(img, uintptr(unsafe.Pointer(C.cairo_image_surface_get_data(surface))), int(C.cairo_image_surface_get_stride(surface)), false) // not NRGBA C.cairo_surface_mark_dirty(surface) basepixbuf := C.gdk_pixbuf_get_from_surface(surface, 0, 0, C.gint(img.Rect.Dx()), C.gint(img.Rect.Dy())) if basepixbuf == nil { panic(fmt.Errorf("gdk_pixbuf_get_from_surface() failed in ImageList.Append() (no reason available)")) } if C.gtk_icon_size_lookup(scaleTo, &width, &height) == C.FALSE { panic(fmt.Errorf("gtk_icon_size_lookup() failed in ImageList.Append() (no reason available)")) } if int(width) == img.Rect.Dx() && int(height) == img.Rect.Dy() { // just add the base pixbuf; we're good i.list = append(i.list, basepixbuf) C.cairo_surface_destroy(surface) return } // else scale pixbuf := C.gdk_pixbuf_scale_simple(basepixbuf, C.int(width), C.int(height), C.GDK_INTERP_NEAREST) if pixbuf == nil { panic(fmt.Errorf("gdk_pixbuf_scale_simple() failed in ImageList.Append() (no reason available)")) } i.list = append(i.list, pixbuf) C.gdk_pixbuf_unref(basepixbuf) C.cairo_surface_destroy(surface) }
func NewSurface(format Format, width, height int) *Surface { s := C.cairo_image_surface_create(C.cairo_format_t(format), C.int(width), C.int(height)) return &Surface{surface: s, context: C.cairo_create(s)} }
func NewSurface(format Format, width, height int) *Surface { surface := new(Surface) surface.surface = C.cairo_image_surface_create(C.cairo_format_t(format), C.int(width), C.int(height)) surface.context = C.cairo_create(surface.surface) return surface }
//NewImageSurface creates an image surface of the given width, height, //and format. // //Originally cairo_image_surface_create. func NewImageSurface(format Format, width, height int) (ImageSurface, error) { is := C.cairo_image_surface_create(format.c(), C.int(width), C.int(height)) stride := int(C.cairo_image_surface_get_stride(is)) return newImg(is, format, width, height, stride) }