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"
24namespace agg
25{
26template<class T>
27inline 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}
34template<class T>
35inline 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