Code

moving trunk for module inkscape
[inkscape.git] / src / livarot / float-line.h
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();
76     
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);
81     
82     void Flatten();
84     void Affiche();
86     void Max(FloatLigne *a, float tresh, bool addIt);
87     
88     void Min(FloatLigne *a, float tresh, bool addIt);
89     
90     void Split(FloatLigne *a, float tresh, FloatLigne *over);
91     
92     void Over(FloatLigne *a, float tresh);
93         
94     void Copy(IntLigne *a);
95     void Copy(FloatLigne *a);
97     float RemainingValAt(float at, int pending);
98   
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         }
109         
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 :