diff --git a/draw.c b/draw.c index 9796848f..6d0eef69 100644 --- a/draw.c +++ b/draw.c @@ -88,292 +88,6 @@ draw_iso2utf8(const char *iso, size_t len, char **dest, ssize_t *dlen) return true; } -/** Initialize a draw_text_context_t with text data. - * \param data The draw text context to init. - * \param str The text string to render. - * \param slen The text string length. - * \return True if everything is ok, false otherwise. - */ -bool -draw_text_context_init(draw_text_context_t *data, const char *str, ssize_t slen) -{ - GError *error = NULL; - - if(!str) - return false; - - if(!pango_parse_markup(str, slen, 0, &data->attr_list, &data->text, NULL, &error)) - { - warn("cannot parse pango markup: %s", error ? error->message : "unknown error"); - if(error) - g_error_free(error); - return false; - } - - data->len = a_strlen(data->text); - - return true; -} - -/** Initialize a new draw context. - * \param d The draw context to initialize. - * \param phys_screen Physical screen id. - * \param width Width. - * \param height Height. - * \param px Pixmap object to store. - * \param fg Foreground color. - * \param bg Background color. - */ -void -draw_context_init(draw_context_t *d, - int width, int height, xcb_pixmap_t px, - const xcolor_t *fg, const xcolor_t *bg) -{ - d->width = width; - d->height = height; - d->pixmap = px; - d->surface = cairo_xcb_surface_create(globalconf.connection, - px, globalconf.visual, - width, height); - d->cr = cairo_create(d->surface); - d->layout = pango_cairo_create_layout(d->cr); - d->fg = *fg; - d->bg = *bg; -}; - -/** Draw text into a draw context. - * \param ctx Draw context to draw to. - * \param data Draw text context data. - * \param ellip Ellipsize mode. - * \param wrap Wrap mode. - * \param align Text alignment. - * \param valign Vertical text alignment. - * \param area Area to draw to. - */ -void -draw_text(draw_context_t *ctx, draw_text_context_t *data, - PangoEllipsizeMode ellip, PangoWrapMode wrap, - alignment_t align, alignment_t valign, area_t area) -{ - pango_layout_set_text(ctx->layout, data->text, data->len); - pango_layout_set_width(ctx->layout, - pango_units_from_double(area.width)); - pango_layout_set_height(ctx->layout, pango_units_from_double(area.height)); - pango_layout_set_ellipsize(ctx->layout, ellip); - pango_layout_set_wrap(ctx->layout, wrap); - pango_layout_set_attributes(ctx->layout, data->attr_list); - pango_layout_set_font_description(ctx->layout, globalconf.font->desc); - - PangoRectangle ext; - pango_layout_get_pixel_extents(ctx->layout, NULL, &ext); - - switch(align) - { - case AlignCenter: - area.x += (area.width - ext.width) / 2; - break; - case AlignRight: - area.x += area.width - ext.width; - break; - default: - break; - } - - switch(valign) - { - case AlignCenter: - area.y += (area.height - ext.height) / 2; - break; - case AlignBottom: - area.y += area.height - ext.height; - break; - default: - break; - } - - cairo_move_to(ctx->cr, area.x, area.y); - - cairo_set_source_rgba(ctx->cr, - ctx->fg.red / 65535.0, - ctx->fg.green / 65535.0, - ctx->fg.blue / 65535.0, - ctx->fg.alpha / 65535.0); - pango_cairo_update_layout(ctx->cr, ctx->layout); - pango_cairo_show_layout(ctx->cr, ctx->layout); -} - -/** Draw rectangle inside the coordinates - * \param ctx Draw context - * \param geometry geometry - * \param line_width line width - * \param filled fill rectangle? - * \param color color to use - */ -void -draw_rectangle(draw_context_t *ctx, area_t geometry, - float line_width, bool filled, const color_t *color) -{ - cairo_set_antialias(ctx->cr, CAIRO_ANTIALIAS_NONE); - cairo_set_line_width(ctx->cr, line_width); - cairo_set_miter_limit(ctx->cr, 10.0); - cairo_set_line_join(ctx->cr, CAIRO_LINE_JOIN_MITER); - cairo_set_source_rgba(ctx->cr, - color->red / 255.0, - color->green / 255.0, - color->blue / 255.0, - color->alpha / 255.0); - if(filled) - { - cairo_rectangle(ctx->cr, geometry.x, geometry.y, - geometry.width, geometry.height); - cairo_fill(ctx->cr); - } - else - { - cairo_rectangle(ctx->cr, geometry.x + line_width / 2.0, geometry.y + line_width / 2.0, - geometry.width - line_width, geometry.height - line_width); - cairo_stroke(ctx->cr); - } -} - -/** Draw an image to a draw context. - * \param ctx Draw context to draw to. - * \param x X coordinate. - * \param y Y coordinate. - * \param ratio The ratio to apply to the image. - * \param source The image to draw. - */ -void -draw_surface(draw_context_t *ctx, int x, int y, - double ratio, cairo_surface_t *source) -{ - cairo_t *cr = cairo_create(ctx->surface); - cairo_scale(cr, ratio, ratio); - cairo_set_source_surface(cr, source, x / ratio, y / ratio); - cairo_paint(cr); - - cairo_destroy(cr); -} - -/** Rotate a pixmap. - * \param ctx Draw context to draw with. - * \param src Drawable to draw from. - * \param dest Drawable to draw to. - * \param src_w Drawable width. - * \param src_h Drawable height. - * \param dest_w Drawable width. - * \param dest_h Drawable height. - * \param angle angle to rotate. - * \param tx Translate to this x coordinate. - * \param ty Translate to this y coordinate. - */ -void -draw_rotate(draw_context_t *ctx, - xcb_pixmap_t src, xcb_pixmap_t dest, - int src_w, int src_h, - int dest_w, int dest_h, - double angle, int tx, int ty) -{ - cairo_surface_t *surface, *source; - cairo_t *cr; - - surface = cairo_xcb_surface_create(globalconf.connection, dest, - globalconf.visual, - dest_w, dest_h); - source = cairo_xcb_surface_create(globalconf.connection, src, - globalconf.visual, - src_w, src_h); - cr = cairo_create (surface); - - cairo_translate(cr, tx, ty); - cairo_rotate(cr, angle); - - cairo_set_source_surface(cr, source, 0.0, 0.0); - cairo_paint(cr); - - cairo_destroy(cr); - cairo_surface_destroy(source); - cairo_surface_destroy(surface); -} - -/** Return the width and height of a text in pixel. - * \param data The draw context text data. - * \return Text height and width. - */ -area_t -draw_text_extents(draw_text_context_t *data) -{ - cairo_surface_t *surface; - cairo_t *cr; - PangoLayout *layout; - PangoRectangle ext; - area_t geom = { 0, 0, 0, 0 }; - - if(data->len <= 0) - return geom; - - surface = cairo_xcb_surface_create(globalconf.connection, - globalconf.default_screen, - globalconf.visual, - globalconf.screen->width_in_pixels, - globalconf.screen->height_in_pixels); - - cr = cairo_create(surface); - layout = pango_cairo_create_layout(cr); - pango_layout_set_text(layout, data->text, data->len); - pango_layout_set_attributes(layout, data->attr_list); - pango_layout_set_font_description(layout, globalconf.font->desc); - pango_layout_get_pixel_extents(layout, NULL, &ext); - g_object_unref(layout); - cairo_destroy(cr); - cairo_surface_destroy(surface); - - geom.width = ext.width; - geom.height = ext.height; - - return geom; -} - -/** Transform a string to a alignment_t type. - * Recognized string are flex, fixed, left, center, middle or right. - * \param align A string with align text. - * \return An alignment_t type. - */ -alignment_t -draw_align_fromstr(const char *align) -{ - if(a_strcmp(align, "center") == 0) - return AlignCenter; - if(a_strcmp(align, "right") == 0) - return AlignRight; - if(a_strcmp(align, "top") == 0) - return AlignTop; - if(a_strcmp(align, "bottom") == 0) - return AlignBottom; - if(a_strcmp(align, "middle") == 0) - return AlignMiddle; - return AlignLeft; -} - -/** Transform an alignment to a string. - * \param a The alignment. - * \return A string which must not be freed. - */ -const char * -draw_align_tostr(alignment_t a) -{ - switch(a) - { - case AlignLeft: return "left"; - case AlignCenter: return "center"; - case AlignRight: return "right"; - case AlignBottom: return "bottom"; - case AlignTop: return "top"; - case AlignMiddle: return "middle"; - default: return NULL; - } -} - static cairo_user_data_key_t data_key; static inline void diff --git a/draw.h b/draw.h index ae47f5cd..bc39b74b 100644 --- a/draw.h +++ b/draw.h @@ -22,25 +22,10 @@ #ifndef AWESOME_COMMON_DRAW_H #define AWESOME_COMMON_DRAW_H -#include -#include - #include - #include -#include "color.h" -#include "common/array.h" - -typedef enum -{ - AlignLeft = (0), - AlignRight = (1), - AlignCenter = (1 << 1), - AlignTop = (1 << 2), - AlignBottom = (1 << 3), - AlignMiddle = (1 << 5) -} alignment_t; +#include "common/util.h" typedef struct area_t area_t; struct area_t @@ -57,44 +42,6 @@ struct area_t #define AREA_RIGHT(a) ((a).x + (a).width) #define AREA_BOTTOM(a) ((a).y + (a).height) -typedef struct -{ - xcb_pixmap_t pixmap; - uint16_t width; - uint16_t height; - cairo_t *cr; - cairo_surface_t *surface; - PangoLayout *layout; - xcolor_t fg; - xcolor_t bg; -} draw_context_t; - -void draw_context_init(draw_context_t *, int, int, - xcb_pixmap_t, const xcolor_t *, const xcolor_t *); - -/** Wipe a draw context. - * \param ctx The draw_context_t to wipe. - */ -static inline void -draw_context_wipe(draw_context_t *ctx) -{ - if(ctx->layout) - { - g_object_unref(ctx->layout); - ctx->layout = NULL; - } - if(ctx->surface) - { - cairo_surface_destroy(ctx->surface); - ctx->surface = NULL; - } - if(ctx->cr) - { - cairo_destroy(ctx->cr); - ctx->cr = NULL; - } -} - bool draw_iso2utf8(const char *, size_t, char **, ssize_t *); /** Convert a string to UTF-8. @@ -118,36 +65,8 @@ a_iso2utf8(const char *str, ssize_t len, char **dest, ssize_t *dlen) return false; } -typedef struct -{ - PangoAttrList *attr_list; - char *text; - ssize_t len; -} draw_text_context_t; - -bool draw_text_context_init(draw_text_context_t *, const char *, ssize_t); -void draw_text(draw_context_t *, draw_text_context_t *, PangoEllipsizeMode, PangoWrapMode, alignment_t, alignment_t, area_t); -void draw_rectangle(draw_context_t *, area_t, float, bool, const color_t *); -void draw_surface(draw_context_t *, int, int, double, cairo_surface_t *); -void draw_rotate(draw_context_t *, xcb_drawable_t, xcb_drawable_t, int, int, int, int, double, int, int); -area_t draw_text_extents(draw_text_context_t *); -alignment_t draw_align_fromstr(const char *); -const char *draw_align_tostr(alignment_t); int luaA_surface_from_data(lua_State *L, int width, int height, uint32_t *data); cairo_surface_t *draw_dup_image_surface(cairo_surface_t *surface); - -static inline void -draw_text_context_wipe(draw_text_context_t *pdata) -{ - if(pdata) - { - if(pdata->attr_list) - pango_attr_list_unref(pdata->attr_list); - p_delete(&pdata->text); - p_clear(pdata, 1); - } -} - #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80