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