39 { |
39 { |
40 rects = new GrowableRectArray(128); |
40 rects = new GrowableRectArray(128); |
41 dirtyArea = new DirtyRegion(); |
41 dirtyArea = new DirtyRegion(); |
42 } |
42 } |
43 |
43 |
44 public void addRect(int x, int y, int width, int height) { |
|
45 int index = rects.getNextIndex(); |
|
46 rects.setX(index, x); |
|
47 rects.setY(index, y); |
|
48 rects.setWidth(index, width); |
|
49 rects.setHeight(index, height); |
|
50 } |
|
51 |
|
52 public void addLine(int x1, int y1, int x2, int y2) { |
|
53 /* |
|
54 * EXA is not able to accalerate diagonal lines, we try to "guide" it a |
|
55 * bit to avoid excessive migration See project documentation for an |
|
56 * detailed explanation |
|
57 */ |
|
58 DirtyRegion region = new DirtyRegion(); |
|
59 region.setDirtyLineRegion(x1, y1, x2, y2); |
|
60 int xDiff = region.x2 - region.x; |
|
61 int yDiff = region.y2 - region.y; |
|
62 |
|
63 if (xDiff == 0 || yDiff == 0) { |
|
64 addRect(region.x, region.y, |
|
65 region.x2 - region.x + 1, region.y2 - region.y + 1); |
|
66 } else if (xDiff == 1 && yDiff == 1) { |
|
67 addRect(x1, y1, 1, 1); |
|
68 addRect(x2, y2, 1, 1); |
|
69 } else { |
|
70 lineToRects(x1, y1, x2, y2); |
|
71 } |
|
72 } |
|
73 |
|
74 private void lineToRects(int xstart, int ystart, int xend, int yend) { |
|
75 int x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err; |
|
76 |
|
77 /* Entfernung in beiden Dimensionen berechnen */ |
|
78 dx = xend - xstart; |
|
79 dy = yend - ystart; |
|
80 |
|
81 /* Vorzeichen des Inkrements bestimmen */ |
|
82 incx = dx > 0 ? 1 : (dx < 0) ? -1 : 0; |
|
83 incy = dy > 0 ? 1 : (dy < 0) ? -1 : 0; |
|
84 if (dx < 0) |
|
85 dx = -dx; |
|
86 if (dy < 0) |
|
87 dy = -dy; |
|
88 |
|
89 /* feststellen, welche Entfernung groesser ist */ |
|
90 if (dx > dy) { |
|
91 /* x ist schnelle Richtung */ |
|
92 pdx = incx; |
|
93 pdy = 0; /* pd. ist Parallelschritt */ |
|
94 ddx = incx; |
|
95 ddy = incy; /* dd. ist Diagonalschritt */ |
|
96 es = dy; |
|
97 el = dx; /* Fehlerschritte schnell, langsam */ |
|
98 } else { |
|
99 /* y ist schnelle Richtung */ |
|
100 pdx = 0; |
|
101 pdy = incy; /* pd. ist Parallelschritt */ |
|
102 ddx = incx; |
|
103 ddy = incy; /* dd. ist Diagonalschritt */ |
|
104 es = dx; |
|
105 el = dy; /* Fehlerschritte schnell, langsam */ |
|
106 } |
|
107 |
|
108 /* Initialisierungen vor Schleifenbeginn */ |
|
109 x = xstart; |
|
110 y = ystart; |
|
111 err = el / 2; |
|
112 addRect(x, y, 1, 1); |
|
113 |
|
114 /* Pixel berechnen */ |
|
115 for (t = 0; t < el; ++t) /* t zaehlt die Pixel, el ist auch Anzahl */ |
|
116 { |
|
117 /* Aktualisierung Fehlerterm */ |
|
118 err -= es; |
|
119 if (err < 0) { |
|
120 /* Fehlerterm wieder positiv (>=0) machen */ |
|
121 err += el; |
|
122 /* Schritt in langsame Richtung, Diagonalschritt */ |
|
123 x += ddx; |
|
124 y += ddy; |
|
125 } else { |
|
126 /* Schritt in schnelle Richtung, Parallelschritt */ |
|
127 x += pdx; |
|
128 y += pdy; |
|
129 } |
|
130 addRect(x, y, 1, 1); |
|
131 // SetPixel(x,y); |
|
132 // System.out.println(x+":"+y); |
|
133 } |
|
134 } |
|
135 |
|
136 public void calculateDirtyAreas() |
44 public void calculateDirtyAreas() |
137 { |
45 { |
138 for (int i=0; i < rects.getSize(); i++) { |
46 for (int i=0; i < rects.getSize(); i++) { |
139 int x = rects.getX(i); |
47 int x = rects.getX(i); |
140 int y = rects.getY(i); |
48 int y = rects.getY(i); |