00001
00039 #include <stdint.h>
00040 #include <stdbool.h>
00041 #include <stddef.h>
00042 #include <assert.h>
00043 #include <gfx/gfx.h>
00044
00045 void gfx_generic_draw_horizontal_line(gfx_coord_t x, gfx_coord_t y,
00046 gfx_coord_t length, gfx_color_t color)
00047 {
00048 gfx_draw_filled_rect(x, y, length, 1, color);
00049 }
00050
00051 void gfx_generic_draw_vertical_line(gfx_coord_t x, gfx_coord_t y,
00052 gfx_coord_t length, gfx_color_t color)
00053 {
00054 gfx_draw_filled_rect(x, y, 1, length, color);
00055 }
00056
00057 void gfx_generic_draw_line(gfx_coord_t x1, gfx_coord_t y1,
00058 gfx_coord_t x2, gfx_coord_t y2, gfx_color_t color)
00059 {
00060 gfx_coord_t x;
00061 gfx_coord_t y;
00062 int16_t xinc;
00063 int16_t yinc;
00064 int16_t dx;
00065 int16_t dy;
00066
00067
00068
00069
00070 xinc = 1;
00071 dx = x2 - x1;
00072 if (dx < 0) {
00073 xinc = -1;
00074 dx = -dx;
00075 }
00076 yinc = 1;
00077 dy = y2 - y1;
00078 if (dy < 0) {
00079 yinc = -1;
00080 dy = -dy;
00081 }
00082
00083
00084 x = x1;
00085 y = y1;
00086 gfx_set_bottom_right_limit(gfx_width - 1, gfx_height - 1);
00087
00088
00089
00090
00091
00092 if (dx > dy) {
00093 gfx_coord_t i;
00094 int16_t e = dx >> 1;
00095
00096
00097 for (i = 0; i <= dx; ++i) {
00098 gfx_draw_line_pixel(x, y, color);
00099
00100
00101 e -= dy;
00102 if (e < 0) {
00103 e += dx;
00104 y += yinc;
00105 }
00106
00107 x += xinc;
00108 }
00109 } else {
00110 gfx_coord_t i;
00111 int16_t e = dy >> 1;
00112
00113
00114 for (i = 0; i <= dy; ++i) {
00115 gfx_draw_line_pixel(x,y,color);
00116
00117
00118 e -= dx;
00119 if (e < 0){
00120 e += dy;
00121 x += xinc;
00122 }
00123
00124 y += yinc;
00125 }
00126 }
00127 }
00128
00129
00130
00131 void gfx_generic_draw_rect(gfx_coord_t x, gfx_coord_t y,
00132 gfx_coord_t width, gfx_coord_t height,
00133 gfx_color_t color)
00134 {
00135 gfx_draw_horizontal_line(x, y, width, color);
00136 gfx_draw_horizontal_line(x, y + height - 1, width, color);
00137 gfx_draw_vertical_line(x, y, height, color);
00138 gfx_draw_vertical_line(x + width - 1, y, height, color);
00139 }
00140
00141
00142 void gfx_generic_draw_filled_rect(gfx_coord_t x, gfx_coord_t y,
00143 gfx_coord_t width, gfx_coord_t height,
00144 gfx_color_t color)
00145 {
00146 gfx_coord_t x2;
00147 gfx_coord_t y2;
00148
00149 if ((width == 0) || (height == 0))
00150 return;
00151
00152
00153 if (width < 0) {
00154 width = -width;
00155 x -= width - 1;
00156 }
00157
00158 if (height < 0) {
00159 height = -height;
00160 y -= height - 1;
00161 }
00162
00163 #ifdef CONFIG_GFX_USE_CLIPPING
00164
00165 if ((x > gfx_max_x) || (y > gfx_max_y)
00166 || ((x + width) <= gfx_min_x)
00167 || ((y + height) <= gfx_min_y))
00168 return;
00169
00170
00171 if (x < gfx_min_x) {
00172 width -= gfx_min_x - x;
00173 x = gfx_min_x;
00174 }
00175
00176
00177 if (y < gfx_min_y) {
00178 height -= gfx_min_y - y;
00179 y = gfx_min_y;
00180 }
00181 #endif
00182
00183
00184 x2 = x + width - 1;
00185 y2 = y + height - 1;
00186
00187 #ifdef CONFIG_GFX_USE_CLIPPING
00188
00189 if (x2 > gfx_max_x) {
00190 x2 = gfx_max_x;
00191 width = x2 - x + 1;
00192 }
00193
00194
00195 if (y2 > gfx_max_y) {
00196 y2 = gfx_max_y;
00197 height = y2 - y + 1;
00198 }
00199 #endif
00200
00201
00202 gfx_set_limits(x, y, x2, y2);
00203 gfx_duplicate_pixel(color, (uint32_t)width * height);
00204 }
00205
00206 void gfx_generic_draw_circle(gfx_coord_t x, gfx_coord_t y,
00207 gfx_coord_t radius, gfx_color_t color, uint8_t octant_mask)
00208 {
00209 gfx_coord_t offset_x;
00210 gfx_coord_t offset_y;
00211 int16_t error;
00212
00213
00214 if (radius == 0) {
00215 gfx_draw_pixel(x, y, color);
00216 return;
00217 }
00218
00219
00220 offset_x = 0;
00221 offset_y = radius;
00222 error = 3 - 2 * radius;
00223
00224
00225 while (offset_x <= offset_y) {
00226
00227 if (octant_mask & GFX_OCTANT0)
00228 gfx_draw_pixel(x + offset_y, y - offset_x, color);
00229 if (octant_mask & GFX_OCTANT1)
00230 gfx_draw_pixel(x + offset_x, y - offset_y, color);
00231 if (octant_mask & GFX_OCTANT2)
00232 gfx_draw_pixel(x - offset_x, y - offset_y, color);
00233 if (octant_mask & GFX_OCTANT3)
00234 gfx_draw_pixel(x - offset_y, y - offset_x, color);
00235 if (octant_mask & GFX_OCTANT4)
00236 gfx_draw_pixel(x - offset_y, y + offset_x, color);
00237 if (octant_mask & GFX_OCTANT5)
00238 gfx_draw_pixel(x - offset_x, y + offset_y, color);
00239 if (octant_mask & GFX_OCTANT6)
00240 gfx_draw_pixel(x + offset_x, y + offset_y, color);
00241 if (octant_mask & GFX_OCTANT7)
00242 gfx_draw_pixel(x + offset_y, y + offset_x, color);
00243
00244
00245 if (error < 0) {
00246 error += ((offset_x << 2) + 6);
00247 } else {
00248 error += (((offset_x - offset_y) << 2) + 10);
00249 --offset_y;
00250 }
00251
00252
00253 ++offset_x;
00254 }
00255 }
00256
00257
00258 void gfx_generic_draw_filled_circle(gfx_coord_t x, gfx_coord_t y,
00259 gfx_coord_t radius, gfx_color_t color, uint8_t quadrant_mask)
00260 {
00261 gfx_coord_t offset_x;
00262 gfx_coord_t offset_y;
00263 int16_t error;
00264
00265
00266 if (radius == 0) {
00267 gfx_draw_pixel(x, y, color);
00268 return;
00269 }
00270
00271
00272 offset_x = 0;
00273 offset_y = radius;
00274 error = 3 - 2 * radius;
00275
00276
00277 while (offset_x <= offset_y) {
00278
00279 if (quadrant_mask & GFX_QUADRANT0) {
00280 gfx_draw_vertical_line(x + offset_y,
00281 y - offset_x, offset_x + 1, color);
00282 gfx_draw_vertical_line(x + offset_x,
00283 y - offset_y, offset_y + 1, color);
00284 }
00285 if (quadrant_mask & GFX_QUADRANT1) {
00286 gfx_draw_vertical_line(x - offset_y,
00287 y - offset_x, offset_x + 1, color);
00288 gfx_draw_vertical_line(x - offset_x,
00289 y - offset_y, offset_y + 1, color);
00290 }
00291 if (quadrant_mask & GFX_QUADRANT2) {
00292 gfx_draw_vertical_line(x - offset_y,
00293 y, offset_x + 1, color);
00294 gfx_draw_vertical_line(x - offset_x,
00295 y, offset_y + 1, color);
00296 }
00297 if (quadrant_mask & GFX_QUADRANT3) {
00298 gfx_draw_vertical_line(x + offset_y,
00299 y, offset_x + 1, color);
00300 gfx_draw_vertical_line(x + offset_x,
00301 y, offset_y + 1, color);
00302 }
00303
00304
00305 if (error < 0) {
00306 error += ((offset_x << 2) + 6);
00307 } else {
00308 error += (((offset_x - offset_y) << 2) + 10);
00309 --offset_y;
00310 }
00311
00312
00313 ++offset_x;
00314 }
00315 }
00316
00317
00318 void gfx_generic_get_pixmap(gfx_color_t *pixmap, gfx_coord_t map_width,
00319 gfx_coord_t map_x, gfx_coord_t map_y,
00320 gfx_coord_t x, gfx_coord_t y,
00321 gfx_coord_t width, gfx_coord_t height)
00322 {
00323 gfx_coord_t x2;
00324 gfx_coord_t y2;
00325
00326
00327 if ((width == 0) || (height == 0))
00328 return;
00329
00330
00331 assert(pixmap != NULL);
00332 assert((map_x + width) <= map_width);
00333 assert(map_x >= 0);
00334 assert(map_y >= 0);
00335 assert(width > 0);
00336 assert(height > 0);
00337
00338 #ifdef CONFIG_GFX_USE_CLIPPING
00339
00340 if ((x > gfx_max_x) || (y > gfx_max_y)
00341 || ((x + width) <= gfx_min_x)
00342 || ((y + height) <= gfx_min_y))
00343 return;
00344
00345
00346 if (x < gfx_min_x) {
00347 width -= gfx_min_x - x;
00348 map_x += gfx_min_x - x;
00349 x = gfx_min_x;
00350 }
00351
00352
00353 if (y < gfx_min_y) {
00354 height -= gfx_min_y - y;
00355 map_y += gfx_min_y - y;
00356 y = gfx_min_y;
00357 }
00358 #endif
00359
00360
00361 x2 = x + width - 1;
00362 y2 = y + height - 1;
00363
00364 #ifdef CONFIG_GFX_USE_CLIPPING
00365
00366 if (x2 > gfx_max_x) {
00367 x2 = gfx_max_x;
00368 width = x2 - x + 1;
00369 }
00370
00371
00372 if (y2 > gfx_max_y) {
00373 y2 = gfx_max_y;
00374 height = y2 - y + 1;
00375 }
00376 #endif
00377
00378
00379 pixmap += map_x;
00380 if (map_y > 0)
00381 pixmap += (uint32_t)map_y * map_width;
00382
00383
00384 gfx_set_bottom_right_limit(x2, y2);
00385
00386
00387
00388 if ((map_width == width) && (map_x == 0)) {
00389 gfx_set_top_left_limit(x, y);
00390 gfx_copy_pixels_from_screen(pixmap, (uint32_t)width * height);
00391 } else {
00392
00393 gfx_coord_t lines_left = height;
00394
00395 while (lines_left > 0) {
00396
00397 gfx_set_top_left_limit(x, y);
00398 ++y;
00399
00400
00401 gfx_copy_pixels_from_screen(pixmap, width);
00402 pixmap += map_width;
00403 --lines_left;
00404 }
00405 }
00406 }
00407
00408
00409 void gfx_generic_put_pixmap(const gfx_color_t *pixmap, gfx_coord_t map_width,
00410 gfx_coord_t map_x, gfx_coord_t map_y,
00411 gfx_coord_t x, gfx_coord_t y,
00412 gfx_coord_t width, gfx_coord_t height)
00413 {
00414 gfx_coord_t x2;
00415 gfx_coord_t y2;
00416
00417
00418 if ((width == 0) || (height == 0))
00419 return;
00420
00421
00422 assert(pixmap != NULL);
00423 assert((map_x + width) <= map_width);
00424 assert(map_x >= 0);
00425 assert(map_y >= 0);
00426 assert(width > 0);
00427 assert(height > 0);
00428
00429 #ifdef CONFIG_GFX_USE_CLIPPING
00430
00431 if ((x > gfx_max_x) || (y > gfx_max_y)
00432 || ((x + width) <= gfx_min_x)
00433 || ((y + height) <= gfx_min_y))
00434 return;
00435
00436
00437 if (x < gfx_min_x) {
00438 width -= gfx_min_x - x;
00439 map_x += gfx_min_x - x;
00440 x = gfx_min_x;
00441 }
00442
00443
00444 if (y < gfx_min_y) {
00445 height -= gfx_min_y - y;
00446 map_y += gfx_min_y - y;
00447 y = gfx_min_y;
00448 }
00449 #endif
00450
00451
00452 x2 = x + width - 1;
00453 y2 = y + height - 1;
00454
00455 #ifdef CONFIG_GFX_USE_CLIPPING
00456
00457 if (x2 > gfx_max_x) {
00458 x2 = gfx_max_x;
00459 width = x2 - x + 1;
00460 }
00461
00462
00463 if (y2 > gfx_max_y) {
00464 y2 = gfx_max_y;
00465 height = y2 - y + 1;
00466 }
00467 #endif
00468
00469
00470 pixmap += map_x;
00471 if (map_y > 0)
00472 pixmap += (uint32_t)map_y * map_width;
00473
00474
00475 gfx_set_bottom_right_limit(x2, y2);
00476
00477
00478
00479 if ((map_width == width) && (map_x == 0)) {
00480 gfx_set_top_left_limit(x, y);
00481 gfx_copy_pixels_to_screen(pixmap, (uint32_t)width * height);
00482 } else {
00483 gfx_coord_t lines_left = height;
00484
00485
00486 while (lines_left > 0) {
00487
00488 gfx_set_top_left_limit(x, y);
00489 ++y;
00490
00491
00492 gfx_copy_pixels_to_screen(pixmap, width);
00493 pixmap += map_width;
00494 --lines_left;
00495 }
00496 }
00497 }