1 #ifndef INKSCAPE_LIVAROT_FLOAT_LINE_H
2 #define INKSCAPE_LIVAROT_FLOAT_LINE_H
4 /** \file
5 * Coverage with floating-point boundaries.
6 */
8 #include <vector>
9 #include "livarot/LivarotDefs.h"
11 class IntLigne;
12 class BitLigne;
14 /// A coverage portion ("run") with floating point boundaries.
15 struct float_ligne_run {
16 float st;
17 float en;
18 float vst;
19 float ven;
20 float pente; ///< (ven-vst)/(en-st)
21 };
23 /**
24 * A floating-point boundary.
25 *
26 * Each float_ligne_bord is a boundary of some coverage.
27 * The Flatten() function will extract non-overlapping runs and produce an
28 * array of float_ligne_run. The float_ligne_bord are stored in an array, but
29 * linked like a doubly-linked list.
30 *
31 * The idea behind that is that a given edge produces one float_ligne_bord at
32 * the beginning of Scan() and possibly another in AvanceEdge() and
33 * DestroyEdge(); but that second float_ligne_bord will not be far away in
34 * the list from the first, so it's faster to salvage the index of the first
35 * float_ligne_bord and try to insert the second from that salvaged position.
36 */
37 struct float_ligne_bord {
38 float pos; ///< position of the boundary
39 bool start; ///< is the beginning of the coverage portion?
40 float val; ///< amount of coverage (ie vst if start==true, and ven if start==false)
41 float pente; ///< (ven-vst)/(en-st)
42 int other; ///< index, in the array of float_ligne_bord, of the other boundary associated to this one
43 int s_prev; ///< index of the previous bord in the doubly-linked list
44 int s_next; ///< index of the next bord in the doubly-linked list
45 int pend_ind; ///< bords[i].pend_ind is the index of the float_ligne_bord that is the start of the
46 ///< coverage portion being scanned (in the Flatten() )
47 int pend_inv; ///< inverse of pend_ind, for faster handling of insertion/removal in the "pending" array
48 };
50 /**
51 * Coverage with floating-point boundaries.
52 *
53 * The goal is to salvage exact coverage info in the sweepline performed by
54 * Scan() or QuickScan(), then clean up a bit, convert floating point bounds
55 * to integer bounds, because pixel have integer bounds, and then raster runs
56 * of the type:
57 * \verbatim
58 position on the (pixel) line: st en
59 | |
60 coverage value (0=empty, 1=full) vst -> ven \endverbatim
61 */
62 class FloatLigne {
63 public:
64 std::vector<float_ligne_bord> bords; ///< vector of coverage boundaries
65 std::vector<float_ligne_run> runs; ///< vector of runs
67 /// first boundary in the doubly-linked list
68 int s_first;
69 /// last boundary in the doubly-linked list
70 int s_last;
72 FloatLigne();
73 ~FloatLigne();
75 void Reset();
77 int AddBord(float spos, float sval, float epos, float eval, int guess = -1);
78 int AddBord(float spos, float sval, float epos, float eval, float pente, int guess = -1);
79 int AddBordR(float spos, float sval, float epos, float eval, float pente, int guess = -1);
80 int AppendBord(float spos, float sval, float epos, float eval, float pente);
82 void Flatten();
84 void Affiche();
86 void Max(FloatLigne *a, float tresh, bool addIt);
88 void Min(FloatLigne *a, float tresh, bool addIt);
90 void Split(FloatLigne *a, float tresh, FloatLigne *over);
92 void Over(FloatLigne *a, float tresh);
94 void Copy(IntLigne *a);
95 void Copy(FloatLigne *a);
97 float RemainingValAt(float at, int pending);
99 static int CmpBord(float_ligne_bord const &d1, float_ligne_bord const &d2) {
100 if ( d1.pos == d2.pos ) {
101 if ( d1.start && !(d2.start) ) {
102 return 1;
103 }
104 if ( !(d1.start) && d2.start ) {
105 return -1;
106 }
107 return 0;
108 }
110 return (( d1.pos < d2.pos ) ? -1 : 1);
111 };
113 int AddRun(float st, float en, float vst, float ven, float pente);
115 private:
116 void InsertBord(int no, float p, int guess);
117 int AddRun(float st, float en, float vst, float ven);
119 inline float ValAt(float at, float ps, float pe, float vs, float ve) {
120 return ((at - ps) * ve + (pe - at) * vs) / (pe - ps);
121 };
122 };
124 #endif
127 /*
128 Local Variables:
129 mode:c++
130 c-file-style:"stroustrup"
131 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
132 indent-tabs-mode:nil
133 fill-column:99
134 End:
135 */
136 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :