91 lines
4.6 KiB
Go
91 lines
4.6 KiB
Go
|
/*
|
||
|
Package xgraphics defines an X image type and provides convenience functions
|
||
|
for reading and writing X pixmaps and bitmaps. It is a work-in-progress, and
|
||
|
while it works for some common X server configurations, it does not work for
|
||
|
all X server configurations. Package xgraphics also provides some support for
|
||
|
drawing text on to images using freetype-go, scaling images using graphics-go,
|
||
|
simple alpha blending, finding EWMH and ICCCM window icons and efficiently
|
||
|
drawing any image into an X pixmap. (Where "efficient" means being able to
|
||
|
specify sub-regions of images to draw, so that the entire image isn't sent to
|
||
|
X.) If more elaborate image routines are required, I recommend using draw2d.
|
||
|
(The xgraphics.Image type satisfies the draw.Image interface, which allows it
|
||
|
to work with draw2d.)
|
||
|
|
||
|
In general, xgraphics paints pixmaps to windows using using the BackPixmap
|
||
|
approach. (Setting the background pixmap of the window to the pixmap containing
|
||
|
your image, and clearing the window's background when the pixmap is updated.)
|
||
|
It also provides experimental support for another mechanism: copying the
|
||
|
contents of your image's pixmap directly to the window. (This requires
|
||
|
responding to expose events to redraw the pixmap.) The former approach requires
|
||
|
less book-keeping, but supposedly has some issues with some video cards. The
|
||
|
latter approach is probably more reliable, but requires more book-keeping.
|
||
|
|
||
|
Note that while text drawing functions are provided, it is not necessary to use
|
||
|
them to write text on images. Namely, there is nothing X specific about them.
|
||
|
They are strictly for convenience.
|
||
|
|
||
|
A quick example
|
||
|
|
||
|
This is a simple example the converts any value satisfying the image.Image
|
||
|
interface into an *xgraphics.Image value, and creates a new window with that
|
||
|
image painted in the window. (The XShow function probably doesn't have any
|
||
|
practical applications outside serving as an example, but can be useful for
|
||
|
debugging what an image looks like.)
|
||
|
|
||
|
imgFile, err := os.Open(imgPath)
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
img, _, err := image.Decode(imgFile)
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
ximg := xgraphics.NewConvert(XUtilValue, img)
|
||
|
ximg.XShow()
|
||
|
|
||
|
A complete working example named 'show-image' that's similar to this can be
|
||
|
found in the examples directory of the xgbutil package. More involved examples,
|
||
|
'show-window-icons' and 'pointer-painting', are also provided.
|
||
|
|
||
|
Portability
|
||
|
|
||
|
The xgraphics package *assumes* a particular kind of X server configuration.
|
||
|
Namely, this configuration specifies bits per pixel, image byte order, bitmap
|
||
|
bit order, scanline padding and unit length, image depth and so on. Handling
|
||
|
all of the possible values for each configuration option will greatly inflate
|
||
|
the code, but is on the TODO list.
|
||
|
|
||
|
I am (BurntSushi) undecided (perhaps because I haven't thought about it too much) about
|
||
|
whether to hide these configuration details behind multiple xgraphics.Image
|
||
|
types or hiding everything inside one xgraphics.Image type. I lean toward the
|
||
|
latter because the former requires a large number of types (and therefore a lot
|
||
|
of code duplication). One design decision that I've already made is that images
|
||
|
should be converted to the format used by the X server (xgraphics currently
|
||
|
assumes this is BGRx) once when the image is created. Without this, an
|
||
|
xgraphics.Image type wouldn't be required, and images would have to be
|
||
|
converted to the X image format every time an image is drawn into a pixmap.
|
||
|
This results in a lot of overhead. Moreover, Go's interfaces allow an
|
||
|
xgraphics.Image type to work anywhere that an image.Image or a draw.Image value
|
||
|
is expected.
|
||
|
|
||
|
The obvious down-side to this approach is that optimizations made in image
|
||
|
drawing routines in other libraries won't be able to apply to xgraphics.Image
|
||
|
values (since the optimizations are probably hard-coded for image types
|
||
|
declared in Go's standard library). This isn't well suited to the process of
|
||
|
creating some canvas to draw on, and using another library to draw on the
|
||
|
canvas. (At least, it won't be as fast as possible.) I can't think of any way
|
||
|
around this, other than having the library add an optimization step
|
||
|
specifically for xgraphics.Image values. Of course, the other approach is to
|
||
|
convert image formats only when drawing to X and completely subvert the
|
||
|
xgraphics.Image type, but this seems worse than unoptimized image drawing
|
||
|
routines. (Unfortunately, both things need to be fast.)
|
||
|
|
||
|
If your X server is not configured to what the xgraphics package expects,
|
||
|
messages will be emitted to stderr when a new xgraphics.Image value is created.
|
||
|
If you see any of these messages, please report them to xgbutil's project page:
|
||
|
https://github.com/jezek/xgbutil.
|
||
|
*/
|
||
|
package xgraphics
|