1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
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.
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
19 #include "agg_basics.h"
24 // See Implementation agg_line_aa_basics.cpp
26 //-------------------------------------------------------------------------
27 enum line_subpixel_scale_e
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
36 //-------------------------------------------------------------------------
37 enum line_mr_subpixel_scale_e
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
44 //------------------------------------------------------------------line_mr
45 AGG_INLINE
int line_mr(int x
)
47 return x
>> (line_subpixel_shift
- line_mr_subpixel_shift
);
50 //-------------------------------------------------------------------line_hr
51 AGG_INLINE
int line_hr(int x
)
53 return x
<< (line_subpixel_shift
- line_mr_subpixel_shift
);
56 //---------------------------------------------------------------line_dbl_hr
57 AGG_INLINE
int line_dbl_hr(int x
)
59 return x
<< line_subpixel_shift
;
62 //---------------------------------------------------------------line_coord
65 AGG_INLINE
static int conv(double x
)
67 return iround(x
* line_subpixel_scale
);
71 //-----------------------------------------------------------line_coord_sat
74 AGG_INLINE
static int conv(double x
)
76 return saturation
<line_max_coord
>::iround(x
* line_subpixel_scale
);
80 //==========================================================line_parameters
81 struct line_parameters
83 //---------------------------------------------------------------------
85 line_parameters(int x1_
, int y1_
, int x2_
, int y2_
, int len_
) :
86 x1(x1_
), y1(y1_
), x2(x2_
), y2(y2_
),
89 sx((x2_
> x1_
) ? 1 : -1),
90 sy((y2_
> y1_
) ? 1 : -1),
92 inc(vertical
? sy
: sx
),
94 octant((sy
& 4) | (sx
& 2) | int(vertical
))
98 //---------------------------------------------------------------------
99 unsigned orthogonal_quadrant() const { return s_orthogonal_quadrant
[octant
]; }
100 unsigned diagonal_quadrant() const { return s_diagonal_quadrant
[octant
]; }
102 //---------------------------------------------------------------------
103 bool same_orthogonal_quadrant(const line_parameters
& lp
) const
105 return s_orthogonal_quadrant
[octant
] == s_orthogonal_quadrant
[lp
.octant
];
108 //---------------------------------------------------------------------
109 bool same_diagonal_quadrant(const line_parameters
& lp
) const
111 return s_diagonal_quadrant
[octant
] == s_diagonal_quadrant
[lp
.octant
];
114 //---------------------------------------------------------------------
115 void divide(line_parameters
& lp1
, line_parameters
& lp2
) const
117 int xmid
= (x1
+ x2
) >> 1;
118 int ymid
= (y1
+ y2
) >> 1;
127 lp1
.dx
= abs(lp1
.x2
- lp1
.x1
);
128 lp1
.dy
= abs(lp1
.y2
- lp1
.y1
);
133 lp2
.dx
= abs(lp2
.x2
- lp2
.x1
);
134 lp2
.dy
= abs(lp2
.y2
- lp2
.y1
);
137 //---------------------------------------------------------------------
138 int x1
, y1
, x2
, y2
, dx
, dy
, sx
, sy
;
144 //---------------------------------------------------------------------
145 static const int8u s_orthogonal_quadrant
[8];
146 static const int8u s_diagonal_quadrant
[8];
151 // See Implementation agg_line_aa_basics.cpp
153 //----------------------------------------------------------------bisectrix
154 void bisectrix(const line_parameters
& l1
,
155 const line_parameters
& l2
,
159 //-------------------------------------------fix_degenerate_bisectrix_start
160 void inline fix_degenerate_bisectrix_start(const line_parameters
& lp
,
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)
167 *x
= lp
.x1
+ (lp
.y2
- lp
.y1
);
168 *y
= lp
.y1
- (lp
.x2
- lp
.x1
);
173 //---------------------------------------------fix_degenerate_bisectrix_end
174 void inline fix_degenerate_bisectrix_end(const line_parameters
& lp
,
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)
181 *x
= lp
.x2
+ (lp
.y2
- lp
.y1
);
182 *y
= lp
.y2
- (lp
.x2
- lp
.x1
);