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