summaryrefslogtreecommitdiffstats
path: root/src/livarot/path-description.h
blob: f2967b550156f3808bb365c871a7517d1777c543 (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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
// SPDX-License-Identifier: GPL-2.0-or-later
/** @file
 * TODO: insert short description here
 *//*
 * Authors: see git history
 *
 * Copyright (C) 2018 Authors
 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
 */
#ifndef SEEN_INKSCAPE_LIVAROT_PATH_DESCRIPTION_H
#define SEEN_INKSCAPE_LIVAROT_PATH_DESCRIPTION_H

#include <2geom/point.h>
#include "svg/stringstream.h"

// path description commands
/* FIXME: these should be unnecessary once the refactoring of the path
** description stuff is finished.
*/
enum
{
  descr_moveto = 0,         // a moveto
  descr_lineto = 1,         // a (guess what) lineto
  descr_cubicto = 2,
  descr_bezierto = 3,       // "beginning" of a quadratic bezier spline, will contain its endpoint (i know, it's bad...)
  descr_arcto = 4,
  descr_close = 5,
  descr_interm_bezier = 6,  // control point of the bezier spline
  descr_forced = 7,

  descr_type_mask = 15      // the command no will be stored in a "flags" field, potentially with other info, so we need
                            // a mask to AND the field and extract the command
};

struct PathDescr
{
  PathDescr() : flags(0), associated(-1), tSt(0), tEn(1) {}
  PathDescr(int f) : flags(f), associated(-1), tSt(0), tEn(1) {}
  virtual ~PathDescr() = default;

  int getType() const { return flags & descr_type_mask; }
  void setType(int t) {
    flags &= ~descr_type_mask;
    flags |= t;
  }

    virtual void dumpSVG(Inkscape::SVGOStringStream &/*s*/, Geom::Point const &/*last*/) const {}
    virtual PathDescr *clone() const = 0;
    virtual void dump(std::ostream &/*s*/) const {}

  int    flags;         // most notably contains the path command no
  int    associated;    // index in the polyline of the point that ends the path portion of this command
  double tSt;
  double tEn;
};

struct PathDescrMoveTo : public PathDescr
{
  PathDescrMoveTo(Geom::Point const &pp)
      : PathDescr(descr_moveto), p(pp) {}

  void dumpSVG(Inkscape::SVGOStringStream &s, Geom::Point const &last) const override;
  PathDescr *clone() const override;
  void dump(std::ostream &s) const override;

  Geom::Point p;
};

struct PathDescrLineTo : public PathDescr
{
  PathDescrLineTo(Geom::Point const &pp)
    : PathDescr(descr_lineto), p(pp) {}

  void dumpSVG(Inkscape::SVGOStringStream &s, Geom::Point const &last) const override;
  PathDescr *clone() const override;
  void dump(std::ostream &s) const override;

  Geom::Point p;
};

// quadratic bezier curves: a set of control points, and an endpoint
struct PathDescrBezierTo : public PathDescr
{
  PathDescrBezierTo(Geom::Point const &pp, int n)
    : PathDescr(descr_bezierto), p(pp), nb(n) {}

  PathDescr *clone() const override;
  void dump(std::ostream &s) const override;

  Geom::Point p;        // the endpoint's coordinates
  int nb;             // number of control points, stored in the next path description commands
};

/* FIXME: I don't think this should be necessary */
struct PathDescrIntermBezierTo : public PathDescr
{
  PathDescrIntermBezierTo()
    : PathDescr(descr_interm_bezier) , p(0, 0) {}
  PathDescrIntermBezierTo(Geom::Point const &pp)
    : PathDescr(descr_interm_bezier), p(pp) {}

  PathDescr *clone() const override;
  void dump(std::ostream &s) const override;

  Geom::Point p;                  // control point coordinates
};

// cubic spline curve: 2 tangents and one endpoint
struct PathDescrCubicTo : public PathDescr
{
  PathDescrCubicTo(Geom::Point const &pp, Geom::Point const &s, Geom::Point const& e)
    : PathDescr(descr_cubicto), p(pp), start(s), end(e) {}

  void dumpSVG(Inkscape::SVGOStringStream &s, Geom::Point const &last) const override;
  PathDescr *clone() const override;
  void dump(std::ostream &s) const override;

  Geom::Point p;
  Geom::Point start;
  Geom::Point end;
};

// arc: endpoint, 2 radii and one angle, plus 2 booleans to choose the arc (svg style)
struct PathDescrArcTo : public PathDescr
{
  PathDescrArcTo(Geom::Point const &pp, double x, double y, double a, bool l, bool c)
    : PathDescr(descr_arcto), p(pp), rx(x), ry(y), angle(a), large(l), clockwise(c) {}

  void dumpSVG(Inkscape::SVGOStringStream &s, Geom::Point const &last) const override;
  PathDescr *clone() const override;
  void dump(std::ostream &s) const override;

  Geom::Point p;
  double rx;
  double ry;
  double angle;
  bool large;
  bool clockwise;
};

struct PathDescrForced : public PathDescr
{
  PathDescrForced() : PathDescr(descr_forced), p(0, 0) {}

  PathDescr *clone() const override;

  /* FIXME: not sure whether _forced should have a point associated with it;
  ** Path::ConvertForcedToMoveTo suggests that maybe it should.
  */
  Geom::Point p;
};

struct PathDescrClose : public PathDescr
{
  PathDescrClose() : PathDescr(descr_close) {}

  void dumpSVG(Inkscape::SVGOStringStream &s, Geom::Point const &last) const override;
  PathDescr *clone() const override;

  /* FIXME: not sure whether _forced should have a point associated with it;
  ** Path::ConvertForcedToMoveTo suggests that maybe it should.
  */
  Geom::Point p;
};

#endif


/*
  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:fileencoding=utf-8:textwidth=99 :