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 (at) antigrain.com 13 // mcseemagg (at) 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> 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> 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