root/trunk/src/gtk/cairo-utils.c

Revision 974, 8.8 kB (checked in by shanoah, 5 months ago)

Clean up a few warnings in the gtk code, and don't show equippy chars in char creation.

  • Property svn:eol-style set to native
Line 
1 /*
2  * File: cairo_utils.c
3  * Purpose: Cairo calls for use in Angband ports
4  * (Currently for the Gtk port, but should be reusable.)
5  *
6  * Copyright (c) 2000-2007 Robert Ruehlmann, Shanoah Alkire
7  *
8  * This work is free software; you can redistribute it and/or modify it
9  * under the terms of either:
10  *
11  * a) the GNU General Public License as published by the Free Software
12  *    Foundation, version 2, or
13  *
14  * b) the "Angband licence":
15  *    This software may be copied and distributed for educational, research,
16  *    and not for profit purposes provided that this copyright and statement
17  *    are included in all such copies.  Other copyrights may also apply.
18  */
19
20 #include "angband.h"
21
22 #ifdef USE_GTK
23 #include "cairo-utils.h"
24
25 #define USE_PANGO
26 void set_foreground_color(cairo_t *cr, byte a)
27 {
28         cairo_set_source_rgb(cr,
29         (double)angband_color_table[a][1] / 256,
30         (double)angband_color_table[a][2] / 256,
31         (double)angband_color_table[a][3] / 256);
32 }
33
34 void init_cairo_rect(cairo_rectangle_t *r, int x, int y, int w, int h)
35 {
36         r->x = x;
37         r->y = y;
38         r->width = w;
39         r->height = h;
40 }
41
42 void c_rect(cairo_t *cr, cairo_rectangle_t r)
43 {
44         if (cr !=NULL)
45                 cairo_rectangle (cr, r.x, r.y, r.width, r.height);
46 }
47
48 /*
49  * Erase the whole term.
50  */
51 void cairo_clear(cairo_surface_t *surface, cairo_rectangle_t r, byte c)
52 {
53         cairo_t *cr = NULL;
54        
55         if ((surface != NULL) &&(cairo_surface_status(surface) == CAIRO_STATUS_SUCCESS))
56         {
57         cr = cairo_create(surface);
58        
59         if (cr !=NULL)
60         {
61                 cairo_save(cr);
62                 c_rect(cr, r);
63                 set_foreground_color(cr, c);
64                 cairo_fill(cr);
65                 cairo_close_path(cr);
66                 cairo_restore(cr);
67         }
68        
69                 cairo_destroy(cr);
70         }
71 }
72
73 void cairo_cursor(cairo_surface_t *surface, cairo_rectangle_t r, byte c)
74 {
75         cairo_t *cr;
76        
77         if (surface != NULL)
78         {
79         cr = cairo_create(surface);
80         if (cr !=NULL)
81         {
82                 cairo_save(cr);
83                 c_rect(cr, r);
84                
85                 set_foreground_color(cr, c);
86        
87                 cairo_set_operator(cr, CAIRO_OPERATOR_ADD);
88                 cairo_fill(cr);
89                 cairo_close_path(cr);
90                 cairo_restore(cr);
91         }
92                 cairo_destroy(cr);
93         }
94 }
95
96 void drawn_progress_bar(cairo_surface_t *surface, font_info *font, int x, int y, float curr, float max, byte color, int len)
97 {
98         cairo_t *cr;
99         int temp;
100         cairo_rectangle_t r;
101         float percent;
102         measurements size;
103        
104          size.w = font->w;
105         size.h = font->h;
106        
107         if (surface != NULL)
108         {
109         cr = cairo_create(surface);
110        
111         if (max > 0)
112                 percent = curr / max;
113         else
114                 percent = 0;
115        
116         init_cairo_rect(&r, (size.w * x)+ 1, (size.h) * y + 1,  (size.w * len) - 1, size.h - 2);
117         cairo_clear(surface, r, TERM_DARK);
118        
119         temp = cairo_get_line_width(cr);
120         set_foreground_color(cr, color);
121        
122         if (percent > 0)
123         {
124                 cairo_set_line_width(cr, size.h);
125                 cairo_move_to(cr, r.x, r.y + (r.height * 0.5));
126                 cairo_line_to(cr, (size.w * ((len * percent) + x)), r.y + (r.height * 0.5));
127                 cairo_stroke(cr);
128         }
129         if (max > 0)
130         {
131                 cairo_set_line_width(cr, 1);
132                
133                 set_foreground_color(cr, TERM_SLATE);
134                 c_rect(cr, r);
135                 cairo_stroke(cr);
136                
137                 cairo_set_line_width(cr, temp);
138         }
139                 cairo_destroy(cr);
140         }
141 }
142
143 void draw_tile(cairo_t *cr, cairo_matrix_t m, cairo_rectangle_t r, int tx, int ty)
144 {
145         if (cr !=NULL)
146         {
147                 cairo_save(cr);
148        
149                 /* Use the rect and pattern */
150                 c_rect(cr, r);
151                 cairo_set_source (cr, tile_pattern);
152        
153                 /* Pull the tile we need */
154                 cairo_surface_set_device_offset(graphical_tiles, tx - r.x, ty - r.y);
155        
156                 /* Use transparency */
157                 cairo_set_operator(cr, CAIRO_OPERATOR_ADD);
158        
159                 /* Use the matrix with our pattern */
160                 cairo_pattern_set_matrix(tile_pattern, &m);
161        
162                 /* Draw it */
163                 cairo_fill(cr);
164        
165                 cairo_restore(cr);
166         }
167 }
168
169 cairo_matrix_t cairo_font_scaling(cairo_surface_t *surface, double tile_w, double tile_h, double font_w, double font_h)
170 {
171         cairo_t *cr;
172         cairo_matrix_t m;
173         double sx, sy;
174
175         if (surface != NULL)
176         {
177         cr = cairo_create(surface);
178         if (cr !=NULL)
179         {
180                 /* Get a matrix set up to scale the graphics. */
181                 cairo_get_matrix(cr, &m);
182                 sx = (tile_w)/(font_w);
183                 sy = (tile_h)/(font_h);
184                 cairo_matrix_scale(&m, sx, sy);
185         }
186        
187         cairo_destroy(cr);
188         }
189         return(m);
190 }
191
192 void cairo_draw_from_surface(cairo_t *cr, cairo_surface_t *surface, cairo_rectangle_t r)
193 {       
194         if ((cr !=NULL) && (surface != NULL))
195         {
196                 cairo_save(cr);
197                 c_rect(cr, r);
198                 cairo_set_source_surface(cr, surface, 0, 0);
199                 cairo_fill(cr);
200                 cairo_restore(cr);
201         }
202 }
203
204 /*
205  * Main reason for the lengthy header is strictly so we don't rely on the font size and tile size
206  * having one particular naming convention in term data. That should probably be standardized
207  * across the board, honestly.
208  */
209 void draw_tiles(
210 cairo_surface_t *surface, int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp,
211 font_info *font, measurements *actual, measurements *tile)
212 {
213         cairo_t *cr;
214         cairo_rectangle_t char_rect, r;
215         int i;
216        
217         /* Tile & Current Position */
218         int tx, ty;
219         int cx, cy;
220        
221         if (surface != NULL)
222         {
223         cr = cairo_create(surface);
224         if (cr !=NULL)
225         {
226         init_cairo_rect(&r, x * font->w, y * font->h,  actual->w * n, actual->h);
227        
228         cairo_clear(surface, r, TERM_DARK);
229        
230         /* Get the current position, Minus cx, which changes for each iteration */
231         cx = 0;
232         cy = (y * font->h);
233        
234         for (i = 0; i < n; i++)
235         {
236                 /* Increment x 1 step; use the font width because of equippy chars and the gap between
237                  * the status bar and the map.
238                  */
239                 cx += x * font->w;
240                 init_cairo_rect(&char_rect, cx, cy, actual->w, actual->h);
241                
242                 cairo_clear(surface, char_rect, TERM_DARK);
243                 /* Get the terrain tile, scaled to the font size */
244                 tx= (tcp[i] & 0x7F) * actual->w;
245                 ty = (tap[i] & 0x7F) * actual->h;
246                
247                 draw_tile(cr, matrix, char_rect, tx, ty);
248        
249                 /* If foreground is the same as background, we're done */
250                 if ((tap[i] == ap[i]) && (tcp[i] == cp[i])) continue;
251                
252                 /* Get the foreground tile size, scaled to the font size */
253                 tx = (cp[i] & 0x7F) * actual->w;
254                 ty = (ap[i] & 0x7F) * actual->h;
255        
256                 draw_tile(cr, matrix, char_rect, tx, ty);
257         }
258         }
259         cairo_destroy(cr);
260         }
261 }
262
263 void get_font_size(font_info *font)
264 {
265         #ifndef USE_PANGO
266         get_toy_font_size(font);
267         #else
268         PangoRectangle r;
269         PangoLayout *temp;
270         PangoFontDescription *temp_font;
271        
272         cairo_t *cr;
273         cairo_surface_t *surface;
274        
275         surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 200, 200);
276         cr = cairo_create(surface);
277        
278         temp = pango_cairo_create_layout(cr);
279         temp_font = pango_font_description_from_string(font->name);
280        
281         /* Draw an @, and measure it */
282         pango_layout_set_font_description(temp, temp_font);
283         pango_layout_set_text(temp, "@", 1);
284         pango_cairo_show_layout(cr, temp);
285         pango_layout_get_pixel_extents(temp, NULL, &r);
286        
287         font->w = r.width;
288         font->h = r.height;
289        
290         pango_font_description_free(temp_font);
291         cairo_destroy(cr);
292         cairo_surface_destroy(surface);
293         g_object_unref(temp);
294         #endif
295 }
296
297 void draw_text(cairo_surface_t *surface, font_info *font, measurements *actual, int x, int y, int n, byte a, cptr s)
298 {
299         cairo_t *cr;
300        
301         if (surface != NULL)
302         {
303         cairo_rectangle_t r;
304         PangoLayout *layout;
305         PangoFontDescription *temp_font;
306                
307         cr = cairo_create(surface);
308         #ifndef USE_PANGO
309         draw_toy_text(cr, font, actual, x, y, n, a, s);
310         #else
311        
312         if (cr !=NULL)
313         {
314         init_cairo_rect(&r, x * font->w, y * font->h,  actual->w * n, actual->h);
315        
316         cairo_clear(surface, r, TERM_DARK);
317                
318         /* Create a PangoLayout, set the font and text */
319         layout = pango_cairo_create_layout(cr);
320        
321         temp_font = pango_font_description_from_string(font->name);
322         set_foreground_color(cr, a);
323         pango_layout_set_text(layout, s, n);
324         pango_layout_set_font_description(layout, temp_font);
325        
326         /* Draw the text to the pixmap */
327         cairo_move_to(cr, x * font->w, y * font->h);
328        
329         pango_cairo_show_layout(cr, layout);
330         g_object_unref(G_OBJECT(layout));
331         }
332         #endif
333         cairo_destroy(cr);
334         }
335 }
336
337 /* Experimental - Currently messes up the display if larger then 12 point Monospace */
338 void set_cairo_font_size(cairo_t *cr, font_info *font)
339 {
340         double size;
341         cairo_font_extents_t extents;
342         cairo_text_extents_t text_extents;
343        
344         cairo_select_font_face(cr, font->family, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
345         size = font->size * (96.0/72.0);
346        
347         cairo_set_font_size(cr, size);
348        
349         cairo_font_extents(cr, &extents);
350         cairo_text_extents(cr, "@", &text_extents);
351        
352         font->w = extents.max_x_advance;
353         font->h = extents.height;
354         font->descent = extents.descent;
355        
356 }
357
358 void get_toy_font_size(font_info *font)
359 {
360         cairo_t *cr;
361         cairo_surface_t *surface;
362        
363         surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 200, 200);
364         cr = cairo_create(surface);
365        
366         set_cairo_font_size(cr, font);
367        
368         cairo_destroy(cr);
369         cairo_surface_destroy(surface);
370 }
371 void draw_toy_text(cairo_t *cr, font_info *font, measurements *actual, int x, int y, int n, byte a, cptr s)
372 {
373         char str[255];
374         cairo_rectangle_t r;
375        
376         set_cairo_font_size(cr, font);
377        
378         init_cairo_rect(&r, x * font->w, y * font->h,  font->w * n, font->h);
379        
380         c_rect(cr,r);
381         cairo_stroke(cr);
382        
383         my_strcpy(str, s, n + 1);
384        
385         if (cr !=NULL)
386         {
387                 set_foreground_color(cr, a);
388                 cairo_move_to(cr, x * (font->w), (y + 1) * font->h - font->descent);
389                 cairo_show_text(cr, str);
390         }
391 }
392
393 #endif  /*USE_GTK */
Note: See TracBrowser for help on using the browser.