Small bugfixes.
[xuni.git] / src / widget / image.c
blobf89aff626fdb7d01a5732de7e4c4daf2b0e093c3
1 /*! \file image.c
3 */
5 #include <stdlib.h>
7 #include "SDL_rotozoom.h"
8 /*#include "sge_rotation.h"*/
10 #include "../graphics.h"
11 #include "../memory.h"
12 #include "../error.h"
13 #include "../utility.h"
14 #include "widgets.h"
15 #include "image.h"
17 static void free_image(struct xuni_t *xuni, struct widget_t *widget);
18 static void reposition_image(struct xuni_t *xuni, struct widget_t *widget);
19 static void rescale_image(struct xuni_t *xuni, struct widget_t *widget);
20 static void paint_image(struct xuni_t *xuni, struct widget_t *widget);
21 static void generate_image(struct xuni_t *xuni, struct widget_t *widget);
23 void image_widget_event(struct xuni_t *xuni, struct widget_t *widget,
24 enum widget_event_t event) {
26 static void (*function[])(struct xuni_t *xuni, struct widget_t *widget)
27 = {
29 free_image,
31 paint_image,
32 reposition_image,
33 rescale_image
36 call_widget_event_func(xuni, widget, event, function,
37 sizeof(function) / sizeof(*function));
40 void init_image(struct widget_t *widget, const char *filename, double angle,
41 enum image_load_t load, enum image_rescale_t rescale) {
43 widget->type = WIDGET_IMAGE;
44 widget->p.image = xuni_memory_allocate(sizeof(*widget->p.image));
46 xuni_memory_increment((void *)filename);
47 widget->p.image->filename = filename;
49 widget->p.image->original = 0;
50 widget->p.image->image = 0;
51 widget->p.image->angle = angle;
52 widget->p.image->keep.load = load;
53 widget->p.image->keep.rescale = rescale;
56 static void free_image(struct xuni_t *xuni, struct widget_t *widget) {
57 xuni_memory_free((void *)widget->p.image->filename);
59 if(xuni_memory_decrement(widget->p.image)) {
60 free_surface(widget->p.image->original);
62 free_surface(xuni_memory_decrement(widget->p.image->image));
64 free(widget->p.image);
68 static void paint_image(struct xuni_t *xuni, struct widget_t *widget) {
69 int x, y;
71 prepare_paint_image(xuni, widget);
73 x = widget->pos->real.x;
74 y = widget->pos->real.y;
76 if(widget->pos->clip) {
77 /*printf("%i %i\n", widget->pos->clip->xoff,
78 widget->pos->clip->yoff);*/
79 x += widget->pos->clip->xoff;
80 y += widget->pos->clip->yoff;
83 blit_surface(xuni->smode->screen, widget->p.image->image, x, y);
86 static void reposition_image(struct xuni_t *xuni, struct widget_t *widget) {
90 static void rescale_image(struct xuni_t *xuni, struct widget_t *widget) {
91 if(widget->p.image->keep.rescale == IMAGE_RESCALE_ALWAYS) {
92 generate_image(xuni, widget);
94 else {
95 free_surface(xuni_memory_decrement(widget->p.image->image));
96 widget->p.image->image = 0;
100 void prepare_paint_image(struct xuni_t *xuni, struct widget_t *widget) {
101 if(!widget->p.image->image) generate_image(xuni, widget);
104 #if 1
105 static void generate_image(struct xuni_t *xuni, struct widget_t *widget) {
106 SDL_Surface *use;
108 if(!widget->p.image->original) {
109 if(!widget->p.image->filename) {
110 log_message(ERROR_TYPE_WARNING, 0, __FILE__, __LINE__,
111 "NULL image of name \"%s\"", widget->name);
112 return;
115 widget->p.image->original = load_image(widget->p.image->filename);
116 if(!widget->p.image->original) return;
119 free_surface(xuni_memory_decrement(widget->p.image->image));
121 /*widget->p.image->image = zoomSurface(widget->p.image->original,
122 widget->pos->scale.w / 100.0
123 * widget->p.image->screen->w / widget->p.image->original->w,
124 widget->pos->scale.h / 100.0
125 * widget->p.image->screen->h / widget->p.image->original->h,
126 SMOOTHING_ON);*/
128 use = widget->p.image->original;
130 if(widget->p.image->angle) {
131 use = rotozoomSurface(widget->p.image->original,
132 radians_to_degrees(widget->p.image->angle), 1.0, SMOOTHING_ON);
135 widget->p.image->image = zoomSurface(use,
136 widget->pos->scale.w / 100.0
137 / ((double)xuni->smode->screen->w / widget->base->pos->real.w)
138 * xuni->smode->screen->w / widget->p.image->original->w,
139 widget->pos->scale.h / 100.0
140 / ((double)xuni->smode->screen->h / widget->base->pos->real.h)
141 * xuni->smode->screen->h / widget->p.image->original->h,
142 SMOOTHING_ON);
144 if(widget->p.image->angle) {
145 SDL_FreeSurface(use);
148 /*if(widget->p.image->image && widget->p.image->angle) {
149 SDL_Surface *temp = rotozoomSurface(widget->p.image->image,
150 radians_to_degrees(widget->p.image->angle), 1.0, SMOOTHING_ON);
151 SDL_FreeSurface(widget->p.image->image);
152 widget->p.image->image = temp;
155 xuni_memory_add_block(widget->p.image->image,
156 MEMORY_BLOCK_TYPE_SDL_SURFACE);
158 /*printf("%i -> %i:\n",
159 (int)allocated_sdl_surface(widget->p.image->original),
160 (int)allocated_sdl_surface(widget->p.image->image));
161 print_widget_backtrace(widget);*/
163 /* Discard the original, unresized image if the filename of the image is
164 known (i.e., the original image can be loaded again if required), and
165 if that is how this image should behave.
167 if(widget->p.image->keep.load == IMAGE_LOAD_FREE
168 && widget->p.image->filename) {
170 SDL_FreeSurface(widget->p.image->original); /* will never be NULL */
171 widget->p.image->original = 0;
174 #elif 1
175 static void rescale_image(struct xuni_t *xuni, struct widget_t *widget) {
176 if(!widget->p.image->original) {
177 if(!widget->p.image->filename) {
178 log_message(ERROR_TYPE_WARNING, 0, __FILE__, __LINE__,
179 "NULL image of name \"%s\"", widget->name);
180 return;
183 widget->p.image->original = load_image(widget->p.image->filename);
184 if(!widget->p.image->original) return;
187 free_surface(xuni_memory_decrement(widget->p.image->image));
189 widget->p.image->image = sge_transform_surface(widget->p.image->original,
190 SDL_MapRGB(xuni->smode->screen->format, 0, 0, 0),
191 radians_to_degrees(widget->p.image->angle),
192 widget->pos->scale.w / 100.0
193 / ((double)xuni->smode->screen->w / widget->base->pos->real.w)
194 * xuni->smode->screen->w / widget->p.image->original->w,
195 widget->pos->scale.h / 100.0
196 / ((double)xuni->smode->screen->h / widget->base->pos->real.h)
197 * xuni->smode->screen->h / widget->p.image->original->h,
200 xuni_memory_add_block(widget->p.image->image,
201 MEMORY_BLOCK_TYPE_SDL_SURFACE);
203 /*printf("%i -> %i:\n",
204 (int)allocated_sdl_surface(widget->p.image->original),
205 (int)allocated_sdl_surface(widget->p.image->image));
206 print_widget_backtrace(widget);*/
208 /* Discard the original, unresized image if the filename of the image is
209 known (i.e., the original image can be loaded again if required). */
210 if(widget->p.image->filename) {
211 SDL_FreeSurface(widget->p.image->original); /* will never be NULL */
212 widget->p.image->original = 0;
215 #elif 0
216 static void rescale_image(struct widget_t *widget) {
217 free_surface(widget->p.image->image);
219 widget->p.image->image
220 = SDL_ResizeXY(load_image(widget->p.image->filename), 1, 1, 7);
222 /*if(widget->p.image->angle) {
223 SDL_Surface *temp = rotozoomSurface(widget->p.image->image,
224 angle_to_degrees(widget->p.image->angle), 1.0, SMOOTHING_ON);
225 SDL_FreeSurface(widget->p.image->image);
226 widget->p.image->image = temp;
229 SDL_SaveBMP(widget->p.image->image, "bmp.bmp");
231 widget->p.image->original = 0;
233 #else
234 static void rescale_image(struct widget_t *widget) {
235 free_surface(widget->p.image->image);
237 if(!widget->p.image->original) {
238 widget->p.image->original = load_image(widget->p.image->filename);
241 printf("Attempting to resize \"%s\" from %ix%i to %fx%f\n",
242 widget->p.image->filename,
243 widget->p.image->original->w,
244 widget->p.image->original->h,
245 widget->pos->scale.w / 100.0 * widget->p.image->screen->w,
246 widget->pos->scale.h / 100.0 * widget->p.image->screen->h);
248 widget->p.image->image = SDL_ResizeXY(widget->p.image->original,
249 widget->pos->scale.w / 100.0 * widget->p.image->screen->w,
250 widget->pos->scale.h / 100.0 * widget->p.image->screen->h, 5);
252 widget->p.image->original = 0;
254 #endif