| 43 | static void gc_combine(GRECT *frame, GRECT *test); |
| 44 | static long gc_area(GRECT *area); |
| 45 | int |
| 46 | add_dirty_rect(dirty_rect *dr, GRECT *area) |
| 47 | { |
| 48 | int cursor; |
| 49 | long lowestcost = 9999999L; |
| 50 | int cheapest = -1; |
| 51 | int cheapestmerge1 = -1; |
| 52 | int cheapestmerge2 = -1; |
| 53 | int merge1; |
| 54 | int merge2; |
| 55 | for (cursor = 0; cursor < dr->used; cursor++) { |
| 56 | if (gc_inside(&dr->rects[cursor], area)) { |
| 57 | /* Wholly contained already. */ |
| 58 | return (TRUE); |
| 59 | } |
| 60 | } |
| 61 | for (cursor = 0; cursor < dr->used; cursor++) { |
| 62 | if (gc_touch(&dr->rects[cursor], area)) { |
| 63 | GRECT larger = dr->rects[cursor]; |
| 64 | long cost; |
| 65 | gc_combine(&larger, area); |
| 66 | cost = gc_area(&larger) - gc_area(&dr->rects[cursor]); |
| 67 | if (cost < lowestcost) { |
| 68 | int bad = FALSE, c; |
| 69 | for (c = 0; c < dr->used && !bad; c++) { |
| 70 | bad = gc_touch(&dr->rects[c], &larger) && c != cursor; |
| 71 | } |
| 72 | if (!bad) { |
| 73 | cheapest = cursor; |
| 74 | lowestcost = cost; |
| 75 | } |
| 76 | } |
| 77 | } |
| 78 | } |
| 79 | if (cheapest >= 0) { |
| 80 | gc_combine(&dr->rects[cheapest], area); |
| 81 | return (TRUE); |
| 82 | } |
| 83 | if (dr->used < dr->max) { |
| 84 | dr->rects[dr->used++] = *area; |
| 85 | return (TRUE); |
| 86 | } |
| 87 | // Do cheapest of: |
| 88 | // add to closest cluster |
| 89 | // do cheapest cluster merge, add to new cluster |
| 90 | lowestcost = 9999999L; |
| 91 | cheapest = -1; |
| 92 | for (cursor = 0; cursor < dr->used; cursor++) { |
| 93 | GRECT larger = dr->rects[cursor]; |
| 94 | long cost; |
| 95 | gc_combine(&larger, area); |
| 96 | cost = gc_area(&larger) - gc_area(&dr->rects[cursor]); |
| 97 | if (cost < lowestcost) { |
| 98 | int bad = FALSE, c; |
| 99 | for (c = 0; c < dr->used && !bad; c++) { |
| 100 | bad = gc_touch(&dr->rects[c], &larger) && c != cursor; |
| 101 | } |
| 102 | if (!bad) { |
no test coverage detected