2 * draw.c - draw functions
4 * Copyright © 2007-2008 Julien Danjou <julien@danjou.info>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <cairo-xlib.h>
29 extern AwesomeConf globalconf
;
31 /** Get a draw context
32 * \param phys_screen physical screen id
34 * \param height height
35 * \return draw context ref
38 draw_get_context(int phys_screen
, int width
, int height
)
40 DrawCtx
*d
= p_new(DrawCtx
, 1);
42 d
->phys_screen
= phys_screen
;
45 d
->depth
= DefaultDepth(globalconf
.display
, phys_screen
);
46 d
->visual
= DefaultVisual(globalconf
.display
, phys_screen
);
47 d
->drawable
= XCreatePixmap(globalconf
.display
,
48 RootWindow(globalconf
.display
, phys_screen
),
49 width
, height
, d
->depth
);
54 /** Free a draw context and its drawable
55 * \param ctx the draw context to free
58 draw_free_context(DrawCtx
*ctx
)
60 XFreePixmap(globalconf
.display
, ctx
->drawable
);
64 /** Draw text into a draw context
69 * \param align alignment
70 * \param padding padding to add before drawing the text
71 * \param font font to use
72 * \param text text to draw
73 * \param fg foreground color
74 * \param bg background color
77 draw_text(DrawCtx
*ctx
,
81 XftFont
*font
, const char *text
,
87 cairo_font_face_t
*font_face
;
88 cairo_surface_t
*surface
;
91 draw_rectangle(ctx
, area
, True
, bg
);
93 olen
= len
= a_strlen(text
);
98 surface
= cairo_xlib_surface_create(globalconf
.display
, ctx
->drawable
, ctx
->visual
, ctx
->width
, ctx
->height
);
99 cr
= cairo_create(surface
);
100 font_face
= cairo_ft_font_face_create_for_pattern(font
->pattern
);
101 cairo_set_font_face(cr
, font_face
);
102 cairo_set_font_size(cr
, font
->height
);
103 cairo_set_source_rgb(cr
, fg
.red
/ 65535.0, fg
.green
/ 65535.0, fg
.blue
/ 65535.0);
105 if(len
>= sizeof(buf
))
106 len
= sizeof(buf
) - 1;
107 memcpy(buf
, text
, len
);
109 while(len
&& (nw
= (draw_textwidth(font
, buf
)) + padding
* 2) > area
.width
)
112 return; /* too long */
126 cairo_move_to(cr
, area
.x
+ padding
, area
.y
+ font
->ascent
+ (ctx
->height
- font
->height
) / 2);
129 cairo_move_to(cr
, area
.x
+ (area
.width
- nw
) + padding
,
130 area
.y
+ font
->ascent
+ (ctx
->height
- font
->height
) / 2);
133 cairo_move_to(cr
, area
.x
+ ((area
.width
- nw
) / 2) + padding
,
134 area
.y
+ font
->ascent
+ (ctx
->height
- font
->height
) / 2);
137 cairo_show_text(cr
, buf
);
139 cairo_font_face_destroy(font_face
);
141 cairo_surface_destroy(surface
);
145 * \param ctx Draw context
146 * \param geometry geometry
147 * \param filled filled rectangle?
148 * \param color color to use
151 draw_rectangle(DrawCtx
*ctx
, Area geometry
, Bool filled
, XColor color
)
153 cairo_surface_t
*surface
;
156 surface
= cairo_xlib_surface_create(globalconf
.display
, ctx
->drawable
, ctx
->visual
, ctx
->width
, ctx
->height
);
157 cr
= cairo_create (surface
);
159 cairo_set_antialias(cr
, CAIRO_ANTIALIAS_NONE
);
160 cairo_set_line_width(cr
, 1.0);
161 cairo_set_source_rgb(cr
, color
.red
/ 65535.0, color
.green
/ 65535.0, color
.blue
/ 65535.0);
164 cairo_rectangle(cr
, geometry
.x
, geometry
.y
, geometry
.width
, geometry
.height
);
168 cairo_rectangle(cr
, geometry
.x
+ 1, geometry
.y
, geometry
.width
- 1, geometry
.height
- 1);
173 cairo_surface_destroy(surface
);
176 /* draws a graph; it takes the line-lengths from 'h' (w = size of h)
177 * It cycles backwards through it, beginning at position h_index, until
178 * h_index is reached again (wrapped around). */
181 draw_graph(DrawCtx
*ctx
, int x
, int y
, int w
, int *h
, int h_index
, XColor color
)
183 cairo_surface_t
*surface
;
187 surface
= cairo_xlib_surface_create(globalconf
.display
, ctx
->drawable
, ctx
->visual
, ctx
->width
, ctx
->height
);
188 cr
= cairo_create (surface
);
190 cairo_set_antialias(cr
, CAIRO_ANTIALIAS_NONE
);
191 cairo_set_line_width(cr
, 1.0);
192 cairo_set_source_rgb(cr
, color
.red
/ 65535.0, color
.green
/ 65535.0, color
.blue
/ 65535.0);
197 cairo_move_to(cr
, x
, y
);
198 cairo_line_to(cr
, x
, y
- h
[h_index
]);
208 cairo_surface_destroy(surface
);
212 draw_circle(DrawCtx
*ctx
, int x
, int y
, int r
, Bool filled
, XColor color
)
214 cairo_surface_t
*surface
;
217 surface
= cairo_xlib_surface_create(globalconf
.display
, ctx
->drawable
, ctx
->visual
, ctx
->width
, ctx
->height
);
218 cr
= cairo_create (surface
);
219 cairo_set_line_width(cr
, 1.0);
220 cairo_set_source_rgb(cr
, color
.red
/ 65535.0, color
.green
/ 65535.0, color
.blue
/ 65535.0);
223 cairo_arc (cr
, x
+ r
, y
+ r
, r
, 0, 2 * M_PI
);
227 cairo_arc (cr
, x
+ r
, y
+ r
, r
- 1, 0, 2 * M_PI
);
232 cairo_surface_destroy(surface
);
235 void draw_image_from_argb_data(DrawCtx
*ctx
, int x
, int y
, int w
, int h
,
236 int wanted_h
, unsigned char *data
)
239 cairo_surface_t
*surface
, *source
;
242 surface
= cairo_xlib_surface_create(globalconf
.display
, ctx
->drawable
, ctx
->visual
, ctx
->width
, ctx
->height
);
243 source
= cairo_image_surface_create_for_data(data
, CAIRO_FORMAT_ARGB32
, w
, h
, 0);
244 cr
= cairo_create (surface
);
245 if(wanted_h
> 0 && h
> 0)
247 ratio
= (double) wanted_h
/ (double) h
;
248 cairo_scale(cr
, ratio
, ratio
);
249 cairo_set_source_surface(cr
, source
, x
/ ratio
, y
/ ratio
);
252 cairo_set_source_surface(cr
, source
, x
, y
);
256 cairo_surface_destroy(source
);
257 cairo_surface_destroy(surface
);
261 draw_image(DrawCtx
*ctx
, int x
, int y
, int wanted_h
, const char *filename
)
265 cairo_surface_t
*surface
, *source
;
268 source
= cairo_xlib_surface_create(globalconf
.display
, ctx
->drawable
, ctx
->visual
, ctx
->width
, ctx
->height
);
269 surface
= cairo_image_surface_create_from_png(filename
);
270 cr
= cairo_create (source
);
271 if(wanted_h
> 0 && (h
= cairo_image_surface_get_height(surface
)) > 0)
273 ratio
= (double) wanted_h
/ (double) h
;
274 cairo_scale(cr
, ratio
, ratio
);
275 cairo_set_source_surface(cr
, surface
, x
/ ratio
, y
/ ratio
);
278 cairo_set_source_surface(cr
, surface
, x
, y
);
282 cairo_surface_destroy(source
);
283 cairo_surface_destroy(surface
);
287 draw_get_image_size(const char *filename
)
290 cairo_surface_t
*surface
;
292 surface
= cairo_image_surface_create_from_png(filename
);
293 cairo_image_surface_get_width(surface
);
296 size
.width
= cairo_image_surface_get_width(surface
);
297 size
.height
= cairo_image_surface_get_height(surface
);
298 cairo_surface_destroy(surface
);
304 draw_rotate(DrawCtx
*ctx
, int screen
, double angle
, int tx
, int ty
)
306 cairo_surface_t
*surface
, *source
;
308 Drawable newdrawable
;
310 newdrawable
= XCreatePixmap(globalconf
.display
,
311 RootWindow(globalconf
.display
, screen
),
312 ctx
->height
, ctx
->width
,
314 surface
= cairo_xlib_surface_create(globalconf
.display
, newdrawable
, ctx
->visual
, ctx
->height
, ctx
->width
);
315 source
= cairo_xlib_surface_create(globalconf
.display
, ctx
->drawable
, ctx
->visual
, ctx
->width
, ctx
->height
);
316 cr
= cairo_create (surface
);
318 cairo_translate(cr
, tx
, ty
);
319 cairo_rotate(cr
, angle
);
321 cairo_set_source_surface(cr
, source
, 0.0, 0.0);
325 cairo_surface_destroy(source
);
326 cairo_surface_destroy(surface
);
332 draw_textwidth(XftFont
*font
, char *text
)
334 cairo_surface_t
*surface
;
336 cairo_font_face_t
*font_face
;
337 cairo_text_extents_t te
;
342 surface
= cairo_xlib_surface_create(globalconf
.display
, DefaultScreen(globalconf
.display
),
343 DefaultVisual(globalconf
.display
, DefaultScreen(globalconf
.display
)),
344 DisplayWidth(globalconf
.display
, DefaultScreen(globalconf
.display
)),
345 DisplayHeight(globalconf
.display
, DefaultScreen(globalconf
.display
)));
346 cr
= cairo_create(surface
);
347 font_face
= cairo_ft_font_face_create_for_pattern(font
->pattern
);
348 cairo_set_font_face(cr
, font_face
);
349 cairo_set_font_size(cr
, font
->height
);
350 cairo_text_extents(cr
, text
, &te
);
352 cairo_surface_destroy(surface
);
353 cairo_font_face_destroy(font_face
);
355 return MAX(te
.x_advance
, te
.width
);
359 draw_get_align(const char *align
)
361 if(!a_strncmp(align
, "center", 6))
363 else if(!a_strncmp(align
, "right", 5))
369 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80