1 //---------------------------------------------------------------------------- 2 // Anti-Grain Geometry - Version 2.4 3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) 4 // 5 // Permission to copy, use, modify, sell and distribute this software 6 // is granted provided this copyright notice appears in all copies. 7 // This software is provided "as is" without express or implied 8 // warranty, and with no claim as to its suitability for any purpose. 9 // 10 //---------------------------------------------------------------------------- 11 // Contact: mcseem@antigrain.com 12 // mcseemagg@yahoo.com 13 // http://www.antigrain.com 14 //---------------------------------------------------------------------------- 15 #ifndef AGG_LINE_AA_BASICS_INCLUDED 16 #define AGG_LINE_AA_BASICS_INCLUDED 17 18 #include <stdlib.h> 19 #include "agg_basics.h" 20 21 namespace agg 22 { 23 24 // See Implementation agg_line_aa_basics.cpp 25 26 //------------------------------------------------------------------------- 27 enum line_subpixel_scale_e 28 { 29 line_subpixel_shift = 8, //----line_subpixel_shift 30 line_subpixel_scale = 1 << line_subpixel_shift, //----line_subpixel_scale 31 line_subpixel_mask = line_subpixel_scale - 1, //----line_subpixel_mask 32 line_max_coord = (1 << 28) - 1, //----line_max_coord 33 line_max_length = 1 << (line_subpixel_shift + 10) //----line_max_length 34 }; 35 36 //------------------------------------------------------------------------- 37 enum line_mr_subpixel_scale_e 38 { 39 line_mr_subpixel_shift = 4, //----line_mr_subpixel_shift 40 line_mr_subpixel_scale = 1 << line_mr_subpixel_shift, //----line_mr_subpixel_scale 41 line_mr_subpixel_mask = line_mr_subpixel_scale - 1 //----line_mr_subpixel_mask 42 }; 43 44 //------------------------------------------------------------------line_mr line_mr(int x)45 AGG_INLINE int line_mr(int x) 46 { 47 return x >> (line_subpixel_shift - line_mr_subpixel_shift); 48 } 49 50 //-------------------------------------------------------------------line_hr line_hr(int x)51 AGG_INLINE int line_hr(int x) 52 { 53 return x << (line_subpixel_shift - line_mr_subpixel_shift); 54 } 55 56 //---------------------------------------------------------------line_dbl_hr line_dbl_hr(int x)57 AGG_INLINE int line_dbl_hr(int x) 58 { 59 return x << line_subpixel_shift; 60 } 61 62 //---------------------------------------------------------------line_coord 63 struct line_coord 64 { convline_coord65 AGG_INLINE static int conv(double x) 66 { 67 return iround(x * line_subpixel_scale); 68 } 69 }; 70 71 //-----------------------------------------------------------line_coord_sat 72 struct line_coord_sat 73 { convline_coord_sat74 AGG_INLINE static int conv(double x) 75 { 76 return saturation<line_max_coord>::iround(x * line_subpixel_scale); 77 } 78 }; 79 80 //==========================================================line_parameters 81 struct line_parameters 82 { 83 //--------------------------------------------------------------------- line_parametersline_parameters84 line_parameters() {} line_parametersline_parameters85 line_parameters(int x1_, int y1_, int x2_, int y2_, int len_) : 86 x1(x1_), y1(y1_), x2(x2_), y2(y2_), 87 dx(abs(x2_ - x1_)), 88 dy(abs(y2_ - y1_)), 89 sx((x2_ > x1_) ? 1 : -1), 90 sy((y2_ > y1_) ? 1 : -1), 91 vertical(dy >= dx), 92 inc(vertical ? sy : sx), 93 len(len_), 94 octant((sy & 4) | (sx & 2) | int(vertical)) 95 { 96 } 97 98 //--------------------------------------------------------------------- orthogonal_quadrantline_parameters99 unsigned orthogonal_quadrant() const { return s_orthogonal_quadrant[octant]; } diagonal_quadrantline_parameters100 unsigned diagonal_quadrant() const { return s_diagonal_quadrant[octant]; } 101 102 //--------------------------------------------------------------------- same_orthogonal_quadrantline_parameters103 bool same_orthogonal_quadrant(const line_parameters& lp) const 104 { 105 return s_orthogonal_quadrant[octant] == s_orthogonal_quadrant[lp.octant]; 106 } 107 108 //--------------------------------------------------------------------- same_diagonal_quadrantline_parameters109 bool same_diagonal_quadrant(const line_parameters& lp) const 110 { 111 return s_diagonal_quadrant[octant] == s_diagonal_quadrant[lp.octant]; 112 } 113 114 //--------------------------------------------------------------------- divideline_parameters115 void divide(line_parameters& lp1, line_parameters& lp2) const 116 { 117 int xmid = (x1 + x2) >> 1; 118 int ymid = (y1 + y2) >> 1; 119 int len2 = len >> 1; 120 121 lp1 = *this; 122 lp2 = *this; 123 124 lp1.x2 = xmid; 125 lp1.y2 = ymid; 126 lp1.len = len2; 127 lp1.dx = abs(lp1.x2 - lp1.x1); 128 lp1.dy = abs(lp1.y2 - lp1.y1); 129 130 lp2.x1 = xmid; 131 lp2.y1 = ymid; 132 lp2.len = len2; 133 lp2.dx = abs(lp2.x2 - lp2.x1); 134 lp2.dy = abs(lp2.y2 - lp2.y1); 135 } 136 137 //--------------------------------------------------------------------- 138 int x1, y1, x2, y2, dx, dy, sx, sy; 139 bool vertical; 140 int inc; 141 int len; 142 int octant; 143 144 //--------------------------------------------------------------------- 145 static const int8u s_orthogonal_quadrant[8]; 146 static const int8u s_diagonal_quadrant[8]; 147 }; 148 149 150 151 // See Implementation agg_line_aa_basics.cpp 152 153 //----------------------------------------------------------------bisectrix 154 void bisectrix(const line_parameters& l1, 155 const line_parameters& l2, 156 int* x, int* y); 157 158 159 //-------------------------------------------fix_degenerate_bisectrix_start fix_degenerate_bisectrix_start(const line_parameters & lp,int * x,int * y)160 void inline fix_degenerate_bisectrix_start(const line_parameters& lp, 161 int* x, int* y) 162 { 163 int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) - 164 double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len); 165 if(d < line_subpixel_scale/2) 166 { 167 *x = lp.x1 + (lp.y2 - lp.y1); 168 *y = lp.y1 - (lp.x2 - lp.x1); 169 } 170 } 171 172 173 //---------------------------------------------fix_degenerate_bisectrix_end fix_degenerate_bisectrix_end(const line_parameters & lp,int * x,int * y)174 void inline fix_degenerate_bisectrix_end(const line_parameters& lp, 175 int* x, int* y) 176 { 177 int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) - 178 double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len); 179 if(d < line_subpixel_scale/2) 180 { 181 *x = lp.x2 + (lp.y2 - lp.y1); 182 *y = lp.y2 - (lp.x2 - lp.x1); 183 } 184 } 185 186 187 } 188 189 #endif 190