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