Freeciv-3.3: /fast/freeciv/nightly/main/client/gui-gtk-4.0/canvas.c Source File

Freeciv-3.3

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-4.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, int canvas_x, int canvas_y,
110 struct sprite *sprite,
111 int offset_x, int offset_y, int width, int height)
112{
113 int sswidth, ssheight;
114 cairo_t *cr;
115
116 get_sprite_dimensions(sprite, &sswidth, &ssheight);
117
118 if (!pcanvas->drawable) {
119 cr = cairo_create(pcanvas->surface);
120 } else {
121 cr = pcanvas->drawable;
122 cairo_save(cr);
123 }
124
125 cairo_scale(cr, pcanvas->zoom, pcanvas->zoom);
126 cairo_set_source_surface(cr, sprite->surface, canvas_x - offset_x, canvas_y - offset_y);
127 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
128 cairo_rectangle(cr, canvas_x - offset_x, canvas_y - offset_y,
129 MIN(width, MAX(0, sswidth - offset_x)),
130 MIN(height, MAX(0, ssheight - offset_y)));
131 cairo_fill(cr);
132
133 if (!pcanvas->drawable) {
134 cairo_destroy(cr);
135 } else {
136 cairo_restore(cr);
137 }
138}
139
140/************************************************************************/
144 void canvas_put_sprite_full(struct canvas *pcanvas, int canvas_x, int canvas_y,
145 struct sprite *sprite)
146{
147 int width, height;
148
149 get_sprite_dimensions(sprite, &width, &height);
150 canvas_put_sprite(pcanvas, canvas_x, canvas_y, sprite,
151 0, 0, width, height);
152}
153
154/************************************************************************/
157 void canvas_put_sprite_full_scaled(struct canvas *pcanvas,
158 int canvas_x, int canvas_y,
159 int canvas_w, int canvas_h,
160 struct sprite *sprite)
161{
162 /* This should never be called as we have not enabled support
163 * in this client yet. */
164 fc_assert(FALSE);
165}
166
167/************************************************************************/
170 void canvas_put_sprite_fogged(struct canvas *pcanvas,
171 int canvas_x, int canvas_y,
172 struct sprite *psprite,
173 bool fog, int fog_x, int fog_y)
174{
175 pixmap_put_overlay_tile_draw(pcanvas, canvas_x, canvas_y,
176 psprite, fog);
177}
178
179/************************************************************************/
183 void canvas_put_rectangle(struct canvas *pcanvas, struct color *pcolor,
184 int canvas_x, int canvas_y, int width, int height)
185{
186 cairo_t *cr;
187
188 if (!pcanvas->drawable) {
189 cr = cairo_create(pcanvas->surface);
190 } else {
191 cr = pcanvas->drawable;
192 cairo_save(cr);
193 }
194
195 cairo_scale(cr, pcanvas->zoom, pcanvas->zoom);
196 gdk_cairo_set_source_rgba(cr, &pcolor->color);
197 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
198 cairo_rectangle(cr, canvas_x, canvas_y, width, height);
199 cairo_fill(cr);
200
201 if (!pcanvas->drawable) {
202 cairo_destroy(cr);
203 } else {
204 cairo_restore(cr);
205 }
206}
207
208/************************************************************************/
211 void canvas_fill_sprite_area(struct canvas *pcanvas, struct sprite *psprite,
212 struct color *pcolor, int canvas_x, int canvas_y)
213{
214 int width, height;
215
216 get_sprite_dimensions(psprite, &width, &height);
217 canvas_put_rectangle(pcanvas, pcolor, canvas_x, canvas_y, width, height);
218}
219
220/************************************************************************/
225 void canvas_put_line(struct canvas *pcanvas, struct color *pcolor,
226 enum line_type ltype, int start_x, int start_y,
227 int dx, int dy)
228{
229 cairo_t *cr;
230 double dashes[2] = {4.0, 4.0};
231
232 if (!pcanvas->drawable) {
233 cr = cairo_create(pcanvas->surface);
234 } else {
235 cr = pcanvas->drawable;
236 cairo_save(cr);
237 }
238
239 switch (ltype) {
240 case LINE_NORMAL:
241 cairo_set_line_width(cr, 1.);
242 break;
243 case LINE_BORDER:
244 cairo_set_line_width(cr, (double)BORDER_WIDTH);
245 cairo_set_dash(cr, dashes, 2, 0);
246 break;
247 case LINE_TILE_FRAME:
248 cairo_set_line_width(cr, 2.);
249 break;
250 case LINE_GOTO:
251 cairo_set_line_width(cr, 2.);
252 break;
253 case LINE_SELECT_RECT:
254 cairo_set_line_width(cr, 2.);
255 cairo_set_dash(cr, dashes, 2, 0);
256 cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE);
257 break;
258 }
259
260 gdk_cairo_set_source_rgba(cr, &pcolor->color);
261 cairo_move_to(cr, start_x, start_y);
262 cairo_line_to(cr, start_x + dx, start_y + dy);
263 cairo_stroke(cr);
264
265 if (!pcanvas->drawable) {
266 cairo_destroy(cr);
267 } else {
268 cairo_restore(cr);
269 }
270}
271
272/************************************************************************/
276 void canvas_put_curved_line(struct canvas *pcanvas,
277 struct color *pcolor,
278 enum line_type ltype, int start_x, int start_y,
279 int dx, int dy)
280{
281 int end_x = start_x + dx;
282 int end_y = start_y + dy;
283 cairo_t *cr;
284 double dashes[2] = {4.0, 4.0};
285
286 if (!pcanvas->drawable) {
287 cr = cairo_create(pcanvas->surface);
288 } else {
289 cr = pcanvas->drawable;
290 }
291
292 if (pcanvas->drawable) {
293 cairo_save(cr);
294 }
295
296 switch (ltype) {
297 case LINE_NORMAL:
298 cairo_set_line_width(cr, 1.);
299 break;
300 case LINE_BORDER:
301 cairo_set_dash(cr, dashes, 2, 0);
302 cairo_set_line_width(cr, (double)BORDER_WIDTH);
303 break;
304 case LINE_TILE_FRAME:
305 cairo_set_line_width(cr, 2.);
306 break;
307 case LINE_GOTO:
308 cairo_set_line_width(cr, 2.);
309 break;
310 case LINE_SELECT_RECT:
311 cairo_set_line_width(cr, 2.);
312 cairo_set_dash(cr, dashes, 2, 0);
313 cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE);
314 break;
315 }
316
317 gdk_cairo_set_source_rgba(cr, &pcolor->color);
318 cairo_move_to(cr, start_x, start_y);
319 cairo_curve_to(cr, end_x, start_y, start_x, end_y, end_x, end_y);
320 cairo_stroke(cr);
321
322 if (!pcanvas->drawable) {
323 cairo_destroy(cr);
324 } else {
325 cairo_restore(cr);
326 }
327}
328
329 static PangoLayout *layout;
330static struct {
331 PangoFontDescription **styles;
332 bool shadowed;
333} fonts[FONT_COUNT] = {
334 {&city_names_style, TRUE},
335 {&city_productions_style, TRUE},
336 {&reqtree_text_style, FALSE}
337};
338#define FONT(font) (*fonts[font].styles)
339
340/************************************************************************/
345 void get_text_size(int *width, int *height,
346 enum client_font font, const char *text)
347{
348 PangoRectangle rect;
349
350 if (!layout) {
351 layout = pango_layout_new(gtk_widget_get_pango_context(toplevel));
352 }
353
354 pango_layout_set_font_description(layout, FONT(font));
355 pango_layout_set_text(layout, text, -1);
356
357 pango_layout_get_pixel_extents(layout, NULL, &rect);
358 if (width) {
359 *width = rect.width;
360 }
361 if (height) {
362 *height = rect.height;
363 }
364}
365
366/************************************************************************/
372 void canvas_put_text(struct canvas *pcanvas, int canvas_x, int canvas_y,
373 enum client_font font, struct color *pcolor,
374 const char *text)
375{
376 cairo_t *cr;
377
378 if (!pcanvas->drawable) {
379 cr = cairo_create(pcanvas->surface);
380 } else {
381 cr = pcanvas->drawable;
382 cairo_save(cr);
383 }
384
385 surface_put_text(cr, canvas_x, canvas_y, pcanvas->zoom,
386 font, pcolor, text);
387
388 if (!pcanvas->drawable) {
389 cairo_destroy(cr);
390 } else {
391 cairo_restore(cr);
392 }
393}
394
395/************************************************************************/
400 void surface_put_text(cairo_t *cr, int x, int y, float zoom,
401 enum client_font font, struct color *pcolor,
402 const char *text)
403{
404 if (!layout) {
405 layout = pango_layout_new(gtk_widget_get_pango_context(toplevel));
406 }
407
408 pango_layout_set_font_description(layout, FONT(font));
409 pango_layout_set_text(layout, text, -1);
410
411 if (fonts[font].shadowed) {
412 /* Suppress drop shadow for black text */
413 const GdkRGBA black = { 0.0, 0.0, 0.0, 1.0 };
414
415 if (!gdk_rgba_equal(&pcolor->color, &black)) {
416 gdk_cairo_set_source_rgba(cr, &black);
417 cairo_move_to(cr, x * zoom + 1,
418 y * zoom + 1);
419 pango_cairo_show_layout(cr, layout);
420 }
421 }
422
423 cairo_move_to(cr, x * zoom, y * zoom);
424 gdk_cairo_set_source_rgba(cr, &pcolor->color);
425 pango_cairo_show_layout(cr, layout);
426}
height
struct canvas int int struct sprite int int int int height
Definition canvas_g.h:44
pcolor
struct canvas int int int int struct sprite *sprite struct canvas struct color * pcolor
Definition canvas_g.h:56
canvas_put_rectangle
struct canvas int int int int struct sprite *sprite canvas_put_rectangle
Definition canvas_g.h:55
canvas_y
struct canvas int int canvas_y
Definition canvas_g.h:43
canvas_x
struct canvas int canvas_x
Definition canvas_g.h:43
canvas_put_line
struct canvas int int int int struct sprite *sprite struct canvas struct color int int int int height canvas_put_line
Definition canvas_g.h:62
canvas_put_sprite
canvas_put_sprite
Definition canvas_g.h:42
canvas_w
struct canvas int int int canvas_w
Definition canvas_g.h:49
canvas_h
struct canvas int int int int canvas_h
Definition canvas_g.h:49
pcanvas
struct canvas * pcanvas
Definition canvas_g.h:42
canvas_put_sprite_full_scaled
canvas_put_sprite_full_scaled
Definition canvas_g.h:48
canvas_put_text
canvas_put_text
Definition canvas_g.h:80
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
width
struct canvas int int struct sprite int int int width
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
incite_cost
char * incite_cost
Definition comments.c:74
canvas_put_sprite_full
void canvas_put_sprite_full(struct canvas *pcanvas, int canvas_x, int canvas_y, struct sprite *sprite)
Definition canvas.c:144
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:328
canvas_fill_sprite_area
void canvas_fill_sprite_area(struct canvas *pcanvas, struct sprite *psprite, struct color *pcolor, int canvas_x, int canvas_y)
Definition canvas.c:211
get_text_size
void get_text_size(int *width, int *height, enum client_font font, const char *text)
Definition canvas.c:341
canvas_free
void canvas_free(struct canvas *store)
Definition canvas.c:44
FONT
#define FONT(font)
Definition canvas.c:334
canvas_put_curved_line
void canvas_put_curved_line(struct canvas *pcanvas, struct color *pcolor, enum line_type ltype, int start_x, int start_y, int dx, int dy)
Definition canvas.c:276
has_zoom_support
bool has_zoom_support(void)
Definition canvas.c:61
layout
static PangoLayout * layout
Definition canvas.c:325
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:396
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
canvas_put_sprite_fogged
void canvas_put_sprite_fogged(struct canvas *pcanvas, int canvas_x, int canvas_y, struct sprite *psprite, bool fog, int fog_x, int fog_y)
Definition canvas.c:170
city_productions_style
PangoFontDescription * city_productions_style
Definition gui_main.c:134
city_names_style
PangoFontDescription * city_names_style
Definition gui_main.c:133
reqtree_text_style
PangoFontDescription * reqtree_text_style
Definition gui_main.c:135
toplevel
GtkWidget * toplevel
Definition gui_main.c:125
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:566
canvas.h
colors.h
gui_main.h
mapview.h
fc_assert
#define fc_assert(condition)
Definition log.h:176
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
y
struct sprite int int y
Definition sprite_g.h:31
x
struct sprite int x
Definition sprite_g.h:31
get_sprite_dimensions
struct sprite int int int int struct sprite int int float bool smooth get_sprite_dimensions
Definition sprite_g.h:36
canvas
Definition canvas.h:22
canvas::zoom
float zoom
Definition canvas.h:25
canvas::surface
cairo_surface_t * surface
Definition canvas.h:23
canvas::drawable
cairo_t * drawable
Definition canvas.h:24
color
Definition colors.h:21
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