Freeciv-3.1: /fast/freeciv/nightly/S3_1/client/gui-gtk-3.0/canvas.c Source File

Freeciv-3.1

Loading...
Searching...
No Matches
canvas.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996-2005 - Freeciv Development Team
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18/* gui-gtk-3.0 */
19#include "colors.h"
20#include "gui_main.h"
21#include "mapview.h"
22
23#include "canvas.h"
24
25/************************************************************************/
28 struct canvas *canvas_create(int width, int height)
29{
30 struct canvas *result = fc_malloc(sizeof(*result));
31
32 result->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
33 width, height);
34 result->drawable = NULL;
35 result->zoom = 1.0;
36
37 return result;
38}
39
40/************************************************************************/
44 void canvas_free(struct canvas *store)
45{
46 cairo_surface_destroy(store->surface);
47 free(store);
48}
49
50/************************************************************************/
53 void canvas_set_zoom(struct canvas *store, float zoom)
54{
55 store->zoom = zoom;
56}
57
58/************************************************************************/
61 bool has_zoom_support(void)
62{
63 return TRUE;
64}
65
66/************************************************************************/
69 void canvas_mapview_init(struct canvas *store)
70{
71}
72
73/************************************************************************/
76 void canvas_copy(struct canvas *dest, struct canvas *src,
77 int src_x, int src_y, int dest_x, int dest_y,
78 int width, int height)
79{
80 cairo_t *cr;
81
82 if (!dest->drawable) {
83 cr = cairo_create(dest->surface);
84 } else {
85 cr = dest->drawable;
86 }
87
88 if (dest->drawable) {
89 cairo_save(cr);
90 }
91
92 cairo_scale(cr, dest->zoom / src->zoom, dest->zoom / src->zoom);
93 cairo_set_source_surface(cr, src->surface, dest_x - src_x, dest_y - src_y);
94 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
95 cairo_rectangle(cr, dest_x, dest_y, width, height);
96 cairo_fill(cr);
97
98 if (!dest->drawable) {
99 cairo_destroy(cr);
100 } else {
101 cairo_restore(cr);
102 }
103}
104
105/************************************************************************/
109 void canvas_put_sprite(struct canvas *pcanvas,
110 int canvas_x, int canvas_y,
111 struct sprite *sprite,
112 int offset_x, int offset_y, int width, int height)
113{
114 int sswidth, ssheight;
115 cairo_t *cr;
116
117 get_sprite_dimensions(sprite, &sswidth, &ssheight);
118
119 if (!pcanvas->drawable) {
120 cr = cairo_create(pcanvas->surface);
121 } else {
122 cr = pcanvas->drawable;
123 }
124
125 if (pcanvas->drawable) {
126 cairo_save(cr);
127 }
128
129 cairo_scale(cr, pcanvas->zoom, pcanvas->zoom);
130 cairo_set_source_surface(cr, sprite->surface, canvas_x - offset_x, canvas_y - offset_y);
131 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
132 cairo_rectangle(cr, canvas_x - offset_x, canvas_y - offset_y,
133 MIN(width, MAX(0, sswidth - offset_x)),
134 MIN(height, MAX(0, ssheight - offset_y)));
135 cairo_fill(cr);
136
137 if (!pcanvas->drawable) {
138 cairo_destroy(cr);
139 } else {
140 cairo_restore(cr);
141 }
142}
143
144/************************************************************************/
148 void canvas_put_sprite_full(struct canvas *pcanvas,
149 int canvas_x, int canvas_y,
150 struct sprite *sprite)
151{
152 int width, height;
153
154 get_sprite_dimensions(sprite, &width, &height);
155 canvas_put_sprite(pcanvas, canvas_x, canvas_y, sprite,
156 0, 0, width, height);
157}
158
159/************************************************************************/
163 void canvas_put_sprite_fogged(struct canvas *pcanvas,
164 int canvas_x, int canvas_y,
165 struct sprite *psprite,
166 bool fog, int fog_x, int fog_y)
167{
168 pixmap_put_overlay_tile_draw(pcanvas, canvas_x, canvas_y,
169 psprite, fog);
170}
171
172/************************************************************************/
176 void canvas_put_rectangle(struct canvas *pcanvas,
177 struct color *pcolor,
178 int canvas_x, int canvas_y, int width, int height)
179{
180 cairo_t *cr;
181
182 if (!pcanvas->drawable) {
183 cr = cairo_create(pcanvas->surface);
184 } else {
185 cr = pcanvas->drawable;
186 }
187
188 if (pcanvas->drawable) {
189 cairo_save(cr);
190 }
191
192 cairo_scale(cr, pcanvas->zoom, pcanvas->zoom);
193 gdk_cairo_set_source_rgba(cr, &pcolor->color);
194 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
195 cairo_rectangle(cr, canvas_x, canvas_y, width, height);
196 cairo_fill(cr);
197
198 if (!pcanvas->drawable) {
199 cairo_destroy(cr);
200 } else {
201 cairo_restore(cr);
202 }
203}
204
205/************************************************************************/
208 void canvas_fill_sprite_area(struct canvas *pcanvas,
209 struct sprite *psprite,
210 struct color *pcolor,
211 int canvas_x, int canvas_y)
212{
213 int width, height;
214 get_sprite_dimensions(psprite, &width, &height);
215 canvas_put_rectangle(pcanvas, pcolor, canvas_x, canvas_y, width, height);
216}
217
218/************************************************************************/
223 void canvas_put_line(struct canvas *pcanvas,
224 struct color *pcolor,
225 enum line_type ltype, int start_x, int start_y,
226 int dx, int dy)
227{
228 cairo_t *cr;
229 double dashes[2] = {4.0, 4.0};
230
231 if (!pcanvas->drawable) {
232 cr = cairo_create(pcanvas->surface);
233 } else {
234 cr = pcanvas->drawable;
235 }
236
237 if (pcanvas->drawable) {
238 cairo_save(cr);
239 }
240
241 switch (ltype) {
242 case LINE_NORMAL:
243 cairo_set_line_width(cr, 1.);
244 break;
245 case LINE_BORDER:
246 cairo_set_line_width(cr, (double)BORDER_WIDTH);
247 cairo_set_dash(cr, dashes, 2, 0);
248 break;
249 case LINE_TILE_FRAME:
250 cairo_set_line_width(cr, 2.);
251 break;
252 case LINE_GOTO:
253 cairo_set_line_width(cr, 2.);
254 break;
255 case LINE_SELECT_RECT:
256 cairo_set_line_width(cr, 2.);
257 cairo_set_dash(cr, dashes, 2, 0);
258 cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE);
259 break;
260 }
261
262 gdk_cairo_set_source_rgba(cr, &pcolor->color);
263 cairo_move_to(cr, start_x, start_y);
264 cairo_line_to(cr, start_x + dx, start_y + dy);
265 cairo_stroke(cr);
266
267 if (!pcanvas->drawable) {
268 cairo_destroy(cr);
269 } else {
270 cairo_restore(cr);
271 }
272}
273
274/************************************************************************/
278 void canvas_put_curved_line(struct canvas *pcanvas,
279 struct color *pcolor,
280 enum line_type ltype, int start_x, int start_y,
281 int dx, int dy)
282{
283 int end_x = start_x + dx;
284 int end_y = start_y + dy;
285 cairo_t *cr;
286 double dashes[2] = {4.0, 4.0};
287
288 if (!pcanvas->drawable) {
289 cr = cairo_create(pcanvas->surface);
290 } else {
291 cr = pcanvas->drawable;
292 }
293
294 if (pcanvas->drawable) {
295 cairo_save(cr);
296 }
297
298 switch (ltype) {
299 case LINE_NORMAL:
300 cairo_set_line_width(cr, 1.);
301 break;
302 case LINE_BORDER:
303 cairo_set_dash(cr, dashes, 2, 0);
304 cairo_set_line_width(cr, (double)BORDER_WIDTH);
305 break;
306 case LINE_TILE_FRAME:
307 cairo_set_line_width(cr, 2.);
308 break;
309 case LINE_GOTO:
310 cairo_set_line_width(cr, 2.);
311 break;
312 case LINE_SELECT_RECT:
313 cairo_set_line_width(cr, 2.);
314 cairo_set_dash(cr, dashes, 2, 0);
315 cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE);
316 break;
317 }
318
319 gdk_cairo_set_source_rgba(cr, &pcolor->color);
320 cairo_move_to(cr, start_x, start_y);
321 cairo_curve_to(cr, end_x, start_y, start_x, end_y, end_x, end_y);
322 cairo_stroke(cr);
323
324 if (!pcanvas->drawable) {
325 cairo_destroy(cr);
326 } else {
327 cairo_restore(cr);
328 }
329}
330
331 static PangoLayout *layout;
332static struct {
333 PangoFontDescription **styles;
334 bool shadowed;
335} fonts[FONT_COUNT] = {
336 {&city_names_style, TRUE},
337 {&city_productions_style, TRUE},
338 {&reqtree_text_style, FALSE}
339};
340#define FONT(font) (*fonts[font].styles)
341
342/************************************************************************/
347 void get_text_size(int *width, int *height,
348 enum client_font font, const char *text)
349{
350 PangoRectangle rect;
351
352 if (!layout) {
353 layout = pango_layout_new(gdk_pango_context_get_for_screen(gdk_screen_get_default()));
354 }
355
356 pango_layout_set_font_description(layout, FONT(font));
357 pango_layout_set_text(layout, text, -1);
358
359 pango_layout_get_pixel_extents(layout, NULL, &rect);
360 if (width) {
361 *width = rect.width;
362 }
363 if (height) {
364 *height = rect.height;
365 }
366}
367
368/************************************************************************/
374 void canvas_put_text(struct canvas *pcanvas, int canvas_x, int canvas_y,
375 enum client_font font, struct color *pcolor,
376 const char *text)
377{
378 cairo_t *cr;
379
380 if (!pcanvas->drawable) {
381 cr = cairo_create(pcanvas->surface);
382 } else {
383 cr = pcanvas->drawable;
384 }
385
386 if (pcanvas->drawable) {
387 cairo_save(cr);
388 }
389
390 surface_put_text(cr, canvas_x, canvas_y, pcanvas->zoom,
391 font, pcolor, text);
392
393 if (!pcanvas->drawable) {
394 cairo_destroy(cr);
395 } else {
396 cairo_restore(cr);
397 }
398}
399
400/************************************************************************/
405 void surface_put_text(cairo_t *cr, int x, int y, float zoom,
406 enum client_font font, struct color *pcolor,
407 const char *text)
408{
409 if (!layout) {
410 layout = pango_layout_new(gdk_pango_context_get_for_screen(gdk_screen_get_default()));
411 }
412
413 pango_layout_set_font_description(layout, FONT(font));
414 pango_layout_set_text(layout, text, -1);
415
416 if (fonts[font].shadowed) {
417 /* Suppress drop shadow for black text */
418 const GdkRGBA black = { 0.0, 0.0, 0.0, 1.0 };
419
420 if (!gdk_rgba_equal(&pcolor->color, &black)) {
421 gdk_cairo_set_source_rgba(cr, &black);
422 cairo_move_to(cr, x * zoom + 1,
423 y * zoom + 1);
424 pango_cairo_show_layout(cr, layout);
425 }
426 }
427
428 cairo_move_to(cr, x * zoom, y * zoom);
429 gdk_cairo_set_source_rgba(cr, &pcolor->color);
430 pango_cairo_show_layout(cr, layout);
431}
canvas_fill_sprite_area
struct canvas int int struct sprite bool int int fog_y canvas_fill_sprite_area
Definition canvas_g.h:55
height
struct canvas int int struct sprite int int int int height
Definition canvas_g.h:44
pcolor
struct canvas int int struct sprite bool int int fog_y struct canvas struct sprite struct color * pcolor
Definition canvas_g.h:57
fog_x
struct canvas int int struct sprite bool int fog_x
Definition canvas_g.h:51
canvas_y
struct canvas int int canvas_y
Definition canvas_g.h:43
canvas_put_sprite_fogged
canvas_put_sprite_fogged
Definition canvas_g.h:48
canvas_x
struct canvas int canvas_x
Definition canvas_g.h:43
canvas_put_curved_line
struct canvas int int struct sprite bool int int fog_y struct canvas struct sprite struct color int int canvas_y canvas_put_curved_line
Definition canvas_g.h:63
canvas_put_sprite
canvas_put_sprite
Definition canvas_g.h:42
client_font
struct canvas int int struct sprite bool int int fog_y struct canvas struct sprite struct color int int canvas_y struct canvas struct color enum line_type ltype int start_x int start_y int dx int dy enum client_font
Definition canvas_g.h:69
width
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
pcanvas
struct canvas * pcanvas
Definition canvas_g.h:42
psprite
struct canvas int int struct sprite * psprite
Definition canvas_g.h:50
canvas_put_text
canvas_put_text
Definition canvas_g.h:77
offset_y
struct canvas int int struct sprite int int offset_y
Definition canvas_g.h:44
offset_x
struct canvas int int struct sprite int offset_x
Definition canvas_g.h:44
line_type
line_type
Definition canvas_g.h:25
LINE_SELECT_RECT
@ LINE_SELECT_RECT
Definition canvas_g.h:26
LINE_GOTO
@ LINE_GOTO
Definition canvas_g.h:26
LINE_TILE_FRAME
@ LINE_TILE_FRAME
Definition canvas_g.h:26
LINE_BORDER
@ LINE_BORDER
Definition canvas_g.h:26
LINE_NORMAL
@ LINE_NORMAL
Definition canvas_g.h:26
fog
struct canvas int int struct sprite bool fog
Definition canvas_g.h:51
canvas_put_rectangle
void canvas_put_rectangle(struct canvas *pcanvas, struct color *pcolor, int canvas_x, int canvas_y, int width, int height)
Definition canvas.c:176
canvas_put_sprite_full
void canvas_put_sprite_full(struct canvas *pcanvas, int canvas_x, int canvas_y, struct sprite *sprite)
Definition canvas.c:148
canvas_set_zoom
void canvas_set_zoom(struct canvas *store, float zoom)
Definition canvas.c:53
canvas_mapview_init
void canvas_mapview_init(struct canvas *store)
Definition canvas.c:69
shadowed
bool shadowed
Definition canvas.c:334
get_text_size
void get_text_size(int *width, int *height, enum client_font font, const char *text)
Definition canvas.c:347
canvas_free
void canvas_free(struct canvas *store)
Definition canvas.c:44
FONT
#define FONT(font)
Definition canvas.c:340
has_zoom_support
bool has_zoom_support(void)
Definition canvas.c:61
canvas_put_line
void canvas_put_line(struct canvas *pcanvas, struct color *pcolor, enum line_type ltype, int start_x, int start_y, int dx, int dy)
Definition canvas.c:223
layout
static PangoLayout * layout
Definition canvas.c:331
surface_put_text
void surface_put_text(cairo_t *cr, int x, int y, float zoom, enum client_font font, struct color *pcolor, const char *text)
Definition canvas.c:405
canvas_copy
void canvas_copy(struct canvas *dest, struct canvas *src, int src_x, int src_y, int dest_x, int dest_y, int width, int height)
Definition canvas.c:76
canvas_create
struct canvas * canvas_create(int width, int height)
Definition canvas.c:28
city_productions_style
PangoFontDescription * city_productions_style
Definition gui_main.c:133
city_names_style
PangoFontDescription * city_names_style
Definition gui_main.c:132
reqtree_text_style
PangoFontDescription * reqtree_text_style
Definition gui_main.c:134
pixmap_put_overlay_tile_draw
void pixmap_put_overlay_tile_draw(struct canvas *pcanvas, int canvas_x, int canvas_y, struct sprite *ssprite, bool fog)
Definition mapview.c:545
get_sprite_dimensions
void get_sprite_dimensions(struct sprite *sprite, int *width, int *height)
Definition sprite.c:107
canvas.h
colors.h
gui_main.h
mapview.h
BORDER_WIDTH
#define BORDER_WIDTH
Definition mapview_common.h:71
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
fonts
Definition fonts.h:26
MIN
#define MIN(x, y)
Definition shared.h:55
MAX
#define MAX(x, y)
Definition shared.h:54
canvas
Definition canvas.h:21
canvas::zoom
float zoom
Definition canvas.h:24
canvas::surface
cairo_surface_t * surface
Definition canvas.h:22
canvas::drawable
cairo_t * drawable
Definition canvas.h:23
color
Definition colors.h:20
sprite
Definition sprite.h:22
sprite::surface
cairo_surface_t * surface
Definition sprite.h:23
styles
static struct nation_style * styles
Definition style.c:29
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47