1 /* ______ ___ ___
2 * /\ _ \ /\_ \ /\_ \
3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 * /\____/
9 * \_/__/
10 *
11 * Bitmap drawing routines.
12 *
13 * See LICENSE.txt for copyright information.
14 */
15
16
17 #include "allegro5/allegro.h"
18 #include "allegro5/internal/aintern_bitmap.h"
19 #include "allegro5/internal/aintern_display.h"
20 #include "allegro5/internal/aintern_memblit.h"
21 #include "allegro5/internal/aintern_pixels.h"
22
23
24 static ALLEGRO_COLOR solid_white = {1, 1, 1, 1};
25
26
_bitmap_drawer(ALLEGRO_BITMAP * bitmap,ALLEGRO_COLOR tint,float sx,float sy,float sw,float sh,int flags)27 static void _bitmap_drawer(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint,
28 float sx, float sy, float sw, float sh, int flags)
29 {
30 ALLEGRO_BITMAP *dest = al_get_target_bitmap();
31 ALLEGRO_DISPLAY *display = _al_get_bitmap_display(dest);
32 ASSERT(bitmap->parent == NULL);
33 ASSERT(!(flags & (ALLEGRO_FLIP_HORIZONTAL | ALLEGRO_FLIP_VERTICAL)));
34 ASSERT(bitmap != dest && bitmap != dest->parent);
35
36 /* If destination is memory, do a memory blit */
37 if (al_get_bitmap_flags(dest) & ALLEGRO_MEMORY_BITMAP ||
38 _al_pixel_format_is_compressed(al_get_bitmap_format(dest))) {
39 _al_draw_bitmap_region_memory(bitmap, tint, sx, sy, sw, sh, 0, 0, flags);
40 }
41 else {
42 /* if source is memory or incompatible */
43 if ((al_get_bitmap_flags(bitmap) & ALLEGRO_MEMORY_BITMAP) ||
44 (!al_is_compatible_bitmap(bitmap)))
45 {
46 if (display && display->vt->draw_memory_bitmap_region) {
47 display->vt->draw_memory_bitmap_region(display, bitmap,
48 sx, sy, sw, sh, flags);
49 }
50 else {
51 _al_draw_bitmap_region_memory(bitmap, tint, sx, sy, sw, sh, 0, 0, flags);
52 }
53 }
54 else {
55 /* Compatible display bitmap, use full acceleration */
56 bitmap->vt->draw_bitmap_region(bitmap, tint, sx, sy, sw, sh, flags);
57 }
58 }
59 }
60
61
_draw_tinted_rotated_scaled_bitmap_region(ALLEGRO_BITMAP * bitmap,ALLEGRO_COLOR tint,float cx,float cy,float angle,float xscale,float yscale,float sx,float sy,float sw,float sh,float dx,float dy,int flags)62 static void _draw_tinted_rotated_scaled_bitmap_region(ALLEGRO_BITMAP *bitmap,
63 ALLEGRO_COLOR tint, float cx, float cy, float angle,
64 float xscale, float yscale,
65 float sx, float sy, float sw, float sh, float dx, float dy,
66 int flags)
67 {
68 ALLEGRO_TRANSFORM backup;
69 ALLEGRO_TRANSFORM t;
70 ALLEGRO_BITMAP *parent = bitmap;
71 float const orig_sw = sw;
72 float const orig_sh = sh;
73 ASSERT(bitmap);
74
75 al_copy_transform(&backup, al_get_current_transform());
76 al_identity_transform(&t);
77
78 if (bitmap->parent) {
79 parent = bitmap->parent;
80 sx += bitmap->xofs;
81 sy += bitmap->yofs;
82 }
83
84 if (sx < 0) {
85 sw += sx;
86 al_translate_transform(&t, -sx, 0);
87 sx = 0;
88 }
89 if (sy < 0) {
90 sh += sy;
91 al_translate_transform(&t, 0, -sy);
92 sy = 0;
93 }
94 if (sx + sw > parent->w)
95 sw = parent->w - sx;
96 if (sy + sh > parent->h)
97 sh = parent->h - sy;
98
99 if (flags & ALLEGRO_FLIP_HORIZONTAL) {
100 al_scale_transform(&t, -1, 1);
101 al_translate_transform(&t, orig_sw, 0);
102 flags &= ~ALLEGRO_FLIP_HORIZONTAL;
103 }
104
105 if (flags & ALLEGRO_FLIP_VERTICAL) {
106 al_scale_transform(&t, 1, -1);
107 al_translate_transform(&t, 0, orig_sh);
108 flags &= ~ALLEGRO_FLIP_VERTICAL;
109 }
110
111 al_translate_transform(&t, -cx, -cy);
112 al_scale_transform(&t, xscale, yscale);
113 al_rotate_transform(&t, angle);
114 al_translate_transform(&t, dx, dy);
115 al_compose_transform(&t, &backup);
116
117 al_use_transform(&t);
118 _bitmap_drawer(parent, tint, sx, sy, sw, sh, flags);
119 al_use_transform(&backup);
120 }
121
122
123 /* Function: al_draw_tinted_bitmap_region
124 */
al_draw_tinted_bitmap_region(ALLEGRO_BITMAP * bitmap,ALLEGRO_COLOR tint,float sx,float sy,float sw,float sh,float dx,float dy,int flags)125 void al_draw_tinted_bitmap_region(ALLEGRO_BITMAP *bitmap,
126 ALLEGRO_COLOR tint,
127 float sx, float sy, float sw, float sh, float dx, float dy,
128 int flags)
129 {
130 _draw_tinted_rotated_scaled_bitmap_region(bitmap, tint,
131 0, 0, 0, 1, 1, sx, sy, sw, sh, dx, dy, flags);
132 }
133
134
135 /* Function: al_draw_tinted_bitmap
136 */
al_draw_tinted_bitmap(ALLEGRO_BITMAP * bitmap,ALLEGRO_COLOR tint,float dx,float dy,int flags)137 void al_draw_tinted_bitmap(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint,
138 float dx, float dy, int flags)
139 {
140 ASSERT(bitmap);
141 al_draw_tinted_bitmap_region(bitmap, tint, 0, 0,
142 bitmap->w, bitmap->h, dx, dy, flags);
143 }
144
145
146 /* Function: al_draw_bitmap
147 */
al_draw_bitmap(ALLEGRO_BITMAP * bitmap,float dx,float dy,int flags)148 void al_draw_bitmap(ALLEGRO_BITMAP *bitmap, float dx, float dy, int flags)
149 {
150 al_draw_tinted_bitmap(bitmap, solid_white, dx, dy, flags);
151 }
152
153
154 /* Function: al_draw_bitmap_region
155 */
al_draw_bitmap_region(ALLEGRO_BITMAP * bitmap,float sx,float sy,float sw,float sh,float dx,float dy,int flags)156 void al_draw_bitmap_region(ALLEGRO_BITMAP *bitmap,
157 float sx, float sy, float sw, float sh, float dx, float dy, int flags)
158 {
159 al_draw_tinted_bitmap_region(bitmap, solid_white, sx, sy, sw, sh,
160 dx, dy, flags);
161 }
162
163
164 /* Function: al_draw_tinted_scaled_bitmap
165 */
al_draw_tinted_scaled_bitmap(ALLEGRO_BITMAP * bitmap,ALLEGRO_COLOR tint,float sx,float sy,float sw,float sh,float dx,float dy,float dw,float dh,int flags)166 void al_draw_tinted_scaled_bitmap(ALLEGRO_BITMAP *bitmap,
167 ALLEGRO_COLOR tint,
168 float sx, float sy, float sw, float sh,
169 float dx, float dy, float dw, float dh, int flags)
170 {
171 _draw_tinted_rotated_scaled_bitmap_region(bitmap, tint,
172 0, 0, 0,
173 dw / sw, dh / sh,
174 sx, sy, sw, sh, dx, dy, flags);
175 }
176
177
178 /* Function: al_draw_scaled_bitmap
179 */
al_draw_scaled_bitmap(ALLEGRO_BITMAP * bitmap,float sx,float sy,float sw,float sh,float dx,float dy,float dw,float dh,int flags)180 void al_draw_scaled_bitmap(ALLEGRO_BITMAP *bitmap,
181 float sx, float sy, float sw, float sh,
182 float dx, float dy, float dw, float dh, int flags)
183 {
184 al_draw_tinted_scaled_bitmap(bitmap, solid_white, sx, sy, sw, sh,
185 dx, dy, dw, dh, flags);
186 }
187
188
189 /* Function: al_draw_tinted_rotated_bitmap
190 *
191 * angle is specified in radians and moves clockwise
192 * on the screen.
193 */
al_draw_tinted_rotated_bitmap(ALLEGRO_BITMAP * bitmap,ALLEGRO_COLOR tint,float cx,float cy,float dx,float dy,float angle,int flags)194 void al_draw_tinted_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
195 ALLEGRO_COLOR tint,
196 float cx, float cy, float dx, float dy, float angle, int flags)
197 {
198 al_draw_tinted_scaled_rotated_bitmap(bitmap, tint, cx, cy, dx, dy,
199 1, 1, angle, flags);
200 }
201
202
203 /* Function: al_draw_rotated_bitmap
204 */
al_draw_rotated_bitmap(ALLEGRO_BITMAP * bitmap,float cx,float cy,float dx,float dy,float angle,int flags)205 void al_draw_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
206 float cx, float cy, float dx, float dy, float angle, int flags)
207 {
208 al_draw_tinted_rotated_bitmap(bitmap, solid_white, cx, cy, dx, dy,
209 angle, flags);
210 }
211
212
213 /* Function: al_draw_tinted_scaled_rotated_bitmap
214 */
al_draw_tinted_scaled_rotated_bitmap(ALLEGRO_BITMAP * bitmap,ALLEGRO_COLOR tint,float cx,float cy,float dx,float dy,float xscale,float yscale,float angle,int flags)215 void al_draw_tinted_scaled_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
216 ALLEGRO_COLOR tint,
217 float cx, float cy, float dx, float dy, float xscale, float yscale,
218 float angle, int flags)
219 {
220 _draw_tinted_rotated_scaled_bitmap_region(bitmap, tint,
221 cx, cy, angle,
222 xscale, yscale,
223 0, 0, bitmap->w, bitmap->h, dx, dy, flags);
224 }
225
226
227 /* Function: al_draw_tinted_scaled_rotated_bitmap_region
228 */
al_draw_tinted_scaled_rotated_bitmap_region(ALLEGRO_BITMAP * bitmap,float sx,float sy,float sw,float sh,ALLEGRO_COLOR tint,float cx,float cy,float dx,float dy,float xscale,float yscale,float angle,int flags)229 void al_draw_tinted_scaled_rotated_bitmap_region(ALLEGRO_BITMAP *bitmap,
230 float sx, float sy, float sw, float sh,
231 ALLEGRO_COLOR tint,
232 float cx, float cy, float dx, float dy, float xscale, float yscale,
233 float angle, int flags)
234 {
235 _draw_tinted_rotated_scaled_bitmap_region(bitmap, tint,
236 cx, cy, angle,
237 xscale, yscale,
238 sx, sy, sw, sh, dx, dy, flags);
239 }
240
241
242 /* Function: al_draw_scaled_rotated_bitmap
243 */
al_draw_scaled_rotated_bitmap(ALLEGRO_BITMAP * bitmap,float cx,float cy,float dx,float dy,float xscale,float yscale,float angle,int flags)244 void al_draw_scaled_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
245 float cx, float cy, float dx, float dy, float xscale, float yscale,
246 float angle, int flags)
247 {
248 al_draw_tinted_scaled_rotated_bitmap(bitmap, solid_white,
249 cx, cy, dx, dy, xscale, yscale, angle, flags);
250 }
251
252
253 /* vim: set ts=8 sts=3 sw=3 et: */
254