Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/agg/agg_rasterizer_sl_clip.h')
-rw-r--r--src/agg/agg_rasterizer_sl_clip.h351
1 files changed, 351 insertions, 0 deletions
diff --git a/src/agg/agg_rasterizer_sl_clip.h b/src/agg/agg_rasterizer_sl_clip.h
new file mode 100644
index 000000000..3a7f3a103
--- /dev/null
+++ b/src/agg/agg_rasterizer_sl_clip.h
@@ -0,0 +1,351 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+#ifndef AGG_RASTERIZER_SL_CLIP_INCLUDED
+#define AGG_RASTERIZER_SL_CLIP_INCLUDED
+
+#include "agg_clip_liang_barsky.h"
+
+namespace agg
+{
+ //--------------------------------------------------------poly_max_coord_e
+ enum poly_max_coord_e
+ {
+ poly_max_coord = (1 << 30) - 1 //----poly_max_coord
+ };
+
+ //------------------------------------------------------------ras_conv_int
+ struct ras_conv_int
+ {
+ typedef int coord_type;
+ static AGG_INLINE int mul_div(double a, double b, double c)
+ {
+ return iround(a * b / c);
+ }
+ static int xi(int v) { return v; }
+ static int yi(int v) { return v; }
+ static int upscale(double v) { return iround(v * poly_subpixel_scale); }
+ static int downscale(int v) { return v; }
+ };
+
+ //--------------------------------------------------------ras_conv_int_sat
+ struct ras_conv_int_sat
+ {
+ typedef int coord_type;
+ static AGG_INLINE int mul_div(double a, double b, double c)
+ {
+ return saturation<poly_max_coord>::iround(a * b / c);
+ }
+ static int xi(int v) { return v; }
+ static int yi(int v) { return v; }
+ static int upscale(double v)
+ {
+ return saturation<poly_max_coord>::iround(v * poly_subpixel_scale);
+ }
+ static int downscale(int v) { return v; }
+ };
+
+ //---------------------------------------------------------ras_conv_int_3x
+ struct ras_conv_int_3x
+ {
+ typedef int coord_type;
+ static AGG_INLINE int mul_div(double a, double b, double c)
+ {
+ return iround(a * b / c);
+ }
+ static int xi(int v) { return v * 3; }
+ static int yi(int v) { return v; }
+ static int upscale(double v) { return iround(v * poly_subpixel_scale); }
+ static int downscale(int v) { return v; }
+ };
+
+ //-----------------------------------------------------------ras_conv_dbl
+ struct ras_conv_dbl
+ {
+ typedef double coord_type;
+ static AGG_INLINE double mul_div(double a, double b, double c)
+ {
+ return a * b / c;
+ }
+ static int xi(double v) { return iround(v * poly_subpixel_scale); }
+ static int yi(double v) { return iround(v * poly_subpixel_scale); }
+ static double upscale(double v) { return v; }
+ static double downscale(int v) { return v / double(poly_subpixel_scale); }
+ };
+
+ //--------------------------------------------------------ras_conv_dbl_3x
+ struct ras_conv_dbl_3x
+ {
+ typedef double coord_type;
+ static AGG_INLINE double mul_div(double a, double b, double c)
+ {
+ return a * b / c;
+ }
+ static int xi(double v) { return iround(v * poly_subpixel_scale * 3); }
+ static int yi(double v) { return iround(v * poly_subpixel_scale); }
+ static double upscale(double v) { return v; }
+ static double downscale(int v) { return v / double(poly_subpixel_scale); }
+ };
+
+
+
+
+
+ //------------------------------------------------------rasterizer_sl_clip
+ template<class Conv> class rasterizer_sl_clip
+ {
+ public:
+ typedef Conv conv_type;
+ typedef typename Conv::coord_type coord_type;
+ typedef rect_base<coord_type> rect_type;
+
+ //--------------------------------------------------------------------
+ rasterizer_sl_clip() :
+ m_clip_box(0,0,0,0),
+ m_x1(0),
+ m_y1(0),
+ m_f1(0),
+ m_clipping(false)
+ {}
+
+ //--------------------------------------------------------------------
+ void reset_clipping()
+ {
+ m_clipping = false;
+ }
+
+ //--------------------------------------------------------------------
+ void clip_box(coord_type x1, coord_type y1, coord_type x2, coord_type y2)
+ {
+ m_clip_box = rect_type(x1, y1, x2, y2);
+ m_clip_box.normalize();
+ m_clipping = true;
+ }
+
+ //--------------------------------------------------------------------
+ void move_to(coord_type x1, coord_type y1)
+ {
+ m_x1 = x1;
+ m_y1 = y1;
+ if(m_clipping) m_f1 = clipping_flags(x1, y1, m_clip_box);
+ }
+
+ private:
+ //------------------------------------------------------------------------
+ template<class Rasterizer>
+ AGG_INLINE void line_clip_y(Rasterizer& ras,
+ coord_type x1, coord_type y1,
+ coord_type x2, coord_type y2,
+ unsigned f1, unsigned f2) const
+ {
+ f1 &= 10;
+ f2 &= 10;
+ if((f1 | f2) == 0)
+ {
+ // Fully visible
+ ras.line(Conv::xi(x1), Conv::yi(y1), Conv::xi(x2), Conv::yi(y2));
+ }
+ else
+ {
+ if(f1 == f2)
+ {
+ // Invisible by Y
+ return;
+ }
+
+ coord_type tx1 = x1;
+ coord_type ty1 = y1;
+ coord_type tx2 = x2;
+ coord_type ty2 = y2;
+
+ if(f1 & 8) // y1 < clip.y1
+ {
+ tx1 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1);
+ ty1 = m_clip_box.y1;
+ }
+
+ if(f1 & 2) // y1 > clip.y2
+ {
+ tx1 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1);
+ ty1 = m_clip_box.y2;
+ }
+
+ if(f2 & 8) // y2 < clip.y1
+ {
+ tx2 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1);
+ ty2 = m_clip_box.y1;
+ }
+
+ if(f2 & 2) // y2 > clip.y2
+ {
+ tx2 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1);
+ ty2 = m_clip_box.y2;
+ }
+ ras.line(Conv::xi(tx1), Conv::yi(ty1),
+ Conv::xi(tx2), Conv::yi(ty2));
+ }
+ }
+
+
+ public:
+ //--------------------------------------------------------------------
+ template<class Rasterizer>
+ void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
+ {
+ if(m_clipping)
+ {
+ unsigned f2 = clipping_flags(x2, y2, m_clip_box);
+
+ if((m_f1 & 10) == (f2 & 10) && (m_f1 & 10) != 0)
+ {
+ // Invisible by Y
+ m_x1 = x2;
+ m_y1 = y2;
+ m_f1 = f2;
+ return;
+ }
+
+ coord_type x1 = m_x1;
+ coord_type y1 = m_y1;
+ unsigned f1 = m_f1;
+ coord_type y3, y4;
+ unsigned f3, f4;
+
+ switch(((f1 & 5) << 1) | (f2 & 5))
+ {
+ case 0: // Visible by X
+ line_clip_y(ras, x1, y1, x2, y2, f1, f2);
+ break;
+
+ case 1: // x2 > clip.x2
+ y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
+ f3 = clipping_flags_y(y3, m_clip_box);
+ line_clip_y(ras, x1, y1, m_clip_box.x2, y3, f1, f3);
+ line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x2, y2, f3, f2);
+ break;
+
+ case 2: // x1 > clip.x2
+ y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
+ f3 = clipping_flags_y(y3, m_clip_box);
+ line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3);
+ line_clip_y(ras, m_clip_box.x2, y3, x2, y2, f3, f2);
+ break;
+
+ case 3: // x1 > clip.x2 && x2 > clip.x2
+ line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y2, f1, f2);
+ break;
+
+ case 4: // x2 < clip.x1
+ y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
+ f3 = clipping_flags_y(y3, m_clip_box);
+ line_clip_y(ras, x1, y1, m_clip_box.x1, y3, f1, f3);
+ line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x1, y2, f3, f2);
+ break;
+
+ case 6: // x1 > clip.x2 && x2 < clip.x1
+ y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
+ y4 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
+ f3 = clipping_flags_y(y3, m_clip_box);
+ f4 = clipping_flags_y(y4, m_clip_box);
+ line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3);
+ line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x1, y4, f3, f4);
+ line_clip_y(ras, m_clip_box.x1, y4, m_clip_box.x1, y2, f4, f2);
+ break;
+
+ case 8: // x1 < clip.x1
+ y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
+ f3 = clipping_flags_y(y3, m_clip_box);
+ line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3);
+ line_clip_y(ras, m_clip_box.x1, y3, x2, y2, f3, f2);
+ break;
+
+ case 9: // x1 < clip.x1 && x2 > clip.x2
+ y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
+ y4 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
+ f3 = clipping_flags_y(y3, m_clip_box);
+ f4 = clipping_flags_y(y4, m_clip_box);
+ line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3);
+ line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x2, y4, f3, f4);
+ line_clip_y(ras, m_clip_box.x2, y4, m_clip_box.x2, y2, f4, f2);
+ break;
+
+ case 12: // x1 < clip.x1 && x2 < clip.x1
+ line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y2, f1, f2);
+ break;
+ }
+ m_f1 = f2;
+ }
+ else
+ {
+ ras.line(Conv::xi(m_x1), Conv::yi(m_y1),
+ Conv::xi(x2), Conv::yi(y2));
+ }
+ m_x1 = x2;
+ m_y1 = y2;
+ }
+
+
+ private:
+ rect_type m_clip_box;
+ coord_type m_x1;
+ coord_type m_y1;
+ unsigned m_f1;
+ bool m_clipping;
+ };
+
+
+
+
+ //---------------------------------------------------rasterizer_sl_no_clip
+ class rasterizer_sl_no_clip
+ {
+ public:
+ typedef ras_conv_int conv_type;
+ typedef int coord_type;
+
+ rasterizer_sl_no_clip() : m_x1(0), m_y1(0) {}
+
+ void reset_clipping() {}
+ void clip_box(coord_type, coord_type, coord_type, coord_type) {}
+ void move_to(coord_type x1, coord_type y1) { m_x1 = x1; m_y1 = y1; }
+
+ template<class Rasterizer>
+ void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
+ {
+ ras.line(m_x1, m_y1, x2, y2);
+ m_x1 = x2;
+ m_y1 = y2;
+ }
+
+ private:
+ int m_x1, m_y1;
+ };
+
+
+ // -----rasterizer_sl_clip_int
+ // -----rasterizer_sl_clip_int_sat
+ // -----rasterizer_sl_clip_int_3x
+ // -----rasterizer_sl_clip_dbl
+ // -----rasterizer_sl_clip_dbl_3x
+ //------------------------------------------------------------------------
+ typedef rasterizer_sl_clip<ras_conv_int> rasterizer_sl_clip_int;
+ typedef rasterizer_sl_clip<ras_conv_int_sat> rasterizer_sl_clip_int_sat;
+ typedef rasterizer_sl_clip<ras_conv_int_3x> rasterizer_sl_clip_int_3x;
+ typedef rasterizer_sl_clip<ras_conv_dbl> rasterizer_sl_clip_dbl;
+ typedef rasterizer_sl_clip<ras_conv_dbl_3x> rasterizer_sl_clip_dbl_3x;
+
+
+}
+
+#endif