1 /***********************************************************************
2 Freeciv - Copyright (C) 2005 The Freeciv 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 /* SDL2 */
19 #ifdef SDL2_PLAIN_INCLUDE
20 #include <SDL.h>
21 #include <SDL_ttf.h>
22 #else /* SDL2_PLAIN_INCLUDE */
23 #include <SDL2/SDL.h>
24 #include <SDL2/SDL_ttf.h>
25 #endif /* SDL2_PLAIN_INCLUDE */
26
27 /* utility */
28 #include "log.h"
29 #include "mem.h"
30
31 /* client/gui-sdl2 */
32 #include "colors.h"
33 #include "graphics.h"
34 #include "gui_main.h"
35 #include "gui_string.h"
36 #include "sprite.h"
37
38 #include "canvas.h"
39
40 static int *fonts[FONT_COUNT] = {
41 &city_names_font_size,
42 &city_productions_font_size,
43 &city_productions_font_size
44 };
45
46 /**************************************************************************
47 Create a canvas of the given size.
48 **************************************************************************/
canvas_create(int width,int height)49 struct canvas *canvas_create(int width, int height)
50 {
51 struct canvas *result = fc_malloc(sizeof(*result));
52
53 result->surf = create_surf(width, height, SDL_SWSURFACE);
54
55 return result;
56 }
57
58 /**************************************************************************
59 Free any resources associated with this canvas and the canvas struct
60 itself.
61 **************************************************************************/
canvas_free(struct canvas * store)62 void canvas_free(struct canvas *store)
63 {
64 FREESURFACE(store->surf);
65 free(store);
66 }
67
68 /****************************************************************************
69 Set canvas zoom for future drawing operations.
70 ****************************************************************************/
canvas_set_zoom(struct canvas * store,float zoom)71 void canvas_set_zoom(struct canvas *store, float zoom)
72 {
73 /* sdl2-client has no zoom support */
74 }
75
76 /****************************************************************************
77 This gui has zoom support.
78 ****************************************************************************/
has_zoom_support(void)79 bool has_zoom_support(void)
80 {
81 return FALSE;
82 }
83
84 /**************************************************************************
85 Initialize canvas as mapview.
86 **************************************************************************/
canvas_mapview_init(struct canvas * store)87 void canvas_mapview_init(struct canvas *store)
88 {
89 SDL_SetSurfaceBlendMode(store->surf, SDL_BLENDMODE_NONE);
90 }
91
92 /**************************************************************************
93 Copies an area from the source canvas to the destination canvas.
94 **************************************************************************/
canvas_copy(struct canvas * dest,struct canvas * src,int src_x,int src_y,int dest_x,int dest_y,int width,int height)95 void canvas_copy(struct canvas *dest, struct canvas *src,
96 int src_x, int src_y, int dest_x, int dest_y, int width,
97 int height)
98 {
99 SDL_Rect src_rect = {src_x, src_y, width, height};
100 SDL_Rect dest_rect = {dest_x, dest_y, width, height};
101
102 alphablit(src->surf, &src_rect, dest->surf, &dest_rect, 255);
103 }
104
105 /****************************************************************************
106 Draw some or all of a sprite onto the canvas.
107 ****************************************************************************/
canvas_put_sprite(struct canvas * pcanvas,int canvas_x,int canvas_y,struct sprite * sprite,int offset_x,int offset_y,int width,int height)108 void canvas_put_sprite(struct canvas *pcanvas,
109 int canvas_x, int canvas_y,
110 struct sprite *sprite,
111 int offset_x, int offset_y, int width, int height)
112 {
113 SDL_Rect src = {offset_x, offset_y, width, height};
114 SDL_Rect dst = {canvas_x + offset_x, canvas_y + offset_y, 0, 0};
115
116 alphablit(GET_SURF(sprite), &src, pcanvas->surf, &dst, 255);
117 }
118
119 /****************************************************************************
120 Draw a full sprite onto the canvas.
121 ****************************************************************************/
canvas_put_sprite_full(struct canvas * pcanvas,int canvas_x,int canvas_y,struct sprite * sprite)122 void canvas_put_sprite_full(struct canvas *pcanvas,
123 int canvas_x, int canvas_y,
124 struct sprite *sprite)
125 {
126 SDL_Rect dst = {canvas_x, canvas_y, 0, 0};
127
128 alphablit(GET_SURF(sprite), NULL, pcanvas->surf, &dst, 255);
129 }
130
131 /****************************************************************************
132 Draw a full sprite onto the canvas. If "fog" is specified draw it with
133 fog.
134 ****************************************************************************/
canvas_put_sprite_fogged(struct canvas * pcanvas,int canvas_x,int canvas_y,struct sprite * psprite,bool fog,int fog_x,int fog_y)135 void canvas_put_sprite_fogged(struct canvas *pcanvas,
136 int canvas_x, int canvas_y,
137 struct sprite *psprite,
138 bool fog, int fog_x, int fog_y)
139 {
140 SDL_Rect dst = {canvas_x, canvas_y, 0, 0};
141
142 if (fog) {
143 alphablit(GET_SURF(psprite), NULL, pcanvas->surf, &dst, 160);
144 } else {
145 canvas_put_sprite_full(pcanvas, canvas_x, canvas_y, psprite);
146 }
147 }
148
149 /****************************************************************************
150 Draw a filled-in colored rectangle onto canvas.
151 ****************************************************************************/
canvas_put_rectangle(struct canvas * pcanvas,struct color * pcolor,int canvas_x,int canvas_y,int width,int height)152 void canvas_put_rectangle(struct canvas *pcanvas, struct color *pcolor,
153 int canvas_x, int canvas_y, int width, int height)
154 {
155 SDL_Rect dst = {canvas_x, canvas_y, width, height};
156
157 SDL_FillRect(pcanvas->surf, &dst, SDL_MapRGBA(pcanvas->surf->format,
158 pcolor->color->r,
159 pcolor->color->g,
160 pcolor->color->b,
161 pcolor->color->a));
162 }
163
164 /****************************************************************************
165 Fill the area covered by the sprite with the given color.
166 ****************************************************************************/
canvas_fill_sprite_area(struct canvas * pcanvas,struct sprite * psprite,struct color * pcolor,int canvas_x,int canvas_y)167 void canvas_fill_sprite_area(struct canvas *pcanvas,
168 struct sprite *psprite, struct color *pcolor,
169 int canvas_x, int canvas_y)
170 {
171 SDL_Rect dst = {canvas_x, canvas_y,
172 GET_SURF(psprite)->w,
173 GET_SURF(psprite)->h};
174
175 SDL_FillRect(pcanvas->surf, &dst, SDL_MapRGBA(pcanvas->surf->format,
176 pcolor->color->r,
177 pcolor->color->g,
178 pcolor->color->b,
179 pcolor->color->a));
180 }
181
182 /****************************************************************************
183 Draw a 1-pixel-width colored line onto the canvas.
184 ****************************************************************************/
canvas_put_line(struct canvas * pcanvas,struct color * pcolor,enum line_type ltype,int start_x,int start_y,int dx,int dy)185 void canvas_put_line(struct canvas *pcanvas, struct color *pcolor,
186 enum line_type ltype, int start_x, int start_y,
187 int dx, int dy)
188 {
189 create_line(pcanvas->surf, start_x, start_y, start_x + dx, start_y + dy, pcolor->color);
190 }
191
192 /****************************************************************************
193 Draw a 1-pixel-width colored curved line onto the canvas.
194 ****************************************************************************/
canvas_put_curved_line(struct canvas * pcanvas,struct color * pcolor,enum line_type ltype,int start_x,int start_y,int dx,int dy)195 void canvas_put_curved_line(struct canvas *pcanvas, struct color *pcolor,
196 enum line_type ltype, int start_x, int start_y,
197 int dx, int dy)
198 {
199 /* FIXME: Implement curved line drawing. */
200 canvas_put_line(pcanvas, pcolor, ltype, start_x, start_y, dx, dy);
201 }
202
203 /****************************************************************************
204 Return the size of the given text in the given font. This size should
205 include the ascent and descent of the text. Either of width or height
206 may be NULL in which case those values simply shouldn't be filled out.
207 ****************************************************************************/
get_text_size(int * width,int * height,enum client_font font,const char * text)208 void get_text_size(int *width, int *height,
209 enum client_font font, const char *text)
210 {
211 utf8_str *ptext = create_utf8_str(NULL, 0, *fonts[font]);
212 SDL_Rect size;
213
214 fc_assert(width != NULL || height != NULL);
215
216 copy_chars_to_utf8_str(ptext, text);
217 utf8_str_size(ptext, &size);
218
219 if (width) {
220 *width = size.w;
221 }
222
223 if (height) {
224 *height = size.h;
225 }
226
227 FREEUTF8STR(ptext);
228 }
229
230 /****************************************************************************
231 Draw the text onto the canvas in the given color and font. The canvas
232 position does not account for the ascent of the text; this function must
233 take care of this manually. The text will not be NULL but may be empty.
234 ****************************************************************************/
canvas_put_text(struct canvas * pcanvas,int canvas_x,int canvas_y,enum client_font font,struct color * pcolor,const char * text)235 void canvas_put_text(struct canvas *pcanvas, int canvas_x, int canvas_y,
236 enum client_font font, struct color *pcolor,
237 const char *text)
238 {
239 SDL_Surface *ptmp;
240 utf8_str *ptext = create_utf8_str(NULL, 0, *fonts[font]);
241
242 copy_chars_to_utf8_str(ptext, text);
243
244 ptext->fgcol = *pcolor->color;
245 ptext->bgcol = (SDL_Color) {0, 0, 0, 0};
246
247 ptmp = create_text_surf_from_utf8(ptext);
248
249 blit_entire_src(ptmp, pcanvas->surf, canvas_x, canvas_y);
250
251 FREEUTF8STR(ptext);
252 FREESURFACE(ptmp);
253 }
254