Mercurial > MadButterfly
comparison src/redraw_man.c @ 14:d34232f15863
-
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Thu, 31 Jul 2008 17:43:20 +0800 |
parents | ed55009d96d3 |
children | c2ce186a5c37 |
comparison
equal
deleted
inserted
replaced
13:ed55009d96d3 | 14:d34232f15863 |
---|---|
39 void redraw_man_destroy(redraw_man_t *rdman) { | 39 void redraw_man_destroy(redraw_man_t *rdman) { |
40 elmpool_free(rdman->coord_pool); | 40 elmpool_free(rdman->coord_pool); |
41 elmpool_free(rdman->geo_pool); | 41 elmpool_free(rdman->geo_pool); |
42 if(rdman->dirty_coords) | 42 if(rdman->dirty_coords) |
43 free(rdman->dirty_coords); | 43 free(rdman->dirty_coords); |
44 if(rdman->redrawing_geos) | 44 if(rdman->dirty_geos) |
45 free(rdman->redrawing_geos); | 45 free(rdman->dirty_geos); |
46 } | 46 } |
47 | 47 |
48 | 48 |
49 #define ASSERT(x) | 49 #define ASSERT(x) |
50 /* | 50 /* |
213 | 213 |
214 return OK; | 214 return OK; |
215 } | 215 } |
216 | 216 |
217 static int add_dirty_geo(redraw_man_t *rdman, geo_t *geo) { | 217 static int add_dirty_geo(redraw_man_t *rdman, geo_t *geo) { |
218 int max_redrawing_geos; | 218 int max_dirty_geos; |
219 int r; | 219 int r; |
220 | 220 |
221 if(rdman->n_redrawing_geos >= rdman->max_redrawing_geos) { | 221 if(rdman->n_dirty_geos >= rdman->max_dirty_geos) { |
222 max_redrawing_geos = rdman->n_geos + rdman->n_coords; | 222 max_dirty_geos = rdman->n_geos; |
223 r = extend_memblk((void **)&rdman->redrawing_geos, | 223 r = extend_memblk((void **)&rdman->dirty_geos, |
224 sizeof(geo_t *) * rdman->n_redrawing_geos, | 224 sizeof(geo_t *) * rdman->n_dirty_geos, |
225 sizeof(geo_t *) * max_redrawing_geos); | 225 sizeof(geo_t *) * max_dirty_geos); |
226 if(r != OK) | 226 if(r != OK) |
227 return ERR; | 227 return ERR; |
228 rdman->max_redrawing_geos = max_redrawing_geos; | 228 rdman->max_dirty_geos = max_dirty_geos; |
229 } | 229 } |
230 | 230 |
231 rdman->redrawing_geos[rdman->n_redrawing_geos++] = geo; | 231 rdman->dirty_geos[rdman->n_dirty_geos++] = geo; |
232 return OK; | 232 return OK; |
233 } | 233 } |
234 | 234 |
235 static int add_dirty_area(redraw_man_t *rdman, area_t *area) { | 235 static int add_dirty_area(redraw_man_t *rdman, area_t *area) { |
236 int max_dirty_areas; | 236 int max_dirty_areas; |
279 } | 279 } |
280 | 280 |
281 /*! \brief Mark a shape is changed. | 281 /*! \brief Mark a shape is changed. |
282 * | 282 * |
283 * The geo_t object of a changed shape is mark as dirty and | 283 * The geo_t object of a changed shape is mark as dirty and |
284 * put into redrawing_geos list. | 284 * put into dirty_geos list. |
285 */ | 285 */ |
286 int rdman_shape_changed(redraw_man_t *rdman, shape_t *shape) { | 286 int rdman_shape_changed(redraw_man_t *rdman, shape_t *shape) { |
287 geo_t *geo; | 287 geo_t *geo; |
288 int r; | 288 int r; |
289 | 289 |
329 shape->geo->flags &= ~GEF_DIRTY; | 329 shape->geo->flags &= ~GEF_DIRTY; |
330 add_dirty_geo(rdman, shape->geo); | 330 add_dirty_geo(rdman, shape->geo); |
331 } | 331 } |
332 } | 332 } |
333 | 333 |
334 static void compute_coord_geo(coord_t *coord) { | 334 static void compute_coord_area(coord_t *coord) { |
335 } | 335 } |
336 | 336 |
337 static void transform_shape(shape_t *shape) { | 337 static void update_shape_geo(shape_t *shape) { |
338 } | 338 } |
339 | 339 |
340 static void draw_shape(shape_t *shape) { | 340 static void draw_shape(redraw_man_t *rdman, shape_t *shape) { |
341 } | |
342 | |
343 static void clip_and_show(redraw_man_t *rdman, int n_dirty_areas, | |
344 area_t **dirty_areas) { | |
341 } | 345 } |
342 | 346 |
343 /*! \brief Re-draw all changed shapes or shapes affected by changed coords. | 347 /*! \brief Re-draw all changed shapes or shapes affected by changed coords. |
344 * | 348 * |
345 * A coord object has a geo to keep track the range that it's members will | 349 * A coord object has a geo to keep track the range that it's members will |
354 * overlay shape objects, too. If a shape's coord is changed, shape's | 358 * overlay shape objects, too. If a shape's coord is changed, shape's |
355 * geo object is not used to find overlay shape objects any more. | 359 * geo object is not used to find overlay shape objects any more. |
356 * | 360 * |
357 * steps: | 361 * steps: |
358 * - update chagned coord objects | 362 * - update chagned coord objects |
359 * - recompute geo for changed coord objects | 363 * - recompute area for changed coord objects |
360 * - recompute geo for members shape objects | 364 * - recompute geo for members shape objects |
365 * - clear dirty of geo for members to prevent from | |
366 * recomputing for change of shape objects. | |
367 * - add old and new area value to list of dirty areas. | |
361 * - recompute geo for changed shape objects | 368 * - recompute geo for changed shape objects |
362 * - finding overlaid shape objects for recomputed geo objects. | 369 * - only if a shape object is dirty. |
363 * - overlaid shape objects is invoked by traveling tree of coord. | 370 * - put new and old value of area of geo to list of dirty areas. |
364 * - members of changed coord object are marked computed and dirty. | 371 * - Scan all shapes and redraw shapes overlaid with dirty areas. |
365 * | 372 * |
366 * assert(n_redrawing_geos <= (num_of(shape) + num_of(coord))) | 373 * dirty flag of coord objects is cleared after update. |
374 * | |
375 * assert(n_dirty_geos <= (num_of(shape) + num_of(coord))) | |
367 * Because | 376 * Because |
368 * - num_of(geo from coord) < num_of(coord) | 377 * - num_of(geo from coord) < num_of(coord) |
369 * - num_of(geo from shape) < num_of(shape) | 378 * - num_of(geo from shape) < num_of(shape) |
370 */ | 379 */ |
371 int rdman_redraw_changed(redraw_man_t *rdman) { | 380 int rdman_redraw_changed(redraw_man_t *rdman) { |
372 int i, j; | 381 int i; |
373 int n_dirty_coords; | 382 int n_dirty_coords; |
374 coord_t **dirty_coords; | 383 coord_t **dirty_coords; |
375 coord_t *visit_coord; | 384 coord_t *visit_coord; |
376 geo_t *visit_geo, **redrawing_geos; | 385 geo_t *visit_geo, **dirty_geos; |
377 int n_redrawing_geos; | 386 int n_dirty_geos; |
378 int n_dirty_areas; | 387 int n_dirty_areas; |
388 area_t **dirty_areas; | |
379 | 389 |
380 if(rdman->n_dirty_coords > 0) { | 390 if(rdman->n_dirty_coords > 0) { |
381 _insert_sort((void **)rdman->dirty_coords, | 391 _insert_sort((void **)rdman->dirty_coords, |
382 rdman->n_dirty_coords, | 392 rdman->n_dirty_coords, |
383 OFFSET(coord_t, order)); | 393 OFFSET(coord_t, order)); |
393 visit_coord = preorder_coord_subtree(dirty_coords[i], | 403 visit_coord = preorder_coord_subtree(dirty_coords[i], |
394 visit_coord)) { | 404 visit_coord)) { |
395 /* Dirty member, here, and members of this coord | 405 /* Dirty member, here, and members of this coord |
396 * will not be visited anymore. */ | 406 * will not be visited anymore. */ |
397 visit_coord->flags &= ~COF_DIRTY; | 407 visit_coord->flags &= ~COF_DIRTY; |
398 visit_coord->flags |= COF_RECOMP; | |
399 | 408 |
400 SWAP(visit_coord->cur_area, visit_coord->last_area, area_t *); | 409 SWAP(visit_coord->cur_area, visit_coord->last_area, area_t *); |
401 compute_coord_geo(visit_coord); | 410 compute_coord_area(visit_coord); |
402 add_dirty_area(rdman, visit_coord->cur_area); | 411 add_dirty_area(rdman, visit_coord->cur_area); |
403 add_dirty_area(rdman, visit_coord->last_area); | 412 add_dirty_area(rdman, visit_coord->last_area); |
404 make_redrawing_members(rdman, visit_coord); | 413 make_redrawing_members(rdman, visit_coord); |
405 } | 414 } |
406 } | 415 } |
407 rdman->n_dirty_coords = 0; | 416 rdman->n_dirty_coords = 0; |
408 } | 417 } |
409 | 418 |
410 n_redrawing_geos = rdman->n_redrawing_geos; | 419 n_dirty_geos = rdman->n_dirty_geos; |
411 if(n_redrawing_geos > 0) { | 420 if(n_dirty_geos > 0) { |
412 redrawing_geos = rdman->redrawing_geos; | 421 dirty_geos = rdman->dirty_geos; |
413 for(i = 0; i < n_redrawing_geos; i++) { | 422 for(i = 0; i < n_dirty_geos; i++) { |
414 visit_geo = redrawing_geos[i]; | 423 visit_geo = dirty_geos[i]; |
415 if(!(visit_geo->flags & GEF_DIRTY)) | 424 if(!(visit_geo->flags & GEF_DIRTY)) |
416 continue; | 425 continue; |
417 | 426 |
427 visit_geo->flags &= ~GEF_DIRTY; | |
418 SWAP(visit_geo->cur_area, visit_geo->last_area, area_t *); | 428 SWAP(visit_geo->cur_area, visit_geo->last_area, area_t *); |
419 transform_shape(visit_geo->shape); | 429 update_shape_geo(visit_geo->shape); |
420 visit_geo->flags &= ~GEF_DIRTY; | |
421 add_dirty_area(rdman, visit_geo->cur_area); | 430 add_dirty_area(rdman, visit_geo->cur_area); |
422 add_dirty_area(rdman, visit_geo->last_area); | 431 add_dirty_area(rdman, visit_geo->last_area); |
423 } | 432 } |
424 | 433 |
425 n_dirty_areas = rdman->n_dirty_areas; | 434 n_dirty_areas = rdman->n_dirty_areas; |
435 dirty_areas = rdman->dirty_areas; | |
426 for(visit_geo = STAILQ_HEAD(rdman->all_geos); | 436 for(visit_geo = STAILQ_HEAD(rdman->all_geos); |
427 visit_geo != NULL; | 437 visit_geo != NULL; |
428 visit_geo = STAILQ_NEXT(geo_t, next, visit_geo)) { | 438 visit_geo = STAILQ_NEXT(geo_t, next, visit_geo)) { |
429 if(visit_geo->flags & GEF_DIRTY) | 439 for(i = 0; i < n_dirty_areas; i++) { |
430 continue; | 440 if(is_overlay(visit_geo->cur_area, |
431 | 441 dirty_areas[i])) { |
442 draw_shape(rdman, visit_geo->shape); | |
443 break; | |
444 } | |
445 } | |
432 } | 446 } |
447 clip_and_show(rdman, n_dirty_areas, dirty_areas); | |
433 } | 448 } |
434 | 449 |
435 return OK; | 450 return OK; |
436 } | 451 } |
437 | 452 |