xref: /haiku/headers/libs/agg/agg_line_aa_basics.h (revision 1e36cfc2721ef13a187c6f7354dc9cbc485e89d3)
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
45     AGG_INLINE int line_mr(int x)
46     {
47         return x >> (line_subpixel_shift - line_mr_subpixel_shift);
48     }
49 
50     //-------------------------------------------------------------------line_hr
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
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     {
65         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     {
74         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         //---------------------------------------------------------------------
84         line_parameters() {}
85         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         //---------------------------------------------------------------------
99         unsigned orthogonal_quadrant() const { return s_orthogonal_quadrant[octant]; }
100         unsigned diagonal_quadrant()   const { return s_diagonal_quadrant[octant];   }
101 
102         //---------------------------------------------------------------------
103         bool same_orthogonal_quadrant(const line_parameters& lp) const
104         {
105             return s_orthogonal_quadrant[octant] == s_orthogonal_quadrant[lp.octant];
106         }
107 
108         //---------------------------------------------------------------------
109         bool same_diagonal_quadrant(const line_parameters& lp) const
110         {
111             return s_diagonal_quadrant[octant] == s_diagonal_quadrant[lp.octant];
112         }
113 
114         //---------------------------------------------------------------------
115         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
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
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