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