1
2 //----------------------------------------------------------------------------
3 // Anti-Grain Geometry - Version 2.3
4 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5 //
6 // Permission to copy, use, modify, sell and distribute this software
7 // is granted provided this copyright notice appears in all copies.
8 // This software is provided "as is" without express or implied
9 // warranty, and with no claim as to its suitability for any purpose.
10 //
11 //----------------------------------------------------------------------------
12 // Contact: mcseem@antigrain.com
13 // mcseemagg@yahoo.com
14 // http://www.antigrain.com
15 //----------------------------------------------------------------------------
16 //
17 // Liang-Barsky clipping
18 //
19 //----------------------------------------------------------------------------
20 #ifndef AGG_CLIP_LIANG_BARSKY_INCLUDED
21 #define AGG_CLIP_LIANG_BARSKY_INCLUDED
22 #include "agg_basics.h"
23 #include "third_party/base/numerics/safe_math.h"
24 namespace agg
25 {
26 template<class T>
clipping_flags(T x,T y,const rect_base<T> & clip_box)27 inline unsigned clipping_flags(T x, T y, const rect_base<T>& clip_box)
28 {
29 return (x > clip_box.x2) |
30 ((y > clip_box.y2) << 1) |
31 ((x < clip_box.x1) << 2) |
32 ((y < clip_box.y1) << 3);
33 }
34 template<class T>
clip_liang_barsky(T x1,T y1,T x2,T y2,const rect_base<T> & clip_box,T * x,T * y)35 inline unsigned clip_liang_barsky(T x1, T y1, T x2, T y2,
36 const rect_base<T>& clip_box,
37 T* x, T* y)
38 {
39 const float nearzero = 1e-30f;
40
41 pdfium::base::CheckedNumeric<float> width = x2;
42 width -= x1;
43 if (!width.IsValid())
44 return 0;
45 pdfium::base::CheckedNumeric<float> height = y2;
46 height -= y1;
47 if (!height.IsValid())
48 return 0;
49
50 float deltax = width.ValueOrDefault(0);
51 float deltay = height.ValueOrDefault(0);
52 unsigned np = 0;
53 if(deltax == 0) {
54 deltax = (x1 > clip_box.x1) ? -nearzero : nearzero;
55 }
56 float xin, xout;
57 if(deltax > 0) {
58 xin = (float)clip_box.x1;
59 xout = (float)clip_box.x2;
60 } else {
61 xin = (float)clip_box.x2;
62 xout = (float)clip_box.x1;
63 }
64 float tinx = (xin - x1) / deltax;
65 if(deltay == 0) {
66 deltay = (y1 > clip_box.y1) ? -nearzero : nearzero;
67 }
68 float yin, yout;
69 if(deltay > 0) {
70 yin = (float)clip_box.y1;
71 yout = (float)clip_box.y2;
72 } else {
73 yin = (float)clip_box.y2;
74 yout = (float)clip_box.y1;
75 }
76 float tiny = (yin - y1) / deltay;
77 float tin1, tin2;
78 if (tinx < tiny) {
79 tin1 = tinx;
80 tin2 = tiny;
81 } else {
82 tin1 = tiny;
83 tin2 = tinx;
84 }
85 if(tin1 <= 1.0f) {
86 if(0 < tin1) {
87 *x++ = (T)xin;
88 *y++ = (T)yin;
89 ++np;
90 }
91 if(tin2 <= 1.0f) {
92 float toutx = (xout - x1) / deltax;
93 float touty = (yout - y1) / deltay;
94 float tout1 = (toutx < touty) ? toutx : touty;
95 if (tin2 > 0 || tout1 > 0) {
96 if(tin2 <= tout1) {
97 if(tin2 > 0) {
98 if(tinx > tiny) {
99 *x++ = (T)xin;
100 *y++ = (T)(y1 + (deltay * tinx));
101 } else {
102 *x++ = (T)(x1 + (deltax * tiny));
103 *y++ = (T)yin;
104 }
105 ++np;
106 }
107 if(tout1 < 1.0f) {
108 if(toutx < touty) {
109 *x++ = (T)xout;
110 *y++ = (T)(y1 + (deltay * toutx));
111 } else {
112 *x++ = (T)(x1 + (deltax * touty));
113 *y++ = (T)yout;
114 }
115 } else {
116 *x++ = x2;
117 *y++ = y2;
118 }
119 ++np;
120 } else {
121 if(tinx > tiny) {
122 *x++ = (T)xin;
123 *y++ = (T)yout;
124 } else {
125 *x++ = (T)xout;
126 *y++ = (T)yin;
127 }
128 ++np;
129 }
130 }
131 }
132 }
133 return np;
134 }
135 }
136 #endif
137