Revert "WIP: SVG import & rasterization"

This reverts commit 9b15908a47.
This commit is contained in:
bubnikv 2019-02-07 12:09:10 +01:00
parent a178a0ff7e
commit 34b14eb8fa
59 changed files with 3609 additions and 10669 deletions

View file

@ -1,7 +1,6 @@
project(Slic3r-native)
add_subdirectory(admesh)
add_subdirectory(agg_svg)
add_subdirectory(avrdude)
# boost/nowide
add_subdirectory(boost)

View file

@ -1,3 +1,2 @@
Anti-Grain Geometry (AGG) - Version 2.5
A high quality rendering engine for C++
Copyright (C) 2002-2006 Maxim Shemanarev
Anti-Grain Geometry - Version 2.4
Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)

View file

@ -1,21 +0,0 @@
Anti-Grain Geometry (AGG) - Version 2.5
A high quality rendering engine for C++
Copyright (C) 2002-2006 Maxim Shemanarev
Contact: mcseem@antigrain.com
mcseemagg@yahoo.com
http://antigrain.com
AGG is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
AGG is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with AGG; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.

2
src/agg/VERSION Normal file
View file

@ -0,0 +1,2 @@
2.4
svn revision 128

View file

@ -1,27 +1,17 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// 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://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_ARRAY_INCLUDED
#define AGG_ARRAY_INCLUDED

View file

@ -1,31 +1,22 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// 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://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_BASICS_INCLUDED
#define AGG_BASICS_INCLUDED
#include <math.h>
#include <cmath>
#include "agg_config.h"
//---------------------------------------------------------AGG_CUSTOM_ALLOCATOR
@ -152,10 +143,18 @@ namespace agg
__asm mov eax, dword ptr [t]
}
#pragma warning(pop)
AGG_INLINE int ifloor(double v)
{
return int(floor(v));
}
AGG_INLINE unsigned ufloor(double v) //-------ufloor
{
return unsigned(floor(v));
}
AGG_INLINE int iceil(double v)
{
return int(ceil(v));
}
AGG_INLINE unsigned uceil(double v) //--------uceil
{
return unsigned(ceil(v));
@ -169,10 +168,18 @@ namespace agg
{
return unsigned(v);
}
AGG_INLINE int ifloor(double v)
{
return int(floor(v));
}
AGG_INLINE unsigned ufloor(double v)
{
return unsigned(floor(v));
}
AGG_INLINE int iceil(double v)
{
return int(ceil(v));
}
AGG_INLINE unsigned uceil(double v)
{
return unsigned(ceil(v));
@ -186,10 +193,19 @@ namespace agg
{
return unsigned(v + 0.5);
}
AGG_INLINE int ifloor(double v)
{
int i = int(v);
return i - (i > v);
}
AGG_INLINE unsigned ufloor(double v)
{
return unsigned(v);
}
AGG_INLINE int iceil(double v)
{
return int(ceil(v));
}
AGG_INLINE unsigned uceil(double v)
{
return unsigned(ceil(v));
@ -212,7 +228,7 @@ namespace agg
{
AGG_INLINE static unsigned mul(unsigned a, unsigned b)
{
register unsigned q = a * b + (1 << (Shift-1));
unsigned q = a * b + (1 << (Shift-1));
return (q + (q >> Shift)) >> Shift;
}
};
@ -238,7 +254,7 @@ namespace agg
{
poly_subpixel_shift = 8, //----poly_subpixel_shift
poly_subpixel_scale = 1<<poly_subpixel_shift, //----poly_subpixel_scale
poly_subpixel_mask = poly_subpixel_scale-1, //----poly_subpixel_mask
poly_subpixel_mask = poly_subpixel_scale-1 //----poly_subpixel_mask
};
//----------------------------------------------------------filling_rule_e
@ -305,6 +321,12 @@ namespace agg
{
return (x >= x1 && x <= x2 && y >= y1 && y <= y2);
}
bool overlaps(const self_type& r) const
{
return !(r.x1 > x2 || r.x2 < x1
|| r.y1 > y2 || r.y2 < y1);
}
};
//-----------------------------------------------------intersect_rectangles
@ -529,9 +551,22 @@ namespace agg
//------------------------------------------------------------is_equal_eps
template<class T> inline bool is_equal_eps(T v1, T v2, T epsilon)
{
return fabs(v1 - v2) <= double(epsilon);
}
bool neg1 = v1 < 0.0;
bool neg2 = v2 < 0.0;
if (neg1 != neg2)
return std::fabs(v1) < epsilon && std::fabs(v2) < epsilon;
int int1, int2;
std::frexp(v1, &int1);
std::frexp(v2, &int2);
int min12 = int1 < int2 ? int1 : int2;
v1 = std::ldexp(v1, -min12);
v2 = std::ldexp(v2, -min12);
return std::fabs(v1 - v2) < epsilon;
}
}

View file

@ -1,25 +1,21 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// 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://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e.,
// 4, 7, 10, or 13 vertices.
//
//----------------------------------------------------------------------------
#ifndef AGG_BEZIER_ARC_INCLUDED
@ -72,7 +68,7 @@ namespace agg
*x = m_vertices[m_vertex];
*y = m_vertices[m_vertex + 1];
m_vertex += 2;
return (m_vertex == 2) ? path_cmd_move_to : m_cmd;
return (m_vertex == 2) ? unsigned(path_cmd_move_to) : m_cmd;
}
// Supplemantary functions. num_vertices() actually returns doubled

View file

@ -1,122 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#ifndef AGG_BOUNDING_RECT_INCLUDED
#define AGG_BOUNDING_RECT_INCLUDED
#include "agg_basics.h"
namespace agg
{
//-----------------------------------------------------------bounding_rect
template<class VertexSource, class GetId, class CoordT>
bool bounding_rect(VertexSource& vs, GetId& gi,
unsigned start, unsigned num,
CoordT* x1, CoordT* y1, CoordT* x2, CoordT* y2)
{
unsigned i;
double x;
double y;
bool first = true;
*x1 = CoordT(1);
*y1 = CoordT(1);
*x2 = CoordT(0);
*y2 = CoordT(0);
for(i = 0; i < num; i++)
{
vs.rewind(gi[start + i]);
unsigned cmd;
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
if(is_vertex(cmd))
{
if(first)
{
*x1 = CoordT(x);
*y1 = CoordT(y);
*x2 = CoordT(x);
*y2 = CoordT(y);
first = false;
}
else
{
if(CoordT(x) < *x1) *x1 = CoordT(x);
if(CoordT(y) < *y1) *y1 = CoordT(y);
if(CoordT(x) > *x2) *x2 = CoordT(x);
if(CoordT(y) > *y2) *y2 = CoordT(y);
}
}
}
}
return *x1 <= *x2 && *y1 <= *y2;
}
//-----------------------------------------------------bounding_rect_single
template<class VertexSource, class CoordT>
bool bounding_rect_single(VertexSource& vs, unsigned path_id,
CoordT* x1, CoordT* y1, CoordT* x2, CoordT* y2)
{
double x;
double y;
bool first = true;
*x1 = CoordT(1);
*y1 = CoordT(1);
*x2 = CoordT(0);
*y2 = CoordT(0);
vs.rewind(path_id);
unsigned cmd;
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
if(is_vertex(cmd))
{
if(first)
{
*x1 = CoordT(x);
*y1 = CoordT(y);
*x2 = CoordT(x);
*y2 = CoordT(y);
first = false;
}
else
{
if(CoordT(x) < *x1) *x1 = CoordT(x);
if(CoordT(y) < *y1) *y1 = CoordT(y);
if(CoordT(x) > *x2) *x2 = CoordT(x);
if(CoordT(y) > *y2) *y2 = CoordT(y);
}
}
}
return *x1 <= *x2 && *y1 <= *y2;
}
}
#endif

View file

@ -1,27 +1,21 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// 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://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Liang-Barsky clipping
//
//----------------------------------------------------------------------------
#ifndef AGG_CLIP_LIANG_BARSKY_INCLUDED
#define AGG_CLIP_LIANG_BARSKY_INCLUDED

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -37,7 +37,7 @@
// Provides cheaper creation and destruction (no mem allocs):
// #define AGG_RENDERING_BUFFER row_accessor<int8u>
//
// You can still use both of them simultaneouslyin your applications
// You can still use both of them simultaneously in your applications
// This #define is used only for default rendering_buffer type,
// in short hand typedefs like pixfmt_rgba32.

View file

@ -1,166 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#ifndef AGG_CONV_ADAPTOR_VCGEN_INCLUDED
#define AGG_CONV_ADAPTOR_VCGEN_INCLUDED
#include "agg_basics.h"
namespace agg
{
//------------------------------------------------------------null_markers
struct null_markers
{
void remove_all() {}
void add_vertex(double, double, unsigned) {}
void prepare_src() {}
void rewind(unsigned) {}
unsigned vertex(double*, double*) { return path_cmd_stop; }
};
//------------------------------------------------------conv_adaptor_vcgen
template<class VertexSource,
class Generator,
class Markers=null_markers> class conv_adaptor_vcgen
{
enum status
{
initial,
accumulate,
generate
};
public:
explicit conv_adaptor_vcgen(VertexSource& source) :
m_source(&source),
m_status(initial)
{}
void attach(VertexSource& source) { m_source = &source; }
Generator& generator() { return m_generator; }
const Generator& generator() const { return m_generator; }
Markers& markers() { return m_markers; }
const Markers& markers() const { return m_markers; }
void rewind(unsigned path_id)
{
m_source->rewind(path_id);
m_status = initial;
}
unsigned vertex(double* x, double* y);
private:
// Prohibit copying
conv_adaptor_vcgen(const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
const conv_adaptor_vcgen<VertexSource, Generator, Markers>&
operator = (const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
VertexSource* m_source;
Generator m_generator;
Markers m_markers;
status m_status;
unsigned m_last_cmd;
double m_start_x;
double m_start_y;
};
//------------------------------------------------------------------------
template<class VertexSource, class Generator, class Markers>
unsigned conv_adaptor_vcgen<VertexSource, Generator, Markers>::vertex(double* x, double* y)
{
unsigned cmd = path_cmd_stop;
bool done = false;
while(!done)
{
switch(m_status)
{
case initial:
m_markers.remove_all();
m_last_cmd = m_source->vertex(&m_start_x, &m_start_y);
m_status = accumulate;
case accumulate:
if(is_stop(m_last_cmd)) return path_cmd_stop;
m_generator.remove_all();
m_generator.add_vertex(m_start_x, m_start_y, path_cmd_move_to);
m_markers.add_vertex(m_start_x, m_start_y, path_cmd_move_to);
for(;;)
{
cmd = m_source->vertex(x, y);
if(is_vertex(cmd))
{
m_last_cmd = cmd;
if(is_move_to(cmd))
{
m_start_x = *x;
m_start_y = *y;
break;
}
m_generator.add_vertex(*x, *y, cmd);
m_markers.add_vertex(*x, *y, path_cmd_line_to);
}
else
{
if(is_stop(cmd))
{
m_last_cmd = path_cmd_stop;
break;
}
if(is_end_poly(cmd))
{
m_generator.add_vertex(*x, *y, cmd);
break;
}
}
}
m_generator.rewind(0);
m_status = generate;
case generate:
cmd = m_generator.vertex(x, y);
if(is_stop(cmd))
{
m_status = accumulate;
break;
}
done = true;
break;
}
}
return cmd;
}
}
#endif

View file

@ -1,71 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#ifndef AGG_CONV_CONTOUR_INCLUDED
#define AGG_CONV_CONTOUR_INCLUDED
#include "agg_basics.h"
#include "agg_vcgen_contour.h"
#include "agg_conv_adaptor_vcgen.h"
namespace agg
{
//-----------------------------------------------------------conv_contour
template<class VertexSource>
struct conv_contour : public conv_adaptor_vcgen<VertexSource, vcgen_contour>
{
typedef conv_adaptor_vcgen<VertexSource, vcgen_contour> base_type;
conv_contour(VertexSource& vs) :
conv_adaptor_vcgen<VertexSource, vcgen_contour>(vs)
{
}
void line_join(line_join_e lj) { base_type::generator().line_join(lj); }
void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); }
void width(double w) { base_type::generator().width(w); }
void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); }
void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); }
void approximation_scale(double as) { base_type::generator().approximation_scale(as); }
void auto_detect_orientation(bool v) { base_type::generator().auto_detect_orientation(v); }
line_join_e line_join() const { return base_type::generator().line_join(); }
inner_join_e inner_join() const { return base_type::generator().inner_join(); }
double width() const { return base_type::generator().width(); }
double miter_limit() const { return base_type::generator().miter_limit(); }
double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); }
double approximation_scale() const { return base_type::generator().approximation_scale(); }
bool auto_detect_orientation() const { return base_type::generator().auto_detect_orientation(); }
private:
conv_contour(const conv_contour<VertexSource>&);
const conv_contour<VertexSource>&
operator = (const conv_contour<VertexSource>&);
};
}
#endif

View file

@ -1,206 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#ifndef AGG_CONV_CURVE_INCLUDED
#define AGG_CONV_CURVE_INCLUDED
#include "agg_basics.h"
#include "agg_curves.h"
namespace agg
{
//---------------------------------------------------------------conv_curve
// Curve converter class. Any path storage can have Bezier curves defined
// by their control points. There're two types of curves supported: curve3
// and curve4. Curve3 is a conic Bezier curve with 2 endpoints and 1 control
// point. Curve4 has 2 control points (4 points in total) and can be used
// to interpolate more complicated curves. Curve4, unlike curve3 can be used
// to approximate arcs, both circular and elliptical. Curves are approximated
// with straight lines and one of the approaches is just to store the whole
// sequence of vertices that approximate our curve. It takes additional
// memory, and at the same time the consecutive vertices can be calculated
// on demand.
//
// Initially, path storages are not suppose to keep all the vertices of the
// curves (although, nothing prevents us from doing so). Instead, path_storage
// keeps only vertices, needed to calculate a curve on demand. Those vertices
// are marked with special commands. So, if the path_storage contains curves
// (which are not real curves yet), and we render this storage directly,
// all we will see is only 2 or 3 straight line segments (for curve3 and
// curve4 respectively). If we need to see real curves drawn we need to
// include this class into the conversion pipeline.
//
// Class conv_curve recognizes commands path_cmd_curve3 and path_cmd_curve4
// and converts these vertices into a move_to/line_to sequence.
//-----------------------------------------------------------------------
template<class VertexSource,
class Curve3=curve3,
class Curve4=curve4> class conv_curve
{
public:
typedef Curve3 curve3_type;
typedef Curve4 curve4_type;
typedef conv_curve<VertexSource, Curve3, Curve4> self_type;
explicit conv_curve(VertexSource& source) :
m_source(&source), m_last_x(0.0), m_last_y(0.0) {}
void attach(VertexSource& source) { m_source = &source; }
void approximation_method(curve_approximation_method_e v)
{
m_curve3.approximation_method(v);
m_curve4.approximation_method(v);
}
curve_approximation_method_e approximation_method() const
{
return m_curve4.approximation_method();
}
void approximation_scale(double s)
{
m_curve3.approximation_scale(s);
m_curve4.approximation_scale(s);
}
double approximation_scale() const
{
return m_curve4.approximation_scale();
}
void angle_tolerance(double v)
{
m_curve3.angle_tolerance(v);
m_curve4.angle_tolerance(v);
}
double angle_tolerance() const
{
return m_curve4.angle_tolerance();
}
void cusp_limit(double v)
{
m_curve3.cusp_limit(v);
m_curve4.cusp_limit(v);
}
double cusp_limit() const
{
return m_curve4.cusp_limit();
}
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
conv_curve(const self_type&);
const self_type& operator = (const self_type&);
VertexSource* m_source;
double m_last_x;
double m_last_y;
curve3_type m_curve3;
curve4_type m_curve4;
};
//------------------------------------------------------------------------
template<class VertexSource, class Curve3, class Curve4>
void conv_curve<VertexSource, Curve3, Curve4>::rewind(unsigned path_id)
{
m_source->rewind(path_id);
m_last_x = 0.0;
m_last_y = 0.0;
m_curve3.reset();
m_curve4.reset();
}
//------------------------------------------------------------------------
template<class VertexSource, class Curve3, class Curve4>
unsigned conv_curve<VertexSource, Curve3, Curve4>::vertex(double* x, double* y)
{
if(!is_stop(m_curve3.vertex(x, y)))
{
m_last_x = *x;
m_last_y = *y;
return path_cmd_line_to;
}
if(!is_stop(m_curve4.vertex(x, y)))
{
m_last_x = *x;
m_last_y = *y;
return path_cmd_line_to;
}
double ct2_x;
double ct2_y;
double end_x;
double end_y;
unsigned cmd = m_source->vertex(x, y);
switch(cmd)
{
case path_cmd_curve3:
m_source->vertex(&end_x, &end_y);
m_curve3.init(m_last_x, m_last_y,
*x, *y,
end_x, end_y);
m_curve3.vertex(x, y); // First call returns path_cmd_move_to
m_curve3.vertex(x, y); // This is the first vertex of the curve
cmd = path_cmd_line_to;
break;
case path_cmd_curve4:
m_source->vertex(&ct2_x, &ct2_y);
m_source->vertex(&end_x, &end_y);
m_curve4.init(m_last_x, m_last_y,
*x, *y,
ct2_x, ct2_y,
end_x, end_y);
m_curve4.vertex(x, y); // First call returns path_cmd_move_to
m_curve4.vertex(x, y); // This is the first vertex of the curve
cmd = path_cmd_line_to;
break;
}
m_last_x = *x;
m_last_y = *y;
return cmd;
}
}
#endif

View file

@ -1,79 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#ifndef AGG_CONV_STROKE_INCLUDED
#define AGG_CONV_STROKE_INCLUDED
#include "agg_basics.h"
#include "agg_vcgen_stroke.h"
#include "agg_conv_adaptor_vcgen.h"
namespace agg
{
//-------------------------------------------------------------conv_stroke
template<class VertexSource, class Markers=null_markers>
struct conv_stroke :
public conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers>
{
typedef Markers marker_type;
typedef conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers> base_type;
conv_stroke(VertexSource& vs) :
conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers>(vs)
{
}
void line_cap(line_cap_e lc) { base_type::generator().line_cap(lc); }
void line_join(line_join_e lj) { base_type::generator().line_join(lj); }
void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); }
line_cap_e line_cap() const { return base_type::generator().line_cap(); }
line_join_e line_join() const { return base_type::generator().line_join(); }
inner_join_e inner_join() const { return base_type::generator().inner_join(); }
void width(double w) { base_type::generator().width(w); }
void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); }
void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); }
void approximation_scale(double as) { base_type::generator().approximation_scale(as); }
double width() const { return base_type::generator().width(); }
double miter_limit() const { return base_type::generator().miter_limit(); }
double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); }
double approximation_scale() const { return base_type::generator().approximation_scale(); }
void shorten(double s) { base_type::generator().shorten(s); }
double shorten() const { return base_type::generator().shorten(); }
private:
conv_stroke(const conv_stroke<VertexSource, Markers>&);
const conv_stroke<VertexSource, Markers>&
operator = (const conv_stroke<VertexSource, Markers>&);
};
}
#endif

View file

@ -1,27 +1,21 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// 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://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// class conv_transform
//
//----------------------------------------------------------------------------
#ifndef AGG_CONV_TRANSFORM_INCLUDED
#define AGG_CONV_TRANSFORM_INCLUDED
@ -35,7 +29,7 @@ namespace agg
template<class VertexSource, class Transformer=trans_affine> class conv_transform
{
public:
conv_transform(VertexSource& source, const Transformer& tr) :
conv_transform(VertexSource& source, Transformer& tr) :
m_source(&source), m_trans(&tr) {}
void attach(VertexSource& source) { m_source = &source; }
@ -54,7 +48,7 @@ namespace agg
return cmd;
}
void transformer(const Transformer& tr)
void transformer(Transformer& tr)
{
m_trans = &tr;
}
@ -65,7 +59,7 @@ namespace agg
operator = (const conv_transform<VertexSource>&);
VertexSource* m_source;
const Transformer* m_trans;
Transformer* m_trans;
};

View file

@ -1,701 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#ifndef AGG_CURVES_INCLUDED
#define AGG_CURVES_INCLUDED
#include "agg_array.h"
namespace agg
{
// See Implementation agg_curves.cpp
//--------------------------------------------curve_approximation_method_e
enum curve_approximation_method_e
{
curve_inc,
curve_div
};
//--------------------------------------------------------------curve3_inc
class curve3_inc
{
public:
curve3_inc() :
m_num_steps(0), m_step(0), m_scale(1.0) { }
curve3_inc(double x1, double y1,
double x2, double y2,
double x3, double y3) :
m_num_steps(0), m_step(0), m_scale(1.0)
{
init(x1, y1, x2, y2, x3, y3);
}
void reset() { m_num_steps = 0; m_step = -1; }
void init(double x1, double y1,
double x2, double y2,
double x3, double y3);
void approximation_method(curve_approximation_method_e) {}
curve_approximation_method_e approximation_method() const { return curve_inc; }
void approximation_scale(double s);
double approximation_scale() const;
void angle_tolerance(double) {}
double angle_tolerance() const { return 0.0; }
void cusp_limit(double) {}
double cusp_limit() const { return 0.0; }
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
int m_num_steps;
int m_step;
double m_scale;
double m_start_x;
double m_start_y;
double m_end_x;
double m_end_y;
double m_fx;
double m_fy;
double m_dfx;
double m_dfy;
double m_ddfx;
double m_ddfy;
double m_saved_fx;
double m_saved_fy;
double m_saved_dfx;
double m_saved_dfy;
};
//-------------------------------------------------------------curve3_div
class curve3_div
{
public:
curve3_div() :
m_approximation_scale(1.0),
m_angle_tolerance(0.0),
m_count(0)
{}
curve3_div(double x1, double y1,
double x2, double y2,
double x3, double y3) :
m_approximation_scale(1.0),
m_angle_tolerance(0.0),
m_count(0)
{
init(x1, y1, x2, y2, x3, y3);
}
void reset() { m_points.remove_all(); m_count = 0; }
void init(double x1, double y1,
double x2, double y2,
double x3, double y3);
void approximation_method(curve_approximation_method_e) {}
curve_approximation_method_e approximation_method() const { return curve_div; }
void approximation_scale(double s) { m_approximation_scale = s; }
double approximation_scale() const { return m_approximation_scale; }
void angle_tolerance(double a) { m_angle_tolerance = a; }
double angle_tolerance() const { return m_angle_tolerance; }
void cusp_limit(double) {}
double cusp_limit() const { return 0.0; }
void rewind(unsigned)
{
m_count = 0;
}
unsigned vertex(double* x, double* y)
{
if(m_count >= m_points.size()) return path_cmd_stop;
const point_d& p = m_points[m_count++];
*x = p.x;
*y = p.y;
return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to;
}
private:
void bezier(double x1, double y1,
double x2, double y2,
double x3, double y3);
void recursive_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
unsigned level);
double m_approximation_scale;
double m_distance_tolerance_square;
double m_angle_tolerance;
unsigned m_count;
pod_bvector<point_d> m_points;
};
//-------------------------------------------------------------curve4_points
struct curve4_points
{
double cp[8];
curve4_points() {}
curve4_points(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2;
cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4;
}
void init(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2;
cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4;
}
double operator [] (unsigned i) const { return cp[i]; }
double& operator [] (unsigned i) { return cp[i]; }
};
//-------------------------------------------------------------curve4_inc
class curve4_inc
{
public:
curve4_inc() :
m_num_steps(0), m_step(0), m_scale(1.0) { }
curve4_inc(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4) :
m_num_steps(0), m_step(0), m_scale(1.0)
{
init(x1, y1, x2, y2, x3, y3, x4, y4);
}
curve4_inc(const curve4_points& cp) :
m_num_steps(0), m_step(0), m_scale(1.0)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void reset() { m_num_steps = 0; m_step = -1; }
void init(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4);
void init(const curve4_points& cp)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void approximation_method(curve_approximation_method_e) {}
curve_approximation_method_e approximation_method() const { return curve_inc; }
void approximation_scale(double s);
double approximation_scale() const;
void angle_tolerance(double) {}
double angle_tolerance() const { return 0.0; }
void cusp_limit(double) {}
double cusp_limit() const { return 0.0; }
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
int m_num_steps;
int m_step;
double m_scale;
double m_start_x;
double m_start_y;
double m_end_x;
double m_end_y;
double m_fx;
double m_fy;
double m_dfx;
double m_dfy;
double m_ddfx;
double m_ddfy;
double m_dddfx;
double m_dddfy;
double m_saved_fx;
double m_saved_fy;
double m_saved_dfx;
double m_saved_dfy;
double m_saved_ddfx;
double m_saved_ddfy;
};
//-------------------------------------------------------catrom_to_bezier
inline curve4_points catrom_to_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
// Trans. matrix Catmull-Rom to Bezier
//
// 0 1 0 0
// -1/6 1 1/6 0
// 0 1/6 1 -1/6
// 0 0 1 0
//
return curve4_points(
x2,
y2,
(-x1 + 6*x2 + x3) / 6,
(-y1 + 6*y2 + y3) / 6,
( x2 + 6*x3 - x4) / 6,
( y2 + 6*y3 - y4) / 6,
x3,
y3);
}
//-----------------------------------------------------------------------
inline curve4_points
catrom_to_bezier(const curve4_points& cp)
{
return catrom_to_bezier(cp[0], cp[1], cp[2], cp[3],
cp[4], cp[5], cp[6], cp[7]);
}
//-----------------------------------------------------ubspline_to_bezier
inline curve4_points ubspline_to_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
// Trans. matrix Uniform BSpline to Bezier
//
// 1/6 4/6 1/6 0
// 0 4/6 2/6 0
// 0 2/6 4/6 0
// 0 1/6 4/6 1/6
//
return curve4_points(
(x1 + 4*x2 + x3) / 6,
(y1 + 4*y2 + y3) / 6,
(4*x2 + 2*x3) / 6,
(4*y2 + 2*y3) / 6,
(2*x2 + 4*x3) / 6,
(2*y2 + 4*y3) / 6,
(x2 + 4*x3 + x4) / 6,
(y2 + 4*y3 + y4) / 6);
}
//-----------------------------------------------------------------------
inline curve4_points
ubspline_to_bezier(const curve4_points& cp)
{
return ubspline_to_bezier(cp[0], cp[1], cp[2], cp[3],
cp[4], cp[5], cp[6], cp[7]);
}
//------------------------------------------------------hermite_to_bezier
inline curve4_points hermite_to_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
// Trans. matrix Hermite to Bezier
//
// 1 0 0 0
// 1 0 1/3 0
// 0 1 0 -1/3
// 0 1 0 0
//
return curve4_points(
x1,
y1,
(3*x1 + x3) / 3,
(3*y1 + y3) / 3,
(3*x2 - x4) / 3,
(3*y2 - y4) / 3,
x2,
y2);
}
//-----------------------------------------------------------------------
inline curve4_points
hermite_to_bezier(const curve4_points& cp)
{
return hermite_to_bezier(cp[0], cp[1], cp[2], cp[3],
cp[4], cp[5], cp[6], cp[7]);
}
//-------------------------------------------------------------curve4_div
class curve4_div
{
public:
curve4_div() :
m_approximation_scale(1.0),
m_angle_tolerance(0.0),
m_cusp_limit(0.0),
m_count(0)
{}
curve4_div(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4) :
m_approximation_scale(1.0),
m_angle_tolerance(0.0),
m_cusp_limit(0.0),
m_count(0)
{
init(x1, y1, x2, y2, x3, y3, x4, y4);
}
curve4_div(const curve4_points& cp) :
m_approximation_scale(1.0),
m_angle_tolerance(0.0),
m_count(0)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void reset() { m_points.remove_all(); m_count = 0; }
void init(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4);
void init(const curve4_points& cp)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void approximation_method(curve_approximation_method_e) {}
curve_approximation_method_e approximation_method() const
{
return curve_div;
}
void approximation_scale(double s) { m_approximation_scale = s; }
double approximation_scale() const { return m_approximation_scale; }
void angle_tolerance(double a) { m_angle_tolerance = a; }
double angle_tolerance() const { return m_angle_tolerance; }
void cusp_limit(double v)
{
m_cusp_limit = (v == 0.0) ? 0.0 : pi - v;
}
double cusp_limit() const
{
return (m_cusp_limit == 0.0) ? 0.0 : pi - m_cusp_limit;
}
void rewind(unsigned)
{
m_count = 0;
}
unsigned vertex(double* x, double* y)
{
if(m_count >= m_points.size()) return path_cmd_stop;
const point_d& p = m_points[m_count++];
*x = p.x;
*y = p.y;
return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to;
}
private:
void bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4);
void recursive_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4,
unsigned level);
double m_approximation_scale;
double m_distance_tolerance_square;
double m_angle_tolerance;
double m_cusp_limit;
unsigned m_count;
pod_bvector<point_d> m_points;
};
//-----------------------------------------------------------------curve3
class curve3
{
public:
curve3() : m_approximation_method(curve_div) {}
curve3(double x1, double y1,
double x2, double y2,
double x3, double y3) :
m_approximation_method(curve_div)
{
init(x1, y1, x2, y2, x3, y3);
}
void reset()
{
m_curve_inc.reset();
m_curve_div.reset();
}
void init(double x1, double y1,
double x2, double y2,
double x3, double y3)
{
if(m_approximation_method == curve_inc)
{
m_curve_inc.init(x1, y1, x2, y2, x3, y3);
}
else
{
m_curve_div.init(x1, y1, x2, y2, x3, y3);
}
}
void approximation_method(curve_approximation_method_e v)
{
m_approximation_method = v;
}
curve_approximation_method_e approximation_method() const
{
return m_approximation_method;
}
void approximation_scale(double s)
{
m_curve_inc.approximation_scale(s);
m_curve_div.approximation_scale(s);
}
double approximation_scale() const
{
return m_curve_inc.approximation_scale();
}
void angle_tolerance(double a)
{
m_curve_div.angle_tolerance(a);
}
double angle_tolerance() const
{
return m_curve_div.angle_tolerance();
}
void cusp_limit(double v)
{
m_curve_div.cusp_limit(v);
}
double cusp_limit() const
{
return m_curve_div.cusp_limit();
}
void rewind(unsigned path_id)
{
if(m_approximation_method == curve_inc)
{
m_curve_inc.rewind(path_id);
}
else
{
m_curve_div.rewind(path_id);
}
}
unsigned vertex(double* x, double* y)
{
if(m_approximation_method == curve_inc)
{
return m_curve_inc.vertex(x, y);
}
return m_curve_div.vertex(x, y);
}
private:
curve3_inc m_curve_inc;
curve3_div m_curve_div;
curve_approximation_method_e m_approximation_method;
};
//-----------------------------------------------------------------curve4
class curve4
{
public:
curve4() : m_approximation_method(curve_div) {}
curve4(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4) :
m_approximation_method(curve_div)
{
init(x1, y1, x2, y2, x3, y3, x4, y4);
}
curve4(const curve4_points& cp) :
m_approximation_method(curve_div)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void reset()
{
m_curve_inc.reset();
m_curve_div.reset();
}
void init(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
if(m_approximation_method == curve_inc)
{
m_curve_inc.init(x1, y1, x2, y2, x3, y3, x4, y4);
}
else
{
m_curve_div.init(x1, y1, x2, y2, x3, y3, x4, y4);
}
}
void init(const curve4_points& cp)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void approximation_method(curve_approximation_method_e v)
{
m_approximation_method = v;
}
curve_approximation_method_e approximation_method() const
{
return m_approximation_method;
}
void approximation_scale(double s)
{
m_curve_inc.approximation_scale(s);
m_curve_div.approximation_scale(s);
}
double approximation_scale() const { return m_curve_inc.approximation_scale(); }
void angle_tolerance(double v)
{
m_curve_div.angle_tolerance(v);
}
double angle_tolerance() const
{
return m_curve_div.angle_tolerance();
}
void cusp_limit(double v)
{
m_curve_div.cusp_limit(v);
}
double cusp_limit() const
{
return m_curve_div.cusp_limit();
}
void rewind(unsigned path_id)
{
if(m_approximation_method == curve_inc)
{
m_curve_inc.rewind(path_id);
}
else
{
m_curve_div.rewind(path_id);
}
}
unsigned vertex(double* x, double* y)
{
if(m_approximation_method == curve_inc)
{
return m_curve_inc.vertex(x, y);
}
return m_curve_div.vertex(x, y);
}
private:
curve4_inc m_curve_inc;
curve4_div m_curve_div;
curve_approximation_method_e m_approximation_method;
};
}
#endif

View file

@ -1,25 +1,16 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// 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://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_GAMMA_FUNCTIONS_INCLUDED
@ -124,6 +115,15 @@ namespace agg
double m_mul;
};
inline double sRGB_to_linear(double x)
{
return (x <= 0.04045) ? (x / 12.92) : pow((x + 0.055) / (1.055), 2.4);
}
inline double linear_to_sRGB(double x)
{
return (x <= 0.0031308) ? (x * 12.92) : (1.055 * pow(x, 1 / 2.4) - 0.055);
}
}
#endif

View file

@ -1,25 +1,16 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// 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://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_GAMMA_LUT_INCLUDED
@ -27,6 +18,7 @@
#include <math.h>
#include "agg_basics.h"
#include "agg_gamma_functions.h"
namespace agg
{
@ -125,6 +117,184 @@ namespace agg
HiResT* m_dir_gamma;
LoResT* m_inv_gamma;
};
//
// sRGB support classes
//
// sRGB_lut - implements sRGB conversion for the various types.
// Base template is undefined, specializations are provided below.
template<class LinearType>
class sRGB_lut;
template<>
class sRGB_lut<float>
{
public:
sRGB_lut()
{
// Generate lookup tables.
for (int i = 0; i <= 255; ++i)
{
m_dir_table[i] = float(sRGB_to_linear(i / 255.0));
}
for (int i = 0; i <= 65535; ++i)
{
m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 65535.0));
}
}
float dir(int8u v) const
{
return m_dir_table[v];
}
int8u inv(float v) const
{
return m_inv_table[int16u(0.5 + v * 65535)];
}
private:
float m_dir_table[256];
int8u m_inv_table[65536];
};
template<>
class sRGB_lut<int16u>
{
public:
sRGB_lut()
{
// Generate lookup tables.
for (int i = 0; i <= 255; ++i)
{
m_dir_table[i] = uround(65535.0 * sRGB_to_linear(i / 255.0));
}
for (int i = 0; i <= 65535; ++i)
{
m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 65535.0));
}
}
int16u dir(int8u v) const
{
return m_dir_table[v];
}
int8u inv(int16u v) const
{
return m_inv_table[v];
}
private:
int16u m_dir_table[256];
int8u m_inv_table[65536];
};
template<>
class sRGB_lut<int8u>
{
public:
sRGB_lut()
{
// Generate lookup tables.
for (int i = 0; i <= 255; ++i)
{
m_dir_table[i] = uround(255.0 * sRGB_to_linear(i / 255.0));
m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 255.0));
}
}
int8u dir(int8u v) const
{
return m_dir_table[v];
}
int8u inv(int8u v) const
{
return m_inv_table[v];
}
private:
int8u m_dir_table[256];
int8u m_inv_table[256];
};
// Common base class for sRGB_conv objects. Defines an internal
// sRGB_lut object so that users don't have to.
template<class T>
class sRGB_conv_base
{
public:
static T rgb_from_sRGB(int8u x)
{
return lut.dir(x);
}
static int8u rgb_to_sRGB(T x)
{
return lut.inv(x);
}
private:
static sRGB_lut<T> lut;
};
// Definition of sRGB_conv_base::lut. Due to the fact that this a template,
// we don't need to place the definition in a cpp file. Hurrah.
template<class T>
sRGB_lut<T> sRGB_conv_base<T>::lut;
// Wrapper for sRGB-linear conversion.
// Base template is undefined, specializations are provided below.
template<class T>
class sRGB_conv;
template<>
class sRGB_conv<float> : public sRGB_conv_base<float>
{
public:
static float alpha_from_sRGB(int8u x)
{
static const double y = 1 / 255.0;
return float(x * y);
}
static int8u alpha_to_sRGB(float x)
{
return int8u(0.5 + x * 255);
}
};
template<>
class sRGB_conv<int16u> : public sRGB_conv_base<int16u>
{
public:
static int16u alpha_from_sRGB(int8u x)
{
return (x << 8) | x;
}
static int8u alpha_to_sRGB(int16u x)
{
return x >> 8;
}
};
template<>
class sRGB_conv<int8u> : public sRGB_conv_base<int8u>
{
public:
static int8u alpha_from_sRGB(int8u x)
{
return x;
}
static int8u alpha_to_sRGB(int8u x)
{
return x;
}
};
}
#endif

View file

@ -1,25 +1,16 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// 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://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// http://www.antigrain.com
//----------------------------------------------------------------------------
// Bessel function (besj) was adapted for use in AGG library by Andy Wilk
// Contact: castor.vulgaris@gmail.com

View file

@ -1,531 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#ifndef AGG_STROKE_MATH_INCLUDED
#define AGG_STROKE_MATH_INCLUDED
#include "agg_math.h"
#include "agg_vertex_sequence.h"
namespace agg
{
//-------------------------------------------------------------line_cap_e
enum line_cap_e
{
butt_cap,
square_cap,
round_cap
};
//------------------------------------------------------------line_join_e
enum line_join_e
{
miter_join = 0,
miter_join_revert = 1,
round_join = 2,
bevel_join = 3,
miter_join_round = 4
};
//-----------------------------------------------------------inner_join_e
enum inner_join_e
{
inner_bevel,
inner_miter,
inner_jag,
inner_round
};
//------------------------------------------------------------math_stroke
template<class VertexConsumer> class math_stroke
{
public:
typedef typename VertexConsumer::value_type coord_type;
math_stroke();
void line_cap(line_cap_e lc) { m_line_cap = lc; }
void line_join(line_join_e lj) { m_line_join = lj; }
void inner_join(inner_join_e ij) { m_inner_join = ij; }
line_cap_e line_cap() const { return m_line_cap; }
line_join_e line_join() const { return m_line_join; }
inner_join_e inner_join() const { return m_inner_join; }
void width(double w);
void miter_limit(double ml) { m_miter_limit = ml; }
void miter_limit_theta(double t);
void inner_miter_limit(double ml) { m_inner_miter_limit = ml; }
void approximation_scale(double as) { m_approx_scale = as; }
double width() const { return m_width * 2.0; }
double miter_limit() const { return m_miter_limit; }
double inner_miter_limit() const { return m_inner_miter_limit; }
double approximation_scale() const { return m_approx_scale; }
void calc_cap(VertexConsumer& vc,
const vertex_dist& v0,
const vertex_dist& v1,
double len);
void calc_join(VertexConsumer& vc,
const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double len1,
double len2);
private:
AGG_INLINE void add_vertex(VertexConsumer& vc, double x, double y)
{
vc.add(coord_type(x, y));
}
void calc_arc(VertexConsumer& vc,
double x, double y,
double dx1, double dy1,
double dx2, double dy2);
void calc_miter(VertexConsumer& vc,
const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double dx1, double dy1,
double dx2, double dy2,
line_join_e lj,
double mlimit,
double dbevel);
double m_width;
double m_width_abs;
double m_width_eps;
int m_width_sign;
double m_miter_limit;
double m_inner_miter_limit;
double m_approx_scale;
line_cap_e m_line_cap;
line_join_e m_line_join;
inner_join_e m_inner_join;
};
//-----------------------------------------------------------------------
template<class VC> math_stroke<VC>::math_stroke() :
m_width(0.5),
m_width_abs(0.5),
m_width_eps(0.5/1024.0),
m_width_sign(1),
m_miter_limit(4.0),
m_inner_miter_limit(1.01),
m_approx_scale(1.0),
m_line_cap(butt_cap),
m_line_join(miter_join),
m_inner_join(inner_miter)
{
}
//-----------------------------------------------------------------------
template<class VC> void math_stroke<VC>::width(double w)
{
m_width = w * 0.5;
if(m_width < 0)
{
m_width_abs = -m_width;
m_width_sign = -1;
}
else
{
m_width_abs = m_width;
m_width_sign = 1;
}
m_width_eps = m_width / 1024.0;
}
//-----------------------------------------------------------------------
template<class VC> void math_stroke<VC>::miter_limit_theta(double t)
{
m_miter_limit = 1.0 / sin(t * 0.5) ;
}
//-----------------------------------------------------------------------
template<class VC>
void math_stroke<VC>::calc_arc(VC& vc,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
{
double a1 = atan2(dy1 * m_width_sign, dx1 * m_width_sign);
double a2 = atan2(dy2 * m_width_sign, dx2 * m_width_sign);
double da = a1 - a2;
int i, n;
da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
add_vertex(vc, x + dx1, y + dy1);
if(m_width_sign > 0)
{
if(a1 > a2) a2 += 2 * pi;
n = int((a2 - a1) / da);
da = (a2 - a1) / (n + 1);
a1 += da;
for(i = 0; i < n; i++)
{
add_vertex(vc, x + cos(a1) * m_width, y + sin(a1) * m_width);
a1 += da;
}
}
else
{
if(a1 < a2) a2 -= 2 * pi;
n = int((a1 - a2) / da);
da = (a1 - a2) / (n + 1);
a1 -= da;
for(i = 0; i < n; i++)
{
add_vertex(vc, x + cos(a1) * m_width, y + sin(a1) * m_width);
a1 -= da;
}
}
add_vertex(vc, x + dx2, y + dy2);
}
//-----------------------------------------------------------------------
template<class VC>
void math_stroke<VC>::calc_miter(VC& vc,
const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double dx1, double dy1,
double dx2, double dy2,
line_join_e lj,
double mlimit,
double dbevel)
{
double xi = v1.x;
double yi = v1.y;
double di = 1;
double lim = m_width_abs * mlimit;
bool miter_limit_exceeded = true; // Assume the worst
bool intersection_failed = true; // Assume the worst
if(calc_intersection(v0.x + dx1, v0.y - dy1,
v1.x + dx1, v1.y - dy1,
v1.x + dx2, v1.y - dy2,
v2.x + dx2, v2.y - dy2,
&xi, &yi))
{
// Calculation of the intersection succeeded
//---------------------
di = calc_distance(v1.x, v1.y, xi, yi);
if(di <= lim)
{
// Inside the miter limit
//---------------------
add_vertex(vc, xi, yi);
miter_limit_exceeded = false;
}
intersection_failed = false;
}
else
{
// Calculation of the intersection failed, most probably
// the three points lie one straight line.
// First check if v0 and v2 lie on the opposite sides of vector:
// (v1.x, v1.y) -> (v1.x+dx1, v1.y-dy1), that is, the perpendicular
// to the line determined by vertices v0 and v1.
// This condition determines whether the next line segments continues
// the previous one or goes back.
//----------------
double x2 = v1.x + dx1;
double y2 = v1.y - dy1;
if((cross_product(v0.x, v0.y, v1.x, v1.y, x2, y2) < 0.0) ==
(cross_product(v1.x, v1.y, v2.x, v2.y, x2, y2) < 0.0))
{
// This case means that the next segment continues
// the previous one (straight line)
//-----------------
add_vertex(vc, v1.x + dx1, v1.y - dy1);
miter_limit_exceeded = false;
}
}
if(miter_limit_exceeded)
{
// Miter limit exceeded
//------------------------
switch(lj)
{
case miter_join_revert:
// For the compatibility with SVG, PDF, etc,
// we use a simple bevel join instead of
// "smart" bevel
//-------------------
add_vertex(vc, v1.x + dx1, v1.y - dy1);
add_vertex(vc, v1.x + dx2, v1.y - dy2);
break;
case miter_join_round:
calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
break;
default:
// If no miter-revert, calculate new dx1, dy1, dx2, dy2
//----------------
if(intersection_failed)
{
mlimit *= m_width_sign;
add_vertex(vc, v1.x + dx1 + dy1 * mlimit,
v1.y - dy1 + dx1 * mlimit);
add_vertex(vc, v1.x + dx2 - dy2 * mlimit,
v1.y - dy2 - dx2 * mlimit);
}
else
{
double x1 = v1.x + dx1;
double y1 = v1.y - dy1;
double x2 = v1.x + dx2;
double y2 = v1.y - dy2;
di = (lim - dbevel) / (di - dbevel);
add_vertex(vc, x1 + (xi - x1) * di,
y1 + (yi - y1) * di);
add_vertex(vc, x2 + (xi - x2) * di,
y2 + (yi - y2) * di);
}
break;
}
}
}
//--------------------------------------------------------stroke_calc_cap
template<class VC>
void math_stroke<VC>::calc_cap(VC& vc,
const vertex_dist& v0,
const vertex_dist& v1,
double len)
{
vc.remove_all();
double dx1 = (v1.y - v0.y) / len;
double dy1 = (v1.x - v0.x) / len;
double dx2 = 0;
double dy2 = 0;
dx1 *= m_width;
dy1 *= m_width;
if(m_line_cap != round_cap)
{
if(m_line_cap == square_cap)
{
dx2 = dy1 * m_width_sign;
dy2 = dx1 * m_width_sign;
}
add_vertex(vc, v0.x - dx1 - dx2, v0.y + dy1 - dy2);
add_vertex(vc, v0.x + dx1 - dx2, v0.y - dy1 - dy2);
}
else
{
double da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
double a1;
int i;
int n = int(pi / da);
da = pi / (n + 1);
add_vertex(vc, v0.x - dx1, v0.y + dy1);
if(m_width_sign > 0)
{
a1 = atan2(dy1, -dx1);
a1 += da;
for(i = 0; i < n; i++)
{
add_vertex(vc, v0.x + cos(a1) * m_width,
v0.y + sin(a1) * m_width);
a1 += da;
}
}
else
{
a1 = atan2(-dy1, dx1);
a1 -= da;
for(i = 0; i < n; i++)
{
add_vertex(vc, v0.x + cos(a1) * m_width,
v0.y + sin(a1) * m_width);
a1 -= da;
}
}
add_vertex(vc, v0.x + dx1, v0.y - dy1);
}
}
//-----------------------------------------------------------------------
template<class VC>
void math_stroke<VC>::calc_join(VC& vc,
const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double len1,
double len2)
{
double dx1 = m_width * (v1.y - v0.y) / len1;
double dy1 = m_width * (v1.x - v0.x) / len1;
double dx2 = m_width * (v2.y - v1.y) / len2;
double dy2 = m_width * (v2.x - v1.x) / len2;
vc.remove_all();
double cp = cross_product(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y);
if(cp != 0 && (cp > 0) == (m_width > 0))
{
// Inner join
//---------------
double limit = ((len1 < len2) ? len1 : len2) / m_width_abs;
if(limit < m_inner_miter_limit)
{
limit = m_inner_miter_limit;
}
switch(m_inner_join)
{
default: // inner_bevel
add_vertex(vc, v1.x + dx1, v1.y - dy1);
add_vertex(vc, v1.x + dx2, v1.y - dy2);
break;
case inner_miter:
calc_miter(vc,
v0, v1, v2, dx1, dy1, dx2, dy2,
miter_join_revert,
limit, 0);
break;
case inner_jag:
case inner_round:
cp = (dx1-dx2) * (dx1-dx2) + (dy1-dy2) * (dy1-dy2);
if(cp < len1 * len1 && cp < len2 * len2)
{
calc_miter(vc,
v0, v1, v2, dx1, dy1, dx2, dy2,
miter_join_revert,
limit, 0);
}
else
{
if(m_inner_join == inner_jag)
{
add_vertex(vc, v1.x + dx1, v1.y - dy1);
add_vertex(vc, v1.x, v1.y );
add_vertex(vc, v1.x + dx2, v1.y - dy2);
}
else
{
add_vertex(vc, v1.x + dx1, v1.y - dy1);
add_vertex(vc, v1.x, v1.y );
calc_arc(vc, v1.x, v1.y, dx2, -dy2, dx1, -dy1);
add_vertex(vc, v1.x, v1.y );
add_vertex(vc, v1.x + dx2, v1.y - dy2);
}
}
break;
}
}
else
{
// Outer join
//---------------
// Calculate the distance between v1 and
// the central point of the bevel line segment
//---------------
double dx = (dx1 + dx2) / 2;
double dy = (dy1 + dy2) / 2;
double dbevel = sqrt(dx * dx + dy * dy);
if(m_line_join == round_join || m_line_join == bevel_join)
{
// This is an optimization that reduces the number of points
// in cases of almost collinear segments. If there's no
// visible difference between bevel and miter joins we'd rather
// use miter join because it adds only one point instead of two.
//
// Here we calculate the middle point between the bevel points
// and then, the distance between v1 and this middle point.
// At outer joins this distance always less than stroke width,
// because it's actually the height of an isosceles triangle of
// v1 and its two bevel points. If the difference between this
// width and this value is small (no visible bevel) we can
// add just one point.
//
// The constant in the expression makes the result approximately
// the same as in round joins and caps. You can safely comment
// out this entire "if".
//-------------------
if(m_approx_scale * (m_width_abs - dbevel) < m_width_eps)
{
if(calc_intersection(v0.x + dx1, v0.y - dy1,
v1.x + dx1, v1.y - dy1,
v1.x + dx2, v1.y - dy2,
v2.x + dx2, v2.y - dy2,
&dx, &dy))
{
add_vertex(vc, dx, dy);
}
else
{
add_vertex(vc, v1.x + dx1, v1.y - dy1);
}
return;
}
}
switch(m_line_join)
{
case miter_join:
case miter_join_revert:
case miter_join_round:
calc_miter(vc,
v0, v1, v2, dx1, dy1, dx2, dy2,
m_line_join,
m_miter_limit,
dbevel);
break;
case round_join:
calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
break;
default: // Bevel join
add_vertex(vc, v1.x + dx1, v1.y - dy1);
add_vertex(vc, v1.x + dx2, v1.y - dy2);
break;
}
}
}
}
#endif

View file

@ -1,25 +1,16 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// 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://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PATH_STORAGE_INCLUDED
@ -499,14 +490,14 @@ namespace agg
m_stop(false)
{}
poly_container_reverse_adaptor(const Container& data, bool closed) :
poly_container_reverse_adaptor(Container& data, bool closed) :
m_container(&data),
m_index(-1),
m_closed(closed),
m_stop(false)
{}
void init(const Container& data, bool closed)
void init(Container& data, bool closed)
{
m_container = &data;
m_index = m_container->size() - 1;
@ -540,7 +531,7 @@ namespace agg
}
private:
const Container* m_container;
Container* m_container;
int m_index;
bool m_closed;
bool m_stop;
@ -844,6 +835,43 @@ namespace agg
}
//--------------------------------------------------------------------
// If the end points of a path are very, very close then make them
// exactly equal so that the stroke converter is not confused.
//--------------------------------------------------------------------
unsigned align_path(unsigned idx = 0)
{
if (idx >= total_vertices() || !is_move_to(command(idx)))
{
return total_vertices();
}
double start_x, start_y;
for (; idx < total_vertices() && is_move_to(command(idx)); ++idx)
{
vertex(idx, &start_x, &start_y);
}
while (idx < total_vertices() && is_drawing(command(idx)))
++idx;
double x, y;
if (is_drawing(vertex(idx - 1, &x, &y)) &&
is_equal_eps(x, start_x, 1e-8) &&
is_equal_eps(y, start_y, 1e-8))
{
modify_vertex(idx - 1, start_x, start_y);
}
while (idx < total_vertices() && !is_move_to(command(idx)))
++idx;
return idx;
}
void align_all_paths()
{
for (unsigned i = 0; i < total_vertices(); i = align_path(i));
}
private:
unsigned perceive_polygon_orientation(unsigned start, unsigned end);

97
src/agg/agg_pixfmt_base.h Normal file
View file

@ -0,0 +1,97 @@
//----------------------------------------------------------------------------
// 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_PIXFMT_BASE_INCLUDED
#define AGG_PIXFMT_BASE_INCLUDED
#include "agg_basics.h"
#include "agg_color_gray.h"
#include "agg_color_rgba.h"
namespace agg
{
struct pixfmt_gray_tag
{
};
struct pixfmt_rgb_tag
{
};
struct pixfmt_rgba_tag
{
};
//--------------------------------------------------------------blender_base
template<class ColorT, class Order = void>
struct blender_base
{
typedef ColorT color_type;
typedef Order order_type;
typedef typename color_type::value_type value_type;
static rgba get(value_type r, value_type g, value_type b, value_type a, cover_type cover = cover_full)
{
if (cover > cover_none)
{
rgba c(
color_type::to_double(r),
color_type::to_double(g),
color_type::to_double(b),
color_type::to_double(a));
if (cover < cover_full)
{
double x = double(cover) / cover_full;
c.r *= x;
c.g *= x;
c.b *= x;
c.a *= x;
}
return c;
}
else return rgba::no_color();
}
static rgba get(const value_type* p, cover_type cover = cover_full)
{
return get(
p[order_type::R],
p[order_type::G],
p[order_type::B],
p[order_type::A],
cover);
}
static void set(value_type* p, value_type r, value_type g, value_type b, value_type a)
{
p[order_type::R] = r;
p[order_type::G] = g;
p[order_type::B] = b;
p[order_type::A] = a;
}
static void set(value_type* p, const rgba& c)
{
p[order_type::R] = color_type::from_double(c.r);
p[order_type::G] = color_type::from_double(c.g);
p[order_type::B] = color_type::from_double(c.b);
p[order_type::A] = color_type::from_double(c.a);
}
};
}
#endif

View file

@ -1,25 +1,16 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// 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://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for high precision colors has been sponsored by
@ -34,8 +25,7 @@
#define AGG_PIXFMT_GRAY_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_color_gray.h"
#include "agg_pixfmt_base.h"
#include "agg_rendering_buffer.h"
namespace agg
@ -47,12 +37,22 @@ namespace agg
typedef ColorT color_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
enum base_scale_e { base_shift = color_type::base_shift };
typedef typename color_type::long_type long_type;
static AGG_INLINE void blend_pix(value_type* p, unsigned cv,
unsigned alpha, unsigned cover=0)
// Blend pixels using the non-premultiplied form of Alvy-Ray Smith's
// compositing function. Since the render buffer is opaque we skip the
// initial premultiply and final demultiply.
static AGG_INLINE void blend_pix(value_type* p,
value_type cv, value_type alpha, cover_type cover)
{
*p = (value_type)((((cv - calc_type(*p)) * alpha) + (calc_type(*p) << base_shift)) >> base_shift);
blend_pix(p, cv, color_type::mult_cover(alpha, cover));
}
static AGG_INLINE void blend_pix(value_type* p,
value_type cv, value_type alpha)
{
*p = color_type::lerp(*p, cv, alpha);
}
};
@ -63,20 +63,21 @@ namespace agg
typedef ColorT color_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
enum base_scale_e { base_shift = color_type::base_shift };
typedef typename color_type::long_type long_type;
static AGG_INLINE void blend_pix(value_type* p, unsigned cv,
unsigned alpha, unsigned cover)
// Blend pixels using the premultiplied form of Alvy-Ray Smith's
// compositing function.
static AGG_INLINE void blend_pix(value_type* p,
value_type cv, value_type alpha, cover_type cover)
{
alpha = color_type::base_mask - alpha;
cover = (cover + 1) << (base_shift - 8);
*p = (value_type)((*p * alpha + cv * cover) >> base_shift);
blend_pix(p, color_type::mult_cover(cv, cover), color_type::mult_cover(alpha, cover));
}
static AGG_INLINE void blend_pix(value_type* p, unsigned cv,
unsigned alpha)
static AGG_INLINE void blend_pix(value_type* p,
value_type cv, value_type alpha)
{
*p = (value_type)(((*p * (color_type::base_mask - alpha)) >> base_shift) + cv);
*p = color_type::prelerp(*p, cv, alpha);
}
};
@ -121,10 +122,11 @@ namespace agg
//=================================================pixfmt_alpha_blend_gray
template<class Blender, class RenBuf, unsigned Step=1, unsigned Offset=0>
template<class Blender, class RenBuf, unsigned Step = 1, unsigned Offset = 0>
class pixfmt_alpha_blend_gray
{
public:
typedef pixfmt_gray_tag pixfmt_category;
typedef RenBuf rbuf_type;
typedef typename rbuf_type::row_data row_data;
typedef Blender blender_type;
@ -132,54 +134,117 @@ namespace agg
typedef int order_type; // A fake one
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
enum base_scale_e
enum
{
base_shift = color_type::base_shift,
base_scale = color_type::base_scale,
base_mask = color_type::base_mask,
pix_width = sizeof(value_type),
pix_step = Step,
pix_offset = Offset
num_components = 1,
pix_width = sizeof(value_type) * Step,
pix_step = Step,
pix_offset = Offset,
};
struct pixel_type
{
value_type c[num_components];
void set(value_type v)
{
c[0] = v;
}
void set(const color_type& color)
{
set(color.v);
}
void get(value_type& v) const
{
v = c[0];
}
color_type get() const
{
return color_type(c[0]);
}
pixel_type* next()
{
return (pixel_type*)(c + pix_step);
}
const pixel_type* next() const
{
return (const pixel_type*)(c + pix_step);
}
pixel_type* advance(int n)
{
return (pixel_type*)(c + n * pix_step);
}
const pixel_type* advance(int n) const
{
return (const pixel_type*)(c + n * pix_step);
}
};
private:
//--------------------------------------------------------------------
static AGG_INLINE void copy_or_blend_pix(value_type* p,
const color_type& c,
unsigned cover)
AGG_INLINE void blend_pix(pixel_type* p,
value_type v, value_type a,
unsigned cover)
{
if (c.a)
blender_type::blend_pix(p->c, v, a, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pix(pixel_type* p, value_type v, value_type a)
{
blender_type::blend_pix(p->c, v, a);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover)
{
blender_type::blend_pix(p->c, c.v, c.a, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pix(pixel_type* p, const color_type& c)
{
blender_type::blend_pix(p->c, c.v, c.a);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover)
{
if (!c.is_transparent())
{
calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
if(alpha == base_mask)
if (c.is_opaque() && cover == cover_mask)
{
*p = c.v;
p->set(c);
}
else
{
Blender::blend_pix(p, c.v, alpha, cover);
blend_pix(p, c, cover);
}
}
}
static AGG_INLINE void copy_or_blend_pix(value_type* p,
const color_type& c)
//--------------------------------------------------------------------
AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c)
{
if (c.a)
if (!c.is_transparent())
{
if(c.a == base_mask)
if (c.is_opaque())
{
*p = c.v;
p->set(c);
}
else
{
Blender::blend_pix(p, c.v, c.a);
blend_pix(p, c);
}
}
}
public:
//--------------------------------------------------------------------
explicit pixfmt_alpha_blend_gray(rbuf_type& rb) :
@ -192,7 +257,7 @@ namespace agg
bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
{
rect_i r(x1, y1, x2, y2);
if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
{
int stride = pixf.stride();
m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
@ -210,61 +275,98 @@ namespace agg
AGG_INLINE int stride() const { return m_rbuf->stride(); }
//--------------------------------------------------------------------
int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
row_data row(int y) const { return m_rbuf->row(y); }
const int8u* pix_ptr(int x, int y) const
{
return m_rbuf->row_ptr(y) + x * Step + Offset;
//--------------------------------------------------------------------
AGG_INLINE int8u* pix_ptr(int x, int y)
{
return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset);
}
int8u* pix_ptr(int x, int y)
AGG_INLINE const int8u* pix_ptr(int x, int y) const
{
return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset);
}
// Return pointer to pixel value, forcing row to be allocated.
AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len)
{
return m_rbuf->row_ptr(y) + x * Step + Offset;
return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step + pix_offset));
}
// Return pointer to pixel value, or null if row not allocated.
AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const
{
int8u* p = m_rbuf->row_ptr(y);
return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step + pix_offset)) : 0;
}
// Get pixel pointer from raw buffer pointer.
AGG_INLINE static pixel_type* pix_value_ptr(void* p)
{
return (pixel_type*)((value_type*)p + pix_offset);
}
// Get pixel pointer from raw buffer pointer.
AGG_INLINE static const pixel_type* pix_value_ptr(const void* p)
{
return (const pixel_type*)((const value_type*)p + pix_offset);
}
//--------------------------------------------------------------------
AGG_INLINE static void write_plain_color(void* p, color_type c)
{
// Grayscale formats are implicitly premultiplied.
c.premultiply();
pix_value_ptr(p)->set(c);
}
//--------------------------------------------------------------------
AGG_INLINE static color_type read_plain_color(const void* p)
{
return pix_value_ptr(p)->get();
}
//--------------------------------------------------------------------
AGG_INLINE static void make_pix(int8u* p, const color_type& c)
{
*(value_type*)p = c.v;
((pixel_type*)p)->set(c);
}
//--------------------------------------------------------------------
AGG_INLINE color_type pixel(int x, int y) const
{
value_type* p = (value_type*)m_rbuf->row_ptr(y) + x * Step + Offset;
return color_type(*p);
if (const pixel_type* p = pix_value_ptr(x, y))
{
return p->get();
}
return color_type::no_color();
}
//--------------------------------------------------------------------
AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
{
*((value_type*)m_rbuf->row_ptr(x, y, 1) + x * Step + Offset) = c.v;
pix_value_ptr(x, y, 1)->set(c);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
copy_or_blend_pix((value_type*)
m_rbuf->row_ptr(x, y, 1) + x * Step + Offset,
c,
cover);
copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_hline(int x, int y,
unsigned len,
const color_type& c)
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
pixel_type* p = pix_value_ptr(x, y, len);
do
{
*p = c.v;
p += Step;
p->set(c);
p = p->next();
}
while(--len);
}
@ -277,12 +379,9 @@ namespace agg
{
do
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
*p = c.v;
pix_value_ptr(x, y++, 1)->set(c);
}
while(--len);
while (--len);
}
@ -292,29 +391,27 @@ namespace agg
const color_type& c,
int8u cover)
{
if (c.a)
if (!c.is_transparent())
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
pixel_type* p = pix_value_ptr(x, y, len);
calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
if(alpha == base_mask)
if (c.is_opaque() && cover == cover_mask)
{
do
{
*p = c.v;
p += Step;
p->set(c);
p = p->next();
}
while(--len);
while (--len);
}
else
{
do
{
Blender::blend_pix(p, c.v, alpha, cover);
p += Step;
blend_pix(p, c, cover);
p = p->next();
}
while(--len);
while (--len);
}
}
}
@ -326,31 +423,23 @@ namespace agg
const color_type& c,
int8u cover)
{
if (c.a)
if (!c.is_transparent())
{
value_type* p;
calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
if(alpha == base_mask)
if (c.is_opaque() && cover == cover_mask)
{
do
{
p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
*p = c.v;
pix_value_ptr(x, y++, 1)->set(c);
}
while(--len);
while (--len);
}
else
{
do
{
p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
Blender::blend_pix(p, c.v, alpha, cover);
blend_pix(pix_value_ptr(x, y++, 1), c, cover);
}
while(--len);
while (--len);
}
}
}
@ -362,26 +451,24 @@ namespace agg
const color_type& c,
const int8u* covers)
{
if (c.a)
if (!c.is_transparent())
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
pixel_type* p = pix_value_ptr(x, y, len);
do
{
calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
if(alpha == base_mask)
if (c.is_opaque() && *covers == cover_mask)
{
*p = c.v;
p->set(c);
}
else
{
Blender::blend_pix(p, c.v, alpha, *covers);
blend_pix(p, c, *covers);
}
p += Step;
p = p->next();
++covers;
}
while(--len);
while (--len);
}
}
@ -392,26 +479,23 @@ namespace agg
const color_type& c,
const int8u* covers)
{
if (c.a)
if (!c.is_transparent())
{
do
{
calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
pixel_type* p = pix_value_ptr(x, y++, 1);
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
if(alpha == base_mask)
if (c.is_opaque() && *covers == cover_mask)
{
*p = c.v;
p->set(c);
}
else
{
Blender::blend_pix(p, c.v, alpha, *covers);
blend_pix(p, c, *covers);
}
++covers;
}
while(--len);
while (--len);
}
}
@ -421,16 +505,14 @@ namespace agg
unsigned len,
const color_type* colors)
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
pixel_type* p = pix_value_ptr(x, y, len);
do
{
*p = colors->v;
p += Step;
++colors;
p->set(*colors++);
p = p->next();
}
while(--len);
while (--len);
}
@ -441,12 +523,9 @@ namespace agg
{
do
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
*p = colors->v;
++colors;
pix_value_ptr(x, y++, 1)->set(*colors++);
}
while(--len);
while (--len);
}
@ -457,50 +536,40 @@ namespace agg
const int8u* covers,
int8u cover)
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
pixel_type* p = pix_value_ptr(x, y, len);
if(covers)
if (covers)
{
do
{
copy_or_blend_pix(p, *colors++, *covers++);
p += Step;
p = p->next();
}
while(--len);
while (--len);
}
else
{
if(cover == 255)
if (cover == cover_mask)
{
do
{
if(colors->a == base_mask)
{
*p = colors->v;
}
else
{
copy_or_blend_pix(p, *colors);
}
p += Step;
++colors;
copy_or_blend_pix(p, *colors++);
p = p->next();
}
while(--len);
while (--len);
}
else
{
do
{
copy_or_blend_pix(p, *colors++, cover);
p += Step;
p = p->next();
}
while(--len);
while (--len);
}
}
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y,
@ -509,49 +578,31 @@ namespace agg
const int8u* covers,
int8u cover)
{
value_type* p;
if(covers)
if (covers)
{
do
{
p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
copy_or_blend_pix(p, *colors++, *covers++);
copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++);
}
while(--len);
while (--len);
}
else
{
if(cover == 255)
if (cover == cover_mask)
{
do
{
p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
if(colors->a == base_mask)
{
*p = colors->v;
}
else
{
copy_or_blend_pix(p, *colors);
}
++colors;
copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++);
}
while(--len);
while (--len);
}
else
{
do
{
p = (value_type*)
m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
copy_or_blend_pix(p, *colors++, cover);
copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover);
}
while(--len);
while (--len);
}
}
}
@ -560,22 +611,19 @@ namespace agg
template<class Function> void for_each_pixel(Function f)
{
unsigned y;
for(y = 0; y < height(); ++y)
for (y = 0; y < height(); ++y)
{
row_data r = m_rbuf->row(y);
if(r.ptr)
if (r.ptr)
{
unsigned len = r.x2 - r.x1 + 1;
value_type* p = (value_type*)
m_rbuf->row_ptr(r.x1, y, len) + r.x1 * Step + Offset;
pixel_type* p = pix_value_ptr(r.x1, y, len);
do
{
f(p);
p += Step;
f(p->c);
p = p->next();
}
while(--len);
while (--len);
}
}
}
@ -599,8 +647,7 @@ namespace agg
int xsrc, int ysrc,
unsigned len)
{
const int8u* p = from.row_ptr(ysrc);
if(p)
if (const int8u* p = from.row_ptr(ysrc))
{
memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
p + xsrc * pix_width,
@ -609,6 +656,7 @@ namespace agg
}
//--------------------------------------------------------------------
// Blend from single color, using grayscale surface as alpha channel.
template<class SrcPixelFormatRenderer>
void blend_from_color(const SrcPixelFormatRenderer& from,
const color_type& color,
@ -617,25 +665,26 @@ namespace agg
unsigned len,
int8u cover)
{
typedef typename SrcPixelFormatRenderer::value_type src_value_type;
const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
if(psrc)
typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
typedef typename SrcPixelFormatRenderer::color_type src_color_type;
if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
{
value_type* pdst =
(value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
do
{
copy_or_blend_pix(pdst,
color,
(*psrc * cover + base_mask) >> base_shift);
++psrc;
++pdst;
copy_or_blend_pix(pdst, color, src_color_type::scale_cover(cover, psrc->c[0]));
psrc = psrc->next();
pdst = pdst->next();
}
while(--len);
while (--len);
}
}
//--------------------------------------------------------------------
// Blend from color table, using grayscale surface as indexes into table.
// Obviously, this only works for integer value types.
template<class SrcPixelFormatRenderer>
void blend_from_lut(const SrcPixelFormatRenderer& from,
const color_type* color_lut,
@ -644,19 +693,19 @@ namespace agg
unsigned len,
int8u cover)
{
typedef typename SrcPixelFormatRenderer::value_type src_value_type;
const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
if(psrc)
typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
{
value_type* pdst =
(value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
do
{
copy_or_blend_pix(pdst, color_lut[*psrc], cover);
++psrc;
++pdst;
copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover);
psrc = psrc->next();
pdst = pdst->next();
}
while(--len);
while (--len);
}
}
@ -664,15 +713,25 @@ namespace agg
rbuf_type* m_rbuf;
};
typedef blender_gray<gray8> blender_gray8;
typedef blender_gray_pre<gray8> blender_gray8_pre;
typedef blender_gray<gray16> blender_gray16;
typedef blender_gray_pre<gray16> blender_gray16_pre;
typedef blender_gray<gray8> blender_gray8;
typedef blender_gray<sgray8> blender_sgray8;
typedef blender_gray<gray16> blender_gray16;
typedef blender_gray<gray32> blender_gray32;
typedef pixfmt_alpha_blend_gray<blender_gray8, rendering_buffer> pixfmt_gray8; //----pixfmt_gray8
typedef pixfmt_alpha_blend_gray<blender_gray8_pre, rendering_buffer> pixfmt_gray8_pre; //----pixfmt_gray8_pre
typedef pixfmt_alpha_blend_gray<blender_gray16, rendering_buffer> pixfmt_gray16; //----pixfmt_gray16
typedef pixfmt_alpha_blend_gray<blender_gray16_pre, rendering_buffer> pixfmt_gray16_pre; //----pixfmt_gray16_pre
typedef blender_gray_pre<gray8> blender_gray8_pre;
typedef blender_gray_pre<sgray8> blender_sgray8_pre;
typedef blender_gray_pre<gray16> blender_gray16_pre;
typedef blender_gray_pre<gray32> blender_gray32_pre;
typedef pixfmt_alpha_blend_gray<blender_gray8, rendering_buffer> pixfmt_gray8;
typedef pixfmt_alpha_blend_gray<blender_sgray8, rendering_buffer> pixfmt_sgray8;
typedef pixfmt_alpha_blend_gray<blender_gray16, rendering_buffer> pixfmt_gray16;
typedef pixfmt_alpha_blend_gray<blender_gray32, rendering_buffer> pixfmt_gray32;
typedef pixfmt_alpha_blend_gray<blender_gray8_pre, rendering_buffer> pixfmt_gray8_pre;
typedef pixfmt_alpha_blend_gray<blender_sgray8_pre, rendering_buffer> pixfmt_sgray8_pre;
typedef pixfmt_alpha_blend_gray<blender_gray16_pre, rendering_buffer> pixfmt_gray16_pre;
typedef pixfmt_alpha_blend_gray<blender_gray32_pre, rendering_buffer> pixfmt_gray32_pre;
}
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,25 +1,12 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// 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.
//
//----------------------------------------------------------------------------
//
// The author gratefully acknowleges the support of David Turner,
@ -27,6 +14,10 @@
// libray - in producing this work. See http://www.freetype.org for details.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
@ -35,12 +26,12 @@
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_CELLS_AA_INCLUDED
#define AGG_RASTERIZER_CELLS_AA_INCLUDED
#include <string.h>
#include <math.h>
#include <cstdlib>
#include <limits>
#include "agg_math.h"
#include "agg_array.h"
@ -160,10 +151,10 @@ namespace agg
m_curr_cell_ptr(0),
m_sorted_cells(),
m_sorted_y(),
m_min_x(0x7FFFFFFF),
m_min_y(0x7FFFFFFF),
m_max_x(-0x7FFFFFFF),
m_max_y(-0x7FFFFFFF),
m_min_x(std::numeric_limits<int>::max()),
m_min_y(std::numeric_limits<int>::max()),
m_max_x(std::numeric_limits<int>::min()),
m_max_y(std::numeric_limits<int>::min()),
m_sorted(false)
{
m_style_cell.initial();
@ -179,10 +170,10 @@ namespace agg
m_curr_cell.initial();
m_style_cell.initial();
m_sorted = false;
m_min_x = 0x7FFFFFFF;
m_min_y = 0x7FFFFFFF;
m_max_x = -0x7FFFFFFF;
m_max_y = -0x7FFFFFFF;
m_min_x = std::numeric_limits<int>::max();
m_min_y = std::numeric_limits<int>::max();
m_max_x = std::numeric_limits<int>::min();
m_max_y = std::numeric_limits<int>::min();
}
//------------------------------------------------------------------------
@ -227,7 +218,8 @@ namespace agg
int fx1 = x1 & poly_subpixel_mask;
int fx2 = x2 & poly_subpixel_mask;
int delta, p, first, dx;
int delta, p, first;
long long dx;
int incr, lift, mod, rem;
//trivial case. Happens often
@ -252,7 +244,7 @@ namespace agg
first = poly_subpixel_scale;
incr = 1;
dx = x2 - x1;
dx = (long long)x2 - (long long)x1;
if(dx < 0)
{
@ -262,13 +254,13 @@ namespace agg
dx = -dx;
}
delta = p / dx;
mod = p % dx;
delta = (int)(p / dx);
mod = (int)(p % dx);
if(mod < 0)
{
delta--;
mod += dx;
mod += static_cast<int>(dx);
}
m_curr_cell.cover += delta;
@ -281,16 +273,16 @@ namespace agg
if(ex1 != ex2)
{
p = poly_subpixel_scale * (y2 - y1 + delta);
lift = p / dx;
rem = p % dx;
lift = (int)(p / dx);
rem = (int)(p % dx);
if (rem < 0)
{
lift--;
rem += dx;
rem += static_cast<int>(dx);
}
mod -= dx;
mod -= static_cast<int>(dx);
while (ex1 != ex2)
{
@ -298,7 +290,7 @@ namespace agg
mod += rem;
if(mod >= 0)
{
mod -= dx;
mod -= static_cast<int>(dx);
delta++;
}
@ -327,17 +319,17 @@ namespace agg
{
enum dx_limit_e { dx_limit = 16384 << poly_subpixel_shift };
int dx = x2 - x1;
long long dx = (long long)x2 - (long long)x1;
if(dx >= dx_limit || dx <= -dx_limit)
{
int cx = (x1 + x2) >> 1;
int cy = (y1 + y2) >> 1;
int cx = (int)(((long long)x1 + (long long)x2) >> 1);
int cy = (int)(((long long)y1 + (long long)y2) >> 1);
line(x1, y1, cx, cy);
line(cx, cy, x2, y2);
}
int dy = y2 - y1;
long long dy = (long long)y2 - (long long)y1;
int ex1 = x1 >> poly_subpixel_shift;
int ex2 = x2 >> poly_subpixel_shift;
int ey1 = y1 >> poly_subpixel_shift;
@ -346,7 +338,8 @@ namespace agg
int fy2 = y2 & poly_subpixel_mask;
int x_from, x_to;
int p, rem, mod, lift, delta, first, incr;
int rem, mod, lift, delta, first, incr;
long long p;
if(ex1 < m_min_x) m_min_x = ex1;
if(ex1 > m_max_x) m_max_x = ex1;
@ -423,13 +416,13 @@ namespace agg
dy = -dy;
}
delta = p / dy;
mod = p % dy;
delta = (int)(p / dy);
mod = (int)(p % dy);
if(mod < 0)
{
delta--;
mod += dy;
mod += static_cast<int>(dy);
}
x_from = x1 + delta;
@ -441,15 +434,15 @@ namespace agg
if(ey1 != ey2)
{
p = poly_subpixel_scale * dx;
lift = p / dy;
rem = p % dy;
lift = (int)(p / dy);
rem = (int)(p % dy);
if(rem < 0)
{
lift--;
rem += dy;
rem += static_cast<int>(dy);
}
mod -= dy;
mod -= static_cast<int>(dy);
while(ey1 != ey2)
{
@ -457,7 +450,7 @@ namespace agg
mod += rem;
if (mod >= 0)
{
mod -= dy;
mod -= static_cast<int>(dy);
delta++;
}
@ -635,8 +628,8 @@ namespace agg
if(m_sorted) return; //Perform sort only the first time.
add_curr_cell();
m_curr_cell.x = 0x7FFFFFFF;
m_curr_cell.y = 0x7FFFFFFF;
m_curr_cell.x = std::numeric_limits<int>::max();
m_curr_cell.y = std::numeric_limits<int>::max();
m_curr_cell.cover = 0;
m_curr_cell.area = 0;
@ -664,12 +657,13 @@ namespace agg
// Create the Y-histogram (count the numbers of cells for each Y)
cell_type** block_ptr = m_cells;
cell_type* cell_ptr;
unsigned nb = m_num_cells >> cell_block_shift;
unsigned nb = m_num_cells;
unsigned i;
while(nb--)
while(nb)
{
cell_ptr = *block_ptr++;
i = cell_block_size;
i = (nb > cell_block_size) ? unsigned(cell_block_size) : nb;
nb -= i;
while(i--)
{
m_sorted_y[cell_ptr->y - m_min_y].start++;
@ -677,14 +671,6 @@ namespace agg
}
}
cell_ptr = *block_ptr++;
i = m_num_cells & cell_block_mask;
while(i--)
{
m_sorted_y[cell_ptr->y - m_min_y].start++;
++cell_ptr;
}
// Convert the Y-histogram into the array of starting indexes
unsigned start = 0;
for(i = 0; i < m_sorted_y.size(); i++)
@ -696,12 +682,13 @@ namespace agg
// Fill the cell pointer array sorted by Y
block_ptr = m_cells;
nb = m_num_cells >> cell_block_shift;
while(nb--)
nb = m_num_cells;
while(nb)
{
cell_ptr = *block_ptr++;
i = cell_block_size;
while(i--)
i = (nb > cell_block_size) ? unsigned(cell_block_size) : nb;
nb -= i;
while(i--)
{
sorted_y& curr_y = m_sorted_y[cell_ptr->y - m_min_y];
m_sorted_cells[curr_y.start + curr_y.num] = cell_ptr;
@ -710,16 +697,6 @@ namespace agg
}
}
cell_ptr = *block_ptr++;
i = m_num_cells & cell_block_mask;
while(i--)
{
sorted_y& curr_y = m_sorted_y[cell_ptr->y - m_min_y];
m_sorted_cells[curr_y.start + curr_y.num] = cell_ptr;
++curr_y.num;
++cell_ptr;
}
// Finally arrange the X-arrays
for(i = 0; i < m_sorted_y.size(); i++)
{

View file

@ -1,25 +1,12 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// 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.
//
//----------------------------------------------------------------------------
//
// The author gratefully acknowleges the support of David Turner,
@ -27,6 +14,10 @@
// libray - in producing this work. See http://www.freetype.org for details.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
@ -35,47 +26,17 @@
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_SCANLINE_AA_INCLUDED
#define AGG_RASTERIZER_SCANLINE_AA_INCLUDED
#include "agg_rasterizer_cells_aa.h"
#include "agg_rasterizer_sl_clip.h"
#include "agg_rasterizer_scanline_aa_nogamma.h"
#include "agg_gamma_functions.h"
namespace agg
{
//-----------------------------------------------------------------cell_aa
// A pixel cell. There're no constructors defined and it was done
// intentionally in order to avoid extra overhead when allocating an
// array of cells.
struct cell_aa
{
int x;
int y;
int cover;
int area;
void initial()
{
x = 0x7FFFFFFF;
y = 0x7FFFFFFF;
cover = 0;
area = 0;
}
void style(const cell_aa&) {}
int not_equal(int ex, int ey, const cell_aa&) const
{
return (ex - x) | (ey - y);
}
};
//==================================================rasterizer_scanline_aa
// Polygon rasterizer that is used to render filled polygons with
// high-quality Anti-Aliasing. Internally, by default, the class uses

View file

@ -0,0 +1,483 @@
//----------------------------------------------------------------------------
// 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.
//
//----------------------------------------------------------------------------
//
// The author gratefully acknowleges the support of David Turner,
// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
// libray - in producing this work. See http://www.freetype.org for details.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED
#define AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED
#include <limits>
#include "agg_rasterizer_cells_aa.h"
#include "agg_rasterizer_sl_clip.h"
namespace agg
{
//-----------------------------------------------------------------cell_aa
// A pixel cell. There're no constructors defined and it was done
// intentionally in order to avoid extra overhead when allocating an
// array of cells.
struct cell_aa
{
int x;
int y;
int cover;
int area;
void initial()
{
x = std::numeric_limits<int>::max();
y = std::numeric_limits<int>::max();
cover = 0;
area = 0;
}
void style(const cell_aa&) {}
int not_equal(int ex, int ey, const cell_aa&) const
{
return ((unsigned)ex - (unsigned)x) | ((unsigned)ey - (unsigned)y);
}
};
//==================================================rasterizer_scanline_aa_nogamma
// Polygon rasterizer that is used to render filled polygons with
// high-quality Anti-Aliasing. Internally, by default, the class uses
// integer coordinates in format 24.8, i.e. 24 bits for integer part
// and 8 bits for fractional - see poly_subpixel_shift. This class can be
// used in the following way:
//
// 1. filling_rule(filling_rule_e ft) - optional.
//
// 2. gamma() - optional.
//
// 3. reset()
//
// 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create
// more than one contour, but each contour must consist of at least 3
// vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3);
// is the absolute minimum of vertices that define a triangle.
// The algorithm does not check either the number of vertices nor
// coincidence of their coordinates, but in the worst case it just
// won't draw anything.
// The orger of the vertices (clockwise or counterclockwise)
// is important when using the non-zero filling rule (fill_non_zero).
// In this case the vertex order of all the contours must be the same
// if you want your intersecting polygons to be without "holes".
// You actually can use different vertices order. If the contours do not
// intersect each other the order is not important anyway. If they do,
// contours with the same vertex order will be rendered without "holes"
// while the intersecting contours with different orders will have "holes".
//
// filling_rule() and gamma() can be called anytime before "sweeping".
//------------------------------------------------------------------------
template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa_nogamma
{
enum status
{
status_initial,
status_move_to,
status_line_to,
status_closed
};
public:
typedef Clip clip_type;
typedef typename Clip::conv_type conv_type;
typedef typename Clip::coord_type coord_type;
enum aa_scale_e
{
aa_shift = 8,
aa_scale = 1 << aa_shift,
aa_mask = aa_scale - 1,
aa_scale2 = aa_scale * 2,
aa_mask2 = aa_scale2 - 1
};
//--------------------------------------------------------------------
rasterizer_scanline_aa_nogamma() :
m_outline(),
m_clipper(),
m_filling_rule(fill_non_zero),
m_auto_close(true),
m_start_x(0),
m_start_y(0),
m_status(status_initial)
{
}
//--------------------------------------------------------------------
void reset();
void reset_clipping();
void clip_box(double x1, double y1, double x2, double y2);
void filling_rule(filling_rule_e filling_rule);
void auto_close(bool flag) { m_auto_close = flag; }
//--------------------------------------------------------------------
unsigned apply_gamma(unsigned cover) const
{
return cover;
}
//--------------------------------------------------------------------
void move_to(int x, int y);
void line_to(int x, int y);
void move_to_d(double x, double y);
void line_to_d(double x, double y);
void close_polygon();
void add_vertex(double x, double y, unsigned cmd);
void edge(int x1, int y1, int x2, int y2);
void edge_d(double x1, double y1, double x2, double y2);
//-------------------------------------------------------------------
template<class VertexSource>
void add_path(VertexSource& vs, unsigned path_id=0)
{
double x;
double y;
unsigned cmd;
vs.rewind(path_id);
if(m_outline.sorted()) reset();
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
add_vertex(x, y, cmd);
}
}
//--------------------------------------------------------------------
int min_x() const { return m_outline.min_x(); }
int min_y() const { return m_outline.min_y(); }
int max_x() const { return m_outline.max_x(); }
int max_y() const { return m_outline.max_y(); }
//--------------------------------------------------------------------
void sort();
bool rewind_scanlines();
bool navigate_scanline(int y);
//--------------------------------------------------------------------
AGG_INLINE unsigned calculate_alpha(int area) const
{
int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift);
if(cover < 0) cover = -cover;
if(m_filling_rule == fill_even_odd)
{
cover &= aa_mask2;
if(cover > aa_scale)
{
cover = aa_scale2 - cover;
}
}
if(cover > aa_mask) cover = aa_mask;
return cover;
}
//--------------------------------------------------------------------
template<class Scanline> bool sweep_scanline(Scanline& sl)
{
for(;;)
{
if(m_scan_y > m_outline.max_y()) return false;
sl.reset_spans();
unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y);
int cover = 0;
while(num_cells)
{
const cell_aa* cur_cell = *cells;
int x = cur_cell->x;
int area = cur_cell->area;
unsigned alpha;
cover += cur_cell->cover;
//accumulate all cells with the same X
while(--num_cells)
{
cur_cell = *++cells;
if(cur_cell->x != x) break;
area += cur_cell->area;
cover += cur_cell->cover;
}
if(area)
{
alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area);
if(alpha)
{
sl.add_cell(x, alpha);
}
x++;
}
if(num_cells && cur_cell->x > x)
{
alpha = calculate_alpha(cover << (poly_subpixel_shift + 1));
if(alpha)
{
sl.add_span(x, cur_cell->x - x, alpha);
}
}
}
if(sl.num_spans()) break;
++m_scan_y;
}
sl.finalize(m_scan_y);
++m_scan_y;
return true;
}
//--------------------------------------------------------------------
bool hit_test(int tx, int ty);
private:
//--------------------------------------------------------------------
// Disable copying
rasterizer_scanline_aa_nogamma(const rasterizer_scanline_aa_nogamma<Clip>&);
const rasterizer_scanline_aa_nogamma<Clip>&
operator = (const rasterizer_scanline_aa_nogamma<Clip>&);
private:
rasterizer_cells_aa<cell_aa> m_outline;
clip_type m_clipper;
filling_rule_e m_filling_rule;
bool m_auto_close;
coord_type m_start_x;
coord_type m_start_y;
unsigned m_status;
int m_scan_y;
};
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::reset()
{
m_outline.reset();
m_status = status_initial;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::filling_rule(filling_rule_e filling_rule)
{
m_filling_rule = filling_rule;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::clip_box(double x1, double y1,
double x2, double y2)
{
reset();
m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1),
conv_type::upscale(x2), conv_type::upscale(y2));
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::reset_clipping()
{
reset();
m_clipper.reset_clipping();
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::close_polygon()
{
if(m_status == status_line_to)
{
m_clipper.line_to(m_outline, m_start_x, m_start_y);
m_status = status_closed;
}
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::move_to(int x, int y)
{
if(m_outline.sorted()) reset();
if(m_auto_close) close_polygon();
m_clipper.move_to(m_start_x = conv_type::downscale(x),
m_start_y = conv_type::downscale(y));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::line_to(int x, int y)
{
m_clipper.line_to(m_outline,
conv_type::downscale(x),
conv_type::downscale(y));
m_status = status_line_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::move_to_d(double x, double y)
{
if(m_outline.sorted()) reset();
if(m_auto_close) close_polygon();
m_clipper.move_to(m_start_x = conv_type::upscale(x),
m_start_y = conv_type::upscale(y));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::line_to_d(double x, double y)
{
m_clipper.line_to(m_outline,
conv_type::upscale(x),
conv_type::upscale(y));
m_status = status_line_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::add_vertex(double x, double y, unsigned cmd)
{
if(is_move_to(cmd))
{
move_to_d(x, y);
}
else
if(is_vertex(cmd))
{
line_to_d(x, y);
}
else
if(is_close(cmd))
{
close_polygon();
}
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::edge(int x1, int y1, int x2, int y2)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
m_clipper.line_to(m_outline,
conv_type::downscale(x2),
conv_type::downscale(y2));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::edge_d(double x1, double y1,
double x2, double y2)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
m_clipper.line_to(m_outline,
conv_type::upscale(x2),
conv_type::upscale(y2));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::sort()
{
if(m_auto_close) close_polygon();
m_outline.sort_cells();
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE bool rasterizer_scanline_aa_nogamma<Clip>::rewind_scanlines()
{
if(m_auto_close) close_polygon();
m_outline.sort_cells();
if(m_outline.total_cells() == 0)
{
return false;
}
m_scan_y = m_outline.min_y();
return true;
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE bool rasterizer_scanline_aa_nogamma<Clip>::navigate_scanline(int y)
{
if(m_auto_close) close_polygon();
m_outline.sort_cells();
if(m_outline.total_cells() == 0 ||
y < m_outline.min_y() ||
y > m_outline.max_y())
{
return false;
}
m_scan_y = y;
return true;
}
//------------------------------------------------------------------------
template<class Clip>
bool rasterizer_scanline_aa_nogamma<Clip>::hit_test(int tx, int ty)
{
if(!navigate_scanline(ty)) return false;
scanline_hit_test sl(tx);
sweep_scanline(sl);
return sl.hit();
}
}
#endif

View file

@ -1,27 +1,17 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// 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://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_SL_CLIP_INCLUDED
#define AGG_RASTERIZER_SL_CLIP_INCLUDED
@ -327,7 +317,7 @@ namespace agg
rasterizer_sl_no_clip() : m_x1(0), m_y1(0) {}
void reset_clipping() {}
void clip_box(coord_type x1, coord_type y1, coord_type x2, coord_type y2) {}
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>

View file

@ -1,25 +1,20 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// 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://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// class renderer_base
//
//----------------------------------------------------------------------------
#ifndef AGG_RENDERER_BASE_INCLUDED
@ -139,6 +134,19 @@ namespace agg
}
//--------------------------------------------------------------------
void fill(const color_type& c)
{
unsigned y;
if(width())
{
for(y = 0; y < height(); y++)
{
m_ren->blend_hline(0, y, width(), c, cover_mask);
}
}
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{

View file

@ -1,30 +1,23 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// 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://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_RENDERER_SCANLINE_INCLUDED
#define AGG_RENDERER_SCANLINE_INCLUDED
#include <limits>
#include <cstdlib>
#include "agg_basics.h"
#include "agg_renderer_base.h"
@ -74,7 +67,7 @@ namespace agg
// "rgba8" is needed. Otherwise it will be implicitly
// converted in the loop many times.
//----------------------
typename BaseRenderer::color_type ren_color(color);
typename BaseRenderer::color_type ren_color = color;
sl.reset(ras.min_x(), ras.max_x());
while(ras.sweep_scanline(sl))
@ -754,7 +747,7 @@ namespace agg
0,
sl_len * sizeof(cover_type));
int sl_y = 0x7FFFFFFF;
int sl_y = std::numeric_limits<int>::max();
unsigned i;
for(i = 0; i < num_styles; i++)
{

View file

@ -1,25 +1,20 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// 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://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// class rendering_buffer
//
//----------------------------------------------------------------------------
#ifndef AGG_RENDERING_BUFFER_INCLUDED
@ -61,14 +56,14 @@ namespace agg
//--------------------------------------------------------------------
void attach(T* buf, unsigned width, unsigned height, int stride)
{
m_buf = m_start = buf;
m_width = width;
m_height = height;
m_stride = stride;
if(stride < 0)
m_buf = m_start = buf;
m_width = width;
m_height = height;
m_stride = stride;
if(stride < 0)
{
m_start = m_buf - int(height - 1) * stride;
}
m_start = m_buf - int(height - 1) * stride;
}
}
//--------------------------------------------------------------------
@ -83,13 +78,13 @@ namespace agg
}
//--------------------------------------------------------------------
AGG_INLINE T* row_ptr(int, int y, unsigned)
AGG_INLINE T* row_ptr(int, int y, unsigned)
{
return m_start + y * m_stride;
}
AGG_INLINE T* row_ptr(int y) { return m_start + y * m_stride; }
AGG_INLINE const T* row_ptr(int y) const { return m_start + y * m_stride; }
AGG_INLINE row_data row (int y) const
AGG_INLINE T* row_ptr(int y) { return m_start + y * m_stride; }
AGG_INLINE const T* row_ptr(int y) const { return m_start + y * m_stride; }
AGG_INLINE row_data row (int y) const
{
return row_data(0, m_width-1, row_ptr(y));
}

View file

@ -1,25 +1,20 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// 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://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Class scanline_p - a general purpose scanline container with packed spans.
//
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates (scanline32_p) has been sponsored by

View file

@ -1,75 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#ifndef AGG_SHORTEN_PATH_INCLUDED
#define AGG_SHORTEN_PATH_INCLUDED
#include "agg_basics.h"
#include "agg_vertex_sequence.h"
namespace agg
{
//===========================================================shorten_path
template<class VertexSequence>
void shorten_path(VertexSequence& vs, double s, unsigned closed = 0)
{
typedef typename VertexSequence::value_type vertex_type;
if(s > 0.0 && vs.size() > 1)
{
double d;
int n = int(vs.size() - 2);
while(n)
{
d = vs[n].dist;
if(d > s) break;
vs.remove_last();
s -= d;
--n;
}
if(vs.size() < 2)
{
vs.remove_all();
}
else
{
n = vs.size() - 1;
vertex_type& prev = vs[n-1];
vertex_type& last = vs[n];
d = (prev.dist - s) / prev.dist;
double x = prev.x + (last.x - prev.x) * d;
double y = prev.y + (last.y - prev.y) * d;
last.x = x;
last.y = y;
if(!prev(last)) vs.remove_last();
vs.close(closed != 0);
}
}
}
}
#endif

View file

@ -1,27 +1,21 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// 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://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Affine transformation classes.
//
//----------------------------------------------------------------------------
#ifndef AGG_TRANS_AFFINE_INCLUDED
#define AGG_TRANS_AFFINE_INCLUDED
@ -217,14 +211,14 @@ namespace agg
// Multiply the matrix by another one and return
// the result in a separete matrix.
trans_affine operator * (const trans_affine& m)
trans_affine operator * (const trans_affine& m) const
{
return trans_affine(*this).multiply(m);
}
// Multiply the matrix by inverse of another one
// and return the result in a separete matrix.
trans_affine operator / (const trans_affine& m)
trans_affine operator / (const trans_affine& m) const
{
return trans_affine(*this).multiply_inv(m);
}
@ -298,7 +292,7 @@ namespace agg
//------------------------------------------------------------------------
inline void trans_affine::transform(double* x, double* y) const
{
register double tmp = *x;
double tmp = *x;
*x = tmp * sx + *y * shx + tx;
*y = tmp * shy + *y * sy + ty;
}
@ -306,7 +300,7 @@ namespace agg
//------------------------------------------------------------------------
inline void trans_affine::transform_2x2(double* x, double* y) const
{
register double tmp = *x;
double tmp = *x;
*x = tmp * sx + *y * shx;
*y = tmp * shy + *y * sy;
}
@ -314,9 +308,9 @@ namespace agg
//------------------------------------------------------------------------
inline void trans_affine::inverse_transform(double* x, double* y) const
{
register double d = determinant_reciprocal();
register double a = (*x - tx) * d;
register double b = (*y - ty) * d;
double d = determinant_reciprocal();
double a = (*x - tx) * d;
double b = (*y - ty) * d;
*x = a * sy - b * shx;
*y = b * sx - a * shy;
}

View file

@ -1,103 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#ifndef AGG_VCGEN_CONTOUR_INCLUDED
#define AGG_VCGEN_CONTOUR_INCLUDED
#include "agg_math_stroke.h"
namespace agg
{
//----------------------------------------------------------vcgen_contour
//
// See Implementation agg_vcgen_contour.cpp
//
class vcgen_contour
{
enum status_e
{
initial,
ready,
outline,
out_vertices,
end_poly,
stop
};
public:
typedef vertex_sequence<vertex_dist, 6> vertex_storage;
typedef pod_bvector<point_d, 6> coord_storage;
vcgen_contour();
void line_cap(line_cap_e lc) { m_stroker.line_cap(lc); }
void line_join(line_join_e lj) { m_stroker.line_join(lj); }
void inner_join(inner_join_e ij) { m_stroker.inner_join(ij); }
line_cap_e line_cap() const { return m_stroker.line_cap(); }
line_join_e line_join() const { return m_stroker.line_join(); }
inner_join_e inner_join() const { return m_stroker.inner_join(); }
void width(double w) { m_stroker.width(m_width = w); }
void miter_limit(double ml) { m_stroker.miter_limit(ml); }
void miter_limit_theta(double t) { m_stroker.miter_limit_theta(t); }
void inner_miter_limit(double ml) { m_stroker.inner_miter_limit(ml); }
void approximation_scale(double as) { m_stroker.approximation_scale(as); }
double width() const { return m_width; }
double miter_limit() const { return m_stroker.miter_limit(); }
double inner_miter_limit() const { return m_stroker.inner_miter_limit(); }
double approximation_scale() const { return m_stroker.approximation_scale(); }
void auto_detect_orientation(bool v) { m_auto_detect = v; }
bool auto_detect_orientation() const { return m_auto_detect; }
// Generator interface
void remove_all();
void add_vertex(double x, double y, unsigned cmd);
// Vertex Source Interface
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
vcgen_contour(const vcgen_contour&);
const vcgen_contour& operator = (const vcgen_contour&);
math_stroke<coord_storage> m_stroker;
double m_width;
vertex_storage m_src_vertices;
coord_storage m_out_vertices;
status_e m_status;
unsigned m_src_vertex;
unsigned m_out_vertex;
unsigned m_closed;
unsigned m_orientation;
bool m_auto_detect;
};
}
#endif

View file

@ -1,111 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#ifndef AGG_VCGEN_STROKE_INCLUDED
#define AGG_VCGEN_STROKE_INCLUDED
#include "agg_math_stroke.h"
namespace agg
{
//============================================================vcgen_stroke
//
// See Implementation agg_vcgen_stroke.cpp
// Stroke generator
//
//------------------------------------------------------------------------
class vcgen_stroke
{
enum status_e
{
initial,
ready,
cap1,
cap2,
outline1,
close_first,
outline2,
out_vertices,
end_poly1,
end_poly2,
stop
};
public:
typedef vertex_sequence<vertex_dist, 6> vertex_storage;
typedef pod_bvector<point_d, 6> coord_storage;
vcgen_stroke();
void line_cap(line_cap_e lc) { m_stroker.line_cap(lc); }
void line_join(line_join_e lj) { m_stroker.line_join(lj); }
void inner_join(inner_join_e ij) { m_stroker.inner_join(ij); }
line_cap_e line_cap() const { return m_stroker.line_cap(); }
line_join_e line_join() const { return m_stroker.line_join(); }
inner_join_e inner_join() const { return m_stroker.inner_join(); }
void width(double w) { m_stroker.width(w); }
void miter_limit(double ml) { m_stroker.miter_limit(ml); }
void miter_limit_theta(double t) { m_stroker.miter_limit_theta(t); }
void inner_miter_limit(double ml) { m_stroker.inner_miter_limit(ml); }
void approximation_scale(double as) { m_stroker.approximation_scale(as); }
double width() const { return m_stroker.width(); }
double miter_limit() const { return m_stroker.miter_limit(); }
double inner_miter_limit() const { return m_stroker.inner_miter_limit(); }
double approximation_scale() const { return m_stroker.approximation_scale(); }
void shorten(double s) { m_shorten = s; }
double shorten() const { return m_shorten; }
// Vertex Generator Interface
void remove_all();
void add_vertex(double x, double y, unsigned cmd);
// Vertex Source Interface
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
vcgen_stroke(const vcgen_stroke&);
const vcgen_stroke& operator = (const vcgen_stroke&);
math_stroke<coord_storage> m_stroker;
vertex_storage m_src_vertices;
coord_storage m_out_vertices;
double m_shorten;
unsigned m_closed;
status_e m_status;
status_e m_prev_status;
unsigned m_src_vertex;
unsigned m_out_vertex;
};
}
#endif

View file

@ -1,178 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#ifndef AGG_VERTEX_SEQUENCE_INCLUDED
#define AGG_VERTEX_SEQUENCE_INCLUDED
#include "agg_basics.h"
#include "agg_array.h"
#include "agg_math.h"
namespace agg
{
//----------------------------------------------------------vertex_sequence
// Modified agg::pod_bvector. The data is interpreted as a sequence
// of vertices. It means that the type T must expose:
//
// bool T::operator() (const T& val)
//
// that is called every time new vertex is being added. The main purpose
// of this operator is the possibility to calculate some values during
// adding and to return true if the vertex fits some criteria or false if
// it doesn't. In the last case the new vertex is not added.
//
// The simple example is filtering coinciding vertices with calculation
// of the distance between the current and previous ones:
//
// struct vertex_dist
// {
// double x;
// double y;
// double dist;
//
// vertex_dist() {}
// vertex_dist(double x_, double y_) :
// x(x_),
// y(y_),
// dist(0.0)
// {
// }
//
// bool operator () (const vertex_dist& val)
// {
// return (dist = calc_distance(x, y, val.x, val.y)) > EPSILON;
// }
// };
//
// Function close() calls this operator and removes the last vertex if
// necessary.
//------------------------------------------------------------------------
template<class T, unsigned S=6>
class vertex_sequence : public pod_bvector<T, S>
{
public:
typedef pod_bvector<T, S> base_type;
void add(const T& val);
void modify_last(const T& val);
void close(bool remove_flag);
};
//------------------------------------------------------------------------
template<class T, unsigned S>
void vertex_sequence<T, S>::add(const T& val)
{
if(base_type::size() > 1)
{
if(!(*this)[base_type::size() - 2]((*this)[base_type::size() - 1]))
{
base_type::remove_last();
}
}
base_type::add(val);
}
//------------------------------------------------------------------------
template<class T, unsigned S>
void vertex_sequence<T, S>::modify_last(const T& val)
{
base_type::remove_last();
add(val);
}
//------------------------------------------------------------------------
template<class T, unsigned S>
void vertex_sequence<T, S>::close(bool closed)
{
while(base_type::size() > 1)
{
if((*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) break;
T t = (*this)[base_type::size() - 1];
base_type::remove_last();
modify_last(t);
}
if(closed)
{
while(base_type::size() > 1)
{
if((*this)[base_type::size() - 1]((*this)[0])) break;
base_type::remove_last();
}
}
}
//-------------------------------------------------------------vertex_dist
// Vertex (x, y) with the distance to the next one. The last vertex has
// distance between the last and the first points if the polygon is closed
// and 0.0 if it's a polyline.
struct vertex_dist
{
double x;
double y;
double dist;
vertex_dist() {}
vertex_dist(double x_, double y_) :
x(x_),
y(y_),
dist(0.0)
{
}
bool operator () (const vertex_dist& val)
{
bool ret = (dist = calc_distance(x, y, val.x, val.y)) > vertex_dist_epsilon;
if(!ret) dist = 1.0 / vertex_dist_epsilon;
return ret;
}
};
//--------------------------------------------------------vertex_dist_cmd
// Save as the above but with additional "command" value
struct vertex_dist_cmd : public vertex_dist
{
unsigned cmd;
vertex_dist_cmd() {}
vertex_dist_cmd(double x_, double y_, unsigned cmd_) :
vertex_dist(x_, y_),
cmd(cmd_)
{
}
};
}
#endif

View file

@ -1,339 +1,65 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
The Anti-Grain Geometry Project
A high quality rendering engine for C++
http://antigrain.com
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Anti-Grain Geometry has dual licensing model. The Modified BSD
License was first added in version v2.4 just for convenience.
It is a simple, permissive non-copyleft free software license,
compatible with the GNU GPL. It's well proven and recognizable.
See http://www.fsf.org/licensing/licenses/index_html#ModifiedBSD
for details.
Preamble
Note that the Modified BSD license DOES NOT restrict your rights
if you choose the Anti-Grain Geometry Public License.
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
Anti-Grain Geometry Public License
====================================================
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Anti-Grain Geometry - Version 2.4
Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
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.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
Modified BSD License
====================================================
Anti-Grain Geometry - Version 2.4
Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
3. The name of the author may not be used to endorse or promote
products derived from this software without specific prior
written permission.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View file

@ -1,22 +0,0 @@
project(agg_svg)
cmake_minimum_required(VERSION 2.6)
add_library(agg_svg STATIC
agg_svg_exception.h
agg_svg_parser.cpp
agg_svg_parser.h
agg_svg_path_renderer.cpp
agg_svg_path_renderer.h
agg_svg_path_tokenizer.cpp
agg_svg_path_tokenizer.h
# agg_bezier_arc.cpp
agg_curves.cpp
agg_trans_affine.cpp
agg_vcgen_contour.cpp
agg_vcgen_stroke.cpp
)
target_include_directories(agg_svg PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(agg_svg ${EXPAT_LIBRARIES})

View file

@ -1,261 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#include <math.h>
#include "agg_bezier_arc.h"
namespace agg
{
// This epsilon is used to prevent us from adding degenerate curves
// (converging to a single point).
// The value isn't very critical. Function arc_to_bezier() has a limit
// of the sweep_angle. If fabs(sweep_angle) exceeds pi/2 the curve
// becomes inaccurate. But slight exceeding is quite appropriate.
//-------------------------------------------------bezier_arc_angle_epsilon
const double bezier_arc_angle_epsilon = 0.01;
//------------------------------------------------------------arc_to_bezier
void arc_to_bezier(double cx, double cy, double rx, double ry,
double start_angle, double sweep_angle,
double* curve)
{
double x0 = cos(sweep_angle / 2.0);
double y0 = sin(sweep_angle / 2.0);
double tx = (1.0 - x0) * 4.0 / 3.0;
double ty = y0 - tx * x0 / y0;
double px[4];
double py[4];
px[0] = x0;
py[0] = -y0;
px[1] = x0 + tx;
py[1] = -ty;
px[2] = x0 + tx;
py[2] = ty;
px[3] = x0;
py[3] = y0;
double sn = sin(start_angle + sweep_angle / 2.0);
double cs = cos(start_angle + sweep_angle / 2.0);
unsigned i;
for(i = 0; i < 4; i++)
{
curve[i * 2] = cx + rx * (px[i] * cs - py[i] * sn);
curve[i * 2 + 1] = cy + ry * (px[i] * sn + py[i] * cs);
}
}
//------------------------------------------------------------------------
void bezier_arc::init(double x, double y,
double rx, double ry,
double start_angle,
double sweep_angle)
{
start_angle = fmod(start_angle, 2.0 * pi);
if(sweep_angle >= 2.0 * pi) sweep_angle = 2.0 * pi;
if(sweep_angle <= -2.0 * pi) sweep_angle = -2.0 * pi;
if(fabs(sweep_angle) < 1e-10)
{
m_num_vertices = 4;
m_cmd = path_cmd_line_to;
m_vertices[0] = x + rx * cos(start_angle);
m_vertices[1] = y + ry * sin(start_angle);
m_vertices[2] = x + rx * cos(start_angle + sweep_angle);
m_vertices[3] = y + ry * sin(start_angle + sweep_angle);
return;
}
double total_sweep = 0.0;
double local_sweep = 0.0;
double prev_sweep;
m_num_vertices = 2;
m_cmd = path_cmd_curve4;
bool done = false;
do
{
if(sweep_angle < 0.0)
{
prev_sweep = total_sweep;
local_sweep = -pi * 0.5;
total_sweep -= pi * 0.5;
if(total_sweep <= sweep_angle + bezier_arc_angle_epsilon)
{
local_sweep = sweep_angle - prev_sweep;
done = true;
}
}
else
{
prev_sweep = total_sweep;
local_sweep = pi * 0.5;
total_sweep += pi * 0.5;
if(total_sweep >= sweep_angle - bezier_arc_angle_epsilon)
{
local_sweep = sweep_angle - prev_sweep;
done = true;
}
}
arc_to_bezier(x, y, rx, ry,
start_angle,
local_sweep,
m_vertices + m_num_vertices - 2);
m_num_vertices += 6;
start_angle += local_sweep;
}
while(!done && m_num_vertices < 26);
}
//--------------------------------------------------------------------
void bezier_arc_svg::init(double x0, double y0,
double rx, double ry,
double angle,
bool large_arc_flag,
bool sweep_flag,
double x2, double y2)
{
m_radii_ok = true;
if(rx < 0.0) rx = -rx;
if(ry < 0.0) ry = -rx;
// Calculate the middle point between
// the current and the final points
//------------------------
double dx2 = (x0 - x2) / 2.0;
double dy2 = (y0 - y2) / 2.0;
double cos_a = cos(angle);
double sin_a = sin(angle);
// Calculate (x1, y1)
//------------------------
double x1 = cos_a * dx2 + sin_a * dy2;
double y1 = -sin_a * dx2 + cos_a * dy2;
// Ensure radii are large enough
//------------------------
double prx = rx * rx;
double pry = ry * ry;
double px1 = x1 * x1;
double py1 = y1 * y1;
// Check that radii are large enough
//------------------------
double radii_check = px1/prx + py1/pry;
if(radii_check > 1.0)
{
rx = sqrt(radii_check) * rx;
ry = sqrt(radii_check) * ry;
prx = rx * rx;
pry = ry * ry;
if(radii_check > 10.0) m_radii_ok = false;
}
// Calculate (cx1, cy1)
//------------------------
double sign = (large_arc_flag == sweep_flag) ? -1.0 : 1.0;
double sq = (prx*pry - prx*py1 - pry*px1) / (prx*py1 + pry*px1);
double coef = sign * sqrt((sq < 0) ? 0 : sq);
double cx1 = coef * ((rx * y1) / ry);
double cy1 = coef * -((ry * x1) / rx);
//
// Calculate (cx, cy) from (cx1, cy1)
//------------------------
double sx2 = (x0 + x2) / 2.0;
double sy2 = (y0 + y2) / 2.0;
double cx = sx2 + (cos_a * cx1 - sin_a * cy1);
double cy = sy2 + (sin_a * cx1 + cos_a * cy1);
// Calculate the start_angle (angle1) and the sweep_angle (dangle)
//------------------------
double ux = (x1 - cx1) / rx;
double uy = (y1 - cy1) / ry;
double vx = (-x1 - cx1) / rx;
double vy = (-y1 - cy1) / ry;
double p, n;
// Calculate the angle start
//------------------------
n = sqrt(ux*ux + uy*uy);
p = ux; // (1 * ux) + (0 * uy)
sign = (uy < 0) ? -1.0 : 1.0;
double v = p / n;
if(v < -1.0) v = -1.0;
if(v > 1.0) v = 1.0;
double start_angle = sign * acos(v);
// Calculate the sweep angle
//------------------------
n = sqrt((ux*ux + uy*uy) * (vx*vx + vy*vy));
p = ux * vx + uy * vy;
sign = (ux * vy - uy * vx < 0) ? -1.0 : 1.0;
v = p / n;
if(v < -1.0) v = -1.0;
if(v > 1.0) v = 1.0;
double sweep_angle = sign * acos(v);
if(!sweep_flag && sweep_angle > 0)
{
sweep_angle -= pi * 2.0;
}
else
if (sweep_flag && sweep_angle < 0)
{
sweep_angle += pi * 2.0;
}
// We can now build and transform the resulting arc
//------------------------
m_arc.init(0.0, 0.0, rx, ry, start_angle, sweep_angle);
trans_affine mtx = trans_affine_rotation(angle);
mtx *= trans_affine_translation(cx, cy);
for(unsigned i = 2; i < m_arc.num_vertices()-2; i += 2)
{
mtx.transform(m_arc.vertices() + i, m_arc.vertices() + i + 1);
}
// We must make sure that the starting and ending points
// exactly coincide with the initial (x0,y0) and (x2,y2)
m_arc.vertices()[0] = x0;
m_arc.vertices()[1] = y0;
if(m_arc.num_vertices() > 2)
{
m_arc.vertices()[m_arc.num_vertices() - 2] = x2;
m_arc.vertices()[m_arc.num_vertices() - 1] = y2;
}
}
}

View file

@ -1,620 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#include <math.h>
#include <agg/agg_curves.h>
#include <agg/agg_math.h>
namespace agg
{
//------------------------------------------------------------------------
const double curve_distance_epsilon = 1e-30;
const double curve_collinearity_epsilon = 1e-30;
const double curve_angle_tolerance_epsilon = 0.01;
enum curve_recursion_limit_e { curve_recursion_limit = 32 };
//------------------------------------------------------------------------
void curve3_inc::approximation_scale(double s)
{
m_scale = s;
}
//------------------------------------------------------------------------
double curve3_inc::approximation_scale() const
{
return m_scale;
}
//------------------------------------------------------------------------
void curve3_inc::init(double x1, double y1,
double x2, double y2,
double x3, double y3)
{
m_start_x = x1;
m_start_y = y1;
m_end_x = x3;
m_end_y = y3;
double dx1 = x2 - x1;
double dy1 = y2 - y1;
double dx2 = x3 - x2;
double dy2 = y3 - y2;
double len = sqrt(dx1 * dx1 + dy1 * dy1) + sqrt(dx2 * dx2 + dy2 * dy2);
m_num_steps = uround(len * 0.25 * m_scale);
if(m_num_steps < 4)
{
m_num_steps = 4;
}
double subdivide_step = 1.0 / m_num_steps;
double subdivide_step2 = subdivide_step * subdivide_step;
double tmpx = (x1 - x2 * 2.0 + x3) * subdivide_step2;
double tmpy = (y1 - y2 * 2.0 + y3) * subdivide_step2;
m_saved_fx = m_fx = x1;
m_saved_fy = m_fy = y1;
m_saved_dfx = m_dfx = tmpx + (x2 - x1) * (2.0 * subdivide_step);
m_saved_dfy = m_dfy = tmpy + (y2 - y1) * (2.0 * subdivide_step);
m_ddfx = tmpx * 2.0;
m_ddfy = tmpy * 2.0;
m_step = m_num_steps;
}
//------------------------------------------------------------------------
void curve3_inc::rewind(unsigned)
{
if(m_num_steps == 0)
{
m_step = -1;
return;
}
m_step = m_num_steps;
m_fx = m_saved_fx;
m_fy = m_saved_fy;
m_dfx = m_saved_dfx;
m_dfy = m_saved_dfy;
}
//------------------------------------------------------------------------
unsigned curve3_inc::vertex(double* x, double* y)
{
if(m_step < 0) return path_cmd_stop;
if(m_step == m_num_steps)
{
*x = m_start_x;
*y = m_start_y;
--m_step;
return path_cmd_move_to;
}
if(m_step == 0)
{
*x = m_end_x;
*y = m_end_y;
--m_step;
return path_cmd_line_to;
}
m_fx += m_dfx;
m_fy += m_dfy;
m_dfx += m_ddfx;
m_dfy += m_ddfy;
*x = m_fx;
*y = m_fy;
--m_step;
return path_cmd_line_to;
}
//------------------------------------------------------------------------
void curve3_div::init(double x1, double y1,
double x2, double y2,
double x3, double y3)
{
m_points.remove_all();
m_distance_tolerance_square = 0.5 / m_approximation_scale;
m_distance_tolerance_square *= m_distance_tolerance_square;
bezier(x1, y1, x2, y2, x3, y3);
m_count = 0;
}
//------------------------------------------------------------------------
void curve3_div::recursive_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
unsigned level)
{
if(level > curve_recursion_limit)
{
return;
}
// Calculate all the mid-points of the line segments
//----------------------
double x12 = (x1 + x2) / 2;
double y12 = (y1 + y2) / 2;
double x23 = (x2 + x3) / 2;
double y23 = (y2 + y3) / 2;
double x123 = (x12 + x23) / 2;
double y123 = (y12 + y23) / 2;
double dx = x3-x1;
double dy = y3-y1;
double d = fabs(((x2 - x3) * dy - (y2 - y3) * dx));
double da;
if(d > curve_collinearity_epsilon)
{
// Regular case
//-----------------
if(d * d <= m_distance_tolerance_square * (dx*dx + dy*dy))
{
// If the curvature doesn't exceed the distance_tolerance value
// we tend to finish subdivisions.
//----------------------
if(m_angle_tolerance < curve_angle_tolerance_epsilon)
{
m_points.add(point_d(x123, y123));
return;
}
// Angle & Cusp Condition
//----------------------
da = fabs(atan2(y3 - y2, x3 - x2) - atan2(y2 - y1, x2 - x1));
if(da >= pi) da = 2*pi - da;
if(da < m_angle_tolerance)
{
// Finally we can stop the recursion
//----------------------
m_points.add(point_d(x123, y123));
return;
}
}
}
else
{
// Collinear case
//------------------
da = dx*dx + dy*dy;
if(da == 0)
{
d = calc_sq_distance(x1, y1, x2, y2);
}
else
{
d = ((x2 - x1)*dx + (y2 - y1)*dy) / da;
if(d > 0 && d < 1)
{
// Simple collinear case, 1---2---3
// We can leave just two endpoints
return;
}
if(d <= 0) d = calc_sq_distance(x2, y2, x1, y1);
else if(d >= 1) d = calc_sq_distance(x2, y2, x3, y3);
else d = calc_sq_distance(x2, y2, x1 + d*dx, y1 + d*dy);
}
if(d < m_distance_tolerance_square)
{
m_points.add(point_d(x2, y2));
return;
}
}
// Continue subdivision
//----------------------
recursive_bezier(x1, y1, x12, y12, x123, y123, level + 1);
recursive_bezier(x123, y123, x23, y23, x3, y3, level + 1);
}
//------------------------------------------------------------------------
void curve3_div::bezier(double x1, double y1,
double x2, double y2,
double x3, double y3)
{
m_points.add(point_d(x1, y1));
recursive_bezier(x1, y1, x2, y2, x3, y3, 0);
m_points.add(point_d(x3, y3));
}
//------------------------------------------------------------------------
void curve4_inc::approximation_scale(double s)
{
m_scale = s;
}
//------------------------------------------------------------------------
double curve4_inc::approximation_scale() const
{
return m_scale;
}
//------------------------------------------------------------------------
static double MSC60_fix_ICE(double v) { return v; }
//------------------------------------------------------------------------
void curve4_inc::init(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
m_start_x = x1;
m_start_y = y1;
m_end_x = x4;
m_end_y = y4;
double dx1 = x2 - x1;
double dy1 = y2 - y1;
double dx2 = x3 - x2;
double dy2 = y3 - y2;
double dx3 = x4 - x3;
double dy3 = y4 - y3;
double len = (sqrt(dx1 * dx1 + dy1 * dy1) +
sqrt(dx2 * dx2 + dy2 * dy2) +
sqrt(dx3 * dx3 + dy3 * dy3)) * 0.25 * m_scale;
#if defined(_MSC_VER) && _MSC_VER <= 1200
m_num_steps = uround(MSC60_fix_ICE(len));
#else
m_num_steps = uround(len);
#endif
if(m_num_steps < 4)
{
m_num_steps = 4;
}
double subdivide_step = 1.0 / m_num_steps;
double subdivide_step2 = subdivide_step * subdivide_step;
double subdivide_step3 = subdivide_step * subdivide_step * subdivide_step;
double pre1 = 3.0 * subdivide_step;
double pre2 = 3.0 * subdivide_step2;
double pre4 = 6.0 * subdivide_step2;
double pre5 = 6.0 * subdivide_step3;
double tmp1x = x1 - x2 * 2.0 + x3;
double tmp1y = y1 - y2 * 2.0 + y3;
double tmp2x = (x2 - x3) * 3.0 - x1 + x4;
double tmp2y = (y2 - y3) * 3.0 - y1 + y4;
m_saved_fx = m_fx = x1;
m_saved_fy = m_fy = y1;
m_saved_dfx = m_dfx = (x2 - x1) * pre1 + tmp1x * pre2 + tmp2x * subdivide_step3;
m_saved_dfy = m_dfy = (y2 - y1) * pre1 + tmp1y * pre2 + tmp2y * subdivide_step3;
m_saved_ddfx = m_ddfx = tmp1x * pre4 + tmp2x * pre5;
m_saved_ddfy = m_ddfy = tmp1y * pre4 + tmp2y * pre5;
m_dddfx = tmp2x * pre5;
m_dddfy = tmp2y * pre5;
m_step = m_num_steps;
}
//------------------------------------------------------------------------
void curve4_inc::rewind(unsigned)
{
if(m_num_steps == 0)
{
m_step = -1;
return;
}
m_step = m_num_steps;
m_fx = m_saved_fx;
m_fy = m_saved_fy;
m_dfx = m_saved_dfx;
m_dfy = m_saved_dfy;
m_ddfx = m_saved_ddfx;
m_ddfy = m_saved_ddfy;
}
//------------------------------------------------------------------------
unsigned curve4_inc::vertex(double* x, double* y)
{
if(m_step < 0) return path_cmd_stop;
if(m_step == m_num_steps)
{
*x = m_start_x;
*y = m_start_y;
--m_step;
return path_cmd_move_to;
}
if(m_step == 0)
{
*x = m_end_x;
*y = m_end_y;
--m_step;
return path_cmd_line_to;
}
m_fx += m_dfx;
m_fy += m_dfy;
m_dfx += m_ddfx;
m_dfy += m_ddfy;
m_ddfx += m_dddfx;
m_ddfy += m_dddfy;
*x = m_fx;
*y = m_fy;
--m_step;
return path_cmd_line_to;
}
//------------------------------------------------------------------------
void curve4_div::init(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
m_points.remove_all();
m_distance_tolerance_square = 0.5 / m_approximation_scale;
m_distance_tolerance_square *= m_distance_tolerance_square;
bezier(x1, y1, x2, y2, x3, y3, x4, y4);
m_count = 0;
}
//------------------------------------------------------------------------
void curve4_div::recursive_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4,
unsigned level)
{
if(level > curve_recursion_limit)
{
return;
}
// Calculate all the mid-points of the line segments
//----------------------
double x12 = (x1 + x2) / 2;
double y12 = (y1 + y2) / 2;
double x23 = (x2 + x3) / 2;
double y23 = (y2 + y3) / 2;
double x34 = (x3 + x4) / 2;
double y34 = (y3 + y4) / 2;
double x123 = (x12 + x23) / 2;
double y123 = (y12 + y23) / 2;
double x234 = (x23 + x34) / 2;
double y234 = (y23 + y34) / 2;
double x1234 = (x123 + x234) / 2;
double y1234 = (y123 + y234) / 2;
// Try to approximate the full cubic curve by a single straight line
//------------------
double dx = x4-x1;
double dy = y4-y1;
double d2 = fabs(((x2 - x4) * dy - (y2 - y4) * dx));
double d3 = fabs(((x3 - x4) * dy - (y3 - y4) * dx));
double da1, da2, k;
switch((int(d2 > curve_collinearity_epsilon) << 1) +
int(d3 > curve_collinearity_epsilon))
{
case 0:
// All collinear OR p1==p4
//----------------------
k = dx*dx + dy*dy;
if(k == 0)
{
d2 = calc_sq_distance(x1, y1, x2, y2);
d3 = calc_sq_distance(x4, y4, x3, y3);
}
else
{
k = 1 / k;
da1 = x2 - x1;
da2 = y2 - y1;
d2 = k * (da1*dx + da2*dy);
da1 = x3 - x1;
da2 = y3 - y1;
d3 = k * (da1*dx + da2*dy);
if(d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1)
{
// Simple collinear case, 1---2---3---4
// We can leave just two endpoints
return;
}
if(d2 <= 0) d2 = calc_sq_distance(x2, y2, x1, y1);
else if(d2 >= 1) d2 = calc_sq_distance(x2, y2, x4, y4);
else d2 = calc_sq_distance(x2, y2, x1 + d2*dx, y1 + d2*dy);
if(d3 <= 0) d3 = calc_sq_distance(x3, y3, x1, y1);
else if(d3 >= 1) d3 = calc_sq_distance(x3, y3, x4, y4);
else d3 = calc_sq_distance(x3, y3, x1 + d3*dx, y1 + d3*dy);
}
if(d2 > d3)
{
if(d2 < m_distance_tolerance_square)
{
m_points.add(point_d(x2, y2));
return;
}
}
else
{
if(d3 < m_distance_tolerance_square)
{
m_points.add(point_d(x3, y3));
return;
}
}
break;
case 1:
// p1,p2,p4 are collinear, p3 is significant
//----------------------
if(d3 * d3 <= m_distance_tolerance_square * (dx*dx + dy*dy))
{
if(m_angle_tolerance < curve_angle_tolerance_epsilon)
{
m_points.add(point_d(x23, y23));
return;
}
// Angle Condition
//----------------------
da1 = fabs(atan2(y4 - y3, x4 - x3) - atan2(y3 - y2, x3 - x2));
if(da1 >= pi) da1 = 2*pi - da1;
if(da1 < m_angle_tolerance)
{
m_points.add(point_d(x2, y2));
m_points.add(point_d(x3, y3));
return;
}
if(m_cusp_limit != 0.0)
{
if(da1 > m_cusp_limit)
{
m_points.add(point_d(x3, y3));
return;
}
}
}
break;
case 2:
// p1,p3,p4 are collinear, p2 is significant
//----------------------
if(d2 * d2 <= m_distance_tolerance_square * (dx*dx + dy*dy))
{
if(m_angle_tolerance < curve_angle_tolerance_epsilon)
{
m_points.add(point_d(x23, y23));
return;
}
// Angle Condition
//----------------------
da1 = fabs(atan2(y3 - y2, x3 - x2) - atan2(y2 - y1, x2 - x1));
if(da1 >= pi) da1 = 2*pi - da1;
if(da1 < m_angle_tolerance)
{
m_points.add(point_d(x2, y2));
m_points.add(point_d(x3, y3));
return;
}
if(m_cusp_limit != 0.0)
{
if(da1 > m_cusp_limit)
{
m_points.add(point_d(x2, y2));
return;
}
}
}
break;
case 3:
// Regular case
//-----------------
if((d2 + d3)*(d2 + d3) <= m_distance_tolerance_square * (dx*dx + dy*dy))
{
// If the curvature doesn't exceed the distance_tolerance value
// we tend to finish subdivisions.
//----------------------
if(m_angle_tolerance < curve_angle_tolerance_epsilon)
{
m_points.add(point_d(x23, y23));
return;
}
// Angle & Cusp Condition
//----------------------
k = atan2(y3 - y2, x3 - x2);
da1 = fabs(k - atan2(y2 - y1, x2 - x1));
da2 = fabs(atan2(y4 - y3, x4 - x3) - k);
if(da1 >= pi) da1 = 2*pi - da1;
if(da2 >= pi) da2 = 2*pi - da2;
if(da1 + da2 < m_angle_tolerance)
{
// Finally we can stop the recursion
//----------------------
m_points.add(point_d(x23, y23));
return;
}
if(m_cusp_limit != 0.0)
{
if(da1 > m_cusp_limit)
{
m_points.add(point_d(x2, y2));
return;
}
if(da2 > m_cusp_limit)
{
m_points.add(point_d(x3, y3));
return;
}
}
}
break;
}
// Continue subdivision
//----------------------
recursive_bezier(x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1);
recursive_bezier(x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1);
}
//------------------------------------------------------------------------
void curve4_div::bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
m_points.add(point_d(x1, y1));
recursive_bezier(x1, y1, x2, y2, x3, y3, x4, y4, 0);
m_points.add(point_d(x4, y4));
}
}

View file

@ -1,69 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.3
// 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
//----------------------------------------------------------------------------
//
// SVG exception
//
//----------------------------------------------------------------------------
#ifndef AGG_SVG_EXCEPTION_INCLUDED
#define AGG_SVG_EXCEPTION_INCLUDED
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
namespace agg
{
namespace svg
{
class exception
{
public:
~exception()
{
delete [] m_msg;
}
exception() : m_msg(0) {}
exception(const char* fmt, ...) :
m_msg(0)
{
if(fmt)
{
m_msg = new char [4096];
va_list arg;
va_start(arg, fmt);
vsprintf(m_msg, fmt, arg);
va_end(arg);
}
}
exception(const exception& exc) :
m_msg(exc.m_msg ? new char[strlen(exc.m_msg) + 1] : 0)
{
if(m_msg) strcpy(m_msg, exc.m_msg);
}
const char* msg() const { return m_msg; }
private:
char* m_msg;
};
}
}
#endif

View file

@ -1,886 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.3
// 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
//----------------------------------------------------------------------------
//
// SVG parser.
//
//----------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "agg_svg_parser.h"
#include "expat.h"
namespace agg
{
namespace svg
{
struct named_color
{
char name[22];
int8u r, g, b, a;
};
named_color colors[] =
{
{ "aliceblue",240,248,255, 255 },
{ "antiquewhite",250,235,215, 255 },
{ "aqua",0,255,255, 255 },
{ "aquamarine",127,255,212, 255 },
{ "azure",240,255,255, 255 },
{ "beige",245,245,220, 255 },
{ "bisque",255,228,196, 255 },
{ "black",0,0,0, 255 },
{ "blanchedalmond",255,235,205, 255 },
{ "blue",0,0,255, 255 },
{ "blueviolet",138,43,226, 255 },
{ "brown",165,42,42, 255 },
{ "burlywood",222,184,135, 255 },
{ "cadetblue",95,158,160, 255 },
{ "chartreuse",127,255,0, 255 },
{ "chocolate",210,105,30, 255 },
{ "coral",255,127,80, 255 },
{ "cornflowerblue",100,149,237, 255 },
{ "cornsilk",255,248,220, 255 },
{ "crimson",220,20,60, 255 },
{ "cyan",0,255,255, 255 },
{ "darkblue",0,0,139, 255 },
{ "darkcyan",0,139,139, 255 },
{ "darkgoldenrod",184,134,11, 255 },
{ "darkgray",169,169,169, 255 },
{ "darkgreen",0,100,0, 255 },
{ "darkgrey",169,169,169, 255 },
{ "darkkhaki",189,183,107, 255 },
{ "darkmagenta",139,0,139, 255 },
{ "darkolivegreen",85,107,47, 255 },
{ "darkorange",255,140,0, 255 },
{ "darkorchid",153,50,204, 255 },
{ "darkred",139,0,0, 255 },
{ "darksalmon",233,150,122, 255 },
{ "darkseagreen",143,188,143, 255 },
{ "darkslateblue",72,61,139, 255 },
{ "darkslategray",47,79,79, 255 },
{ "darkslategrey",47,79,79, 255 },
{ "darkturquoise",0,206,209, 255 },
{ "darkviolet",148,0,211, 255 },
{ "deeppink",255,20,147, 255 },
{ "deepskyblue",0,191,255, 255 },
{ "dimgray",105,105,105, 255 },
{ "dimgrey",105,105,105, 255 },
{ "dodgerblue",30,144,255, 255 },
{ "firebrick",178,34,34, 255 },
{ "floralwhite",255,250,240, 255 },
{ "forestgreen",34,139,34, 255 },
{ "fuchsia",255,0,255, 255 },
{ "gainsboro",220,220,220, 255 },
{ "ghostwhite",248,248,255, 255 },
{ "gold",255,215,0, 255 },
{ "goldenrod",218,165,32, 255 },
{ "gray",128,128,128, 255 },
{ "green",0,128,0, 255 },
{ "greenyellow",173,255,47, 255 },
{ "grey",128,128,128, 255 },
{ "honeydew",240,255,240, 255 },
{ "hotpink",255,105,180, 255 },
{ "indianred",205,92,92, 255 },
{ "indigo",75,0,130, 255 },
{ "ivory",255,255,240, 255 },
{ "khaki",240,230,140, 255 },
{ "lavender",230,230,250, 255 },
{ "lavenderblush",255,240,245, 255 },
{ "lawngreen",124,252,0, 255 },
{ "lemonchiffon",255,250,205, 255 },
{ "lightblue",173,216,230, 255 },
{ "lightcoral",240,128,128, 255 },
{ "lightcyan",224,255,255, 255 },
{ "lightgoldenrodyellow",250,250,210, 255 },
{ "lightgray",211,211,211, 255 },
{ "lightgreen",144,238,144, 255 },
{ "lightgrey",211,211,211, 255 },
{ "lightpink",255,182,193, 255 },
{ "lightsalmon",255,160,122, 255 },
{ "lightseagreen",32,178,170, 255 },
{ "lightskyblue",135,206,250, 255 },
{ "lightslategray",119,136,153, 255 },
{ "lightslategrey",119,136,153, 255 },
{ "lightsteelblue",176,196,222, 255 },
{ "lightyellow",255,255,224, 255 },
{ "lime",0,255,0, 255 },
{ "limegreen",50,205,50, 255 },
{ "linen",250,240,230, 255 },
{ "magenta",255,0,255, 255 },
{ "maroon",128,0,0, 255 },
{ "mediumaquamarine",102,205,170, 255 },
{ "mediumblue",0,0,205, 255 },
{ "mediumorchid",186,85,211, 255 },
{ "mediumpurple",147,112,219, 255 },
{ "mediumseagreen",60,179,113, 255 },
{ "mediumslateblue",123,104,238, 255 },
{ "mediumspringgreen",0,250,154, 255 },
{ "mediumturquoise",72,209,204, 255 },
{ "mediumvioletred",199,21,133, 255 },
{ "midnightblue",25,25,112, 255 },
{ "mintcream",245,255,250, 255 },
{ "mistyrose",255,228,225, 255 },
{ "moccasin",255,228,181, 255 },
{ "navajowhite",255,222,173, 255 },
{ "navy",0,0,128, 255 },
{ "oldlace",253,245,230, 255 },
{ "olive",128,128,0, 255 },
{ "olivedrab",107,142,35, 255 },
{ "orange",255,165,0, 255 },
{ "orangered",255,69,0, 255 },
{ "orchid",218,112,214, 255 },
{ "palegoldenrod",238,232,170, 255 },
{ "palegreen",152,251,152, 255 },
{ "paleturquoise",175,238,238, 255 },
{ "palevioletred",219,112,147, 255 },
{ "papayawhip",255,239,213, 255 },
{ "peachpuff",255,218,185, 255 },
{ "peru",205,133,63, 255 },
{ "pink",255,192,203, 255 },
{ "plum",221,160,221, 255 },
{ "powderblue",176,224,230, 255 },
{ "purple",128,0,128, 255 },
{ "red",255,0,0, 255 },
{ "rosybrown",188,143,143, 255 },
{ "royalblue",65,105,225, 255 },
{ "saddlebrown",139,69,19, 255 },
{ "salmon",250,128,114, 255 },
{ "sandybrown",244,164,96, 255 },
{ "seagreen",46,139,87, 255 },
{ "seashell",255,245,238, 255 },
{ "sienna",160,82,45, 255 },
{ "silver",192,192,192, 255 },
{ "skyblue",135,206,235, 255 },
{ "slateblue",106,90,205, 255 },
{ "slategray",112,128,144, 255 },
{ "slategrey",112,128,144, 255 },
{ "snow",255,250,250, 255 },
{ "springgreen",0,255,127, 255 },
{ "steelblue",70,130,180, 255 },
{ "tan",210,180,140, 255 },
{ "teal",0,128,128, 255 },
{ "thistle",216,191,216, 255 },
{ "tomato",255,99,71, 255 },
{ "turquoise",64,224,208, 255 },
{ "violet",238,130,238, 255 },
{ "wheat",245,222,179, 255 },
{ "white",255,255,255, 255 },
{ "whitesmoke",245,245,245, 255 },
{ "yellow",255,255,0, 255 },
{ "yellowgreen",154,205,50, 255 },
{ "zzzzzzzzzzz",0,0,0, 0 }
};
//------------------------------------------------------------------------
parser::~parser()
{
delete [] m_attr_value;
delete [] m_attr_name;
delete [] m_buf;
delete [] m_title;
}
//------------------------------------------------------------------------
parser::parser(path_renderer& path) :
m_path(path),
m_tokenizer(),
m_buf(new char[buf_size]),
m_title(new char[256]),
m_title_len(0),
m_title_flag(false),
m_path_flag(false),
m_attr_name(new char[128]),
m_attr_value(new char[1024]),
m_attr_name_len(127),
m_attr_value_len(1023)
{
m_title[0] = 0;
}
//------------------------------------------------------------------------
void parser::parse(const char* fname)
{
char msg[1024];
XML_Parser p = XML_ParserCreate(NULL);
if(p == 0)
{
throw exception("Couldn't allocate memory for parser");
}
XML_SetUserData(p, this);
XML_SetElementHandler(p, start_element, end_element);
XML_SetCharacterDataHandler(p, content);
FILE* fd = fopen(fname, "r");
if(fd == 0)
{
sprintf(msg, "Couldn't open file %s", fname);
throw exception(msg);
}
bool done = false;
do
{
size_t len = fread(m_buf, 1, buf_size, fd);
done = len < buf_size;
if(!XML_Parse(p, m_buf, len, done))
{
sprintf(msg,
"%s at line %d\n",
XML_ErrorString(XML_GetErrorCode(p)),
XML_GetCurrentLineNumber(p));
throw exception(msg);
}
}
while(!done);
fclose(fd);
XML_ParserFree(p);
char* ts = m_title;
while(*ts)
{
if(*ts < ' ') *ts = ' ';
++ts;
}
}
//------------------------------------------------------------------------
void parser::start_element(void* data, const char* el, const char** attr)
{
parser& self = *(parser*)data;
if(strcmp(el, "title") == 0)
{
self.m_title_flag = true;
}
else
if(strcmp(el, "g") == 0)
{
self.m_path.push_attr();
self.parse_attr(attr);
}
else
if(strcmp(el, "path") == 0)
{
if(self.m_path_flag)
{
throw exception("start_element: Nested path");
}
self.m_path.begin_path();
self.parse_path(attr);
self.m_path.end_path();
self.m_path_flag = true;
}
else
if(strcmp(el, "rect") == 0)
{
self.parse_rect(attr);
}
else
if(strcmp(el, "line") == 0)
{
self.parse_line(attr);
}
else
if(strcmp(el, "polyline") == 0)
{
self.parse_poly(attr, false);
}
else
if(strcmp(el, "polygon") == 0)
{
self.parse_poly(attr, true);
}
//else
//if(strcmp(el, "<OTHER_ELEMENTS>") == 0)
//{
//}
// . . .
}
//------------------------------------------------------------------------
void parser::end_element(void* data, const char* el)
{
parser& self = *(parser*)data;
if(strcmp(el, "title") == 0)
{
self.m_title_flag = false;
}
else
if(strcmp(el, "g") == 0)
{
self.m_path.pop_attr();
}
else
if(strcmp(el, "path") == 0)
{
self.m_path_flag = false;
}
//else
//if(strcmp(el, "<OTHER_ELEMENTS>") == 0)
//{
//}
// . . .
}
//------------------------------------------------------------------------
void parser::content(void* data, const char* s, int len)
{
parser& self = *(parser*)data;
// m_title_flag signals that the <title> tag is being parsed now.
// The following code concatenates the pieces of content of the <title> tag.
if(self.m_title_flag)
{
if(len + self.m_title_len > 255) len = 255 - self.m_title_len;
if(len > 0)
{
memcpy(self.m_title + self.m_title_len, s, len);
self.m_title_len += len;
self.m_title[self.m_title_len] = 0;
}
}
}
//------------------------------------------------------------------------
void parser::parse_attr(const char** attr)
{
int i;
for(i = 0; attr[i]; i += 2)
{
if(strcmp(attr[i], "style") == 0)
{
parse_style(attr[i + 1]);
}
else
{
parse_attr(attr[i], attr[i + 1]);
}
}
}
//-------------------------------------------------------------
void parser::parse_path(const char** attr)
{
int i;
for(i = 0; attr[i]; i += 2)
{
// The <path> tag can consist of the path itself ("d=")
// as well as of other parameters like "style=", "transform=", etc.
// In the last case we simply rely on the function of parsing
// attributes (see 'else' branch).
if(strcmp(attr[i], "d") == 0)
{
m_tokenizer.set_path_str(attr[i + 1]);
m_path.parse_path(m_tokenizer);
}
else
{
// Create a temporary single pair "name-value" in order
// to avoid multiple calls for the same attribute.
const char* tmp[4];
tmp[0] = attr[i];
tmp[1] = attr[i + 1];
tmp[2] = 0;
tmp[3] = 0;
parse_attr(tmp);
}
}
}
//-------------------------------------------------------------
int cmp_color(const void* p1, const void* p2)
{
return strcmp(((named_color*)p1)->name, ((named_color*)p2)->name);
}
//-------------------------------------------------------------
rgba8 parse_color(const char* str)
{
while(*str == ' ') ++str;
unsigned c = 0;
if(*str == '#')
{
sscanf(str + 1, "%x", &c);
return rgb8_packed(c);
}
else
{
named_color c;
unsigned len = strlen(str);
if(len > sizeof(c.name) - 1)
{
throw exception("parse_color: Invalid color name '%s'", str);
}
strcpy(c.name, str);
const void* p = bsearch(&c,
colors,
sizeof(colors) / sizeof(colors[0]),
sizeof(colors[0]),
cmp_color);
if(p == 0)
{
throw exception("parse_color: Invalid color name '%s'", str);
}
const named_color* pc = (const named_color*)p;
return rgba8(pc->r, pc->g, pc->b, pc->a);
}
}
double parse_double(const char* str)
{
while(*str == ' ') ++str;
return atof(str);
}
//-------------------------------------------------------------
bool parser::parse_attr(const char* name, const char* value)
{
if(strcmp(name, "style") == 0)
{
parse_style(value);
}
else
if(strcmp(name, "fill") == 0)
{
if(strcmp(value, "none") == 0)
{
m_path.fill_none();
}
else
{
m_path.fill(parse_color(value));
}
}
else
if(strcmp(name, "fill-opacity") == 0)
{
m_path.fill_opacity(parse_double(value));
}
else
if(strcmp(name, "stroke") == 0)
{
if(strcmp(value, "none") == 0)
{
m_path.stroke_none();
}
else
{
m_path.stroke(parse_color(value));
}
}
else
if(strcmp(name, "stroke-width") == 0)
{
m_path.stroke_width(parse_double(value));
}
else
if(strcmp(name, "stroke-linecap") == 0)
{
if(strcmp(value, "butt") == 0) m_path.line_cap(butt_cap);
else if(strcmp(value, "round") == 0) m_path.line_cap(round_cap);
else if(strcmp(value, "square") == 0) m_path.line_cap(square_cap);
}
else
if(strcmp(name, "stroke-linejoin") == 0)
{
if(strcmp(value, "miter") == 0) m_path.line_join(miter_join);
else if(strcmp(value, "round") == 0) m_path.line_join(round_join);
else if(strcmp(value, "bevel") == 0) m_path.line_join(bevel_join);
}
else
if(strcmp(name, "stroke-miterlimit") == 0)
{
m_path.miter_limit(parse_double(value));
}
else
if(strcmp(name, "stroke-opacity") == 0)
{
m_path.stroke_opacity(parse_double(value));
}
else
if(strcmp(name, "transform") == 0)
{
parse_transform(value);
}
//else
//if(strcmp(el, "<OTHER_ATTRIBUTES>") == 0)
//{
//}
// . . .
else
{
return false;
}
return true;
}
//-------------------------------------------------------------
void parser::copy_name(const char* start, const char* end)
{
unsigned len = unsigned(end - start);
if(m_attr_name_len == 0 || len > m_attr_name_len)
{
delete [] m_attr_name;
m_attr_name = new char[len + 1];
m_attr_name_len = len;
}
if(len) memcpy(m_attr_name, start, len);
m_attr_name[len] = 0;
}
//-------------------------------------------------------------
void parser::copy_value(const char* start, const char* end)
{
unsigned len = unsigned(end - start);
if(m_attr_value_len == 0 || len > m_attr_value_len)
{
delete [] m_attr_value;
m_attr_value = new char[len + 1];
m_attr_value_len = len;
}
if(len) memcpy(m_attr_value, start, len);
m_attr_value[len] = 0;
}
//-------------------------------------------------------------
bool parser::parse_name_value(const char* nv_start, const char* nv_end)
{
const char* str = nv_start;
while(str < nv_end && *str != ':') ++str;
const char* val = str;
// Right Trim
while(str > nv_start &&
(*str == ':' || isspace(*str))) --str;
++str;
copy_name(nv_start, str);
while(val < nv_end && (*val == ':' || isspace(*val))) ++val;
copy_value(val, nv_end);
return parse_attr(m_attr_name, m_attr_value);
}
//-------------------------------------------------------------
void parser::parse_style(const char* str)
{
while(*str)
{
// Left Trim
while(*str && isspace(*str)) ++str;
const char* nv_start = str;
while(*str && *str != ';') ++str;
const char* nv_end = str;
// Right Trim
while(nv_end > nv_start &&
(*nv_end == ';' || isspace(*nv_end))) --nv_end;
++nv_end;
parse_name_value(nv_start, nv_end);
if(*str) ++str;
}
}
//-------------------------------------------------------------
void parser::parse_rect(const char** attr)
{
int i;
double x = 0.0;
double y = 0.0;
double w = 0.0;
double h = 0.0;
m_path.begin_path();
for(i = 0; attr[i]; i += 2)
{
if(!parse_attr(attr[i], attr[i + 1]))
{
if(strcmp(attr[i], "x") == 0) x = parse_double(attr[i + 1]);
if(strcmp(attr[i], "y") == 0) y = parse_double(attr[i + 1]);
if(strcmp(attr[i], "width") == 0) w = parse_double(attr[i + 1]);
if(strcmp(attr[i], "height") == 0) h = parse_double(attr[i + 1]);
// rx - to be implemented
// ry - to be implemented
}
}
if(w != 0.0 && h != 0.0)
{
if(w < 0.0) throw exception("parse_rect: Invalid width: %f", w);
if(h < 0.0) throw exception("parse_rect: Invalid height: %f", h);
m_path.move_to(x, y);
m_path.line_to(x + w, y);
m_path.line_to(x + w, y + h);
m_path.line_to(x, y + h);
m_path.close_subpath();
}
m_path.end_path();
}
//-------------------------------------------------------------
void parser::parse_line(const char** attr)
{
int i;
double x1 = 0.0;
double y1 = 0.0;
double x2 = 0.0;
double y2 = 0.0;
m_path.begin_path();
for(i = 0; attr[i]; i += 2)
{
if(!parse_attr(attr[i], attr[i + 1]))
{
if(strcmp(attr[i], "x1") == 0) x1 = parse_double(attr[i + 1]);
if(strcmp(attr[i], "y1") == 0) y1 = parse_double(attr[i + 1]);
if(strcmp(attr[i], "x2") == 0) x2 = parse_double(attr[i + 1]);
if(strcmp(attr[i], "y2") == 0) y2 = parse_double(attr[i + 1]);
}
}
m_path.move_to(x1, y1);
m_path.line_to(x2, y2);
m_path.end_path();
}
//-------------------------------------------------------------
void parser::parse_poly(const char** attr, bool close_flag)
{
int i;
double x = 0.0;
double y = 0.0;
m_path.begin_path();
for(i = 0; attr[i]; i += 2)
{
if(!parse_attr(attr[i], attr[i + 1]))
{
if(strcmp(attr[i], "points") == 0)
{
m_tokenizer.set_path_str(attr[i + 1]);
if(!m_tokenizer.next())
{
throw exception("parse_poly: Too few coordinates");
}
x = m_tokenizer.last_number();
if(!m_tokenizer.next())
{
throw exception("parse_poly: Too few coordinates");
}
y = m_tokenizer.last_number();
m_path.move_to(x, y);
while(m_tokenizer.next())
{
x = m_tokenizer.last_number();
if(!m_tokenizer.next())
{
throw exception("parse_poly: Odd number of coordinates");
}
y = m_tokenizer.last_number();
m_path.line_to(x, y);
}
}
}
}
if(close_flag)
{
m_path.close_subpath();
}
m_path.end_path();
}
//-------------------------------------------------------------
void parser::parse_transform(const char* str)
{
while(*str)
{
if(islower(*str))
{
if(strncmp(str, "matrix", 6) == 0) str += parse_matrix(str); else
if(strncmp(str, "translate", 9) == 0) str += parse_translate(str); else
if(strncmp(str, "rotate", 6) == 0) str += parse_rotate(str); else
if(strncmp(str, "scale", 5) == 0) str += parse_scale(str); else
if(strncmp(str, "skewX", 5) == 0) str += parse_skew_x(str); else
if(strncmp(str, "skewY", 5) == 0) str += parse_skew_y(str); else
{
++str;
}
}
else
{
++str;
}
}
}
//-------------------------------------------------------------
static bool is_numeric(char c)
{
return strchr("0123456789+-.eE", c) != 0;
}
//-------------------------------------------------------------
static unsigned parse_transform_args(const char* str,
double* args,
unsigned max_na,
unsigned* na)
{
*na = 0;
const char* ptr = str;
while(*ptr && *ptr != '(') ++ptr;
if(*ptr == 0)
{
throw exception("parse_transform_args: Invalid syntax");
}
const char* end = ptr;
while(*end && *end != ')') ++end;
if(*end == 0)
{
throw exception("parse_transform_args: Invalid syntax");
}
while(ptr < end)
{
if(is_numeric(*ptr))
{
if(*na >= max_na)
{
throw exception("parse_transform_args: Too many arguments");
}
args[(*na)++] = atof(ptr);
while(ptr < end && is_numeric(*ptr)) ++ptr;
}
else
{
++ptr;
}
}
return unsigned(end - str);
}
//-------------------------------------------------------------
unsigned parser::parse_matrix(const char* str)
{
double args[6];
unsigned na = 0;
unsigned len = parse_transform_args(str, args, 6, &na);
if(na != 6)
{
throw exception("parse_matrix: Invalid number of arguments");
}
m_path.transform().premultiply(trans_affine(args[0], args[1], args[2], args[3], args[4], args[5]));
return len;
}
//-------------------------------------------------------------
unsigned parser::parse_translate(const char* str)
{
double args[2];
unsigned na = 0;
unsigned len = parse_transform_args(str, args, 2, &na);
if(na == 1) args[1] = 0.0;
m_path.transform().premultiply(trans_affine_translation(args[0], args[1]));
return len;
}
//-------------------------------------------------------------
unsigned parser::parse_rotate(const char* str)
{
double args[3];
unsigned na = 0;
unsigned len = parse_transform_args(str, args, 3, &na);
if(na == 1)
{
m_path.transform().premultiply(trans_affine_rotation(deg2rad(args[0])));
}
else if(na == 3)
{
trans_affine t = trans_affine_translation(-args[1], -args[2]);
t *= trans_affine_rotation(deg2rad(args[0]));
t *= trans_affine_translation(args[1], args[2]);
m_path.transform().premultiply(t);
}
else
{
throw exception("parse_rotate: Invalid number of arguments");
}
return len;
}
//-------------------------------------------------------------
unsigned parser::parse_scale(const char* str)
{
double args[2];
unsigned na = 0;
unsigned len = parse_transform_args(str, args, 2, &na);
if(na == 1) args[1] = args[0];
m_path.transform().premultiply(trans_affine_scaling(args[0], args[1]));
return len;
}
//-------------------------------------------------------------
unsigned parser::parse_skew_x(const char* str)
{
double arg;
unsigned na = 0;
unsigned len = parse_transform_args(str, &arg, 1, &na);
m_path.transform().premultiply(trans_affine_skewing(deg2rad(arg), 0.0));
return len;
}
//-------------------------------------------------------------
unsigned parser::parse_skew_y(const char* str)
{
double arg;
unsigned na = 0;
unsigned len = parse_transform_args(str, &arg, 1, &na);
m_path.transform().premultiply(trans_affine_skewing(0.0, deg2rad(arg)));
return len;
}
}
}

View file

@ -1,85 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.3
// 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
//----------------------------------------------------------------------------
//
// SVG parser.
//
//----------------------------------------------------------------------------
#ifndef AGG_SVG_PARSER_INCLUDED
#define AGG_SVG_PARSER_INCLUDED
#include "agg_svg_path_tokenizer.h"
#include "agg_svg_path_renderer.h"
namespace agg
{
namespace svg
{
class parser
{
enum buf_size_e { buf_size = BUFSIZ };
public:
~parser();
parser(path_renderer& path);
void parse(const char* fname);
const char* title() const { return m_title; }
private:
// XML event handlers
static void start_element(void* data, const char* el, const char** attr);
static void end_element(void* data, const char* el);
static void content(void* data, const char* s, int len);
void parse_attr(const char** attr);
void parse_path(const char** attr);
void parse_poly(const char** attr, bool close_flag);
void parse_rect(const char** attr);
void parse_line(const char** attr);
void parse_style(const char* str);
void parse_transform(const char* str);
unsigned parse_matrix(const char* str);
unsigned parse_translate(const char* str);
unsigned parse_rotate(const char* str);
unsigned parse_scale(const char* str);
unsigned parse_skew_x(const char* str);
unsigned parse_skew_y(const char* str);
bool parse_attr(const char* name, const char* value);
bool parse_name_value(const char* nv_start, const char* nv_end);
void copy_name(const char* start, const char* end);
void copy_value(const char* start, const char* end);
private:
path_renderer& m_path;
path_tokenizer m_tokenizer;
char* m_buf;
char* m_title;
unsigned m_title_len;
bool m_title_flag;
bool m_path_flag;
char* m_attr_name;
char* m_attr_value;
unsigned m_attr_name_len;
unsigned m_attr_value_len;
};
}
}
#endif

View file

@ -1,366 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.3
// 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
//----------------------------------------------------------------------------
//
// SVG path renderer.
//
//----------------------------------------------------------------------------
#include <stdio.h>
#include "agg_svg_path_renderer.h"
namespace agg
{
namespace svg
{
//------------------------------------------------------------------------
path_renderer::path_renderer() :
m_curved(m_storage),
m_curved_count(m_curved),
m_curved_stroked(m_curved_count),
m_curved_stroked_trans(m_curved_stroked, m_transform),
m_curved_trans(m_curved_count, m_transform),
m_curved_trans_contour(m_curved_trans)
{
m_curved_trans_contour.auto_detect_orientation(false);
}
//------------------------------------------------------------------------
void path_renderer::remove_all()
{
m_storage.remove_all();
m_attr_storage.remove_all();
m_attr_stack.remove_all();
m_transform.reset();
}
//------------------------------------------------------------------------
void path_renderer::begin_path()
{
push_attr();
unsigned idx = m_storage.start_new_path();
m_attr_storage.add(path_attributes(cur_attr(), idx));
}
//------------------------------------------------------------------------
void path_renderer::end_path()
{
if(m_attr_storage.size() == 0)
{
throw exception("end_path : The path was not begun");
}
path_attributes attr = cur_attr();
unsigned idx = m_attr_storage[m_attr_storage.size() - 1].index;
attr.index = idx;
m_attr_storage[m_attr_storage.size() - 1] = attr;
pop_attr();
}
//------------------------------------------------------------------------
void path_renderer::move_to(double x, double y, bool rel) // M, m
{
if(rel) m_storage.rel_to_abs(&x, &y);
m_storage.move_to(x, y);
}
//------------------------------------------------------------------------
void path_renderer::line_to(double x, double y, bool rel) // L, l
{
if(rel) m_storage.rel_to_abs(&x, &y);
m_storage.line_to(x, y);
}
//------------------------------------------------------------------------
void path_renderer::hline_to(double x, bool rel) // H, h
{
double x2 = 0.0;
double y2 = 0.0;
if(m_storage.total_vertices())
{
m_storage.vertex(m_storage.total_vertices() - 1, &x2, &y2);
if(rel) x += x2;
m_storage.line_to(x, y2);
}
}
//------------------------------------------------------------------------
void path_renderer::vline_to(double y, bool rel) // V, v
{
double x2 = 0.0;
double y2 = 0.0;
if(m_storage.total_vertices())
{
m_storage.vertex(m_storage.total_vertices() - 1, &x2, &y2);
if(rel) y += y2;
m_storage.line_to(x2, y);
}
}
//------------------------------------------------------------------------
void path_renderer::curve3(double x1, double y1, // Q, q
double x, double y, bool rel)
{
if(rel)
{
m_storage.rel_to_abs(&x1, &y1);
m_storage.rel_to_abs(&x, &y);
}
m_storage.curve3(x1, y1, x, y);
}
//------------------------------------------------------------------------
void path_renderer::curve3(double x, double y, bool rel) // T, t
{
// throw exception("curve3(x, y) : NOT IMPLEMENTED YET");
if(rel)
{
m_storage.curve3_rel(x, y);
} else
{
m_storage.curve3(x, y);
}
}
//------------------------------------------------------------------------
void path_renderer::curve4(double x1, double y1, // C, c
double x2, double y2,
double x, double y, bool rel)
{
if(rel)
{
m_storage.rel_to_abs(&x1, &y1);
m_storage.rel_to_abs(&x2, &y2);
m_storage.rel_to_abs(&x, &y);
}
m_storage.curve4(x1, y1, x2, y2, x, y);
}
//------------------------------------------------------------------------
void path_renderer::curve4(double x2, double y2, // S, s
double x, double y, bool rel)
{
//throw exception("curve4(x2, y2, x, y) : NOT IMPLEMENTED YET");
if(rel)
{
m_storage.curve4_rel(x2, y2, x, y);
} else
{
m_storage.curve4(x2, y2, x, y);
}
}
//------------------------------------------------------------------------
void path_renderer::close_subpath()
{
m_storage.end_poly(path_flags_close);
}
//------------------------------------------------------------------------
path_attributes& path_renderer::cur_attr()
{
if(m_attr_stack.size() == 0)
{
throw exception("cur_attr : Attribute stack is empty");
}
return m_attr_stack[m_attr_stack.size() - 1];
}
//------------------------------------------------------------------------
void path_renderer::push_attr()
{
m_attr_stack.add(m_attr_stack.size() ?
m_attr_stack[m_attr_stack.size() - 1] :
path_attributes());
}
//------------------------------------------------------------------------
void path_renderer::pop_attr()
{
if(m_attr_stack.size() == 0)
{
throw exception("pop_attr : Attribute stack is empty");
}
m_attr_stack.remove_last();
}
//------------------------------------------------------------------------
void path_renderer::fill(const rgba8& f)
{
path_attributes& attr = cur_attr();
attr.fill_color = f;
attr.fill_flag = true;
}
//------------------------------------------------------------------------
void path_renderer::stroke(const rgba8& s)
{
path_attributes& attr = cur_attr();
attr.stroke_color = s;
attr.stroke_flag = true;
}
//------------------------------------------------------------------------
void path_renderer::even_odd(bool flag)
{
cur_attr().even_odd_flag = flag;
}
//------------------------------------------------------------------------
void path_renderer::stroke_width(double w)
{
cur_attr().stroke_width = w;
}
//------------------------------------------------------------------------
void path_renderer::fill_none()
{
cur_attr().fill_flag = false;
}
//------------------------------------------------------------------------
void path_renderer::stroke_none()
{
cur_attr().stroke_flag = false;
}
//------------------------------------------------------------------------
void path_renderer::fill_opacity(double op)
{
cur_attr().fill_color.opacity(op);
}
//------------------------------------------------------------------------
void path_renderer::stroke_opacity(double op)
{
cur_attr().stroke_color.opacity(op);
}
//------------------------------------------------------------------------
void path_renderer::line_join(line_join_e join)
{
cur_attr().line_join = join;
}
//------------------------------------------------------------------------
void path_renderer::line_cap(line_cap_e cap)
{
cur_attr().line_cap = cap;
}
//------------------------------------------------------------------------
void path_renderer::miter_limit(double ml)
{
cur_attr().miter_limit = ml;
}
//------------------------------------------------------------------------
trans_affine& path_renderer::transform()
{
return cur_attr().transform;
}
//------------------------------------------------------------------------
void path_renderer::parse_path(path_tokenizer& tok)
{
while(tok.next())
{
double arg[10];
char cmd = tok.last_command();
unsigned i;
switch(cmd)
{
case 'M': case 'm':
arg[0] = tok.last_number();
arg[1] = tok.next(cmd);
move_to(arg[0], arg[1], cmd == 'm');
break;
case 'L': case 'l':
arg[0] = tok.last_number();
arg[1] = tok.next(cmd);
line_to(arg[0], arg[1], cmd == 'l');
break;
case 'V': case 'v':
vline_to(tok.last_number(), cmd == 'v');
break;
case 'H': case 'h':
hline_to(tok.last_number(), cmd == 'h');
break;
case 'Q': case 'q':
arg[0] = tok.last_number();
for(i = 1; i < 4; i++)
{
arg[i] = tok.next(cmd);
}
curve3(arg[0], arg[1], arg[2], arg[3], cmd == 'q');
break;
case 'T': case 't':
arg[0] = tok.last_number();
arg[1] = tok.next(cmd);
curve3(arg[0], arg[1], cmd == 't');
break;
case 'C': case 'c':
arg[0] = tok.last_number();
for(i = 1; i < 6; i++)
{
arg[i] = tok.next(cmd);
}
curve4(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], cmd == 'c');
break;
case 'S': case 's':
arg[0] = tok.last_number();
for(i = 1; i < 4; i++)
{
arg[i] = tok.next(cmd);
}
curve4(arg[0], arg[1], arg[2], arg[3], cmd == 's');
break;
case 'A': case 'a':
arg[0] = tok.last_number();
for (i = 1; i < 7; i++)
{
arg[i] = tok.next(cmd);
}
// curve3(arg[0], arg[1], arg[2], arg[3], cmd == 'q');
// throw exception("parse_path: Command A: NOT IMPLEMENTED YET");
break;
case 'Z': case 'z':
close_subpath();
break;
default:
{
char buf[100];
sprintf(buf, "parse_path: Invalid Command %c", cmd);
throw exception(buf);
}
}
}
}
}
}

View file

@ -1,321 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.3
// 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
//----------------------------------------------------------------------------
//
// SVG path renderer.
//
//----------------------------------------------------------------------------
#ifndef AGG_SVG_PATH_RENDERER_INCLUDED
#define AGG_SVG_PATH_RENDERER_INCLUDED
#include <agg/agg_path_storage.h>
#include <agg/agg_conv_transform.h>
#include <agg/agg_conv_stroke.h>
#include <agg/agg_conv_contour.h>
#include <agg/agg_conv_curve.h>
#include <agg/agg_color_rgba.h>
#include <agg/agg_renderer_scanline.h>
#include <agg/agg_bounding_rect.h>
#include <agg/agg_rasterizer_scanline_aa.h>
#include "agg_svg_path_tokenizer.h"
namespace agg
{
namespace svg
{
template<class VertexSource> class conv_count
{
public:
conv_count(VertexSource& vs) : m_source(&vs), m_count(0) {}
void count(unsigned n) { m_count = n; }
unsigned count() const { return m_count; }
void rewind(unsigned path_id) { m_source->rewind(path_id); }
unsigned vertex(double* x, double* y)
{
++m_count;
return m_source->vertex(x, y);
}
private:
VertexSource* m_source;
unsigned m_count;
};
//============================================================================
// Basic path attributes
struct path_attributes
{
unsigned index;
rgba8 fill_color;
rgba8 stroke_color;
bool fill_flag;
bool stroke_flag;
bool even_odd_flag;
line_join_e line_join;
line_cap_e line_cap;
double miter_limit;
double stroke_width;
trans_affine transform;
// Empty constructor
path_attributes() :
index(0),
fill_color(rgba(0,0,0)),
stroke_color(rgba(0,0,0)),
fill_flag(true),
stroke_flag(false),
even_odd_flag(false),
line_join(miter_join),
line_cap(butt_cap),
miter_limit(4.0),
stroke_width(1.0),
transform()
{
}
// Copy constructor
path_attributes(const path_attributes& attr) :
index(attr.index),
fill_color(attr.fill_color),
stroke_color(attr.stroke_color),
fill_flag(attr.fill_flag),
stroke_flag(attr.stroke_flag),
even_odd_flag(attr.even_odd_flag),
line_join(attr.line_join),
line_cap(attr.line_cap),
miter_limit(attr.miter_limit),
stroke_width(attr.stroke_width),
transform(attr.transform)
{
}
// Copy constructor with new index value
path_attributes(const path_attributes& attr, unsigned idx) :
index(idx),
fill_color(attr.fill_color),
stroke_color(attr.stroke_color),
fill_flag(attr.fill_flag),
stroke_flag(attr.stroke_flag),
even_odd_flag(attr.even_odd_flag),
line_join(attr.line_join),
line_cap(attr.line_cap),
miter_limit(attr.miter_limit),
stroke_width(attr.stroke_width),
transform(attr.transform)
{
}
};
//============================================================================
// Path container and renderer.
class path_renderer
{
public:
typedef pod_bvector<path_attributes> attr_storage;
typedef conv_curve<path_storage> curved;
typedef conv_count<curved> curved_count;
typedef conv_stroke<curved_count> curved_stroked;
typedef conv_transform<curved_stroked> curved_stroked_trans;
typedef conv_transform<curved_count> curved_trans;
typedef conv_contour<curved_trans> curved_trans_contour;
path_renderer();
void remove_all();
// Use these functions as follows:
// begin_path() when the XML tag <path> comes ("start_element" handler)
// parse_path() on "d=" tag attribute
// end_path() when parsing of the entire tag is done.
void begin_path();
void parse_path(path_tokenizer& tok);
void end_path();
// The following functions are essentially a "reflection" of
// the respective SVG path commands.
void move_to(double x, double y, bool rel=false); // M, m
void line_to(double x, double y, bool rel=false); // L, l
void hline_to(double x, bool rel=false); // H, h
void vline_to(double y, bool rel=false); // V, v
void curve3(double x1, double y1, // Q, q
double x, double y, bool rel=false);
void curve3(double x, double y, bool rel=false); // T, t
void curve4(double x1, double y1, // C, c
double x2, double y2,
double x, double y, bool rel=false);
void curve4(double x2, double y2, // S, s
double x, double y, bool rel=false);
void close_subpath(); // Z, z
// template<class VertexSource>
// void add_path(VertexSource& vs,
// unsigned path_id = 0,
// bool solid_path = true)
// {
// m_storage.add_path(vs, path_id, solid_path);
// }
unsigned vertex_count() const { return m_curved_count.count(); }
// Call these functions on <g> tag (start_element, end_element respectively)
void push_attr();
void pop_attr();
// Attribute setting functions.
void fill(const rgba8& f);
void stroke(const rgba8& s);
void even_odd(bool flag);
void stroke_width(double w);
void fill_none();
void stroke_none();
void fill_opacity(double op);
void stroke_opacity(double op);
void line_join(line_join_e join);
void line_cap(line_cap_e cap);
void miter_limit(double ml);
trans_affine& transform();
// Make all polygons CCW-oriented
void arrange_orientations()
{
m_storage.arrange_orientations_all_paths(path_flags_ccw);
}
// Expand all polygons
void expand(double value)
{
m_curved_trans_contour.width(value);
}
unsigned operator [](unsigned idx)
{
m_transform = m_attr_storage[idx].transform;
return m_attr_storage[idx].index;
}
void bounding_rect(double* x1, double* y1, double* x2, double* y2)
{
agg::conv_transform<agg::path_storage> trans(m_storage, m_transform);
agg::bounding_rect(trans, *this, 0, m_attr_storage.size(), x1, y1, x2, y2);
}
// Rendering. One can specify two additional parameters:
// trans_affine and opacity. They can be used to transform the whole
// image and/or to make it translucent.
template<class Rasterizer, class Scanline, class Renderer>
void render(Rasterizer& ras,
Scanline& sl,
Renderer& ren,
const trans_affine& mtx,
const rect_i& cb,
double opacity=1.0)
{
unsigned i;
ras.clip_box(cb.x1, cb.y1, cb.x2, cb.y2);
m_curved_count.count(0);
for(i = 0; i < m_attr_storage.size(); i++)
{
const path_attributes& attr = m_attr_storage[i];
m_transform = attr.transform;
m_transform *= mtx;
double scl = m_transform.scale();
//m_curved.approximation_method(curve_inc);
m_curved.approximation_scale(scl);
m_curved.angle_tolerance(0.0);
rgba8 color;
if(attr.fill_flag)
{
ras.reset();
ras.filling_rule(attr.even_odd_flag ? fill_even_odd : fill_non_zero);
if(fabs(m_curved_trans_contour.width()) < 0.0001)
{
ras.add_path(m_curved_trans, attr.index);
}
else
{
m_curved_trans_contour.miter_limit(attr.miter_limit);
ras.add_path(m_curved_trans_contour, attr.index);
}
color = attr.fill_color;
color.opacity(color.opacity() * opacity);
ren.color(color);
agg::render_scanlines(ras, sl, ren);
}
if(attr.stroke_flag)
{
m_curved_stroked.width(attr.stroke_width);
//m_curved_stroked.line_join((attr.line_join == miter_join) ? miter_join_round : attr.line_join);
m_curved_stroked.line_join(attr.line_join);
m_curved_stroked.line_cap(attr.line_cap);
m_curved_stroked.miter_limit(attr.miter_limit);
m_curved_stroked.inner_join(inner_round);
m_curved_stroked.approximation_scale(scl);
// If the *visual* line width is considerable we
// turn on processing of curve cusps.
//---------------------
if(attr.stroke_width * scl > 1.0)
{
m_curved.angle_tolerance(0.2);
}
ras.reset();
ras.filling_rule(fill_non_zero);
ras.add_path(m_curved_stroked_trans, attr.index);
color = attr.stroke_color;
color.opacity(color.opacity() * opacity);
ren.color(color);
agg::render_scanlines(ras, sl, ren);
}
}
}
private:
path_attributes& cur_attr();
path_storage m_storage;
attr_storage m_attr_storage;
attr_storage m_attr_stack;
trans_affine m_transform;
curved m_curved;
curved_count m_curved_count;
curved_stroked m_curved_stroked;
curved_stroked_trans m_curved_stroked_trans;
curved_trans m_curved_trans;
curved_trans_contour m_curved_trans_contour;
};
}
}
#endif

View file

@ -1,151 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.3
// 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
//----------------------------------------------------------------------------
//
// SVG path tokenizer.
//
//----------------------------------------------------------------------------
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "agg_svg_exception.h"
#include "agg_svg_path_tokenizer.h"
namespace agg
{
namespace svg
{
//------------------------------------------------------------------------
const char path_tokenizer::s_commands[] = "+-MmZzLlHhVvCcSsQqTtAaFfPp";
const char path_tokenizer::s_numeric[] = ".Ee0123456789";
const char path_tokenizer::s_separators[] = " ,\t\n\r";
//------------------------------------------------------------------------
path_tokenizer::path_tokenizer()
: m_path(0), m_last_command(0), m_last_number(0.0)
{
init_char_mask(m_commands_mask, s_commands);
init_char_mask(m_numeric_mask, s_numeric);
init_char_mask(m_separators_mask, s_separators);
}
//------------------------------------------------------------------------
void path_tokenizer::set_path_str(const char* str)
{
m_path = str;
m_last_command = 0;
m_last_number = 0.0;
}
//------------------------------------------------------------------------
void path_tokenizer::init_char_mask(char* mask, const char* char_set)
{
memset(mask, 0, 256/8);
while(*char_set)
{
unsigned c = unsigned(*char_set++) & 0xFF;
mask[c >> 3] |= 1 << (c & 7);
}
}
//------------------------------------------------------------------------
bool path_tokenizer::next()
{
if(m_path == 0) return false;
// Skip all white spaces and other garbage
while(*m_path && !is_command(*m_path) && !is_numeric(*m_path))
{
if(!is_separator(*m_path))
{
char buf[100];
sprintf(buf, "path_tokenizer::next : Invalid Character %c", *m_path);
throw exception(buf);
}
m_path++;
}
if(*m_path == 0) return false;
if(is_command(*m_path))
{
// Check if the command is a numeric sign character
if(*m_path == '-' || *m_path == '+')
{
return parse_number();
}
m_last_command = *m_path++;
while(*m_path && is_separator(*m_path)) m_path++;
if(*m_path == 0) return true;
}
return parse_number();
}
//------------------------------------------------------------------------
double path_tokenizer::next(char cmd)
{
if(!next()) throw exception("parse_path: Unexpected end of path");
if(last_command() != cmd)
{
char buf[100];
sprintf(buf, "parse_path: Command %c: bad or missing parameters", cmd);
throw exception(buf);
}
return last_number();
}
//------------------------------------------------------------------------
bool path_tokenizer::parse_number()
{
char buf[256]; // Should be enough for any number
char* buf_ptr = buf;
// Copy all sign characters
while(buf_ptr < buf+255 && *m_path == '-' || *m_path == '+')
{
*buf_ptr++ = *m_path++;
}
// Copy all numeric characters
bool dot_seen = false;
while(buf_ptr < buf+255 && is_numeric(*m_path))
{
char c = *m_path;
if (c == '.') {
if (dot_seen)
break;
dot_seen = true;
}
*buf_ptr++ = *m_path++;
}
*buf_ptr = 0;
m_last_number = atof(buf);
return true;
}
} //namespace svg
} //namespace agg

View file

@ -1,114 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.3
// 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
//----------------------------------------------------------------------------
//
// SVG path tokenizer.
//
//----------------------------------------------------------------------------
#ifndef AGG_SVG_PATH_TOKENIZER_INCLUDED
#define AGG_SVG_PATH_TOKENIZER_INCLUDED
#include "agg_svg_exception.h"
namespace agg
{
namespace svg
{
// SVG path tokenizer.
// Example:
//
// agg::svg::path_tokenizer tok;
//
// tok.set_str("M-122.304 84.285L-122.304 84.285 122.203 86.179 ");
// while(tok.next())
// {
// printf("command='%c' number=%f\n",
// tok.last_command(),
// tok.last_number());
// }
//
// The tokenizer does all the routine job of parsing the SVG paths.
// It doesn't recognize any graphical primitives, it even doesn't know
// anything about pairs of coordinates (X,Y). The purpose of this class
// is to tokenize the numeric values and commands. SVG paths can
// have single numeric values for Horizontal or Vertical line_to commands
// as well as more than two coordinates (4 or 6) for Bezier curves
// depending on the semantics of the command.
// The behaviour is as follows:
//
// Each call to next() returns true if there's new command or new numeric
// value or false when the path ends. How to interpret the result
// depends on the sematics of the command. For example, command "C"
// (cubic Bezier curve) implies 6 floating point numbers preceded by this
// command. If the command assumes no arguments (like z or Z) the
// the last_number() values won't change, that is, last_number() always
// returns the last recognized numeric value, so does last_command().
//===============================================================
class path_tokenizer
{
public:
path_tokenizer();
void set_path_str(const char* str);
bool next();
double next(char cmd);
char last_command() const { return m_last_command; }
double last_number() const { return m_last_number; }
private:
static void init_char_mask(char* mask, const char* char_set);
bool contains(const char* mask, unsigned c) const
{
return (mask[(c >> 3) & (256/8-1)] & (1 << (c & 7))) != 0;
}
bool is_command(unsigned c) const
{
return contains(m_commands_mask, c);
}
bool is_numeric(unsigned c) const
{
return contains(m_numeric_mask, c);
}
bool is_separator(unsigned c) const
{
return contains(m_separators_mask, c);
}
bool parse_number();
char m_separators_mask[256/8];
char m_commands_mask[256/8];
char m_numeric_mask[256/8];
const char* m_path;
double m_last_number;
char m_last_command;
static const char s_commands[];
static const char s_numeric[];
static const char s_separators[];
};
} //namespace svg
} //namespace agg
#endif

View file

@ -1,200 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#include <agg/agg_trans_affine.h>
namespace agg
{
//------------------------------------------------------------------------
const trans_affine& trans_affine::parl_to_parl(const double* src,
const double* dst)
{
sx = src[2] - src[0];
shy = src[3] - src[1];
shx = src[4] - src[0];
sy = src[5] - src[1];
tx = src[0];
ty = src[1];
invert();
multiply(trans_affine(dst[2] - dst[0], dst[3] - dst[1],
dst[4] - dst[0], dst[5] - dst[1],
dst[0], dst[1]));
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::rect_to_parl(double x1, double y1,
double x2, double y2,
const double* parl)
{
double src[6];
src[0] = x1; src[1] = y1;
src[2] = x2; src[3] = y1;
src[4] = x2; src[5] = y2;
parl_to_parl(src, parl);
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::parl_to_rect(const double* parl,
double x1, double y1,
double x2, double y2)
{
double dst[6];
dst[0] = x1; dst[1] = y1;
dst[2] = x2; dst[3] = y1;
dst[4] = x2; dst[5] = y2;
parl_to_parl(parl, dst);
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::multiply(const trans_affine& m)
{
double t0 = sx * m.sx + shy * m.shx;
double t2 = shx * m.sx + sy * m.shx;
double t4 = tx * m.sx + ty * m.shx + m.tx;
shy = sx * m.shy + shy * m.sy;
sy = shx * m.shy + sy * m.sy;
ty = tx * m.shy + ty * m.sy + m.ty;
sx = t0;
shx = t2;
tx = t4;
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::invert()
{
double d = determinant_reciprocal();
double t0 = sy * d;
sy = sx * d;
shy = -shy * d;
shx = -shx * d;
double t4 = -tx * t0 - ty * shx;
ty = -tx * shy - ty * sy;
sx = t0;
tx = t4;
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::flip_x()
{
sx = -sx;
shy = -shy;
tx = -tx;
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::flip_y()
{
shx = -shx;
sy = -sy;
ty = -ty;
return *this;
}
//------------------------------------------------------------------------
const trans_affine& trans_affine::reset()
{
sx = sy = 1.0;
shy = shx = tx = ty = 0.0;
return *this;
}
//------------------------------------------------------------------------
bool trans_affine::is_identity(double epsilon) const
{
return is_equal_eps(sx, 1.0, epsilon) &&
is_equal_eps(shy, 0.0, epsilon) &&
is_equal_eps(shx, 0.0, epsilon) &&
is_equal_eps(sy, 1.0, epsilon) &&
is_equal_eps(tx, 0.0, epsilon) &&
is_equal_eps(ty, 0.0, epsilon);
}
//------------------------------------------------------------------------
bool trans_affine::is_valid(double epsilon) const
{
return fabs(sx) > epsilon && fabs(sy) > epsilon;
}
//------------------------------------------------------------------------
bool trans_affine::is_equal(const trans_affine& m, double epsilon) const
{
return is_equal_eps(sx, m.sx, epsilon) &&
is_equal_eps(shy, m.shy, epsilon) &&
is_equal_eps(shx, m.shx, epsilon) &&
is_equal_eps(sy, m.sy, epsilon) &&
is_equal_eps(tx, m.tx, epsilon) &&
is_equal_eps(ty, m.ty, epsilon);
}
//------------------------------------------------------------------------
double trans_affine::rotation() const
{
double x1 = 0.0;
double y1 = 0.0;
double x2 = 1.0;
double y2 = 0.0;
transform(&x1, &y1);
transform(&x2, &y2);
return atan2(y2-y1, x2-x1);
}
//------------------------------------------------------------------------
void trans_affine::translation(double* dx, double* dy) const
{
*dx = tx;
*dy = ty;
}
//------------------------------------------------------------------------
void trans_affine::scaling(double* x, double* y) const
{
double x1 = 0.0;
double y1 = 0.0;
double x2 = 1.0;
double y2 = 1.0;
trans_affine t(*this);
t *= trans_affine_rotation(-rotation());
t.transform(&x1, &y1);
t.transform(&x2, &y2);
*x = x2 - x1;
*y = y2 - y1;
}
}

View file

@ -1,170 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#include <math.h>
#include <agg/agg_vcgen_contour.h>
namespace agg
{
//------------------------------------------------------------------------
vcgen_contour::vcgen_contour() :
m_stroker(),
m_width(1),
m_src_vertices(),
m_out_vertices(),
m_status(initial),
m_src_vertex(0),
m_closed(0),
m_orientation(0),
m_auto_detect(false)
{
}
//------------------------------------------------------------------------
void vcgen_contour::remove_all()
{
m_src_vertices.remove_all();
m_closed = 0;
m_orientation = 0;
m_status = initial;
}
//------------------------------------------------------------------------
void vcgen_contour::add_vertex(double x, double y, unsigned cmd)
{
m_status = initial;
if(is_move_to(cmd))
{
m_src_vertices.modify_last(vertex_dist(x, y));
}
else
{
if(is_vertex(cmd))
{
m_src_vertices.add(vertex_dist(x, y));
}
else
{
if(is_end_poly(cmd))
{
m_closed = get_close_flag(cmd);
if(m_orientation == path_flags_none)
{
m_orientation = get_orientation(cmd);
}
}
}
}
}
//------------------------------------------------------------------------
void vcgen_contour::rewind(unsigned)
{
if(m_status == initial)
{
m_src_vertices.close(true);
if(m_auto_detect)
{
if(!is_oriented(m_orientation))
{
m_orientation = (calc_polygon_area(m_src_vertices) > 0.0) ?
path_flags_ccw :
path_flags_cw;
}
}
if(is_oriented(m_orientation))
{
m_stroker.width(is_ccw(m_orientation) ? m_width : -m_width);
}
}
m_status = ready;
m_src_vertex = 0;
}
//------------------------------------------------------------------------
unsigned vcgen_contour::vertex(double* x, double* y)
{
unsigned cmd = path_cmd_line_to;
while(!is_stop(cmd))
{
switch(m_status)
{
case initial:
rewind(0);
case ready:
if(m_src_vertices.size() < 2 + unsigned(m_closed != 0))
{
cmd = path_cmd_stop;
break;
}
m_status = outline;
cmd = path_cmd_move_to;
m_src_vertex = 0;
m_out_vertex = 0;
case outline:
if(m_src_vertex >= m_src_vertices.size())
{
m_status = end_poly;
break;
}
m_stroker.calc_join(m_out_vertices,
m_src_vertices.prev(m_src_vertex),
m_src_vertices.curr(m_src_vertex),
m_src_vertices.next(m_src_vertex),
m_src_vertices.prev(m_src_vertex).dist,
m_src_vertices.curr(m_src_vertex).dist);
++m_src_vertex;
m_status = out_vertices;
m_out_vertex = 0;
case out_vertices:
if(m_out_vertex >= m_out_vertices.size())
{
m_status = outline;
}
else
{
const point_d& c = m_out_vertices[m_out_vertex++];
*x = c.x;
*y = c.y;
return cmd;
}
break;
case end_poly:
if(!m_closed) return path_cmd_stop;
m_status = stop;
return path_cmd_end_poly | path_flags_close | path_flags_ccw;
case stop:
return path_cmd_stop;
}
}
return cmd;
}
}

View file

@ -1,219 +0,0 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#include <math.h>
#include <agg/agg_vcgen_stroke.h>
#include <agg/agg_shorten_path.h>
namespace agg
{
//------------------------------------------------------------------------
vcgen_stroke::vcgen_stroke() :
m_stroker(),
m_src_vertices(),
m_out_vertices(),
m_shorten(0.0),
m_closed(0),
m_status(initial),
m_src_vertex(0),
m_out_vertex(0)
{
}
//------------------------------------------------------------------------
void vcgen_stroke::remove_all()
{
m_src_vertices.remove_all();
m_closed = 0;
m_status = initial;
}
//------------------------------------------------------------------------
void vcgen_stroke::add_vertex(double x, double y, unsigned cmd)
{
m_status = initial;
if(is_move_to(cmd))
{
m_src_vertices.modify_last(vertex_dist(x, y));
}
else
{
if(is_vertex(cmd))
{
m_src_vertices.add(vertex_dist(x, y));
}
else
{
m_closed = get_close_flag(cmd);
}
}
}
//------------------------------------------------------------------------
void vcgen_stroke::rewind(unsigned)
{
if(m_status == initial)
{
m_src_vertices.close(m_closed != 0);
shorten_path(m_src_vertices, m_shorten, m_closed);
if(m_src_vertices.size() < 3) m_closed = 0;
}
m_status = ready;
m_src_vertex = 0;
m_out_vertex = 0;
}
//------------------------------------------------------------------------
unsigned vcgen_stroke::vertex(double* x, double* y)
{
unsigned cmd = path_cmd_line_to;
while(!is_stop(cmd))
{
switch(m_status)
{
case initial:
rewind(0);
case ready:
if(m_src_vertices.size() < 2 + unsigned(m_closed != 0))
{
cmd = path_cmd_stop;
break;
}
m_status = m_closed ? outline1 : cap1;
cmd = path_cmd_move_to;
m_src_vertex = 0;
m_out_vertex = 0;
break;
case cap1:
m_stroker.calc_cap(m_out_vertices,
m_src_vertices[0],
m_src_vertices[1],
m_src_vertices[0].dist);
m_src_vertex = 1;
m_prev_status = outline1;
m_status = out_vertices;
m_out_vertex = 0;
break;
case cap2:
m_stroker.calc_cap(m_out_vertices,
m_src_vertices[m_src_vertices.size() - 1],
m_src_vertices[m_src_vertices.size() - 2],
m_src_vertices[m_src_vertices.size() - 2].dist);
m_prev_status = outline2;
m_status = out_vertices;
m_out_vertex = 0;
break;
case outline1:
if(m_closed)
{
if(m_src_vertex >= m_src_vertices.size())
{
m_prev_status = close_first;
m_status = end_poly1;
break;
}
}
else
{
if(m_src_vertex >= m_src_vertices.size() - 1)
{
m_status = cap2;
break;
}
}
m_stroker.calc_join(m_out_vertices,
m_src_vertices.prev(m_src_vertex),
m_src_vertices.curr(m_src_vertex),
m_src_vertices.next(m_src_vertex),
m_src_vertices.prev(m_src_vertex).dist,
m_src_vertices.curr(m_src_vertex).dist);
++m_src_vertex;
m_prev_status = m_status;
m_status = out_vertices;
m_out_vertex = 0;
break;
case close_first:
m_status = outline2;
cmd = path_cmd_move_to;
case outline2:
if(m_src_vertex <= unsigned(m_closed == 0))
{
m_status = end_poly2;
m_prev_status = stop;
break;
}
--m_src_vertex;
m_stroker.calc_join(m_out_vertices,
m_src_vertices.next(m_src_vertex),
m_src_vertices.curr(m_src_vertex),
m_src_vertices.prev(m_src_vertex),
m_src_vertices.curr(m_src_vertex).dist,
m_src_vertices.prev(m_src_vertex).dist);
m_prev_status = m_status;
m_status = out_vertices;
m_out_vertex = 0;
break;
case out_vertices:
if(m_out_vertex >= m_out_vertices.size())
{
m_status = m_prev_status;
}
else
{
const point_d& c = m_out_vertices[m_out_vertex++];
*x = c.x;
*y = c.y;
return cmd;
}
break;
case end_poly1:
m_status = m_prev_status;
return path_cmd_end_poly | path_flags_close | path_flags_ccw;
case end_poly2:
m_status = m_prev_status;
return path_cmd_end_poly | path_flags_close | path_flags_cw;
case stop:
cmd = path_cmd_stop;
break;
}
}
return cmd;
}
}

View file

@ -27,7 +27,7 @@ public:
using TPixel = TPixelRenderer::color_type;
using TRawBuffer = agg::rendering_buffer;
using TBuffer = std::vector<TPixelRenderer::value_type>;
using TBuffer = std::vector<TPixelRenderer::pixel_type>;
using TRendererAA = agg::renderer_scanline_aa_solid<TRawRenderer>;
@ -36,11 +36,6 @@ public:
using Origin = Raster::Origin;
enum
{
num_components = 1,
};
private:
Raster::Resolution m_resolution;
Raster::PixelDim m_pxdim;
@ -63,7 +58,7 @@ public:
m_buf(res.pixels()),
m_rbuf(reinterpret_cast<TPixelRenderer::value_type*>(m_buf.data()),
res.width_px, res.height_px,
int(res.width_px*num_components)),
int(res.width_px*TPixelRenderer::num_components)),
m_pixfmt(m_rbuf),
m_raw_renderer(m_pixfmt),
m_renderer(m_raw_renderer),

View file

@ -121,8 +121,6 @@ set(SLIC3R_GUI_SOURCES
Utils/Bonjour.hpp
Utils/PresetUpdater.cpp
Utils/PresetUpdater.hpp
Utils/SVGImport.cpp
Utils/SVGImport.hpp
Utils/Time.cpp
Utils/Time.hpp
Utils/HexFile.cpp
@ -135,10 +133,7 @@ endif ()
add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES})
target_compile_definitions(libslic3r_gui PUBLIC -DUSE_TBB ${PNG_DEFINITIONS})
target_include_directories(libslic3r_gui PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${PNG_INCLUDE_DIRS})
target_link_libraries(libslic3r_gui libslic3r avrdude imgui ${PNG_LIBRARIES} agg_svg)
target_link_libraries(libslic3r_gui libslic3r avrdude imgui)
if (SLIC3R_PCH AND NOT SLIC3R_SYNTAXONLY)
add_precompiled_header(libslic3r_gui pchheader.hpp FORCEINCLUDE)
endif ()

View file

@ -27,7 +27,6 @@
#include <fstream>
#include "GUI_App.hpp"
#include "Utils/SVGImport.hpp"
namespace Slic3r {
namespace GUI {
@ -36,9 +35,6 @@ MainFrame::MainFrame() :
wxFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, "mainframe"),
m_printhost_queue_dlg(new PrintHostQueueDialog(this))
{
Slic3r::Utils::vojtikuv_pokus();
// Load the icon either from the exe, or from the ico file.
#if _WIN32
{

View file

@ -1,98 +0,0 @@
#include "SVGImport.hpp"
#include <agg/agg_basics.h>
#include <agg/agg_rendering_buffer.h>
#include <agg/agg_rasterizer_scanline_aa.h>
#include <agg/agg_scanline_p.h>
#include <agg/agg_renderer_scanline.h>
#include <agg/agg_pixfmt_rgba.h>
#include <agg_svg/agg_svg_parser.h>
#include <png/writer.hpp>
#include <boost/nowide/iostream.hpp>
namespace Slic3r { namespace Utils {
int vojtikuv_pokus()
{
std::string fname = "D:\\temp\\svg_examples\\slicer_vnitrni-menu.svg";
try
{
agg::svg::path_renderer path;
agg::svg::parser prsr(path);
prsr.parse(fname.c_str());
path.arrange_orientations();
double m_min_x;
double m_min_y;
double m_max_x;
double m_max_y;
path.bounding_rect(&m_min_x, &m_min_y, &m_max_x, &m_max_y);
// caption(p.title());
// typedef agg::pixfmt_bgra32 pixfmt;
typedef agg::pixfmt_rgba32 pixfmt;
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
unsigned int width_px = 1000;
unsigned int height_px = 1000;
std::vector<unsigned char> buffer(width_px * height_px * 4, 0);
agg::rendering_buffer rbuf(reinterpret_cast<pixfmt::value_type*>(buffer.data()), width_px, height_px, int(width_px * 4));
pixfmt pixf(rbuf);
renderer_base rb(pixf);
renderer_solid ren(rb);
rb.clear(agg::rgba(1,1,1));
agg::rasterizer_scanline_aa<> ras;
agg::scanline_p8 sl;
agg::trans_affine mtx;
ras.gamma(agg::gamma_power(1.));
mtx *= agg::trans_affine_translation(- m_min_x, - m_min_y);
mtx *= agg::trans_affine_scaling(double(width_px) / (m_max_x - m_min_x), double(height_px) / (m_max_y - m_min_y));
path.expand(1.);
path.render(ras, sl, ren, mtx, rb.clip_box(), 1.0);
// ren.color(agg::rgba(0,0,0));
ren.color(agg::rgba(1,1,1));
agg::render_scanlines(ras, sl, ren);
try {
boost::nowide::ofstream c;
c.open("d:\\temp\\rasterized.png", std::ios::out | std::ios::binary | std::ios::trunc);
png::writer<std::ostream> wr(c);
wr.set_bit_depth(8);
wr.set_color_type(png::color_type_rgb_alpha);
wr.set_width(width_px);
wr.set_height(height_px);
wr.set_compression_type(png::compression_type_default);
wr.write_info();
auto ptr = reinterpret_cast<png::byte*>(buffer.data());
unsigned stride = 4 * width_px;
for(unsigned r = 0; r < height_px; ++ r, ptr += stride)
wr.write_row(ptr);
wr.write_end_info();
c.close();
}
catch (std::exception &ex) {
printf("Hu!");
}
}
catch(agg::svg::exception& e)
{
// app.message(e.msg());
}
return 0;
}
} } // namespace Slic3r::Utils

View file

@ -1,12 +0,0 @@
#ifndef slic3r_Utils_SVGImport_hpp_
#define slic3r_Utils_SVGImport_hpp_
namespace Slic3r {
namespace Utils {
int vojtikuv_pokus();
}; // namespace Utils
}; // namespace Slic3r
#endif /* slic3r_Utils_SVGImport_hpp_ */