Home | History | Annotate | Download | only in agg23
      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 namespace agg
     24 {
     25 template<class T>
     26 inline unsigned clipping_flags(T x, T y, const rect_base<T>& clip_box)
     27 {
     28     return  (x > clip_box.x2) |
     29             ((y > clip_box.y2) << 1) |
     30             ((x < clip_box.x1) << 2) |
     31             ((y < clip_box.y1) << 3);
     32 }
     33 template<class T>
     34 inline unsigned clip_liang_barsky(T x1, T y1, T x2, T y2,
     35                                   const rect_base<T>& clip_box,
     36                                   T* x, T* y)
     37 {
     38     const FX_FLOAT nearzero = 1e-30f;
     39     FX_FLOAT deltax = (FX_FLOAT)(x2 - x1);
     40     FX_FLOAT deltay = (FX_FLOAT)(y2 - y1);
     41     unsigned np = 0;
     42     if(deltax == 0) {
     43         deltax = (x1 > clip_box.x1) ? -nearzero : nearzero;
     44     }
     45     FX_FLOAT xin, xout;
     46     if(deltax > 0) {
     47         xin  = (FX_FLOAT)clip_box.x1;
     48         xout = (FX_FLOAT)clip_box.x2;
     49     } else {
     50         xin  = (FX_FLOAT)clip_box.x2;
     51         xout = (FX_FLOAT)clip_box.x1;
     52     }
     53     FX_FLOAT tinx = FXSYS_Div(xin - x1, deltax);
     54     if(deltay == 0) {
     55         deltay = (y1 > clip_box.y1) ? -nearzero : nearzero;
     56     }
     57     FX_FLOAT yin, yout;
     58     if(deltay > 0) {
     59         yin  = (FX_FLOAT)clip_box.y1;
     60         yout = (FX_FLOAT)clip_box.y2;
     61     } else {
     62         yin  = (FX_FLOAT)clip_box.y2;
     63         yout = (FX_FLOAT)clip_box.y1;
     64     }
     65     FX_FLOAT tiny = FXSYS_Div(yin - y1, deltay);
     66     FX_FLOAT tin1, tin2;
     67     if (tinx < tiny) {
     68         tin1 = tinx;
     69         tin2 = tiny;
     70     } else {
     71         tin1 = tiny;
     72         tin2 = tinx;
     73     }
     74     if(tin1 <= 1.0f) {
     75         if(0 < tin1) {
     76             *x++ = (T)xin;
     77             *y++ = (T)yin;
     78             ++np;
     79         }
     80         if(tin2 <= 1.0f) {
     81             FX_FLOAT toutx = FXSYS_Div(xout - x1, deltax);
     82             FX_FLOAT touty = FXSYS_Div(yout - y1, deltay);
     83             FX_FLOAT tout1 = (toutx < touty) ? toutx : touty;
     84             if(tin2 > 0 || tout1 > 0) {
     85                 if(tin2 <= tout1) {
     86                     if(tin2 > 0) {
     87                         if(tinx > tiny) {
     88                             *x++ = (T)xin;
     89                             *y++ = (T)(y1 + FXSYS_Mul(deltay, tinx));
     90                         } else {
     91                             *x++ = (T)(x1 + FXSYS_Mul(deltax, tiny));
     92                             *y++ = (T)yin;
     93                         }
     94                         ++np;
     95                     }
     96                     if(tout1 < 1.0f) {
     97                         if(toutx < touty) {
     98                             *x++ = (T)xout;
     99                             *y++ = (T)(y1 + FXSYS_Mul(deltay, toutx));
    100                         } else {
    101                             *x++ = (T)(x1 + FXSYS_Mul(deltax, touty));
    102                             *y++ = (T)yout;
    103                         }
    104                     } else {
    105                         *x++ = x2;
    106                         *y++ = y2;
    107                     }
    108                     ++np;
    109                 } else {
    110                     if(tinx > tiny) {
    111                         *x++ = (T)xin;
    112                         *y++ = (T)yout;
    113                     } else {
    114                         *x++ = (T)xout;
    115                         *y++ = (T)yin;
    116                     }
    117                     ++np;
    118                 }
    119             }
    120         }
    121     }
    122     return np;
    123 }
    124 }
    125 #endif
    126