Code

Rendering optimisation, which gives best results for zoomed in drawings with complex...
authorknutux <knutux@users.sourceforge.net>
Wed, 19 Apr 2006 05:14:26 +0000 (05:14 +0000)
committerknutux <knutux@users.sourceforge.net>
Wed, 19 Apr 2006 05:14:26 +0000 (05:14 +0000)
19 files changed:
src/display/canvas-arena.cpp
src/display/nr-arena-glyphs.cpp
src/display/nr-arena-item.cpp
src/display/nr-arena-shape.cpp
src/display/nr-arena-shape.h
src/display/nr-arena.cpp
src/display/nr-gradient-gpl.cpp
src/display/sp-canvas.cpp
src/display/sp-canvas.h
src/display/sp-ctrlline.cpp
src/libnr/nr-pixblock.cpp
src/libnr/nr-pixblock.h
src/livarot/Path.cpp
src/livarot/Path.h
src/livarot/PathConversion.cpp
src/livarot/Shape.cpp
src/livarot/Shape.h
src/livarot/ShapeMisc.cpp
src/livarot/ShapeSweep.cpp

index 1d77de1583e7346450c2c6fa3b494989664220f4..2d192ac1b222afa98405e5a371d680cb4b458a79 100644 (file)
@@ -278,10 +278,12 @@ sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf)
                                                  FALSE, FALSE);
 
 #ifdef STRICT_RGBA
+            pb.visible_area = buf->visible_rect; 
                        nr_arena_item_invoke_render (arena->root, &area, &pb, 0);
                        nr_blit_pixblock_pixblock (&cb, &pb);
                        nr_pixblock_release (&pb);
 #else
+            cb.visible_area = buf->visible_rect; 
                        nr_arena_item_invoke_render (arena->root, &area, &cb, 0);
 #endif
 
index 78ba90c2bd6f82ca033943f20c3f3476c8895635..083e7a7f4a7b35e36179c16cd27f67a970ed1c7d 100644 (file)
@@ -440,6 +440,7 @@ nr_arena_glyphs_group_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, u
     if (style->fill.type != SP_PAINT_TYPE_NONE || item->arena->rendermode == RENDERMODE_OUTLINE) {
         NRPixBlock m;
         nr_pixblock_setup_fast(&m, NR_PIXBLOCK_MODE_A8, area->x0, area->y0, area->x1, area->y1, TRUE);
+        m.visible_area = pb->visible_area; 
 
         /* Render children fill mask */
         for (child = group->children; child != NULL; child = child->next) {
@@ -479,6 +480,7 @@ nr_arena_glyphs_group_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, u
         NRPixBlock m;
         guint32 rgba;
         nr_pixblock_setup_fast(&m, NR_PIXBLOCK_MODE_A8, area->x0, area->y0, area->x1, area->y1, TRUE);
+        m.visible_area = pb->visible_area; 
         /* Render children stroke mask */
         for (child = group->children; child != NULL; child = child->next) {
             ret = nr_arena_glyphs_stroke_mask(NR_ARENA_GLYPHS(child), area, &m);
index 7f473ae4d551f8d73b14727d88ef8070c246e058..44068cf9dc282f6574d9de298a8830f8983902b0 100644 (file)
@@ -340,6 +340,7 @@ unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area,
                nr_pixblock_setup_extern (&cpb, NR_PIXBLOCK_MODE_R8G8B8A8P,
                               carea.x0, carea.y0, carea.x1, carea.y1,
                               item->px, 4 * (carea.x1 - carea.x0), TRUE, TRUE);
+        cpb.visible_area = pb->visible_area; 
                dpb = &cpb;
                // Set nocache flag for downstream rendering
                flags |= NR_ARENA_ITEM_RENDER_NO_CACHE;
@@ -401,6 +402,7 @@ unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area,
 
     /* Setup and render item buffer */
     nr_pixblock_setup_fast (&ipb, NR_PIXBLOCK_MODE_R8G8B8A8P, carea.x0, carea.y0, carea.x1, carea.y1, TRUE);
+    ipb.visible_area = pb->visible_area; 
     state = NR_ARENA_ITEM_VIRTUAL (item, render) (item, &carea, &ipb, flags);
     if (state & NR_ARENA_ITEM_STATE_INVALID) {
       /* Clean up and return error */
@@ -414,6 +416,7 @@ unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area,
     if (item->clip || item->mask) {
       /* Setup mask pixblock */
       nr_pixblock_setup_fast (&mpb, NR_PIXBLOCK_MODE_A8, carea.x0, carea.y0, carea.x1, carea.y1, TRUE);
+      mpb.visible_area = pb->visible_area; 
       /* Do clip if needed */
       if (item->clip) {
         state = nr_arena_item_invoke_clip (item->clip, &carea, &mpb);
@@ -432,6 +435,7 @@ unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area,
         NRPixBlock tpb;
         /* Set up yet another temporary pixblock */
         nr_pixblock_setup_fast (&tpb, NR_PIXBLOCK_MODE_R8G8B8A8N, carea.x0, carea.y0, carea.x1, carea.y1, TRUE);
+        tpb.visible_area = pb->visible_area; 
         state = NR_ARENA_ITEM_VIRTUAL (item->mask, render) (item->mask, &carea, &tpb, flags);
         if (state & NR_ARENA_ITEM_STATE_INVALID) {
           /* Clean up and return error */
@@ -542,6 +546,7 @@ unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area,
 
       /* Setup and render item buffer */
       nr_pixblock_setup_fast (&ipb, NR_PIXBLOCK_MODE_R8G8B8A8P, carea.x0, carea.y0, carea.x1, carea.y1, TRUE);
+      ipb.visible_area = pb->visible_area; 
       state = NR_ARENA_ITEM_VIRTUAL (item, render) (item, &carea, &ipb, flags);
       if (state & NR_ARENA_ITEM_STATE_INVALID) {
         /* Clean up and return error */
@@ -555,6 +560,7 @@ unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area,
       if (item->clip || item->mask) {
         /* Setup mask pixblock */
         nr_pixblock_setup_fast (&mpb, NR_PIXBLOCK_MODE_A8, carea.x0, carea.y0, carea.x1, carea.y1, TRUE);
+        mpb.visible_area = pb->visible_area; 
         /* Do clip if needed */
         if (item->clip) {
           state = nr_arena_item_invoke_clip (item->clip, &carea, &mpb);
@@ -573,6 +579,7 @@ unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area,
           NRPixBlock tpb;
           /* Set up yet another temporary pixblock */
           nr_pixblock_setup_fast (&tpb, NR_PIXBLOCK_MODE_R8G8B8A8N, carea.x0, carea.y0, carea.x1, carea.y1, TRUE);
+          tpb.visible_area = pb->visible_area; 
           state = NR_ARENA_ITEM_VIRTUAL (item->mask, render) (item->mask, &carea, &tpb, flags);
           if (state & NR_ARENA_ITEM_STATE_INVALID) {
             /* Clean up and return error */
index 743a70f9c085dab5d2d6283ba13b0b211ad89eee..4f8acca487f108a2a6a2a44610daeadaedd7e608 100644 (file)
@@ -97,6 +97,8 @@ nr_arena_shape_init(NRArenaShape *shape)
     shape->stroke_painter = NULL;
     shape->cached_fill = NULL;
     shape->cached_stroke = NULL;
+    shape->cached_fpartialy = false;
+    shape->cached_spartialy = false;
     shape->fill_shp = NULL;
     shape->stroke_shp = NULL;
 
@@ -184,8 +186,8 @@ nr_arena_shape_set_child_position(NRArenaItem *item, NRArenaItem *child, NRArena
     nr_arena_item_request_render(child);
 }
 
-void nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc);
-void nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, bool force_shape = false);
+void nr_arena_shape_update_stroke(NRArenaShape *shape, NRGC* gc, NRRectL *area);
+void nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, NRRectL *area, bool force_shape = false);
 void nr_arena_shape_add_bboxes(NRArenaShape* shape,NRRect &bbox);
 
 static guint
@@ -301,8 +303,8 @@ nr_arena_shape_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, g
     if ( shape->delayed_shp ) {
         item->bbox=shape->approx_bbox;
     } else {
-        nr_arena_shape_update_stroke(shape,gc);
-        nr_arena_shape_update_fill(shape,gc);
+        nr_arena_shape_update_stroke(shape, gc, area);
+        nr_arena_shape_update_fill(shape, gc, area);
 
         bbox.x0 = bbox.y0 = bbox.x1 = bbox.y1 = 0.0;
         nr_arena_shape_add_bboxes(shape,bbox);
@@ -377,19 +379,28 @@ int matrix_is_isometry(NR::Matrix p) {
     return 0;
 }
 
+static bool is_inner_area(NRRectL const &outer, NRRectL const &inner) {
+    return (outer.x0 <= inner.x0 && outer.y0 <= inner.y0 && outer.x1 >= inner.x1 && outer.y1 >= inner.y1);
+}
+
 /** force_shape is used for clipping paths, when we need the shape for clipping even if it's not filled */
 void
-nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, bool force_shape)
+nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, NRRectL *area, bool force_shape)
 {
-    shape->delayed_shp = false;
     if ((shape->_fill.paint.type() != NRArenaShape::Paint::NONE || force_shape) &&
         ((shape->curve->end > 2) || (shape->curve->bpath[1].code == NR_CURVETO)) ) {
         if (TRUE || !shape->fill_shp) {
             NR::Matrix  cached_to_new;
             int isometry = 0;
             if ( shape->cached_fill ) {
-                cached_to_new = shape->cached_fctm.inverse()*gc->transform;
-                isometry = matrix_is_isometry(cached_to_new);
+                if (shape->cached_fctm == gc->transform) {
+                    isometry = 2; // identity
+                } else {
+                    cached_to_new = shape->cached_fctm.inverse() * gc->transform;
+                    isometry = matrix_is_isometry(cached_to_new);
+                }
+                if (0 != isometry && !is_inner_area(shape->cached_farea, *area))
+                    isometry = 0;
             }
             if ( isometry == 0 ) {
                 if ( shape->cached_fill == NULL ) shape->cached_fill=new Shape;
@@ -402,7 +413,13 @@ nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, bool force_shape)
                     thePath->LoadArtBPath(shape->curve->bpath,tempMat,true);
                 }
 
-                thePath->Convert(1.0);
+                if (is_inner_area(*area, NR_ARENA_ITEM(shape)->bbox)) {
+                    thePath->Convert(1.0);
+                    shape->cached_fpartialy = false;
+                } else {
+                    thePath->Convert(area, 1.0);
+                    shape->cached_fpartialy = true;
+                }
 
                 thePath->Fill(theShape, 0);
 
@@ -414,6 +431,7 @@ nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, bool force_shape)
                     shape->cached_fill->ConvertToShape(theShape, fill_nonZero);
                 }
                 shape->cached_fctm=gc->transform;
+                shape->cached_farea = *area;
                 delete theShape;
                 delete thePath;
                 if ( shape->fill_shp == NULL )
@@ -421,6 +439,11 @@ nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, bool force_shape)
 
                 shape->fill_shp->Copy(shape->cached_fill);
 
+            } else if ( 2 == isometry ) {
+                if ( shape->fill_shp == NULL ) {
+                    shape->fill_shp = new Shape;
+                    shape->fill_shp->Copy(shape->cached_fill);
+                }
             } else {
 
                 if ( shape->fill_shp == NULL )
@@ -443,17 +466,16 @@ nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, bool force_shape)
                 shape->fill_shp->needPointsSorting();
                 shape->fill_shp->needEdgesSorting();
             }
+            shape->delayed_shp |= shape->cached_fpartialy;
         }
     }
 }
 
 void
-nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc)
+nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc, NRRectL *area)
 {
     SPStyle* style = shape->style;
 
-    shape->delayed_shp = false;
-
     float const scale = NR_MATRIX_DF_EXPANSION(&gc->transform);
 
     if (NR_ARENA_ITEM(shape)->arena->rendermode == RENDERMODE_OUTLINE ||
@@ -468,8 +490,14 @@ nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc)
 
         int isometry = 0;
         if ( shape->cached_stroke ) {
-            cached_to_new = shape->cached_sctm.inverse() * gc->transform;
-            isometry = matrix_is_isometry(cached_to_new);
+            if (shape->cached_sctm == gc->transform) {
+                isometry = 2; // identity
+            } else {
+                cached_to_new = shape->cached_sctm.inverse() * gc->transform;
+                isometry = matrix_is_isometry(cached_to_new);
+            }
+            if (0 != isometry && !is_inner_area(shape->cached_sarea, *area))
+                isometry = 0;
         }
 
         if ( isometry == 0 ) {
@@ -482,10 +510,20 @@ nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc)
                 thePath->LoadArtBPath(shape->curve->bpath, tempMat, true);
             }
 
-            if (NR_ARENA_ITEM(shape)->arena->rendermode != RENDERMODE_OUTLINE)
-                thePath->Convert(1.0);
-            else
-                thePath->Convert(4.0); // slightly rougher & faster
+            // add some padding to the rendering area, so clipped path does not go into a render area
+            NRRectL padded_area = *area;
+            padded_area.x0 -= (NR::ICoord)width;
+            padded_area.x1 += (NR::ICoord)width;
+            padded_area.y0 -= (NR::ICoord)width;
+            padded_area.y1 += (NR::ICoord)width;
+            if (is_inner_area(padded_area, NR_ARENA_ITEM(shape)->bbox)) {
+                thePath->Convert((NR_ARENA_ITEM(shape)->arena->rendermode != RENDERMODE_OUTLINE) ? 1.0 : 4.0);
+                shape->cached_spartialy = false;
+            }
+            else {
+                thePath->Convert(&padded_area, (NR_ARENA_ITEM(shape)->arena->rendermode != RENDERMODE_OUTLINE) ? 1.0 : 4.0);
+                shape->cached_spartialy = true;
+            }
 
             if (style->stroke_dash.n_dash && NR_ARENA_ITEM(shape)->arena->rendermode != RENDERMODE_OUTLINE) {
                 double dlen = 0.0;
@@ -555,14 +593,19 @@ nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc)
             }
 
             shape->cached_sctm=gc->transform;
+            shape->cached_sarea = *area;
             delete thePath;
             delete theShape;
             if ( shape->stroke_shp == NULL ) shape->stroke_shp=new Shape;
 
             shape->stroke_shp->Copy(shape->cached_stroke);
 
+        } else if ( 2 == isometry ) {
+            if ( shape->stroke_shp == NULL ) {
+                shape->stroke_shp=new Shape;
+                shape->stroke_shp->Copy(shape->cached_stroke);
+            }
         } else {
-
             if ( shape->stroke_shp == NULL )
                 shape->stroke_shp=new Shape;
             shape->stroke_shp->Reset(shape->cached_stroke->numberOfPoints(), shape->cached_stroke->numberOfEdges());
@@ -581,6 +624,7 @@ nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc)
             shape->stroke_shp->needPointsSorting();
             shape->stroke_shp->needEdgesSorting();
         }
+        shape->delayed_shp |= shape->cached_spartialy;
     }
 }
 
@@ -655,8 +699,9 @@ nr_arena_shape_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned
         if ( nr_rect_l_test_intersect(area, &item->bbox) ) {
             NRGC   tempGC(NULL);
             tempGC.transform=shape->ctm;
-            nr_arena_shape_update_stroke(shape,&tempGC);
-            nr_arena_shape_update_fill(shape,&tempGC);
+            shape->delayed_shp = false;
+            nr_arena_shape_update_stroke(shape,&tempGC,&pb->visible_area);
+            nr_arena_shape_update_fill(shape,&tempGC,&pb->visible_area);
 /*      NRRect bbox;
         bbox.x0 = bbox.y0 = bbox.x1 = bbox.y1 = 0.0;
         nr_arena_shape_add_bboxes(shape,bbox);
@@ -665,6 +710,8 @@ nr_arena_shape_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned
         item->bbox.x1 = (gint32)(bbox.x1 + 1.0F);
         item->bbox.y1 = (gint32)(bbox.y1 + 1.0F);
         shape->approx_bbox=item->bbox;*/
+        } else {
+            return item->state;
         }
     }
 
@@ -674,6 +721,7 @@ nr_arena_shape_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned
         guint32 rgba;
 
         nr_pixblock_setup_fast(&m, NR_PIXBLOCK_MODE_A8, area->x0, area->y0, area->x1, area->y1, TRUE);
+        m.visible_area = pb->visible_area; 
         nr_pixblock_render_shape_mask_or(m,shape->fill_shp);
         m.empty = FALSE;
 
@@ -704,6 +752,7 @@ nr_arena_shape_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned
         guint32 rgba;
 
         nr_pixblock_setup_fast(&m, NR_PIXBLOCK_MODE_A8, area->x0, area->y0, area->x1, area->y1, TRUE);
+        m.visible_area = pb->visible_area; 
         nr_pixblock_render_shape_mask_or(m, shape->stroke_shp);
         m.empty = FALSE;
 
@@ -750,7 +799,10 @@ nr_arena_shape_clip(NRArenaItem *item, NRRectL *area, NRPixBlock *pb)
         if ( nr_rect_l_test_intersect(area, &item->bbox) ) {
             NRGC   tempGC(NULL);
             tempGC.transform=shape->ctm;
-            nr_arena_shape_update_fill(shape, &tempGC, true);
+            shape->delayed_shp = false;
+            nr_arena_shape_update_fill(shape, &tempGC, &pb->visible_area, true);
+        } else {
+            return item->state;
         }
     }
 
@@ -759,6 +811,7 @@ nr_arena_shape_clip(NRArenaItem *item, NRRectL *area, NRPixBlock *pb)
 
         /* fixme: We can OR in one step (Lauris) */
         nr_pixblock_setup_fast(&m, NR_PIXBLOCK_MODE_A8, area->x0, area->y0, area->x1, area->y1, TRUE);
+        m.visible_area = pb->visible_area; 
         nr_pixblock_render_shape_mask_or(m,shape->fill_shp);
 
         for (int y = area->y0; y < area->y1; y++) {
@@ -786,7 +839,7 @@ nr_arena_shape_pick(NRArenaItem *item, NR::Point p, double delta, unsigned int /
     if (!shape->curve) return NULL;
     if (!shape->style) return NULL;
     if ( shape->delayed_shp ) {
-        NRRectL  area;
+        NRRectL  area, updateArea;
         area.x0=(int)floor(p[NR::X]);
         area.x1=(int)ceil(p[NR::X]);
         area.y0=(int)floor(p[NR::Y]);
@@ -800,8 +853,13 @@ nr_arena_shape_pick(NRArenaItem *item, NR::Point p, double delta, unsigned int /
         if ( nr_rect_l_test_intersect(&area, &item->bbox) ) {
             NRGC   tempGC(NULL);
             tempGC.transform=shape->ctm;
-            nr_arena_shape_update_stroke(shape,&tempGC);
-            nr_arena_shape_update_fill(shape,&tempGC);
+            updateArea = item->bbox;
+            if (shape->cached_stroke)
+                nr_rect_l_intersect (&updateArea, &updateArea, &shape->cached_sarea);
+
+            shape->delayed_shp = false;
+            nr_arena_shape_update_stroke(shape, &tempGC, &updateArea);
+            nr_arena_shape_update_fill(shape, &tempGC, &updateArea);
             /*      NRRect bbox;
                     bbox.x0 = bbox.y0 = bbox.x1 = bbox.y1 = 0.0;
                     nr_arena_shape_add_bboxes(shape,bbox);
index 9f8eec99ae64aa740d381269aea6ab4d8e2bd073..cd72013f6d2cab12e063309addcb84f01bc8e148 100644 (file)
@@ -138,6 +138,10 @@ struct NRArenaShape : public NRArenaItem {
        // skewing
        NR::Matrix cached_fctm;
        NR::Matrix cached_sctm;
+    NRRectL    cached_farea;
+    NRRectL    cached_sarea;
+    bool       cached_fpartialy;
+    bool       cached_spartialy;
        
        Shape    *cached_fill;
        Shape    *cached_stroke;
index f54bfbb90b4ed5dd49598ab5874a099945fcee69..a6e33d2dc43ba743e0340ad5cd2ee4f4629a1105 100644 (file)
@@ -109,6 +109,8 @@ nr_arena_render_paintserver_fill (NRPixBlock *pb, NRRectL *area, SPPainter *pain
        NRPixBlock cb, cb_opa;
        nr_pixblock_setup_fast (&cb, NR_PIXBLOCK_MODE_R8G8B8A8N, area->x0, area->y0, area->x1, area->y1, TRUE);
        nr_pixblock_setup_fast (&cb_opa, NR_PIXBLOCK_MODE_R8G8B8A8N, area->x0, area->y0, area->x1, area->y1, TRUE);
+    cb.visible_area = pb->visible_area; 
+    cb_opa.visible_area = pb->visible_area; 
 
        /* Need separate gradient buffer (lauris)*/
        // do the filling
index 54a33cfdb6a6e758a750926b5b50758170cd460d..536217649ae2ea1b0ba8870bb5740475f1207d85 100644 (file)
@@ -271,6 +271,7 @@ nr_lgradient_render_generic (NRLGradientRenderer *lgr, NRPixBlock *pb)
                                  (unsigned char *) lgr->vector,
                                  4 * NR_GRADIENT_VECTOR_LENGTH,
                                  0, 0);
+    spb.visible_area = pb->visible_area; 
        bpp = (pb->mode == NR_PIXBLOCK_MODE_A8) ? 1 : (pb->mode == NR_PIXBLOCK_MODE_R8G8B8) ? 3 : 4;
 
        for (y = 0; y < height; y++) {
index b1ed7d3d23fd81537decc9e9656e17bd03b97116..5e19539f37bf9293e0116798259b5a75d71ca9c7 100644 (file)
@@ -1565,6 +1565,10 @@ sp_canvas_paint_rect (SPCanvas *canvas, int xx0, int yy0, int xx1, int yy1)
             buf.rect.y0 = y0;
             buf.rect.x1 = x1;
             buf.rect.y1 = y1;
+            buf.visible_rect.x0 = draw_x1;
+            buf.visible_rect.y0 = draw_y1;
+            buf.visible_rect.x1 = draw_x2;
+            buf.visible_rect.y1 = draw_y2;
             GdkColor *color = &widget->style->bg[GTK_STATE_NORMAL];
             buf.bg_color = (((color->red & 0xff00) << 8)
                             | (color->green & 0xff00)
index 86522870a19cc321b118fdaeb009cf8bb7697a6d..34ed87ac9198722ba9fc53795e4fd253b9c7d36a 100644 (file)
@@ -52,6 +52,7 @@ struct SPCanvasBuf{
     guchar *buf;
     int buf_rowstride;
     NRRectL rect;
+    NRRectL visible_rect;
     /// Background color, given as 0xrrggbb
     guint32 bg_color;
     // If empty, ignore contents of buffer and use a solid area of bg_color
index 6715f890fc0ebd215b6640e9f6164c5da1dc855c..463d32336f486c3014035cc31c9f2dd23a5d0982 100644 (file)
@@ -142,7 +142,12 @@ sp_ctrlline_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int f
     thePath->MoveTo(NR::Point(cl->s.x, cl->s.y) * affine);
     thePath->LineTo(NR::Point(cl->e.x, cl->e.y) * affine);
 
-    thePath->Convert(1.0);
+    NRRectL  area;
+    area.x0=item->x1;
+    area.x1=item->x2;
+    area.y0=item->y1;
+    area.y1=item->y2;
+    thePath->Convert(&area, 1.0);
     if ( cl->shp == NULL ) cl->shp=new Shape;
     thePath->Stroke(cl->shp,false,0.5,join_straight,butt_straight,20.0,false);
     cl->shp->CalcBBox();
index 9b1ff27526382382294c529f1eec2a07d07e1985..59e64b558e367d040a2c987a6ccfe3e818c82a72 100644 (file)
@@ -64,10 +64,10 @@ nr_pixblock_setup_fast (NRPixBlock *pb, NR_PIXBLOCK_MODE mode, int x0, int y0, i
 
        pb->mode = mode;
        pb->empty = 1;
-       pb->area.x0 = x0;
-       pb->area.y0 = y0;
-       pb->area.x1 = x1;
-       pb->area.y1 = y1;
+    pb->visible_area.x0 = pb->area.x0 = x0;
+    pb->visible_area.y0 = pb->area.y0 = y0;
+    pb->visible_area.x1 = pb->area.x1 = x1;
+    pb->visible_area.y1 = pb->area.y1 = y1;
        pb->rs = bpp * w;
 }
 
@@ -103,10 +103,10 @@ nr_pixblock_setup (NRPixBlock *pb, NR_PIXBLOCK_MODE mode, int x0, int y0, int x1
 
        pb->mode = mode;
        pb->empty = 1;
-       pb->area.x0 = x0;
-       pb->area.y0 = y0;
-       pb->area.x1 = x1;
-       pb->area.y1 = y1;
+    pb->visible_area.x0 = pb->area.x0 = x0;
+    pb->visible_area.y0 = pb->area.y0 = y0;
+    pb->visible_area.x1 = pb->area.x1 = x1;
+    pb->visible_area.y1 = pb->area.y1 = y1;
        pb->rs = bpp * w;
 }
 
@@ -130,10 +130,10 @@ nr_pixblock_setup_extern (NRPixBlock *pb, NR_PIXBLOCK_MODE mode, int x0, int y0,
        pb->size = NR_PIXBLOCK_SIZE_STATIC; 
        pb->mode = mode;
        pb->empty = empty;
-       pb->area.x0 = x0;
-       pb->area.y0 = y0;
-       pb->area.x1 = x1;
-       pb->area.y1 = y1;
+       pb->visible_area.x0 = pb->area.x0 = x0;
+       pb->visible_area.y0 = pb->area.y0 = y0;
+       pb->visible_area.x1 = pb->area.x1 = x1;
+       pb->visible_area.y1 = pb->area.y1 = y1;
        pb->data.px = px;
        pb->rs = rs;
 
index 2a13dd921ae740c4ab0d6252813563cb856f5ce0..c9ccb4fc62dcdf26d5435cd998f19222ba64554c 100644 (file)
@@ -41,6 +41,7 @@ struct NRPixBlock {
        bool empty : 1;            ///< Empty flag
        unsigned int rs;           ///< Size of line in bytes
        NRRectL area;
+    NRRectL visible_area;
        union {
                unsigned char *px; ///< Pointer to buffer
                unsigned char p[sizeof (unsigned char *)]; ///< Tiny buffer
index 32c1003101823b9095844e38cd6665e770238d57..8ad806349db8230488d012941c729a79a2e146f9 100644 (file)
@@ -428,6 +428,18 @@ int Path::AddPoint(NR::Point const &iPt, bool mvto)
 }
 
 
+int Path::ReplacePoint(NR::Point const &iPt)
+{
+    if (pts.empty()) {
+        return -1;
+    }
+  
+    int const n = pts.size() - 1;
+    pts[n] = path_lineto(polyline_lineto, iPt);
+    return n;
+}
+
+
 int Path::AddPoint(NR::Point const &iPt, int ip, double it, bool mvto)
 {
     if (back == false) {
index 5b1df6294446aeb9dc8ab9bd3be1b8179b6fe88a..291d8f1571266eb2b4da13fc379b3875d5ba481f 100644 (file)
@@ -13,6 +13,7 @@
 #include "LivarotDefs.h"
 #include "livarot/livarot-forward.h"
 #include "libnr/nr-point.h"
+#include <libnr/nr-rect-l.h>
 
 /*
  * the Path class: a structure to hold path description and their polyline approximation (not kept in sync)
@@ -108,6 +109,7 @@ public:
   // transforms a description in a polyline (for stroking and filling)
   // treshhold is the max length^2 (sort of)
   void Convert (double treshhold);
+  void Convert(NRRectL *area, double treshhold);
   void ConvertEvenLines (double treshhold);    // decomposes line segments too, for later recomposition
   // same function for use when you want to later recompose the curves from the polyline
   void ConvertWithBackData (double treshhold);
@@ -119,6 +121,7 @@ public:
   int AddPoint ( NR::Point const &iPt, int ip, double it, bool mvto = false);
   int AddForcedPoint ( NR::Point const &iPt);  // add point
   int AddForcedPoint ( NR::Point const &iPt, int ip, double it);
+  int ReplacePoint(NR::Point const &iPt);  // replace point
 
   // transform in a polygon (in a graph, in fact; a subsequent call to ConvertToShape is needed)
   //  - fills the polyline; justAdd=true doesn't reset the Shape dest, but simply adds the polyline into it
index e6f7acb0c17319f396099b5d529e724ea43651b6..d81785d20eebacb30921b73cc1aa4c130a1528b4 100644 (file)
@@ -400,6 +400,271 @@ void Path::Convert(double treshhold)
     }
 }
 
+#define POINT_RELATION_TO_AREA(pt, area) ((pt)[0] < (area)->x0 ? 1 : ((pt)[0] > (area)->x1 ? 2 : ((pt)[1] < (area)->y0 ? 3 : ((pt)[1] > (area)->y1 ? 4 : 0))))
+
+void Path::Convert(NRRectL *area, double treshhold)
+{
+    if ( descr_flags & descr_adding_bezier ) {
+        CancelBezier();
+    }
+
+    if ( descr_flags & descr_doing_subpath ) {
+        CloseSubpath();
+    }
+
+    SetBackData(false);
+    ResetPoints();
+    if ( descr_cmd.empty() ) {
+        return;
+    }
+
+    NR::Point curX;
+    int curP = 1;
+    int lastMoveTo = 0;
+    short last_point_relation = 0;
+    short curent_point_relation = 0;
+    bool start_elimination = false;
+    bool replace = false;
+
+    // le moveto
+    {
+        int const firstTyp = descr_cmd[0]->getType();
+        if ( firstTyp == descr_moveto ) {
+            curX = dynamic_cast<PathDescrMoveTo *>(descr_cmd[0])->p;
+        } else {
+            curP = 0;
+            curX[0] = curX[1] = 0;
+        }
+        
+        last_point_relation = POINT_RELATION_TO_AREA(curX, area);
+        lastMoveTo = AddPoint(curX, true);
+    }
+    descr_cmd[0]->associated = lastMoveTo;
+
+    // et le reste, 1 par 1
+    while ( curP < int(descr_cmd.size()) ) {
+
+        int const nType = descr_cmd[curP]->getType();
+        NR::Point nextX;
+
+        switch (nType) {
+            case descr_forced: {
+                descr_cmd[curP]->associated = AddForcedPoint(curX);
+                last_point_relation = 0;
+                curP++;
+                break;
+            }
+
+            case descr_moveto: {
+                PathDescrMoveTo *nData = dynamic_cast<PathDescrMoveTo *>(descr_cmd[curP]);
+                nextX = nData->p;
+                lastMoveTo = AddPoint(nextX, true);
+                descr_cmd[curP]->associated = lastMoveTo;
+                last_point_relation = 0;
+
+                // et on avance
+                curP++;
+                break;
+            }
+
+            case descr_close: {
+                nextX = pts[lastMoveTo].p;
+                descr_cmd[curP]->associated = AddPoint(nextX, false);
+                if ( descr_cmd[curP]->associated < 0 ) {
+                    if ( curP == 0 ) {
+                        descr_cmd[curP]->associated = 0;
+                    } else {
+                        descr_cmd[curP]->associated = descr_cmd[curP - 1]->associated;
+                    }
+                }
+                last_point_relation = 0;
+                curP++;
+                break;
+            }
+
+            case descr_lineto: {
+                PathDescrLineTo *nData = dynamic_cast<PathDescrLineTo *>(descr_cmd[curP]);
+                nextX = nData->p;
+                curent_point_relation = POINT_RELATION_TO_AREA(nextX, area);
+                replace = false;
+                if (curent_point_relation > 0 && curent_point_relation == last_point_relation) {
+                    if (!start_elimination) {
+                        start_elimination = true;
+                    } else {
+                        replace = true;
+                        descr_cmd[curP]->associated = ReplacePoint(nextX);
+                    }
+                } else {
+                    start_elimination = false;
+                }
+                
+                if (!replace) {
+                    descr_cmd[curP]->associated = AddPoint(nextX, false);
+                }
+
+                if ( descr_cmd[curP]->associated < 0 ) {
+                    if ( curP == 0 ) {
+                        descr_cmd[curP]->associated = 0;
+                    } else {
+                        descr_cmd[curP]->associated = descr_cmd[curP - 1]->associated;
+                    }
+                }
+                last_point_relation = curent_point_relation;
+                // et on avance
+                curP++;
+                break;
+            }
+
+            case descr_cubicto: {
+                PathDescrCubicTo *nData = dynamic_cast<PathDescrCubicTo *>(descr_cmd[curP]);
+                nextX = nData->p;
+
+                curent_point_relation = POINT_RELATION_TO_AREA(nextX, area);
+                replace = false;
+                if (curent_point_relation > 0 && curent_point_relation == last_point_relation &&
+                    curent_point_relation == POINT_RELATION_TO_AREA(curX + (nData->start), area) &&
+                    curent_point_relation == POINT_RELATION_TO_AREA(nextX + (nData->end), area))
+                {
+                    if (!start_elimination) {
+                        start_elimination = true;
+                    } else {
+                        replace = true;
+                        descr_cmd[curP]->associated = ReplacePoint(nextX);
+                    }
+                } else {
+                    start_elimination = false;
+                }
+                
+                if (!replace) {
+                    RecCubicTo(curX, nData->start, nextX, nData->end, treshhold, 8);
+                    descr_cmd[curP]->associated = AddPoint(nextX,false);
+                }
+
+                if ( descr_cmd[curP]->associated < 0 ) {
+                    if ( curP == 0 ) {
+                        descr_cmd[curP]->associated = 0;
+                    } else {
+                        descr_cmd[curP]->associated = descr_cmd[curP - 1]->associated;
+                    }
+                }
+                last_point_relation = curent_point_relation;
+                // et on avance
+                curP++;
+                break;
+            }
+
+            case descr_arcto: {
+                PathDescrArcTo *nData = dynamic_cast<PathDescrArcTo *>(descr_cmd[curP]);
+                nextX = nData->p;
+                DoArc(curX, nextX, nData->rx, nData->ry, nData->angle, nData->large, nData->clockwise, treshhold);
+                descr_cmd[curP]->associated = AddPoint(nextX, false);
+                if ( descr_cmd[curP]->associated < 0 ) {
+                    if ( curP == 0 ) {
+                        descr_cmd[curP]->associated = 0;
+                    } else {
+                        descr_cmd[curP]->associated = descr_cmd[curP - 1]->associated;
+                    }
+                }
+                last_point_relation = 0;
+                // et on avance
+                curP++;
+                break;
+            }
+
+            case descr_bezierto: {
+                PathDescrBezierTo *nBData = dynamic_cast<PathDescrBezierTo *>(descr_cmd[curP]);
+                int nbInterm = nBData->nb;
+                nextX = nBData->p;
+                int curBD = curP;
+
+                curP++;
+                int ip = curP;
+                PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[ip]);
+
+                if ( nbInterm == 1 ) {
+                    NR::Point const midX = nData->p;
+                    RecBezierTo(midX, curX, nextX, treshhold, 8);
+                } else if ( nbInterm > 1 ) {
+                    NR::Point bx = curX;
+                    NR::Point cx = curX;
+                    NR::Point dx = curX;
+
+                    dx = nData->p;
+                    ip++;
+                    nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[ip]);
+
+                    cx = 2 * bx - dx;
+
+                    for (int k = 0; k < nbInterm - 1; k++) {
+                        bx = cx;
+                        cx = dx;
+
+                        dx = nData->p;
+                        ip++;
+                        nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[ip]);
+
+                        NR::Point stx = (bx + cx) / 2;
+                        if ( k > 0 ) {
+                            descr_cmd[ip - 2]->associated = AddPoint(stx, false);
+                            if ( descr_cmd[ip - 2]->associated < 0 ) {
+                                if ( curP == 0 ) {
+                                    descr_cmd[ip - 2]->associated = 0;
+                                } else {
+                                    descr_cmd[ip - 2]->associated = descr_cmd[ip - 3]->associated;
+                                }
+                            }
+                        }
+
+                        {
+                            NR::Point const mx = (cx + dx) / 2;
+                            RecBezierTo(cx, stx, mx, treshhold, 8);
+                        }
+                    }
+
+                    {
+                        bx = cx;
+                        cx = dx;
+
+                        dx = nextX;
+                        dx = 2 * dx - cx;
+
+                        NR::Point stx = (bx + cx) / 2;
+
+                        descr_cmd[ip - 1]->associated = AddPoint(stx, false);
+                        if ( descr_cmd[ip - 1]->associated < 0 ) {
+                            if ( curP == 0 ) {
+                                descr_cmd[ip - 1]->associated = 0;
+                            } else {
+                                descr_cmd[ip - 1]->associated = descr_cmd[ip - 2]->associated;
+                            }
+                        }
+
+                        {
+                            NR::Point mx = (cx + dx) / 2;
+                            RecBezierTo(cx, stx, mx, treshhold, 8);
+                        }
+                    }
+                }
+
+                descr_cmd[curBD]->associated = AddPoint(nextX, false);
+                if ( descr_cmd[curBD]->associated < 0 ) {
+                    if ( curP == 0 ) {
+                        descr_cmd[curBD]->associated = 0;
+                    } else {
+                        descr_cmd[curBD]->associated = descr_cmd[curBD - 1]->associated;
+                    }
+                }
+
+                last_point_relation = 0;
+                // et on avance
+                curP += nbInterm;
+                break;
+            }
+        }
+
+        curX = nextX;
+    }
+}
 
 
 void Path::ConvertEvenLines(double treshhold)
index eead99225fb89816b29e7e7752dee947a5a0da21..178e8660ee2531273ac341aefa8ecbc39c713a39 100644 (file)
@@ -22,16 +22,19 @@ Shape::Shape()
   : iData(NULL),
     sTree(NULL),
     sEvts(NULL),
+    qrsData(NULL),
     _need_points_sorting(false),
     _need_edges_sorting(false),
     _has_points_data(false),
+    _point_data_initialised(false),
     _has_edges_data(false),
     _has_sweep_src_data(false),
     _has_sweep_dest_data(false),
     _has_raster_data(false),
     _has_quick_raster_data(false),
     _has_back_data(false),
-    _has_voronoi_data(false)
+    _has_voronoi_data(false),
+    _bbox_up_to_date(false)
 {
   leftX = topY = rightX = bottomY = 0;
   maxPt = 0;
@@ -43,6 +46,7 @@ Shape::~Shape (void)
 {
   maxPt = 0;
   maxAr = 0;
+  free(qrsData);
 }
 
 void Shape::Affiche(void)
@@ -58,64 +62,65 @@ void Shape::Affiche(void)
   */
 }
 
+/**
+ * Allocates space for point cache or clears the cache
+ \param  nVal   Allocate a cache (true) or clear it (false)
+ */
 void
 Shape::MakePointData (bool nVal)
 {
   if (nVal)
     {
       if (_has_points_data == false)
-       {
-         _has_points_data = true;
-         pData.resize(maxPt);
-       }
-    }
-  else
-    {
-      if (_has_points_data)
-       {
-         _has_points_data = false;
-         pData.clear();
-       }
-    }
+        {
+          _has_points_data = true;
+          _point_data_initialised = false;
+          _bbox_up_to_date = false;
+          pData.resize(maxPt);
+        }
+    }
+    /* no need to clean point data - keep it cached*/
 }
+
 void
 Shape::MakeEdgeData (bool nVal)
 {
   if (nVal)
     {
       if (_has_edges_data == false)
-       {
-         _has_edges_data = true;
-         eData.resize(maxAr);
-       }
+        {
+          _has_edges_data = true;
+          eData.resize(maxAr);
+        }
     }
   else
     {
       if (_has_edges_data)
-       {
-         _has_edges_data = false;
-         eData.clear();
-       }
+        {
+          _has_edges_data = false;
+          eData.clear();
+        }
     }
 }
+
 void
 Shape::MakeRasterData (bool nVal)
 {
   if (nVal)
     {
       if (_has_raster_data == false)
-       {
-         _has_raster_data = true;
-         swrData.resize(maxAr);
-       }
+        {
+          _has_raster_data = true;
+          swrData.resize(maxAr);
+        }
     }
   else
     {
       if (_has_raster_data)
-       {
-         _has_raster_data = false;
-         swrData.clear();
-       }
+        {
+          _has_raster_data = false;
+          swrData.clear();
+        }
     }
 }
 void
@@ -124,18 +129,17 @@ Shape::MakeQuickRasterData (bool nVal)
   if (nVal)
     {
       if (_has_quick_raster_data == false)
-       {
-         _has_quick_raster_data = true;
-         qrsData.resize(maxAr);
-       }
+        {
+          _has_quick_raster_data = true;
+          qrsData = (quick_raster_data*)realloc(qrsData, maxAr * sizeof(quick_raster_data));
+        }
     }
   else
     {
       if (_has_quick_raster_data)
-       {
-         _has_quick_raster_data = false;
-         qrsData.clear();
-       }
+        {
+          _has_quick_raster_data = false;
+        }
     }
 }
 void
@@ -144,18 +148,18 @@ Shape::MakeSweepSrcData (bool nVal)
   if (nVal)
     {
       if (_has_sweep_src_data == false)
-       {
-         _has_sweep_src_data = true;
-         swsData.resize(maxAr);
-       }
+        {
+          _has_sweep_src_data = true;
+          swsData.resize(maxAr);
+        }
     }
   else
     {
       if (_has_sweep_src_data)
-       {
-         _has_sweep_src_data = false;
-         swsData.clear();
-       }
+        {
+          _has_sweep_src_data = false;
+          swsData.clear();
+        }
     }
 }
 void
@@ -164,18 +168,18 @@ Shape::MakeSweepDestData (bool nVal)
   if (nVal)
     {
       if (_has_sweep_dest_data == false)
-       {
-         _has_sweep_dest_data = true;
-         swdData.resize(maxAr);
-       }
+        {
+          _has_sweep_dest_data = true;
+          swdData.resize(maxAr);
+        }
     }
   else
     {
       if (_has_sweep_dest_data)
-       {
-         _has_sweep_dest_data = false;
-         swdData.clear();
-       }
+        {
+          _has_sweep_dest_data = false;
+          swdData.clear();
+        }
     }
 }
 void
@@ -184,18 +188,18 @@ Shape::MakeBackData (bool nVal)
   if (nVal)
     {
       if (_has_back_data == false)
-       {
-         _has_back_data = true;
-         ebData.resize(maxAr);
-       }
+        {
+          _has_back_data = true;
+          ebData.resize(maxAr);
+        }
     }
   else
     {
       if (_has_back_data)
-       {
-         _has_back_data = false;
-         ebData.clear();
-       }
+        {
+          _has_back_data = false;
+          ebData.clear();
+        }
     }
 }
 void
@@ -204,20 +208,20 @@ Shape::MakeVoronoiData (bool nVal)
   if (nVal)
     {
       if (_has_voronoi_data == false)
-       {
-         _has_voronoi_data = true;
-         vorpData.resize(maxPt);
-         voreData.resize(maxAr);
-       }
+        {
+          _has_voronoi_data = true;
+          vorpData.resize(maxPt);
+          voreData.resize(maxAr);
+        }
     }
   else
     {
       if (_has_voronoi_data)
-       {
-         _has_voronoi_data = false;
-         vorpData.clear();
-         voreData.clear();
-       }
+        {
+          _has_voronoi_data = false;
+          vorpData.clear();
+          voreData.clear();
+        }
     }
 }
 
@@ -252,6 +256,7 @@ Shape::Copy (Shape * who)
   _need_points_sorting = who->_need_points_sorting;
   _need_edges_sorting = who->_need_edges_sorting;
   _has_points_data = false;
+  _point_data_initialised = false;
   _has_edges_data = false;
   _has_sweep_src_data = false;
   _has_sweep_dest_data = false;
@@ -259,42 +264,48 @@ Shape::Copy (Shape * who)
   _has_quick_raster_data = false;
   _has_back_data = false;
   _has_voronoi_data = false;
+  _bbox_up_to_date = false;
 
   _pts = who->_pts;
   _aretes = who->_aretes;
 }
 
+/**
+ *  Clear points and edges and prepare internal data using new size.
+ */
 void
-Shape::Reset (int n, int m)
+Shape::Reset (int pointCount, int edgeCount)
 {
   _pts.clear();
   _aretes.clear();
   
   type = shape_polygon;
-  if (n > maxPt)
+  if (pointCount > maxPt)
     {
-      maxPt = n;
+      maxPt = pointCount;
       if (_has_points_data)
-       pData.resize(maxPt);
+        pData.resize(maxPt);
       if (_has_voronoi_data)
-       vorpData.resize(maxPt);
+        vorpData.resize(maxPt);
     }
-  if (m > maxAr)
+  if (edgeCount > maxAr)
     {
-      maxAr = m;
+      maxAr = edgeCount;
       if (_has_edges_data)
-       eData.resize(maxAr);
+        eData.resize(maxAr);
       if (_has_sweep_dest_data)
-       swdData.resize(maxAr);
+        swdData.resize(maxAr);
       if (_has_sweep_src_data)
-       swsData.resize(maxAr);
+        swsData.resize(maxAr);
       if (_has_back_data)
-       ebData.resize(maxAr);
+        ebData.resize(maxAr);
       if (_has_voronoi_data)
-       voreData.resize(maxAr);
+        voreData.resize(maxAr);
     }
   _need_points_sorting = false;
   _need_edges_sorting = false;
+  _point_data_initialised = false;
+  _bbox_up_to_date = false;
 }
 
 int
@@ -304,9 +315,9 @@ Shape::AddPoint (const NR::Point x)
     {
       maxPt = 2 * numberOfPoints() + 1;
       if (_has_points_data)
-       pData.resize(maxPt);
+        pData.resize(maxPt);
       if (_has_voronoi_data)
-       vorpData.resize(maxPt);
+        vorpData.resize(maxPt);
     }
 
   dg_point p;
@@ -324,6 +335,8 @@ Shape::AddPoint (const NR::Point x)
       pData[n].nextLinkedPoint = -1;
       pData[n].askForWindingS = NULL;
       pData[n].askForWindingB = -1;
+      pData[n].rx[0] = Round(p.x[0]);
+      pData[n].rx[1] = Round(p.x[1]);
     }
   if (_has_voronoi_data)
     {
@@ -346,23 +359,23 @@ Shape::SubPoint (int p)
   while (cb >= 0 && cb < numberOfEdges())
     {
       if (getEdge(cb).st == p)
-       {
-         int ncb = getEdge(cb).nextS;
-         _aretes[cb].nextS = _aretes[cb].prevS = -1;
-         _aretes[cb].st = -1;
-         cb = ncb;
-       }
+        {
+          int ncb = getEdge(cb).nextS;
+          _aretes[cb].nextS = _aretes[cb].prevS = -1;
+          _aretes[cb].st = -1;
+          cb = ncb;
+        }
       else if (getEdge(cb).en == p)
-       {
-         int ncb = getEdge(cb).nextE;
-         _aretes[cb].nextE = _aretes[cb].prevE = -1;
-         _aretes[cb].en = -1;
-         cb = ncb;
-       }
+        {
+          int ncb = getEdge(cb).nextE;
+          _aretes[cb].nextE = _aretes[cb].prevE = -1;
+          _aretes[cb].en = -1;
+          cb = ncb;
+        }
       else
-       {
-         break;
-       }
+        {
+          break;
+        }
     }
   _pts[p].incidentEdge[FIRST] = _pts[p].incidentEdge[LAST] = -1;
   if (p < numberOfPoints() - 1)
@@ -379,60 +392,60 @@ Shape::SwapPoints (int a, int b)
     {
       int cb = getPoint(a).incidentEdge[FIRST];
       if (getEdge(cb).st == a)
-       {
-         _aretes[cb].st = numberOfPoints();
-       }
+        {
+          _aretes[cb].st = numberOfPoints();
+        }
       else if (getEdge(cb).en == a)
-       {
-         _aretes[cb].en = numberOfPoints();
-       }
+        {
+          _aretes[cb].en = numberOfPoints();
+        }
       cb = getPoint(a).incidentEdge[LAST];
       if (getEdge(cb).st == a)
-       {
-         _aretes[cb].st = numberOfPoints();
-       }
+        {
+          _aretes[cb].st = numberOfPoints();
+        }
       else if (getEdge(cb).en == a)
-       {
-         _aretes[cb].en = numberOfPoints();
-       }
+        {
+          _aretes[cb].en = numberOfPoints();
+        }
 
       cb = getPoint(b).incidentEdge[FIRST];
       if (getEdge(cb).st == b)
-       {
-         _aretes[cb].st = a;
-       }
+        {
+          _aretes[cb].st = a;
+        }
       else if (getEdge(cb).en == b)
-       {
-         _aretes[cb].en = a;
-       }
+        {
+          _aretes[cb].en = a;
+        }
       cb = getPoint(b).incidentEdge[LAST];
       if (getEdge(cb).st == b)
-       {
-         _aretes[cb].st = a;
-       }
+        {
+          _aretes[cb].st = a;
+        }
       else if (getEdge(cb).en == b)
-       {
-         _aretes[cb].en = a;
-       }
+        {
+          _aretes[cb].en = a;
+        }
 
       cb = getPoint(a).incidentEdge[FIRST];
       if (getEdge(cb).st == numberOfPoints())
-       {
-         _aretes[cb].st = b;
-       }
+        {
+          _aretes[cb].st = b;
+        }
       else if (getEdge(cb).en == numberOfPoints())
-       {
-         _aretes[cb].en = b;
-       }
+        {
+          _aretes[cb].en = b;
+        }
       cb = getPoint(a).incidentEdge[LAST];
       if (getEdge(cb).st == numberOfPoints())
-       {
-         _aretes[cb].st = b;
-       }
+        {
+          _aretes[cb].st = b;
+        }
       else if (getEdge(cb).en == numberOfPoints())
-       {
-         _aretes[cb].en = b;
-       }
+        {
+          _aretes[cb].en = b;
+        }
 
     }
   else
@@ -440,46 +453,46 @@ Shape::SwapPoints (int a, int b)
       int cb;
       cb = getPoint(a).incidentEdge[FIRST];
       while (cb >= 0)
-       {
-         int ncb = NextAt (a, cb);
-         if (getEdge(cb).st == a)
-           {
-             _aretes[cb].st = numberOfPoints();
-           }
-         else if (getEdge(cb).en == a)
-           {
-             _aretes[cb].en = numberOfPoints();
-           }
-         cb = ncb;
-       }
+        {
+          int ncb = NextAt (a, cb);
+          if (getEdge(cb).st == a)
+            {
+              _aretes[cb].st = numberOfPoints();
+            }
+          else if (getEdge(cb).en == a)
+            {
+              _aretes[cb].en = numberOfPoints();
+            }
+          cb = ncb;
+        }
       cb = getPoint(b).incidentEdge[FIRST];
       while (cb >= 0)
-       {
-         int ncb = NextAt (b, cb);
-         if (getEdge(cb).st == b)
-           {
-             _aretes[cb].st = a;
-           }
-         else if (getEdge(cb).en == b)
-           {
-             _aretes[cb].en = a;
-           }
-         cb = ncb;
-       }
+        {
+          int ncb = NextAt (b, cb);
+          if (getEdge(cb).st == b)
+            {
+              _aretes[cb].st = a;
+            }
+          else if (getEdge(cb).en == b)
+            {
+              _aretes[cb].en = a;
+            }
+          cb = ncb;
+        }
       cb = getPoint(a).incidentEdge[FIRST];
       while (cb >= 0)
-       {
-         int ncb = NextAt (numberOfPoints(), cb);
-         if (getEdge(cb).st == numberOfPoints())
-           {
-             _aretes[cb].st = b;
-           }
-         else if (getEdge(cb).en == numberOfPoints())
-           {
-             _aretes[cb].en = b;
-           }
-         cb = ncb;
-       }
+        {
+          int ncb = NextAt (numberOfPoints(), cb);
+          if (getEdge(cb).st == numberOfPoints())
+            {
+              _aretes[cb].st = b;
+            }
+          else if (getEdge(cb).en == numberOfPoints())
+            {
+              _aretes[cb].en = b;
+            }
+          cb = ncb;
+        }
     }
   {
     dg_point swap = getPoint(a);
@@ -533,8 +546,8 @@ Shape::SortPoints (int s, int e)
   if (e == s + 1)
     {
       if (getPoint(s).x[1] > getPoint(e).x[1]
-         || (getPoint(s).x[1] == getPoint(e).x[1] && getPoint(s).x[0] > getPoint(e).x[0]))
-       SwapPoints (s, e);
+          || (getPoint(s).x[1] == getPoint(e).x[1] && getPoint(s).x[0] > getPoint(e).x[0]))
+        SwapPoints (s, e);
       return;
     }
 
@@ -547,160 +560,160 @@ Shape::SortPoints (int s, int e)
   while (le < ppos || ri > plast)
     {
       if (le < ppos)
-       {
-         do
-           {
-             int test = 0;
-             if (getPoint(le).x[1] > pvaly)
-               {
-                 test = 1;
-               }
-             else if (getPoint(le).x[1] == pvaly)
-               {
-                 if (getPoint(le).x[0] > pvalx)
-                   {
-                     test = 1;
-                   }
-                 else if (getPoint(le).x[0] == pvalx)
-                   {
-                     test = 0;
-                   }
-                 else
-                   {
-                     test = -1;
-                   }
-               }
-             else
-               {
-                 test = -1;
-               }
-             if (test == 0)
-               {
-                 // on colle les valeurs egales au pivot ensemble
-                 if (le < ppos - 1)
-                   {
-                     SwapPoints (le, ppos - 1, ppos);
-                     ppos--;
-                     continue; // sans changer le
-                   }
-                 else if (le == ppos - 1)
-                   {
-                     ppos--;
-                     break;
-                   }
-                 else
-                   {
-                     // oupsie
-                     break;
-                   }
-               }
-             if (test > 0)
-               {
-                 break;
-               }
-             le++;
-           }
-         while (le < ppos);
-       }
+        {
+          do
+            {
+              int test = 0;
+              if (getPoint(le).x[1] > pvaly)
+                {
+                  test = 1;
+                }
+              else if (getPoint(le).x[1] == pvaly)
+                {
+                  if (getPoint(le).x[0] > pvalx)
+                    {
+                      test = 1;
+                    }
+                  else if (getPoint(le).x[0] == pvalx)
+                    {
+                      test = 0;
+                    }
+                  else
+                    {
+                      test = -1;
+                    }
+                }
+              else
+                {
+                  test = -1;
+                }
+              if (test == 0)
+                {
+                  // on colle les valeurs egales au pivot ensemble
+                  if (le < ppos - 1)
+                    {
+                      SwapPoints (le, ppos - 1, ppos);
+                      ppos--;
+                      continue;        // sans changer le
+                    }
+                  else if (le == ppos - 1)
+                    {
+                      ppos--;
+                      break;
+                    }
+                  else
+                    {
+                      // oupsie
+                      break;
+                    }
+                }
+              if (test > 0)
+                {
+                  break;
+                }
+              le++;
+            }
+          while (le < ppos);
+        }
       if (ri > plast)
-       {
-         do
-           {
-             int test = 0;
-             if (getPoint(ri).x[1] > pvaly)
-               {
-                 test = 1;
-               }
-             else if (getPoint(ri).x[1] == pvaly)
-               {
-                 if (getPoint(ri).x[0] > pvalx)
-                   {
-                     test = 1;
-                   }
-                 else if (getPoint(ri).x[0] == pvalx)
-                   {
-                     test = 0;
-                   }
-                 else
-                   {
-                     test = -1;
-                   }
-               }
-             else
-               {
-                 test = -1;
-               }
-             if (test == 0)
-               {
-                 // on colle les valeurs egales au pivot ensemble
-                 if (ri > plast + 1)
-                   {
-                     SwapPoints (ri, plast + 1, plast);
-                     plast++;
-                     continue; // sans changer ri
-                   }
-                 else if (ri == plast + 1)
-                   {
-                     plast++;
-                     break;
-                   }
-                 else
-                   {
-                     // oupsie
-                     break;
-                   }
-               }
-             if (test < 0)
-               {
-                 break;
-               }
-             ri--;
-           }
-         while (ri > plast);
-       }
+        {
+          do
+            {
+              int test = 0;
+              if (getPoint(ri).x[1] > pvaly)
+                {
+                  test = 1;
+                }
+              else if (getPoint(ri).x[1] == pvaly)
+                {
+                  if (getPoint(ri).x[0] > pvalx)
+                    {
+                      test = 1;
+                    }
+                  else if (getPoint(ri).x[0] == pvalx)
+                    {
+                      test = 0;
+                    }
+                  else
+                    {
+                      test = -1;
+                    }
+                }
+              else
+                {
+                  test = -1;
+                }
+              if (test == 0)
+                {
+                  // on colle les valeurs egales au pivot ensemble
+                  if (ri > plast + 1)
+                    {
+                      SwapPoints (ri, plast + 1, plast);
+                      plast++;
+                      continue;        // sans changer ri
+                    }
+                  else if (ri == plast + 1)
+                    {
+                      plast++;
+                      break;
+                    }
+                  else
+                    {
+                      // oupsie
+                      break;
+                    }
+                }
+              if (test < 0)
+                {
+                  break;
+                }
+              ri--;
+            }
+          while (ri > plast);
+        }
       if (le < ppos)
-       {
-         if (ri > plast)
-           {
-             SwapPoints (le, ri);
-             le++;
-             ri--;
-           }
-         else
-           {
-             if (le < ppos - 1)
-               {
-                 SwapPoints (ppos - 1, plast, le);
-                 ppos--;
-                 plast--;
-               }
-             else if (le == ppos - 1)
-               {
-                 SwapPoints (plast, le);
-                 ppos--;
-                 plast--;
-               }
-           }
-       }
+        {
+          if (ri > plast)
+            {
+              SwapPoints (le, ri);
+              le++;
+              ri--;
+            }
+          else
+            {
+              if (le < ppos - 1)
+                {
+                  SwapPoints (ppos - 1, plast, le);
+                  ppos--;
+                  plast--;
+                }
+              else if (le == ppos - 1)
+                {
+                  SwapPoints (plast, le);
+                  ppos--;
+                  plast--;
+                }
+            }
+        }
       else
-       {
-         if (ri > plast + 1)
-           {
-             SwapPoints (plast + 1, ppos, ri);
-             ppos++;
-             plast++;
-           }
-         else if (ri == plast + 1)
-           {
-             SwapPoints (ppos, ri);
-             ppos++;
-             plast++;
-           }
-         else
-           {
-             break;
-           }
-       }
+        {
+          if (ri > plast + 1)
+            {
+              SwapPoints (plast + 1, ppos, ri);
+              ppos++;
+              plast++;
+            }
+          else if (ri == plast + 1)
+            {
+              SwapPoints (ppos, ri);
+              ppos++;
+              plast++;
+            }
+          else
+            {
+              break;
+            }
+        }
     }
   SortPoints (s, ppos - 1);
   SortPoints (plast + 1, e);
@@ -714,9 +727,9 @@ Shape::SortPointsByOldInd (int s, int e)
   if (e == s + 1)
     {
       if (getPoint(s).x[1] > getPoint(e).x[1] || (getPoint(s).x[1] == getPoint(e).x[1] && getPoint(s).x[0] > getPoint(e).x[0])
-         || (getPoint(s).x[1] == getPoint(e).x[1] && getPoint(s).x[0] == getPoint(e).x[0]
-             && pData[s].oldInd > pData[e].oldInd))
-       SwapPoints (s, e);
+          || (getPoint(s).x[1] == getPoint(e).x[1] && getPoint(s).x[0] == getPoint(e).x[0]
+              && pData[s].oldInd > pData[e].oldInd))
+        SwapPoints (s, e);
       return;
     }
 
@@ -730,182 +743,182 @@ Shape::SortPointsByOldInd (int s, int e)
   while (le < ppos || ri > plast)
     {
       if (le < ppos)
-       {
-         do
-           {
-             int test = 0;
-             if (getPoint(le).x[1] > pvaly)
-               {
-                 test = 1;
-               }
-             else if (getPoint(le).x[1] == pvaly)
-               {
-                 if (getPoint(le).x[0] > pvalx)
-                   {
-                     test = 1;
-                   }
-                 else if (getPoint(le).x[0] == pvalx)
-                   {
-                     if (pData[le].oldInd > pvali)
-                       {
-                         test = 1;
-                       }
-                     else if (pData[le].oldInd == pvali)
-                       {
-                         test = 0;
-                       }
-                     else
-                       {
-                         test = -1;
-                       }
-                   }
-                 else
-                   {
-                     test = -1;
-                   }
-               }
-             else
-               {
-                 test = -1;
-               }
-             if (test == 0)
-               {
-                 // on colle les valeurs egales au pivot ensemble
-                 if (le < ppos - 1)
-                   {
-                     SwapPoints (le, ppos - 1, ppos);
-                     ppos--;
-                     continue; // sans changer le
-                   }
-                 else if (le == ppos - 1)
-                   {
-                     ppos--;
-                     break;
-                   }
-                 else
-                   {
-                     // oupsie
-                     break;
-                   }
-               }
-             if (test > 0)
-               {
-                 break;
-               }
-             le++;
-           }
-         while (le < ppos);
-       }
+        {
+          do
+            {
+              int test = 0;
+              if (getPoint(le).x[1] > pvaly)
+                {
+                  test = 1;
+                }
+              else if (getPoint(le).x[1] == pvaly)
+                {
+                  if (getPoint(le).x[0] > pvalx)
+                    {
+                      test = 1;
+                    }
+                  else if (getPoint(le).x[0] == pvalx)
+                    {
+                      if (pData[le].oldInd > pvali)
+                        {
+                          test = 1;
+                        }
+                      else if (pData[le].oldInd == pvali)
+                        {
+                          test = 0;
+                        }
+                      else
+                        {
+                          test = -1;
+                        }
+                    }
+                  else
+                    {
+                      test = -1;
+                    }
+                }
+              else
+                {
+                  test = -1;
+                }
+              if (test == 0)
+                {
+                  // on colle les valeurs egales au pivot ensemble
+                  if (le < ppos - 1)
+                    {
+                      SwapPoints (le, ppos - 1, ppos);
+                      ppos--;
+                      continue;        // sans changer le
+                    }
+                  else if (le == ppos - 1)
+                    {
+                      ppos--;
+                      break;
+                    }
+                  else
+                    {
+                      // oupsie
+                      break;
+                    }
+                }
+              if (test > 0)
+                {
+                  break;
+                }
+              le++;
+            }
+          while (le < ppos);
+        }
       if (ri > plast)
-       {
-         do
-           {
-             int test = 0;
-             if (getPoint(ri).x[1] > pvaly)
-               {
-                 test = 1;
-               }
-             else if (getPoint(ri).x[1] == pvaly)
-               {
-                 if (getPoint(ri).x[0] > pvalx)
-                   {
-                     test = 1;
-                   }
-                 else if (getPoint(ri).x[0] == pvalx)
-                   {
-                     if (pData[ri].oldInd > pvali)
-                       {
-                         test = 1;
-                       }
-                     else if (pData[ri].oldInd == pvali)
-                       {
-                         test = 0;
-                       }
-                     else
-                       {
-                         test = -1;
-                       }
-                   }
-                 else
-                   {
-                     test = -1;
-                   }
-               }
-             else
-               {
-                 test = -1;
-               }
-             if (test == 0)
-               {
-                 // on colle les valeurs egales au pivot ensemble
-                 if (ri > plast + 1)
-                   {
-                     SwapPoints (ri, plast + 1, plast);
-                     plast++;
-                     continue; // sans changer ri
-                   }
-                 else if (ri == plast + 1)
-                   {
-                     plast++;
-                     break;
-                   }
-                 else
-                   {
-                     // oupsie
-                     break;
-                   }
-               }
-             if (test < 0)
-               {
-                 break;
-               }
-             ri--;
-           }
-         while (ri > plast);
-       }
+        {
+          do
+            {
+              int test = 0;
+              if (getPoint(ri).x[1] > pvaly)
+                {
+                  test = 1;
+                }
+              else if (getPoint(ri).x[1] == pvaly)
+                {
+                  if (getPoint(ri).x[0] > pvalx)
+                    {
+                      test = 1;
+                    }
+                  else if (getPoint(ri).x[0] == pvalx)
+                    {
+                      if (pData[ri].oldInd > pvali)
+                        {
+                          test = 1;
+                        }
+                      else if (pData[ri].oldInd == pvali)
+                        {
+                          test = 0;
+                        }
+                      else
+                        {
+                          test = -1;
+                        }
+                    }
+                  else
+                    {
+                      test = -1;
+                    }
+                }
+              else
+                {
+                  test = -1;
+                }
+              if (test == 0)
+                {
+                  // on colle les valeurs egales au pivot ensemble
+                  if (ri > plast + 1)
+                    {
+                      SwapPoints (ri, plast + 1, plast);
+                      plast++;
+                      continue;        // sans changer ri
+                    }
+                  else if (ri == plast + 1)
+                    {
+                      plast++;
+                      break;
+                    }
+                  else
+                    {
+                      // oupsie
+                      break;
+                    }
+                }
+              if (test < 0)
+                {
+                  break;
+                }
+              ri--;
+            }
+          while (ri > plast);
+        }
       if (le < ppos)
-       {
-         if (ri > plast)
-           {
-             SwapPoints (le, ri);
-             le++;
-             ri--;
-           }
-         else
-           {
-             if (le < ppos - 1)
-               {
-                 SwapPoints (ppos - 1, plast, le);
-                 ppos--;
-                 plast--;
-               }
-             else if (le == ppos - 1)
-               {
-                 SwapPoints (plast, le);
-                 ppos--;
-                 plast--;
-               }
-           }
-       }
+        {
+          if (ri > plast)
+            {
+              SwapPoints (le, ri);
+              le++;
+              ri--;
+            }
+          else
+            {
+              if (le < ppos - 1)
+                {
+                  SwapPoints (ppos - 1, plast, le);
+                  ppos--;
+                  plast--;
+                }
+              else if (le == ppos - 1)
+                {
+                  SwapPoints (plast, le);
+                  ppos--;
+                  plast--;
+                }
+            }
+        }
       else
-       {
-         if (ri > plast + 1)
-           {
-             SwapPoints (plast + 1, ppos, ri);
-             ppos++;
-             plast++;
-           }
-         else if (ri == plast + 1)
-           {
-             SwapPoints (ppos, ri);
-             ppos++;
-             plast++;
-           }
-         else
-           {
-             break;
-           }
-       }
+        {
+          if (ri > plast + 1)
+            {
+              SwapPoints (plast + 1, ppos, ri);
+              ppos++;
+              plast++;
+            }
+          else if (ri == plast + 1)
+            {
+              SwapPoints (ppos, ri);
+              ppos++;
+              plast++;
+            }
+          else
+            {
+              break;
+            }
+        }
     }
   SortPointsByOldInd (s, ppos - 1);
   SortPointsByOldInd (plast + 1, e);
@@ -919,8 +932,8 @@ Shape::SortPointsRounded (int s, int e)
   if (e == s + 1)
     {
       if (pData[s].rx[1] > pData[e].rx[1]
-         || (pData[s].rx[1] == pData[e].rx[1] && pData[s].rx[0] > pData[e].rx[0]))
-       SwapPoints (s, e);
+          || (pData[s].rx[1] == pData[e].rx[1] && pData[s].rx[0] > pData[e].rx[0]))
+        SwapPoints (s, e);
       return;
     }
 
@@ -933,160 +946,160 @@ Shape::SortPointsRounded (int s, int e)
   while (le < ppos || ri > plast)
     {
       if (le < ppos)
-       {
-         do
-           {
-             int test = 0;
-             if (pData[le].rx[1] > pvaly)
-               {
-                 test = 1;
-               }
-             else if (pData[le].rx[1] == pvaly)
-               {
-                 if (pData[le].rx[0] > pvalx)
-                   {
-                     test = 1;
-                   }
-                 else if (pData[le].rx[0] == pvalx)
-                   {
-                     test = 0;
-                   }
-                 else
-                   {
-                     test = -1;
-                   }
-               }
-             else
-               {
-                 test = -1;
-               }
-             if (test == 0)
-               {
-                 // on colle les valeurs egales au pivot ensemble
-                 if (le < ppos - 1)
-                   {
-                     SwapPoints (le, ppos - 1, ppos);
-                     ppos--;
-                     continue; // sans changer le
-                   }
-                 else if (le == ppos - 1)
-                   {
-                     ppos--;
-                     break;
-                   }
-                 else
-                   {
-                     // oupsie
-                     break;
-                   }
-               }
-             if (test > 0)
-               {
-                 break;
-               }
-             le++;
-           }
-         while (le < ppos);
-       }
+        {
+          do
+            {
+              int test = 0;
+              if (pData[le].rx[1] > pvaly)
+                {
+                  test = 1;
+                }
+              else if (pData[le].rx[1] == pvaly)
+                {
+                  if (pData[le].rx[0] > pvalx)
+                    {
+                      test = 1;
+                    }
+                  else if (pData[le].rx[0] == pvalx)
+                    {
+                      test = 0;
+                    }
+                  else
+                    {
+                      test = -1;
+                    }
+                }
+              else
+                {
+                  test = -1;
+                }
+              if (test == 0)
+                {
+                  // on colle les valeurs egales au pivot ensemble
+                  if (le < ppos - 1)
+                    {
+                      SwapPoints (le, ppos - 1, ppos);
+                      ppos--;
+                      continue;        // sans changer le
+                    }
+                  else if (le == ppos - 1)
+                    {
+                      ppos--;
+                      break;
+                    }
+                  else
+                    {
+                      // oupsie
+                      break;
+                    }
+                }
+              if (test > 0)
+                {
+                  break;
+                }
+              le++;
+            }
+          while (le < ppos);
+        }
       if (ri > plast)
-       {
-         do
-           {
-             int test = 0;
-             if (pData[ri].rx[1] > pvaly)
-               {
-                 test = 1;
-               }
-             else if (pData[ri].rx[1] == pvaly)
-               {
-                 if (pData[ri].rx[0] > pvalx)
-                   {
-                     test = 1;
-                   }
-                 else if (pData[ri].rx[0] == pvalx)
-                   {
-                     test = 0;
-                   }
-                 else
-                   {
-                     test = -1;
-                   }
-               }
-             else
-               {
-                 test = -1;
-               }
-             if (test == 0)
-               {
-                 // on colle les valeurs egales au pivot ensemble
-                 if (ri > plast + 1)
-                   {
-                     SwapPoints (ri, plast + 1, plast);
-                     plast++;
-                     continue; // sans changer ri
-                   }
-                 else if (ri == plast + 1)
-                   {
-                     plast++;
-                     break;
-                   }
-                 else
-                   {
-                     // oupsie
-                     break;
-                   }
-               }
-             if (test < 0)
-               {
-                 break;
-               }
-             ri--;
-           }
-         while (ri > plast);
-       }
+        {
+          do
+            {
+              int test = 0;
+              if (pData[ri].rx[1] > pvaly)
+                {
+                  test = 1;
+                }
+              else if (pData[ri].rx[1] == pvaly)
+                {
+                  if (pData[ri].rx[0] > pvalx)
+                    {
+                      test = 1;
+                    }
+                  else if (pData[ri].rx[0] == pvalx)
+                    {
+                      test = 0;
+                    }
+                  else
+                    {
+                      test = -1;
+                    }
+                }
+              else
+                {
+                  test = -1;
+                }
+              if (test == 0)
+                {
+                  // on colle les valeurs egales au pivot ensemble
+                  if (ri > plast + 1)
+                    {
+                      SwapPoints (ri, plast + 1, plast);
+                      plast++;
+                      continue;        // sans changer ri
+                    }
+                  else if (ri == plast + 1)
+                    {
+                      plast++;
+                      break;
+                    }
+                  else
+                    {
+                      // oupsie
+                      break;
+                    }
+                }
+              if (test < 0)
+                {
+                  break;
+                }
+              ri--;
+            }
+          while (ri > plast);
+        }
       if (le < ppos)
-       {
-         if (ri > plast)
-           {
-             SwapPoints (le, ri);
-             le++;
-             ri--;
-           }
-         else
-           {
-             if (le < ppos - 1)
-               {
-                 SwapPoints (ppos - 1, plast, le);
-                 ppos--;
-                 plast--;
-               }
-             else if (le == ppos - 1)
-               {
-                 SwapPoints (plast, le);
-                 ppos--;
-                 plast--;
-               }
-           }
-       }
+        {
+          if (ri > plast)
+            {
+              SwapPoints (le, ri);
+              le++;
+              ri--;
+            }
+          else
+            {
+              if (le < ppos - 1)
+                {
+                  SwapPoints (ppos - 1, plast, le);
+                  ppos--;
+                  plast--;
+                }
+              else if (le == ppos - 1)
+                {
+                  SwapPoints (plast, le);
+                  ppos--;
+                  plast--;
+                }
+            }
+        }
       else
-       {
-         if (ri > plast + 1)
-           {
-             SwapPoints (plast + 1, ppos, ri);
-             ppos++;
-             plast++;
-           }
-         else if (ri == plast + 1)
-           {
-             SwapPoints (ppos, ri);
-             ppos++;
-             plast++;
-           }
-         else
-           {
-             break;
-           }
-       }
+        {
+          if (ri > plast + 1)
+            {
+              SwapPoints (plast + 1, ppos, ri);
+              ppos++;
+              plast++;
+            }
+          else if (ri == plast + 1)
+            {
+              SwapPoints (ppos, ri);
+              ppos++;
+              plast++;
+            }
+          else
+            {
+              break;
+            }
+        }
     }
   SortPointsRounded (s, ppos - 1);
   SortPointsRounded (plast + 1, e);
@@ -1107,17 +1120,17 @@ Shape::AddEdge (int st, int en)
     {
       maxAr = 2 * numberOfEdges() + 1;
       if (_has_edges_data)
-       eData.resize(maxAr);
+        eData.resize(maxAr);
       if (_has_sweep_src_data)
-       swsData.resize(maxAr);
+        swsData.resize(maxAr);
       if (_has_sweep_dest_data)
-       swdData.resize(maxAr);
+        swdData.resize(maxAr);
       if (_has_raster_data)
-       swrData.resize(maxAr);
+        swrData.resize(maxAr);
       if (_has_back_data)
-       ebData.resize(maxAr);
+        ebData.resize(maxAr);
       if (_has_voronoi_data)
-       voreData.resize(maxAr);
+        voreData.resize(maxAr);
     }
 
   dg_arete a;
@@ -1170,11 +1183,11 @@ Shape::AddEdge (int st, int en, int leF, int riF)
     int cb = getPoint(st).incidentEdge[FIRST];
     while (cb >= 0)
       {
-       if (getEdge(cb).st == st && getEdge(cb).en == en)
-         return -1;            // doublon
-       if (getEdge(cb).st == en && getEdge(cb).en == st)
-         return -1;            // doublon
-       cb = NextAt (st, cb);
+        if (getEdge(cb).st == st && getEdge(cb).en == en)
+          return -1;           // doublon
+        if (getEdge(cb).st == en && getEdge(cb).en == st)
+          return -1;           // doublon
+        cb = NextAt (st, cb);
       }
   }
   type = shape_graph;
@@ -1182,17 +1195,17 @@ Shape::AddEdge (int st, int en, int leF, int riF)
     {
       maxAr = 2 * numberOfEdges() + 1;
       if (_has_edges_data)
-       eData.resize(maxAr);
+        eData.resize(maxAr);
       if (_has_sweep_src_data)
-       swsData.resize(maxAr);
+        swsData.resize(maxAr);
       if (_has_sweep_dest_data)
-       swdData.resize(maxAr);
+        swdData.resize(maxAr);
       if (_has_raster_data)
-       swrData.resize(maxAr);
+        swrData.resize(maxAr);
       if (_has_back_data)
-       ebData.resize(maxAr);
+        ebData.resize(maxAr);
       if (_has_voronoi_data)
-       voreData.resize(maxAr);
+        voreData.resize(maxAr);
     }
 
   dg_arete a;
@@ -1256,106 +1269,106 @@ Shape::SwapEdges (int a, int b)
   if (getEdge(a).prevS >= 0 && getEdge(a).prevS != b)
     {
       if (getEdge(getEdge(a).prevS).st == getEdge(a).st)
-       {
-         _aretes[getEdge(a).prevS].nextS = b;
-       }
+        {
+          _aretes[getEdge(a).prevS].nextS = b;
+        }
       else if (getEdge(getEdge(a).prevS).en == getEdge(a).st)
-       {
-         _aretes[getEdge(a).prevS].nextE = b;
-       }
+        {
+          _aretes[getEdge(a).prevS].nextE = b;
+        }
     }
   if (getEdge(a).nextS >= 0 && getEdge(a).nextS != b)
     {
       if (getEdge(getEdge(a).nextS).st == getEdge(a).st)
-       {
-         _aretes[getEdge(a).nextS].prevS = b;
-       }
+        {
+          _aretes[getEdge(a).nextS].prevS = b;
+        }
       else if (getEdge(getEdge(a).nextS).en == getEdge(a).st)
-       {
-         _aretes[getEdge(a).nextS].prevE = b;
-       }
+        {
+          _aretes[getEdge(a).nextS].prevE = b;
+        }
     }
   if (getEdge(a).prevE >= 0 && getEdge(a).prevE != b)
     {
       if (getEdge(getEdge(a).prevE).st == getEdge(a).en)
-       {
-         _aretes[getEdge(a).prevE].nextS = b;
-       }
+        {
+          _aretes[getEdge(a).prevE].nextS = b;
+        }
       else if (getEdge(getEdge(a).prevE).en == getEdge(a).en)
-       {
-         _aretes[getEdge(a).prevE].nextE = b;
-       }
+        {
+          _aretes[getEdge(a).prevE].nextE = b;
+        }
     }
   if (getEdge(a).nextE >= 0 && getEdge(a).nextE != b)
     {
       if (getEdge(getEdge(a).nextE).st == getEdge(a).en)
-       {
-         _aretes[getEdge(a).nextE].prevS = b;
-       }
+        {
+          _aretes[getEdge(a).nextE].prevS = b;
+        }
       else if (getEdge(getEdge(a).nextE).en == getEdge(a).en)
-       {
-         _aretes[getEdge(a).nextE].prevE = b;
-       }
+        {
+          _aretes[getEdge(a).nextE].prevE = b;
+        }
     }
   if (getEdge(a).st >= 0)
     {
       if (getPoint(getEdge(a).st).incidentEdge[FIRST] == a)
-       _pts[getEdge(a).st].incidentEdge[FIRST] = numberOfEdges();
+        _pts[getEdge(a).st].incidentEdge[FIRST] = numberOfEdges();
       if (getPoint(getEdge(a).st).incidentEdge[LAST] == a)
-       _pts[getEdge(a).st].incidentEdge[LAST] = numberOfEdges();
+        _pts[getEdge(a).st].incidentEdge[LAST] = numberOfEdges();
     }
   if (getEdge(a).en >= 0)
     {
       if (getPoint(getEdge(a).en).incidentEdge[FIRST] == a)
-       _pts[getEdge(a).en].incidentEdge[FIRST] = numberOfEdges();
+        _pts[getEdge(a).en].incidentEdge[FIRST] = numberOfEdges();
       if (getPoint(getEdge(a).en).incidentEdge[LAST] == a)
-       _pts[getEdge(a).en].incidentEdge[LAST] = numberOfEdges();
+        _pts[getEdge(a).en].incidentEdge[LAST] = numberOfEdges();
     }
 
 
   if (getEdge(b).prevS >= 0 && getEdge(b).prevS != a)
     {
       if (getEdge(getEdge(b).prevS).st == getEdge(b).st)
-       {
-         _aretes[getEdge(b).prevS].nextS = a;
-       }
+        {
+          _aretes[getEdge(b).prevS].nextS = a;
+        }
       else if (getEdge(getEdge(b).prevS).en == getEdge(b).st)
-       {
-         _aretes[getEdge(b).prevS].nextE = a;
-       }
+        {
+          _aretes[getEdge(b).prevS].nextE = a;
+        }
     }
   if (getEdge(b).nextS >= 0 && getEdge(b).nextS != a)
     {
       if (getEdge(getEdge(b).nextS).st == getEdge(b).st)
-       {
-         _aretes[getEdge(b).nextS].prevS = a;
-       }
+        {
+          _aretes[getEdge(b).nextS].prevS = a;
+        }
       else if (getEdge(getEdge(b).nextS).en == getEdge(b).st)
-       {
-         _aretes[getEdge(b).nextS].prevE = a;
-       }
+        {
+          _aretes[getEdge(b).nextS].prevE = a;
+        }
     }
   if (getEdge(b).prevE >= 0 && getEdge(b).prevE != a)
     {
       if (getEdge(getEdge(b).prevE).st == getEdge(b).en)
-       {
-         _aretes[getEdge(b).prevE].nextS = a;
-       }
+        {
+          _aretes[getEdge(b).prevE].nextS = a;
+        }
       else if (getEdge(getEdge(b).prevE).en == getEdge(b).en)
-       {
-         _aretes[getEdge(b).prevE].nextE = a;
-       }
+        {
+          _aretes[getEdge(b).prevE].nextE = a;
+        }
     }
   if (getEdge(b).nextE >= 0 && getEdge(b).nextE != a)
     {
       if (getEdge(getEdge(b).nextE).st == getEdge(b).en)
-       {
-         _aretes[getEdge(b).nextE].prevS = a;
-       }
+        {
+          _aretes[getEdge(b).nextE].prevS = a;
+        }
       else if (getEdge(getEdge(b).nextE).en == getEdge(b).en)
-       {
-         _aretes[getEdge(b).nextE].prevE = a;
-       }
+        {
+          _aretes[getEdge(b).nextE].prevE = a;
+        }
     }
 
   
@@ -1363,28 +1376,28 @@ Shape::SwapEdges (int a, int b)
     int p = getEdge(b).st;
     if (p >= 0) {
       if (getPoint(p).incidentEdge[i] == b) {
-       _pts[p].incidentEdge[i] = a;
+        _pts[p].incidentEdge[i] = a;
       }
     }
 
     p = getEdge(b).en;
     if (p >= 0) {
       if (getPoint(p).incidentEdge[i] == b) {
-       _pts[p].incidentEdge[i] = a;
+        _pts[p].incidentEdge[i] = a;
       }
     }
 
     p = getEdge(a).st;
     if (p >= 0) {
       if (getPoint(p).incidentEdge[i] == numberOfEdges()) {
-       _pts[p].incidentEdge[i] = b;
+        _pts[p].incidentEdge[i] = b;
       }
     }
 
     p = getEdge(a).en;
     if (p >= 0) {
       if (getPoint(p).incidentEdge[i] == numberOfEdges()) {
-       _pts[p].incidentEdge[i] = b;
+        _pts[p].incidentEdge[i] = b;
       }
     }
 
@@ -1469,71 +1482,71 @@ Shape::SortEdges (void)
     {
       int const d = getPoint(p).totalDegree();
       if (d > 1)
-       {
-         int cb;
-         cb = getPoint(p).incidentEdge[FIRST];
-         int nb = 0;
-         while (cb >= 0)
-           {
-             int n = nb++;
-             list[n].no = cb;
-             if (getEdge(cb).st == p)
-               {
-                 list[n].x = getEdge(cb).dx;
-                 list[n].starting = true;
-               }
-             else
-               {
-                 list[n].x = -getEdge(cb).dx;
-                 list[n].starting = false;
-               }
-             cb = NextAt (p, cb);
-           }
-         SortEdgesList (list, 0, nb - 1);
-         _pts[p].incidentEdge[FIRST] = list[0].no;
-         _pts[p].incidentEdge[LAST] = list[nb - 1].no;
-         for (int i = 0; i < nb; i++)
-           {
-             if (list[i].starting)
-               {
-                 if (i > 0)
-                   {
-                     _aretes[list[i].no].prevS = list[i - 1].no;
-                   }
-                 else
-                   {
-                     _aretes[list[i].no].prevS = -1;
-                   }
-                 if (i < nb - 1)
-                   {
-                     _aretes[list[i].no].nextS = list[i + 1].no;
-                   }
-                 else
-                   {
-                     _aretes[list[i].no].nextS = -1;
-                   }
-               }
-             else
-               {
-                 if (i > 0)
-                   {
-                     _aretes[list[i].no].prevE = list[i - 1].no;
-                   }
-                 else
-                   {
-                     _aretes[list[i].no].prevE = -1;
-                   }
-                 if (i < nb - 1)
-                   {
-                     _aretes[list[i].no].nextE = list[i + 1].no;
-                   }
-                 else
-                   {
-                     _aretes[list[i].no].nextE = -1;
-                   }
-               }
-           }
-       }
+        {
+          int cb;
+          cb = getPoint(p).incidentEdge[FIRST];
+          int nb = 0;
+          while (cb >= 0)
+            {
+              int n = nb++;
+              list[n].no = cb;
+              if (getEdge(cb).st == p)
+                {
+                  list[n].x = getEdge(cb).dx;
+                  list[n].starting = true;
+                }
+              else
+                {
+                  list[n].x = -getEdge(cb).dx;
+                  list[n].starting = false;
+                }
+              cb = NextAt (p, cb);
+            }
+          SortEdgesList (list, 0, nb - 1);
+          _pts[p].incidentEdge[FIRST] = list[0].no;
+          _pts[p].incidentEdge[LAST] = list[nb - 1].no;
+          for (int i = 0; i < nb; i++)
+            {
+              if (list[i].starting)
+                {
+                  if (i > 0)
+                    {
+                      _aretes[list[i].no].prevS = list[i - 1].no;
+                    }
+                  else
+                    {
+                      _aretes[list[i].no].prevS = -1;
+                    }
+                  if (i < nb - 1)
+                    {
+                      _aretes[list[i].no].nextS = list[i + 1].no;
+                    }
+                  else
+                    {
+                      _aretes[list[i].no].nextS = -1;
+                    }
+                }
+              else
+                {
+                  if (i > 0)
+                    {
+                      _aretes[list[i].no].prevE = list[i - 1].no;
+                    }
+                  else
+                    {
+                      _aretes[list[i].no].prevE = -1;
+                    }
+                  if (i < nb - 1)
+                    {
+                      _aretes[list[i].no].nextE = list[i + 1].no;
+                    }
+                  else
+                    {
+                      _aretes[list[i].no].nextE = -1;
+                    }
+                }
+            }
+        }
     }
   g_free(list);
 }
@@ -1566,92 +1579,92 @@ Shape::CmpToVert (NR::Point ax, NR::Point bx,bool as,bool bs)
   if (tstAX < 0)
     {
       if (tstAY < 0)
-       {
-         quadA = 7;
-       }
+        {
+          quadA = 7;
+        }
       else if (tstAY == 0)
-       {
-         quadA = 6;
-       }
+        {
+          quadA = 6;
+        }
       else if (tstAY > 0)
-       {
-         quadA = 5;
-       }
+        {
+          quadA = 5;
+        }
     }
   else if (tstAX == 0)
     {
       if (tstAY < 0)
-       {
-         quadA = 0;
-       }
+        {
+          quadA = 0;
+        }
       else if (tstAY == 0)
-       {
-         quadA = -1;
-       }
+        {
+          quadA = -1;
+        }
       else if (tstAY > 0)
-       {
-         quadA = 4;
-       }
+        {
+          quadA = 4;
+        }
     }
   else if (tstAX > 0)
     {
       if (tstAY < 0)
-       {
-         quadA = 1;
-       }
+        {
+          quadA = 1;
+        }
       else if (tstAY == 0)
-       {
-         quadA = 2;
-       }
+        {
+          quadA = 2;
+        }
       else if (tstAY > 0)
-       {
-         quadA = 3;
-       }
+        {
+          quadA = 3;
+        }
     }
   if (tstBX < 0)
     {
       if (tstBY < 0)
-       {
-         quadB = 7;
-       }
+        {
+          quadB = 7;
+        }
       else if (tstBY == 0)
-       {
-         quadB = 6;
-       }
+        {
+          quadB = 6;
+        }
       else if (tstBY > 0)
-       {
-         quadB = 5;
-       }
+        {
+          quadB = 5;
+        }
     }
   else if (tstBX == 0)
     {
       if (tstBY < 0)
-       {
-         quadB = 0;
-       }
+        {
+          quadB = 0;
+        }
       else if (tstBY == 0)
-       {
-         quadB = -1;
-       }
+        {
+          quadB = -1;
+        }
       else if (tstBY > 0)
-       {
-         quadB = 4;
-       }
+        {
+          quadB = 4;
+        }
     }
   else if (tstBX > 0)
     {
       if (tstBY < 0)
-       {
-         quadB = 1;
-       }
+        {
+          quadB = 1;
+        }
       else if (tstBY == 0)
-       {
-         quadB = 2;
-       }
+        {
+          quadB = 2;
+        }
       else if (tstBY > 0)
-       {
-         quadB = 3;
-       }
+        {
+          quadB = 3;
+        }
     }
   if (quadA < quadB)
     return 1;
@@ -1696,134 +1709,134 @@ Shape::SortEdgesList (edge_list * list, int s, int e)
   while (le < ppos || ri > plast)
     {
       if (le < ppos)
-       {
-         do
-           {
+        {
+          do
+            {
         int test = CmpToVert (pvalx, list[le].x,pvals,list[le].starting);
-             if (test == 0)
-               {
-                 // on colle les valeurs egales au pivot ensemble
-                 if (le < ppos - 1)
-                   {
-                     edge_list swap = list[le];
-                     list[le] = list[ppos - 1];
-                     list[ppos - 1] = list[ppos];
-                     list[ppos] = swap;
-                     ppos--;
-                     continue; // sans changer le
-                   }
-                 else if (le == ppos - 1)
-                   {
-                     ppos--;
-                     break;
-                   }
-                 else
-                   {
-                     // oupsie
-                     break;
-                   }
-               }
-             if (test > 0)
-               {
-                 break;
-               }
-             le++;
-           }
-         while (le < ppos);
-       }
+              if (test == 0)
+                {
+                  // on colle les valeurs egales au pivot ensemble
+                  if (le < ppos - 1)
+                    {
+                      edge_list swap = list[le];
+                      list[le] = list[ppos - 1];
+                      list[ppos - 1] = list[ppos];
+                      list[ppos] = swap;
+                      ppos--;
+                      continue;        // sans changer le
+                    }
+                  else if (le == ppos - 1)
+                    {
+                      ppos--;
+                      break;
+                    }
+                  else
+                    {
+                      // oupsie
+                      break;
+                    }
+                }
+              if (test > 0)
+                {
+                  break;
+                }
+              le++;
+            }
+          while (le < ppos);
+        }
       if (ri > plast)
-       {
-         do
-           {
+        {
+          do
+            {
         int test = CmpToVert (pvalx, list[ri].x,pvals,list[ri].starting);
-             if (test == 0)
-               {
-                 // on colle les valeurs egales au pivot ensemble
-                 if (ri > plast + 1)
-                   {
-                     edge_list swap = list[ri];
-                     list[ri] = list[plast + 1];
-                     list[plast + 1] = list[plast];
-                     list[plast] = swap;
-                     plast++;
-                     continue; // sans changer ri
-                   }
-                 else if (ri == plast + 1)
-                   {
-                     plast++;
-                     break;
-                   }
-                 else
-                   {
-                     // oupsie
-                     break;
-                   }
-               }
-             if (test < 0)
-               {
-                 break;
-               }
-             ri--;
-           }
-         while (ri > plast);
-       }
+              if (test == 0)
+                {
+                  // on colle les valeurs egales au pivot ensemble
+                  if (ri > plast + 1)
+                    {
+                      edge_list swap = list[ri];
+                      list[ri] = list[plast + 1];
+                      list[plast + 1] = list[plast];
+                      list[plast] = swap;
+                      plast++;
+                      continue;        // sans changer ri
+                    }
+                  else if (ri == plast + 1)
+                    {
+                      plast++;
+                      break;
+                    }
+                  else
+                    {
+                      // oupsie
+                      break;
+                    }
+                }
+              if (test < 0)
+                {
+                  break;
+                }
+              ri--;
+            }
+          while (ri > plast);
+        }
 
       if (le < ppos)
-       {
-         if (ri > plast)
-           {
-             edge_list swap = list[le];
-             list[le] = list[ri];
-             list[ri] = swap;
-             le++;
-             ri--;
-           }
-         else if (le < ppos - 1)
-           {
-             edge_list swap = list[ppos - 1];
-             list[ppos - 1] = list[plast];
-             list[plast] = list[le];
-             list[le] = swap;
-             ppos--;
-             plast--;
-           }
-         else if (le == ppos - 1)
-           {
-             edge_list swap = list[plast];
-             list[plast] = list[le];
-             list[le] = swap;
-             ppos--;
-             plast--;
-           }
-         else
-           {
-             break;
-           }
-       }
+        {
+          if (ri > plast)
+            {
+              edge_list swap = list[le];
+              list[le] = list[ri];
+              list[ri] = swap;
+              le++;
+              ri--;
+            }
+          else if (le < ppos - 1)
+            {
+              edge_list swap = list[ppos - 1];
+              list[ppos - 1] = list[plast];
+              list[plast] = list[le];
+              list[le] = swap;
+              ppos--;
+              plast--;
+            }
+          else if (le == ppos - 1)
+            {
+              edge_list swap = list[plast];
+              list[plast] = list[le];
+              list[le] = swap;
+              ppos--;
+              plast--;
+            }
+          else
+            {
+              break;
+            }
+        }
       else
-       {
-         if (ri > plast + 1)
-           {
-             edge_list swap = list[plast + 1];
-             list[plast + 1] = list[ppos];
-             list[ppos] = list[ri];
-             list[ri] = swap;
-             ppos++;
-             plast++;
-           }
-         else if (ri == plast + 1)
-           {
-             edge_list swap = list[ppos];
-             list[ppos] = list[ri];
-             list[ri] = swap;
-             ppos++;
-             plast++;
-           }
-         else
-           {
-             break;
-           }
-       }
+        {
+          if (ri > plast + 1)
+            {
+              edge_list swap = list[plast + 1];
+              list[plast + 1] = list[ppos];
+              list[ppos] = list[ri];
+              list[ri] = swap;
+              ppos++;
+              plast++;
+            }
+          else if (ri == plast + 1)
+            {
+              edge_list swap = list[ppos];
+              list[ppos] = list[ri];
+              list[ri] = swap;
+              ppos++;
+              plast++;
+            }
+          else
+            {
+              break;
+            }
+        }
     }
   SortEdgesList (list, s, ppos - 1);
   SortEdgesList (list, plast + 1, e);
@@ -1848,13 +1861,13 @@ Shape::ConnectStart (int p, int b)
   if (getPoint(p).incidentEdge[LAST] >= 0)
     {
       if (getEdge(getPoint(p).incidentEdge[LAST]).st == p)
-       {
-         _aretes[getPoint(p).incidentEdge[LAST]].nextS = b;
-       }
+        {
+          _aretes[getPoint(p).incidentEdge[LAST]].nextS = b;
+        }
       else if (getEdge(getPoint(p).incidentEdge[LAST]).en == p)
-       {
-         _aretes[getPoint(p).incidentEdge[LAST]].nextE = b;
-       }
+        {
+          _aretes[getPoint(p).incidentEdge[LAST]].nextE = b;
+        }
     }
   _pts[p].incidentEdge[LAST] = b;
   if (getPoint(p).incidentEdge[FIRST] < 0)
@@ -1873,13 +1886,13 @@ Shape::ConnectEnd (int p, int b)
   if (getPoint(p).incidentEdge[LAST] >= 0)
     {
       if (getEdge(getPoint(p).incidentEdge[LAST]).st == p)
-       {
-         _aretes[getPoint(p).incidentEdge[LAST]].nextS = b;
-       }
+        {
+          _aretes[getPoint(p).incidentEdge[LAST]].nextS = b;
+        }
       else if (getEdge(getPoint(p).incidentEdge[LAST]).en == p)
-       {
-         _aretes[getPoint(p).incidentEdge[LAST]].nextE = b;
-       }
+        {
+          _aretes[getPoint(p).incidentEdge[LAST]].nextE = b;
+        }
     }
   _pts[p].incidentEdge[LAST] = b;
   if (getPoint(p).incidentEdge[FIRST] < 0)
@@ -1895,24 +1908,24 @@ Shape::DisconnectStart (int b)
   if (getEdge(b).prevS >= 0)
     {
       if (getEdge(getEdge(b).prevS).st == getEdge(b).st)
-       {
-         _aretes[getEdge(b).prevS].nextS = getEdge(b).nextS;
-       }
+        {
+          _aretes[getEdge(b).prevS].nextS = getEdge(b).nextS;
+        }
       else if (getEdge(getEdge(b).prevS).en == getEdge(b).st)
-       {
-         _aretes[getEdge(b).prevS].nextE = getEdge(b).nextS;
-       }
+        {
+          _aretes[getEdge(b).prevS].nextE = getEdge(b).nextS;
+        }
     }
   if (getEdge(b).nextS >= 0)
     {
       if (getEdge(getEdge(b).nextS).st == getEdge(b).st)
-       {
-         _aretes[getEdge(b).nextS].prevS = getEdge(b).prevS;
-       }
+        {
+          _aretes[getEdge(b).nextS].prevS = getEdge(b).prevS;
+        }
       else if (getEdge(getEdge(b).nextS).en == getEdge(b).st)
-       {
-         _aretes[getEdge(b).nextS].prevE = getEdge(b).prevS;
-       }
+        {
+          _aretes[getEdge(b).nextS].prevE = getEdge(b).prevS;
+        }
     }
   if (getPoint(getEdge(b).st).incidentEdge[FIRST] == b)
     _pts[getEdge(b).st].incidentEdge[FIRST] = getEdge(b).nextS;
@@ -1930,24 +1943,24 @@ Shape::DisconnectEnd (int b)
   if (getEdge(b).prevE >= 0)
     {
       if (getEdge(getEdge(b).prevE).st == getEdge(b).en)
-       {
-         _aretes[getEdge(b).prevE].nextS = getEdge(b).nextE;
-       }
+        {
+          _aretes[getEdge(b).prevE].nextS = getEdge(b).nextE;
+        }
       else if (getEdge(getEdge(b).prevE).en == getEdge(b).en)
-       {
-         _aretes[getEdge(b).prevE].nextE = getEdge(b).nextE;
-       }
+        {
+          _aretes[getEdge(b).prevE].nextE = getEdge(b).nextE;
+        }
     }
   if (getEdge(b).nextE >= 0)
     {
       if (getEdge(getEdge(b).nextE).st == getEdge(b).en)
-       {
-         _aretes[getEdge(b).nextE].prevS = getEdge(b).prevE;
-       }
+        {
+          _aretes[getEdge(b).nextE].prevS = getEdge(b).prevE;
+        }
       else if (getEdge(getEdge(b).nextE).en == getEdge(b).en)
-       {
-         _aretes[getEdge(b).nextE].prevE = getEdge(b).prevE;
-       }
+        {
+          _aretes[getEdge(b).nextE].prevE = getEdge(b).prevE;
+        }
     }
   if (getPoint(getEdge(b).en).incidentEdge[FIRST] == b)
     _pts[getEdge(b).en].incidentEdge[FIRST] = getEdge(b).nextE;
@@ -2005,9 +2018,12 @@ Shape::Inverse (int b)
 void
 Shape::CalcBBox (bool strict_degree)
 {
+  if (_bbox_up_to_date)
+    return;
   if (hasPoints() == false)
   {
     leftX = rightX = topY = bottomY = 0;
+    _bbox_up_to_date = true;
     return;
   }
   leftX = rightX = getPoint(0).x[0];
@@ -2028,6 +2044,8 @@ Shape::CalcBBox (bool strict_degree)
       }
     }
   }
+
+  _bbox_up_to_date = true;
 }
 
 // winding of a point with respect to the Shape
@@ -2091,15 +2109,19 @@ Shape::PtWinding (const NR::Point px) const
 
 void Shape::initialisePointData()
 {
+    if (_point_data_initialised)
+        return;
     int const N = numberOfPoints();
   
     for (int i = 0; i < N; i++) {
-       pData[i].pending = 0;
-       pData[i].edgeOnLeft = -1;
-       pData[i].nextLinkedPoint = -1;
-       pData[i].rx[0] = Round(getPoint(i).x[0]);
-       pData[i].rx[1] = Round(getPoint(i).x[1]);
+        pData[i].pending = 0;
+        pData[i].edgeOnLeft = -1;
+        pData[i].nextLinkedPoint = -1;
+        pData[i].rx[0] = Round(getPoint(i).x[0]);
+        pData[i].rx[1] = Round(getPoint(i).x[1]);
     }
+
+    _point_data_initialised = true;
 }
 
 void Shape::initialiseEdgeData()
@@ -2107,27 +2129,27 @@ void Shape::initialiseEdgeData()
     int const N = numberOfEdges();
 
     for (int i = 0; i < N; i++) {
-       eData[i].rdx = pData[getEdge(i).en].rx - pData[getEdge(i).st].rx;
-       eData[i].length = dot(eData[i].rdx, eData[i].rdx);
-       eData[i].ilength = 1 / eData[i].length;
-       eData[i].sqlength = sqrt(eData[i].length);
-       eData[i].isqlength = 1 / eData[i].sqlength;
-       eData[i].siEd = eData[i].rdx[1] * eData[i].isqlength;
-       eData[i].coEd = eData[i].rdx[0] * eData[i].isqlength;
-       
-       if (eData[i].siEd < 0) {
-           eData[i].siEd = -eData[i].siEd;
-           eData[i].coEd = -eData[i].coEd;
-       }
-
-       swsData[i].misc = NULL;
-       swsData[i].firstLinkedPoint = -1;
-       swsData[i].stPt = swsData[i].enPt = -1;
-       swsData[i].leftRnd = swsData[i].rightRnd = -1;
-       swsData[i].nextSh = NULL;
-       swsData[i].nextBo = -1;
-       swsData[i].curPoint = -1;
-       swsData[i].doneTo = -1;
+        eData[i].rdx = pData[getEdge(i).en].rx - pData[getEdge(i).st].rx;
+        eData[i].length = dot(eData[i].rdx, eData[i].rdx);
+        eData[i].ilength = 1 / eData[i].length;
+        eData[i].sqlength = sqrt(eData[i].length);
+        eData[i].isqlength = 1 / eData[i].sqlength;
+        eData[i].siEd = eData[i].rdx[1] * eData[i].isqlength;
+        eData[i].coEd = eData[i].rdx[0] * eData[i].isqlength;
+        
+        if (eData[i].siEd < 0) {
+            eData[i].siEd = -eData[i].siEd;
+            eData[i].coEd = -eData[i].coEd;
+        }
+
+        swsData[i].misc = NULL;
+        swsData[i].firstLinkedPoint = -1;
+        swsData[i].stPt = swsData[i].enPt = -1;
+        swsData[i].leftRnd = swsData[i].rightRnd = -1;
+        swsData[i].nextSh = NULL;
+        swsData[i].nextBo = -1;
+        swsData[i].curPoint = -1;
+        swsData[i].doneTo = -1;
   }
 }
 
@@ -2152,9 +2174,9 @@ void Shape::clearIncidenceData()
 bool directedEulerian(Shape const *s)
 {
     for (int i = 0; i < s->numberOfPoints(); i++) {
-       if (s->getPoint(i).dI != s->getPoint(i).dO) {
-           return false;
-       }
+        if (s->getPoint(i).dI != s->getPoint(i).dO) {
+            return false;
+        }
     }
 
     return true;
@@ -2171,7 +2193,7 @@ bool directedEulerian(Shape const *s)
 double distance(Shape const *s, NR::Point const &p)
 {
     if ( s->hasPoints() == false) {
-       return 0.0;
+        return 0.0;
     }
 
     /* Find the minimum distance from p to one of the points on s.
@@ -2182,35 +2204,35 @@ double distance(Shape const *s, NR::Point const &p)
     double bdot = NR::dot(p - s->getPoint(0).x, p - s->getPoint(0).x);
 
     for (int i = 0; i < s->numberOfPoints(); i++) {
-       NR::Point const offset( p - s->getPoint(i).x );
-       double ndot = NR::dot(offset, offset);
-       if ( ndot < bdot ) {
-           bdot = ndot;
-       }
+        NR::Point const offset( p - s->getPoint(i).x );
+        double ndot = NR::dot(offset, offset);
+        if ( ndot < bdot ) {
+            bdot = ndot;
+        }
     }
 
     for (int i = 0; i < s->numberOfEdges(); i++) {
-       if ( s->getEdge(i).st >= 0 && s->getEdge(i).en >= 0 ) {
-           /* The edge has start and end points */
-           NR::Point const st(s->getPoint(s->getEdge(i).st).x); // edge start
-           NR::Point const en(s->getPoint(s->getEdge(i).en).x); // edge end
-
-           NR::Point const d(p - st);       // vector between p and edge start
-           NR::Point const e(en - st);      // vector of the edge
-           double const el = NR::dot(e, e); // edge length
-
-           /* Update bdot if appropriate */
-           if ( el > 0.001 ) {
-               double const npr = NR::dot(d, e);
-               if ( npr > 0 && npr < el ) {
-                   double const nl = fabs( NR::cross(d, e) );
-                   double ndot = nl * nl / el;
-                   if ( ndot < bdot ) {
-                       bdot = ndot;
-                   }
-               }
-           }
-       }
+        if ( s->getEdge(i).st >= 0 && s->getEdge(i).en >= 0 ) {
+            /* The edge has start and end points */
+            NR::Point const st(s->getPoint(s->getEdge(i).st).x); // edge start
+            NR::Point const en(s->getPoint(s->getEdge(i).en).x); // edge end
+
+            NR::Point const d(p - st);       // vector between p and edge start
+            NR::Point const e(en - st);      // vector of the edge
+            double const el = NR::dot(e, e); // edge length
+
+            /* Update bdot if appropriate */
+            if ( el > 0.001 ) {
+                double const npr = NR::dot(d, e);
+                if ( npr > 0 && npr < el ) {
+                    double const nl = fabs( NR::cross(d, e) );
+                    double ndot = nl * nl / el;
+                    if ( ndot < bdot ) {
+                        bdot = ndot;
+                    }
+                }
+            }
+        }
     }
     
     return sqrt(bdot);
@@ -2233,7 +2255,7 @@ double distance(Shape const *s, NR::Point const &p)
 bool distanceLessThanOrEqual(Shape const *s, NR::Point const &p, double const max_l2)
 {
     if ( s->hasPoints() == false ) {
-       return false;
+        return false;
     }
     
     /* TODO: Consider using bbox to return early, perhaps conditional on nbPt or nbAr. */
@@ -2248,31 +2270,31 @@ bool distanceLessThanOrEqual(Shape const *s, NR::Point const &p, double const ma
   
     double const max_l1 = max_l2 * M_SQRT2;
     for (int i = 0; i < s->numberOfPoints(); i++) {
-       NR::Point const offset( p - s->getPoint(i).x );
-       double const l1 = NR::L1(offset);
-       if ( (l1 <= max_l2) || ((l1 <= max_l1) && (NR::L2(offset) <= max_l2)) ) {
-           return true;
-       }
+        NR::Point const offset( p - s->getPoint(i).x );
+        double const l1 = NR::L1(offset);
+        if ( (l1 <= max_l2) || ((l1 <= max_l1) && (NR::L2(offset) <= max_l2)) ) {
+            return true;
+        }
     }
     
     for (int i = 0; i < s->numberOfEdges(); i++) {
-       if ( s->getEdge(i).st >= 0 && s->getEdge(i).en >= 0 ) {
-           NR::Point const st(s->getPoint(s->getEdge(i).st).x);
-           NR::Point const en(s->getPoint(s->getEdge(i).en).x);
-           NR::Point const d(p - st);
-           NR::Point const e(en - st);
-           double const el = NR::L2(e);
-           if ( el > 0.001 ) {
-               NR::Point const e_unit(e / el);
-               double const npr = NR::dot(d, e_unit);
-               if ( npr > 0 && npr < el ) {
-                   double const nl = fabs(NR::cross(d, e_unit));
-                   if ( nl <= max_l2 ) {
-                       return true;
-                   }
-               }
-           }
-       }
+        if ( s->getEdge(i).st >= 0 && s->getEdge(i).en >= 0 ) {
+            NR::Point const st(s->getPoint(s->getEdge(i).st).x);
+            NR::Point const en(s->getPoint(s->getEdge(i).en).x);
+            NR::Point const d(p - st);
+            NR::Point const e(en - st);
+            double const el = NR::L2(e);
+            if ( el > 0.001 ) {
+                NR::Point const e_unit(e / el);
+                double const npr = NR::dot(d, e_unit);
+                if ( npr > 0 && npr < el ) {
+                    double const nl = fabs(NR::cross(d, e_unit));
+                    if ( nl <= max_l2 ) {
+                        return true;
+                    }
+                }
+            }
+        }
     }
     
     return false;
index d0be5e44e04f26ca9bd6c06c75d1dc58cdb28eb6..37039f2415cb960c5793aff11036375a6491ea05 100644 (file)
@@ -315,7 +315,7 @@ public:
     int nbQRas;
     int firstQRas;
     int lastQRas;
-    std::vector<quick_raster_data> qrsData;
+    quick_raster_data *qrsData;
 
     std::vector<sTreeChange> chgts;
     int nbInc;
@@ -523,6 +523,7 @@ private:
     bool _need_edges_sorting;   ///< edges have been added: maybe they are not ordered clockwise
     ///< nota: if you remove an edge, the clockwise order still holds
     bool _has_points_data;      ///< the pData array is allocated
+    bool _point_data_initialised;///< the pData array is up to date
     bool _has_edges_data;       ///< the eData array is allocated
     bool _has_sweep_src_data;   ///< the swsData array is allocated
     bool _has_sweep_dest_data;  ///< the swdData array is allocated
@@ -530,6 +531,7 @@ private:
     bool _has_quick_raster_data;///< the swrData array is allocated
     bool _has_back_data;        //< the ebData array is allocated
     bool _has_voronoi_data;
+    bool _bbox_up_to_date;      ///< the leftX/rightX/topY/bottomY are up to date
 
     std::vector<dg_point> _pts;
     std::vector<dg_arete> _aretes;
index d9bb665f056a18704f6be0c1ae3ed54516963706..a76c0f74517e811184b4cb2fdf40cb79ddd85b54 100644 (file)
@@ -541,8 +541,11 @@ Shape::MakeOffset (Shape * a, double dec, JoinType join, double miter)
     if (numberOfPoints() > maxPt)
     {
       maxPt = numberOfPoints();
-      if (_has_points_data)
+      if (_has_points_data) {
         pData.resize(maxPt);
+        _point_data_initialised = false;
+        _bbox_up_to_date = false;
+        }
     }
     
     _aretes = a->_aretes;
index 3e5a3bcafd93c74fac0230ffd5b5f5a4448bb652..ea401f7f05d3940b7942be699458abb1fb3bb14f 100644 (file)
@@ -75,8 +75,11 @@ Shape::Reoriente (Shape * a)
   if (numberOfPoints() > maxPt)
     {
       maxPt = numberOfPoints();
-      if (_has_points_data)
-       pData.resize(maxPt);
+      if (_has_points_data) {
+        pData.resize(maxPt);
+        _point_data_initialised = false;
+        _bbox_up_to_date = false;
+        }
     }
 
   _aretes = a->_aretes;