- Timestamp:
- Jul 24, 2009, 8:48:35 AM (13 years ago)
- Location:
- libcaca/trunk/caca
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
libcaca/trunk/caca/caca_internals.h
r3471 r3568 24 24 #if !defined(_DOXYGEN_SKIP_ME) 25 25 # define EVENTBUF_LEN 10 26 # define MAX_DIRTY_COUNT 1 26 27 #endif 27 28 … … 61 62 /* Dirty rectangles */ 62 63 int ndirty; 63 int dirty_xmin, dirty_xmax, dirty_ymin, dirty_ymax; 64 struct 65 { 66 int xmin, xmax, ymin, ymax; 67 } 68 dirty[MAX_DIRTY_COUNT]; 64 69 65 70 /* Shortcut to the active frame information */ … … 217 222 }; 218 223 224 /* Dirty rectangle functions */ 225 extern void _caca_clip_dirty_rect_list(caca_canvas_t *); 226 219 227 /* Colour functions */ 220 228 extern uint32_t _caca_attr_to_rgb24fg(uint32_t); -
libcaca/trunk/caca/canvas.c
r3494 r3568 371 371 _caca_save_frame_info(cv); 372 372 373 /* Preload new width and height values into the canvas to optimise 374 * dirty rectangle handling */ 373 375 cv->width = width; 374 376 cv->height = height; 375 377 new_size = width * height; 378 379 /* If width or height is smaller (or both), we have the opportunity to 380 * reduce or even remove dirty rectangles */ 381 if(width < old_width || height < old_height) 382 _caca_clip_dirty_rect_list(cv); 376 383 377 384 /* Step 1: if new area is bigger, resize the memory area now. */ … … 471 478 } 472 479 473 /* XXX: technically we should not worry about the dirty rectangle in 474 * the bottom-right corner, because we only handle one dirty rectangle, 475 * but in case the API changes later, we make sure this is handled. */ 480 /* If both width and height are larger, there is a new dirty rectangle 481 * that needs to be created in the lower right corner. */ 476 482 if(width > old_width && height > old_height) 477 483 caca_add_dirty_rect(cv, old_width, old_height, -
libcaca/trunk/caca/dirty.c
r3494 r3568 15 15 /* 16 16 * This file contains the dirty rectangle handling functions. 17 * 18 * 19 * About dirty rectangles: 20 * 21 * * Dirty rectangles MUST NOT be larger than the canvas. If the user 22 * provides a large rectangle through caca_add_dirty_rect(), or if the 23 * canvas changes size to become smaller, all dirty rectangles MUST 24 * immediately be clipped to the canvas size. 17 25 */ 18 26 … … 78 86 } 79 87 80 /* Normalise dirty rectangle so that the values can be directly used. */ 81 if(cv->dirty_xmin < 0) 82 cv->dirty_xmin = 0; 83 84 if(cv->dirty_xmax > cv->width - 1) 85 cv->dirty_xmax = cv->width - 1; 86 87 if(cv->dirty_ymin < 0) 88 cv->dirty_ymin = 0; 89 90 if(cv->dirty_ymax > cv->height - 1) 91 cv->dirty_ymax = cv->height - 1; 92 93 *x = cv->dirty_xmin; 94 *y = cv->dirty_ymin; 95 *width = cv->dirty_xmax - cv->dirty_xmin + 1; 96 *height = cv->dirty_ymax - cv->dirty_ymin + 1; 88 *x = cv->dirty[r].xmin; 89 *y = cv->dirty[r].ymin; 90 *width = cv->dirty[r].xmax - cv->dirty[r].xmin + 1; 91 *height = cv->dirty[r].ymax - cv->dirty[r].ymin + 1; 92 93 debug("dirty #%i: %ix%i at (%i,%i)\n", r, *width, *height, *x, *y); 97 94 98 95 return 0; … … 119 116 * \return 0 in case of success, -1 if an error occurred. 120 117 */ 121 int caca_add_dirty_rect(caca_canvas_t *cv, int x, int y, 122 int width, int height) 123 { 124 /* Ignore empty and out-of-bounds rectangles */ 125 if(width <= 0 || height <= 0 || x + width <= 0 || x >= cv->width 126 || y + height <= 0 || y >= cv->height) 118 int caca_add_dirty_rect(caca_canvas_t *cv, int x, int y, int width, int height) 119 { 120 debug("new dirty: %ix%i at (%i,%i)\n", width, height, x, y); 121 122 /* Clip arguments to canvas */ 123 if(x < 0) { width += x; x = 0; } 124 125 if(x + width > cv->width) 126 width = cv->width - x; 127 128 if(y < 0) { height += y; y = 0; } 129 130 if(y + height > cv->height) 131 height = cv->height - y; 132 133 /* Ignore empty and out-of-canvas rectangles */ 134 if(width <= 0 || height <= 0) 127 135 { 128 136 seterrno(EINVAL); … … 130 138 } 131 139 132 if(cv->ndirty == 0) 133 { 134 cv->ndirty = 1; 135 cv->dirty_xmin = x; 136 cv->dirty_xmax = x + width - 1; 137 cv->dirty_ymin = y; 138 cv->dirty_ymax = y + height - 1; 140 /* Add dirty rectangle to list. Current strategy: if there is room 141 * for rectangles, just append it to the list. Otherwise, merge the 142 * new rectangle with the first in the list. */ 143 if(cv->ndirty < MAX_DIRTY_COUNT) 144 { 145 cv->dirty[cv->ndirty].xmin = x; 146 cv->dirty[cv->ndirty].xmax = x + width - 1; 147 cv->dirty[cv->ndirty].ymin = y; 148 cv->dirty[cv->ndirty].ymax = y + height - 1; 149 cv->ndirty++; 139 150 } 140 151 else 141 152 { 142 if(x < cv->dirty _xmin)143 cv->dirty _xmin = x;144 if(x + width - 1 > cv->dirty _xmax)145 cv->dirty _xmax = x + width - 1;146 if(y < cv->dirty _ymin)147 cv->dirty _ymin = y;148 if(y + height - 1 > cv->dirty _ymax)149 cv->dirty _ymax = y + height - 1;153 if(x < cv->dirty[0].xmin) 154 cv->dirty[0].xmin = x; 155 if(x + width - 1 > cv->dirty[0].xmax) 156 cv->dirty[0].xmax = x + width - 1; 157 if(y < cv->dirty[0].ymin) 158 cv->dirty[0].ymin = y; 159 if(y + height - 1 > cv->dirty[0].ymax) 160 cv->dirty[0].ymax = y + height - 1; 150 161 } 151 162 … … 174 185 int width, int height) 175 186 { 176 /* Ignore empty and out-of-bounds rectangles */ 177 if(width <= 0 || height <= 0 || x + width <= 0 || x >= cv->width 178 || y + height <= 0 || y >= cv->height) 187 /* Clip arguments to canvas size */ 188 if(x < 0) { width += x; x = 0; } 189 190 if(x + width > cv->width) 191 width = cv->width - x; 192 193 if(y < 0) { height += y; y = 0; } 194 195 if(y + height > cv->height) 196 height = cv->height - y; 197 198 /* Ignore empty and out-of-canvas rectangles */ 199 if(width <= 0 || height <= 0) 179 200 { 180 201 seterrno(EINVAL); … … 205 226 } 206 227 228 /* 229 * XXX: the following functions are local. 230 */ 231 232 /* Clip all dirty rectangles in case they're larger than the canvas */ 233 void _caca_clip_dirty_rect_list(caca_canvas_t *cv) 234 { 235 int i; 236 237 for(i = 0; i < cv->ndirty; i++) 238 { 239 if(cv->dirty[i].xmin < 0) 240 cv->dirty[i].xmin = 0; 241 242 if(cv->dirty[i].ymin < 0) 243 cv->dirty[i].ymin = 0; 244 245 if(cv->dirty[i].xmax >= cv->width) 246 cv->dirty[i].xmax = cv->width - 1; 247 248 if(cv->dirty[i].ymax >= cv->height) 249 cv->dirty[i].ymax = cv->height - 1; 250 } 251 } 252
Note: See TracChangeset
for help on using the changeset viewer.