Anti-Grain Geometry - AGG (libagg)
2.5
|
00001 //---------------------------------------------------------------------------- 00002 // Anti-Grain Geometry (AGG) - Version 2.5 00003 // A high quality rendering engine for C++ 00004 // Copyright (C) 2002-2006 Maxim Shemanarev 00005 // Contact: mcseem@antigrain.com 00006 // mcseemagg@yahoo.com 00007 // http://antigrain.com 00008 // 00009 // AGG is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU General Public License 00011 // as published by the Free Software Foundation; either version 2 00012 // of the License, or (at your option) any later version. 00013 // 00014 // AGG is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with AGG; if not, write to the Free Software 00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00022 // MA 02110-1301, USA. 00023 //---------------------------------------------------------------------------- 00024 00025 #ifndef AGG_LINE_AA_BASICS_INCLUDED 00026 #define AGG_LINE_AA_BASICS_INCLUDED 00027 00028 #include <stdlib.h> 00029 #include "agg_basics.h" 00030 00031 namespace agg 00032 { 00033 00034 // See Implementation agg_line_aa_basics.cpp 00035 00036 //------------------------------------------------------------------------- 00037 enum line_subpixel_scale_e 00038 { 00039 line_subpixel_shift = 8, //----line_subpixel_shift 00040 line_subpixel_scale = 1 << line_subpixel_shift, //----line_subpixel_scale 00041 line_subpixel_mask = line_subpixel_scale - 1, //----line_subpixel_mask 00042 line_max_coord = (1 << 28) - 1, //----line_max_coord 00043 line_max_length = 1 << (line_subpixel_shift + 10) //----line_max_length 00044 }; 00045 00046 //------------------------------------------------------------------------- 00047 enum line_mr_subpixel_scale_e 00048 { 00049 line_mr_subpixel_shift = 4, //----line_mr_subpixel_shift 00050 line_mr_subpixel_scale = 1 << line_mr_subpixel_shift, //----line_mr_subpixel_scale 00051 line_mr_subpixel_mask = line_mr_subpixel_scale - 1 //----line_mr_subpixel_mask 00052 }; 00053 00054 //------------------------------------------------------------------line_mr 00055 AGG_INLINE int line_mr(int x) 00056 { 00057 return x >> (line_subpixel_shift - line_mr_subpixel_shift); 00058 } 00059 00060 //-------------------------------------------------------------------line_hr 00061 AGG_INLINE int line_hr(int x) 00062 { 00063 return x << (line_subpixel_shift - line_mr_subpixel_shift); 00064 } 00065 00066 //---------------------------------------------------------------line_dbl_hr 00067 AGG_INLINE int line_dbl_hr(int x) 00068 { 00069 return x << line_subpixel_shift; 00070 } 00071 00072 //---------------------------------------------------------------line_coord 00073 struct line_coord 00074 { 00075 AGG_INLINE static int conv(double x) 00076 { 00077 return iround(x * line_subpixel_scale); 00078 } 00079 }; 00080 00081 //-----------------------------------------------------------line_coord_sat 00082 struct line_coord_sat 00083 { 00084 AGG_INLINE static int conv(double x) 00085 { 00086 return saturation<line_max_coord>::iround(x * line_subpixel_scale); 00087 } 00088 }; 00089 00090 //==========================================================line_parameters 00091 struct line_parameters 00092 { 00093 //--------------------------------------------------------------------- 00094 line_parameters() {} 00095 line_parameters(int x1_, int y1_, int x2_, int y2_, int len_) : 00096 x1(x1_), y1(y1_), x2(x2_), y2(y2_), 00097 dx(abs(x2_ - x1_)), 00098 dy(abs(y2_ - y1_)), 00099 sx((x2_ > x1_) ? 1 : -1), 00100 sy((y2_ > y1_) ? 1 : -1), 00101 vertical(dy >= dx), 00102 inc(vertical ? sy : sx), 00103 len(len_), 00104 octant((sy & 4) | (sx & 2) | int(vertical)) 00105 { 00106 } 00107 00108 //--------------------------------------------------------------------- 00109 unsigned orthogonal_quadrant() const { return s_orthogonal_quadrant[octant]; } 00110 unsigned diagonal_quadrant() const { return s_diagonal_quadrant[octant]; } 00111 00112 //--------------------------------------------------------------------- 00113 bool same_orthogonal_quadrant(const line_parameters& lp) const 00114 { 00115 return s_orthogonal_quadrant[octant] == s_orthogonal_quadrant[lp.octant]; 00116 } 00117 00118 //--------------------------------------------------------------------- 00119 bool same_diagonal_quadrant(const line_parameters& lp) const 00120 { 00121 return s_diagonal_quadrant[octant] == s_diagonal_quadrant[lp.octant]; 00122 } 00123 00124 //--------------------------------------------------------------------- 00125 void divide(line_parameters& lp1, line_parameters& lp2) const 00126 { 00127 int xmid = (x1 + x2) >> 1; 00128 int ymid = (y1 + y2) >> 1; 00129 int len2 = len >> 1; 00130 00131 lp1 = *this; 00132 lp2 = *this; 00133 00134 lp1.x2 = xmid; 00135 lp1.y2 = ymid; 00136 lp1.len = len2; 00137 lp1.dx = abs(lp1.x2 - lp1.x1); 00138 lp1.dy = abs(lp1.y2 - lp1.y1); 00139 00140 lp2.x1 = xmid; 00141 lp2.y1 = ymid; 00142 lp2.len = len2; 00143 lp2.dx = abs(lp2.x2 - lp2.x1); 00144 lp2.dy = abs(lp2.y2 - lp2.y1); 00145 } 00146 00147 //--------------------------------------------------------------------- 00148 int x1, y1, x2, y2, dx, dy, sx, sy; 00149 bool vertical; 00150 int inc; 00151 int len; 00152 int octant; 00153 00154 //--------------------------------------------------------------------- 00155 static const int8u s_orthogonal_quadrant[8]; 00156 static const int8u s_diagonal_quadrant[8]; 00157 }; 00158 00159 00160 00161 // See Implementation agg_line_aa_basics.cpp 00162 00163 //----------------------------------------------------------------bisectrix 00164 void bisectrix(const line_parameters& l1, 00165 const line_parameters& l2, 00166 int* x, int* y); 00167 00168 00169 //-------------------------------------------fix_degenerate_bisectrix_start 00170 void inline fix_degenerate_bisectrix_start(const line_parameters& lp, 00171 int* x, int* y) 00172 { 00173 int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) - 00174 double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len); 00175 if(d < line_subpixel_scale/2) 00176 { 00177 *x = lp.x1 + (lp.y2 - lp.y1); 00178 *y = lp.y1 - (lp.x2 - lp.x1); 00179 } 00180 } 00181 00182 00183 //---------------------------------------------fix_degenerate_bisectrix_end 00184 void inline fix_degenerate_bisectrix_end(const line_parameters& lp, 00185 int* x, int* y) 00186 { 00187 int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) - 00188 double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len); 00189 if(d < line_subpixel_scale/2) 00190 { 00191 *x = lp.x2 + (lp.y2 - lp.y1); 00192 *y = lp.y2 - (lp.x2 - lp.x1); 00193 } 00194 } 00195 00196 00197 } 00198 00199 #endif