Пример #1
0
// 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
}
Пример #2
0
// 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
}
Пример #3
0
// 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
}
Пример #4
0
//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)
}
Пример #5
0
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)
}
Пример #6
0
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)}
}
Пример #7
0
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
}
Пример #8
0
//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)
}