| 1302 | /**************** helper macros and functions for sequence/contour processing ***********/ |
| 1303 | |
| 1304 | static void |
| 1305 | FillEdgeCollection( Mat& img, vector<PolyEdge>& edges, const void* color ) |
| 1306 | { |
| 1307 | PolyEdge tmp; |
| 1308 | int i, y, total = (int)edges.size(); |
| 1309 | Size size = img.size(); |
| 1310 | PolyEdge* e; |
| 1311 | int y_max = INT_MIN, y_min = INT_MAX; |
| 1312 | int64 x_max = 0xFFFFFFFFFFFFFFFF, x_min = 0x7FFFFFFFFFFFFFFF; |
| 1313 | int pix_size = (int)img.elemSize(); |
| 1314 | |
| 1315 | if( total < 2 ) |
| 1316 | return; |
| 1317 | |
| 1318 | for( i = 0; i < total; i++ ) |
| 1319 | { |
| 1320 | PolyEdge& e1 = edges[i]; |
| 1321 | assert( e1.y0 < e1.y1 ); |
| 1322 | // Determine x-coordinate of the end of the edge. |
| 1323 | // (This is not necessary x-coordinate of any vertex in the array.) |
| 1324 | int64 x1 = e1.x + (e1.y1 - e1.y0) * e1.dx; |
| 1325 | y_min = std::min( y_min, e1.y0 ); |
| 1326 | y_max = std::max( y_max, e1.y1 ); |
| 1327 | x_min = std::min( x_min, e1.x ); |
| 1328 | x_max = std::max( x_max, e1.x ); |
| 1329 | x_min = std::min( x_min, x1 ); |
| 1330 | x_max = std::max( x_max, x1 ); |
| 1331 | } |
| 1332 | |
| 1333 | if( y_max < 0 || y_min >= size.height || x_max < 0 || x_min >= ((int64)size.width<<XY_SHIFT) ) |
| 1334 | return; |
| 1335 | |
| 1336 | std::sort( edges.begin(), edges.end(), CmpEdges() ); |
| 1337 | |
| 1338 | // start drawing |
| 1339 | tmp.y0 = INT_MAX; |
| 1340 | edges.push_back(tmp); // after this point we do not add |
| 1341 | // any elements to edges, thus we can use pointers |
| 1342 | i = 0; |
| 1343 | tmp.next = 0; |
| 1344 | e = &edges[i]; |
| 1345 | y_max = MIN( y_max, size.height ); |
| 1346 | |
| 1347 | for( y = e->y0; y < y_max; y++ ) |
| 1348 | { |
| 1349 | PolyEdge *last, *prelast, *keep_prelast; |
| 1350 | int sort_flag = 0; |
| 1351 | int draw = 0; |
| 1352 | int clipline = y < 0; |
| 1353 | |
| 1354 | prelast = &tmp; |
| 1355 | last = tmp.next; |
| 1356 | while( last || e->y0 == y ) |
| 1357 | { |
| 1358 | if( last && last->y1 == y ) |
| 1359 | { |
| 1360 | // exclude edge if y reachs its lower point |
| 1361 | prelast->next = last->next; |