@@ -79,35 +79,42 @@ namespace pretty_poly {
79
79
std::swap (sx, ex);
80
80
}
81
81
82
+ if (ey < 0 || sy >= (int )node_buffer_size) return ;
83
+
82
84
/* sx <<= settings::antialias;
83
85
ex <<= settings::antialias;
84
86
sy <<= settings::antialias;
85
87
ey <<= settings::antialias;*/
86
88
87
89
int x = sx;
88
- int y = sy;
89
90
int e = 0 ;
90
91
91
92
int xinc = sign (ex - sx);
92
93
int einc = abs (ex - sx) + 1 ;
93
-
94
- // todo: preclamp sy and ey (and therefore count) no need to perform
95
- // that test inside the loop
96
94
int dy = ey - sy;
97
- int count = dy;
95
+
96
+ if (sy < 0 ) {
97
+ e = einc * -sy;
98
+ int xjump = e / dy;
99
+ e -= dy * xjump;
100
+ x += xinc * xjump;
101
+ sy = 0 ;
102
+ }
103
+
104
+ int y = sy;
105
+
106
+ int count = std::min ((int )node_buffer_size, ey) - sy;
98
107
debug (" + line segment from %d, %d to %d, %d\n " , sx, sy, ex, ey);
99
108
// loop over scanlines
100
109
while (count--) {
101
110
// consume accumulated error
102
111
while (e > dy) {e -= dy; x += xinc;}
103
112
104
- if (y >= 0 && y < (int )node_buffer_size) {
105
- // clamp node x value to tile bounds
106
- int nx = std::max (std::min (x, (int )(tile_bounds.w << settings::antialias)), 0 );
107
- debug (" + adding node at %d, %d\n " , x, y);
108
- // add node to node list
109
- nodes[y][node_counts[y]++] = nx;
110
- }
113
+ // clamp node x value to tile bounds
114
+ int nx = std::max (std::min (x, (int )(tile_bounds.w << settings::antialias)), 0 );
115
+ debug (" + adding node at %d, %d\n " , x, y);
116
+ // add node to node list
117
+ nodes[y][node_counts[y]++] = nx;
111
118
112
119
// step to next scanline and accumulate error
113
120
y++;
@@ -138,11 +145,17 @@ namespace pretty_poly {
138
145
}
139
146
}
140
147
141
- void render_nodes (const tile_t &tile) {
148
+ void render_nodes (const tile_t &tile, rect_t &bounds) {
149
+ int maxy = -1 ;
150
+ bounds.y = 0 ;
151
+ bounds.x = tile.bounds .w ;
152
+ int maxx = 0 ;
142
153
for (auto y = 0 ; y < (int )node_buffer_size; y++) {
143
154
if (node_counts[y] == 0 ) {
155
+ if (y == bounds.y ) ++bounds.y ;
144
156
continue ;
145
157
}
158
+ maxy = y;
146
159
147
160
std::sort (&nodes[y][0 ], &nodes[y][0 ] + node_counts[y]);
148
161
@@ -154,13 +167,19 @@ namespace pretty_poly {
154
167
continue ;
155
168
}
156
169
170
+ bounds.x = std::min (sx >> settings::antialias, bounds.x );
171
+ maxx = std::max ((ex - 1 ) >> settings::antialias, maxx);
172
+
157
173
debug (" - render span at %d from %d to %d\n " , y, sx, ex);
158
174
159
175
for (int x = sx; x < ex; x++) {
160
176
tile.data [(x >> settings::antialias) + (y >> settings::antialias) * tile.stride ]++;
161
177
}
162
178
}
163
179
}
180
+
181
+ bounds.w = (maxx >= bounds.x ) ? maxx + 1 - bounds.x : 0 ;
182
+ bounds.h = (maxy >= bounds.y ) ? maxy + 1 - bounds.y : 0 ;
164
183
}
165
184
166
185
template <typename T>
@@ -225,7 +244,16 @@ namespace pretty_poly {
225
244
226
245
debug (" : render the tile\n " );
227
246
// render the tile
228
- render_nodes (tile);
247
+ rect_t bounds;
248
+ render_nodes (tile, bounds);
249
+
250
+ tile.data += bounds.x + tile.stride * bounds.y ;
251
+ bounds.x += tile.bounds .x ;
252
+ bounds.y += tile.bounds .y ;
253
+ tile.bounds = bounds.intersection (tile.bounds );
254
+ if (tile.bounds .empty ()) {
255
+ continue ;
256
+ }
229
257
230
258
settings::callback (tile);
231
259
}
0 commit comments