summaryrefslogtreecommitdiffstats
path: root/src/libnr/n-art-bpath-2geom.cpp
blob: 2bd76e6234ba8bd5cfc920cfd80bcbdd3c19236b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#define SEEN_LIBNR_N_ART_BPATH_2GEOM_CPP

/** \file
 * Contains functions to convert from NArtBpath to 2geom's Path
 *
 * Copyright (C) Johan Engelen 2007-2008 <j.b.c.engelen@utwente.nl>
 *
 * Released under GNU GPL, read the file 'COPYING' for more information
 */
 
#include "libnr/n-art-bpath-2geom.h"

#include "svg/svg.h"
#include <glib.h>
#include <2geom/path.h>
#include <2geom/svg-path.h>
#include <2geom/svg-path-parser.h>
#include <typeinfo>

std::vector<Geom::Path>
BPath_to_2GeomPath(NArtBpath const * bpath)
{
    std::vector<Geom::Path> pathv;
    if (!bpath) {
        return pathv;
    }

    NArtBpath const *bp = bpath;   // points to element within bpath
    Geom::Path * current = NULL;   // points to current path
    while (bp->code != NR_END) {
        if ( current &&
             ( (bp->code == NR_MOVETO) || (bp->code == NR_MOVETO_OPEN) )
            )
        {   // about to start a new path, correct the current path: nartbpath manually adds the closing line segment so erase it for closed path.
            if (current->closed() && !current->empty()) {
                // but only remove this last segment if it is a *linesegment*:
                if ( dynamic_cast<Geom::LineSegment const *>(&current->back()) ) {
                    current->erase_last();
                }
            }
        }

        switch(bp->code) {
            case NR_MOVETO:
                pathv.push_back( Geom::Path() );  // for some reason Geom::Path(Point) does not work...
                current = &pathv.back();
                current->start( Geom::Point(bp->x3, bp->y3) );
                current->close(true);
            break;

            case NR_MOVETO_OPEN:
                pathv.push_back( Geom::Path() );  // for some reason Geom::Path(Point) does not work...
                current = &pathv.back();
                current->start( Geom::Point(bp->x3, bp->y3) );
                current->close(false);
            break;

            case NR_LINETO:
                current->appendNew<Geom::LineSegment>( Geom::Point(bp->x3, bp->y3) );
            break;

            case NR_CURVETO:
                current->appendNew<Geom::CubicBezier> ( Geom::Point(bp->x1, bp->y1), Geom::Point(bp->x2, bp->y2), Geom::Point(bp->x3, bp->y3) );
            break;

            case NR_END:
                g_error("BPath_to_2GeomPath: logical error");
            break;
        }
        ++bp;
    }
    if ( current && current->closed() && !current->empty() ) {
        // correct the current path: nartbpath manually adds the closing line segment so erase it for closed path.
        // but only remove this last segment if it is a *linesegment*:
        if ( dynamic_cast<Geom::LineSegment const *>(&current->back()) ) {
            current->erase_last();
        }
    }

    return pathv;
}

NArtBpath *
BPath_from_2GeomPath(std::vector<Geom::Path> const & path)
{
    char * svgd = sp_svg_write_path(path);
    NArtBpath *bpath = sp_svg_read_path(svgd);
    g_free(svgd);
    return bpath;
}



/*
  Local Variables:
  mode:c++
  c-file-style:"stroustrup"
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
  indent-tabs-mode:nil
  fill-column:99
  End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :