update dev300-m58
[ooovba.git] / agg / inc / agg_clip_liang_barsky.h
blob5f185da37a78b78b41be2b30a704f9db88d97575
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.3
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 //----------------------------------------------------------------------------
16 // Liang-Barsky clipping
18 //----------------------------------------------------------------------------
19 #ifndef AGG_CLIP_LIANG_BARSKY_INCLUDED
20 #define AGG_CLIP_LIANG_BARSKY_INCLUDED
22 #include "agg_basics.h"
24 namespace agg
27 //----------------------------------------------------------clipping_flags
28 // Determine the clipping code of the vertex according to the
29 // Cyrus-Beck line clipping algorithm
31 // | |
32 // 0110 | 0010 | 0011
33 // | |
34 // -------+--------+-------- clip_box.y2
35 // | |
36 // 0100 | 0000 | 0001
37 // | |
38 // -------+--------+-------- clip_box.y1
39 // | |
40 // 1100 | 1000 | 1001
41 // | |
42 // clip_box.x1 clip_box.x2
44 //
45 template<class T>
46 inline unsigned clipping_flags(T x, T y, const rect_base<T>& clip_box)
48 return (x > clip_box.x2) |
49 ((y > clip_box.y2) << 1) |
50 ((x < clip_box.x1) << 2) |
51 ((y < clip_box.y1) << 3);
56 //-------------------------------------------------------clip_liang_barsky
57 template<class T>
58 /*inline*/ unsigned clip_liang_barsky(T x1, T y1, T x2, T y2,
59 const rect_base<T>& clip_box,
60 T* x, T* y)
62 const double nearzero = 1e-30;
64 double deltax = x2 - x1;
65 double deltay = y2 - y1;
66 double xin;
67 double xout;
68 double yin;
69 double yout;
70 double tinx;
71 double tiny;
72 double toutx;
73 double touty;
74 double tin1;
75 double tin2;
76 double tout1;
77 unsigned np = 0;
79 if(deltax == 0.0)
81 // bump off of the vertical
82 deltax = (x1 > clip_box.x1) ? -nearzero : nearzero;
85 if(deltay == 0.0)
87 // bump off of the horizontal
88 deltay = (y1 > clip_box.y1) ? -nearzero : nearzero;
91 if(deltax > 0.0)
93 // points to right
94 xin = clip_box.x1;
95 xout = clip_box.x2;
97 else
99 xin = clip_box.x2;
100 xout = clip_box.x1;
103 if(deltay > 0.0)
105 // points up
106 yin = clip_box.y1;
107 yout = clip_box.y2;
109 else
111 yin = clip_box.y2;
112 yout = clip_box.y1;
115 tinx = (xin - x1) / deltax;
116 tiny = (yin - y1) / deltay;
118 if (tinx < tiny)
120 // hits x first
121 tin1 = tinx;
122 tin2 = tiny;
124 else
126 // hits y first
127 tin1 = tiny;
128 tin2 = tinx;
131 if(tin1 <= 1.0)
133 if(0.0 < tin1)
135 *x++ = (T)xin;
136 *y++ = (T)yin;
137 ++np;
140 if(tin2 <= 1.0)
142 toutx = (xout - x1) / deltax;
143 touty = (yout - y1) / deltay;
145 tout1 = (toutx < touty) ? toutx : touty;
147 if(tin2 > 0.0 || tout1 > 0.0)
149 if(tin2 <= tout1)
151 if(tin2 > 0.0)
153 if(tinx > tiny)
155 *x++ = (T)xin;
156 *y++ = (T)(y1 + tinx * deltay);
158 else
160 *x++ = (T)(x1 + tiny * deltax);
161 *y++ = (T)yin;
163 ++np;
166 if(tout1 < 1.0)
168 if(toutx < touty)
170 *x++ = (T)xout;
171 *y++ = (T)(y1 + toutx * deltay);
173 else
175 *x++ = (T)(x1 + touty * deltax);
176 *y++ = (T)yout;
179 else
181 *x++ = x2;
182 *y++ = y2;
184 ++np;
186 else
188 if(tinx > tiny)
190 *x++ = (T)xin;
191 *y++ = (T)yout;
193 else
195 *x++ = (T)xout;
196 *y++ = (T)yin;
198 ++np;
203 return np;
209 #endif