diff --git a/allegro5/bitmap.go b/allegro5/bitmap.go index 00b621c..2e3f41d 100644 --- a/allegro5/bitmap.go +++ b/allegro5/bitmap.go @@ -16,6 +16,7 @@ type Bitmap struct { bitmap *C.ALLEGRO_BITMAP width int height int + subs []*Bitmap } type DrawOptions struct { @@ -66,7 +67,7 @@ func newBitmap(width, height int, mut func(m FlagMutation), flags []NewBitmapFla if nil == b { return nil, errors.New("error creating bitmap") } - return &Bitmap{b, width, height}, nil + return &Bitmap{b, width, height, nil}, nil } // NewBitmap creates a new bitmap of given width and height and optional flags @@ -133,7 +134,7 @@ func NewBitmapFromImage(im image.Image, video bool) (*Bitmap, error) { }) C.al_convert_bitmap(b) } - return &Bitmap{b, width, height}, nil + return &Bitmap{b, width, height, nil}, nil } // LoadBitmap tries to load the image at the specified path as a bitmap @@ -146,7 +147,7 @@ func LoadBitmap(path string) (*Bitmap, error) { } width := int(C.al_get_bitmap_width(b)) height := int(C.al_get_bitmap_height(b)) - return &Bitmap{b, width, height}, nil + return &Bitmap{b, width, height, nil}, nil } // Draw draws the bitmap at the given location @@ -206,6 +207,22 @@ func (b *Bitmap) DrawOptions(left, top float32, options DrawOptions) { } } +// Sub creates a sub-bitmap of the original bitmap +func (b *Bitmap) Sub(x, y, w, h int) *Bitmap { + var sub = C.al_create_sub_bitmap(b.bitmap, C.int(x), C.int(y), C.int(w), C.int(h)) + if nil == sub { + return nil + } + var bmp = &Bitmap{sub, w, h, nil} + b.subs = append(b.subs, bmp) + return bmp +} + +// Subs returns the slice of sub-bitmaps +func (b *Bitmap) Subs() []*Bitmap { + return b.subs +} + func (b *Bitmap) Width() int { return b.width } @@ -220,5 +237,13 @@ func (b *Bitmap) SetAsTarget() { // Destroy destroys the bitmap func (b *Bitmap) Destroy() { - C.al_destroy_bitmap(b.bitmap) + var bmp = b.bitmap + if nil == bmp { + return + } + b.bitmap = nil + for _, sub := range b.subs { + sub.Destroy() + } + C.al_destroy_bitmap(bmp) } diff --git a/allegro5/color.go b/allegro5/color.go index 1afa266..c861cbc 100644 --- a/allegro5/color.go +++ b/allegro5/color.go @@ -2,15 +2,30 @@ package allegro5 // #include import "C" +import "image/color" + +var _ color.Color = &Color{} type Color struct { - color C.ALLEGRO_COLOR + color C.ALLEGRO_COLOR } func NewColor(r, g, b byte) Color { - return Color{C.al_map_rgb(C.uchar(r), C.uchar(g), C.uchar(b))} + return Color{C.al_map_rgb(C.uchar(r), C.uchar(g), C.uchar(b))} } -func NewColorAlpha(r, g, b, a byte) Color { - return Color{C.al_map_rgba(C.uchar(r), C.uchar(g), C.uchar(b), C.uchar(a))} -} \ No newline at end of file +func NewColorAlpha(r, g, b, a byte) Color { + return Color{C.al_map_rgba(C.uchar(r), C.uchar(g), C.uchar(b), C.uchar(a))} +} + +// RGBA implements the color.Color interface. +func (c Color) RGBA() (r, g, b, a uint32) { + var cr, cg, cb, ca C.uchar + C.al_unmap_rgba(c.color, &cr, &cg, &cb, &ca) + a = uint32(ca) + r = uint32(cr) * a + g = uint32(cg) * a + b = uint32(cb) * a + a *= a + return +} diff --git a/allegro5/font.go b/allegro5/font.go index 511fe71..4937860 100644 --- a/allegro5/font.go +++ b/allegro5/font.go @@ -12,6 +12,9 @@ import ( type Font struct { font *C.ALLEGRO_FONT + hght float32 + asc float32 + desc float32 } type HorizontalAlignment int @@ -30,7 +33,7 @@ func LoadTTFFont(path string, size int) (*Font, error) { if nil == f { return nil, fmt.Errorf("unable to load ttf font '%s'", path) } - return &Font{f}, nil + return &Font{f, 0, 0, 0}, nil } func (f *Font) drawFlags(a HorizontalAlignment) C.int { @@ -53,6 +56,45 @@ func (f *Font) Draw(left, top float32, color Color, align HorizontalAlignment, t C.al_draw_text(f.font, color.color, C.float(left), C.float(top), flags, t) } +// Ascent returns the ascent of the font +func (f *Font) Ascent() float32 { + if 0 == f.asc { + f.asc = float32(C.al_get_font_ascent(f.font)) + } + return f.asc +} + +// Descent returns the descent of the font. +func (f *Font) Descent() float32 { + if 0 == f.desc { + f.desc = float32(C.al_get_font_descent(f.font)) + } + return f.desc +} + +// Height returns the height of the font +func (f *Font) Height() float32 { + if 0 == f.hght { + f.hght = f.Ascent() + f.Descent() + } + return f.hght +} + +// TextDimensions returns the bounding box of the rendered text. +func (f *Font) TextDimensions(text string) (x, y, w, h float32) { + t := C.CString(text) + defer C.free(unsafe.Pointer(t)) + + var bbx, bby, bbw, bbh C.int + C.al_get_text_dimensions(f.font, t, &bbx, &bby, &bbw, &bbh) + x = float32(bbx) + y = float32(bby) + w = float32(bbw) + h = float32(bbh) + return +} + +// TextWidth returns the width of the rendered text. func (f *Font) TextWidth(text string) float32 { t := C.CString(text) defer C.free(unsafe.Pointer(t)) diff --git a/allegro5/primitives.go b/allegro5/primitives.go index 507c742..72205e0 100644 --- a/allegro5/primitives.go +++ b/allegro5/primitives.go @@ -3,6 +3,7 @@ package allegro5 // #include // #include import "C" +import "unsafe" func DrawFilledRectangle(x1, y1, x2, y2 float32, c Color) { C.al_draw_filled_rectangle(C.float(x1), C.float(y1), C.float(x2), C.float(y2), c.color) @@ -16,6 +17,10 @@ func DrawLine(x1, y1, x2, y2 float32, c Color, thickness float32) { C.al_draw_line(C.float(x1), C.float(y1), C.float(x2), C.float(y2), c.color, C.float(thickness)) } +func DrawPolyline(vertices []float32, c Color, thickness float32) { + C.al_draw_polyline((*C.float)(unsafe.Pointer(&vertices[0])), 8, C.int(len(vertices)>>1), C.ALLEGRO_LINE_JOIN_ROUND, C.ALLEGRO_LINE_CAP_ROUND, c.color, C.float(thickness), 1) +} + func DrawRectangle(x1, y1, x2, y2 float32, c Color, thickness float32) { C.al_draw_rectangle(C.float(x1), C.float(y1), C.float(x2), C.float(y2), c.color, C.float(thickness)) }