00001
00039 #include <stdint.h>
00040 #include <stdbool.h>
00041 #include <stddef.h>
00042 #include <assert.h>
00043 #include <gfx/gfx.h>
00044
00045
00055 void gfx_draw_bitmap(const struct gfx_bitmap *bmp, gfx_coord_t x, gfx_coord_t y)
00056 {
00057 assert(bmp);
00058
00059 gfx_put_bitmap(bmp, 0, 0, x, y, bmp->width, bmp->height);
00060 }
00061
00104 void gfx_draw_bitmap_tiled(const struct gfx_bitmap *bmp, gfx_coord_t x1,
00105 gfx_coord_t y1, gfx_coord_t x2, gfx_coord_t y2,
00106 gfx_coord_t tile_origin_x, gfx_coord_t tile_origin_y)
00107 {
00108 gfx_coord_t map_width;
00109 gfx_coord_t map_height;
00110 gfx_coord_t start_x;
00111 gfx_coord_t start_y;
00112 gfx_coord_t index_x;
00113 gfx_coord_t index_y;
00114
00115
00116 assert(bmp);
00117 assert(x1 >= 0);
00118 assert(y1 >= 0);
00119 assert(x2 > x1);
00120 assert(y2 > y1);
00121 assert(tile_origin_x <= x1);
00122 assert(tile_origin_y <= y1);
00123
00124
00125 if (bmp->type == BITMAP_SOLID) {
00126 gfx_draw_filled_rect(x1, y1, x2 - x1 + 1, y2 - y1 + 1,
00127 bmp->data.color);
00128 return;
00129 }
00130
00131
00132 map_width = bmp->width;
00133 map_height = bmp->height;
00134 start_x = tile_origin_x;
00135 start_y = tile_origin_y;
00136
00137 while (start_x <= (x1 - map_width)) {
00138 start_x += map_width;
00139 }
00140 while (start_y <= (y1 - map_height)) {
00141 start_y += map_height;
00142 }
00143
00144
00145 for (index_y = start_y; index_y <= y2; index_y += map_height) {
00146 for (index_x = start_x; index_x <= x2; index_x += map_width) {
00147 gfx_put_bitmap(bmp, 0, 0, index_x, index_y, map_width, map_height);
00148 }
00149 }
00150 }
00151
00178 void gfx_put_bitmap(const struct gfx_bitmap *bmp,
00179 gfx_coord_t map_x, gfx_coord_t map_y,
00180 gfx_coord_t x, gfx_coord_t y,
00181 gfx_coord_t width, gfx_coord_t height)
00182 {
00183
00184 gfx_coord_t x2;
00185 gfx_coord_t y2;
00186 gfx_coord_t map_width = bmp->width;
00187 gfx_color_t *pixmap;
00188 const gfx_color_t __progmem_arg *progmem_pixmap;
00189 #ifdef CONFIG_HUGEMEM
00190 hugemem_ptr_t hugemem_pixmap;
00191 #endif
00192
00193
00194 if ((width == 0) || (height == 0))
00195 return;
00196
00197
00198 assert(bmp);
00199 assert((map_x + width) <= map_width);
00200 assert(map_x >= 0);
00201 assert(map_y >= 0);
00202 assert(width > 0);
00203 assert(height > 0);
00204
00205 #ifdef CONFIG_GFX_USE_CLIPPING
00206
00207 if ((x > gfx_max_x) || (y > gfx_max_y)
00208 || ((x + width) <= gfx_min_x)
00209 || ((y + height) <= gfx_min_y))
00210 return;
00211
00212
00213 if (x < gfx_min_x) {
00214 width -= gfx_min_x - x;
00215 map_x += gfx_min_x - x;
00216 x = gfx_min_x;
00217 }
00218
00219
00220 if (y < gfx_min_y) {
00221 height -= gfx_min_y - y;
00222 map_y += gfx_min_y - y;
00223 y = gfx_min_y;
00224 }
00225 #endif
00226
00227
00228 x2 = x + width - 1;
00229 y2 = y + height - 1;
00230
00231 #ifdef CONFIG_GFX_USE_CLIPPING
00232
00233 if (x2 > gfx_max_x) {
00234 x2 = gfx_max_x;
00235 width = x2 - x + 1;
00236 }
00237
00238
00239 if (y2 > gfx_max_y) {
00240 y2 = gfx_max_y;
00241 height = y2 - y + 1;
00242 }
00243 #endif
00244
00245 switch (bmp->type) {
00246 case BITMAP_SOLID:
00247 gfx_draw_filled_rect(x, y, x2 - x, y2 - y, bmp->data.color);
00248 break;
00249
00250 case BITMAP_RAM:
00251 pixmap = bmp->data.pixmap;
00252
00253 pixmap += map_x;
00254
00255 if (map_y > 0)
00256 pixmap += (uint32_t)map_y * map_width;
00257
00258
00259 gfx_set_bottom_right_limit(x2, y2);
00260
00261
00262
00263 if ((map_width == width) && (map_x == 0)) {
00264 gfx_set_top_left_limit(x, y);
00265 gfx_copy_pixels_to_screen(pixmap, (uint32_t)width * height);
00266 } else {
00267 gfx_coord_t lines_left = height;
00268
00269
00270 while (lines_left > 0) {
00271
00272 gfx_set_top_left_limit(x, y);
00273 ++y;
00274
00275
00276 gfx_copy_pixels_to_screen(pixmap, width);
00277 pixmap += map_width;
00278 --lines_left;
00279 }
00280 }
00281 break;
00282
00283 case BITMAP_PROGMEM:
00284 progmem_pixmap = bmp->data.progmem;
00285
00286 progmem_pixmap += map_x;
00287
00288 if (map_y > 0) {
00289 progmem_pixmap += (uint32_t) map_y * map_width;
00290 }
00291
00292
00293 gfx_set_bottom_right_limit(x2, y2);
00294
00295
00296
00297
00298 if ((map_width == width) && (map_x == 0)) {
00299 gfx_set_top_left_limit(x, y);
00300 gfx_copy_progmem_pixels_to_screen(progmem_pixmap,
00301 (uint32_t)width * height);
00302 } else {
00303 gfx_coord_t lines_left = height;
00304
00305
00306 while (lines_left > 0) {
00307
00308 gfx_set_top_left_limit(x, y);
00309 ++y;
00310
00311
00312 gfx_copy_progmem_pixels_to_screen(progmem_pixmap, width);
00313 progmem_pixmap += map_width;
00314 --lines_left;
00315 }
00316 }
00317 break;
00318
00319 #ifdef CONFIG_HUGEMEM
00320 case BITMAP_HUGEMEM:
00321 hugemem_pixmap = bmp->data.hugemem;
00322
00323 hugemem_pixmap = (hugemem_ptr_t)((uint32_t)hugemem_pixmap +
00324 map_x);
00325
00326 if (map_y > 0) {
00327 hugemem_pixmap = (hugemem_ptr_t)
00328 ((uint32_t)hugemem_pixmap +
00329 ((uint32_t)map_y *
00330 (uint32_t)map_width));
00331 }
00332
00333
00334 gfx_set_bottom_right_limit(x2, y2);
00335
00336
00337
00338
00339 if ((map_width == width) && (map_x == 0)) {
00340 gfx_set_top_left_limit(x, y);
00341 gfx_copy_hugemem_pixels_to_screen(hugemem_pixmap,
00342 (uint32_t)width * height);
00343 } else {
00344 gfx_coord_t lines_left = height;
00345
00346
00347 while (lines_left > 0) {
00348
00349 gfx_set_top_left_limit(x, y);
00350 ++y;
00351
00352
00353 gfx_copy_hugemem_pixels_to_screen(
00354 hugemem_pixmap, width);
00355 hugemem_pixmap =
00356 (hugemem_ptr_t)((uint32_t)hugemem_pixmap
00357 + map_width);
00358 --lines_left;
00359 }
00360 }
00361 break;
00362 #endif
00363 }
00364 }