mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
.....
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@61952 954022d7-b5bf-4e40-9824-e11837661b57
This commit is contained in:
committed by
Alexander Trofimov
parent
858ab0bb93
commit
b858608c6b
211
DesktopEditor/agg-2.4/svg/agg_svg_assoc_pod_array.h
Normal file
211
DesktopEditor/agg-2.4/svg/agg_svg_assoc_pod_array.h
Normal file
@ -0,0 +1,211 @@
|
||||
#ifndef AGG_SVG_ASSOC_POD_ARRAY_INCLUDE
|
||||
#define AGG_SVG_ASSOC_POD_ARRAY_INCLUDE
|
||||
//-----------------------------------------------------------------------------
|
||||
#pragma warning(disable:4786)
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
enum sort_state_e {off,on};
|
||||
//-------------------------------------------------------------------------
|
||||
template<class T1, class T2>
|
||||
struct pair
|
||||
{
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
|
||||
pair() : first(T1()), second(T2()) {}
|
||||
pair(const T1& v1, const T2& v2) : first(v1), second(v2) {}
|
||||
|
||||
T1 first;
|
||||
T2 second;
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
template<class KeyT, class T, class CompareT = std::less<KeyT> >
|
||||
class assoc_pod_array : private std::vector<pair<KeyT, T> >
|
||||
{
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
typedef std::vector<pair<KeyT, T> > base_type;
|
||||
//---------------------------------------------------------------------
|
||||
typedef typename base_type::value_type value_type;
|
||||
//---------------------------------------------------------------------
|
||||
typedef KeyT key_type;
|
||||
typedef T mapped_type;
|
||||
typedef CompareT key_compare;
|
||||
//---------------------------------------------------------------------
|
||||
typedef base_type::iterator iterator;
|
||||
typedef base_type::const_iterator const_iterator;
|
||||
//---------------------------------------------------------------------
|
||||
iterator begin()
|
||||
{
|
||||
return base_type::begin();
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
const_iterator begin() const
|
||||
{
|
||||
return base_type::begin();
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
iterator end()
|
||||
{
|
||||
return base_type::end();
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
const_iterator end() const
|
||||
{
|
||||
return base_type::end();
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
class value_compare
|
||||
{
|
||||
//-----------------------------------------------------------------
|
||||
friend class assoc_pod_array;
|
||||
//private:
|
||||
public:
|
||||
//-----------------------------------------------------------------
|
||||
CompareT m_comp;
|
||||
//-----------------------------------------------------------------
|
||||
value_compare(CompareT c) : m_comp(c) {}
|
||||
public:
|
||||
//-----------------------------------------------------------------
|
||||
template <class T>
|
||||
bool operator()(const value_type& x, const T& y) const
|
||||
{
|
||||
return m_comp(x.first, y);
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
template <class T>
|
||||
bool operator()(const T& x, const value_type& y) const
|
||||
{
|
||||
return m_comp(x, y.first);
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
bool operator()(const value_type& x, const typename value_type::first_type& y) const
|
||||
{
|
||||
return m_comp(x.first, y);
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
bool operator()(const typename value_type::first_type& x, const value_type& y) const
|
||||
{
|
||||
return m_comp(x, y.first);
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
bool operator()(const value_type& x, const value_type& y) const
|
||||
{
|
||||
return m_comp(x.first, y.first);
|
||||
}
|
||||
};
|
||||
//---------------------------------------------------------------------
|
||||
class value_compare_for_sort
|
||||
{
|
||||
//-----------------------------------------------------------------
|
||||
friend class assoc_pod_array;
|
||||
//private:
|
||||
public:
|
||||
//-----------------------------------------------------------------
|
||||
CompareT m_comp;
|
||||
//-----------------------------------------------------------------
|
||||
value_compare_for_sort(CompareT c) : m_comp(c) {}
|
||||
public:
|
||||
//-----------------------------------------------------------------
|
||||
bool operator()(const value_type& x, const typename value_type::first_type& y) const
|
||||
{
|
||||
return m_comp(x.first, y);
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
bool operator()(const typename value_type::first_type& x, const value_type& y) const
|
||||
{
|
||||
return m_comp(x, y.first);
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
bool operator()(const value_type& x, const value_type& y) const
|
||||
{
|
||||
return m_comp(x.first, y.first);
|
||||
}
|
||||
};
|
||||
//-----------------------------------------------------------------
|
||||
explicit assoc_pod_array(const CompareT& comp = key_compare())
|
||||
: m_sort_state(off), m_compare(comp)
|
||||
{
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
void sort_state(sort_state_e state)
|
||||
{
|
||||
m_sort_state = state;
|
||||
if (m_sort_state == on)
|
||||
{
|
||||
std::sort(begin(), end(), value_compare_for_sort(m_compare));
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
unsigned size() const
|
||||
{
|
||||
return base_type::size();
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void clear()
|
||||
{
|
||||
m_sort_state = off;
|
||||
base_type::clear();
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
// Inserts val if and only if there is no element in the container with
|
||||
// key equivalent to the key.
|
||||
// return value indicates indicates whether the insertion takes place
|
||||
bool insert(KeyT const & key, T const & val)
|
||||
{
|
||||
bool find(false);
|
||||
|
||||
if (m_sort_state == off)
|
||||
{
|
||||
//base_type::add(value_type(key, val));
|
||||
base_type::push_back(value_type(key, val));
|
||||
}
|
||||
else
|
||||
{
|
||||
iterator it = std::lower_bound(begin(), end(),
|
||||
key,value_compare(m_compare));
|
||||
if (it == end())
|
||||
{
|
||||
base_type::insert(it, value_type(key, val));
|
||||
}
|
||||
else
|
||||
if (!(!m_compare(it->first,key) && !m_compare(key,it->first)))
|
||||
{
|
||||
base_type::insert(it, value_type(key, val));
|
||||
}
|
||||
else
|
||||
{
|
||||
find = true;
|
||||
}
|
||||
}
|
||||
return !find;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
template <class Key>
|
||||
iterator find(const Key& key)
|
||||
{
|
||||
assert(m_sort_state == on);
|
||||
|
||||
std::pair<iterator, iterator> p = std::equal_range(begin(), end(),
|
||||
key, value_compare(m_compare));
|
||||
return p.first != p.second ? p.first : end();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
private:
|
||||
sort_state_e m_sort_state;
|
||||
CompareT m_compare;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
167
DesktopEditor/agg-2.4/svg/agg_svg_attribute_source.h
Normal file
167
DesktopEditor/agg-2.4/svg/agg_svg_attribute_source.h
Normal file
@ -0,0 +1,167 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef AGG_SVG_ATTRIBUTE_SOURCE_INCLUDED
|
||||
#define AGG_SVG_ATTRIBUTE_SOURCE_INCLUDED
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <cstring> // for memcpy
|
||||
#include "agg_svg_basics.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
class attribute_byte
|
||||
{
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
attribute_byte(attr_e attr, agg::int8u data)
|
||||
{
|
||||
m_storage[0] = tag_attribute_bin_byte;
|
||||
m_storage[1] = attr;
|
||||
m_storage[2] = data;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
const agg::int8u* head() const { return m_storage; }
|
||||
//---------------------------------------------------------------------
|
||||
agg::int32u head_size() const { return buf_size - 1; }
|
||||
//---------------------------------------------------------------------
|
||||
const agg::int8u* data() const { return &m_storage[2]; }
|
||||
//---------------------------------------------------------------------
|
||||
agg::int32u data_size() const { return 1; }
|
||||
//---------------------------------------------------------------------
|
||||
private:
|
||||
//---------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
buf_size = 1 // tag
|
||||
+ 1 // attr_e
|
||||
+ 1 // data
|
||||
};
|
||||
//---------------------------------------------------------------------
|
||||
agg::int8u m_storage[buf_size];
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
class attribute_bin
|
||||
{
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
attribute_bin(attr_e attr,
|
||||
const void * data,
|
||||
agg::int32u size)
|
||||
|
||||
: m_data(static_cast<const agg::int8u*>(data)),
|
||||
m_size(size),
|
||||
m_with_type(false)
|
||||
{
|
||||
fill_head(attr);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
attribute_bin(attr_e attr,
|
||||
agg::int8u type,
|
||||
const void * data,
|
||||
agg::int32u size)
|
||||
|
||||
: m_data(static_cast<const agg::int8u*>(data)),
|
||||
m_size(size + 1),
|
||||
m_with_type(true)
|
||||
{
|
||||
fill_head(attr);
|
||||
m_storage[2 + sizeof(agg::int32u)] = type;
|
||||
--m_size;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
const agg::int8u* head() const { return m_storage; }
|
||||
//---------------------------------------------------------------------
|
||||
agg::int32u head_size() const
|
||||
{
|
||||
return m_with_type ? buf_size : buf_size - 1;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
const agg::int8u* data() const { return m_data; }
|
||||
//---------------------------------------------------------------------
|
||||
agg::int32u data_size() const { return m_size; }
|
||||
//---------------------------------------------------------------------
|
||||
private:
|
||||
//---------------------------------------------------------------------
|
||||
void fill_head(attr_e attr)
|
||||
{
|
||||
m_storage[0] = tag_attribute_bin;
|
||||
m_storage[1] = attr;
|
||||
memcpy(&m_storage[2], &m_size, sizeof(agg::int32u));
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
buf_size = 1 // tag
|
||||
+ 1 // attr_e
|
||||
+ sizeof(agg::int32u) // size
|
||||
+ 1 // type
|
||||
};
|
||||
//---------------------------------------------------------------------
|
||||
agg::int8u m_storage[buf_size];
|
||||
const agg::int8u* m_data;
|
||||
agg::int32u m_size;
|
||||
bool m_with_type;
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
class attribute_bin_short
|
||||
{
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
attribute_bin_short(attr_e attr, const void* data, agg::int8u size)
|
||||
: m_data(static_cast<const agg::int8u*>(data)),
|
||||
m_size(size),
|
||||
m_with_type(false)
|
||||
{
|
||||
fill_head(attr);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
attribute_bin_short(attr_e attr, agg::int8u type, const void* data, agg::int8u size)
|
||||
: m_data(static_cast<const agg::int8u*>(data)),
|
||||
m_size(size + 1),
|
||||
m_with_type(true)
|
||||
{
|
||||
fill_head(attr);
|
||||
m_storage[3] = type;
|
||||
--m_size;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
const agg::int8u* head() const { return m_storage; }
|
||||
//---------------------------------------------------------------------
|
||||
agg::int32u head_size() const
|
||||
{
|
||||
return m_with_type ? buf_size : buf_size - 1;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
const agg::int8u* data() const { return m_data; }
|
||||
//---------------------------------------------------------------------
|
||||
agg::int32u data_size() const { return m_size; }
|
||||
//---------------------------------------------------------------------
|
||||
private:
|
||||
//---------------------------------------------------------------------
|
||||
void fill_head(attr_e attr)
|
||||
{
|
||||
m_storage[0] = tag_attribute_bin_short;
|
||||
m_storage[1] = attr;
|
||||
m_storage[2] = m_size;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
buf_size = 1 // tag
|
||||
+ 1 // attr_e
|
||||
+ 1 // size
|
||||
+ 1 // type
|
||||
};
|
||||
//---------------------------------------------------------------------
|
||||
agg::int8u m_storage[buf_size];
|
||||
const agg::int8u* m_data;
|
||||
agg::int32u m_size;
|
||||
bool m_with_type;
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_ATTRIBUTE_SOURCE_INCLUDED
|
||||
480
DesktopEditor/agg-2.4/svg/agg_svg_attributes.cpp
Normal file
480
DesktopEditor/agg-2.4/svg/agg_svg_attributes.cpp
Normal file
@ -0,0 +1,480 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_svg_attributes.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//---------------------------------------------------------------------------------
|
||||
agg::line_join_e g_stroke_linejoin_lut[] =
|
||||
{
|
||||
agg::miter_join_revert,
|
||||
agg::round_join,
|
||||
agg::bevel_join
|
||||
};
|
||||
//---------------------------------------------------------------------------------
|
||||
agg::line_cap_e g_stroke_linecap_lut[] =
|
||||
{
|
||||
agg::butt_cap,
|
||||
agg::round_cap,
|
||||
agg::square_cap
|
||||
};
|
||||
//---------------------------------------------------------------------------------
|
||||
agg::filling_rule_e g_fill_rule_lut[] =
|
||||
{
|
||||
agg::fill_non_zero,
|
||||
agg::fill_even_odd
|
||||
};
|
||||
//--------------------------------------------------------------------
|
||||
agg::int8u* attr_stack::push_attribute(unsigned type, unsigned size)
|
||||
{
|
||||
if(m_sessions.size())
|
||||
{
|
||||
session& s = m_sessions.last();
|
||||
agg::int8u* data = 0;
|
||||
|
||||
if(size < attr_heap_block_size)
|
||||
{
|
||||
int i = m_heap.allocate_continuous_block(size);
|
||||
if(i >= 0)
|
||||
{
|
||||
data = &m_heap[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data = new agg::int8u[size];
|
||||
type |= large_block_flag;
|
||||
}
|
||||
|
||||
if(data)
|
||||
{
|
||||
m_attributes.add(attr(type, data, size));
|
||||
s.set_saved_attribute(type);
|
||||
++s.num_attributes;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attr_stack::end_session()
|
||||
{
|
||||
const session& s = m_sessions.last();
|
||||
for(int i = (int)num_attributes() - 1; i >= 0; --i)
|
||||
{
|
||||
attr& a = m_attributes[s.start_attr_index + i];
|
||||
if(a.type & large_block_flag)
|
||||
{
|
||||
delete [] a.data;
|
||||
}
|
||||
}
|
||||
m_heap.free_tail(s.start_attr_heap);
|
||||
m_attributes.free_tail(s.start_attr_index);
|
||||
m_sessions.remove_last();
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
attributes::attributes(const global_settings& settings)
|
||||
: m_stack()
|
||||
, m_settings(&settings)
|
||||
, m_values()
|
||||
{}
|
||||
//--------------------------------------------------------------------
|
||||
struct affine_serializer_adaptor
|
||||
{
|
||||
transformer& m_trans;
|
||||
affine_serializer_adaptor(transformer& trans) : m_trans(trans) {}
|
||||
unsigned byte_size() const { return m_trans.byte_size_affine(); }
|
||||
void serialize(agg::int8u* ptr) const { m_trans.serialize_affine(ptr); }
|
||||
void deserialize(const agg::int8u* ptr) { m_trans.deserialize_affine(ptr); }
|
||||
};
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::end_session()
|
||||
{
|
||||
// Restore saved attributes
|
||||
//-------------------------
|
||||
int i = int(m_stack.num_attributes()) - 1;
|
||||
for(; i >= 0; --i)
|
||||
{
|
||||
const attr_stack::attr* a = m_stack.attribute(i);
|
||||
if(a)
|
||||
{
|
||||
switch(a->attr_type())
|
||||
{
|
||||
case attr_transform: { affine_serializer_adaptor (m_values.transformer).deserialize(a->data); } break;
|
||||
case attr_viewBox: restore_attribute(m_values.transformer, a->data); break;
|
||||
case attr_color: restore_attribute(m_values.color, a->data); break;
|
||||
case attr_opacity: restore_attribute(m_values.opacity, a->data); break;
|
||||
case attr_fill: restore_attribute(m_values.fill_type, a->data); break;
|
||||
case attr_fill_color: restore_attribute(m_values.fill_color, a->data); break;
|
||||
case attr_fill_gradient: restore_serializable(m_values.fill_gradient_id,a->data, a->size); break;
|
||||
case attr_fill_opacity: restore_attribute(m_values.fill_opacity, a->data); break;
|
||||
|
||||
case attr_stroke: restore_attribute(m_values.stroke_type, a->data); break;
|
||||
case attr_stroke_color: restore_attribute(m_values.stroke_color, a->data); break;
|
||||
case attr_stroke_gradient: restore_serializable(m_values.stroke_gradient_id, a->data, a->size); break;
|
||||
case attr_stroke_opacity: restore_attribute(m_values.stroke_opacity, a->data); break;
|
||||
case attr_fill_rule: restore_attribute(m_values.fill_rule, a->data); break;
|
||||
case attr_stroke_linejoin: restore_attribute(m_values.stroke_linejoin, a->data); break;
|
||||
case attr_stroke_linecap: restore_attribute(m_values.stroke_linecap, a->data); break;
|
||||
case attr_stroke_miterlimit: restore_attribute(m_values.stroke_miterlimit, a->data); break;
|
||||
case attr_stroke_width: restore_attribute(m_values.stroke_width, a->data); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Pop all attributes from stack
|
||||
//--------------------------
|
||||
m_stack.end_session();
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::reset_all()
|
||||
{
|
||||
m_values = values();
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::window(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
m_values.transformer.window(x1, y1, x2, y2);
|
||||
update_zoom();
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::set_zoom(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
zoom_data zoom;
|
||||
zoom.sx1 = window_x1();
|
||||
zoom.sy1 = window_y1();
|
||||
zoom.sx2 = window_x2();
|
||||
zoom.sy2 = window_y2();
|
||||
zoom.wx1 = x1;
|
||||
zoom.wy1 = y1;
|
||||
zoom.wx2 = x2;
|
||||
zoom.wy2 = y2;
|
||||
m_zoom_stack.add(zoom);
|
||||
update_zoom();
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::initial_zoom()
|
||||
{
|
||||
m_zoom_stack.remove_all();
|
||||
update_zoom();
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::update_zoom()
|
||||
{
|
||||
unsigned i;
|
||||
m_values.transformer.zoom(window_x1(), window_y1(), window_x2(), window_y2(),
|
||||
window_x1(), window_y1(), window_x2(), window_y2());
|
||||
for(i = 0; i < m_zoom_stack.size(); i++)
|
||||
{
|
||||
const zoom_data& zoom = m_zoom_stack[i];
|
||||
double zoom_wx1 = zoom.wx1;
|
||||
double zoom_wy1 = zoom.wy1;
|
||||
double zoom_wx2 = zoom.wx2;
|
||||
double zoom_wy2 = zoom.wy2;
|
||||
m_values.transformer.zoom().inverse_transform(&zoom_wx1, &zoom_wy1);
|
||||
m_values.transformer.zoom().inverse_transform(&zoom_wx2, &zoom_wy2);
|
||||
m_values.transformer.zoom(zoom_wx1, zoom_wy1, zoom_wx2, zoom_wy2,
|
||||
zoom.sx1, zoom.sy1, zoom.sx2, zoom.sy2);
|
||||
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::viewBox(double scx, double scy, double scw, double sch,
|
||||
double vbx, double vby, double vbw, double vbh,
|
||||
uniform_scaling_e align_type,
|
||||
window_fit_logic_e meet_or_slice,
|
||||
bool separate_window)
|
||||
{
|
||||
save_attribute(attr_viewBox, m_values.transformer);
|
||||
m_values.transformer.viewBox(scx, scy, scw, sch,
|
||||
vbx, vby, vbw, vbh,
|
||||
align_type, meet_or_slice, separate_window);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::opacity(double op)
|
||||
{
|
||||
save_attribute(attr_opacity, m_values.opacity);
|
||||
m_values.opacity = op;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::color(const color_type& c)
|
||||
{
|
||||
save_attribute(attr_color, m_values.color);
|
||||
m_values.color = gamma_color(c);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::color(unsigned c)
|
||||
{
|
||||
color(agg::rgb8_packed(c));
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::fill_none()
|
||||
{
|
||||
save_attribute(attr_fill, m_values.fill_type);
|
||||
m_values.fill_type = paint_none;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::fill_currentColor()
|
||||
{
|
||||
save_attribute(attr_fill, m_values.fill_type);
|
||||
m_values.fill_type = paint_currentColor;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::fill(const color_type& c)
|
||||
{
|
||||
save_attribute(attr_fill, m_values.fill_type);
|
||||
save_attribute(attr_fill_color, m_values.fill_color);
|
||||
m_values.fill_type = paint_color;
|
||||
m_values.fill_color = gamma_color(c);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::fill(unsigned c)
|
||||
{
|
||||
fill(agg::rgb8_packed(c));
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
color_type attributes::fill_color() const
|
||||
{
|
||||
color_type c = (m_values.fill_type == paint_color) ? m_values.fill_color : m_values.color;
|
||||
c.a = (color_type::value_type)(c.a * fill_opacity() + 0.5);
|
||||
return c;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::fill_opacity(double op)
|
||||
{
|
||||
save_attribute(attr_fill_opacity, m_values.fill_opacity);
|
||||
m_values.fill_opacity = op;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::stroke_none()
|
||||
{
|
||||
save_attribute(attr_stroke, m_values.stroke_type);
|
||||
m_values.stroke_type = paint_none;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::stroke_currentColor()
|
||||
{
|
||||
save_attribute(attr_stroke, m_values.stroke_type);
|
||||
m_values.stroke_type = paint_currentColor;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::stroke(const color_type& c)
|
||||
{
|
||||
save_attribute(attr_stroke, m_values.stroke_type);
|
||||
save_attribute(attr_stroke_color, m_values.stroke_color);
|
||||
m_values.stroke_type = paint_color;
|
||||
m_values.stroke_color = gamma_color(c);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::stroke(unsigned c)
|
||||
{
|
||||
stroke(agg::rgb8_packed(c));
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
color_type attributes::stroke_color() const
|
||||
{
|
||||
color_type c = (m_values.stroke_type == paint_color) ? m_values.stroke_color : m_values.color;
|
||||
c.a = (color_type::value_type)(c.a * stroke_opacity() + 0.5);
|
||||
return c;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::stroke_opacity(double op)
|
||||
{
|
||||
save_attribute(attr_stroke_opacity, m_values.stroke_opacity);
|
||||
m_values.stroke_opacity = op;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::fill_rule(fill_rule_e fe)
|
||||
{
|
||||
save_attribute(attr_fill_rule, m_values.fill_rule);
|
||||
m_values.fill_rule = fe;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::stroke_linejoin(stroke_linejoin_e lj)
|
||||
{
|
||||
save_attribute(attr_stroke_linejoin, m_values.stroke_linejoin);
|
||||
m_values.stroke_linejoin = lj;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::stroke_linecap(stroke_linecap_e lc)
|
||||
{
|
||||
save_attribute(attr_stroke_linecap, m_values.stroke_linecap);
|
||||
m_values.stroke_linecap = lc;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::stroke_miterlimit(double ml)
|
||||
{
|
||||
save_attribute(attr_stroke_miterlimit, m_values.stroke_miterlimit);
|
||||
m_values.stroke_miterlimit = ml;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::stroke_width(double sw)
|
||||
{
|
||||
save_attribute(attr_stroke_width, m_values.stroke_width);
|
||||
m_values.stroke_width = sw;
|
||||
if(sw <= 1e-30)
|
||||
{
|
||||
stroke_none();
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::object_bbox(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
save_attribute(attr_object_bbox, m_values.object_bbox);
|
||||
m_values.object_bbox[0] = x1;
|
||||
m_values.object_bbox[1] = y1;
|
||||
m_values.object_bbox[2] = x2;
|
||||
m_values.object_bbox[3] = y2;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::object_bbox(const rectangle& bbox)
|
||||
{
|
||||
object_bbox(bbox.x1, bbox.y1, bbox.x2, bbox.y2);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::transform(const agg::trans_affine& mtx)
|
||||
{
|
||||
save_serializable(attr_transform, affine_serializer_adaptor(m_values.transformer));
|
||||
m_values.transformer.transform(mtx);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::transform(double a0, double a1, double a2,
|
||||
double a3, double a4, double a5)
|
||||
{
|
||||
save_serializable(attr_transform, affine_serializer_adaptor(m_values.transformer));
|
||||
m_values.transformer.transform(a0, a1, a2, a3, a4, a5);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::translate(double dx, double dy)
|
||||
{
|
||||
save_serializable(attr_transform, affine_serializer_adaptor(m_values.transformer));
|
||||
m_values.transformer.translate(dx, dy);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::rotate(double angle)
|
||||
{
|
||||
save_serializable(attr_transform, affine_serializer_adaptor(m_values.transformer));
|
||||
m_values.transformer.rotate(angle);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::rotate(double angle, double cx, double cy)
|
||||
{
|
||||
save_serializable(attr_transform, affine_serializer_adaptor(m_values.transformer));
|
||||
m_values.transformer.rotate(angle, cx, cy);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::scale(double s)
|
||||
{
|
||||
save_serializable(attr_transform, affine_serializer_adaptor(m_values.transformer));
|
||||
m_values.transformer.scale(s);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::scale(double sx, double sy)
|
||||
{
|
||||
save_serializable(attr_transform, affine_serializer_adaptor(m_values.transformer));
|
||||
m_values.transformer.scale(sx, sy);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::skew(double sx, double sy)
|
||||
{
|
||||
save_serializable(attr_transform, affine_serializer_adaptor(m_values.transformer));
|
||||
m_values.transformer.skew(sx, sy);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::skew_x(double s)
|
||||
{
|
||||
save_serializable(attr_transform, affine_serializer_adaptor(m_values.transformer));
|
||||
m_values.transformer.skew_x(s);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
void attributes::skew_y(double s)
|
||||
{
|
||||
save_serializable(attr_transform, affine_serializer_adaptor(m_values.transformer));
|
||||
m_values.transformer.skew_y(s);
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
double attributes::percent2pix(double percent) const
|
||||
{
|
||||
double w = window_x2() - window_x1();
|
||||
double h = window_y2() - window_y1();
|
||||
if(m_values.transformer.viewBox_level())
|
||||
{
|
||||
double x1, y1, x2, y2;
|
||||
m_values.transformer.world_viewport(&x1, &y1, &x2, &y2);
|
||||
w = x2 - x1;
|
||||
h = y2 - y1;
|
||||
}
|
||||
return percent * sqrt(w*w + h*h) * 0.0070710678118654752440084436210485;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
double attributes::percent2pix_x(double percent) const
|
||||
{
|
||||
double w = window_x2() - window_x1();
|
||||
if(m_values.transformer.viewBox_level())
|
||||
{
|
||||
double x1, y1, x2, y2;
|
||||
m_values.transformer.world_viewport(&x1, &y1, &x2, &y2);
|
||||
w = x2 - x1;
|
||||
}
|
||||
return percent * 0.01 * w;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
double attributes::percent2pix_y(double percent) const
|
||||
{
|
||||
double h = window_y2() - window_y1();
|
||||
if(m_values.transformer.viewBox_level())
|
||||
{
|
||||
double x1, y1, x2, y2;
|
||||
m_values.transformer.world_viewport(&x1, &y1, &x2, &y2);
|
||||
h = y2 - y1;
|
||||
}
|
||||
return percent * 0.01 * h;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
double attributes::conv_units(double v, units2_e u) const
|
||||
{
|
||||
switch(u)
|
||||
{
|
||||
default: break;
|
||||
case units_em: return v; // don't supported
|
||||
case units_ex: return v; // don't supported
|
||||
|
||||
case units_pt:
|
||||
case units_pt_x: return m_settings->pt2pix_x(v);
|
||||
case units_pt_y: return m_settings->pt2pix_y(v);
|
||||
|
||||
case units_pc:
|
||||
case units_pc_x: return m_settings->pc2pix_x(v);
|
||||
case units_pc_y: return m_settings->pc2pix_y(v);
|
||||
|
||||
case units_cm:
|
||||
case units_cm_x: return m_settings->cm2pix_x(v);
|
||||
case units_cm_y: return m_settings->cm2pix_y(v);
|
||||
|
||||
case units_mm:
|
||||
case units_mm_x: return m_settings->mm2pix_x(v);
|
||||
case units_mm_y: return m_settings->mm2pix_y(v);
|
||||
|
||||
case units_in:
|
||||
case units_in_x: return m_settings->in2pix_x(v);
|
||||
case units_in_y: return m_settings->in2pix_y(v);
|
||||
|
||||
case units_percent: return percent2pix(v);
|
||||
case units_percent_x: return percent2pix_x(v);
|
||||
case units_percent_y: return percent2pix_y(v);
|
||||
|
||||
case units_deg: return v * agg::pi / 180.0;
|
||||
case units_grad: return v * agg::pi / 200.0;
|
||||
case units_rad: return v;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
590
DesktopEditor/agg-2.4/svg/agg_svg_attributes.h
Normal file
590
DesktopEditor/agg-2.4/svg/agg_svg_attributes.h
Normal file
@ -0,0 +1,590 @@
|
||||
#ifndef AGG_SVG_ATTRIBUTES_INCLUDED
|
||||
#define AGG_SVG_ATTRIBUTES_INCLUDED
|
||||
|
||||
#include "agg_conv_stroke.h"
|
||||
#include "agg_gamma_lut.h"
|
||||
#include "agg_svg_basics.h"
|
||||
#include "agg_svg_defines.h"
|
||||
#include "agg_svg_transformer.h"
|
||||
#include "agg_svg_frame_buffer_rgba.h"
|
||||
#include "agg_svg_gradient_lut_cache.h"
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
extern agg::line_join_e g_stroke_linejoin_lut[];
|
||||
extern agg::line_cap_e g_stroke_linecap_lut[];
|
||||
extern agg::filling_rule_e g_fill_rule_lut[];
|
||||
|
||||
class global_settings
|
||||
{
|
||||
public:
|
||||
typedef agg::gamma_lut<color_type::value_type,
|
||||
color_type::value_type,
|
||||
color_type::base_shift,
|
||||
color_type::base_shift> gamma_lut_type;
|
||||
|
||||
global_settings()
|
||||
: m_gamma()
|
||||
, m_dpi_x(96.0)
|
||||
, m_dpi_y(96.0)
|
||||
{}
|
||||
|
||||
// Metrics
|
||||
//-----------------------------------------------------------------------
|
||||
void dpi(double v) { m_dpi_x = m_dpi_y = v; }
|
||||
void dpi_x(double v) { m_dpi_x = v; }
|
||||
void dpi_y(double v) { m_dpi_y = v; }
|
||||
double dpi() const { return (m_dpi_x + m_dpi_y) / 2; }
|
||||
|
||||
static double pt2pix(double pt, double dpi) { return pt * dpi / 72.0; }
|
||||
static double pc2pix(double pc, double dpi) { return pc * dpi / 6.0; }
|
||||
static double cm2pix(double cm, double dpi) { return cm * dpi / 2.54; }
|
||||
static double mm2pix(double mm, double dpi) { return mm * dpi / 25.4; }
|
||||
static double in2pix(double in, double dpi) { return in * dpi; }
|
||||
|
||||
double pt2pix_x(double pt) const { return pt2pix(pt, m_dpi_x); }
|
||||
double pt2pix_y(double pt) const { return pt2pix(pt, m_dpi_y); }
|
||||
double pc2pix_x(double pc) const { return pc2pix(pc, m_dpi_x); }
|
||||
double pc2pix_y(double pc) const { return pc2pix(pc, m_dpi_y); }
|
||||
double cm2pix_x(double cm) const { return cm2pix(cm, m_dpi_x); }
|
||||
double cm2pix_y(double cm) const { return cm2pix(cm, m_dpi_y); }
|
||||
double mm2pix_x(double mm) const { return mm2pix(mm, m_dpi_x); }
|
||||
double mm2pix_y(double mm) const { return mm2pix(mm, m_dpi_y); }
|
||||
double in2pix_x(double in) const { return in2pix(in, m_dpi_x); }
|
||||
double in2pix_y(double in) const { return in2pix(in, m_dpi_y); }
|
||||
|
||||
|
||||
double pt2pix(double pt) const { return pt2pix(pt, m_dpi_x); }
|
||||
double pc2pix(double pc) const { return pc2pix(pc, m_dpi_x); }
|
||||
double cm2pix(double cm) const { return cm2pix(cm, m_dpi_x); }
|
||||
double mm2pix(double mm) const { return mm2pix(mm, m_dpi_x); }
|
||||
double in2pix(double in) const { return in2pix(in, m_dpi_x); }
|
||||
|
||||
|
||||
// Full color gamma correction
|
||||
//-----------------------------------------------------------------------
|
||||
void gamma(double g) { m_gamma.gamma(g); }
|
||||
double gamma() const { return m_gamma.gamma(); }
|
||||
|
||||
const gamma_lut_type& gamma_lut() const { return m_gamma; }
|
||||
|
||||
unsigned gamma_dir(unsigned v) const { return m_gamma.dir(v); }
|
||||
unsigned gamma_inv(unsigned v) const { return m_gamma.inv(v); }
|
||||
|
||||
private:
|
||||
gamma_lut_type m_gamma;
|
||||
double m_dpi_x;
|
||||
double m_dpi_y;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Class attr_stack is used to save and restore different attributes.
|
||||
//
|
||||
// USAGE:
|
||||
//
|
||||
// 1. When the SVG command comes (startElement event), call
|
||||
// begin_session();
|
||||
//
|
||||
// 2. When the attribute comes, you do the following:
|
||||
// if(!stack.attribute_saved(attr.type()))
|
||||
// {
|
||||
// int8u* ptr = stack.push_attribute(attr.type(), attr.size());
|
||||
// if(ptr) attr.serialize(ptr);
|
||||
// }
|
||||
// attr.set_new_value(attr_value);
|
||||
//
|
||||
// 3. When processing of the command is done (endElement event)
|
||||
// you restore all saved attributes and call end_session():
|
||||
//
|
||||
// for(i = 0; i < stack.num_attributes(); ++i)
|
||||
// {
|
||||
// const attr_stack::attr* a = stack.attribute(i);
|
||||
// if(a)
|
||||
// {
|
||||
// attr.deserialize(a->data, a->size);
|
||||
// }
|
||||
// }
|
||||
// end_session();
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
class attr_stack
|
||||
{
|
||||
public:
|
||||
//-----------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
attr_heap_block_shift = 16,
|
||||
attr_heap_block_size = 1 << attr_heap_block_shift,
|
||||
attr_heap_block_mask = attr_heap_block_size - 1,
|
||||
|
||||
large_block_flag = (1 << 16)
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
struct attr
|
||||
{
|
||||
unsigned type;
|
||||
unsigned size;
|
||||
agg::int8u* data;
|
||||
|
||||
attr() {}
|
||||
attr(unsigned t, agg::int8u* d, unsigned s) :
|
||||
type(t), size(s), data(d)
|
||||
{}
|
||||
unsigned attr_type() const { return type & (~large_block_flag); }
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
attr_stack() :
|
||||
m_heap(256-4),
|
||||
m_attributes(),
|
||||
m_sessions()
|
||||
{}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
unsigned num_sessions() const
|
||||
{
|
||||
return m_sessions.size();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void begin_session()
|
||||
{
|
||||
m_sessions.add(session(m_attributes.size(), m_heap.size()));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
bool attribute_saved(unsigned type) const
|
||||
{
|
||||
return m_sessions.last().attribute_saved(type) != 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
agg::int8u* push_attribute(unsigned type, unsigned size);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
unsigned num_attributes() const
|
||||
{
|
||||
return m_sessions.last().num_attributes;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
const attr* attribute(unsigned idx) const
|
||||
{
|
||||
return &m_attributes[m_sessions.last().start_attr_index + idx];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void end_session();
|
||||
//-----------------------------------------------------------------------
|
||||
void clear()
|
||||
{
|
||||
m_heap.free_all();
|
||||
m_attributes.free_all();
|
||||
m_sessions.free_all();
|
||||
}
|
||||
|
||||
private:
|
||||
//-----------------------------------------------------------------------
|
||||
struct session
|
||||
{
|
||||
enum
|
||||
{
|
||||
num_flag_bytes = 512/8
|
||||
};
|
||||
|
||||
unsigned start_attr_index;
|
||||
unsigned num_attributes;
|
||||
unsigned start_attr_heap;
|
||||
agg::int8u saved_attributes[num_flag_bytes];
|
||||
|
||||
session() {}
|
||||
session(unsigned start_attr, unsigned start_heap) :
|
||||
start_attr_index(start_attr),
|
||||
num_attributes(0),
|
||||
start_attr_heap(start_heap)
|
||||
{
|
||||
memset(saved_attributes, 0, sizeof(saved_attributes));
|
||||
}
|
||||
|
||||
void set_saved_attribute(unsigned attr_type)
|
||||
{
|
||||
attr_type &= ~large_block_flag;
|
||||
saved_attributes[attr_type >> 3] |= 1 << (attr_type & 7);
|
||||
}
|
||||
|
||||
unsigned attribute_saved(unsigned attr_type) const
|
||||
{
|
||||
attr_type &= ~large_block_flag;
|
||||
return saved_attributes[attr_type >> 3] & (1 << (attr_type & 7));
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
agg::pod_bvector<agg::int8u, attr_heap_block_shift> m_heap;
|
||||
agg::pod_bvector<attr, 8> m_attributes;
|
||||
agg::pod_bvector<session, 6> m_sessions;
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
class attr_string
|
||||
{
|
||||
std::string m_value;
|
||||
|
||||
public:
|
||||
const char_type* data()const { return m_value.c_str(); }
|
||||
|
||||
unsigned byte_size()const {return (unsigned)m_value.size(); }
|
||||
|
||||
template <class DataAccessor>
|
||||
const attr_string& assign_from(DataAccessor str)
|
||||
{
|
||||
unsigned len = str.size();
|
||||
|
||||
m_value.clear();
|
||||
m_value.reserve(len + 1);
|
||||
|
||||
for(unsigned i = 0; str.size();)
|
||||
{
|
||||
m_value += str.read_value();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void serialize(agg::int8u* ptr)const
|
||||
{
|
||||
memcpy(ptr, m_value.data(), m_value.size());
|
||||
}
|
||||
|
||||
void deserialize(const agg::int8u* data, unsigned size)
|
||||
{
|
||||
m_value.assign(data, data + size);
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// This class is a container for all known SVG attributes. It uses
|
||||
// attr_stack inside.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
class attributes
|
||||
{
|
||||
private:
|
||||
struct zoom_data
|
||||
{
|
||||
double wx1, wy1, wx2, wy2;
|
||||
double sx1, sy1, sx2, sy2;
|
||||
};
|
||||
|
||||
typedef global_settings::gamma_lut_type gamma_lut_type;
|
||||
|
||||
// prevent copy
|
||||
attributes(const attributes& attr);
|
||||
const attributes& operator = (const attributes& attr);
|
||||
|
||||
struct values
|
||||
{
|
||||
double opacity;
|
||||
color_type color;
|
||||
paint_type_e fill_type;
|
||||
color_type fill_color;
|
||||
attr_string fill_gradient_id;
|
||||
double fill_opacity;
|
||||
fill_rule_e fill_rule;
|
||||
paint_type_e stroke_type;
|
||||
color_type stroke_color;
|
||||
attr_string stroke_gradient_id;
|
||||
double stroke_opacity;
|
||||
double stroke_width;
|
||||
stroke_linejoin_e stroke_linejoin;
|
||||
stroke_linecap_e stroke_linecap;
|
||||
double stroke_miterlimit;
|
||||
|
||||
agg::svg::transformer transformer;
|
||||
double object_bbox[4];
|
||||
|
||||
values() :
|
||||
opacity(1.0),
|
||||
color(color_type(0,0,0)),
|
||||
fill_type(paint_color),
|
||||
fill_color(color_type(0, 0, 0)),
|
||||
fill_gradient_id(),
|
||||
fill_opacity(1.0),
|
||||
fill_rule(fill_rule_nonzero),
|
||||
stroke_type(paint_none),
|
||||
stroke_color(color_type(0,0,0)),
|
||||
|
||||
stroke_gradient_id(),
|
||||
|
||||
stroke_opacity(1.0),
|
||||
stroke_width(1.0),
|
||||
stroke_linejoin(stroke_linejoin_miter),
|
||||
stroke_linecap(stroke_linecap_butt),
|
||||
stroke_miterlimit(4.0),
|
||||
|
||||
transformer()
|
||||
{
|
||||
object_bbox[0] = 0;
|
||||
object_bbox[1] = 0;
|
||||
object_bbox[2] = 1;
|
||||
object_bbox[3] = 1;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
explicit attributes(const global_settings& settings);
|
||||
|
||||
// Global Settings
|
||||
//-----------------------------------------------------------------------
|
||||
const global_settings& settings() const { return *m_settings; }
|
||||
|
||||
double gamma() const { return m_settings->gamma(); }
|
||||
const gamma_lut_type& gamma_lut() const { return m_settings->gamma_lut(); }
|
||||
|
||||
color_type gamma_color(color_type c) const
|
||||
{
|
||||
c.r = m_settings->gamma_dir(c.r);
|
||||
c.g = m_settings->gamma_dir(c.g);
|
||||
c.b = m_settings->gamma_dir(c.b);
|
||||
return c;
|
||||
}
|
||||
|
||||
// Sessions
|
||||
//-----------------------------------------------------------------------
|
||||
void begin_session() { m_stack.begin_session(); }
|
||||
void end_session();
|
||||
unsigned num_sessions() const { return m_stack.num_sessions(); }
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void reset_all();
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_stack.clear();
|
||||
reset_all();
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
void window(int x1, int y1, int x2, int y2);
|
||||
void set_zoom(double x1, double y1, double x2, double y2);
|
||||
void initial_zoom();
|
||||
|
||||
// General attributes and properties
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void viewBox(double scx, double scy, double scw, double sch,
|
||||
double vbx, double vby, double vbw, double vbh,
|
||||
uniform_scaling_e align_type,
|
||||
window_fit_logic_e meet_or_slice,
|
||||
bool separate_window);
|
||||
|
||||
void opacity(double op);
|
||||
void color(const color_type& c);
|
||||
void color(unsigned c);
|
||||
|
||||
void fill_none();
|
||||
void fill_currentColor();
|
||||
void fill(const color_type& c);
|
||||
void fill(unsigned c);
|
||||
|
||||
template<class DataAccessor>
|
||||
void fill_gradient_id(DataAccessor gradient_id)
|
||||
{
|
||||
save_attribute(attr_fill, m_values.fill_type);
|
||||
save_serializable(attr_fill_gradient, m_values.fill_gradient_id);
|
||||
m_values.fill_type = paint_gradient;
|
||||
m_values.fill_gradient_id.assign_from(gradient_id);
|
||||
}
|
||||
|
||||
void fill_opacity(double op);
|
||||
|
||||
void stroke_none();
|
||||
void stroke_currentColor();
|
||||
void stroke(const color_type& c);
|
||||
void stroke(unsigned c);
|
||||
|
||||
template<class DataAccessor>
|
||||
void stroke_gradient_id(DataAccessor gradient_id)
|
||||
{
|
||||
save_attribute(attr_stroke, m_values.stroke_type);
|
||||
save_serializable(attr_stroke_gradient, m_values.stroke_gradient_id);
|
||||
m_values.stroke_type = paint_gradient;
|
||||
m_values.stroke_gradient_id.assign_from(gradient_id);
|
||||
}
|
||||
|
||||
void stroke_opacity(double op);
|
||||
void fill_rule(fill_rule_e fe);
|
||||
void stroke_linejoin(stroke_linejoin_e lj);
|
||||
void stroke_linecap(stroke_linecap_e lc);
|
||||
void stroke_miterlimit(double ml);
|
||||
void stroke_width(double sw);
|
||||
|
||||
void object_bbox(double x1, double y1, double x2, double y2);
|
||||
void object_bbox(const rectangle& bbox);
|
||||
|
||||
void transform(const agg::trans_affine& mtx);
|
||||
void transform(double a0, double a1, double a2,
|
||||
double a3, double a4, double a5);
|
||||
void translate(double dx, double dy);
|
||||
void rotate(double angle);
|
||||
void rotate(double angle, double cx, double cy);
|
||||
void scale(double s);
|
||||
void scale(double sx, double sy);
|
||||
void skew(double sx, double sy);
|
||||
void skew_x(double s);
|
||||
void skew_y(double s);
|
||||
|
||||
// Accessors
|
||||
//-----------------------------------------------------------------------
|
||||
double opacity() const { return m_values.opacity; }
|
||||
paint_type_e fill_type() const { return m_values.fill_type; }
|
||||
color_type fill_color() const;
|
||||
double fill_opacity() const { return m_values.fill_opacity * opacity(); }
|
||||
const char_type* fill_gradient_id() const { return m_values.fill_gradient_id.data(); }
|
||||
|
||||
fill_rule_e fill_rule() const { return m_values.fill_rule; }
|
||||
paint_type_e stroke_type() const { return m_values.stroke_type; }
|
||||
color_type stroke_color() const;
|
||||
double stroke_opacity() const { return m_values.stroke_opacity * opacity(); }
|
||||
const char_type* stroke_gradient_id() const { return m_values.stroke_gradient_id.data(); }
|
||||
double stroke_width() const { return m_values.stroke_width; }
|
||||
stroke_linejoin_e stroke_linejoin() const { return m_values.stroke_linejoin; }
|
||||
stroke_linecap_e stroke_linecap() const { return m_values.stroke_linecap; }
|
||||
double stroke_miterlimit() const { return m_values.stroke_miterlimit; }
|
||||
|
||||
|
||||
const transformer& transform() const { return m_values.transformer; }
|
||||
transformer& transform() { return m_values.transformer; }
|
||||
double scale() const { return m_values.transformer.scale(); }
|
||||
double object_x1() const { return m_values.object_bbox[0]; }
|
||||
double object_y1() const { return m_values.object_bbox[1]; }
|
||||
double object_x2() const { return m_values.object_bbox[2]; }
|
||||
double object_y2() const { return m_values.object_bbox[3]; }
|
||||
|
||||
int window_x1() const { return m_values.transformer.window_x1(); }
|
||||
int window_y1() const { return m_values.transformer.window_y1(); }
|
||||
int window_x2() const { return m_values.transformer.window_x2(); }
|
||||
int window_y2() const { return m_values.transformer.window_y2(); }
|
||||
|
||||
double clip_x1() const { return m_values.transformer.clip_x1(); }
|
||||
double clip_y1() const { return m_values.transformer.clip_y1(); }
|
||||
double clip_x2() const { return m_values.transformer.clip_x2(); }
|
||||
double clip_y2() const { return m_values.transformer.clip_y2(); }
|
||||
|
||||
int buffer_x1() const { return m_values.transformer.buffer_x1(); }
|
||||
int buffer_y1() const { return m_values.transformer.buffer_y1(); }
|
||||
int buffer_x2() const { return m_values.transformer.buffer_x2(); }
|
||||
int buffer_y2() const { return m_values.transformer.buffer_y2(); }
|
||||
bool viewBox_is_valid() const { return m_values.transformer.is_valid(); }
|
||||
bool is_visible(double x1, double y1, double x2, double y2) const
|
||||
{
|
||||
return m_values.transformer.is_visible(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
|
||||
// Metrics
|
||||
//-----------------------------------------------------------------------
|
||||
double percent2pix(double percent) const;
|
||||
double percent2pix_x(double percent) const;
|
||||
double percent2pix_y(double percent) const;
|
||||
|
||||
double conv_units(double v, units2_e u) const;
|
||||
|
||||
private:
|
||||
template<class Serializer>
|
||||
void save_serializable(unsigned attr, const Serializer& serializer)
|
||||
{
|
||||
if(!m_stack.attribute_saved(attr))
|
||||
{
|
||||
agg::int8u* ptr = m_stack.push_attribute(attr, serializer.byte_size());
|
||||
serializer.serialize(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
template<class Serializer>
|
||||
void restore_serializable(Serializer& serializer,
|
||||
const agg::int8u* data,
|
||||
unsigned size)
|
||||
{
|
||||
serializer.deserialize(data, size);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void save_attribute(attr_e attr, const T& data)
|
||||
{
|
||||
if(!m_stack.attribute_saved(attr))
|
||||
{
|
||||
agg::int8u* ptr = m_stack.push_attribute(attr, sizeof(T));
|
||||
memcpy(ptr, &data, sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
template<class T1, class T2>
|
||||
void save_attribute(unsigned attr, const T1& data1, const T2& data2)
|
||||
{
|
||||
if(!m_stack.attribute_saved(attr))
|
||||
{
|
||||
agg::int8u* ptr = m_stack.push_attribute(attr, sizeof(T1) + sizeof(T2));
|
||||
memcpy(ptr, &data1, sizeof(T1));
|
||||
memcpy(ptr + sizeof(T1), &data2, sizeof(T2));
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void restore_attribute(T& attr, const agg::int8u* data)
|
||||
{
|
||||
memcpy(&attr, data, sizeof(T));
|
||||
}
|
||||
|
||||
template<class T1, class T2>
|
||||
void restore_attribute(T1& attr1, T2& attr2, const agg::int8u* data)
|
||||
{
|
||||
memcpy(&attr1, data, sizeof(T1));
|
||||
memcpy(&attr2, data + sizeof(T1), sizeof(T2));
|
||||
}
|
||||
|
||||
template<class ArrayType, class UnitsArrayAccessor>
|
||||
void deserialize_units_array(unsigned start,
|
||||
ArrayType& array,
|
||||
UnitsArrayAccessor data)
|
||||
{
|
||||
if(start == 0) array.remove_all();
|
||||
while(array.size() < start)
|
||||
{
|
||||
array.add(0.0);
|
||||
}
|
||||
|
||||
for(unsigned i = 0; data.size(); i++)
|
||||
{
|
||||
double v = data.read_units_value(*this);
|
||||
if(start + i < array.size())
|
||||
{
|
||||
array.at(start + i) = v;
|
||||
}
|
||||
else
|
||||
{
|
||||
array.add(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void update_zoom();
|
||||
|
||||
attr_stack m_stack;
|
||||
const global_settings* m_settings;
|
||||
agg::pod_bvector<zoom_data> m_zoom_stack;
|
||||
values m_values;
|
||||
};
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_ATTRIBUTES_INCLUDED
|
||||
|
||||
116
DesktopEditor/agg-2.4/svg/agg_svg_attributes_map.cpp
Normal file
116
DesktopEditor/agg-2.4/svg/agg_svg_attributes_map.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_svg_attributes_map.h"
|
||||
#include "agg_svg_utils.h"
|
||||
#include "agg_svg_basics.h"
|
||||
#include "member_comparer.h"
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
typedef std::vector<std::pair<const char*, attr_e> > map_type;
|
||||
map_type m_map;
|
||||
unsigned m_names_positions[end_of_attr];
|
||||
}
|
||||
|
||||
#define ADD_ATTR(name, value) \
|
||||
m_map.push_back(map_type::value_type(name, value));
|
||||
//-------------------------------------------------------------------------
|
||||
attributes_map::attributes_map()
|
||||
{
|
||||
memset(m_names_positions, 0, sizeof(unsigned)*end_of_attr);
|
||||
m_map.reserve(end_of_attr);
|
||||
int index = 0;
|
||||
|
||||
ADD_ATTR( "color", attr_color );
|
||||
ADD_ATTR( "cx", attr_cx );
|
||||
ADD_ATTR( "cy", attr_cy );
|
||||
ADD_ATTR( "d", attr_d );
|
||||
ADD_ATTR( "fill", attr_fill );
|
||||
ADD_ATTR( "fill-opacity", attr_fill_opacity );
|
||||
ADD_ATTR( "fill-rule", attr_fill_rule );
|
||||
ADD_ATTR( "fx", attr_fx );
|
||||
ADD_ATTR( "fy", attr_fy );
|
||||
ADD_ATTR( "gradientTransform", attr_gradientTransform );
|
||||
ADD_ATTR( "gradientUnits", attr_gradientUnits );
|
||||
ADD_ATTR( "height", attr_height );
|
||||
ADD_ATTR( "id", attr_id );
|
||||
ADD_ATTR( "offset", attr_offset );
|
||||
ADD_ATTR( "opacity", attr_opacity );
|
||||
ADD_ATTR( "points", attr_points );
|
||||
ADD_ATTR( "preserveAspectRatio", attr_preserveAspectRatio );
|
||||
ADD_ATTR( "r", attr_r );
|
||||
ADD_ATTR( "rx", attr_rx );
|
||||
ADD_ATTR( "ry", attr_ry );
|
||||
ADD_ATTR( "spreadMethod", attr_spreadMethod );
|
||||
ADD_ATTR( "stop-color", attr_stop_color );
|
||||
ADD_ATTR( "stop-opacity", attr_stop_opacity );
|
||||
ADD_ATTR( "stroke", attr_stroke );
|
||||
ADD_ATTR( "stroke-linecap", attr_stroke_linecap );
|
||||
ADD_ATTR( "stroke-linejoin", attr_stroke_linejoin );
|
||||
ADD_ATTR( "stroke-miterlimit", attr_stroke_miterlimit );
|
||||
ADD_ATTR( "stroke-opacity", attr_stroke_opacity );
|
||||
ADD_ATTR( "stroke-width", attr_stroke_width );
|
||||
ADD_ATTR( "style", attr_style );
|
||||
ADD_ATTR( "transform", attr_transform );
|
||||
ADD_ATTR( "viewBox", attr_viewBox );
|
||||
ADD_ATTR( "width", attr_width );
|
||||
ADD_ATTR( "x", attr_x );
|
||||
ADD_ATTR( "x1", attr_x1 );
|
||||
ADD_ATTR( "x2", attr_x2 );
|
||||
ADD_ATTR( "xlink:href", attr_xlink_href );
|
||||
ADD_ATTR( "y", attr_y );
|
||||
ADD_ATTR( "y1", attr_y1 );
|
||||
ADD_ATTR( "y2", attr_y2 );
|
||||
|
||||
//--------------------------------------
|
||||
std::sort(m_map.begin(),
|
||||
m_map.end(),
|
||||
make_comparer
|
||||
(
|
||||
&map_type::value_type::first,
|
||||
string_comparer()
|
||||
)
|
||||
);
|
||||
|
||||
map_type::iterator it = m_map.begin();
|
||||
map_type::iterator end = m_map.end();
|
||||
for (unsigned i = 0; it != end; ++it)
|
||||
m_names_positions[it->second] = i++;
|
||||
}
|
||||
#undef ADD_ATTR
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
attr_e attributes_map::get_type(const char * name)
|
||||
{
|
||||
typedef std::pair<const char*, attr_e>* iterator;
|
||||
std::pair<map_type::iterator,map_type::iterator> range;
|
||||
|
||||
range = std::equal_range(m_map.begin(), m_map.end(), name,
|
||||
make_comparer
|
||||
(
|
||||
&std::pair<const char*, attr_e>::first,
|
||||
string_comparer()
|
||||
));
|
||||
|
||||
return range.first != range.second ? range.first->second : end_of_attr;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
const char * attributes_map::get_name(unsigned attr)
|
||||
{
|
||||
assert(attr >= 0);
|
||||
assert(attr < end_of_attr);
|
||||
|
||||
return m_map[m_names_positions[attr]].first;
|
||||
}
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
24
DesktopEditor/agg-2.4/svg/agg_svg_attributes_map.h
Normal file
24
DesktopEditor/agg-2.4/svg/agg_svg_attributes_map.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef AGG_SVG_ATTRIBUTES_MAP
|
||||
#define AGG_SVG_ATTRIBUTES_MAP
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_svg_defines.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
class attributes_map
|
||||
{
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
attributes_map();
|
||||
//---------------------------------------------------------------------
|
||||
attr_e get_type(const char * name);
|
||||
//---------------------------------------------------------------------
|
||||
const char * get_name(unsigned attr);
|
||||
};
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_ATTRIBUTES_MAP
|
||||
274
DesktopEditor/agg-2.4/svg/agg_svg_attributes_setter.cpp
Normal file
274
DesktopEditor/agg-2.4/svg/agg_svg_attributes_setter.cpp
Normal file
@ -0,0 +1,274 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_svg_attributes_setter.h"
|
||||
#include "agg_svg_attributes.h"
|
||||
#include "agg_svg_rendering_interpreter.h"
|
||||
#include <string>
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
attributes_setter::attributes_setter(attributes& at)
|
||||
: m_attributes(at)
|
||||
, m_interpreter(0)
|
||||
{
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void attributes_setter::set_interpreter(rendering_interpreter* rin)
|
||||
{
|
||||
m_interpreter = rin;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void attributes_setter::set_xlink_attributes(attr_data* attr,
|
||||
unsigned num_attr)
|
||||
{
|
||||
element_e element;
|
||||
|
||||
for (unsigned i = 0; i < num_attr; ++i)
|
||||
{
|
||||
if (!attr[i].processed) switch (attr[i].code)
|
||||
{
|
||||
case attr_xlink_href:
|
||||
assert(attr[i].data.size() > 0);
|
||||
element = m_interpreter->current_element();
|
||||
|
||||
if (element == elem_linearGradient ||
|
||||
element == elem_radialGradient )
|
||||
{
|
||||
m_interpreter->process_xlink_href(attr[i].data);
|
||||
}
|
||||
|
||||
attr[i].processed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void attributes_setter::set_paint_attributes(attr_data* attr, unsigned num_attr)
|
||||
{
|
||||
for (unsigned i = 0; i < num_attr; ++i)
|
||||
{
|
||||
if (!attr[i].processed) switch (attr[i].code)
|
||||
{
|
||||
case attr_color:
|
||||
assert(attr[i].data.size() == sizeof(agg::rgba8));
|
||||
m_attributes.color(attr[i].data.color_at(0));
|
||||
attr[i].processed = true;
|
||||
break;
|
||||
case attr_fill:
|
||||
set_fill(attr[i].data);
|
||||
attr[i].processed = true;
|
||||
break;
|
||||
case attr_fill_rule:
|
||||
assert(attr[i].data.size() == 1);
|
||||
m_attributes.fill_rule(fill_rule_e(*attr[i].data));
|
||||
attr[i].processed = true;
|
||||
break;
|
||||
case attr_stroke:
|
||||
set_stroke(attr[i].data);
|
||||
attr[i].processed = true;
|
||||
break;
|
||||
case attr_stroke_linecap:
|
||||
assert(attr[i].data.size() == 1);
|
||||
m_attributes.stroke_linecap(stroke_linecap_e(*attr[i].data));
|
||||
attr[i].processed = true;
|
||||
break;
|
||||
case attr_stroke_linejoin:
|
||||
assert(attr[i].data.size() == 1);
|
||||
m_attributes.stroke_linejoin(stroke_linejoin_e(*attr[i].data));
|
||||
attr[i].processed = true;
|
||||
break;
|
||||
case attr_stroke_miterlimit:
|
||||
assert(attr[i].data.size() == sizeof(coord_type));
|
||||
m_attributes.stroke_miterlimit(attr[i].data.coord_at(0));
|
||||
attr[i].processed = true;
|
||||
break;
|
||||
case attr_stroke_width:
|
||||
assert(attr[i].data.size() == sizeof(coord_type) + 1);
|
||||
m_attributes.stroke_width(attr[i].data.units_value(m_attributes));
|
||||
attr[i].processed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void attributes_setter::set_color_attributes(attr_data* attr,
|
||||
unsigned num_attr)
|
||||
{
|
||||
for (unsigned i = 0; i < num_attr; ++i)
|
||||
{
|
||||
if (!attr[i].processed && attr[i].code == attr_color)
|
||||
{
|
||||
assert(attr[i].data.size() == sizeof(agg::rgba8));
|
||||
m_attributes.color(attr[i].data.color_at(0));
|
||||
attr[i].processed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void attributes_setter::set_opacity_attributes(attr_data* attr,
|
||||
unsigned num_attr)
|
||||
{
|
||||
for (unsigned i = 0; i < num_attr; ++i)
|
||||
{
|
||||
if (!attr[i].processed) switch (attr[i].code)
|
||||
{
|
||||
case attr_opacity:
|
||||
assert(attr[i].data.size() == sizeof(coord_type));
|
||||
m_attributes.opacity(attr[i].data.coord_at(0) * m_attributes.opacity());
|
||||
attr[i].processed = true;
|
||||
break;
|
||||
case attr_stroke_opacity:
|
||||
assert(attr[i].data.size() == sizeof(coord_type));
|
||||
m_attributes.stroke_opacity(attr[i].data.coord_at(0));
|
||||
attr[i].processed = true;
|
||||
break;
|
||||
case attr_fill_opacity:
|
||||
assert(attr[i].data.size() == sizeof(coord_type));
|
||||
m_attributes.fill_opacity(attr[i].data.coord_at(0));
|
||||
attr[i].processed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void attributes_setter::set_transform_attributes(attr_data* attr,
|
||||
unsigned num_attr)
|
||||
{
|
||||
for (unsigned i = 0; i < num_attr; ++i)
|
||||
{
|
||||
if (!attr[i].processed && attr[i].code == attr_transform)
|
||||
{
|
||||
set_transform(m_attributes, attr[i].data);
|
||||
attr[i].processed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void attributes_setter::set_presentation_attributes(attr_data* attr,
|
||||
unsigned num_attr)
|
||||
{
|
||||
set_paint_attributes (attr, num_attr);
|
||||
set_color_attributes (attr, num_attr);
|
||||
set_opacity_attributes (attr, num_attr);
|
||||
set_xlink_attributes (attr, num_attr);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void attributes_setter::set_basic_shapes_common_attributes(
|
||||
attr_data* attr,
|
||||
unsigned num_attr)
|
||||
{
|
||||
set_paint_attributes (attr, num_attr);
|
||||
set_color_attributes (attr, num_attr);
|
||||
set_opacity_attributes (attr, num_attr);
|
||||
set_transform_attributes (attr, num_attr);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void attributes_setter::set_stroke_for_id(data_accessor_type data)
|
||||
{
|
||||
|
||||
++data; // skip paint type
|
||||
|
||||
switch (m_interpreter->interpret_element(data))
|
||||
{
|
||||
case elem_linearGradient:
|
||||
case elem_radialGradient:
|
||||
m_attributes.stroke_gradient_id(data);
|
||||
break;
|
||||
default:
|
||||
m_attributes.stroke_none();
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void attributes_setter::set_fill_for_id(data_accessor_type data)
|
||||
{
|
||||
++data; // skip paint type
|
||||
|
||||
switch (m_interpreter->interpret_element(data))
|
||||
{
|
||||
case elem_linearGradient:
|
||||
case elem_radialGradient:
|
||||
m_attributes.fill_gradient_id(data);
|
||||
break;
|
||||
default:
|
||||
m_attributes.fill_none();
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void attributes_setter::set_fill(const data_accessor_type& data)
|
||||
{
|
||||
assert(data.size() >= 1);
|
||||
|
||||
paint_type_e p = paint_type_e(*data);
|
||||
switch (p)
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
case paint_none:
|
||||
assert(data.size() == 1);
|
||||
m_attributes.fill_none();
|
||||
break;
|
||||
//---------------------------------------------------------------------
|
||||
case paint_currentColor:
|
||||
assert(data.size() == 1);
|
||||
m_attributes.fill_currentColor();
|
||||
break;
|
||||
//---------------------------------------------------------------------
|
||||
case paint_color:
|
||||
assert(data.size() == 1 + sizeof(agg::rgba8));
|
||||
m_attributes.fill(data.color_at(1));
|
||||
break;
|
||||
//---------------------------------------------------------------------
|
||||
case paint_id:
|
||||
set_fill_for_id(data);
|
||||
break;
|
||||
//---------------------------------------------------------------------
|
||||
case paint_gradient:
|
||||
assert(false);
|
||||
//---------------------------------------------------------------------
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void attributes_setter::set_stroke(const data_accessor_type& data)
|
||||
{
|
||||
assert(data.size() >= 1);
|
||||
|
||||
paint_type_e p = paint_type_e(*data);
|
||||
switch (p)
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
case paint_none:
|
||||
assert(data.size() == 1);
|
||||
m_attributes.stroke_none();
|
||||
break;
|
||||
//---------------------------------------------------------------------
|
||||
case paint_currentColor:
|
||||
assert(data.size() == 1);
|
||||
m_attributes.stroke_currentColor();
|
||||
break;
|
||||
//---------------------------------------------------------------------
|
||||
case paint_color:
|
||||
assert(data.size() == sizeof(agg::rgba8) + 1);
|
||||
m_attributes.stroke(data.color_at(1));
|
||||
break;
|
||||
//---------------------------------------------------------------------
|
||||
case paint_id:
|
||||
set_stroke_for_id(data);
|
||||
break;
|
||||
//---------------------------------------------------------------------
|
||||
case paint_gradient:
|
||||
assert(false);
|
||||
//---------------------------------------------------------------------
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
}
|
||||
119
DesktopEditor/agg-2.4/svg/agg_svg_attributes_setter.h
Normal file
119
DesktopEditor/agg-2.4/svg/agg_svg_attributes_setter.h
Normal file
@ -0,0 +1,119 @@
|
||||
#ifndef AGG_SVG_ATTRIBUTES_SETTER_INCLUDE
|
||||
#define AGG_SVG_ATTRIBUTES_SETTER_INCLUDE
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_svg_dom_storage.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
class attributes;
|
||||
class rendering_interpreter;
|
||||
//-------------------------------------------------------------------------
|
||||
class attributes_setter
|
||||
{
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
attributes_setter(attributes&);
|
||||
//---------------------------------------------------------------------
|
||||
void set_interpreter(rendering_interpreter*);
|
||||
//---------------------------------------------------------------------
|
||||
void set_paint_attributes (attr_data*, unsigned);
|
||||
void set_color_attributes (attr_data*, unsigned);
|
||||
void set_opacity_attributes (attr_data*, unsigned);
|
||||
void set_transform_attributes (attr_data*, unsigned);
|
||||
void set_basic_shapes_common_attributes(attr_data*, unsigned);
|
||||
void set_presentation_attributes (attr_data*, unsigned);
|
||||
void set_xlink_attributes (attr_data*, unsigned);
|
||||
//---------------------------------------------------------------------
|
||||
template <class Consumer>
|
||||
void set_transform(Consumer& cons, const data_accessor_type& data)
|
||||
{
|
||||
assert(data.size() >= 1);
|
||||
|
||||
transform_e t = transform_e(*data);
|
||||
|
||||
switch (t)
|
||||
{
|
||||
//-----------------------------------------------------------------
|
||||
case transform_matrix:
|
||||
assert(data.size() == 1 + 6 * sizeof(coord_type));
|
||||
cons.transform(data.coord_at(1),
|
||||
data.coord_at(1 + sizeof(coord_type)),
|
||||
data.coord_at(1 + sizeof(coord_type) * 2),
|
||||
data.coord_at(1 + sizeof(coord_type) * 3),
|
||||
data.coord_at(1 + sizeof(coord_type) * 4),
|
||||
data.coord_at(1 + sizeof(coord_type) * 5));
|
||||
break;
|
||||
//-----------------------------------------------------------------
|
||||
case transform_translate:
|
||||
assert(data.size() == 1 + 2 * sizeof(coord_type));
|
||||
cons.translate(data.coord_at(1),
|
||||
data.coord_at(1 + sizeof(coord_type)));
|
||||
break;
|
||||
//-----------------------------------------------------------------
|
||||
case transform_rotate:
|
||||
assert(data.size() >= 1 + sizeof(coord_type));
|
||||
if (data.size() - 1 == sizeof(coord_type))
|
||||
{
|
||||
cons.rotate(data.coord_at(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(data.size() == 1 + 3 * sizeof(coord_type));
|
||||
cons.rotate(data.coord_at(1),
|
||||
data.coord_at(1 + sizeof(coord_type)),
|
||||
data.coord_at(1 + sizeof(coord_type) * 2));
|
||||
}
|
||||
break;
|
||||
//-----------------------------------------------------------------
|
||||
case transform_scale:
|
||||
assert(data.size() >= 1 + sizeof(coord_type));
|
||||
if (data.size() - 1 == sizeof(coord_type))
|
||||
{
|
||||
cons.scale(data.coord_at(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(data.size() == 1 + 2 * sizeof(coord_type));
|
||||
cons.scale(data.coord_at(1),
|
||||
data.coord_at(1 + sizeof(coord_type)));
|
||||
}
|
||||
break;
|
||||
//-----------------------------------------------------------------
|
||||
case transform_skew_x:
|
||||
assert(data.size() == 1 + sizeof(coord_type));
|
||||
cons.skew_x(data.coord_at(1));
|
||||
break;
|
||||
//-----------------------------------------------------------------
|
||||
case transform_skew_y:
|
||||
assert(data.size() == 1 + sizeof(coord_type));
|
||||
cons.skew_y(data.coord_at(1));
|
||||
break;
|
||||
//-----------------------------------------------------------------
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
//---------------------------------------------------------------------
|
||||
void set_fill (const data_accessor_type&);
|
||||
//---------------------------------------------------------------------
|
||||
void set_stroke(const data_accessor_type&);
|
||||
//---------------------------------------------------------------------
|
||||
void set_fill_for_id (data_accessor_type);
|
||||
void set_stroke_for_id(data_accessor_type);
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
attributes& m_attributes;
|
||||
rendering_interpreter* m_interpreter;
|
||||
};
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_ATTRIBUTES_SETTER_INCLUDE
|
||||
72
DesktopEditor/agg-2.4/svg/agg_svg_basics.h
Normal file
72
DesktopEditor/agg-2.4/svg/agg_svg_basics.h
Normal file
@ -0,0 +1,72 @@
|
||||
#ifndef AGG_SVG_BASICS_INCLUDED
|
||||
#define AGG_SVG_BASICS_INCLUDED
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
#include "agg_array.h"
|
||||
#include "agg_pixfmt_rgba.h"
|
||||
#include "platform/agg_platform_support.h"
|
||||
#include "agg_svg_defines.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
// The main container used to store binary SVG data
|
||||
typedef agg::pod_bvector<agg::int8u,14> data_container;
|
||||
//-------------------------------------------------------------------------
|
||||
template<class Container> class data_accessor;
|
||||
//-------------------------------------------------------------------------
|
||||
typedef data_accessor<data_container> data_accessor_type;
|
||||
//-------------------------------------------------------------------------
|
||||
typedef double coord_type;
|
||||
//-------------------------------------------------------------------------
|
||||
typedef char char_type;
|
||||
//-------------------------------------------------------------------------
|
||||
const pix_format_e pix_format = agg::pix_format_bgra32;
|
||||
//-------------------------------------------------------------------------
|
||||
typedef agg::rgba8 color_type;
|
||||
typedef agg::pixel32_type pixel_type;
|
||||
typedef agg::order_bgra component_order;
|
||||
typedef agg::rect_d rectangle;
|
||||
//-------------------------------------------------------------------------
|
||||
struct length
|
||||
{
|
||||
coord_type value;
|
||||
units2_e unit;
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
typedef length coordinate;
|
||||
//-------------------------------------------------------------------------
|
||||
typedef agg::pod_auto_array<color_type, 256> gradient_lut_type;
|
||||
//-------------------------------------------------------------------------
|
||||
struct string_comparer
|
||||
{
|
||||
bool operator()(const char* lhs, const char* rhs) const
|
||||
{
|
||||
using namespace std;
|
||||
return strcmp(lhs, rhs) < 0;
|
||||
}
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
struct string_n_comparer
|
||||
{
|
||||
string_n_comparer(unsigned len) : m_len(len) {}
|
||||
|
||||
bool operator()(const char* lhs, const char* rhs) const
|
||||
{
|
||||
using namespace std;
|
||||
return strncmp(lhs, rhs, m_len) < 0;
|
||||
}
|
||||
|
||||
unsigned m_len;
|
||||
};
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // ifndef AGG_SVG_BASICS_INCLUDED
|
||||
|
||||
573
DesktopEditor/agg-2.4/svg/agg_svg_color_parser.cpp
Normal file
573
DesktopEditor/agg-2.4/svg/agg_svg_color_parser.cpp
Normal file
@ -0,0 +1,573 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_svg_color_parser.h"
|
||||
#include "agg_svg_utils.h"
|
||||
#include <cstdlib> // for wcstombs
|
||||
#include <cstring>
|
||||
#include "agg_svg_basics.h"
|
||||
#include "agg_svg_exception.h"
|
||||
#include "member_comparer.h"
|
||||
#include <utility>
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
VEC_COLOR_RGBA color_parser::m_colors_to_rgba;
|
||||
VEC_ULONG_COLOR color_parser::m_ulong_to_colors;
|
||||
//-------------------------------------------------------------------------
|
||||
const char* color_parser::m_input_str = init();
|
||||
//-------------------------------------------------------------------------
|
||||
namespace
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
inline unsigned long make_color(unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b)
|
||||
{
|
||||
return (unsigned long)(r) |
|
||||
(unsigned long)(g) << 8 |
|
||||
(unsigned long)(b) << 16;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
template <class T>
|
||||
struct find_result
|
||||
{
|
||||
typedef std::pair<typename T::iterator, typename T::iterator> type;
|
||||
};
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
#define ADD_COLOR( COLOR, R, G, B )\
|
||||
m_colors_to_rgba.push_back( VEC_COLOR_RGBA::value_type(COLOR,agg::rgba8(R,G,B)) );\
|
||||
m_ulong_to_colors.push_back(VEC_ULONG_COLOR::value_type(make_color(R, G, B), COLOR));
|
||||
//-------------------------------------------------------------------------
|
||||
const char* color_parser::init()
|
||||
{
|
||||
m_colors_to_rgba.reserve( 150 );
|
||||
m_ulong_to_colors.reserve( 150 );
|
||||
|
||||
ADD_COLOR( "aliceblue", 240, 248, 255);
|
||||
ADD_COLOR( "antiquewhite", 250, 235, 215);
|
||||
ADD_COLOR( "aqua", 0, 255, 255);
|
||||
ADD_COLOR( "aquamarine", 127, 255, 212);
|
||||
ADD_COLOR( "azure", 240, 255, 255);
|
||||
ADD_COLOR( "beige", 245, 245, 220);
|
||||
ADD_COLOR( "bisque", 255, 228, 196);
|
||||
ADD_COLOR( "black", 0, 0, 0);
|
||||
ADD_COLOR( "blanchedalmond", 255, 235, 205);
|
||||
ADD_COLOR( "blue", 0, 0, 255);
|
||||
ADD_COLOR( "blueviolet", 138, 43, 226);
|
||||
ADD_COLOR( "brown", 165, 42, 42);
|
||||
ADD_COLOR( "burlywood", 222, 184, 135);
|
||||
ADD_COLOR( "cadetblue", 95, 158, 160);
|
||||
ADD_COLOR( "chartreuse", 127, 255, 0);
|
||||
ADD_COLOR( "chocolate", 210, 105, 30);
|
||||
ADD_COLOR( "coral", 255, 127, 80);
|
||||
ADD_COLOR( "cornflowerblue", 100, 149, 237);
|
||||
ADD_COLOR( "cornsilk", 255, 248, 220);
|
||||
ADD_COLOR( "crimson", 220, 20, 60);
|
||||
ADD_COLOR( "cyan", 0, 255, 255);
|
||||
ADD_COLOR( "darkblue", 0, 0, 139);
|
||||
ADD_COLOR( "darkcyan", 0, 139, 139);
|
||||
ADD_COLOR( "darkgoldenrod", 184, 134, 11);
|
||||
ADD_COLOR( "darkgray", 169, 169, 169);
|
||||
ADD_COLOR( "darkgreen", 0, 100, 0);
|
||||
ADD_COLOR( "darkgrey", 169, 169, 169);
|
||||
ADD_COLOR( "darkkhaki", 189, 183, 107);
|
||||
ADD_COLOR( "darkmagenta", 139, 0, 139);
|
||||
ADD_COLOR( "darkolivegreen", 85, 107, 47);
|
||||
ADD_COLOR( "darkorange", 255, 140, 0);
|
||||
ADD_COLOR( "darkorchid", 153, 50, 204);
|
||||
ADD_COLOR( "darkred", 139, 0, 0);
|
||||
ADD_COLOR( "darksalmon", 233, 150, 122);
|
||||
ADD_COLOR( "darkseagreen", 143, 188, 143);
|
||||
ADD_COLOR( "darkslateblue", 72, 61, 139);
|
||||
ADD_COLOR( "darkslategray", 47, 79, 79);
|
||||
ADD_COLOR( "darkslategrey", 47, 79, 79);
|
||||
ADD_COLOR( "darkturquoise", 0, 206, 209);
|
||||
ADD_COLOR( "darkviolet", 148, 0, 211);
|
||||
ADD_COLOR( "deeppink", 255, 20, 147);
|
||||
ADD_COLOR( "deepskyblue", 0, 191, 255);
|
||||
ADD_COLOR( "dimgray", 105, 105, 105);
|
||||
ADD_COLOR( "dimgrey", 105, 105, 105);
|
||||
ADD_COLOR( "dodgerblue", 30, 144, 255);
|
||||
ADD_COLOR( "firebrick", 178, 34, 34);
|
||||
ADD_COLOR( "floralwhite", 255, 250, 240);
|
||||
ADD_COLOR( "forestgreen", 34, 139, 34);
|
||||
ADD_COLOR( "fuchsia", 255, 0, 255);
|
||||
ADD_COLOR( "gainsboro", 220, 220, 220);
|
||||
ADD_COLOR( "ghostwhite", 248, 248, 255);
|
||||
ADD_COLOR( "gold", 255, 215, 0);
|
||||
ADD_COLOR( "goldenrod", 218, 165, 32);
|
||||
ADD_COLOR( "gray", 128, 128, 128);
|
||||
ADD_COLOR( "grey", 128, 128, 128);
|
||||
ADD_COLOR( "green", 0, 128, 0);
|
||||
ADD_COLOR( "greenyellow", 173, 255, 47);
|
||||
ADD_COLOR( "honeydew", 240, 255, 240);
|
||||
ADD_COLOR( "hotpink", 255, 105, 180);
|
||||
ADD_COLOR( "indianred", 205, 92, 92);
|
||||
ADD_COLOR( "indigo", 75, 0, 130);
|
||||
ADD_COLOR( "ivory", 255, 255, 240);
|
||||
ADD_COLOR( "khaki", 240, 230, 140);
|
||||
ADD_COLOR( "lavender", 230, 230, 250);
|
||||
ADD_COLOR( "lavenderblush", 255, 240, 245);
|
||||
ADD_COLOR( "lawngreen", 124, 252, 0);
|
||||
ADD_COLOR( "lemonchiffon", 255, 250, 205);
|
||||
ADD_COLOR( "lightblue", 173, 216, 230);
|
||||
ADD_COLOR( "lightcoral", 240, 128, 128);
|
||||
ADD_COLOR( "lightcyan", 224, 255, 255);
|
||||
ADD_COLOR( "lightgoldenrodyellow", 250, 250, 210);
|
||||
ADD_COLOR( "lightgray", 211, 211, 211);
|
||||
ADD_COLOR( "lightgreen", 144, 238, 144);
|
||||
ADD_COLOR( "lightgrey", 211, 211, 211);
|
||||
ADD_COLOR( "lightpink", 255, 182, 193);
|
||||
ADD_COLOR( "lightsalmon", 255, 160, 122);
|
||||
ADD_COLOR( "lightseagreen", 32, 178, 170);
|
||||
ADD_COLOR( "lightskyblue", 135, 206, 250);
|
||||
ADD_COLOR( "lightslategray", 119, 136, 153);
|
||||
ADD_COLOR( "lightslategrey", 119, 136, 153);
|
||||
ADD_COLOR( "lightsteelblue", 176, 196, 222);
|
||||
ADD_COLOR( "lightyellow", 255, 255, 224);
|
||||
ADD_COLOR( "lime", 0, 255, 0);
|
||||
ADD_COLOR( "limegreen", 50, 205, 50);
|
||||
ADD_COLOR( "linen", 250, 240, 230);
|
||||
ADD_COLOR( "magenta", 255, 0, 255);
|
||||
ADD_COLOR( "maroon", 128, 0, 0);
|
||||
ADD_COLOR( "mediumaquamarine", 102, 205, 170);
|
||||
ADD_COLOR( "mediumblue", 0, 0, 205);
|
||||
ADD_COLOR( "mediumorchid", 186, 85, 211);
|
||||
ADD_COLOR( "mediumpurple", 147, 112, 219);
|
||||
ADD_COLOR( "mediumseagreen", 60, 179, 113);
|
||||
ADD_COLOR( "mediumslateblue", 123, 104, 238);
|
||||
ADD_COLOR( "mediumspringgreen", 0, 250, 154);
|
||||
ADD_COLOR( "mediumturquoise", 72, 209, 204);
|
||||
ADD_COLOR( "mediumvioletred", 199, 21, 133);
|
||||
ADD_COLOR( "midnightblue", 25, 25, 112);
|
||||
ADD_COLOR( "mintcream", 245, 255, 250);
|
||||
ADD_COLOR( "mistyrose", 255, 228, 225);
|
||||
ADD_COLOR( "moccasin", 255, 228, 181);
|
||||
ADD_COLOR( "navajowhite", 255, 222, 173);
|
||||
ADD_COLOR( "navy", 0, 0, 128);
|
||||
ADD_COLOR( "oldlace", 253, 245, 230);
|
||||
ADD_COLOR( "olive", 128, 128, 0);
|
||||
ADD_COLOR( "olivedrab", 107, 142, 35);
|
||||
ADD_COLOR( "orange", 255, 165, 0);
|
||||
ADD_COLOR( "orangered", 255, 69, 0);
|
||||
ADD_COLOR( "orchid", 218, 112, 214);
|
||||
ADD_COLOR( "palegoldenrod", 238, 232, 170);
|
||||
ADD_COLOR( "palegreen", 152, 251, 152);
|
||||
ADD_COLOR( "paleturquoise", 175, 238, 238);
|
||||
ADD_COLOR( "palevioletred", 219, 112, 147);
|
||||
ADD_COLOR( "papayawhip", 255, 239, 213);
|
||||
ADD_COLOR( "peachpuff", 255, 218, 185);
|
||||
ADD_COLOR( "peru", 205, 133, 63);
|
||||
ADD_COLOR( "pink", 255, 192, 203);
|
||||
ADD_COLOR( "plum", 221, 160, 221);
|
||||
ADD_COLOR( "powderblue", 176, 224, 230);
|
||||
ADD_COLOR( "purple", 128, 0, 128);
|
||||
ADD_COLOR( "red", 255, 0, 0);
|
||||
ADD_COLOR( "rosybrown", 188, 143, 143);
|
||||
ADD_COLOR( "royalblue", 65, 105, 225);
|
||||
ADD_COLOR( "paddlebrown", 139, 69, 19);
|
||||
ADD_COLOR( "palmon", 250, 128, 114);
|
||||
ADD_COLOR( "pandybrown", 244, 164, 96);
|
||||
ADD_COLOR( "peagreen", 46, 139, 87);
|
||||
ADD_COLOR( "peashell", 255, 245, 238);
|
||||
ADD_COLOR( "pienna", 160, 82, 45);
|
||||
ADD_COLOR( "pilver", 192, 192, 192);
|
||||
ADD_COLOR( "pkyblue", 135, 206, 235);
|
||||
ADD_COLOR( "plateblue", 106, 90, 205);
|
||||
ADD_COLOR( "plategray", 112, 128, 144);
|
||||
ADD_COLOR( "plategrey", 112, 128, 144);
|
||||
ADD_COLOR( "pnow", 255, 250, 250);
|
||||
ADD_COLOR( "ppringgreen", 0, 255, 127);
|
||||
ADD_COLOR( "pteelblue", 70, 130, 180);
|
||||
ADD_COLOR( "tan", 210, 180, 140);
|
||||
ADD_COLOR( "teal", 0, 128, 128);
|
||||
ADD_COLOR( "thistle", 216, 191, 216);
|
||||
ADD_COLOR( "tomato", 255, 99, 71);
|
||||
ADD_COLOR( "turquoise", 64, 224, 208);
|
||||
ADD_COLOR( "violet", 238, 130, 238);
|
||||
ADD_COLOR( "wheat", 245, 222, 179);
|
||||
ADD_COLOR( "white", 255, 255, 255);
|
||||
ADD_COLOR( "whitesmoke", 245, 245, 245);
|
||||
ADD_COLOR( "yellow", 255, 255, 0);
|
||||
ADD_COLOR( "yellowgreen", 154, 205, 50);
|
||||
|
||||
//--------------------------------------
|
||||
std::sort(
|
||||
m_colors_to_rgba.begin(),
|
||||
m_colors_to_rgba.end(),
|
||||
make_comparer(&VEC_COLOR_RGBA::value_type::first, string_comparer()));
|
||||
//--------------------------------------
|
||||
std::sort(
|
||||
m_ulong_to_colors.begin(),
|
||||
m_ulong_to_colors.end(),
|
||||
make_comparer(&VEC_ULONG_COLOR::value_type::first));
|
||||
//--------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-- parses color string represented in hex format ( for ex. #FFF or #FFFFFF )
|
||||
//-- return value - position where parser stopped
|
||||
const char* color_parser::parse_color_hex(const char* str, agg::rgba8& color)
|
||||
{
|
||||
unsigned c = 0u;
|
||||
unsigned r = 0u;
|
||||
unsigned g = 0u;
|
||||
unsigned b = 0u;
|
||||
color.a = 255;
|
||||
|
||||
//-- find the length hex-color in input str( i.e. find_first_not_of )
|
||||
int len = static_cast<int>(strspn( str, "#0123456789abcdefABCDEF" ));
|
||||
|
||||
switch( len )
|
||||
{
|
||||
|
||||
case 7: //-- format #FFFFFF consists of 7 chars
|
||||
|
||||
sscanf( str+1, "%6x", &c );
|
||||
color = agg::rgb8_packed(c);
|
||||
return str+7;
|
||||
|
||||
case 4: //-- format #FFF consists of 4 chars
|
||||
sscanf( str+1, "%1x", &r );
|
||||
sscanf( str+2, "%1x", &g );
|
||||
sscanf( str+3, "%1x", &b );
|
||||
|
||||
//-- convert format #FFF to #FFFFFF (every digit should be doubled)
|
||||
color.r = (16 * r) + r;
|
||||
color.g = (16 * g) + g;
|
||||
color.b = (16 * b) + b;
|
||||
return str+4;
|
||||
|
||||
default:
|
||||
// Output an error and return str+len as we cannot read it
|
||||
throw exception("[%s] is an invalid hex color format (expected '#FFF' or '#FFFFFF')", str);
|
||||
}//switch
|
||||
|
||||
}
|
||||
|
||||
//-- parses color string represented in rgb format ( for ex. rgba(255,255,255,1.0) )
|
||||
//-- return value - position where parser stopped
|
||||
const char* color_parser::parse_color_rgb( const char* str, agg::rgba8& color )
|
||||
{
|
||||
|
||||
bool rgba_format = false;
|
||||
|
||||
//-- check 'rgba' syntax
|
||||
if( str[ RGB_KEYWORD_LEN ] == 'a' && str[ RGB_KEYWORD_LEN + 1] == '(' )
|
||||
rgba_format = true;
|
||||
|
||||
//-- check 'rgb(' syntax
|
||||
if( !rgba_format && str[ RGB_KEYWORD_LEN ] != '(' )
|
||||
{
|
||||
throw exception("[%s] has a wrong syntax at position %i", str, RGB_KEYWORD_LEN+1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//pos to begin search
|
||||
str += ( rgba_format ? RGB_KEYWORD_LEN + 2 : RGB_KEYWORD_LEN + 1 );
|
||||
|
||||
color.r = get_next_rgb_value( str, ',' );
|
||||
color.g = get_next_rgb_value( str, ',' );
|
||||
|
||||
if( rgba_format )
|
||||
{
|
||||
color.b = get_next_rgb_value( str, ',' );
|
||||
color.a = static_cast<unsigned char>( 255 * get_opacity_value(str) + 0.5 );
|
||||
}
|
||||
else
|
||||
{
|
||||
color.b = get_next_rgb_value( str, ')' );
|
||||
color.a = 255;
|
||||
}
|
||||
|
||||
return str;
|
||||
|
||||
}
|
||||
|
||||
//--reads next RGB value from str, using stop_sign as delimiter
|
||||
unsigned char color_parser::get_next_rgb_value( const char*& str, char stop_sign )
|
||||
{
|
||||
bool value_is_percent = false;
|
||||
|
||||
int value = extract_next_value( str, stop_sign, value_is_percent, 0 );
|
||||
|
||||
if( value_is_percent )
|
||||
value = value * 255/100; //--handle percents
|
||||
|
||||
if( value < 0 || value > 255 )
|
||||
{
|
||||
throw exception("[%s] - the value %i is out of range [0,255]", m_input_str, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
//--reads opacity value from str
|
||||
//--returns value in range [ 0.0 - 1.0 ]
|
||||
float color_parser::get_opacity_value( const char*& str )
|
||||
{
|
||||
|
||||
bool value_is_percent = false;
|
||||
float fValue = extract_next_value( str, ')', value_is_percent, 0.0f, "%3f" );
|
||||
|
||||
if( value_is_percent )
|
||||
{
|
||||
throw exception("[%s] - percents are not allowed in opacity values [%f%%]", m_input_str, fValue);
|
||||
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
//-- check bounds
|
||||
if( fValue < 0.0f ) fValue = 0.0f;
|
||||
if( fValue > 1.0f ) fValue = 1.0f;
|
||||
|
||||
return fValue;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-- parses input string and fills rgba structure.
|
||||
//-- returns pointer where the parser stopped.
|
||||
const char* color_parser::parse_color( const char* str, agg::rgba8& color )
|
||||
{
|
||||
assert( str != 0 );
|
||||
|
||||
m_input_str = str;
|
||||
|
||||
left_trim( str );
|
||||
|
||||
//if( strlen(str) < 4 ) // at least 4 signs in #FFF format ( all other formats are longer )
|
||||
// throw exception( "[%s]- wrong syntax : too short input string", str );
|
||||
|
||||
if( str_starts(str, '#') )
|
||||
return parse_color_hex( str, color );
|
||||
|
||||
if( str_starts(str,RGB_KEYWORD) ) //-- check if string begins with "rgb"
|
||||
return parse_color_rgb( str, color );
|
||||
|
||||
//-- assume that we have keyword i.e. named color
|
||||
|
||||
//-- find where is the end of keyword in input str(i.e. find_first_not_of)
|
||||
int pos = static_cast<int>(strspn( str, "abcdefghigklmnopqrstuvwxyz" ));
|
||||
|
||||
if( pos == 0 )
|
||||
{
|
||||
throw exception("[%s] is an unknown color or value or can not be parsed", str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// lets try to find this color in named colors vector
|
||||
VEC_COLOR_RGBA::iterator it;
|
||||
|
||||
it = std::lower_bound(m_colors_to_rgba.begin(),
|
||||
m_colors_to_rgba.end(),
|
||||
str,
|
||||
make_comparer
|
||||
(
|
||||
&VEC_COLOR_RGBA::value_type::first,
|
||||
string_n_comparer(pos)
|
||||
));
|
||||
|
||||
if( it == m_colors_to_rgba.end() )
|
||||
{
|
||||
throw exception("[%s] is an unknown color name (lowercase?)", str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
color = it->second;
|
||||
|
||||
return str + pos;
|
||||
}
|
||||
|
||||
|
||||
//-- parses input string and fills rgba structure.
|
||||
//-- returns pointer where the parser stopped.
|
||||
const wchar_t* color_parser::parse_color( const wchar_t* wstr, agg::rgba8& color )
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
char szBuf[ 256 ];
|
||||
|
||||
size_t nLen = wcslen(wstr);
|
||||
|
||||
if( nLen != wcstombs( szBuf, wstr, nLen + 1 ) )
|
||||
{
|
||||
throw exception("[%s] is an invalid color string", to_str(wstr).c_str());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return wstr + ( parse_color(szBuf, color) - szBuf );
|
||||
}
|
||||
|
||||
|
||||
agg::rgba8 color_parser::parse_str( const char* str )
|
||||
{
|
||||
agg::rgba8 color(0, 0, 0, 0);
|
||||
parse_color( str, color );
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
//-- extracts next value from string ( R , G, B or Opacity )
|
||||
template<class T>
|
||||
T color_parser::extract_next_value(
|
||||
const char*& str, char stop_sign, bool& value_is_percent,
|
||||
T dummy, const char* fmt )
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
//STATIC_ASSERT(
|
||||
assert( sizeof(T) == sizeof(int) || sizeof(T) == sizeof(float) );
|
||||
// Extract_next_value_supports_only_int_and_float )
|
||||
|
||||
|
||||
value_is_percent = false;
|
||||
|
||||
//--find value start position ( find_first_of )
|
||||
int pos_value_begin = static_cast<int>(strcspn( str, " -0123456789" ));
|
||||
|
||||
if( pos_value_begin != 0 )
|
||||
{
|
||||
throw exception("[%s] has a wrong syntax at position %i", m_input_str, str-m_input_str+1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
left_trim( str );//-- skip leading spaces
|
||||
|
||||
//--find value stop position
|
||||
const char * p = strchr( str, stop_sign );
|
||||
|
||||
if( p == 0 )
|
||||
{
|
||||
throw exception("[%s] found, [%c] expected", m_input_str, stop_sign);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( *(p-1) == '%' ) //if value is a percent
|
||||
value_is_percent = true;
|
||||
|
||||
T value;
|
||||
int res = sscanf( str, fmt, &value );
|
||||
|
||||
if( res != 1 )
|
||||
{
|
||||
throw exception("[%s] - value [%s] can not be converted", m_input_str, str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
str = p+1; //--go to next value in str
|
||||
|
||||
return value;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
//-- from given numbers (r,g,b,a) composes the ASCII-string of the color
|
||||
std::string color_parser::compose_color_string(unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b,
|
||||
unsigned char a)
|
||||
{
|
||||
float fOpacity = 0.01f * ( 0.5f + (a / 255.0f) * 100.f);
|
||||
|
||||
if (a != 255)
|
||||
{
|
||||
// !EVC FIX: No std::ostringstream on WindowsCe
|
||||
char buf[1024];
|
||||
unsigned r_ = r;
|
||||
unsigned g_ = g;
|
||||
unsigned b_ = b;
|
||||
sprintf(buf, "rgba(%d,%d,%d,%.1f)", r_, g_, b_, fOpacity);
|
||||
return std::string(buf);
|
||||
/*
|
||||
std::ostringstream oss;
|
||||
oss << "rgba(" << (int)r << "," << (int)g << "," << (int)b << "," << fOpacity << ")";
|
||||
return oss.str();
|
||||
*/
|
||||
}
|
||||
|
||||
unsigned long ulColor = ((unsigned long)(r) | (unsigned long)(g) << 8 | (unsigned long)(b) << 16 );
|
||||
|
||||
// lets try to find this color in color keywords vector
|
||||
std::pair<VEC_ULONG_COLOR::iterator, VEC_ULONG_COLOR::iterator>
|
||||
result =
|
||||
std::equal_range(m_ulong_to_colors.begin(),
|
||||
m_ulong_to_colors.end(),
|
||||
ulColor,
|
||||
make_comparer
|
||||
(
|
||||
&VEC_ULONG_COLOR::value_type::first,
|
||||
std::less<VEC_ULONG_COLOR::value_type::first_type>()
|
||||
));
|
||||
if (result.first != result.second)
|
||||
return result.first->second;
|
||||
|
||||
char szColor[8];
|
||||
|
||||
//-- if we have double digits like #FFFFFF - we should
|
||||
//-- return string in short hex format( #FFF )
|
||||
if( (r & 0x0F) == (r >> 4) && (g & 0x0F) == (g >> 4) && (b & 0x0F) == (b >> 4) )
|
||||
{
|
||||
r = (r >> 4);
|
||||
g = (g >> 4);
|
||||
b = (b >> 4);
|
||||
|
||||
int ret = sprintf( szColor, "#%x%x%x" , r,g,b );
|
||||
assert( 4 == ret );
|
||||
|
||||
}else
|
||||
{
|
||||
int ret = sprintf( szColor, "#%02x%02x%02x" , r,g,b );
|
||||
assert( 7 == ret);
|
||||
}
|
||||
|
||||
return std::string( szColor );
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
//-- from given numbers (r,g,b,a) composes the ASCII-string of the color
|
||||
std::string color_parser::compose_color_string(unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b)
|
||||
{
|
||||
unsigned long color = make_color(r, g, b);
|
||||
|
||||
// lets try to find this color in color keywords vector
|
||||
find_result<VEC_ULONG_COLOR>::type result;
|
||||
result = std::equal_range
|
||||
(
|
||||
m_ulong_to_colors.begin(),
|
||||
m_ulong_to_colors.end(),
|
||||
color,
|
||||
make_comparer
|
||||
(
|
||||
&VEC_ULONG_COLOR::value_type::first,
|
||||
std::less<VEC_ULONG_COLOR::value_type::first_type>()
|
||||
)
|
||||
);
|
||||
|
||||
if (result.first != result.second)
|
||||
return result.first->second;
|
||||
|
||||
char buf[1024];
|
||||
unsigned r_ = r;
|
||||
unsigned g_ = g;
|
||||
unsigned b_ = b;
|
||||
sprintf(buf, "rgb(%d,%d,%d)", r_, g_, b_);
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
} // namespace svg
|
||||
}
|
||||
80
DesktopEditor/agg-2.4/svg/agg_svg_color_parser.h
Normal file
80
DesktopEditor/agg-2.4/svg/agg_svg_color_parser.h
Normal file
@ -0,0 +1,80 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef AGG_SVG_COLOR_PARSER_INCLUDED
|
||||
#define AGG_SVG_COLOR_PARSER_INCLUDED
|
||||
//-----------------------------------------------------------------------------
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1300
|
||||
#pragma warning( disable : 4786 ) // ident trunc to '255' chars in debug info
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_svg_basics.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
//-----------------------------------------------------------------------------
|
||||
#define RGB_KEYWORD "rgb"
|
||||
#define RGB_KEYWORD_LEN sizeof(RGB_KEYWORD)-1
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
typedef std::vector<std::pair<const char*,agg::rgba8> > VEC_COLOR_RGBA;
|
||||
typedef std::vector<std::pair<unsigned long,const char*> > VEC_ULONG_COLOR;
|
||||
//-------------------------------------------------------------------------
|
||||
class color_parser
|
||||
{
|
||||
public:
|
||||
static agg::rgba8 parse_str(const char* str);
|
||||
|
||||
//-- parses input string and fills agg::rgba8 structure.
|
||||
//-- returns pointer where the parser stopped.
|
||||
static const char* parse_color( const char* str, agg::rgba8& color );
|
||||
static const wchar_t* parse_color( const wchar_t* str, agg::rgba8& color );
|
||||
|
||||
//-- from given numbers (r,g,b,a) composes the ASCII-string of the color
|
||||
static std::string compose_color_string(unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b,
|
||||
unsigned char a);
|
||||
//-- from given numbers (r,g,b,a) composes the ASCII-string of the color
|
||||
static std::string compose_color_string(unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b);
|
||||
|
||||
private:
|
||||
|
||||
//-- parses color string represented in hex format ( #FFF or #FFFFFF )
|
||||
static const char* parse_color_hex( const char* str, agg::rgba8& color );
|
||||
|
||||
//-- parses color string represented in rgb format( ex: rgba(255,255,255,1.0) )
|
||||
static const char* parse_color_rgb( const char* str, agg::rgba8& color );
|
||||
|
||||
//-- reads next RGB value from str, using stop_sign as delimiter
|
||||
static unsigned char get_next_rgb_value( const char*& str, char stop_sign );
|
||||
|
||||
//-- reads opacity value from str
|
||||
static float get_opacity_value( const char*& str );
|
||||
|
||||
//-- extracts next value from str ( R, G, B or Opacity )
|
||||
template<class T>
|
||||
static T extract_next_value(
|
||||
const char*& str, char stop_sign, bool& value_is_percent,
|
||||
T dummy, const char* fmt="%3d" );
|
||||
|
||||
static const char* init();
|
||||
|
||||
private:
|
||||
static const char* m_input_str;
|
||||
|
||||
static VEC_COLOR_RGBA m_colors_to_rgba;
|
||||
static VEC_ULONG_COLOR m_ulong_to_colors;
|
||||
|
||||
};//color_parser class
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_COLOR_PARSER_INCLUDED
|
||||
|
||||
222
DesktopEditor/agg-2.4/svg/agg_svg_data_accessor.h
Normal file
222
DesktopEditor/agg-2.4/svg/agg_svg_data_accessor.h
Normal file
@ -0,0 +1,222 @@
|
||||
#ifndef AGG_SVG_DATA_ACCESSOR_INCLUDED
|
||||
#define AGG_SVG_DATA_ACCESSOR_INCLUDED
|
||||
|
||||
#include "agg_svg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
// Data accessor. An analog of a simple const pointer or an iterator used with
|
||||
// plain arrays or standard containers.
|
||||
template<class Container> class data_accessor
|
||||
{
|
||||
public:
|
||||
typedef Container container_type;
|
||||
typedef typename container_type::value_type value_type;
|
||||
//------------------------------------------------------------------------
|
||||
data_accessor() : m_container(0), m_pos(0), m_size(0) {}
|
||||
data_accessor(const container_type& c) :
|
||||
m_container(&c), m_pos(0), m_size(c.size()) {}
|
||||
data_accessor(const container_type& c, unsigned pos, unsigned size_) :
|
||||
m_container(&c), m_pos(pos), m_size(size_) {}
|
||||
|
||||
void reset()
|
||||
{
|
||||
m_container = 0;
|
||||
m_pos = 0;
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
void init(const container_type& c)
|
||||
{
|
||||
m_container = &c;
|
||||
m_pos = 0;
|
||||
m_size = c.size();
|
||||
}
|
||||
|
||||
void init(const container_type& c, unsigned pos, unsigned size_)
|
||||
{
|
||||
m_container = &c;
|
||||
m_pos = pos;
|
||||
m_size = size_;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
const container_type* container() const { return m_container; }
|
||||
|
||||
unsigned pos() const { return m_pos; }
|
||||
unsigned size() const { return m_size; }
|
||||
value_type value() const { return m_container->value_at(m_pos); }
|
||||
value_type operator * () const { return m_container->value_at(m_pos); }
|
||||
|
||||
value_type operator [] (unsigned i) const
|
||||
{
|
||||
return m_container->value_at(m_pos + i);
|
||||
}
|
||||
|
||||
value_type at(unsigned i) const
|
||||
{
|
||||
return m_container->value_at(m_pos + i);
|
||||
}
|
||||
|
||||
void inc()
|
||||
{
|
||||
++m_pos;
|
||||
--m_size;
|
||||
}
|
||||
|
||||
void operator ++ ()
|
||||
{
|
||||
++m_pos;
|
||||
--m_size;
|
||||
}
|
||||
|
||||
void operator += (unsigned n)
|
||||
{
|
||||
m_pos += n;
|
||||
m_size -= n;
|
||||
}
|
||||
|
||||
value_type read_value()
|
||||
{
|
||||
--m_size;
|
||||
return m_container->value_at(m_pos++);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <class T>
|
||||
double units_value(const T& attr) const
|
||||
{
|
||||
return attr.conv_units(double(coord_at(0)),
|
||||
units2_e(int8u_at(sizeof(coord_type))));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void value_at(unsigned i, char* v) const
|
||||
{
|
||||
*v = (char)at(i);
|
||||
}
|
||||
|
||||
void value_at(unsigned i, agg::int8* v) const
|
||||
{
|
||||
*v = (agg::int8)at(i);
|
||||
}
|
||||
|
||||
void value_at(unsigned i, agg::int8u* v) const
|
||||
{
|
||||
*v = (agg::int8u)at(i);
|
||||
}
|
||||
|
||||
void value_at(unsigned i, agg::int16* v) const
|
||||
{
|
||||
((agg::int8u*)v)[0] = at(i+0);
|
||||
((agg::int8u*)v)[1] = at(i+1);
|
||||
}
|
||||
|
||||
void value_at(unsigned i, agg::int16u* v) const
|
||||
{
|
||||
((agg::int8u*)v)[0] = at(i+0);
|
||||
((agg::int8u*)v)[1] = at(i+1);
|
||||
}
|
||||
|
||||
void value_at(unsigned i, agg::int32* v) const
|
||||
{
|
||||
((agg::int8u*)v)[0] = at(i+0);
|
||||
((agg::int8u*)v)[1] = at(i+1);
|
||||
((agg::int8u*)v)[2] = at(i+2);
|
||||
((agg::int8u*)v)[3] = at(i+3);
|
||||
}
|
||||
|
||||
void value_at(unsigned i, agg::int32u* v) const
|
||||
{
|
||||
((agg::int8u*)v)[0] = at(i+0);
|
||||
((agg::int8u*)v)[1] = at(i+1);
|
||||
((agg::int8u*)v)[2] = at(i+2);
|
||||
((agg::int8u*)v)[3] = at(i+3);
|
||||
}
|
||||
|
||||
void value_at(unsigned i, float* v) const
|
||||
{
|
||||
((agg::int8u*)v)[0] = at(i+0);
|
||||
((agg::int8u*)v)[1] = at(i+1);
|
||||
((agg::int8u*)v)[2] = at(i+2);
|
||||
((agg::int8u*)v)[3] = at(i+3);
|
||||
}
|
||||
|
||||
void value_at(unsigned i, double* v) const
|
||||
{
|
||||
((agg::int8u*)v)[0] = at(i+0);
|
||||
((agg::int8u*)v)[1] = at(i+1);
|
||||
((agg::int8u*)v)[2] = at(i+2);
|
||||
((agg::int8u*)v)[3] = at(i+3);
|
||||
((agg::int8u*)v)[4] = at(i+4);
|
||||
((agg::int8u*)v)[5] = at(i+5);
|
||||
((agg::int8u*)v)[6] = at(i+6);
|
||||
((agg::int8u*)v)[7] = at(i+7);
|
||||
}
|
||||
|
||||
void value_at(unsigned i, agg::rgba8* v) const
|
||||
{
|
||||
v->r = at(i+0);
|
||||
v->g = at(i+1);
|
||||
v->b = at(i+2);
|
||||
v->a = at(i+3);
|
||||
}
|
||||
|
||||
|
||||
template<class T> void read_value(T* v)
|
||||
{
|
||||
value_at(0, v);
|
||||
m_pos += sizeof(T);
|
||||
m_size -= sizeof(T);
|
||||
}
|
||||
|
||||
agg::int8 int8_at(unsigned i) const { return (agg::int8)at(i); }
|
||||
agg::int8u int8u_at(unsigned i) const { return (agg::int8u)at(i); }
|
||||
agg::int16 int16_at(unsigned i) const { agg::int16 v; value_at(i, &v); return v; }
|
||||
agg::int16u int16u_at(unsigned i) const { agg::int16u v; value_at(i, &v); return v; }
|
||||
agg::int32 int32_at(unsigned i) const { agg::int32 v; value_at(i, &v); return v; }
|
||||
agg::int32u int32u_at(unsigned i) const { agg::int32u v; value_at(i, &v); return v; }
|
||||
coord_type coord_at(unsigned i) const { coord_type v; value_at(i, &v); return v; }
|
||||
agg::rgba8 color_at(unsigned i) const { agg::rgba8 v; value_at(i, &v); return v; }
|
||||
|
||||
agg::int8 read_int8() { return (agg::int8)read_value(); }
|
||||
agg::int8u read_int8u() { return (agg::int8u)read_value(); }
|
||||
agg::int16 read_int16() { agg::int16 v; read_value(&v); return v; }
|
||||
agg::int16u read_int16u() { agg::int16u v; read_value(&v); return v; }
|
||||
agg::int32 read_int32() { agg::int32 v; read_value(&v); return v; }
|
||||
agg::int32u read_int32u() { agg::int32u v; read_value(&v); return v; }
|
||||
coord_type read_coord() { coord_type v; read_value(&v); return v; }
|
||||
agg::rgba8 read_rgba8() { agg::rgba8 v; read_value(&v); return v; }
|
||||
|
||||
private:
|
||||
const container_type* m_container;
|
||||
unsigned m_pos;
|
||||
unsigned m_size;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
template<class T1, class T2>
|
||||
inline
|
||||
bool operator<(data_accessor<T1> const & lhs, data_accessor<T2> const & rhs)
|
||||
{
|
||||
const agg::int32u count1 = lhs.size();
|
||||
const agg::int32u count2 = rhs.size();
|
||||
agg::int32u i = 0;
|
||||
agg::int32u j = 0;
|
||||
|
||||
for (; i < count1 && j < count2; ++i, ++j)
|
||||
if (lhs[i] < rhs[j])
|
||||
return true;
|
||||
else if (rhs[j] < lhs[i])
|
||||
return false;
|
||||
|
||||
return (i == count1 && j != count2);
|
||||
}
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_DATA_ACCESSOR_INCLUDED
|
||||
229
DesktopEditor/agg-2.4/svg/agg_svg_defines.h
Normal file
229
DesktopEditor/agg-2.4/svg/agg_svg_defines.h
Normal file
@ -0,0 +1,229 @@
|
||||
#ifndef AGG_SVG_DEFINES_INCLUDED
|
||||
#define AGG_SVG_DEFINES_INCLUDED
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
// Element types
|
||||
//-------------------------------------------------------------------------
|
||||
enum element_e
|
||||
{
|
||||
elem_circle,
|
||||
elem_clipPath,
|
||||
elem_defs,
|
||||
elem_ellipse,
|
||||
elem_g,
|
||||
elem_line,
|
||||
elem_linearGradient,
|
||||
elem_path,
|
||||
elem_polygon,
|
||||
elem_polyline,
|
||||
elem_radialGradient,
|
||||
elem_rect,
|
||||
elem_stop,
|
||||
elem_svg,
|
||||
elem_title,
|
||||
elem_use,
|
||||
|
||||
end_of_elements
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
enum attr_e
|
||||
{
|
||||
attr_color = 0,
|
||||
attr_cx,
|
||||
attr_cy,
|
||||
attr_d,
|
||||
attr_fill,
|
||||
attr_fill_color,
|
||||
attr_fill_gradient,
|
||||
attr_fill_opacity,
|
||||
attr_fill_rule,
|
||||
attr_fx,
|
||||
attr_fy,
|
||||
attr_gradientTransform,
|
||||
attr_gradientUnits,
|
||||
attr_height,
|
||||
attr_id,
|
||||
attr_object_bbox,
|
||||
attr_offset,
|
||||
attr_opacity,
|
||||
attr_points,
|
||||
attr_preserveAspectRatio,
|
||||
attr_r,
|
||||
attr_rx,
|
||||
attr_ry,
|
||||
attr_spreadMethod,
|
||||
attr_stop_color,
|
||||
attr_stop_opacity,
|
||||
attr_stroke,
|
||||
attr_stroke_color,
|
||||
attr_stroke_gradient,
|
||||
attr_stroke_linecap,
|
||||
attr_stroke_linejoin,
|
||||
attr_stroke_miterlimit,
|
||||
attr_stroke_opacity,
|
||||
attr_stroke_width,
|
||||
attr_style,
|
||||
attr_transform,
|
||||
attr_viewBox,
|
||||
attr_width,
|
||||
attr_x,
|
||||
attr_x1,
|
||||
attr_x2,
|
||||
attr_xlink_href,
|
||||
attr_y,
|
||||
attr_y1,
|
||||
attr_y2,
|
||||
|
||||
attr_bounds,
|
||||
|
||||
end_of_attr
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------uniform_scaling_e
|
||||
enum uniform_scaling_e
|
||||
{
|
||||
usc_none,
|
||||
usc_xMinYMin,
|
||||
usc_xMidYMin,
|
||||
usc_xMaxYMin,
|
||||
usc_xMinYMid,
|
||||
usc_xMidYMid,
|
||||
usc_xMaxYMid,
|
||||
usc_xMinYMax,
|
||||
usc_xMidYMax,
|
||||
usc_xMaxYMax
|
||||
};
|
||||
|
||||
//---------------------------------------------------------window_fit_logic_e
|
||||
enum window_fit_logic_e
|
||||
{
|
||||
window_meet,
|
||||
window_slice
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------paint_type_e
|
||||
enum paint_type_e
|
||||
{
|
||||
paint_none,
|
||||
paint_color,
|
||||
paint_currentColor,
|
||||
paint_gradient,
|
||||
paint_id
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------uri_type_e
|
||||
enum uri_type_e
|
||||
{
|
||||
uri_none,
|
||||
uri_id
|
||||
};
|
||||
//----------------------------------------------------------------gradient_e
|
||||
enum gradient_e
|
||||
{
|
||||
gradient_linear,
|
||||
gradient_radial
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------objectUnits_e
|
||||
enum objectUnits_e
|
||||
{
|
||||
objectUnits_userSpaceOnUse,
|
||||
objectUnits_objectBoundingBox,
|
||||
objectUnits_strokeWidth
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------spreadMethod_e
|
||||
enum spreadMethod_e
|
||||
{
|
||||
spreadMethod_pad,
|
||||
spreadMethod_reflect,
|
||||
spreadMethod_repeat
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------transform_e
|
||||
enum transform_e
|
||||
{
|
||||
transform_matrix,
|
||||
transform_translate,
|
||||
transform_rotate,
|
||||
transform_scale,
|
||||
transform_skew_x,
|
||||
transform_skew_y
|
||||
};
|
||||
|
||||
//----------------------------------------------------------stroke_linejoin_e
|
||||
enum stroke_linejoin_e
|
||||
{
|
||||
stroke_linejoin_miter = 0,
|
||||
stroke_linejoin_round = 1,
|
||||
stroke_linejoin_bevel = 2
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------stroke_linecap_e
|
||||
enum stroke_linecap_e
|
||||
{
|
||||
stroke_linecap_butt = 0,
|
||||
stroke_linecap_round = 1,
|
||||
stroke_linecap_square = 2
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------fill_rule_e
|
||||
enum fill_rule_e
|
||||
{
|
||||
fill_rule_nonzero = 0,
|
||||
fill_rule_evenodd = 1
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
enum units2_e
|
||||
{
|
||||
units_em, // The font size of the default font,
|
||||
// usually equivalent to the height of a character
|
||||
|
||||
units_ex, // The height of the letter x
|
||||
|
||||
units_px, // Pixels
|
||||
|
||||
units_pt,
|
||||
units_pt_x, // Points (1/72 of an inch)
|
||||
units_pt_y,
|
||||
|
||||
units_pc,
|
||||
units_pc_x, // Picas (1/6 of an inch)
|
||||
units_pc_y,
|
||||
|
||||
units_cm,
|
||||
units_cm_x, // Centimeters
|
||||
units_cm_y,
|
||||
|
||||
units_mm,
|
||||
units_mm_x, // Millimeters
|
||||
units_mm_y,
|
||||
|
||||
units_in,
|
||||
units_in_x, // Inches
|
||||
units_in_y,
|
||||
|
||||
units_percent, // Percent
|
||||
units_percent_x,
|
||||
units_percent_y,
|
||||
|
||||
units_deg, // Angle units
|
||||
units_grad,
|
||||
units_rad,
|
||||
};
|
||||
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
|
||||
#endif // ifndef AGG_SVG_DEFINES_INCLUDED
|
||||
|
||||
76
DesktopEditor/agg-2.4/svg/agg_svg_dom_read_protocol.cpp
Normal file
76
DesktopEditor/agg-2.4/svg/agg_svg_dom_read_protocol.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_svg_dom_read_protocol.h"
|
||||
#include "agg_svg_dom_storage.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
read_protocol::read_protocol(dom_storage const& dom)
|
||||
: m_storage(dom.storage())
|
||||
, m_size(dom.storage().size())
|
||||
, m_idx(0)
|
||||
{
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
tag_e read_protocol::read_tag()const
|
||||
{
|
||||
data_container::value_type val = m_storage[m_idx++];
|
||||
|
||||
tag_e tag = tag_e(val);
|
||||
|
||||
assert(tag < end_of_tags);
|
||||
|
||||
return tag;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void read_protocol::element_bin(agg::int32u* el_idx, element_e* code) const
|
||||
{
|
||||
*el_idx = m_idx - 1;
|
||||
*code = (element_e)m_storage[m_idx++];
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void read_protocol::attribute_bin(data_container const** cont,attr_e* type,
|
||||
agg::int32u* data_idx, agg::int32u* size)const
|
||||
{
|
||||
*type = (attr_e)m_storage[m_idx++];
|
||||
|
||||
data_accessor_type accessor(m_storage);
|
||||
|
||||
accessor.value_at(m_idx, size);
|
||||
m_idx += sizeof(agg::int32u);
|
||||
*data_idx = m_idx;
|
||||
m_idx += *size;
|
||||
*cont = &m_storage;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void read_protocol::attribute_bin_short(data_container const ** cont,
|
||||
attr_e* type,
|
||||
agg::int32u* data_idx, agg::int32u* size)const
|
||||
{
|
||||
*type = (attr_e)m_storage[m_idx++];
|
||||
|
||||
data_accessor_type accessor(m_storage);
|
||||
|
||||
*size = m_storage[m_idx++];
|
||||
*data_idx = m_idx;
|
||||
m_idx += *size;
|
||||
*cont = &m_storage;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void read_protocol::attribute_bin_byte(data_container const ** cont,
|
||||
attr_e* type,
|
||||
agg::int32u* data_idx)const
|
||||
{
|
||||
*type = (attr_e)m_storage[m_idx++];
|
||||
*cont = &m_storage;
|
||||
*data_idx = m_idx;
|
||||
++m_idx;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void read_protocol::end_element() const
|
||||
{
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
80
DesktopEditor/agg-2.4/svg/agg_svg_dom_read_protocol.h
Normal file
80
DesktopEditor/agg-2.4/svg/agg_svg_dom_read_protocol.h
Normal file
@ -0,0 +1,80 @@
|
||||
#ifndef AGG_SVG_DOM_STORAGE_READ_PROTOCOL_INCLUDE
|
||||
#define AGG_SVG_DOM_STORAGE_READ_PROTOCOL_INCLUDE
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_svg_basics.h"
|
||||
#include "agg_svg_defines.h"
|
||||
#include "agg_svg_tags.h"
|
||||
#include "agg_svg_iomemstream.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
class dom_storage;
|
||||
//-------------------------------------------------------------------------
|
||||
class read_protocol
|
||||
{
|
||||
private:
|
||||
read_protocol(read_protocol const&);
|
||||
read_protocol operator=(read_protocol const&);
|
||||
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
explicit read_protocol(dom_storage const&);
|
||||
//---------------------------------------------------------------------
|
||||
void rewind(agg::int32u idx);
|
||||
//---------------------------------------------------------------------
|
||||
bool end()const;
|
||||
//---------------------------------------------------------------------
|
||||
void unread(unsigned offset = 1) const;
|
||||
//---------------------------------------------------------------------
|
||||
agg::int32u current_location() const;
|
||||
//---------------------------------------------------------------------
|
||||
tag_e read_tag()const;
|
||||
//---------------------------------------------------------------------
|
||||
void element_bin(agg::int32u* idx, element_e* code)const;
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_bin(data_container const ** cont, attr_e* type,
|
||||
agg::int32u* data_idx, agg::int32u* size) const;
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_bin_short(data_container const ** cont, attr_e* type,
|
||||
agg::int32u* data_idx,agg::int32u* size)const;
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_bin_byte(data_container const ** cont, attr_e* type,
|
||||
agg::int32u* data_idx)const;
|
||||
//---------------------------------------------------------------------
|
||||
void end_element() const;
|
||||
//---------------------------------------------------------------------
|
||||
private:
|
||||
const data_container & m_storage;
|
||||
|
||||
agg::int32u m_size;
|
||||
mutable agg::int32u m_idx;
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
inline void read_protocol::rewind(agg::int32u idx)
|
||||
{
|
||||
m_idx = idx;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline bool read_protocol::end()const
|
||||
{
|
||||
return m_idx >= m_size;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline void read_protocol::unread(unsigned offset) const
|
||||
{
|
||||
m_idx -= offset;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline agg::int32u read_protocol::current_location() const
|
||||
{
|
||||
return m_idx;
|
||||
}
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_DOM_STORAGE_READ_PROTOCOL_INCLUDE
|
||||
|
||||
417
DesktopEditor/agg-2.4/svg/agg_svg_dom_storage.cpp
Normal file
417
DesktopEditor/agg-2.4/svg/agg_svg_dom_storage.cpp
Normal file
@ -0,0 +1,417 @@
|
||||
#include "agg_svg_dom_storage.h"
|
||||
#include "agg_svg_ptr_size_pair.h"
|
||||
#include "agg_svg_basics.h"
|
||||
#include "agg_svg_path_interpreter.h"
|
||||
#include "agg_bounding_rect.h"
|
||||
#include "agg_svg_rendering_interpreter.h"
|
||||
#include "agg_svg_attribute_source.h"
|
||||
#include "agg_svg_percent.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <cstring> // for std::strlen, std::memcpy
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace
|
||||
{
|
||||
bool find_attribute(agg::svg::read_protocol const& rp, agg::svg::attr_data& attr)
|
||||
{
|
||||
using namespace agg::svg;
|
||||
|
||||
attr_e attr_type = end_of_attr;
|
||||
agg::int32u data_size = 0u;
|
||||
bool find = false;
|
||||
|
||||
const data_container* cont = 0;
|
||||
agg::int32u data_idx = 0;
|
||||
|
||||
while (!rp.end())
|
||||
{
|
||||
tag_e tag = rp.read_tag();
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
case tag_attribute_bin_byte:
|
||||
rp.attribute_bin_byte(&cont, &attr_type, &data_idx);
|
||||
if (attr.code == attr_type)
|
||||
{
|
||||
attr.data.init(*cont, data_idx, 1);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case tag_attribute_bin:
|
||||
rp.attribute_bin(&cont, &attr_type, &data_idx, &data_size);
|
||||
if (attr.code == attr_type)
|
||||
{
|
||||
assert(!find);
|
||||
attr.data.init(*cont, data_idx, data_size);
|
||||
find = true;
|
||||
}
|
||||
break;
|
||||
case tag_attribute_bin_short:
|
||||
rp.attribute_bin_short(&cont, &attr_type, &data_idx, &data_size);
|
||||
if (attr.code == attr_type)
|
||||
{
|
||||
assert(!find);
|
||||
attr.data.init(*cont, data_idx, data_size);
|
||||
find = true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
rp.unread(1);
|
||||
return find;
|
||||
}
|
||||
}
|
||||
assert(false);
|
||||
return find;
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
namespace
|
||||
{
|
||||
void read_raw_data(data_container const & cont, agg::int8u* ptr,
|
||||
unsigned size, unsigned idx)
|
||||
{
|
||||
for (unsigned i = 0u; i < size; ++i)
|
||||
{
|
||||
*ptr++ = cont[idx++];
|
||||
}
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
iomemstream& operator<<(iomemstream& s, tag_e tag)
|
||||
{
|
||||
return s << (agg::int8u)tag;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
iomemstream& operator<<(iomemstream& s, attr_e attr)
|
||||
{
|
||||
return s << (agg::int8u)attr;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::start_element(element_e el)
|
||||
{
|
||||
m_storage << tag_element_bin << (agg::int8u)el;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::end_element()
|
||||
{
|
||||
m_storage << tag_end_element;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute(attr_e attr, const void * data,
|
||||
agg::int32u size)
|
||||
{
|
||||
assert(data && size);
|
||||
|
||||
if (size <= 255)
|
||||
{
|
||||
attribute_short(attr, data, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
agg::svg::attribute_bin src(attr, data, size);
|
||||
m_storage.add(src);
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute_short(attr_e attr, const void* data,
|
||||
agg::int8u size)
|
||||
{
|
||||
agg::svg::attribute_bin_short src(attr, data, size);
|
||||
m_storage.add(src);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute(attr_e attr, agg::int8u type,
|
||||
const void* data, agg::int32u size)
|
||||
{
|
||||
if (size <= 254)
|
||||
{
|
||||
attribute_short(attr, type, data, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
agg::svg::attribute_bin src(attr, type, data, size);
|
||||
m_storage.add(src);
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute_short(attr_e attr, agg::int8u type,
|
||||
const void* data, agg::int8u size)
|
||||
{
|
||||
agg::svg::attribute_bin_short src(attr, type, data, size);
|
||||
m_storage.add(src);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute_byte(attr_e attr, agg::int8u val)
|
||||
{
|
||||
agg::svg::attribute_byte src(attr, val);
|
||||
m_storage.add(src);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute_string(attr_e attr, const char* val)
|
||||
{
|
||||
using namespace std;
|
||||
attribute(attr, val, static_cast<agg::int32u>(strlen(val)));
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute(attr_e attr, const length & val)
|
||||
{
|
||||
m_storage << tag_attribute_bin_short
|
||||
<< attr
|
||||
<< agg::int8u(sizeof(coord_type) + 1);
|
||||
|
||||
m_storage.write(&val.value, sizeof(coord_type));
|
||||
m_storage << (agg::int8u)val.unit;
|
||||
|
||||
if (attr==attr_width)
|
||||
m_width = val.value;
|
||||
if (attr==attr_height)
|
||||
m_height = val.value;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute_numeric(attr_e attr, double val)
|
||||
{
|
||||
coord_type data = static_cast<coord_type>(val);
|
||||
attribute_short(attr, &data, sizeof(data));
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute_unsigned(attr_e attr, unsigned val)
|
||||
{
|
||||
attribute_short(attr, &val, sizeof(unsigned));
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute_percent(attr_e attr, double val)
|
||||
{
|
||||
attribute_numeric(attr, percent::encrypt(val));
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute(attr_e attr, const data_accessor_type & data)
|
||||
{
|
||||
if (data.size() <= 255u)
|
||||
{
|
||||
m_storage << tag_attribute_bin_short
|
||||
<< attr
|
||||
<< static_cast<agg::int8u>(data.size())
|
||||
<< data;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_storage << tag_attribute_bin << attr << data.size() << data;
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute_transform_matrix(double m0, double m1,
|
||||
double m2, double m3,
|
||||
double m4, double m5)
|
||||
{
|
||||
coord_type data[] = {coord_type(m0), coord_type(m1),
|
||||
coord_type(m2), coord_type(m3),
|
||||
coord_type(m4), coord_type(m5)};
|
||||
|
||||
attribute_short(attr_transform, transform_matrix, data, sizeof(data));
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute_transform_translate(double dx, double dy)
|
||||
{
|
||||
coord_type data[] = {coord_type(dx), coord_type(dy)};
|
||||
|
||||
attribute_short(attr_transform, transform_translate, data, sizeof(data));
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute_transform_rotate(double angle)
|
||||
{
|
||||
coord_type data = coord_type(angle);
|
||||
|
||||
attribute_short(attr_transform, transform_rotate, &data, sizeof(data));
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute_transform_rotate(double angle,
|
||||
double cx, double cy)
|
||||
{
|
||||
coord_type data[] = {coord_type(angle),
|
||||
coord_type(cx),
|
||||
coord_type(cy)};
|
||||
|
||||
attribute_short(attr_transform, transform_rotate, &data, sizeof(data));
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute_transform_scale(double s)
|
||||
{
|
||||
coord_type data = coord_type(s);
|
||||
|
||||
attribute_short(attr_transform, transform_scale, &data, sizeof(data));
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute_transform_scale(double sx, double sy)
|
||||
{
|
||||
coord_type data[] = {coord_type(sx), coord_type(sy)};
|
||||
|
||||
attribute_short(attr_transform, transform_scale, &data, sizeof(data));
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute_transform_skew_x(double sx)
|
||||
{
|
||||
coord_type data = coord_type(sx);
|
||||
|
||||
attribute_short(attr_transform, transform_skew_x, &data, sizeof(data));
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute_transform_skew_y(double sy)
|
||||
{
|
||||
coord_type data = coord_type(sy);
|
||||
|
||||
attribute_short(attr_transform, transform_skew_y, &data, sizeof(data));
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute_d_with_bounds(data_accessor_type data)
|
||||
{
|
||||
coord_type bounds[4];
|
||||
path_interpreter<data_accessor_type> p(data);
|
||||
agg::bounding_rect_single(p, 0,
|
||||
&bounds[0], &bounds[1],
|
||||
&bounds[2], &bounds[3]);
|
||||
attribute(attr_bounds, bounds, sizeof(bounds));
|
||||
attribute(attr_d, data);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::attribute_points_with_bounds(data_accessor_type data)
|
||||
{
|
||||
coord_type bounds[4];
|
||||
poly_interpreter<data_accessor_type> p(data, false);
|
||||
agg::bounding_rect_single(p, 0,
|
||||
&bounds[0], &bounds[1],
|
||||
&bounds[2], &bounds[3]);
|
||||
attribute(attr_bounds, bounds, sizeof(bounds));
|
||||
attribute(attr_points, data);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
data_accessor_type dom_storage::get_attr_specified_value(unsigned offset, attr_e code)const
|
||||
{
|
||||
attr_data attr;
|
||||
attr.code = code;
|
||||
|
||||
read_protocol rp(*this);
|
||||
rp.rewind(offset);
|
||||
|
||||
if (rp.read_tag() == tag_element_bin)
|
||||
{
|
||||
element_data el;
|
||||
el.clear();
|
||||
|
||||
rp.element_bin(&el.index, &el.code);
|
||||
|
||||
find_attribute(rp, attr);
|
||||
}
|
||||
return attr.data;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::push_element(const element_data& el,
|
||||
element_stack_type& element_stack) const
|
||||
{
|
||||
element_stack_data esd;
|
||||
|
||||
esd.index = el.index;
|
||||
esd.code = el.code;
|
||||
|
||||
element_stack.add(esd);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::pop_element(element_stack_type& element_stack) const
|
||||
{
|
||||
if (element_stack.size())
|
||||
{
|
||||
element_stack.remove_last();
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::proceed_attribute(attributes_type& attributes,
|
||||
traverse_buffer_type& traverse_buffer,
|
||||
element_data& el,
|
||||
attr_data& attr,
|
||||
data_container const& cont,
|
||||
agg::int32u data_idx,
|
||||
agg::int32u data_size) const
|
||||
{
|
||||
int i = -1;
|
||||
|
||||
switch (attr.code)
|
||||
{
|
||||
case attr_points:
|
||||
case attr_d:
|
||||
el.shape_data.init(cont, data_idx, data_size);
|
||||
break;
|
||||
|
||||
case attr_bounds:
|
||||
i = traverse_buffer.allocate_continuous_block(data_size);
|
||||
if (i < -1)
|
||||
{
|
||||
el.bounds = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
read_raw_data(cont, &traverse_buffer[i], data_size, data_idx);
|
||||
el.bounds = &traverse_buffer[i];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
attr.processed = false;
|
||||
attr.data.init(cont, data_idx, data_size);
|
||||
if (attributes.size() >= attributes.capacity())
|
||||
{
|
||||
attributes.resize(attributes.size() + 256);
|
||||
}
|
||||
attributes.add(attr);
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void dom_storage::collect_attributes(read_protocol const& rp,
|
||||
element_data& el, attributes_type& attributes,
|
||||
traverse_buffer_type& traverse_buffer) const
|
||||
{
|
||||
attr_data attr;
|
||||
unsigned data_idx;
|
||||
unsigned data_size;
|
||||
int i = -1;
|
||||
|
||||
const data_container* cont = 0;
|
||||
|
||||
attributes.remove_all();
|
||||
traverse_buffer.remove_all();
|
||||
|
||||
while (!rp.end())
|
||||
{
|
||||
tag_e tag = rp.read_tag();
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
default:
|
||||
el.attr = &attributes[0];
|
||||
el.num_attr = attributes.size();
|
||||
|
||||
rp.unread(1);
|
||||
return;
|
||||
case tag_attribute_bin:
|
||||
rp.attribute_bin(&cont, &attr.code, &data_idx, &data_size);
|
||||
proceed_attribute(attributes, traverse_buffer, el, attr, *cont, data_idx, data_size);
|
||||
break;
|
||||
|
||||
case tag_attribute_bin_short:
|
||||
rp.attribute_bin_short(&cont, &attr.code, &data_idx, &data_size);
|
||||
proceed_attribute(attributes, traverse_buffer, el, attr, *cont, data_idx, data_size);
|
||||
break;
|
||||
|
||||
case tag_attribute_bin_byte:
|
||||
rp.attribute_bin_byte(&cont, &attr.code, &data_idx);
|
||||
proceed_attribute(attributes, traverse_buffer, el, attr, *cont, data_idx, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
278
DesktopEditor/agg-2.4/svg/agg_svg_dom_storage.h
Normal file
278
DesktopEditor/agg-2.4/svg/agg_svg_dom_storage.h
Normal file
@ -0,0 +1,278 @@
|
||||
#ifndef AGG_SVG_DOM_STORAGE_INCLUDE
|
||||
#define AGG_SVG_DOM_STORAGE_INCLUDE
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_svg_defines.h"
|
||||
#include "agg_svg_basics.h"
|
||||
#include "agg_svg_tags.h"
|
||||
#include "agg_svg_dom_read_protocol.h"
|
||||
#include "agg_svg_assoc_pod_array.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
// Attribute data. If the attribute is known, it has valid "code"
|
||||
// (see enum attr_e). If it's unknown, its "code" has value
|
||||
// "end_of_attributes".
|
||||
// Fields "data" represent raw attribute data;
|
||||
// its interpretation depends on the attribute.
|
||||
//
|
||||
//----------------------------------------------------------------------
|
||||
struct attr_data
|
||||
{
|
||||
bool processed;
|
||||
|
||||
attr_e code;
|
||||
data_accessor_type data;
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
// Element data. Field "index" defines the starting index in the array
|
||||
// where the element begins.
|
||||
// If the attribute is known, it has valid "code"
|
||||
// (see enum element_e). If it's unknown,
|
||||
// its code has value "end_of_elements".
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
struct element_data
|
||||
{
|
||||
agg::int32u index;
|
||||
element_e code;
|
||||
const agg::int8u* bounds;
|
||||
attr_data* attr;
|
||||
unsigned num_attr;
|
||||
|
||||
data_accessor_type shape_data;
|
||||
|
||||
void clear()
|
||||
{
|
||||
index = 0u;
|
||||
code = end_of_elements;
|
||||
bounds = 0;
|
||||
attr = 0;
|
||||
num_attr = 0u;
|
||||
shape_data.reset();
|
||||
}
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
template <class DataAccessor>
|
||||
struct data_accessor_compare
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
typedef data_accessor<agg::pod_array_adaptor<char const> > string_type;
|
||||
//---------------------------------------------------------------------
|
||||
bool operator()(const DataAccessor& lhs, const DataAccessor& rhs)const
|
||||
{
|
||||
return lhs < rhs;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
bool operator()(const DataAccessor& lhs, const string_type& rhs)const
|
||||
{
|
||||
return lhs < rhs;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
bool operator()(const string_type& lhs, const DataAccessor& rhs)const
|
||||
{
|
||||
return lhs < rhs;
|
||||
}
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
class dom_storage
|
||||
{
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
struct element_location
|
||||
{
|
||||
agg::int32u idx;
|
||||
element_e code;
|
||||
};
|
||||
|
||||
typedef assoc_pod_array
|
||||
<
|
||||
data_accessor_type,
|
||||
element_location,
|
||||
data_accessor_compare<data_accessor_type>
|
||||
> map_type;
|
||||
//---------------------------------------------------------------------
|
||||
void clear()
|
||||
{
|
||||
m_storage.clear();
|
||||
m_width = m_height = 0;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void start_element(element_e);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute(attr_e, const void* data, agg::int32u size);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute(attr_e, agg::int8u type, const void* data, agg::int32u);
|
||||
//---------------------------------------------------------------------
|
||||
template<class T>
|
||||
void attribute_datatype(attr_e attr, const T& data)
|
||||
{
|
||||
attribute(attr, &data, sizeof(data));
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
template<class T>
|
||||
void attribute_datatype(attr_e attr, agg::int8u type, const T& data)
|
||||
{
|
||||
attribute(attr, type, &data, sizeof(data));
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void attribute(attr_e, const data_accessor_type &);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_byte(attr_e, agg::int8u val);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_string(attr_e attr, const char* val);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute(attr_e attr, const length & val);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_numeric(attr_e, double val);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_unsigned(attr_e, unsigned val);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_percent(attr_e attr, double val);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_transform_matrix(double m0, double m1, double m2,
|
||||
double m3, double m4, double m5);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_transform_translate(double dx, double dy);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_transform_rotate(double angle);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_transform_rotate(double angle, double cx, double cy);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_transform_scale(double s);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_transform_scale(double sx, double sy);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_transform_skew_x(double sx);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_transform_skew_y(double sy);
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_d_with_bounds(data_accessor_type data);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_points_with_bounds(data_accessor_type data);
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
void end_element();
|
||||
//---------------------------------------------------------------------
|
||||
const data_container & storage()const { return m_storage.buffer(); }
|
||||
data_container & storage() { return m_storage.buffer(); }
|
||||
//---------------------------------------------------------------------
|
||||
data_accessor_type get_attr_specified_value(unsigned offset, attr_e code)const;
|
||||
//---------------------------------------------------------------------
|
||||
private:
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_short(attr_e, const void* data, agg::int8u size);
|
||||
//---------------------------------------------------------------------
|
||||
void attribute_short(attr_e, agg::int8u type,
|
||||
const void* data, agg::int8u size);
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
//---------------------------------------------------------------------
|
||||
struct element_stack_data
|
||||
{
|
||||
unsigned index;
|
||||
element_e code;
|
||||
};
|
||||
//---------------------------------------------------------------------
|
||||
typedef agg::pod_bvector<element_stack_data, 5> element_stack_type;
|
||||
//---------------------------------------------------------------------
|
||||
void push_element(const element_data&, element_stack_type&) const;
|
||||
//---------------------------------------------------------------------
|
||||
void pop_element(element_stack_type&) const;
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
typedef agg::pod_vector<attr_data> attributes_type;
|
||||
typedef agg::pod_bvector<agg::int8u, 10> traverse_buffer_type;
|
||||
//---------------------------------------------------------------------
|
||||
void collect_attributes(read_protocol const& rp,
|
||||
element_data& el,
|
||||
attributes_type& attributes,
|
||||
traverse_buffer_type& traverse_buffer) const;
|
||||
//---------------------------------------------------------------------
|
||||
void proceed_attribute(attributes_type& attributes,
|
||||
traverse_buffer_type& traverse_buffer,
|
||||
element_data& el,
|
||||
attr_data& attr,
|
||||
data_container const& cont,
|
||||
agg::int32u data_idx,
|
||||
agg::int32u data_size) const;
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
template <class Consumer>
|
||||
agg::int32u traverse(Consumer& cons, agg::int32u idx = 0) const
|
||||
{
|
||||
traverse_buffer_type traverse_buffer(32);
|
||||
element_stack_type element_stack(32);
|
||||
attributes_type attributes(256);
|
||||
element_data el;
|
||||
const data_container* cont = 0;
|
||||
agg::int32u data_idx = 0u;
|
||||
agg::int32u data_size = 0u;
|
||||
bool not_done = true;
|
||||
read_protocol rp(*this);
|
||||
|
||||
rp.rewind(idx);
|
||||
|
||||
while (not_done && !rp.end())
|
||||
{
|
||||
tag_e tag = rp.read_tag();
|
||||
switch (tag)
|
||||
{
|
||||
case tag_end_element:
|
||||
el.clear();
|
||||
|
||||
rp.end_element();
|
||||
|
||||
if (element_stack.size())
|
||||
{
|
||||
const element_stack_data& esd = element_stack.last();
|
||||
el.index = esd.index;
|
||||
el.code = esd.code;
|
||||
}
|
||||
not_done = cons.end_element(*this, el);
|
||||
pop_element(element_stack);
|
||||
if (element_stack.size() == 0) not_done = false;
|
||||
break;
|
||||
|
||||
case tag_element_bin:
|
||||
el.clear();
|
||||
rp.element_bin(&el.index, &el.code);
|
||||
collect_attributes(rp, el, attributes, traverse_buffer);
|
||||
push_element(el, element_stack);
|
||||
not_done = cons.start_element(*this, el);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
return rp.current_location();
|
||||
}
|
||||
|
||||
private:
|
||||
iomemstream m_storage;
|
||||
|
||||
/***************************************************************************/
|
||||
private:
|
||||
double m_width;
|
||||
double m_height;
|
||||
public:
|
||||
double get_width() const {return m_width;};
|
||||
double get_height() const {return m_height;};
|
||||
};
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_DOM_STORAGE_INCLUDE
|
||||
|
||||
50
DesktopEditor/agg-2.4/svg/agg_svg_exception.h
Normal file
50
DesktopEditor/agg-2.4/svg/agg_svg_exception.h
Normal file
@ -0,0 +1,50 @@
|
||||
#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
|
||||
107
DesktopEditor/agg-2.4/svg/agg_svg_frame_buffer_rgba.h
Normal file
107
DesktopEditor/agg-2.4/svg/agg_svg_frame_buffer_rgba.h
Normal file
@ -0,0 +1,107 @@
|
||||
#ifndef AGG_SVG_FRAME_BUFFER_RGBA_INCLUDED
|
||||
#define AGG_SVG_FRAME_BUFFER_RGBA_INCLUDED
|
||||
|
||||
#include "agg_rendering_buffer.h"
|
||||
#include "agg_pixfmt_rgba.h"
|
||||
#include "agg_renderer_base.h"
|
||||
#include "agg_renderer_scanline.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
class frame_buffer_rgba
|
||||
{
|
||||
public:
|
||||
typedef agg::blender_rgba<color_type, component_order> blender_type;
|
||||
typedef agg::pixfmt_alpha_blend_rgba<blender_type, agg::rendering_buffer, pixel_type> pixfmt_type;
|
||||
typedef agg::renderer_base<pixfmt_type> renderer_base_type;
|
||||
typedef agg::renderer_scanline_aa_solid<renderer_base_type> renderer_solid_type;
|
||||
|
||||
enum { pix_size = sizeof(pixel_type) };
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
~frame_buffer_rgba()
|
||||
{
|
||||
if (!m_buf_was_attach)
|
||||
delete [] m_internal_buf;
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
frame_buffer_rgba()
|
||||
: m_internal_buf(0)
|
||||
, m_is_valid(false)
|
||||
, m_ren_buf()
|
||||
, m_pixfmt()
|
||||
, m_ren_base()
|
||||
, m_ren_solid()
|
||||
, m_buf_was_attach(false)
|
||||
{}
|
||||
//-----------------------------------------------------------------------
|
||||
void create(unsigned width, unsigned height, bool flip, int& stride, void* buff=NULL)
|
||||
{
|
||||
if (!m_buf_was_attach)
|
||||
delete [] m_internal_buf;
|
||||
|
||||
if (!buff)
|
||||
{
|
||||
stride = flip ? -int(width * pix_size) : int(width * pix_size);
|
||||
m_internal_buf = new agg::int8u[width * height * pix_size];
|
||||
m_buf_was_attach = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_internal_buf = (agg::int8u*)buff;
|
||||
m_buf_was_attach = true;
|
||||
}
|
||||
|
||||
m_ren_buf.attach(m_internal_buf, width, height, stride);
|
||||
|
||||
m_pixfmt.attach(m_ren_buf);
|
||||
m_ren_base.attach(m_pixfmt);
|
||||
m_ren_solid.attach(m_ren_base);
|
||||
|
||||
m_is_valid = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void clear() { m_ren_buf.clear(0); }
|
||||
void clear(color_type c) { m_ren_base.clear(c); }
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
const agg::rendering_buffer& ren_buf() const { return m_ren_buf; }
|
||||
agg::rendering_buffer& ren_buf() { return m_ren_buf; }
|
||||
|
||||
bool is_valid() const { return m_is_valid; }
|
||||
unsigned width() const { return m_ren_buf.width(); }
|
||||
unsigned height() const { return m_ren_buf.height(); }
|
||||
|
||||
const pixfmt_type& pixfmt() const { return m_pixfmt; }
|
||||
pixfmt_type& pixfmt() { return m_pixfmt; }
|
||||
|
||||
const renderer_base_type& ren_base() const { return m_ren_base; }
|
||||
renderer_base_type& ren_base() { return m_ren_base; }
|
||||
|
||||
const renderer_solid_type& ren_solid()const { return m_ren_solid; }
|
||||
renderer_solid_type& ren_solid() { return m_ren_solid; }
|
||||
|
||||
const agg::int8u* get_internal_buf() const {return m_internal_buf;}
|
||||
|
||||
private:
|
||||
frame_buffer_rgba(const frame_buffer_rgba&);
|
||||
const frame_buffer_rgba& operator = (const frame_buffer_rgba&);
|
||||
|
||||
agg::int8u* m_internal_buf;
|
||||
bool m_is_valid;
|
||||
agg::rendering_buffer m_ren_buf;
|
||||
pixfmt_type m_pixfmt;
|
||||
renderer_base_type m_ren_base;
|
||||
renderer_solid_type m_ren_solid;
|
||||
|
||||
bool m_buf_was_attach;
|
||||
};
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_FRAME_BUFFER_RGBA_INCLUDED
|
||||
86
DesktopEditor/agg-2.4/svg/agg_svg_gradient.cpp
Normal file
86
DesktopEditor/agg-2.4/svg/agg_svg_gradient.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_svg_gradient.h"
|
||||
#include "agg_svg_attributes.h"
|
||||
#include "agg_dda_line.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
class color_interpolator_rgba
|
||||
{
|
||||
public:
|
||||
color_interpolator_rgba(const color_type& c1,
|
||||
const color_type& c2,
|
||||
unsigned len) :
|
||||
r(c1.r, c2.r, len),
|
||||
g(c1.g, c2.g, len),
|
||||
b(c1.b, c2.b, len),
|
||||
a(c1.a, c2.a, len)
|
||||
{}
|
||||
|
||||
void operator ++ ()
|
||||
{
|
||||
++r; ++g; ++b; ++a;
|
||||
}
|
||||
color_type color() const
|
||||
{
|
||||
return color_type(r.y(), g.y(), b.y(), a.y());
|
||||
}
|
||||
|
||||
private:
|
||||
agg::dda_line_interpolator<14> r, g, b, a;
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
void gradient::create_gradient_lut(attributes& attr, gradient_lut_cache& cache)
|
||||
{
|
||||
agg::quick_sort(m_colors, offset_less);
|
||||
m_colors.cut_at(agg::remove_duplicates(m_colors, offset_equal));
|
||||
|
||||
m_lut = cache.get_lut(m_colors);
|
||||
if (m_lut == 0)
|
||||
{
|
||||
if(m_colors.size() >= 2)
|
||||
{
|
||||
gradient_lut_type lut;
|
||||
unsigned i;
|
||||
|
||||
unsigned start = unsigned(m_colors[0].offset * lut.size() + 0.5);
|
||||
unsigned end;
|
||||
color_type c1 = attr.gamma_color(m_colors[0].stop_color);
|
||||
color_type c2;
|
||||
c1.a = (color_type::value_type)(c1.a * m_colors[0].stop_opacity + 0.5);
|
||||
for(i = 0; i < start; i++)
|
||||
{
|
||||
lut[i] = c1;
|
||||
}
|
||||
for(i = 1; i < m_colors.size(); i++)
|
||||
{
|
||||
end = unsigned(m_colors[i].offset * lut.size() + 0.5);
|
||||
c1 = attr.gamma_color(m_colors[i-1].stop_color);
|
||||
c1.a = (color_type::value_type)(c1.a * m_colors[i-1].stop_opacity + 0.5);
|
||||
c2 = attr.gamma_color(m_colors[i].stop_color);
|
||||
c2.a = (color_type::value_type)(c2.a * m_colors[i].stop_opacity + 0.5);
|
||||
color_interpolator_rgba ci(c1, c2, end - start + 1);
|
||||
while(start < end)
|
||||
{
|
||||
lut[start] = ci.color();
|
||||
++ci;
|
||||
++start;
|
||||
}
|
||||
}
|
||||
c2 = attr.gamma_color(m_colors.last().stop_color);
|
||||
c2.a = (color_type::value_type)(c2.a * m_colors.last().stop_opacity + 0.5);
|
||||
for(; end < lut.size(); end++)
|
||||
{
|
||||
lut[end] = c2;
|
||||
}
|
||||
m_lut = cache.add(m_colors, lut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
203
DesktopEditor/agg-2.4/svg/agg_svg_gradient.h
Normal file
203
DesktopEditor/agg-2.4/svg/agg_svg_gradient.h
Normal file
@ -0,0 +1,203 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef AGG_SVG_GRADIENT_INCLUDED
|
||||
#define AGG_SVG_GRADIENT_INCLUDED
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_array.h"
|
||||
#include "agg_trans_affine.h"
|
||||
#include "agg_svg_basics.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
class attributes;
|
||||
class gradient_lut_cache;
|
||||
//-------------------------------------------------------------------------
|
||||
class gradient
|
||||
{
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
struct stop
|
||||
{
|
||||
double offset;
|
||||
color_type stop_color;
|
||||
double stop_opacity;
|
||||
|
||||
stop() {}
|
||||
stop(double off, const color_type& c, double op) :
|
||||
offset(off), stop_color(c), stop_opacity(op)
|
||||
{
|
||||
if(offset < 0.0) offset = 0.0;
|
||||
if(offset > 1.0) offset = 1.0;
|
||||
if(stop_opacity < 0.0) stop_opacity = 0.0;
|
||||
if(stop_opacity > 1.0) stop_opacity = 1.0;
|
||||
}
|
||||
};
|
||||
typedef agg::pod_bvector<stop, 4> stop_array_type;
|
||||
|
||||
static bool offset_less(const stop& a, const stop& b)
|
||||
{
|
||||
return a.offset < b.offset;
|
||||
}
|
||||
static bool offset_equal(const stop& a, const stop& b)
|
||||
{
|
||||
return a.offset == b.offset;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
gradient() :
|
||||
m_type(gradient_linear),
|
||||
m_gradientUnits(objectUnits_objectBoundingBox),
|
||||
m_spreadMethod(spreadMethod_pad),
|
||||
m_gradientTransform(),
|
||||
m_x1(0), m_y1(0), m_x2(1), m_y2(0),
|
||||
m_cx(0.5), m_cy(0.5), m_r(0.5), m_fx(0.5), m_fy(0.5), m_lut(0)
|
||||
{}
|
||||
//-----------------------------------------------------------------------
|
||||
void reset()
|
||||
{
|
||||
m_type = gradient_linear;
|
||||
m_gradientUnits = objectUnits_objectBoundingBox;
|
||||
m_spreadMethod = spreadMethod_pad;
|
||||
m_gradientTransform.reset();
|
||||
m_x1 = 0; m_y1 = 0; m_x2 = 1; m_y2 = 0;
|
||||
m_cx = 0.5; m_cy = 0.5; m_r = 0.5; m_fx = 0.5; m_fy = 0.5;
|
||||
m_colors.remove_all();
|
||||
m_lut = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void type(gradient_e v) { m_type = v; }
|
||||
void gradientUnits(objectUnits_e v) { m_gradientUnits = v; }
|
||||
void spreadMethod(spreadMethod_e v) { m_spreadMethod = v; }
|
||||
|
||||
void linear(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
m_type = gradient_linear;
|
||||
m_x1 = x1; m_y1 = y1;
|
||||
m_x2 = x2; m_y2 = y2;
|
||||
}
|
||||
|
||||
void radial(double cx, double cy, double r)
|
||||
{
|
||||
m_type = gradient_radial;
|
||||
m_cx = m_fx = cx;
|
||||
m_cy = m_fy = cy;
|
||||
m_r = r;
|
||||
}
|
||||
|
||||
void focus(double fx, double fy)
|
||||
{
|
||||
m_fx = fx;
|
||||
m_fy = fy;
|
||||
}
|
||||
|
||||
void x1(double v) { m_x1 = v; }
|
||||
void y1(double v) { m_y1 = v; }
|
||||
void x2(double v) { m_x2 = v; }
|
||||
void y2(double v) { m_y2 = v; }
|
||||
void cx(double v) { m_cx = v; }
|
||||
void cy(double v) { m_cy = v; }
|
||||
void r(double v) { m_r = v; }
|
||||
void fx(double v) { m_fx = v; }
|
||||
void fy(double v) { m_fy = v; }
|
||||
|
||||
void remove_all_stops()
|
||||
{
|
||||
m_colors.remove_all();
|
||||
}
|
||||
|
||||
void add_stop(double offset, const color_type& color, double opacity)
|
||||
{
|
||||
m_colors.add(stop(offset, color, opacity));
|
||||
}
|
||||
|
||||
void create_gradient_lut(attributes& attr, gradient_lut_cache&);
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void transform(double a0, double a1, double a2,
|
||||
double a3, double a4, double a5)
|
||||
{
|
||||
m_gradientTransform.premultiply(agg::trans_affine(a0, a1, a2, a3, a4, a5));
|
||||
}
|
||||
|
||||
void translate(double dx, double dy)
|
||||
{
|
||||
m_gradientTransform.premultiply(agg::trans_affine_translation(dx, dy));
|
||||
}
|
||||
|
||||
void rotate(double angle)
|
||||
{
|
||||
m_gradientTransform.premultiply(agg::trans_affine_rotation(angle));
|
||||
}
|
||||
|
||||
void rotate(double angle, double cx, double cy)
|
||||
{
|
||||
agg::trans_affine_translation m(-cx, -cy);
|
||||
m *= agg::trans_affine_rotation(angle);
|
||||
m *= agg::trans_affine_translation(cx, cy);
|
||||
m_gradientTransform.premultiply(m);
|
||||
}
|
||||
|
||||
void scale(double s)
|
||||
{
|
||||
m_gradientTransform.premultiply(agg::trans_affine_scaling(s));
|
||||
}
|
||||
|
||||
void scale(double sx, double sy)
|
||||
{
|
||||
m_gradientTransform.premultiply(agg::trans_affine_scaling(sx, sy));
|
||||
}
|
||||
|
||||
void skew(double sx, double sy)
|
||||
{
|
||||
m_gradientTransform.premultiply(agg::trans_affine_skewing(sx, sy));
|
||||
}
|
||||
|
||||
void skew_x(double s)
|
||||
{
|
||||
m_gradientTransform.premultiply(agg::trans_affine_skewing(s, 0.0));
|
||||
}
|
||||
|
||||
void skew_y(double s)
|
||||
{
|
||||
m_gradientTransform.premultiply(agg::trans_affine_skewing(0.0, s));
|
||||
}
|
||||
|
||||
// Accessors
|
||||
//-----------------------------------------------------------------------
|
||||
gradient_e type() const { return m_type; }
|
||||
objectUnits_e gradientUnits() const { return m_gradientUnits; }
|
||||
spreadMethod_e spreadMethod() const { return m_spreadMethod; }
|
||||
agg::trans_affine& gradientTransform() { return m_gradientTransform; }
|
||||
const agg::trans_affine& gradientTransform() const { return m_gradientTransform; }
|
||||
double x1() const { return m_x1; }
|
||||
double y1() const { return m_y1; }
|
||||
double x2() const { return m_x2; }
|
||||
double y2() const { return m_y2; }
|
||||
double cx() const { return m_cx; }
|
||||
double cy() const { return m_cy; }
|
||||
double r() const { return m_r; }
|
||||
double fx() const { return m_fx; }
|
||||
double fy() const { return m_fy; }
|
||||
const gradient_lut_type& lut() const { return *m_lut; }
|
||||
|
||||
private:
|
||||
gradient(const gradient&);
|
||||
const gradient& operator = (const gradient&);
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
gradient_e m_type;
|
||||
objectUnits_e m_gradientUnits;
|
||||
spreadMethod_e m_spreadMethod;
|
||||
agg::trans_affine m_gradientTransform;
|
||||
double m_x1, m_y1, m_x2, m_y2;
|
||||
double m_cx, m_cy, m_r, m_fx, m_fy;
|
||||
stop_array_type m_colors;
|
||||
gradient_lut_type* m_lut;
|
||||
};
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_GRADIENT_INCLUDED
|
||||
81
DesktopEditor/agg-2.4/svg/agg_svg_gradient_lut_cache.h
Normal file
81
DesktopEditor/agg-2.4/svg/agg_svg_gradient_lut_cache.h
Normal file
@ -0,0 +1,81 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef AGG_SVG_GRADIENT_LUT_CACHE_INCLUDED
|
||||
#define AGG_SVG_GRADIENT_LUT_CACHE_INCLUDED
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_array.h"
|
||||
#include "agg_svg_basics.h"
|
||||
#include "agg_svg_gradient.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
class gradient_lut_cache
|
||||
{
|
||||
typedef gradient::stop_array_type stop_array_type;
|
||||
typedef agg::pod_bvector<gradient_lut_type,8> cache_type;
|
||||
typedef agg::pod_bvector<stop_array_type> stop_array_key_type;
|
||||
|
||||
cache_type m_cache;
|
||||
stop_array_key_type m_colors_key;
|
||||
|
||||
static bool color_equal(const color_type& lhs,
|
||||
const color_type& rhs)
|
||||
{
|
||||
return lhs.r == rhs.r &&
|
||||
lhs.g == rhs.g &&
|
||||
lhs.b == rhs.b &&
|
||||
lhs.a == rhs.a;
|
||||
}
|
||||
|
||||
static bool stop_equal(const gradient::stop& lhs,
|
||||
const gradient::stop& rhs)
|
||||
{
|
||||
return lhs.offset == rhs.offset &&
|
||||
lhs.stop_opacity == rhs.stop_opacity &&
|
||||
color_equal(lhs.stop_color, rhs.stop_color);
|
||||
}
|
||||
|
||||
static bool stop_array_equal(const stop_array_type& lhs,
|
||||
const stop_array_type& rhs)
|
||||
{
|
||||
if (lhs.size() != rhs.size())
|
||||
return false;
|
||||
|
||||
for (unsigned i = 0u, size = lhs.size(); i < size; ++i)
|
||||
{
|
||||
if (!stop_equal(lhs[i], rhs[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned find_lut_index(const stop_array_type& colors)
|
||||
{
|
||||
for (unsigned i = 0u, size = m_colors_key.size(); i < size; ++i)
|
||||
if (stop_array_equal(m_colors_key[i], colors))
|
||||
return i + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public:
|
||||
gradient_lut_type* get_lut(const stop_array_type& colors)
|
||||
{
|
||||
unsigned idx = find_lut_index(colors);
|
||||
return idx ? &m_cache[idx - 1] : 0;
|
||||
}
|
||||
|
||||
gradient_lut_type* add(const stop_array_type& colors, const gradient_lut_type& lut)
|
||||
{
|
||||
m_cache.add(lut);
|
||||
m_colors_key.add(colors);
|
||||
|
||||
return &m_cache.last();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_GRADIENT_LUT_CACHE_INCLUDED
|
||||
53
DesktopEditor/agg-2.4/svg/agg_svg_indexation_interpreter.h
Normal file
53
DesktopEditor/agg-2.4/svg/agg_svg_indexation_interpreter.h
Normal file
@ -0,0 +1,53 @@
|
||||
#ifndef AGG_SVG_INDEXATION_INTERPRETER
|
||||
#define AGG_SVG_INDEXATION_INTERPRETER
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_svg_defines.h"
|
||||
#include "agg_svg_dom_storage.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
class indexation_interpreter
|
||||
{
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
explicit indexation_interpreter(dom_storage::map_type& map)
|
||||
:
|
||||
m_attr2element_map(map)
|
||||
{
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
bool start_element(const dom_storage&, const element_data& el)
|
||||
{
|
||||
for (unsigned i = 0; i < el.num_attr; ++i)
|
||||
{
|
||||
if (el.attr[i].code == attr_id)
|
||||
{
|
||||
dom_storage::element_location eloc;
|
||||
eloc.code = el.code;
|
||||
eloc.idx = el.index;
|
||||
|
||||
m_attr2element_map.insert(el.attr[i].data, eloc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
bool end_element(const dom_storage&, const element_data&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
dom_storage::map_type& m_attr2element_map;
|
||||
};
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_INDEXATION_INTERPRETER
|
||||
|
||||
125
DesktopEditor/agg-2.4/svg/agg_svg_iomemstream.h
Normal file
125
DesktopEditor/agg-2.4/svg/agg_svg_iomemstream.h
Normal file
@ -0,0 +1,125 @@
|
||||
#ifndef AGG_SVG_IOMEMSTREAM_INCLUDE
|
||||
#define AGG_SVG_IOMEMSTREAM_INCLUDE
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_svg_basics.h"
|
||||
#include "agg_svg_data_accessor.h"
|
||||
#include "agg_svg_ptr_size_pair.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
class iomemstream
|
||||
{
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
void clear();
|
||||
//---------------------------------------------------------------------
|
||||
agg::int32u size() const;
|
||||
//---------------------------------------------------------------------
|
||||
data_container const & buffer() const;
|
||||
data_container & buffer() ;
|
||||
//---------------------------------------------------------------------
|
||||
iomemstream& operator<<(agg::int8u);
|
||||
iomemstream& operator<<(agg::int32u);
|
||||
iomemstream& operator<<(const ptr_size &);
|
||||
iomemstream& operator<<(const ptr_size_short &);
|
||||
iomemstream& operator<<(data_accessor_type);
|
||||
//---------------------------------------------------------------------
|
||||
iomemstream& write(const void* ptr, agg::int32u size);
|
||||
//---------------------------------------------------------------------
|
||||
template <class T>
|
||||
void add(const T& attr)
|
||||
{
|
||||
m_buffer.add_array(attr.head(), attr.head_size());
|
||||
m_buffer.add_array(attr.data(), attr.data_size());
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
private:
|
||||
data_container m_buffer;
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
inline void iomemstream::clear()
|
||||
{
|
||||
m_buffer.free_all();
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline agg::int32u iomemstream::size() const
|
||||
{
|
||||
return m_buffer.size();
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline data_container const & iomemstream::buffer() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline data_container & iomemstream::buffer()
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline iomemstream& iomemstream::operator<<(agg::int8u v)
|
||||
{
|
||||
m_buffer.add(v);
|
||||
return *this;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline iomemstream& iomemstream::operator<<(agg::int32u v)
|
||||
{
|
||||
m_buffer.add_array((const agg::int8u *)&v, sizeof(agg::int32u));
|
||||
return *this;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline iomemstream& iomemstream::operator<<(const ptr_size & ps)
|
||||
{
|
||||
(*this) << ps.m_size;
|
||||
m_buffer.add_array(ps.m_ptr, ps.m_size);
|
||||
return *this;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline iomemstream& iomemstream::operator<<(const ptr_size_short& ps)
|
||||
{
|
||||
m_buffer.add(ps.m_size);
|
||||
m_buffer.add_array(ps.m_ptr, ps.m_size);
|
||||
return *this;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline iomemstream& iomemstream::operator<<(data_accessor_type data)
|
||||
{
|
||||
while (data.size())
|
||||
{
|
||||
m_buffer.add(*data);
|
||||
++data;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline iomemstream& iomemstream::write(const void * ptr, agg::int32u size)
|
||||
{
|
||||
assert(ptr);
|
||||
|
||||
const agg::int8u * p = (const agg::int8u *)ptr;
|
||||
while (size--)
|
||||
{
|
||||
m_buffer.add(*p++);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_IOMEMSTREAM_INCLUDE
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
56
DesktopEditor/agg-2.4/svg/agg_svg_parse_real.cpp
Normal file
56
DesktopEditor/agg-2.4/svg/agg_svg_parse_real.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include "agg_svg_parse_real.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
|
||||
namespace aux
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
struct contains_helper
|
||||
{
|
||||
contains_helper()
|
||||
{
|
||||
init_mask(m_set_mask, s_set);
|
||||
}
|
||||
|
||||
bool operator()(unsigned c) const
|
||||
{
|
||||
return (m_set_mask[(c >> 3) & (256/8-1)] & (1 << (c & 7))) != 0;
|
||||
}
|
||||
|
||||
private:
|
||||
static void init_mask(unsigned char* mask, const unsigned char* char_set);
|
||||
|
||||
unsigned char m_set_mask[256/8];
|
||||
|
||||
static const unsigned char s_set[];
|
||||
|
||||
};
|
||||
|
||||
const unsigned char contains_helper::s_set[] = "0123456789";
|
||||
//-----------------------------------------------------------------------------
|
||||
void contains_helper::init_mask(unsigned char* mask, const unsigned
|
||||
char* char_set)
|
||||
{
|
||||
memset(mask, 0, 256/8);
|
||||
while(*char_set)
|
||||
{
|
||||
unsigned c = unsigned(*char_set++) & 0xFF;
|
||||
mask[c >> 3] |= 1 << (c & 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
bool isdigit(unsigned c)
|
||||
{
|
||||
static aux::contains_helper helper;
|
||||
|
||||
return helper(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
280
DesktopEditor/agg-2.4/svg/agg_svg_parse_real.h
Normal file
280
DesktopEditor/agg-2.4/svg/agg_svg_parse_real.h
Normal file
@ -0,0 +1,280 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef AGG_SVG_PARSE_REAL_INCLUDED
|
||||
#define AGG_SVG_PARSE_REAL_INCLUDED
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
namespace detail
|
||||
{
|
||||
bool isdigit(unsigned c);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
template<int Radix>
|
||||
struct radix_traits;
|
||||
//-------------------------------------------------------------------------
|
||||
////////////////////////////////// Decimal
|
||||
template<>
|
||||
struct radix_traits<10>
|
||||
{
|
||||
static bool is_valid(char ch)
|
||||
{
|
||||
return detail::isdigit(ch);
|
||||
}
|
||||
|
||||
static int digit(char ch)
|
||||
{
|
||||
return ch - '0';
|
||||
}
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
template<int Radix>
|
||||
struct positive_accumulate
|
||||
{
|
||||
// Use this accumulator if number is positive
|
||||
template <typename T>
|
||||
static bool check(T const& n, T const& prev)
|
||||
{
|
||||
return n < prev;
|
||||
}
|
||||
|
||||
template <typename T, typename CharT>
|
||||
static void add(T& n, CharT ch)
|
||||
{
|
||||
n += radix_traits<Radix>::digit(ch);
|
||||
}
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
template<int Radix>
|
||||
struct negative_accumulate
|
||||
{
|
||||
// Use this accumulator if number is negative
|
||||
|
||||
template <typename T>
|
||||
static bool check(T const& n, T const& prev)
|
||||
{
|
||||
return n > prev;
|
||||
}
|
||||
|
||||
template <typename T, typename CharT>
|
||||
static void add(T& n, CharT ch)
|
||||
{
|
||||
n -= radix_traits<Radix>::digit(ch);
|
||||
}
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
template <int Radix, typename Accumulate>
|
||||
struct extract_int_base
|
||||
{
|
||||
// Common code for extract_int specializations
|
||||
template <typename T>
|
||||
static bool f(const char* scan, T& n)
|
||||
{
|
||||
T prev = n;
|
||||
n *= Radix;
|
||||
if (Accumulate::check(n, prev))
|
||||
return false; // over/underflow!
|
||||
prev = n;
|
||||
Accumulate::add(n, *scan);
|
||||
if (Accumulate::check(n, prev))
|
||||
return false; // over/underflow!
|
||||
return true;
|
||||
}
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
template <int Radix = 10, typename Accumulate = positive_accumulate<Radix> >
|
||||
struct extract_int
|
||||
{
|
||||
template <typename T>
|
||||
static bool f(const char* & scan, const char * const end, T& n, size_t& count)
|
||||
{
|
||||
typedef extract_int_base<Radix, Accumulate> base;
|
||||
typedef radix_traits<Radix> check;
|
||||
|
||||
size_t i = 0;
|
||||
for (; scan != end && check::is_valid(*scan);
|
||||
++i, ++scan, ++count)
|
||||
{
|
||||
if (!base::f(scan, n))
|
||||
return false; // over/underflow!
|
||||
}
|
||||
return i >= 1;
|
||||
}
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
class parse_real
|
||||
{
|
||||
private:
|
||||
//-------------------------------------------------------------------------
|
||||
const bool allow_leading_dot;
|
||||
const bool allow_trailing_dot;
|
||||
const bool expect_dot;
|
||||
public:
|
||||
//-------------------------------------------------------------------------
|
||||
parse_real()
|
||||
: allow_leading_dot(true),
|
||||
allow_trailing_dot(true),
|
||||
expect_dot(false)
|
||||
{
|
||||
}
|
||||
private:
|
||||
//---------------------------------------------------------------------
|
||||
bool parse_sign(const char * & src)
|
||||
{
|
||||
bool neg = *src == '-';
|
||||
if (neg || (*src == '+'))
|
||||
{
|
||||
++src;
|
||||
return neg;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
bool parse_dot(const char* & src)
|
||||
{
|
||||
if (*src == '.')
|
||||
{
|
||||
++src;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
bool parse_exp(const char* & src)
|
||||
{
|
||||
if (*src == 'e' || *src == 'E')
|
||||
{
|
||||
++src;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
template <class T>
|
||||
bool parse_uint(const char * & beg, const char * const end, T& n, size_t& count)
|
||||
{
|
||||
count = 0;
|
||||
bool result = extract_int<>::f(beg, end, n, count);
|
||||
return result;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
template <class T>
|
||||
bool parse_int(const char * & beg, const char * const end, T& n, size_t& count)
|
||||
{
|
||||
typedef extract_int<10,negative_accumulate<10> > extract_int_neg_t;
|
||||
typedef extract_int<> extract_int_pos_t;
|
||||
|
||||
if (*beg)
|
||||
{
|
||||
count = 0;
|
||||
n = 0;
|
||||
const char* save = beg;
|
||||
|
||||
bool hit = parse_sign(beg);
|
||||
|
||||
if (hit)
|
||||
hit = extract_int_neg_t::f(beg, end, n, count);
|
||||
else
|
||||
hit = extract_int_pos_t::f(beg, end, n, count);
|
||||
|
||||
if (hit)
|
||||
return true;
|
||||
else
|
||||
beg = save;
|
||||
// return no-match if number overflows or underflows
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public:
|
||||
//-------------------------------------------------------------------------
|
||||
bool parse(const char* beg, const char * const end,
|
||||
double* d, const char** endptr)
|
||||
{
|
||||
const char * src = beg;
|
||||
|
||||
if (src == 0 || *src == 0)
|
||||
return false;
|
||||
|
||||
double result = 0;
|
||||
|
||||
size_t count = 0;
|
||||
|
||||
bool neg = parse_sign(src);
|
||||
|
||||
bool got_a_number = parse_uint(src, end, result, count) && count;
|
||||
|
||||
if (!got_a_number && !allow_leading_dot)
|
||||
return false;
|
||||
|
||||
bool exp_hit = false;
|
||||
int exp = 0;
|
||||
|
||||
if (parse_dot(src))
|
||||
{
|
||||
// We got the decimal point. Now we will try to parse
|
||||
// the fraction if it is there. If not, it defaults
|
||||
// to zero (0) only if we already got a number.
|
||||
|
||||
if (parse_uint(src, end, result, count))
|
||||
{
|
||||
exp = (int)count;
|
||||
exp = -exp;
|
||||
}
|
||||
else if (!got_a_number || !allow_trailing_dot)
|
||||
return false;
|
||||
|
||||
exp_hit = parse_exp(src);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have reached a point where we
|
||||
// still haven't seen a number at all.
|
||||
// We return early with a no-match.
|
||||
if (!got_a_number)
|
||||
return false;
|
||||
|
||||
// If we must expect a dot and we didn't see
|
||||
// an exponent, return early with a no-match.
|
||||
exp_hit = parse_exp(src);
|
||||
if (expect_dot && !exp_hit)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (exp_hit)
|
||||
{
|
||||
// We got the exponent prefix. Now we will try to parse the
|
||||
// actual exponent. It is an error if it is not there.
|
||||
int temp;
|
||||
if (parse_int(src, end, temp, count))
|
||||
{
|
||||
exp += temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*d = result;
|
||||
|
||||
if (neg)
|
||||
*d = -(*d);
|
||||
|
||||
*d *= pow(10., exp);
|
||||
|
||||
*endptr = src;
|
||||
|
||||
return true;//src == end;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_PARSE_REAL_INCLUDED
|
||||
|
||||
1137
DesktopEditor/agg-2.4/svg/agg_svg_parser.cpp
Normal file
1137
DesktopEditor/agg-2.4/svg/agg_svg_parser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
181
DesktopEditor/agg-2.4/svg/agg_svg_parser.h
Normal file
181
DesktopEditor/agg-2.4/svg/agg_svg_parser.h
Normal file
@ -0,0 +1,181 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// SVG parser.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef AGG_SVG_PARSER_INCLUDED
|
||||
#define AGG_SVG_PARSER_INCLUDED
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_svg_basics.h"
|
||||
#include "agg_svg_path_serializer.h"
|
||||
#include "agg_svg_path_interpreter.h"
|
||||
#include "agg_svg_dom_storage.h"
|
||||
#include <stack>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
class attributes_map;
|
||||
//-------------------------------------------------------------------------
|
||||
class parser
|
||||
{
|
||||
enum buf_size_e { buf_size = 8 * BUFSIZ };
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
parser(dom_storage&, attributes_map& attr_map);
|
||||
//---------------------------------------------------------------------
|
||||
~parser();
|
||||
//---------------------------------------------------------------------
|
||||
void parse(const wchar_t* fname);
|
||||
//---------------------------------------------------------------------
|
||||
private:
|
||||
|
||||
// XML event handlers
|
||||
static void on_start_element(void* data, const char* el, const char** attr);
|
||||
static void on_end_element(void* data, const char* el);
|
||||
static void on_content(void* data, const char* s, int len);
|
||||
//---------------------------------------------------------------------
|
||||
typedef path_tokenizer<char> path_tokenizer_type;
|
||||
typedef path_serializer<data_container> path_serializer_type;
|
||||
//---------------------------------------------------------------------
|
||||
// utility
|
||||
//
|
||||
//---------------------------------------------------------------------
|
||||
void prepare_attributes( const char**);
|
||||
//---------------------------------------------------------------------
|
||||
void start_element_cleanup();
|
||||
//---------------------------------------------------------------------
|
||||
const char* extract_attribute(attr_e attr);
|
||||
//---------------------------------------------------------------------
|
||||
attr_e find_known_attribute(const char* attr_name);
|
||||
//---------------------------------------------------------------------
|
||||
void parse_name_value(char* nv_start, char* nv_end);
|
||||
//---------------------------------------------------------------------
|
||||
void add_double_to_buffer(double val);
|
||||
//---------------------------------------------------------------------
|
||||
const char* get_attr_name( unsigned attr );
|
||||
//---------------------------------------------------------------------
|
||||
// Error processing
|
||||
//
|
||||
//---------------------------------------------------------------------
|
||||
typedef void(parser::*error_checker_type)(double);
|
||||
//---------------------------------------------------------------------
|
||||
void not_negative(double);
|
||||
//---------------------------------------------------------------------
|
||||
// parse basic data types
|
||||
//
|
||||
//---------------------------------------------------------------------
|
||||
enum axis_e {no_axis, axis_x, axis_y};
|
||||
//---------------------------------------------------------------------
|
||||
enum necessity_e {optional, required};
|
||||
//---------------------------------------------------------------------
|
||||
void parse_number(attr_e, necessity_e necessity);
|
||||
//---------------------------------------------------------------------
|
||||
void parse_color (attr_e, necessity_e necessity);
|
||||
//---------------------------------------------------------------------
|
||||
void parse_string(attr_e);
|
||||
//---------------------------------------------------------------------
|
||||
void parse_coordinate_attr(attr_e attr, axis_e axis,
|
||||
necessity_e necessity, error_checker_type = 0);
|
||||
//---------------------------------------------------------------------
|
||||
bool length_parser(length& len, const char* begin, const char * end);
|
||||
//---------------------------------------------------------------------
|
||||
void parse_length_attr(attr_e attr, necessity_e necessity,
|
||||
error_checker_type = 0);
|
||||
//---------------------------------------------------------------------
|
||||
// parse elements
|
||||
//
|
||||
//---------------------------------------------------------------------
|
||||
void parse_polygon();
|
||||
void parse_polyline();
|
||||
void parse_svg();
|
||||
void parse_path();
|
||||
void parse_rect();
|
||||
void parse_line();
|
||||
void parse_circle();
|
||||
void parse_ellipse();
|
||||
void parse_linearGradient();
|
||||
void parse_radialGradient();
|
||||
void parse_stop();
|
||||
void parse_defs();
|
||||
void parse_title();
|
||||
void parse_g();
|
||||
void parse_use();
|
||||
void parse_clipPath();
|
||||
//---------------------------------------------------------------------
|
||||
// parse attributes
|
||||
//
|
||||
void parse_attr_viewBox();
|
||||
void parse_attr_preserveAspectRatio();
|
||||
void parse_object_units_attr(attr_e);
|
||||
void parse_paint_attr(attr_e);
|
||||
void parse_uri_attr(attr_e);
|
||||
|
||||
|
||||
unsigned parse_transform_args(const char* str, double* args,
|
||||
unsigned max_na, unsigned* na);
|
||||
|
||||
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);
|
||||
//---------------------------------------------------------------------
|
||||
// parse attribute sets
|
||||
//
|
||||
void parse_core_attributes ();
|
||||
void parse_presentation_attributes ();
|
||||
void parse_style_attributes ();
|
||||
void parse_paint_attributes ();
|
||||
void parse_color_attributes ();
|
||||
void parse_opacity_attributes ();
|
||||
void parse_xlink_attributes ();
|
||||
void parse_common_gradient_attributes ();
|
||||
void parse_basic_shapes_common_attributes();
|
||||
void parse_transform_attributes (attr_e);
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
//---------------------------------------------------------------------
|
||||
struct extra_attr
|
||||
{
|
||||
const char* name;
|
||||
const char* value;
|
||||
extra_attr() {}
|
||||
extra_attr(const char* n, const char* v) : name(n), value(v) {}
|
||||
};
|
||||
//---------------------------------------------------------------------
|
||||
struct unit_descriptor
|
||||
{
|
||||
units2_e unit;
|
||||
const char * literal;
|
||||
unsigned char length;
|
||||
};
|
||||
//---------------------------------------------------------------------
|
||||
dom_storage& m_storage;
|
||||
path_tokenizer_type m_path_tokenizer;
|
||||
data_container m_buffer;
|
||||
path_serializer_type m_path_serializer;
|
||||
const char* m_curr_elem_name;
|
||||
|
||||
const char* m_known_attr[end_of_attr];
|
||||
char* m_style_buffer;
|
||||
unsigned m_style_buffer_len;
|
||||
static unit_descriptor m_units[];
|
||||
attributes_map& m_attr_map;
|
||||
|
||||
std::stack<bool> m_unknownElement;
|
||||
|
||||
char* m_buf;
|
||||
};
|
||||
|
||||
} //namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_PARSER_INCLUDED
|
||||
|
||||
|
||||
|
||||
630
DesktopEditor/agg-2.4/svg/agg_svg_path_interpreter.h
Normal file
630
DesktopEditor/agg-2.4/svg/agg_svg_path_interpreter.h
Normal file
@ -0,0 +1,630 @@
|
||||
#ifndef AGG_SVG_PATH_INTERPRETER_INCLUDED
|
||||
#define AGG_SVG_PATH_INTERPRETER_INCLUDED
|
||||
|
||||
#include "agg_bezier_arc.h"
|
||||
#include "agg_math.h"
|
||||
#include "agg_svg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Use this class to interprete the serialized path.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
template<class DataAccessor> class path_interpreter
|
||||
{
|
||||
public:
|
||||
typedef DataAccessor data_accessor_type;
|
||||
typedef typename data_accessor_type::value_type value_type;
|
||||
|
||||
path_interpreter();
|
||||
path_interpreter(const data_accessor_type& data);
|
||||
|
||||
void init(const data_accessor_type& data);
|
||||
|
||||
void rewind(unsigned);
|
||||
unsigned vertex(double* x, double* y);
|
||||
|
||||
unsigned num_vertices() const { return m_num_vertices; }
|
||||
|
||||
private:
|
||||
void rel_to_abs(double *x, double *y) const
|
||||
{
|
||||
if(m_num_vertices > 1)
|
||||
{
|
||||
*x += m_vertices[m_num_vertices - 2];
|
||||
*y += m_vertices[m_num_vertices - 1];
|
||||
}
|
||||
}
|
||||
|
||||
unsigned last_command() const
|
||||
{
|
||||
if(m_last_command >= 'A' && m_last_command <= 'z')
|
||||
{
|
||||
return m_commands[m_last_command - 'A'];
|
||||
}
|
||||
return agg::path_cmd_stop;
|
||||
}
|
||||
|
||||
void move_to(unsigned cmd);
|
||||
void line_to(unsigned cmd);
|
||||
void hline_to(unsigned cmd);
|
||||
void vline_to(unsigned cmd);
|
||||
void curve3_to(unsigned cmd);
|
||||
void curve3_to_ref(unsigned cmd);
|
||||
void curve4_to(unsigned cmd);
|
||||
void curve4_to_ref(unsigned cmd);
|
||||
void arc_to(unsigned cmd);
|
||||
void close_subpath(unsigned cmd);
|
||||
|
||||
typedef void (path_interpreter<DataAccessor>::*command_handler)(unsigned cmd);
|
||||
|
||||
static const agg::int8u m_commands[58];
|
||||
static const command_handler m_command_handlers[58];
|
||||
|
||||
data_accessor_type m_accessor;
|
||||
data_accessor_type m_data;
|
||||
double m_vertices[26];
|
||||
unsigned m_num_vertices;
|
||||
unsigned m_vertex;
|
||||
double m_start_x;
|
||||
double m_start_y;
|
||||
unsigned m_last_command;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class DA>
|
||||
const agg::int8u path_interpreter<DA>::m_commands[58] =
|
||||
{
|
||||
agg::path_cmd_curve4, //065 A
|
||||
0, //066 B
|
||||
agg::path_cmd_curve4, //067 C
|
||||
0, //068 D
|
||||
0, //069 E
|
||||
0, //070 F
|
||||
0, //071 G
|
||||
agg::path_cmd_line_to, //072 H
|
||||
0, //073 I
|
||||
0, //074 J
|
||||
0, //075 K
|
||||
agg::path_cmd_line_to, //076 L
|
||||
agg::path_cmd_move_to, //077 M
|
||||
0, //078 N
|
||||
0, //079 O
|
||||
0, //080 P
|
||||
agg::path_cmd_curve3, //081 Q
|
||||
0, //082 R
|
||||
agg::path_cmd_curve4, //083 S
|
||||
agg::path_cmd_curve3, //084 T
|
||||
0, //085 U
|
||||
agg::path_cmd_line_to, //086 V
|
||||
0, //087 W
|
||||
0, //088 X
|
||||
0, //089 Y
|
||||
agg::path_cmd_end_poly | agg::path_flags_close, //090 Z
|
||||
0, //091 [
|
||||
0, //092 backslash
|
||||
0, //093 ]
|
||||
0, //094 ^
|
||||
0, //095 _
|
||||
0, //096 '
|
||||
agg::path_cmd_curve4, //097 a
|
||||
0, //098 b
|
||||
agg::path_cmd_curve4, //099 c
|
||||
0, //100 d
|
||||
0, //101 e
|
||||
0, //102 f
|
||||
0, //103 g
|
||||
agg::path_cmd_line_to, //104 h
|
||||
0, //105 i
|
||||
0, //106 j
|
||||
0, //107 k
|
||||
agg::path_cmd_line_to, //108 l
|
||||
agg::path_cmd_move_to, //109 m
|
||||
0, //110 n
|
||||
0, //111 o
|
||||
0, //112 p
|
||||
agg::path_cmd_curve3, //113 q
|
||||
0, //114 r
|
||||
agg::path_cmd_curve4, //115 s
|
||||
agg::path_cmd_curve3, //116 t
|
||||
0, //117 u
|
||||
agg::path_cmd_line_to, //118 v
|
||||
0, //119 w
|
||||
0, //120 x
|
||||
0, //121 y
|
||||
agg::path_cmd_end_poly | agg::path_flags_close //122 z
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class DA>
|
||||
path_interpreter<DA>::path_interpreter() :
|
||||
m_accessor(),
|
||||
m_data(),
|
||||
m_num_vertices(0),
|
||||
m_vertex(0),
|
||||
m_start_x(0.0),
|
||||
m_start_y(0.0),
|
||||
m_last_command(0)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class DA>
|
||||
path_interpreter<DA>::path_interpreter(const data_accessor_type& data) :
|
||||
m_accessor(data),
|
||||
m_data(data),
|
||||
m_num_vertices(0),
|
||||
m_vertex(0),
|
||||
m_start_x(0.0),
|
||||
m_start_y(0.0),
|
||||
m_last_command(0)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class DA>
|
||||
void path_interpreter<DA>::init(const data_accessor_type& data)
|
||||
{
|
||||
m_accessor = data;
|
||||
m_data = data;
|
||||
m_num_vertices = 0;
|
||||
m_vertex = 0;
|
||||
m_start_x = 0.0;
|
||||
m_start_y = 0.0;
|
||||
m_last_command = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class DA>
|
||||
void path_interpreter<DA>::move_to(unsigned cmd)
|
||||
{
|
||||
double x = m_data.read_coord();
|
||||
double y = m_data.read_coord();
|
||||
if(cmd == 'm')
|
||||
{
|
||||
rel_to_abs(&x, &y);
|
||||
}
|
||||
m_start_x = x;
|
||||
m_start_y = y;
|
||||
m_vertices[0] = x;
|
||||
m_vertices[1] = y;
|
||||
m_num_vertices = 2;
|
||||
m_last_command = cmd;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class DA>
|
||||
void path_interpreter<DA>::line_to(unsigned cmd)
|
||||
{
|
||||
double x = m_data.read_coord();
|
||||
double y = m_data.read_coord();
|
||||
if(cmd == 'l')
|
||||
{
|
||||
rel_to_abs(&x, &y);
|
||||
}
|
||||
m_vertices[0] = x;
|
||||
m_vertices[1] = y;
|
||||
m_num_vertices = 2;
|
||||
m_last_command = cmd;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class DA>
|
||||
void path_interpreter<DA>::hline_to(unsigned cmd)
|
||||
{
|
||||
double x = m_data.read_coord();
|
||||
double y = 0.0;
|
||||
if(m_num_vertices > 1)
|
||||
{
|
||||
if(cmd == 'h')
|
||||
{
|
||||
x += m_vertices[m_num_vertices - 2];
|
||||
}
|
||||
y = m_vertices[m_num_vertices - 1];
|
||||
}
|
||||
m_vertices[0] = x;
|
||||
m_vertices[1] = y;
|
||||
m_num_vertices = 2;
|
||||
m_last_command = cmd;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class DA>
|
||||
void path_interpreter<DA>::vline_to(unsigned cmd)
|
||||
{
|
||||
double x = 0.0;
|
||||
double y = m_data.read_coord();
|
||||
if(m_num_vertices > 1)
|
||||
{
|
||||
x = m_vertices[m_num_vertices - 2];
|
||||
if(cmd == 'v')
|
||||
{
|
||||
y += m_vertices[m_num_vertices - 1];
|
||||
}
|
||||
}
|
||||
m_vertices[0] = x;
|
||||
m_vertices[1] = y;
|
||||
m_num_vertices = 2;
|
||||
m_last_command = cmd;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class DA>
|
||||
void path_interpreter<DA>::curve3_to(unsigned cmd)
|
||||
{
|
||||
double x1 = m_data.read_coord();
|
||||
double y1 = m_data.read_coord();
|
||||
double x = m_data.read_coord();
|
||||
double y = m_data.read_coord();
|
||||
if(cmd == 'q')
|
||||
{
|
||||
rel_to_abs(&x1, &y1);
|
||||
rel_to_abs(&x, &y);
|
||||
}
|
||||
m_vertices[0] = x1;
|
||||
m_vertices[1] = y1;
|
||||
m_vertices[2] = x;
|
||||
m_vertices[3] = y;
|
||||
m_num_vertices = 4;
|
||||
m_last_command = cmd;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class DA>
|
||||
void path_interpreter<DA>::curve3_to_ref(unsigned cmd)
|
||||
{
|
||||
double x1 = 0.0;
|
||||
double y1 = 0.0;
|
||||
double x = m_data.read_coord();
|
||||
double y = m_data.read_coord();
|
||||
rel_to_abs(&x1, &y1);
|
||||
|
||||
if(cmd == 't')
|
||||
{
|
||||
rel_to_abs(&x, &y);
|
||||
}
|
||||
if(agg::is_curve(last_command()) && m_num_vertices > 3)
|
||||
{
|
||||
x1 += x1 - m_vertices[m_num_vertices - 4];
|
||||
y1 += y1 - m_vertices[m_num_vertices - 3];
|
||||
}
|
||||
m_vertices[0] = x1;
|
||||
m_vertices[1] = y1;
|
||||
m_vertices[2] = x;
|
||||
m_vertices[3] = y;
|
||||
m_num_vertices = 4;
|
||||
m_last_command = cmd;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class DA>
|
||||
void path_interpreter<DA>::curve4_to(unsigned cmd)
|
||||
{
|
||||
double x1 = m_data.read_coord();
|
||||
double y1 = m_data.read_coord();
|
||||
double x2 = m_data.read_coord();
|
||||
double y2 = m_data.read_coord();
|
||||
double x = m_data.read_coord();
|
||||
double y = m_data.read_coord();
|
||||
if(cmd == 'c')
|
||||
{
|
||||
rel_to_abs(&x1, &y1);
|
||||
rel_to_abs(&x2, &y2);
|
||||
rel_to_abs(&x, &y);
|
||||
}
|
||||
m_vertices[0] = x1;
|
||||
m_vertices[1] = y1;
|
||||
m_vertices[2] = x2;
|
||||
m_vertices[3] = y2;
|
||||
m_vertices[4] = x;
|
||||
m_vertices[5] = y;
|
||||
m_num_vertices = 6;
|
||||
m_last_command = cmd;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class DA>
|
||||
void path_interpreter<DA>::curve4_to_ref(unsigned cmd)
|
||||
{
|
||||
double x1 = 0.0;
|
||||
double y1 = 0.0;
|
||||
double x2 = m_data.read_coord();
|
||||
double y2 = m_data.read_coord();
|
||||
double x = m_data.read_coord();
|
||||
double y = m_data.read_coord();
|
||||
rel_to_abs(&x1, &y1);
|
||||
|
||||
if(cmd == 's')
|
||||
{
|
||||
rel_to_abs(&x, &y);
|
||||
rel_to_abs(&x2, &y2);
|
||||
}
|
||||
if(agg::is_curve(last_command()) && m_num_vertices > 3)
|
||||
{
|
||||
x1 += x1 - m_vertices[m_num_vertices - 4];
|
||||
y1 += y1 - m_vertices[m_num_vertices - 3];
|
||||
}
|
||||
m_vertices[0] = x1;
|
||||
m_vertices[1] = y1;
|
||||
m_vertices[2] = x2;
|
||||
m_vertices[3] = y2;
|
||||
m_vertices[4] = x;
|
||||
m_vertices[5] = y;
|
||||
m_num_vertices = 6;
|
||||
m_last_command = cmd;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class DA>
|
||||
void path_interpreter<DA>::arc_to(unsigned cmd)
|
||||
{
|
||||
const double epsilon = 1e-30;
|
||||
|
||||
double x0 = 0.0;
|
||||
double y0 = 0.0;
|
||||
double rx = m_data.read_coord();
|
||||
double ry = m_data.read_coord();
|
||||
double x_axis_rotation = m_data.read_coord();
|
||||
bool large_arc_flag = m_data.read_int8u() != '0';
|
||||
bool sweep_flag = m_data.read_int8u() != '0';
|
||||
double x = m_data.read_coord();
|
||||
double y = m_data.read_coord();
|
||||
|
||||
if(m_num_vertices > 1)
|
||||
{
|
||||
x0 = m_vertices[m_num_vertices - 2];
|
||||
y0 = m_vertices[m_num_vertices - 1];
|
||||
}
|
||||
if(cmd == 'a')
|
||||
{
|
||||
rel_to_abs(&x, &y);
|
||||
}
|
||||
|
||||
rx = fabs(rx);
|
||||
ry = fabs(ry);
|
||||
|
||||
if(rx < epsilon || ry < epsilon)
|
||||
{
|
||||
m_vertices[0] = x;
|
||||
m_vertices[1] = y;
|
||||
m_num_vertices = 2;
|
||||
m_last_command = (cmd == 'a') ? 'l' : 'L';
|
||||
return;
|
||||
}
|
||||
|
||||
if(agg::calc_distance(x0, y0, x, y) < epsilon)
|
||||
{
|
||||
return;
|
||||
}
|
||||
agg::bezier_arc_svg a(x0, y0,
|
||||
rx, ry,
|
||||
x_axis_rotation,
|
||||
large_arc_flag, sweep_flag,
|
||||
x, y);
|
||||
if(a.radii_ok())
|
||||
{
|
||||
for(unsigned i = 2; i < a.num_vertices(); i += 2)
|
||||
{
|
||||
m_vertices[i - 2] = a.vertices()[i];
|
||||
m_vertices[i - 1] = a.vertices()[i + 1];
|
||||
}
|
||||
m_num_vertices = a.num_vertices() - 2;
|
||||
m_last_command = cmd;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_vertices[0] = x;
|
||||
m_vertices[1] = y;
|
||||
m_num_vertices = 2;
|
||||
m_last_command = (cmd == 'a') ? 'l' : 'L';
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class DA>
|
||||
void path_interpreter<DA>::close_subpath(unsigned cmd)
|
||||
{
|
||||
m_vertices[0] = m_start_x;
|
||||
m_vertices[1] = m_start_y;
|
||||
m_num_vertices = 2;
|
||||
m_vertex = 0;
|
||||
m_last_command = cmd;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class DA>
|
||||
const typename path_interpreter<DA>::command_handler
|
||||
path_interpreter<DA>::m_command_handlers[58] =
|
||||
{
|
||||
&path_interpreter<DA>::arc_to, //065 A
|
||||
0, //066 B
|
||||
&path_interpreter<DA>::curve4_to, //067 C
|
||||
0, //068 D
|
||||
0, //069 E
|
||||
0, //070 F
|
||||
0, //071 G
|
||||
&path_interpreter<DA>::hline_to, //072 H
|
||||
0, //073 I
|
||||
0, //074 J
|
||||
0, //075 K
|
||||
&path_interpreter<DA>::line_to, //076 L
|
||||
&path_interpreter<DA>::move_to, //077 M
|
||||
0, //078 N
|
||||
0, //079 O
|
||||
0, //080 P
|
||||
&path_interpreter<DA>::curve3_to, //081 Q
|
||||
0, //082 R
|
||||
&path_interpreter<DA>::curve4_to_ref, //083 S
|
||||
&path_interpreter<DA>::curve3_to_ref, //084 T
|
||||
0, //085 U
|
||||
&path_interpreter<DA>::vline_to, //086 V
|
||||
0, //087 W
|
||||
0, //088 X
|
||||
0, //089 Y
|
||||
&path_interpreter<DA>::close_subpath, //090 Z
|
||||
0, //091 [
|
||||
0, //092 backslash
|
||||
0, //093 ]
|
||||
0, //094 ^
|
||||
0, //095 _
|
||||
0, //096 '
|
||||
&path_interpreter<DA>::arc_to, //097 a
|
||||
0, //098 b
|
||||
&path_interpreter<DA>::curve4_to, //099 c
|
||||
0, //100 d
|
||||
0, //101 e
|
||||
0, //102 f
|
||||
0, //103 g
|
||||
&path_interpreter<DA>::hline_to, //104 h
|
||||
0, //105 i
|
||||
0, //106 j
|
||||
0, //107 k
|
||||
&path_interpreter<DA>::line_to, //108 l
|
||||
&path_interpreter<DA>::move_to, //109 m
|
||||
0, //110 n
|
||||
0, //111 o
|
||||
0, //112 p
|
||||
&path_interpreter<DA>::curve3_to, //113 q
|
||||
0, //114 r
|
||||
&path_interpreter<DA>::curve4_to_ref, //115 s
|
||||
&path_interpreter<DA>::curve3_to_ref, //116 t
|
||||
0, //117 u
|
||||
&path_interpreter<DA>::vline_to, //118 v
|
||||
0, //119 w
|
||||
0, //120 x
|
||||
0, //121 y
|
||||
&path_interpreter<DA>::close_subpath //122 z
|
||||
};
|
||||
|
||||
|
||||
// AGG Vertex Source interface functions
|
||||
//------------------------------------------------------------------------
|
||||
template<class DA>
|
||||
void path_interpreter<DA>::rewind(unsigned)
|
||||
{
|
||||
m_data = m_accessor;
|
||||
m_num_vertices = 0;
|
||||
m_vertex = 0;
|
||||
m_start_x = 0.0;
|
||||
m_start_y = 0.0;
|
||||
m_last_command = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class DA>
|
||||
unsigned path_interpreter<DA>::vertex(double* x, double* y)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
if(m_vertex < m_num_vertices)
|
||||
{
|
||||
*x = m_vertices[m_vertex++];
|
||||
*y = m_vertices[m_vertex++];
|
||||
break;
|
||||
}
|
||||
|
||||
if(m_data.size() == 0)
|
||||
{
|
||||
*x = *y = 0.0;
|
||||
return agg::path_cmd_stop;
|
||||
}
|
||||
|
||||
unsigned cmd = m_data.read_int8u();
|
||||
|
||||
//----------------------------
|
||||
command_handler ch;
|
||||
if(cmd >= 'A' && cmd <= 'z' &&
|
||||
(ch = m_command_handlers[cmd - 'A']) != 0)
|
||||
{
|
||||
(this->*ch)(cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_last_command = 0;
|
||||
return agg::path_cmd_stop;
|
||||
}
|
||||
m_vertex = 0;
|
||||
}
|
||||
return last_command();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Similar to path_interpreter.
|
||||
//
|
||||
// Use flag "closed=false" for polylines and "closed=true" for polygons.
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
template<class DataAccessor> class poly_interpreter
|
||||
{
|
||||
public:
|
||||
typedef DataAccessor data_accessor_type;
|
||||
typedef typename data_accessor_type::value_type value_type;
|
||||
|
||||
poly_interpreter() :
|
||||
m_accessor(),
|
||||
m_data(),
|
||||
m_closed(false),
|
||||
m_stop(false)
|
||||
{}
|
||||
|
||||
poly_interpreter(const data_accessor_type& data, bool closed) :
|
||||
m_accessor(data),
|
||||
m_data(data),
|
||||
m_closed(closed),
|
||||
m_stop(false)
|
||||
{}
|
||||
|
||||
void init(const data_accessor_type& data, bool closed)
|
||||
{
|
||||
m_accessor = data;
|
||||
m_data = data;
|
||||
m_closed = closed;
|
||||
m_stop = false;
|
||||
}
|
||||
|
||||
void rewind(unsigned)
|
||||
{
|
||||
m_data = m_accessor;
|
||||
m_stop = false;
|
||||
}
|
||||
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
if(m_data.size())
|
||||
{
|
||||
bool first = m_data.size() == m_accessor.size();
|
||||
*x = m_data.read_coord();
|
||||
*y = m_data.read_coord();
|
||||
return first ? agg::path_cmd_move_to : agg::path_cmd_line_to;
|
||||
}
|
||||
*x = *y = 0.0;
|
||||
if(m_closed && !m_stop)
|
||||
{
|
||||
m_stop = true;
|
||||
return agg::path_cmd_end_poly | agg::path_flags_close;
|
||||
}
|
||||
return agg::path_cmd_stop;
|
||||
}
|
||||
|
||||
private:
|
||||
data_accessor_type m_accessor;
|
||||
data_accessor_type m_data;
|
||||
bool m_closed;
|
||||
bool m_stop;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
453
DesktopEditor/agg-2.4/svg/agg_svg_path_renderer.cpp
Normal file
453
DesktopEditor/agg-2.4/svg/agg_svg_path_renderer.cpp
Normal file
@ -0,0 +1,453 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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();
|
||||
m_all_gradients.remove_all();
|
||||
}
|
||||
|
||||
void path_renderer::push_gradient(gradient_struct::GRADIENT_TYPE grTp)
|
||||
{
|
||||
m_all_gradients.add(gradient_struct());
|
||||
gradient_struct& curGr = cur_gradient();
|
||||
curGr.gradient_type = grTp;
|
||||
}
|
||||
void path_renderer::add_color_to_gradient(const rgba8& f, double offs)
|
||||
{
|
||||
if(m_all_gradients.size() == 0)
|
||||
return;
|
||||
gradient_struct& curGr = cur_gradient();
|
||||
curGr.push_color(f,offs);
|
||||
}
|
||||
void path_renderer::set_id_to_gradient(const char* nid)
|
||||
{
|
||||
if(m_all_gradients.size() == 0 || !nid)
|
||||
return;
|
||||
gradient_struct& curGr = cur_gradient();
|
||||
strcpy(curGr.id_string,nid);
|
||||
}
|
||||
void path_renderer::set_val_to_gradient(gradient_struct::vals_ids idV, double valNumb)
|
||||
{
|
||||
if(m_all_gradients.size() == 0)
|
||||
return;
|
||||
gradient_struct& curGr = cur_gradient();
|
||||
curGr.rect_points[idV] = valNumb;
|
||||
}
|
||||
void path_renderer::set_colors_from_other(const char* other_id)
|
||||
{
|
||||
if(m_all_gradients.size() == 0)
|
||||
return;
|
||||
gradient_struct& curGr = cur_gradient();
|
||||
unsigned cnt = m_all_gradients.size();
|
||||
for (unsigned i=0;i<cnt-1;i++)
|
||||
{
|
||||
if (strcmp(m_all_gradients[i].id_string, other_id) == 0)
|
||||
{
|
||||
unsigned cnt_2 = m_all_gradients[i].all_colors.size();
|
||||
for (unsigned j=0;j<cnt_2;j++)
|
||||
curGr.all_colors.add(m_all_gradients[i].all_colors[j]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void path_renderer::set_gradient_brush_to_path(const char* gr_id)
|
||||
{
|
||||
if(m_all_gradients.size() == 0)
|
||||
return;
|
||||
path_attributes& attr = cur_attr();
|
||||
unsigned cnt = m_all_gradients.size();
|
||||
for (unsigned i=0;i<cnt;i++)
|
||||
{
|
||||
if (strcmp(m_all_gradients[i].id_string, gr_id) == 0)
|
||||
{
|
||||
attr.gradient_brush = &m_all_gradients[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
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::arc(double rx, double ry, // A, a
|
||||
double angle,
|
||||
bool large_arc_flag,
|
||||
bool sweep_flag,
|
||||
double dx, double dy,
|
||||
bool rel)
|
||||
{
|
||||
if(rel)
|
||||
{
|
||||
m_storage.rel_to_abs(&dx, &dy);
|
||||
}
|
||||
m_storage.arc_to(rx, ry, angle, large_arc_flag, sweep_flag, dx, dy);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
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];
|
||||
}
|
||||
|
||||
gradient_struct& path_renderer::cur_gradient()
|
||||
{
|
||||
if(m_all_gradients.size() == 0)
|
||||
{
|
||||
throw exception("cur_gradient : Gradients stack is empty");
|
||||
}
|
||||
return m_all_gradients[m_all_gradients.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;
|
||||
bool b1,b2;
|
||||
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);
|
||||
}
|
||||
b1 = fabs(arg[3]-1)<0.00001;
|
||||
b2 = fabs(arg[4]-1)<0.00001;
|
||||
arc(arg[0], arg[1], arg[2], b1, b2, arg[5], arg[6], cmd == 'a');
|
||||
break;
|
||||
case 'Z': case 'z':
|
||||
close_subpath();
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
char buf[100];
|
||||
sprintf(buf, "parse_path: Invalid Command %c", cmd);
|
||||
throw exception(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
405
DesktopEditor/agg-2.4/svg/agg_svg_path_renderer.h
Normal file
405
DesktopEditor/agg-2.4/svg/agg_svg_path_renderer.h
Normal file
@ -0,0 +1,405 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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_path_storage.h"
|
||||
#include "agg_conv_transform.h"
|
||||
#include "agg_conv_stroke.h"
|
||||
#include "agg_conv_contour.h"
|
||||
#include "agg_conv_curve.h"
|
||||
#include "agg_color_rgba.h"
|
||||
#include "agg_renderer_scanline.h"
|
||||
#include "agg_bounding_rect.h"
|
||||
#include "agg_rasterizer_scanline_aa.h"
|
||||
#include "agg_svg_path_tokenizer.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
struct stop_color
|
||||
{
|
||||
rgba8 color;
|
||||
double offset;
|
||||
};
|
||||
struct gradient_struct
|
||||
{
|
||||
typedef pod_bvector<stop_color> colors_storage;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LINEAR_GR,
|
||||
RADIAL_GR
|
||||
} GRADIENT_TYPE;
|
||||
GRADIENT_TYPE gradient_type;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
X1 = 0,
|
||||
Y1 = 1,
|
||||
X2 = 2,
|
||||
Y2 = 3,
|
||||
CX = 0,
|
||||
CY = 1,
|
||||
R = 2,
|
||||
FX = 3,
|
||||
FY = 4
|
||||
} vals_ids;
|
||||
|
||||
colors_storage all_colors;
|
||||
char id_string[128];
|
||||
double rect_points[5]; // x1, y1, x2, y2 - for LINEAR_GR
|
||||
// cx, cy, r , fx, fy - for RADIAL_GR
|
||||
|
||||
gradient_struct():gradient_type(LINEAR_GR)
|
||||
{
|
||||
id_string[0]='\0';
|
||||
memset(rect_points,0,sizeof(double)*5);
|
||||
}
|
||||
void push_color(const rgba8& col, double offs)
|
||||
{
|
||||
stop_color colr;
|
||||
colr.color = col;
|
||||
colr.offset = offs;
|
||||
all_colors.add(colr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
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;
|
||||
gradient_struct* gradient_brush;
|
||||
|
||||
// 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(),
|
||||
gradient_brush(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
// 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),
|
||||
gradient_brush(attr.gradient_brush)
|
||||
{
|
||||
}
|
||||
|
||||
// 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),
|
||||
gradient_brush(attr.gradient_brush)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//============================================================================
|
||||
// Path container and renderer.
|
||||
class path_renderer
|
||||
{
|
||||
public:
|
||||
typedef pod_bvector<gradient_struct> gradients_storage;
|
||||
|
||||
void push_gradient(gradient_struct::GRADIENT_TYPE grTp);
|
||||
void add_color_to_gradient(const rgba8& f, double offs);
|
||||
void set_id_to_gradient(const char* nid);
|
||||
void set_val_to_gradient(gradient_struct::vals_ids idV, double valNumb);
|
||||
void set_colors_from_other(const char* other_id);
|
||||
|
||||
void set_gradient_brush_to_path(const char* gr_id);
|
||||
|
||||
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 arc(double rx, double ry, // A, a
|
||||
double angle,
|
||||
bool large_arc_flag,
|
||||
bool sweep_flag,
|
||||
double dx, double dy,
|
||||
bool rel);
|
||||
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.gradient_brush)
|
||||
{
|
||||
ras.reset();
|
||||
ras.filling_rule(fill_even_odd);
|
||||
m_curved_trans_contour.miter_limit(attr.miter_limit);
|
||||
ras.add_path(m_curved_trans_contour, attr.index);
|
||||
ren.color(rgba8(0,255,0));
|
||||
agg::render_scanlines(ras, sl, ren);
|
||||
}
|
||||
else
|
||||
{
|
||||
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();
|
||||
gradient_struct& cur_gradient();
|
||||
|
||||
path_storage m_storage;
|
||||
attr_storage m_attr_storage;
|
||||
attr_storage m_attr_stack;
|
||||
trans_affine m_transform;
|
||||
|
||||
gradients_storage m_all_gradients;
|
||||
|
||||
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
|
||||
614
DesktopEditor/agg-2.4/svg/agg_svg_path_serializer.h
Normal file
614
DesktopEditor/agg-2.4/svg/agg_svg_path_serializer.h
Normal file
@ -0,0 +1,614 @@
|
||||
#ifndef AGG_SVG_PATH_SERIALIZER_INCLUDED
|
||||
#define AGG_SVG_PATH_SERIALIZER_INCLUDED
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "agg_array.h"
|
||||
#include "agg_svg_basics.h"
|
||||
#include "agg_svg_parse_real.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// The tokenizer does all the routine job of parsing the SVG paths.
|
||||
//----------------------------------------------------------------------------
|
||||
template<class CharT=char> class path_tokenizer
|
||||
{
|
||||
public:
|
||||
typedef CharT value_type;
|
||||
|
||||
path_tokenizer();
|
||||
|
||||
void path_str(const value_type* str);
|
||||
bool rewind();
|
||||
bool token();
|
||||
|
||||
double token(value_type cmd);
|
||||
|
||||
value_type last_command() const { return m_last_command; }
|
||||
double last_number() const { return m_last_number; }
|
||||
bool multiple_coordinate_pair() const
|
||||
{
|
||||
return (m_num_count > 2) && (m_num_count & 1) == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
static void init_mask(agg::int8u* mask, const agg::int8u* char_set);
|
||||
|
||||
bool contains(const agg::int8u* 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();
|
||||
|
||||
agg::int8u m_separators_mask[256/8];
|
||||
agg::int8u m_commands_mask[256/8];
|
||||
agg::int8u m_numeric_mask[256/8];
|
||||
|
||||
const value_type* m_str;
|
||||
const value_type* m_ptr;
|
||||
double m_last_number;
|
||||
unsigned m_num_count;
|
||||
value_type m_last_command;
|
||||
|
||||
|
||||
static const agg::int8u s_commands[];
|
||||
static const agg::int8u s_numeric[];
|
||||
static const agg::int8u s_separators[];
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class CharT>
|
||||
const agg::int8u path_tokenizer<CharT>::s_commands[] = "+-MmZzLlHhVvCcSsQqTtAa";
|
||||
|
||||
template<class CharT>
|
||||
const agg::int8u path_tokenizer<CharT>::s_numeric[] = ".0123456789";
|
||||
|
||||
template<class CharT>
|
||||
const agg::int8u path_tokenizer<CharT>::s_separators[] = " ,\t\n\r";
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class CharT>
|
||||
path_tokenizer<CharT>::path_tokenizer() :
|
||||
m_str(0), m_ptr(0), m_last_number(0.0), m_num_count(0), m_last_command(0)
|
||||
{
|
||||
init_mask(m_commands_mask, s_commands);
|
||||
init_mask(m_numeric_mask, s_numeric);
|
||||
init_mask(m_separators_mask, s_separators);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class CharT>
|
||||
void path_tokenizer<CharT>::path_str(const CharT* str)
|
||||
{
|
||||
m_ptr = m_str = str;
|
||||
m_last_command = 0;
|
||||
m_num_count = 0;
|
||||
m_last_number = 0.0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class CharT>
|
||||
void path_tokenizer<CharT>::init_mask(agg::int8u* mask, const agg::int8u* char_set)
|
||||
{
|
||||
memset(mask, 0, 256/8);
|
||||
while(*char_set)
|
||||
{
|
||||
unsigned c = unsigned(*char_set++) & 0xFF;
|
||||
mask[c >> 3] |= 1 << (c & 7);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class CharT>
|
||||
bool path_tokenizer<CharT>::rewind()
|
||||
{
|
||||
m_ptr = m_str;
|
||||
m_last_command = 0;
|
||||
m_num_count = 0;
|
||||
m_last_number = 0.0;
|
||||
return m_str != 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class CharT>
|
||||
bool path_tokenizer<CharT>::token()
|
||||
{
|
||||
if(m_ptr == 0) return false;
|
||||
|
||||
// Skip all white spaces and other garbage
|
||||
while(*m_ptr && !is_command(*m_ptr) && !is_numeric(*m_ptr))
|
||||
{
|
||||
if(!is_separator(*m_ptr))
|
||||
{
|
||||
throw exception("Parsing Path Structure: Invalid Character %c", *m_ptr);
|
||||
}
|
||||
m_ptr++;
|
||||
}
|
||||
|
||||
if(*m_ptr == 0) return false;
|
||||
|
||||
if(is_command(*m_ptr))
|
||||
{
|
||||
// Check if the command is a numeric sign character
|
||||
if(*m_ptr == '-' || *m_ptr == '+')
|
||||
{
|
||||
return parse_number();
|
||||
}
|
||||
m_last_command = *m_ptr++;
|
||||
m_num_count = 0;
|
||||
while(*m_ptr && is_separator(*m_ptr)) m_ptr++;
|
||||
if(*m_ptr == 0) return true;
|
||||
}
|
||||
return parse_number();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class CharT>
|
||||
double path_tokenizer<CharT>::token(CharT cmd)
|
||||
{
|
||||
if(!token())
|
||||
{
|
||||
throw exception("Parsing Path Structure: Unexpected end of Path");
|
||||
}
|
||||
if(last_command() != cmd)
|
||||
{
|
||||
throw exception("Parsing Path Structure: Command %c is bad or missing parameters", cmd);
|
||||
}
|
||||
return last_number();
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
template<class CharT>
|
||||
bool path_tokenizer<CharT>::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_ptr == '-' || *m_ptr == '+')
|
||||
{
|
||||
*buf_ptr++ = char(*m_ptr++);
|
||||
}
|
||||
|
||||
// Copy all numeric characters
|
||||
while(buf_ptr < buf+255 && is_numeric(*m_ptr))
|
||||
{
|
||||
*buf_ptr++ = char(*m_ptr++);
|
||||
}
|
||||
|
||||
// check for exponent
|
||||
if (*m_ptr == 'e' || *m_ptr == 'E')
|
||||
{
|
||||
*buf_ptr++ = char(*m_ptr++);
|
||||
// Copy all sign characters
|
||||
while(buf_ptr < buf+255 && *m_ptr == '-' || *m_ptr == '+')
|
||||
{
|
||||
*buf_ptr++ = char(*m_ptr++);
|
||||
}
|
||||
|
||||
// Copy all numeric characters
|
||||
while(buf_ptr < buf+255 && is_numeric(*m_ptr))
|
||||
{
|
||||
*buf_ptr++ = char(*m_ptr++);
|
||||
}
|
||||
}
|
||||
|
||||
*buf_ptr = 0;
|
||||
|
||||
const char* endptr = 0;
|
||||
parse_real pd;
|
||||
|
||||
pd.parse(buf, buf + strlen(buf), &m_last_number, &endptr);
|
||||
++m_num_count;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Ths class is used to parse, validate, and serialize paths into binary format.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
template<class Container> class path_serializer
|
||||
{
|
||||
public:
|
||||
typedef Container container_type;
|
||||
|
||||
path_serializer(container_type& buffer);
|
||||
|
||||
// Make path
|
||||
//------------------------------------------------------------------------
|
||||
void reset();
|
||||
void move_to(double x, double y, bool rel=false);
|
||||
void line_to(double x, double y, bool rel=false);
|
||||
void hline_to(double x, bool rel=false);
|
||||
void vline_to(double y, bool rel=false);
|
||||
void curve3_to(double x1, double y1, double x, double y, bool rel=false);
|
||||
void curve3_to(double x, double y, bool rel=false);
|
||||
|
||||
void curve4_to(double x1, double y1, double x2, double y2,
|
||||
double x, double y, bool rel=false);
|
||||
|
||||
void curve4_to(double x2, double y2, double x, double y, bool rel=false);
|
||||
|
||||
void arc_to(double rx, double ry, double x_axis_rotation,
|
||||
bool large_arc_flag, bool sweep_flag,
|
||||
double x, double y, bool rel=false);
|
||||
void close_subpath();
|
||||
|
||||
// Parse path string.
|
||||
//------------------------------------------------------------------------
|
||||
template<class Tokenizer> void parse(Tokenizer& tok)
|
||||
{
|
||||
reset();
|
||||
if(!tok.rewind()) return;
|
||||
while(tok.token())
|
||||
{
|
||||
double arg[10];
|
||||
unsigned cmd = tok.last_command();
|
||||
unsigned i;
|
||||
switch(cmd)
|
||||
{
|
||||
case 'M': case 'm':
|
||||
arg[0] = tok.last_number();
|
||||
arg[1] = tok.token(cmd);
|
||||
if(tok.multiple_coordinate_pair())
|
||||
{
|
||||
line_to(arg[0], arg[1], cmd == 'm');
|
||||
}
|
||||
else
|
||||
{
|
||||
move_to(arg[0], arg[1], cmd == 'm');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'L': case 'l':
|
||||
arg[0] = tok.last_number();
|
||||
arg[1] = tok.token(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.token(cmd);
|
||||
}
|
||||
curve3_to(arg[0], arg[1], arg[2], arg[3], cmd == 'q');
|
||||
break;
|
||||
|
||||
case 'T': case 't':
|
||||
arg[0] = tok.last_number();
|
||||
arg[1] = tok.token(cmd);
|
||||
curve3_to(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.token(cmd);
|
||||
}
|
||||
curve4_to(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.token(cmd);
|
||||
}
|
||||
curve4_to(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.token(cmd);
|
||||
}
|
||||
arc_to(arg[0], arg[1], agg::deg2rad(arg[2]),
|
||||
arg[3] > 0.1, arg[4] > 0.1,
|
||||
arg[5], arg[6], cmd == 'a');
|
||||
break;
|
||||
|
||||
case 'Z': case 'z':
|
||||
close_subpath();
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
throw exception("Parsing Path Structure: Invalid Command %c", cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void check_last_vertex(unsigned cmd);
|
||||
void check_curve_reflection(unsigned cmd);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void append_c(unsigned chr)
|
||||
{
|
||||
m_buffer->add((agg::int8u)chr);
|
||||
}
|
||||
|
||||
void append_d(double val)
|
||||
{
|
||||
coord_type f = (coord_type)val;
|
||||
const agg::int8u* p = (const agg::int8u*)&f;
|
||||
unsigned i;
|
||||
for(i = 0; i < sizeof(coord_type); i++)
|
||||
{
|
||||
m_buffer->add(*p++);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
container_type* m_buffer;
|
||||
unsigned m_last_command;
|
||||
unsigned m_num_vertices;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Container>
|
||||
path_serializer<Container>::path_serializer(container_type& buffer) :
|
||||
m_buffer(&buffer),
|
||||
m_last_command(0),
|
||||
m_num_vertices(0)
|
||||
{}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Container>
|
||||
void path_serializer<Container>::check_last_vertex(unsigned cmd)
|
||||
{
|
||||
if(m_num_vertices == 0)
|
||||
{
|
||||
throw exception("Parsing Path Structure: Invalid use of command '%c' - Path must begin with 'M' or 'm'", cmd);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Container>
|
||||
void path_serializer<Container>::check_curve_reflection(unsigned cmd)
|
||||
{
|
||||
if(m_last_command == 'C' || m_last_command == 'c' ||
|
||||
m_last_command == 'S' || m_last_command == 's' ||
|
||||
m_last_command == 'Q' || m_last_command == 'q' ||
|
||||
m_last_command == 'T' || m_last_command == 't')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
throw exception("Parsing Path Structure: Invalid use of reflection in command '%c' - The command must be followed by a curve command", cmd);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Container>
|
||||
void path_serializer<Container>::reset()
|
||||
{
|
||||
m_last_command = 0;
|
||||
m_num_vertices = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Container>
|
||||
void path_serializer<Container>::move_to(double x, double y, bool rel)
|
||||
{
|
||||
append_c(m_last_command = (rel ? 'm' : 'M'));
|
||||
append_d(x);
|
||||
append_d(y);
|
||||
++m_num_vertices;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Container>
|
||||
void path_serializer<Container>::line_to(double x, double y, bool rel)
|
||||
{
|
||||
check_last_vertex(rel ? 'l' : 'L');
|
||||
append_c(m_last_command = (rel ? 'l' : 'L'));
|
||||
append_d(x);
|
||||
append_d(y);
|
||||
++m_num_vertices;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Container>
|
||||
void path_serializer<Container>::hline_to(double x, bool rel)
|
||||
{
|
||||
check_last_vertex(rel ? 'h' : 'H');
|
||||
append_c(m_last_command = (rel ? 'h' : 'H'));
|
||||
append_d(x);
|
||||
++m_num_vertices;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Container>
|
||||
void path_serializer<Container>::vline_to(double y, bool rel)
|
||||
{
|
||||
check_last_vertex(rel ? 'v' : 'V');
|
||||
append_c(m_last_command = (rel ? 'v' : 'V'));
|
||||
append_d(y);
|
||||
++m_num_vertices;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Container>
|
||||
void path_serializer<Container>::curve3_to(double x1, double y1,
|
||||
double x, double y,
|
||||
bool rel)
|
||||
{
|
||||
check_last_vertex(rel ? 'q' : 'Q');
|
||||
append_c(m_last_command = (rel ? 'q' : 'Q'));
|
||||
append_d(x1);
|
||||
append_d(y1);
|
||||
append_d(x);
|
||||
append_d(y);
|
||||
m_num_vertices += 2;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Container>
|
||||
void path_serializer<Container>::curve3_to(double x, double y, bool rel)
|
||||
{
|
||||
check_last_vertex(rel ? 't' : 'T');
|
||||
check_curve_reflection(rel ? 't' : 'T');
|
||||
append_c(m_last_command = (rel ? 't' : 'T'));
|
||||
append_d(x);
|
||||
append_d(y);
|
||||
++m_num_vertices;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Container>
|
||||
void path_serializer<Container>::curve4_to(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x, double y, bool rel)
|
||||
{
|
||||
check_last_vertex(rel ? 'c' : 'C');
|
||||
append_c(m_last_command = (rel ? 'c' : 'C'));
|
||||
append_d(x1);
|
||||
append_d(y1);
|
||||
append_d(x2);
|
||||
append_d(y2);
|
||||
append_d(x);
|
||||
append_d(y);
|
||||
m_num_vertices += 3;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Container>
|
||||
void path_serializer<Container>::curve4_to(double x2, double y2,
|
||||
double x, double y, bool rel)
|
||||
{
|
||||
check_last_vertex(rel ? 's' : 'S');
|
||||
check_curve_reflection(rel ? 's' : 'S');
|
||||
append_c(m_last_command = (rel ? 's' : 'S'));
|
||||
append_d(x2);
|
||||
append_d(y2);
|
||||
append_d(x);
|
||||
append_d(y);
|
||||
m_num_vertices += 2;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Container>
|
||||
void path_serializer<Container>::arc_to(double rx, double ry,
|
||||
double x_axis_rotation,
|
||||
bool large_arc_flag,
|
||||
bool sweep_flag,
|
||||
double x, double y,
|
||||
bool rel)
|
||||
{
|
||||
check_last_vertex(rel ? 'a' : 'A');
|
||||
append_c(m_last_command = (rel ? 'a' : 'A'));
|
||||
append_d(rx);
|
||||
append_d(ry);
|
||||
append_d(x_axis_rotation);
|
||||
append_c(large_arc_flag ? '1' : '0');
|
||||
append_c(sweep_flag ? '1' : '0');
|
||||
append_d(x);
|
||||
append_d(y);
|
||||
m_num_vertices += 3;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Container>
|
||||
void path_serializer<Container>::close_subpath()
|
||||
{
|
||||
append_c('z');
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Ths class is used to parse, validate, and serialize polygons and polylines
|
||||
// into binary format.
|
||||
//----------------------------------------------------------------------------
|
||||
template<class Container> class poly_serializer
|
||||
{
|
||||
public:
|
||||
typedef Container container_type;
|
||||
|
||||
poly_serializer(container_type& buffer) : m_buffer(&buffer) {}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Tokenizer> void parse(Tokenizer& tok, bool closed)
|
||||
{
|
||||
unsigned np = 0;
|
||||
while(tok.token())
|
||||
{
|
||||
double x = tok.last_number();
|
||||
if(!tok.token())
|
||||
{
|
||||
throw exception("Parsing Polygon Structure: Odd number of coordinates");
|
||||
}
|
||||
double y = tok.last_number();
|
||||
append_d(x);
|
||||
append_d(y);
|
||||
++np;
|
||||
}
|
||||
if(closed)
|
||||
{
|
||||
if(np < 3)
|
||||
{
|
||||
throw exception("Parsing Polygon Structure: Too few coordinates for polygon/polyline");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(np < 2)
|
||||
{
|
||||
throw exception("Parsing Polygon Structure: Too few coordinates for polygon/polyline");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void append_d(double val)
|
||||
{
|
||||
coord_type f = (coord_type)val;
|
||||
const agg::int8u* p = (const agg::int8u*)&f;
|
||||
unsigned i;
|
||||
for(i = 0; i < sizeof(coord_type); i++)
|
||||
{
|
||||
m_buffer->add(*p++);
|
||||
}
|
||||
}
|
||||
|
||||
container_type* m_buffer;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
143
DesktopEditor/agg-2.4/svg/agg_svg_path_tokenizer.cpp
Normal file
143
DesktopEditor/agg-2.4/svg/agg_svg_path_tokenizer.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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
|
||||
while(buf_ptr < buf+255 && is_numeric(*m_path))
|
||||
{
|
||||
*buf_ptr++ = *m_path++;
|
||||
}
|
||||
*buf_ptr = 0;
|
||||
m_last_number = atof(buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} //namespace svg
|
||||
} //namespace agg
|
||||
|
||||
|
||||
|
||||
|
||||
114
DesktopEditor/agg-2.4/svg/agg_svg_path_tokenizer.h
Normal file
114
DesktopEditor/agg-2.4/svg/agg_svg_path_tokenizer.h
Normal file
@ -0,0 +1,114 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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
|
||||
26
DesktopEditor/agg-2.4/svg/agg_svg_percent.h
Normal file
26
DesktopEditor/agg-2.4/svg/agg_svg_percent.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef AGG_SVG_PERCENT_INCLUDE
|
||||
#define AGG_SVG_PERCENT_INCLUDE
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
struct percent
|
||||
{
|
||||
static double decrypt(double val)
|
||||
{
|
||||
return (val > 1.)?
|
||||
(val - (double)difference_helper) / 100.:val;
|
||||
}
|
||||
static double encrypt(double val)
|
||||
{
|
||||
return (double)difference_helper + val;
|
||||
}
|
||||
private:
|
||||
enum {difference_helper = 2};
|
||||
};
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_PERCENT_INCLUDE
|
||||
251
DesktopEditor/agg-2.4/svg/agg_svg_pipeline.h
Normal file
251
DesktopEditor/agg-2.4/svg/agg_svg_pipeline.h
Normal file
@ -0,0 +1,251 @@
|
||||
#ifndef AGG_SVG_PIPELINE_INCLUDED
|
||||
#define AGG_SVG_PIPELINE_INCLUDED
|
||||
|
||||
#include "agg_svg_attributes.h"
|
||||
#include "agg_svg_transformer.h"
|
||||
#include "agg_svg_renderer_rgba.h"
|
||||
|
||||
#include "agg_conv_curve.h"
|
||||
#include "agg_conv_transform.h"
|
||||
#include "agg_conv_stroke.h"
|
||||
#include "agg_conv_contour.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
class conv_polymorphic_base
|
||||
{
|
||||
public:
|
||||
virtual ~conv_polymorphic_base() {}
|
||||
virtual void rewind(unsigned path_id) = 0;
|
||||
virtual unsigned vertex(double* x, double* y) = 0;
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
template<class VertexSource>
|
||||
class conv_polymorphic_wrapper : public conv_polymorphic_base
|
||||
{
|
||||
public:
|
||||
conv_polymorphic_wrapper(VertexSource& source) : m_source(&source) {}
|
||||
|
||||
virtual void rewind(unsigned path_id)
|
||||
{
|
||||
m_source->rewind(path_id);
|
||||
}
|
||||
|
||||
virtual unsigned vertex(double* x, double* y)
|
||||
{
|
||||
return m_source->vertex(x, y);
|
||||
}
|
||||
|
||||
private:
|
||||
VertexSource* m_source;
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
struct fake_vertex_source : public conv_polymorphic_base
|
||||
{
|
||||
public:
|
||||
virtual void rewind(unsigned) {}
|
||||
virtual unsigned vertex(double*, double*)
|
||||
{
|
||||
return agg::path_cmd_stop;
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
class pipeline
|
||||
{
|
||||
public:
|
||||
//-----------------------------------------------------------------------
|
||||
typedef agg::conv_curve<conv_polymorphic_base> conv_curve;
|
||||
typedef agg::conv_transform<conv_curve, transformer> conv_curve_trans;
|
||||
typedef agg::conv_stroke<conv_curve> conv_curve_stroke;
|
||||
typedef agg::conv_transform<conv_curve_stroke, transformer> conv_curve_stroke_trans;
|
||||
typedef agg::conv_contour<conv_curve_trans> conv_curve_trans_contour;
|
||||
//-----------------------------------------------------------------------
|
||||
pipeline()
|
||||
: m_fake_source()
|
||||
, m_identity_transformer()
|
||||
, m_conv_curve(m_fake_source)
|
||||
, m_conv_curve_trans(m_conv_curve, m_identity_transformer)
|
||||
, m_conv_curve_stroke(m_conv_curve)
|
||||
, m_conv_curve_stroke_trans(m_conv_curve_stroke, m_identity_transformer)
|
||||
, m_conv_curve_trans_contour(m_conv_curve_trans)
|
||||
, m_approximation_scale(4.0)
|
||||
{
|
||||
m_conv_curve_stroke.inner_join(agg::inner_round);
|
||||
m_conv_curve_trans_contour.auto_detect_orientation(false);
|
||||
|
||||
m_conv_curve_trans_contour.width(0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void approximation_scale(double s) { m_approximation_scale = s; }
|
||||
double approximation_scale() const { return m_approximation_scale; }
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
#ifdef EXPAND_PATHS
|
||||
// Expand all polygons
|
||||
void expand(double value)
|
||||
{
|
||||
m_conv_curve_trans_contour.width(value);
|
||||
}
|
||||
#endif
|
||||
//-----------------------------------------------------------------------
|
||||
template<class Source>
|
||||
void render(const attributes& attr, Source& src, renderer_rgba& ren)
|
||||
{
|
||||
if(!ren.is_valid()) return;
|
||||
conv_polymorphic_wrapper<Source> psrc(src);
|
||||
m_conv_curve.attach(psrc);
|
||||
unsigned cmd;
|
||||
double x, y;
|
||||
|
||||
double scale = attr.scale() * m_approximation_scale;
|
||||
m_conv_curve.approximation_scale(scale);
|
||||
m_conv_curve.angle_tolerance(0.0);
|
||||
m_conv_curve_stroke.approximation_scale(scale);
|
||||
|
||||
ren.clip_box(attr.clip_x1(), attr.clip_y1(), attr.clip_x2(), attr.clip_y2());
|
||||
|
||||
if(attr.fill_type() != paint_none)
|
||||
{
|
||||
ren.reset();
|
||||
m_conv_curve_trans.transformer(attr.transform());
|
||||
|
||||
if(fabs(m_conv_curve_trans_contour.width()) < 0.0001)
|
||||
{
|
||||
m_conv_curve_trans.rewind(0);
|
||||
while(!agg::is_stop(cmd = m_conv_curve_trans.vertex(&x, &y)))
|
||||
{
|
||||
ren.add_vertex(x, y, cmd);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_conv_curve_trans_contour.miter_limit(attr.stroke_miterlimit());
|
||||
m_conv_curve_trans_contour.rewind(0);
|
||||
while(!agg::is_stop(cmd = m_conv_curve_trans_contour.vertex(&x, &y)))
|
||||
{
|
||||
ren.add_vertex(x, y, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
ren.fill(attr);
|
||||
}
|
||||
|
||||
if(attr.stroke_type() != paint_none)
|
||||
{
|
||||
ren.reset();
|
||||
m_conv_curve_stroke_trans.transformer(attr.transform());
|
||||
m_conv_curve_stroke.width(attr.stroke_width());
|
||||
m_conv_curve_stroke.line_join(g_stroke_linejoin_lut[attr.stroke_linejoin()]);
|
||||
m_conv_curve_stroke.line_cap(g_stroke_linecap_lut[attr.stroke_linecap()]);
|
||||
m_conv_curve_stroke.miter_limit(attr.stroke_miterlimit());
|
||||
|
||||
if(attr.stroke_width() * scale > 1.0)
|
||||
{
|
||||
m_conv_curve.angle_tolerance(agg::deg2rad(10.0));
|
||||
}
|
||||
|
||||
m_conv_curve_stroke_trans.rewind(0);
|
||||
while(!agg::is_stop(cmd = m_conv_curve_stroke_trans.vertex(&x, &y)))
|
||||
{
|
||||
ren.add_vertex(x, y, cmd);
|
||||
}
|
||||
ren.stroke(attr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
//-----------------------------------------------------------------------
|
||||
transformer m_identity_transformer;
|
||||
fake_vertex_source m_fake_source;
|
||||
conv_curve m_conv_curve;
|
||||
conv_curve_trans m_conv_curve_trans;
|
||||
conv_curve_stroke m_conv_curve_stroke;
|
||||
conv_curve_stroke_trans m_conv_curve_stroke_trans;
|
||||
conv_curve_trans_contour m_conv_curve_trans_contour;
|
||||
double m_approximation_scale;
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
class object_bbox
|
||||
{
|
||||
public:
|
||||
//-----------------------------------------------------------------------
|
||||
typedef agg::conv_curve<conv_polymorphic_base> conv_curve;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
object_bbox() :
|
||||
m_fake_source(),
|
||||
m_conv_curve(m_fake_source),
|
||||
m_minx(1e100),
|
||||
m_miny(1e100),
|
||||
m_maxx(-1e100),
|
||||
m_maxy(-1e100)
|
||||
{}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void reset()
|
||||
{
|
||||
m_minx = 1e100;
|
||||
m_miny = 1e100;
|
||||
m_maxx = -1e100;
|
||||
m_maxy = -1e100;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template<class Source> void calculate(const attributes& attr,
|
||||
Source& src,
|
||||
bool reset_flag=true)
|
||||
{
|
||||
if(reset_flag) reset();
|
||||
|
||||
conv_polymorphic_wrapper<Source> psrc(src);
|
||||
m_conv_curve.attach(psrc);
|
||||
unsigned cmd;
|
||||
double x, y;
|
||||
|
||||
m_conv_curve.approximation_scale(attr.scale());
|
||||
m_conv_curve.rewind(0);
|
||||
while(!agg::is_stop(cmd = m_conv_curve.vertex(&x, &y)))
|
||||
{
|
||||
if(agg::is_vertex(cmd))
|
||||
{
|
||||
if(x < m_minx) m_minx = x;
|
||||
if(y < m_miny) m_miny = y;
|
||||
if(x > m_maxx) m_maxx = x;
|
||||
if(y > m_maxy) m_maxy = y;
|
||||
}
|
||||
}
|
||||
m_conv_curve.attach(m_fake_source);
|
||||
}
|
||||
|
||||
double minx() const { return m_minx; }
|
||||
double miny() const { return m_miny; }
|
||||
double maxx() const { return m_maxx; }
|
||||
double maxy() const { return m_maxy; }
|
||||
rectangle bbox() const { return rectangle(m_minx, m_miny, m_maxx, m_maxy); }
|
||||
|
||||
private:
|
||||
fake_vertex_source m_fake_source;
|
||||
conv_curve m_conv_curve;
|
||||
double m_minx;
|
||||
double m_miny;
|
||||
double m_maxx;
|
||||
double m_maxy;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
42
DesktopEditor/agg-2.4/svg/agg_svg_ptr_size_pair.h
Normal file
42
DesktopEditor/agg-2.4/svg/agg_svg_ptr_size_pair.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef AGG_SVG_PTR_SIZE_PAIR_INCLUDE
|
||||
#define AGG_SVG_PTR_SIZE_PAIR_INCLUDE
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_basics.h"
|
||||
#include <cassert>
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
struct ptr_size
|
||||
{
|
||||
ptr_size(const void * ptr, agg::int32u size)
|
||||
: m_ptr(static_cast<const agg::int8u *>(ptr)),
|
||||
m_size(size)
|
||||
{
|
||||
}
|
||||
|
||||
const agg::int8u * m_ptr;
|
||||
agg::int32u m_size;
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
struct ptr_size_short
|
||||
{
|
||||
ptr_size_short(const void * ptr, agg::int32u size)
|
||||
: m_ptr(static_cast<const agg::int8u *>(ptr)),
|
||||
m_size(static_cast<agg::int8u>(size))
|
||||
{
|
||||
assert(m_size == size);
|
||||
}
|
||||
|
||||
const agg::int8u * m_ptr;
|
||||
agg::int8u m_size;
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_PTR_SIZE_PAIR_INCLUDE
|
||||
|
||||
87
DesktopEditor/agg-2.4/svg/agg_svg_rasterizer.h
Normal file
87
DesktopEditor/agg-2.4/svg/agg_svg_rasterizer.h
Normal file
@ -0,0 +1,87 @@
|
||||
#ifndef AGG_SVG_RASTERIZER_INCLUDED
|
||||
#define AGG_SVG_RASTERIZER_INCLUDED
|
||||
|
||||
#include "agg_rasterizer_scanline_aa.h"
|
||||
#include "agg_scanline_u.h"
|
||||
#include "agg_span_allocator.h"
|
||||
#include "agg_svg_attributes.h" // for g_fill_rule_lut
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// This class incapsulates AGG scanline rasterizer, AGG scanline container
|
||||
// and RGBA span allocators.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
class rasterizer
|
||||
{
|
||||
public:
|
||||
typedef agg::span_allocator<color_type> span_allocator_rgba_type;
|
||||
typedef agg::rasterizer_scanline_aa<> rasterizer_type;
|
||||
|
||||
rasterizer()
|
||||
: m_scanline()
|
||||
, m_rasterizer()
|
||||
, m_allocator_rgba()
|
||||
{}
|
||||
//-----------------------------------------------------------------------
|
||||
void fill_rule(fill_rule_e fr)
|
||||
{
|
||||
m_rasterizer.filling_rule(g_fill_rule_lut[fr]);
|
||||
}
|
||||
|
||||
void gamma(double g)
|
||||
{
|
||||
m_rasterizer.gamma(agg::gamma_power(g));
|
||||
}
|
||||
void gamma_multi(double g)
|
||||
{
|
||||
m_rasterizer.gamma(agg::gamma_multiply(g));
|
||||
}
|
||||
|
||||
void clip_box(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
m_rasterizer.clip_box(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
void reset_clipping()
|
||||
{
|
||||
m_rasterizer.reset_clipping();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Rasterizer Interface
|
||||
void reset()
|
||||
{
|
||||
m_rasterizer.reset();
|
||||
}
|
||||
|
||||
void add_vertex(double x, double y, unsigned cmd)
|
||||
{
|
||||
m_rasterizer.add_vertex(x, y, cmd);
|
||||
}
|
||||
|
||||
template<class Renderer> void render(Renderer& ren)
|
||||
{
|
||||
agg::render_scanlines(m_rasterizer, m_scanline, ren);
|
||||
}
|
||||
|
||||
span_allocator_rgba_type& allocator_rgba() { return m_allocator_rgba; }
|
||||
rasterizer_type& get_rasterizer() { return m_rasterizer; }
|
||||
agg::scanline_u8& get_scanline() { return m_scanline; }
|
||||
|
||||
private:
|
||||
agg::scanline_u8 m_scanline;
|
||||
rasterizer_type m_rasterizer;
|
||||
span_allocator_rgba_type m_allocator_rgba;
|
||||
};
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_RASTERIZER_INCLUDED
|
||||
|
||||
|
||||
265
DesktopEditor/agg-2.4/svg/agg_svg_renderer_rgba.cpp
Normal file
265
DesktopEditor/agg-2.4/svg/agg_svg_renderer_rgba.cpp
Normal file
@ -0,0 +1,265 @@
|
||||
#include "agg_svg_renderer_rgba.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
class gradient_opacity_adaptor
|
||||
{
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
gradient_opacity_adaptor(const gradient_lut_type& lut, double opacity)
|
||||
: m_lut(lut)
|
||||
, m_opacity(unsigned(opacity * color_type::base_scale + 0.5))
|
||||
{}
|
||||
//---------------------------------------------------------------------
|
||||
static unsigned size()
|
||||
{
|
||||
return gradient_lut_type::size();
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
color_type operator[] (unsigned i) const
|
||||
{
|
||||
color_type c = m_lut[i];
|
||||
c.a = (color_type::value_type)((c.a * m_opacity) >> color_type::base_shift);
|
||||
return c;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
private:
|
||||
const gradient_lut_type& m_lut;
|
||||
unsigned m_opacity;
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
renderer_rgba::renderer_rgba(rasterizer& ras, frame_buffer_type& fb)
|
||||
: m_rasterizer(ras)
|
||||
, m_frame_buffer(&fb)
|
||||
, m_fill_gradient(0)
|
||||
, m_stroke_gradient(0)
|
||||
{}
|
||||
//-------------------------------------------------------------------------
|
||||
template<class GradientFunc, class InterpolatorType>
|
||||
void renderer_rgba::render_gradient_func(const GradientFunc& gradient_func,
|
||||
InterpolatorType& span_interpolator,
|
||||
const gradient_opacity_adaptor& gradient_colors)
|
||||
{
|
||||
typedef agg::span_gradient
|
||||
<
|
||||
color_type,
|
||||
InterpolatorType,
|
||||
GradientFunc,
|
||||
gradient_opacity_adaptor
|
||||
>
|
||||
span_gradient_type;
|
||||
|
||||
span_gradient_type span_gradient(span_interpolator, gradient_func, gradient_colors, 0, 100);
|
||||
|
||||
agg::renderer_scanline_aa
|
||||
<
|
||||
renderer_base_type,
|
||||
rasterizer::span_allocator_rgba_type,
|
||||
span_gradient_type
|
||||
>
|
||||
ren_gradient(m_frame_buffer->ren_base(), m_rasterizer.allocator_rgba(), span_gradient);
|
||||
|
||||
m_rasterizer.render(ren_gradient);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void renderer_rgba::fill(const attributes& attr)
|
||||
{
|
||||
if (!m_frame_buffer->is_valid()) return;
|
||||
|
||||
m_rasterizer.fill_rule(attr.fill_rule());
|
||||
|
||||
switch (attr.fill_type())
|
||||
{
|
||||
case paint_none:
|
||||
break;
|
||||
|
||||
case paint_color:
|
||||
case paint_currentColor:
|
||||
m_frame_buffer->ren_solid().color(attr.fill_color());
|
||||
m_rasterizer.render(m_frame_buffer->ren_solid());
|
||||
break;
|
||||
|
||||
case paint_gradient:
|
||||
render_gradient(attr,
|
||||
*m_fill_gradient,
|
||||
m_fill_gradient->lut(),
|
||||
attr.fill_opacity());
|
||||
break;
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void renderer_rgba::stroke(const attributes& attr)
|
||||
{
|
||||
if(!m_frame_buffer->is_valid()) return;
|
||||
|
||||
m_rasterizer.fill_rule(fill_rule_nonzero);
|
||||
|
||||
switch (attr.stroke_type())
|
||||
{
|
||||
case paint_none:
|
||||
break;
|
||||
|
||||
case paint_color:
|
||||
case paint_currentColor:
|
||||
m_frame_buffer->ren_solid().color(attr.stroke_color());
|
||||
m_rasterizer.render(m_frame_buffer->ren_solid());
|
||||
break;
|
||||
|
||||
case paint_gradient:
|
||||
render_gradient(attr,
|
||||
*m_stroke_gradient,
|
||||
m_stroke_gradient->lut(),
|
||||
attr.stroke_opacity());
|
||||
break;
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void renderer_rgba::render_gradient(const attributes& attr,
|
||||
const gradient& g,
|
||||
const gradient_lut_type& lut,
|
||||
double opacity)
|
||||
{
|
||||
enum gradient_type
|
||||
{
|
||||
linear_pad = 0 | 0,
|
||||
linear_reflect = 4 | 0,
|
||||
linear_repeat = 8 | 0,
|
||||
radial_pad = 0 | 1,
|
||||
radial_reflect = 4 | 1,
|
||||
radial_repeat = 8 | 1,
|
||||
radial_focus_pad = 0 | 2,
|
||||
radial_focus_reflect = 4 | 2,
|
||||
radial_focus_repeat = 8 | 2
|
||||
};
|
||||
|
||||
// Deduce gradient type and calculate the transformation matrix
|
||||
//------------------
|
||||
agg::trans_affine mtx;
|
||||
int gradient_type = 0;
|
||||
|
||||
double fx = 0;
|
||||
double fy = 0;
|
||||
|
||||
if (g.type() == gradient_linear)
|
||||
{
|
||||
mtx = agg::trans_affine_line_segment(g.x1(), g.y1(), g.x2(), g.y2(), 100.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gradient_type = (g.fx() == g.cx() && g.fy() == g.cy()) ? 1 : 2;
|
||||
mtx = agg::trans_affine_scaling(g.r() / 100.0);
|
||||
mtx *= agg::trans_affine_translation(g.cx(), g.cy());
|
||||
fx = g.fx();
|
||||
fy = g.fy();
|
||||
mtx.inverse_transform(&fx, &fy);
|
||||
}
|
||||
|
||||
switch (g.spreadMethod())
|
||||
{
|
||||
default: break;
|
||||
case spreadMethod_reflect: gradient_type |= 4; break;
|
||||
case spreadMethod_repeat: gradient_type |= 8; break;
|
||||
}
|
||||
|
||||
if (g.gradientUnits() == objectUnits_objectBoundingBox)
|
||||
{
|
||||
double parl[6] = { 0,0, 1,0, 1,1 };
|
||||
double x1 = attr.object_x1();
|
||||
double y1 = attr.object_y1();
|
||||
double x2 = attr.object_x2();
|
||||
double y2 = attr.object_y2();
|
||||
|
||||
if (y1 == y2)
|
||||
y2 += .1;
|
||||
if (x1 == x2)
|
||||
x2 += .1;
|
||||
|
||||
mtx *= agg::trans_affine(parl, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
mtx *= g.gradientTransform();
|
||||
mtx *= attr.transform().transform();
|
||||
mtx.invert();
|
||||
|
||||
gradient_opacity_adaptor gradient_colors(lut, opacity);
|
||||
agg::span_interpolator_linear<> span_interpolator(mtx);
|
||||
|
||||
switch (gradient_type)
|
||||
{
|
||||
default: break;
|
||||
case linear_pad:
|
||||
{
|
||||
agg::gradient_x gradient_func;
|
||||
render_gradient_func(gradient_func, span_interpolator, gradient_colors);
|
||||
}
|
||||
break;
|
||||
|
||||
case linear_reflect:
|
||||
{
|
||||
agg::gradient_x gradient_func;
|
||||
agg::gradient_reflect_adaptor<agg::gradient_x> gradient_adaptor(gradient_func);
|
||||
render_gradient_func(gradient_adaptor, span_interpolator, gradient_colors);
|
||||
}
|
||||
break;
|
||||
|
||||
case linear_repeat:
|
||||
{
|
||||
agg::gradient_x gradient_func;
|
||||
agg::gradient_repeat_adaptor<agg::gradient_x> gradient_adaptor(gradient_func);
|
||||
render_gradient_func(gradient_adaptor, span_interpolator, gradient_colors);
|
||||
}
|
||||
break;
|
||||
|
||||
case radial_pad:
|
||||
{
|
||||
agg::gradient_radial gradient_func;
|
||||
render_gradient_func(gradient_func, span_interpolator, gradient_colors);
|
||||
}
|
||||
break;
|
||||
|
||||
case radial_reflect:
|
||||
{
|
||||
agg::gradient_radial gradient_func;
|
||||
agg::gradient_reflect_adaptor<agg::gradient_radial> gradient_adaptor(gradient_func);
|
||||
render_gradient_func(gradient_adaptor, span_interpolator, gradient_colors);
|
||||
}
|
||||
break;
|
||||
|
||||
case radial_repeat:
|
||||
{
|
||||
agg::gradient_radial gradient_func;
|
||||
agg::gradient_repeat_adaptor<agg::gradient_radial> gradient_adaptor(gradient_func);
|
||||
render_gradient_func(gradient_adaptor, span_interpolator, gradient_colors);
|
||||
}
|
||||
break;
|
||||
|
||||
case radial_focus_pad:
|
||||
{
|
||||
agg::gradient_radial_focus gradient_func(100.0, fx, fy);
|
||||
render_gradient_func(gradient_func, span_interpolator, gradient_colors);
|
||||
}
|
||||
break;
|
||||
|
||||
case radial_focus_reflect:
|
||||
{
|
||||
agg::gradient_radial_focus gradient_func(100.0, fx, fy);
|
||||
agg::gradient_reflect_adaptor<agg::gradient_radial_focus> gradient_adaptor(gradient_func);
|
||||
render_gradient_func(gradient_adaptor, span_interpolator, gradient_colors);
|
||||
}
|
||||
break;
|
||||
|
||||
case radial_focus_repeat:
|
||||
{
|
||||
agg::gradient_radial_focus gradient_func(100.0, fx, fy);
|
||||
agg::gradient_repeat_adaptor<agg::gradient_radial_focus> gradient_adaptor(gradient_func);
|
||||
render_gradient_func(gradient_adaptor, span_interpolator, gradient_colors);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
114
DesktopEditor/agg-2.4/svg/agg_svg_renderer_rgba.h
Normal file
114
DesktopEditor/agg-2.4/svg/agg_svg_renderer_rgba.h
Normal file
@ -0,0 +1,114 @@
|
||||
#ifndef AGG_SVG_RENDERER_RGBA_INCLUDED
|
||||
#define AGG_SVG_RENDERER_RGBA_INCLUDED
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_svg_attributes.h"
|
||||
#include "agg_svg_rasterizer.h"
|
||||
#include "agg_svg_frame_buffer_rgba.h"
|
||||
#include "agg_span_interpolator_linear.h"
|
||||
#include "agg_span_gradient.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
class gradient_opacity_adaptor;
|
||||
//-------------------------------------------------------------------------
|
||||
// Main rgba renderer
|
||||
//
|
||||
// Used to incapsulate AGG rendering functionality
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
class renderer_rgba
|
||||
{
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
typedef frame_buffer_rgba frame_buffer_type;
|
||||
typedef frame_buffer_type::pixfmt_type pixfmt_type;
|
||||
typedef frame_buffer_type::renderer_base_type renderer_base_type;
|
||||
typedef frame_buffer_type::renderer_solid_type renderer_solid_type;
|
||||
//---------------------------------------------------------------------
|
||||
enum { pixel_size = sizeof(pixel_type) };
|
||||
//---------------------------------------------------------------------
|
||||
renderer_rgba(rasterizer&, frame_buffer_type&);
|
||||
//---------------------------------------------------------------------
|
||||
void attach(frame_buffer_type&);
|
||||
//---------------------------------------------------------------------
|
||||
void fill_gradient(const gradient&);
|
||||
void stroke_gradient(const gradient&);
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void reset();
|
||||
void clip_box(double x1, double y1, double x2, double y2);
|
||||
void add_vertex(double x, double y, unsigned cmd);
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void fill(const attributes& attr);
|
||||
void stroke(const attributes& attr);
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
bool is_valid()const;
|
||||
//---------------------------------------------------------------------
|
||||
private:
|
||||
//---------------------------------------------------------------------
|
||||
renderer_rgba(const renderer_rgba&);
|
||||
const renderer_rgba& operator = (const renderer_rgba&);
|
||||
//---------------------------------------------------------------------
|
||||
void render_gradient(const attributes&,
|
||||
const gradient&,
|
||||
const gradient_lut_type&,
|
||||
double opacity);
|
||||
//---------------------------------------------------------------------
|
||||
template <class GradientFunc, class InterpolatorType>
|
||||
void render_gradient_func(const GradientFunc& gradient_func,
|
||||
InterpolatorType& span_interpolator,
|
||||
const gradient_opacity_adaptor& gradient_colors);
|
||||
//---------------------------------------------------------------------
|
||||
rasterizer& m_rasterizer;
|
||||
frame_buffer_type* m_frame_buffer;
|
||||
const gradient* m_fill_gradient;
|
||||
const gradient* m_stroke_gradient;
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
inline void renderer_rgba::attach(frame_buffer_type& fb)
|
||||
{
|
||||
m_frame_buffer = &fb;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline void renderer_rgba::fill_gradient(const gradient& g)
|
||||
{
|
||||
m_fill_gradient = &g;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline void renderer_rgba::stroke_gradient(const gradient& g)
|
||||
{
|
||||
m_stroke_gradient = &g;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline void renderer_rgba::reset()
|
||||
{
|
||||
m_rasterizer.reset();
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
inline void renderer_rgba::clip_box(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
m_rasterizer.clip_box(x1, y1, x2, y2);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
inline void renderer_rgba::add_vertex(double x, double y, unsigned cmd)
|
||||
{
|
||||
m_rasterizer.add_vertex(x, y, cmd);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
inline bool renderer_rgba::is_valid()const
|
||||
{
|
||||
return m_frame_buffer->is_valid();
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_RENDERER_RGBA_INCLUDED
|
||||
|
||||
862
DesktopEditor/agg-2.4/svg/agg_svg_rendering_interpreter.cpp
Normal file
862
DesktopEditor/agg-2.4/svg/agg_svg_rendering_interpreter.cpp
Normal file
@ -0,0 +1,862 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_svg_rendering_interpreter.h"
|
||||
#include "agg_svg_pipeline.h"
|
||||
#include "agg_svg_frame_buffer_rgba.h"
|
||||
#include "agg_svg_renderer_rgba.h"
|
||||
#include "agg_svg_shape_adaptors.h"
|
||||
#include "agg_svg_gradient_lut_cache.h"
|
||||
#include "agg_bounding_rect.h"
|
||||
#include "agg_svg_percent.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
rendering_interpreter::el_interpreter const
|
||||
rendering_interpreter::element_interpreters[end_of_elements] = {
|
||||
&render_circle,
|
||||
&render_clipPath,
|
||||
&render_defs,
|
||||
&render_ellipse,
|
||||
&render_g,
|
||||
&render_line,
|
||||
&render_linearGradient,
|
||||
&render_path,
|
||||
&render_polygon,
|
||||
&render_polyline,
|
||||
&render_radialGradient,
|
||||
&render_rect,
|
||||
&render_stop,
|
||||
&render_svg,
|
||||
&set_title_element,
|
||||
&render_use,
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
rendering_interpreter::rendering_interpreter(pipeline& p,
|
||||
attributes& attr,
|
||||
renderer_rgba_type& ren,
|
||||
dom_storage::map_type& map,
|
||||
gradient_lut_cache& g_lut_cache,
|
||||
bool render_paint_servers)
|
||||
|
||||
: m_storage(0)
|
||||
, m_pipeline(p)
|
||||
, m_attributes(attr)
|
||||
, m_renderer(ren)
|
||||
, m_it2element_map(map)
|
||||
, m_gradient_lut_cache(g_lut_cache)
|
||||
, m_current_element(end_of_elements)
|
||||
, m_vertex_source(0)
|
||||
, m_defs_counter(0)
|
||||
, m_paint_server_counter(0)
|
||||
, m_attr_setter(m_attributes)
|
||||
, m_render_paint_servers(render_paint_servers)
|
||||
, m_clipPath(false)
|
||||
, m_gradient(0)
|
||||
, m_ignore_view_box(false)
|
||||
{
|
||||
m_attr_setter.set_interpreter(this);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
rendering_interpreter::rendering_interpreter(rendering_interpreter const& r,
|
||||
attributes& attr,
|
||||
renderer_rgba_type& ren,
|
||||
bool render_paint_servers)
|
||||
: m_storage(r.m_storage)
|
||||
, m_pipeline(r.m_pipeline)
|
||||
, m_attributes(attr)
|
||||
, m_renderer(ren)
|
||||
, m_it2element_map(r.m_it2element_map)
|
||||
, m_current_element(end_of_elements)
|
||||
, m_vertex_source(r.m_vertex_source)
|
||||
, m_defs_counter(0)
|
||||
, m_paint_server_counter(render_paint_servers ? -1 : 0)
|
||||
, m_attr_setter(attr)
|
||||
, m_render_paint_servers(render_paint_servers)
|
||||
, m_gradient(0)
|
||||
, m_gradient_lut_cache(r.m_gradient_lut_cache)
|
||||
, m_clipPath(false)
|
||||
, m_ignore_view_box(false)
|
||||
{
|
||||
m_attr_setter.set_interpreter(this);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
bool rendering_interpreter::element_is_paint_server(element_e code) const
|
||||
{
|
||||
return (code == elem_linearGradient || code == elem_radialGradient);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
bool rendering_interpreter::start_element(const dom_storage& st,
|
||||
const element_data& el)
|
||||
{
|
||||
m_storage = &st;
|
||||
m_current_element = el.code;
|
||||
|
||||
if (m_defs_counter)
|
||||
{
|
||||
if (el.code == elem_defs)
|
||||
{
|
||||
++m_defs_counter;
|
||||
|
||||
m_attributes.begin_session();
|
||||
render_defs(el);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (el.code == elem_defs)
|
||||
++m_defs_counter;
|
||||
|
||||
|
||||
if (element_is_paint_server(el.code))
|
||||
{
|
||||
++m_paint_server_counter;
|
||||
}
|
||||
|
||||
if (m_paint_server_counter > 0)
|
||||
return true;
|
||||
|
||||
if (m_clipPath)
|
||||
return true;
|
||||
|
||||
m_attributes.begin_session();
|
||||
|
||||
if (el.code != end_of_elements)
|
||||
{
|
||||
(this->*element_interpreters[el.code])(el);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
bool rendering_interpreter::end_element(const dom_storage& st,
|
||||
const element_data& el)
|
||||
{
|
||||
m_current_element = el.code;
|
||||
|
||||
if (el.code == elem_defs)
|
||||
{
|
||||
--m_defs_counter;
|
||||
m_attributes.end_session();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_defs_counter)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (element_is_paint_server(el.code))
|
||||
{
|
||||
if (m_paint_server_counter)
|
||||
{
|
||||
--m_paint_server_counter;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_clipPath)
|
||||
m_clipPath = false;
|
||||
|
||||
else if (m_paint_server_counter == 0)
|
||||
m_attributes.end_session();
|
||||
|
||||
return true;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::prepare_gradient_fill(gradient& g)
|
||||
{
|
||||
if (m_attributes.fill_type() == paint_gradient)
|
||||
{
|
||||
create_gradient(g, locate(m_attributes.fill_gradient_id()));
|
||||
m_renderer.fill_gradient(g);
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::prepare_gradient_stroke(gradient& g)
|
||||
{
|
||||
if (m_attributes.stroke_type() == paint_gradient)
|
||||
{
|
||||
create_gradient(g, locate(m_attributes.stroke_gradient_id()));
|
||||
m_renderer.stroke_gradient(g);
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::calculate_and_set_object_bbox(object_bbox& bbox)
|
||||
{
|
||||
assert(m_vertex_source);
|
||||
|
||||
bbox.calculate(m_attributes, *m_vertex_source);
|
||||
m_attributes.object_bbox(bbox.bbox());
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
bool rendering_interpreter::is_visible(coord_type(&bounds)[4]) const
|
||||
{
|
||||
coord_type stroke_width = (coord_type)m_attributes.stroke_width();
|
||||
bounds[0] -= stroke_width;
|
||||
bounds[1] -= stroke_width;
|
||||
bounds[2] += stroke_width;
|
||||
bounds[3] += stroke_width;
|
||||
double x1 = bounds[0];
|
||||
double y1 = bounds[1];
|
||||
double x2 = bounds[2];
|
||||
double y2 = bounds[1];
|
||||
double x3 = bounds[2];
|
||||
double y3 = bounds[3];
|
||||
double x4 = bounds[0];
|
||||
double y4 = bounds[3];
|
||||
|
||||
m_attributes.transform().transform(&x1, &y1);
|
||||
m_attributes.transform().transform(&x2, &y2);
|
||||
m_attributes.transform().transform(&x3, &y3);
|
||||
m_attributes.transform().transform(&x4, &y4);
|
||||
|
||||
double cx1 = x1;
|
||||
double cy1 = y1;
|
||||
double cx2 = x1;
|
||||
double cy2 = y1;
|
||||
if(x2 < cx1) cx1 = x2;
|
||||
if(y2 < cy1) cy1 = y2;
|
||||
if(x3 < cx1) cx1 = x3;
|
||||
if(y3 < cy1) cy1 = y3;
|
||||
if(x4 < cx1) cx1 = x4;
|
||||
if(y4 < cy1) cy1 = y4;
|
||||
if(x2 > cx2) cx2 = x2;
|
||||
if(y2 > cy2) cy2 = y2;
|
||||
if(x3 > cx2) cx2 = x3;
|
||||
if(y3 > cy2) cy2 = y3;
|
||||
if(x4 > cx2) cx2 = x4;
|
||||
if(y4 > cy2) cy2 = y4;
|
||||
|
||||
// Check for clipping
|
||||
//----------------------
|
||||
if(!m_attributes.is_visible(cx1, cy1, cx2, cy2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If not clipped check if the bounding box area
|
||||
// is more than 0.01 of a pixel.
|
||||
//----------------------
|
||||
return (cx2 - cx1) * (cy2 - cy1) > 0.01;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::set_common_gradient_attributes(attr_data* attr,
|
||||
unsigned num_attr)
|
||||
{
|
||||
spreadMethod_e spreadMethod;
|
||||
|
||||
for (unsigned i = 0; i < num_attr; ++i)
|
||||
{
|
||||
if (!attr[i].processed) switch (attr[i].code)
|
||||
{
|
||||
case attr_spreadMethod:
|
||||
assert(attr[i].data.size() == 1);
|
||||
spreadMethod = (spreadMethod_e)attr[i].data.int8u_at(0);
|
||||
assert(spreadMethod == spreadMethod_pad ||
|
||||
spreadMethod == spreadMethod_reflect ||
|
||||
spreadMethod == spreadMethod_repeat);
|
||||
|
||||
m_gradient->spreadMethod(spreadMethod);
|
||||
attr[i].processed = true;
|
||||
break;
|
||||
|
||||
case attr_gradientUnits:
|
||||
m_gradient->gradientUnits(read_objectUnits(attr[i].data));
|
||||
attr[i].processed = true;
|
||||
break;
|
||||
|
||||
case attr_transform:
|
||||
m_attr_setter.set_transform(*m_gradient, attr[i].data);
|
||||
attr[i].processed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
double rendering_interpreter::read_length(
|
||||
const data_accessor_type& data) const
|
||||
{
|
||||
assert(data.size() == sizeof(coord_type) + 1);
|
||||
|
||||
double value = data.units_value(m_attributes);
|
||||
return value;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
objectUnits_e rendering_interpreter::read_objectUnits(
|
||||
const data_accessor_type& data) const
|
||||
{
|
||||
assert(data.size() == 1);
|
||||
|
||||
objectUnits_e objectUnits = (objectUnits_e)data.int8u_at(0);
|
||||
|
||||
assert(objectUnits == objectUnits_userSpaceOnUse ||
|
||||
objectUnits == objectUnits_objectBoundingBox ||
|
||||
objectUnits == objectUnits_strokeWidth);
|
||||
|
||||
return objectUnits;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::read_viewBox(const data_accessor_type& data,
|
||||
double* x, double* y,
|
||||
double* w, double* h) const
|
||||
{
|
||||
assert(data.size() == 4 * sizeof(coord_type));
|
||||
|
||||
*x = data.coord_at(sizeof(coord_type) * 0);
|
||||
*y = data.coord_at(sizeof(coord_type) * 1);
|
||||
*w = data.coord_at(sizeof(coord_type) * 2);
|
||||
*h = data.coord_at(sizeof(coord_type) * 3);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::read_preserveAspectRatio(
|
||||
const data_accessor_type& data,
|
||||
uniform_scaling_e* usc,
|
||||
window_fit_logic_e* wfl) const
|
||||
{
|
||||
assert(data.size() == 2);
|
||||
|
||||
*usc = uniform_scaling_e (data.int8u_at(0));
|
||||
*wfl = window_fit_logic_e(data.int8u_at(sizeof(agg::int8u)));
|
||||
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// render basic shapes
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::render_rect(const element_data& el)
|
||||
{
|
||||
double x = 0.;
|
||||
double y = 0.;
|
||||
double w = 0.;
|
||||
double h = 0.;
|
||||
double rx = -1.;
|
||||
double ry = -1.;
|
||||
|
||||
for (unsigned i = 0; i < el.num_attr; ++i)
|
||||
{
|
||||
if (!el.attr[i].processed) switch (el.attr[i].code)
|
||||
{
|
||||
case attr_x: x = read_length(el.attr[i].data); break;
|
||||
case attr_y: y = read_length(el.attr[i].data); break;
|
||||
case attr_width: w = read_length(el.attr[i].data); break;
|
||||
case attr_height: h = read_length(el.attr[i].data); break;
|
||||
case attr_rx: rx = read_length(el.attr[i].data); break;
|
||||
case attr_ry: rx = read_length(el.attr[i].data); break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rx < 0. && ry < 0.)
|
||||
{
|
||||
rx = 0.;
|
||||
rx = 0.;
|
||||
}
|
||||
if (rx < 0.) rx = ry;
|
||||
if (ry < 0.) ry = rx;
|
||||
|
||||
if (rx > w / 2.) rx = w / 2.;
|
||||
if (ry > h / 2.) ry = h / 2.;
|
||||
|
||||
m_attr_setter.set_transform_attributes(el.attr, el.num_attr);
|
||||
|
||||
coord_type bounds[4] = {x, y, x + w, y + h};
|
||||
|
||||
if (is_visible(bounds))
|
||||
{
|
||||
rectangle_adaptor source(x, y, w, h, rx, ry);
|
||||
general_work_for_basic_shapes(el, source);
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::render_circle(const element_data& el)
|
||||
{
|
||||
double cx = 0.;
|
||||
double cy = 0.;
|
||||
double r = 0.;
|
||||
|
||||
for (unsigned i = 0; i < el.num_attr; ++i)
|
||||
{
|
||||
if (!el.attr[i].processed) switch (el.attr[i].code)
|
||||
{
|
||||
case attr_cx: cx = read_length(el.attr[i].data); break;
|
||||
case attr_cy: cy = read_length(el.attr[i].data); break;
|
||||
case attr_r: r = read_length(el.attr[i].data); break;
|
||||
}
|
||||
}
|
||||
|
||||
m_attr_setter.set_transform_attributes(el.attr, el.num_attr);
|
||||
|
||||
coord_type bounds[4] = {cx - r, cy - r, cx + r, cy + r};
|
||||
|
||||
if (is_visible(bounds))
|
||||
{
|
||||
circle_adaptor source(cx, cy, r);
|
||||
general_work_for_basic_shapes(el, source);
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::render_clipPath(const element_data&)
|
||||
{
|
||||
m_clipPath = true;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::render_ellipse(const element_data& el)
|
||||
{
|
||||
double cx = 0.;
|
||||
double cy = 0.;
|
||||
double rx = 0.;
|
||||
double ry = 0.;
|
||||
|
||||
for (unsigned i = 0; i < el.num_attr; ++i)
|
||||
{
|
||||
if (!el.attr[i].processed) switch (el.attr[i].code)
|
||||
{
|
||||
case attr_cx: cx = read_length(el.attr[i].data); break;
|
||||
case attr_cy: cy = read_length(el.attr[i].data); break;
|
||||
case attr_rx: rx = read_length(el.attr[i].data); break;
|
||||
case attr_ry: ry = read_length(el.attr[i].data); break;
|
||||
}
|
||||
}
|
||||
|
||||
m_attr_setter.set_transform_attributes(el.attr, el.num_attr);
|
||||
|
||||
coord_type bounds[4] = {cx - rx, cy - ry, cx + rx, cy + ry};
|
||||
|
||||
if (is_visible(bounds))
|
||||
{
|
||||
ellipse_adaptor source(cx, cy, rx, ry);
|
||||
general_work_for_basic_shapes(el, source);
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::render_line(const element_data& el)
|
||||
{
|
||||
double x1 = 0.;
|
||||
double y1 = 0.;
|
||||
double x2 = 0.;
|
||||
double y2 = 0.;
|
||||
|
||||
for (unsigned i = 0; i < el.num_attr; ++i)
|
||||
{
|
||||
if (!el.attr[i].processed) switch (el.attr[i].code)
|
||||
{
|
||||
case attr_x1: x1 = read_length(el.attr[i].data); break;
|
||||
case attr_y1: y1 = read_length(el.attr[i].data); break;
|
||||
case attr_x2: x2 = read_length(el.attr[i].data); break;
|
||||
case attr_y2: y2 = read_length(el.attr[i].data); break;
|
||||
}
|
||||
}
|
||||
|
||||
m_attr_setter.set_transform_attributes(el.attr, el.num_attr);
|
||||
|
||||
coord_type bounds[4] = {x1, y1, x2, y2};
|
||||
|
||||
if (is_visible(bounds))
|
||||
{
|
||||
line_adaptor source(x1, y1, x2, y2);
|
||||
general_work_for_basic_shapes(el, source);
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::render_polygon(const element_data& el)
|
||||
{
|
||||
assert(el.shape_data.size() > 0);
|
||||
|
||||
m_attr_setter.set_transform_attributes(el.attr, el.num_attr);
|
||||
|
||||
if (el.bounds)
|
||||
{
|
||||
coord_type bounds[4];
|
||||
memcpy(bounds, el.bounds, sizeof(bounds));
|
||||
|
||||
if (is_visible(bounds))
|
||||
{
|
||||
poly_interpreter<data_accessor_type> source(el.shape_data, true);
|
||||
general_work_for_basic_shapes(el, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::render_polyline(const element_data& el)
|
||||
{
|
||||
assert(el.shape_data.size() > 0);
|
||||
|
||||
m_attr_setter.set_transform_attributes(el.attr, el.num_attr);
|
||||
|
||||
if (el.bounds)
|
||||
{
|
||||
coord_type bounds[4];
|
||||
memcpy(bounds, el.bounds, sizeof(bounds));
|
||||
|
||||
if (is_visible(bounds))
|
||||
{
|
||||
poly_interpreter<data_accessor_type> source(el.shape_data, false);
|
||||
general_work_for_basic_shapes(el, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::render_path(const element_data& el)
|
||||
{
|
||||
assert(el.shape_data.size() > 0);
|
||||
|
||||
m_attr_setter.set_transform_attributes(el.attr, el.num_attr);
|
||||
|
||||
if (el.bounds)
|
||||
{
|
||||
coord_type bounds[4];
|
||||
memcpy(bounds, el.bounds, sizeof(bounds));
|
||||
|
||||
if (is_visible(bounds))
|
||||
{
|
||||
path_interpreter<data_accessor_type> source(el.shape_data);
|
||||
general_work_for_basic_shapes(el, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::render_radialGradient(const element_data& el)
|
||||
{
|
||||
m_attr_setter.set_color_attributes (el.attr, el.num_attr);
|
||||
m_attr_setter.set_xlink_attributes (el.attr, el.num_attr);
|
||||
|
||||
set_common_gradient_attributes (el.attr, el.num_attr);
|
||||
|
||||
// set default values
|
||||
double cx = m_attributes.conv_units(50., units_percent);
|
||||
double cy = m_attributes.conv_units(50., units_percent);
|
||||
double r = m_attributes.conv_units(50., units_percent );
|
||||
|
||||
// read attributes from DOM storage
|
||||
for (unsigned i = 0; i < el.num_attr; ++i)
|
||||
{
|
||||
if (!el.attr[i].processed) switch (el.attr[i].code)
|
||||
{
|
||||
case attr_cx:
|
||||
assert(el.attr[i].data.size() == sizeof(coord_type) + 1);
|
||||
cx = el.attr[i].data.units_value(m_attributes);
|
||||
break;
|
||||
case attr_cy:
|
||||
assert(el.attr[i].data.size() == sizeof(coord_type) + 1);
|
||||
cy = el.attr[i].data.units_value(m_attributes);
|
||||
break;
|
||||
case attr_r:
|
||||
assert(el.attr[i].data.size() == sizeof(coord_type) + 1);
|
||||
r = el.attr[i].data.units_value(m_attributes);
|
||||
break;
|
||||
case attr_fx:
|
||||
assert(el.attr[i].data.size() == sizeof(coord_type) + 1);
|
||||
m_gradient->fx(el.attr[i].data.units_value(m_attributes));
|
||||
break;
|
||||
case attr_fy:
|
||||
assert(el.attr[i].data.size() == sizeof(coord_type) + 1);
|
||||
m_gradient->fy(el.attr[i].data.units_value(m_attributes));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_gradient->radial(cx, cy, r);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::render_linearGradient(const element_data& el)
|
||||
{
|
||||
m_attr_setter.set_color_attributes (el.attr, el.num_attr);
|
||||
m_attr_setter.set_xlink_attributes (el.attr, el.num_attr);
|
||||
|
||||
set_common_gradient_attributes (el.attr, el.num_attr);
|
||||
|
||||
double x1 = 0.;
|
||||
double y1 = 0.;
|
||||
double x2 = 1.;
|
||||
double y2 = 0.;
|
||||
|
||||
for (unsigned i = 0; i < el.num_attr; ++i)
|
||||
{
|
||||
if (!el.attr[i].processed) switch (el.attr[i].code)
|
||||
{
|
||||
case attr_x1:
|
||||
assert(el.attr[i].data.size() == sizeof(coord_type) + 1);
|
||||
x1 = el.attr[i].data.units_value(m_attributes);
|
||||
break;
|
||||
case attr_y1:
|
||||
assert(el.attr[i].data.size() == sizeof(coord_type) + 1);
|
||||
y1 = el.attr[i].data.units_value(m_attributes);
|
||||
break;
|
||||
case attr_x2:
|
||||
assert(el.attr[i].data.size() == sizeof(coord_type) + 1);
|
||||
x2 = el.attr[i].data.units_value(m_attributes);
|
||||
break;
|
||||
case attr_y2:
|
||||
assert(el.attr[i].data.size() == sizeof(coord_type) + 1);
|
||||
y2 = el.attr[i].data.units_value(m_attributes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_gradient->linear(x1, y1, x2, y2);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::render_defs(const element_data& el)
|
||||
{
|
||||
m_vertex_source = 0;
|
||||
|
||||
m_attr_setter.set_presentation_attributes (el.attr, el.num_attr);
|
||||
m_attr_setter.set_transform_attributes (el.attr, el.num_attr);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::create_gradient(gradient& g, unsigned idx)
|
||||
{
|
||||
object_bbox bbox;
|
||||
|
||||
bool is_necessary_set_bbox =
|
||||
units_is_objectBoundingBox(idx, attr_gradientUnits);
|
||||
|
||||
if (is_necessary_set_bbox)
|
||||
{
|
||||
calculate_and_set_object_bbox(bbox);
|
||||
}
|
||||
|
||||
attributes attr(m_attributes.settings());
|
||||
|
||||
attr.begin_session();
|
||||
|
||||
if (is_necessary_set_bbox)
|
||||
{
|
||||
attr.object_bbox(bbox.bbox());
|
||||
}
|
||||
|
||||
rendering_interpreter rin(*this, attr, m_renderer,true);
|
||||
rin.set_gradient(&g);
|
||||
|
||||
m_storage->traverse(rin, idx);
|
||||
|
||||
g.create_gradient_lut(attr, m_gradient_lut_cache);
|
||||
|
||||
attr.end_session();
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
bool rendering_interpreter::units_is_objectBoundingBox(unsigned idx,
|
||||
attr_e code) const
|
||||
{
|
||||
data_accessor_type data = m_storage->get_attr_specified_value(idx, code);
|
||||
|
||||
if (data.size() == 1)
|
||||
{
|
||||
objectUnits_e units = read_objectUnits(data);
|
||||
|
||||
return units == objectUnits_objectBoundingBox;
|
||||
}
|
||||
else if (data.size() == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::render_g(const element_data& el)
|
||||
{
|
||||
m_vertex_source = 0;
|
||||
|
||||
m_attr_setter.set_presentation_attributes (el.attr, el.num_attr);
|
||||
m_attr_setter.set_transform_attributes (el.attr, el.num_attr);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::process_xlink_href(data_accessor_type data)
|
||||
{
|
||||
unsigned index = locate(data);
|
||||
|
||||
if (index == 0) return;
|
||||
|
||||
if (m_current_element == elem_linearGradient ||
|
||||
m_current_element == elem_radialGradient)
|
||||
{
|
||||
rendering_interpreter rin(*this, m_attributes, m_renderer, true);
|
||||
rin.set_gradient(m_gradient);
|
||||
m_storage->traverse(rin, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
unsigned rendering_interpreter::locate(const char* id)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
typedef agg::pod_array_adaptor<char const> adaptor_type;
|
||||
|
||||
adaptor_type id_adaptor(id, (unsigned)strlen(id));
|
||||
|
||||
data_accessor<adaptor_type> data(id_adaptor);
|
||||
|
||||
return locate(data);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::render_stop(const element_data& el)
|
||||
{
|
||||
m_vertex_source = 0;
|
||||
|
||||
m_attr_setter.set_color_attributes(el.attr, el.num_attr);
|
||||
|
||||
double stop_offset = 0.;
|
||||
color_type stop_color = color_type(0, 0, 0);
|
||||
double stop_opacity = 1.;
|
||||
|
||||
for (unsigned i = 0; i < el.num_attr; ++i)
|
||||
{
|
||||
if (!el.attr[i].processed) switch (el.attr[i].code)
|
||||
{
|
||||
case attr_offset:
|
||||
assert(el.attr[i].data.size() == sizeof(coord_type));
|
||||
stop_offset = percent::decrypt(el.attr[i].data.coord_at(0));
|
||||
break;
|
||||
|
||||
case attr_stop_color:
|
||||
assert(el.attr[i].data.size() == sizeof(color_type));
|
||||
stop_color = el.attr[i].data.color_at(0);
|
||||
break;
|
||||
|
||||
case attr_stop_opacity:
|
||||
assert(el.attr[i].data.size() == sizeof(coord_type));
|
||||
stop_opacity = el.attr[i].data.coord_at(0);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
m_gradient->add_stop(stop_offset, stop_color, stop_opacity);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::render_svg(const element_data& el)
|
||||
{
|
||||
m_vertex_source = 0;
|
||||
|
||||
m_attr_setter.set_presentation_attributes(el.attr, el.num_attr);
|
||||
|
||||
// set default values
|
||||
coordinate x = { 0, units_px};
|
||||
coordinate y = { 0, units_px};
|
||||
length w = {100, units_percent_x};
|
||||
length h = {100, units_percent_y};
|
||||
|
||||
double vb_x = 0.;
|
||||
double vb_y = 0.;
|
||||
double vb_w = 0.;
|
||||
double vb_h = 0.;
|
||||
|
||||
uniform_scaling_e usc = usc_xMidYMid;
|
||||
if (m_ignore_view_box)
|
||||
usc = usc_none;
|
||||
window_fit_logic_e wfl = window_meet;
|
||||
|
||||
bool is_viewBox_present = false;
|
||||
|
||||
// read attributes
|
||||
for (unsigned i = 0; i < el.num_attr; ++i)
|
||||
{
|
||||
if (!el.attr[i].processed) switch (el.attr[i].code)
|
||||
{
|
||||
case attr_x:
|
||||
assert(el.attr[i].data.size() == sizeof(coord_type) + 1);
|
||||
x.value = el.attr[i].data.coord_at(0);
|
||||
x.unit = units2_e(el.attr[i].data.int8u_at(sizeof(coord_type)));
|
||||
break;
|
||||
|
||||
case attr_y:
|
||||
assert(el.attr[i].data.size() == sizeof(coord_type) + 1);
|
||||
y.value = el.attr[i].data.coord_at(0);
|
||||
y.unit = units2_e(el.attr[i].data.int8u_at(sizeof(coord_type)));
|
||||
break;
|
||||
case attr_width:
|
||||
assert(el.attr[i].data.size() == sizeof(coord_type) + 1);
|
||||
w.value = el.attr[i].data.coord_at(0);
|
||||
w.unit = units2_e(el.attr[i].data.int8u_at(sizeof(coord_type)));
|
||||
break;
|
||||
case attr_height:
|
||||
assert(el.attr[i].data.size() == sizeof(coord_type) + 1);
|
||||
h.value = el.attr[i].data.coord_at(0);
|
||||
h.unit = units2_e(el.attr[i].data.int8u_at(sizeof(coord_type)));
|
||||
break;
|
||||
|
||||
case attr_viewBox:
|
||||
read_viewBox(el.attr[i].data, &vb_x, &vb_y, &vb_w, &vb_h);
|
||||
is_viewBox_present = true;
|
||||
break;
|
||||
|
||||
case attr_preserveAspectRatio:
|
||||
read_preserveAspectRatio(el.attr[i].data, &usc, &wfl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize values
|
||||
x.value = m_attributes.conv_units(x.value, x.unit);
|
||||
y.value = m_attributes.conv_units(y.value, y.unit);
|
||||
w.value = m_attributes.conv_units(w.value, w.unit);
|
||||
h.value = m_attributes.conv_units(h.value, h.unit);
|
||||
|
||||
if (!is_viewBox_present)
|
||||
{
|
||||
vb_w = w.value;
|
||||
vb_h = h.value;
|
||||
}
|
||||
|
||||
if (m_ignore_view_box)
|
||||
{
|
||||
double scrW = (m_attributes.window_x2()<0)?w.value:(m_attributes.window_x2()/2-m_attributes.window_x1());
|
||||
double scrH = (m_attributes.window_y2()<0)?h.value:(m_attributes.window_y2()/2-m_attributes.window_y1());
|
||||
m_attributes.viewBox(m_attributes.window_x1(), m_attributes.window_y1(),
|
||||
scrW,
|
||||
scrH,
|
||||
vb_x, vb_y, vb_w, vb_h, usc, wfl, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_attributes.viewBox(x.value, y.value, w.value, h.value,
|
||||
vb_x, vb_y, vb_w, vb_h, usc, wfl, false);
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::set_title_element(const element_data& el)
|
||||
{
|
||||
m_vertex_source = 0;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
void rendering_interpreter::render_use(const element_data& el)
|
||||
{
|
||||
m_attr_setter.set_paint_attributes (el.attr, el.num_attr);
|
||||
m_attr_setter.set_color_attributes (el.attr, el.num_attr);
|
||||
m_attr_setter.set_opacity_attributes (el.attr, el.num_attr);
|
||||
|
||||
m_attr_setter.set_transform_attributes (el.attr, el.num_attr);
|
||||
|
||||
double x = 0.;
|
||||
double y = 0.;
|
||||
data_accessor_type href;
|
||||
|
||||
for (unsigned i = 0; i < el.num_attr; ++i)
|
||||
{
|
||||
if (!el.attr[i].processed) switch (el.attr[i].code)
|
||||
{
|
||||
case attr_x: x = read_length(el.attr[i].data); break;
|
||||
case attr_y: y = read_length(el.attr[i].data); break;
|
||||
case attr_xlink_href: href = el.attr[i].data; break;
|
||||
}
|
||||
}
|
||||
|
||||
if (href.size() > 0)
|
||||
{
|
||||
m_attributes.translate(x, y);
|
||||
|
||||
unsigned index = locate(href, 0);
|
||||
|
||||
if (index != 0)
|
||||
{
|
||||
rendering_interpreter rin(*this, m_attributes, m_renderer);
|
||||
m_storage->traverse(rin, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
187
DesktopEditor/agg-2.4/svg/agg_svg_rendering_interpreter.h
Normal file
187
DesktopEditor/agg-2.4/svg/agg_svg_rendering_interpreter.h
Normal file
@ -0,0 +1,187 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef AGG_SVG_RENDERING_INTERPRETER_INCLUDED
|
||||
#define AGG_SVG_RENDERING_INTERPRETER_INCLUDED
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "agg_array.h"
|
||||
#include "agg_svg_basics.h"
|
||||
#include "agg_svg_attributes_setter.h"
|
||||
#include "agg_svg_attributes.h"
|
||||
#include "agg_svg_dom_storage.h"
|
||||
#include "agg_svg_assoc_pod_array.h"
|
||||
#include "agg_svg_pipeline.h"
|
||||
#include "agg_svg_exception.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
// forward declarations
|
||||
//
|
||||
class pipeline;
|
||||
class gradient_lut_cache;
|
||||
class frame_buffer_rgba;
|
||||
class renderer_rgba;
|
||||
//-------------------------------------------------------------------------
|
||||
class rendering_interpreter
|
||||
{
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
typedef renderer_rgba renderer_rgba_type;
|
||||
//---------------------------------------------------------------------
|
||||
rendering_interpreter(rendering_interpreter const&,
|
||||
attributes&,
|
||||
renderer_rgba_type&,
|
||||
bool render_paint_servers = false);
|
||||
//---------------------------------------------------------------------
|
||||
rendering_interpreter(pipeline&,
|
||||
attributes&,
|
||||
renderer_rgba_type&,
|
||||
dom_storage::map_type&,
|
||||
gradient_lut_cache&,
|
||||
bool render_paint_servers = false);
|
||||
//---------------------------------------------------------------------
|
||||
void ignore_viewBox(bool ignVB)
|
||||
{
|
||||
m_ignore_view_box = ignVB;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
bool start_element(const dom_storage& st,
|
||||
const element_data& el);
|
||||
//---------------------------------------------------------------------
|
||||
bool end_element(const dom_storage& st, const element_data& el);
|
||||
//---------------------------------------------------------------------
|
||||
#ifdef EXPAND_PATHS
|
||||
void expand(double value)
|
||||
{
|
||||
m_pipeline.expand(value);
|
||||
}
|
||||
#endif
|
||||
//---------------------------------------------------------------------
|
||||
element_e current_element() {return m_current_element;}
|
||||
//---------------------------------------------------------------------
|
||||
template <class DataAccessor>
|
||||
element_e interpret_element(const DataAccessor& data)
|
||||
{
|
||||
dom_storage::map_type::iterator it = m_it2element_map.find(data);
|
||||
if (it == m_it2element_map.end())
|
||||
{
|
||||
return end_of_elements;
|
||||
}
|
||||
m_current_element = end_of_elements;
|
||||
|
||||
return (*it).second.code;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void process_xlink_href(data_accessor_type data);
|
||||
//---------------------------------------------------------------------
|
||||
private:
|
||||
//---------------------------------------------------------------------
|
||||
typedef rendering_interpreter this_type;
|
||||
typedef void (this_type::*el_interpreter)(const element_data&);
|
||||
static el_interpreter const element_interpreters[];
|
||||
//---------------------------------------------------------------------
|
||||
void render_circle (const element_data&);
|
||||
void render_clipPath (const element_data&);
|
||||
void render_defs (const element_data&);
|
||||
void render_ellipse (const element_data&);
|
||||
void render_g (const element_data&);
|
||||
void render_line (const element_data&);
|
||||
void render_linearGradient (const element_data&);
|
||||
void render_path (const element_data&);
|
||||
void render_polygon (const element_data&);
|
||||
void render_polyline (const element_data&);
|
||||
void render_radialGradient (const element_data&);
|
||||
void render_rect (const element_data&);
|
||||
void render_stop (const element_data&);
|
||||
void render_svg (const element_data&);
|
||||
void set_title_element (const element_data&);
|
||||
void render_use (const element_data&);
|
||||
//---------------------------------------------------------------------
|
||||
double read_length(const data_accessor_type& data) const;
|
||||
//---------------------------------------------------------------------
|
||||
objectUnits_e read_objectUnits(const data_accessor_type& data) const;
|
||||
//---------------------------------------------------------------------
|
||||
void read_viewBox(const data_accessor_type& data,
|
||||
double* x, double* y, double* w, double* h) const;
|
||||
//---------------------------------------------------------------------
|
||||
void read_preserveAspectRatio(const data_accessor_type& data,
|
||||
uniform_scaling_e* usc,
|
||||
window_fit_logic_e* wfl) const;
|
||||
//---------------------------------------------------------------------
|
||||
template <class VertexSource>
|
||||
void general_work_for_basic_shapes(const element_data& el,
|
||||
VertexSource& src)
|
||||
{
|
||||
conv_polymorphic_wrapper<VertexSource> source(src);
|
||||
m_vertex_source = &source;
|
||||
|
||||
m_attr_setter.set_basic_shapes_common_attributes(el.attr, el.num_attr);
|
||||
|
||||
gradient fill_gradient;
|
||||
gradient stroke_gradient;
|
||||
|
||||
prepare_gradient_fill (fill_gradient);
|
||||
prepare_gradient_stroke (stroke_gradient);
|
||||
|
||||
m_pipeline.render(m_attributes, src, m_renderer);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
bool element_is_paint_server(element_e code) const;
|
||||
//---------------------------------------------------------------------
|
||||
void calculate_and_set_object_bbox(object_bbox& bbox);
|
||||
//---------------------------------------------------------------------
|
||||
bool units_is_objectBoundingBox(unsigned idx, attr_e code) const;
|
||||
//---------------------------------------------------------------------
|
||||
void create_gradient(gradient&, unsigned);
|
||||
//---------------------------------------------------------------------
|
||||
void prepare_gradient_fill (gradient&);
|
||||
//---------------------------------------------------------------------
|
||||
void prepare_gradient_stroke(gradient&);
|
||||
//---------------------------------------------------------------------
|
||||
bool is_visible(coord_type(&)[4]) const;
|
||||
//---------------------------------------------------------------------
|
||||
void set_common_gradient_attributes(attr_data*, unsigned);
|
||||
//---------------------------------------------------------------------
|
||||
void set_gradient (gradient* g) {m_gradient = g; }
|
||||
//---------------------------------------------------------------------
|
||||
unsigned locate(const char* str);
|
||||
//---------------------------------------------------------------------
|
||||
template <class DataAccessor>
|
||||
unsigned locate(DataAccessor id, int* = 0)
|
||||
{
|
||||
dom_storage::map_type::iterator it;
|
||||
|
||||
it = m_it2element_map.find(id);
|
||||
|
||||
if (it == m_it2element_map.end())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return it->second.idx;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
pipeline& m_pipeline;
|
||||
attributes& m_attributes;
|
||||
gradient_lut_cache& m_gradient_lut_cache;
|
||||
renderer_rgba_type& m_renderer;
|
||||
dom_storage const * m_storage;
|
||||
dom_storage::map_type& m_it2element_map;
|
||||
element_e m_current_element;
|
||||
gradient* m_gradient;
|
||||
attributes_setter m_attr_setter;
|
||||
int m_defs_counter;
|
||||
int m_paint_server_counter;
|
||||
|
||||
conv_polymorphic_base* m_vertex_source;
|
||||
|
||||
bool m_render_paint_servers;
|
||||
bool m_clipPath;
|
||||
bool m_ignore_view_box;
|
||||
};
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_RENDERING_INTERPRETER_INCLUDED
|
||||
305
DesktopEditor/agg-2.4/svg/agg_svg_shape_adaptors.h
Normal file
305
DesktopEditor/agg-2.4/svg/agg_svg_shape_adaptors.h
Normal file
@ -0,0 +1,305 @@
|
||||
#ifndef AGG_SVG_SHAPE_ADAPTORS_INCLUDED
|
||||
#define AGG_SVG_SHAPE_ADAPTORS_INCLUDED
|
||||
|
||||
#include "agg_bezier_arc.h"
|
||||
#include "agg_svg_basics.h"
|
||||
#include "agg_svg_path_serializer.h"
|
||||
#include "agg_svg_path_interpreter.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
template<class CoordT, unsigned MaxVertices=32> class simple_path_container
|
||||
{
|
||||
public:
|
||||
typedef CoordT coord_type;
|
||||
enum { max_vertices = MaxVertices };
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
simple_path_container() :
|
||||
m_end_of_buffer(m_buffer + max_vertices * (sizeof(agg::int8u) + sizeof(CoordT) * 2)),
|
||||
m_end_of_data(m_buffer),
|
||||
m_vertex(m_buffer)
|
||||
{}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void remove_all()
|
||||
{
|
||||
m_end_of_data = m_buffer;
|
||||
m_vertex = m_buffer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
bool add_vertex(double x, double y, unsigned cmd)
|
||||
{
|
||||
if((m_end_of_data + sizeof(agg::int8u) + sizeof(CoordT) * 2) <= m_end_of_buffer)
|
||||
{
|
||||
CoordT tx = (CoordT)x;
|
||||
CoordT ty = (CoordT)y;
|
||||
*m_end_of_data++ = (agg::int8u)cmd;
|
||||
memcpy(m_end_of_data, &tx, sizeof(CoordT));
|
||||
m_end_of_data += sizeof(CoordT);
|
||||
memcpy(m_end_of_data, &ty, sizeof(CoordT));
|
||||
m_end_of_data += sizeof(CoordT);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void move_to(double x, double y)
|
||||
{
|
||||
add_vertex(x, y, agg::path_cmd_move_to);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void line_to(double x, double y)
|
||||
{
|
||||
add_vertex(x, y, agg::path_cmd_line_to);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void curve3_to(double x1, double y1, double x, double y)
|
||||
{
|
||||
add_vertex(x1, y1, agg::path_cmd_curve3);
|
||||
add_vertex(x , y, agg::path_cmd_curve3);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void curve4_to(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x, double y)
|
||||
{
|
||||
add_vertex(x1, y1, agg::path_cmd_curve4);
|
||||
add_vertex(x2, y2, agg::path_cmd_curve4);
|
||||
add_vertex(x , y, agg::path_cmd_curve4);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void close_subpath()
|
||||
{
|
||||
add_vertex(0.0, 0.0, agg::path_cmd_end_poly | agg::path_flags_close);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template<class VertexSource> void add_path(VertexSource& vs, unsigned path_id=0)
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
unsigned cmd;
|
||||
vs.rewind(path_id);
|
||||
while(!agg::is_stop(cmd = vs.vertex(&x, &y)))
|
||||
{
|
||||
if(!add_vertex(x, y, cmd)) break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template<class VertexSource> void add_path_solid(VertexSource& vs, unsigned path_id=0)
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
unsigned cmd;
|
||||
vs.rewind(path_id);
|
||||
while(agg::is_move_to(cmd = vs.vertex(&x, &y)));
|
||||
if(!agg::is_stop(cmd))
|
||||
{
|
||||
if(add_vertex(x, y, cmd))
|
||||
{
|
||||
while(!agg::is_stop(cmd = vs.vertex(&x, &y)))
|
||||
{
|
||||
if(!add_vertex(x, y, cmd)) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void rewind(unsigned)
|
||||
{
|
||||
m_vertex = m_buffer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
if(m_vertex >= m_end_of_data) return agg::path_cmd_stop;
|
||||
CoordT tx;
|
||||
CoordT ty;
|
||||
unsigned cmd = *m_vertex++;
|
||||
memcpy(&tx, m_vertex, sizeof(CoordT));
|
||||
m_vertex += sizeof(CoordT);
|
||||
memcpy(&ty, m_vertex, sizeof(CoordT));
|
||||
m_vertex += sizeof(CoordT);
|
||||
*x = (double)tx;
|
||||
*y = (double)ty;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
private:
|
||||
agg::int8u m_buffer[max_vertices * (sizeof(agg::int8u) + sizeof(CoordT) * 2)];
|
||||
agg::int8u* m_end_of_buffer;
|
||||
agg::int8u* m_end_of_data;
|
||||
const agg::int8u* m_vertex;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
class line_adaptor
|
||||
{
|
||||
public:
|
||||
line_adaptor() {}
|
||||
line_adaptor(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
init(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
void init(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
m_path.remove_all();
|
||||
m_path.move_to(x1, y1);
|
||||
m_path.line_to(x2, y2);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void rewind(unsigned) { m_path.rewind(0); }
|
||||
unsigned vertex(double* x, double* y) { return m_path.vertex(x, y); }
|
||||
|
||||
private:
|
||||
simple_path_container<coord_type, 2> m_path;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
class rectangle_adaptor
|
||||
{
|
||||
public:
|
||||
rectangle_adaptor() {}
|
||||
rectangle_adaptor(double x, double y, double w, double h, double rx=0, double ry=0)
|
||||
{
|
||||
init(x, y, w, h, rx, ry);
|
||||
}
|
||||
|
||||
void init(double x, double y, double w, double h, double rx=0, double ry=0)
|
||||
{
|
||||
m_path.remove_all();
|
||||
if(w < 0.0) return;
|
||||
if(h < 0.0) return;
|
||||
double x1 = x;
|
||||
double y1 = y;
|
||||
double x2 = x + w;
|
||||
double y2 = y + h;
|
||||
if(rx == 0.0) rx = ry;
|
||||
if(ry == 0.0) ry = rx;
|
||||
if(rx == 0.0 || ry == 0.0)
|
||||
{
|
||||
m_path.move_to(x1, y1);
|
||||
m_path.line_to(x2, y1);
|
||||
m_path.line_to(x2, y2);
|
||||
m_path.line_to(x1, y2);
|
||||
m_path.close_subpath();
|
||||
}
|
||||
else
|
||||
{
|
||||
double dx = fabs(y2 - y1);
|
||||
double dy = fabs(x2 - x1);
|
||||
|
||||
double k = 1.0;
|
||||
double t;
|
||||
t = dx / (rx * 2.0); if(t < k) k = t;
|
||||
t = dy / (ry * 2.0); if(t < k) k = t;
|
||||
|
||||
if(k < 1.0)
|
||||
{
|
||||
rx *= k;
|
||||
ry *= k;
|
||||
}
|
||||
agg::bezier_arc a;
|
||||
m_path.move_to(x1 + rx, y1);
|
||||
m_path.line_to(x2 - rx, y1);
|
||||
a.init(x2 - rx, y1 + ry, rx, ry, -agg::pi/2.0, agg::pi/2.0);
|
||||
m_path.add_path_solid(a);
|
||||
m_path.line_to(x2, y2 - ry);
|
||||
a.init(x2 - rx, y2 - ry, rx, ry, 0.0, agg::pi/2.0);
|
||||
m_path.add_path_solid(a);
|
||||
m_path.line_to(x1 + rx, y2);
|
||||
a.init(x1 + rx, y2 - ry, rx, ry, agg::pi/2.0, agg::pi/2.0);
|
||||
m_path.add_path_solid(a);
|
||||
m_path.line_to(x1, y1 + ry);
|
||||
a.init(x1 + rx, y1 + ry, rx, ry, agg::pi, agg::pi/2.0);
|
||||
m_path.add_path_solid(a);
|
||||
m_path.close_subpath();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void rewind(unsigned) { m_path.rewind(0); }
|
||||
unsigned vertex(double* x, double* y) { return m_path.vertex(x, y); }
|
||||
|
||||
private:
|
||||
simple_path_container<coord_type, 30> m_path;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
class circle_adaptor
|
||||
{
|
||||
public:
|
||||
circle_adaptor() {}
|
||||
circle_adaptor(double cx, double cy, double r)
|
||||
{
|
||||
init(cx, cy, r);
|
||||
}
|
||||
|
||||
void init(double cx, double cy, double r)
|
||||
{
|
||||
m_path.remove_all();
|
||||
if(r > 0.0)
|
||||
{
|
||||
agg::bezier_arc a(cx, cy, r, r, 0, 2.0*agg::pi);
|
||||
m_path.add_path(a);
|
||||
m_path.close_subpath();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void rewind(unsigned) { m_path.rewind(0); }
|
||||
unsigned vertex(double* x, double* y) { return m_path.vertex(x, y); }
|
||||
|
||||
private:
|
||||
simple_path_container<coord_type, 20> m_path;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
class ellipse_adaptor
|
||||
{
|
||||
public:
|
||||
ellipse_adaptor() {}
|
||||
ellipse_adaptor(double cx, double cy, double rx, double ry)
|
||||
{
|
||||
init(cx, cy, rx, ry);
|
||||
}
|
||||
|
||||
void init(double cx, double cy, double rx, double ry)
|
||||
{
|
||||
m_path.remove_all();
|
||||
if(rx > 0.0 && ry > 0.0)
|
||||
{
|
||||
agg::bezier_arc a(cx, cy, rx, ry, 0, 2.0*agg::pi);
|
||||
m_path.add_path(a);
|
||||
m_path.close_subpath();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void rewind(unsigned) { m_path.rewind(0); }
|
||||
unsigned vertex(double* x, double* y) { return m_path.vertex(x, y); }
|
||||
|
||||
private:
|
||||
simple_path_container<coord_type, 20> m_path;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
26
DesktopEditor/agg-2.4/svg/agg_svg_tags.h
Normal file
26
DesktopEditor/agg-2.4/svg/agg_svg_tags.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef AGG_SVG_TAGS_INCLUDE
|
||||
#define AGG_SVG_TAGS_INCLUDE
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
enum tag_e
|
||||
{
|
||||
tag_end_element = 0,
|
||||
|
||||
tag_element_bin,
|
||||
|
||||
tag_attribute_bin,
|
||||
tag_attribute_bin_short,
|
||||
tag_attribute_bin_byte,
|
||||
|
||||
end_of_tags,
|
||||
};
|
||||
|
||||
} // namespace svg
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_TAGS_INCLUDE
|
||||
|
||||
|
||||
276
DesktopEditor/agg-2.4/svg/agg_svg_transformer.cpp
Normal file
276
DesktopEditor/agg-2.4/svg/agg_svg_transformer.cpp
Normal file
@ -0,0 +1,276 @@
|
||||
#include "agg_svg_transformer.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void viewbox_to_viewport(agg::trans_viewport& tr,
|
||||
double x, double y, double w, double h,
|
||||
uniform_scaling_e align_type,
|
||||
window_fit_logic_e meet_or_slice)
|
||||
{
|
||||
if(w > 0.0 && h > 0.0)
|
||||
{
|
||||
tr.world_viewport(x, y, x + w, y + h);
|
||||
}
|
||||
|
||||
agg::aspect_ratio_e ar =
|
||||
(meet_or_slice == window_meet) ? agg::aspect_ratio_meet :
|
||||
agg::aspect_ratio_slice;
|
||||
switch(align_type)
|
||||
{
|
||||
case usc_none: tr.preserve_aspect_ratio(0.0, 0.0, agg::aspect_ratio_stretch); break;
|
||||
case usc_xMinYMin: tr.preserve_aspect_ratio(0.0, 0.0, ar); break;
|
||||
case usc_xMidYMin: tr.preserve_aspect_ratio(0.5, 0.0, ar); break;
|
||||
case usc_xMaxYMin: tr.preserve_aspect_ratio(1.0, 0.0, ar); break;
|
||||
case usc_xMinYMid: tr.preserve_aspect_ratio(0.0, 0.5, ar); break;
|
||||
case usc_xMidYMid: tr.preserve_aspect_ratio(0.5, 0.5, ar); break;
|
||||
case usc_xMaxYMid: tr.preserve_aspect_ratio(1.0, 0.5, ar); break;
|
||||
case usc_xMinYMax: tr.preserve_aspect_ratio(0.0, 1.0, ar); break;
|
||||
case usc_xMidYMax: tr.preserve_aspect_ratio(0.5, 1.0, ar); break;
|
||||
case usc_xMaxYMax: tr.preserve_aspect_ratio(1.0, 1.0, ar); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void transformer::update()
|
||||
{
|
||||
if(is_valid())
|
||||
{
|
||||
m_transformer = m_affine;
|
||||
m_transformer *= m_viewport.to_affine();
|
||||
m_transformer *= m_zoom.to_affine();
|
||||
m_transformer *= agg::trans_affine_translation(-m_dx, -m_dy);
|
||||
m_scale = m_transformer.scale();
|
||||
m_viewport.device_viewport(&m_device_x1, &m_device_y1,
|
||||
&m_device_x2, &m_device_y2);
|
||||
m_clip_x1 = m_viewbox_x1;
|
||||
m_clip_y1 = m_viewbox_y1;
|
||||
m_clip_x2 = m_viewbox_x2;
|
||||
m_clip_y2 = m_viewbox_y2;
|
||||
double w = m_buffer_x2 - m_buffer_x1;
|
||||
double h = m_buffer_y2 - m_buffer_y1;
|
||||
if(m_clip_x1 < 0) m_clip_x1 = 0;
|
||||
if(m_clip_x2 > w) m_clip_x2 = w;
|
||||
if(m_clip_y1 < 0) m_clip_y1 = 0;
|
||||
if(m_clip_y2 > h) m_clip_y2 = h;
|
||||
}
|
||||
else
|
||||
{
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void transformer::invalidate()
|
||||
{
|
||||
m_transformer = m_affine;
|
||||
m_scale = m_affine.scale();
|
||||
m_dx = 0;
|
||||
m_dy = 0;
|
||||
m_device_x1 = 0;
|
||||
m_device_y1 = 0;
|
||||
m_device_x2 = 1;
|
||||
m_device_y2 = 1;
|
||||
m_window_x1 = 0;
|
||||
m_window_y1 = 0;
|
||||
m_window_x2 = -1;
|
||||
m_window_y2 = -1;
|
||||
m_viewbox_x1 = 0;
|
||||
m_viewbox_y1 = 0;
|
||||
m_viewbox_x2 = -1;
|
||||
m_viewbox_y2 = -1;
|
||||
m_viewbox_dx = 0;
|
||||
m_viewbox_dy = 0;
|
||||
m_buffer_x1 = 0;
|
||||
m_buffer_y1 = 0;
|
||||
m_buffer_x2 = -1;
|
||||
m_buffer_y2 = -1;
|
||||
m_clip_x1 = 0;
|
||||
m_clip_y1 = 0;
|
||||
m_clip_x2 = -1;
|
||||
m_clip_y2 = -1;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void transformer::viewBox(const agg::trans_viewport& vp)
|
||||
{
|
||||
m_viewport = vp;
|
||||
m_viewport.device_viewport(&m_device_x1, &m_device_y1,
|
||||
&m_device_x2, &m_device_y2);
|
||||
m_buffer_x1 = int(floor(m_device_x1));
|
||||
m_buffer_y1 = int(floor(m_device_y1));
|
||||
m_buffer_x2 = int( ceil(m_device_x2));
|
||||
m_buffer_y2 = int( ceil(m_device_y2));
|
||||
m_window_x1 = int(floor(m_device_x1));
|
||||
m_window_y1 = int(floor(m_device_y1));
|
||||
m_window_x2 = int( ceil(m_device_x2));
|
||||
m_window_y2 = int( ceil(m_device_y2));
|
||||
m_dx = 0;
|
||||
m_dy = 0;
|
||||
m_viewbox_x1 = m_device_x1;
|
||||
m_viewbox_y1 = m_device_y1;
|
||||
m_viewbox_x2 = m_device_x2;
|
||||
m_viewbox_y2 = m_device_y2;
|
||||
m_viewbox_dx = 0;
|
||||
m_viewbox_dy = 0;
|
||||
m_clip_x1 = m_device_x1;
|
||||
m_clip_y1 = m_device_y1;
|
||||
m_clip_x2 = m_device_x2;
|
||||
m_clip_y2 = m_device_y2;
|
||||
m_viewBox_level = 1;
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void transformer::viewBox(double scx, double scy, double scw, double sch,
|
||||
double vbx, double vby, double vbw, double vbh,
|
||||
uniform_scaling_e align_type,
|
||||
window_fit_logic_e meet_or_slice,
|
||||
bool separate_buffer)
|
||||
{
|
||||
if(!is_valid())
|
||||
{
|
||||
invalidate();
|
||||
return;
|
||||
}
|
||||
|
||||
double x0, y0, x1, y1, x2, y2;
|
||||
x2 = scx + scw;
|
||||
y2 = scy + sch;
|
||||
m_viewport.transform(&scx, &scy);
|
||||
m_viewport.transform(&x2, &y2);
|
||||
if(separate_buffer)
|
||||
{
|
||||
x0 = 0;
|
||||
y0 = 0;
|
||||
m_viewport.transform(&x0, &y0);
|
||||
if(m_viewBox_level > 0)
|
||||
{
|
||||
x1 = m_zoom.device_dx() - m_viewbox_dx;
|
||||
y1 = m_zoom.device_dy() - m_viewbox_dy;
|
||||
m_zoom.inverse_transform_scale_only(&x1, &y1);
|
||||
x0 += x1;
|
||||
y0 += y1;
|
||||
}
|
||||
|
||||
x1 = m_viewbox_x1;
|
||||
y1 = m_viewbox_y1;
|
||||
m_zoom.inverse_transform_scale_only(&x1, &y1);
|
||||
x0 -= x1;
|
||||
y0 -= y1;
|
||||
scx -= x0;
|
||||
scy -= y0;
|
||||
x2 -= x0;
|
||||
y2 -= y0;
|
||||
}
|
||||
else
|
||||
{
|
||||
x0 = m_dx;
|
||||
y0 = m_dy;
|
||||
m_zoom.inverse_transform_scale_only(&x0, &y0);
|
||||
scx -= x0;
|
||||
scy -= y0;
|
||||
x2 -= x0;
|
||||
y2 -= y0;
|
||||
}
|
||||
|
||||
m_viewport.device_viewport(scx, scy, x2, y2);
|
||||
viewbox_to_viewport(m_viewport, vbx, vby, vbw, vbh, align_type, meet_or_slice);
|
||||
if(!m_viewport.is_valid())
|
||||
{
|
||||
invalidate();
|
||||
return;
|
||||
}
|
||||
|
||||
m_dx = 0;
|
||||
m_dy = 0;
|
||||
if(separate_buffer)
|
||||
{
|
||||
bool wflag = m_window_x1 < m_window_x2 && m_window_y1 < m_window_y2;
|
||||
if(wflag)
|
||||
{
|
||||
m_viewport.world_viewport(&x1, &y1, &x2, &y2);
|
||||
m_viewport.transform(&x1, &y1);
|
||||
m_viewport.transform(&x2, &y2);
|
||||
x0 = x1;
|
||||
y0 = y1;
|
||||
m_zoom.transform(&x1, &y1);
|
||||
m_zoom.transform(&x2, &y2);
|
||||
m_viewbox_x1 = x1;
|
||||
m_viewbox_y1 = y1;
|
||||
m_viewbox_x2 = x2;
|
||||
m_viewbox_y2 = y2;
|
||||
|
||||
m_viewbox_dx = 0;
|
||||
m_viewbox_dy = 0;
|
||||
if(m_viewbox_x1 < m_window_x1)
|
||||
{
|
||||
m_viewbox_dx = m_viewbox_x1 - m_window_x1;
|
||||
m_viewbox_x1 = m_window_x1;
|
||||
}
|
||||
if(m_viewbox_y1 < m_window_y1)
|
||||
{
|
||||
m_viewbox_dy = m_viewbox_y1 - m_window_y1;
|
||||
m_viewbox_y1 = m_window_y1;
|
||||
}
|
||||
if(m_viewbox_x2 > m_window_x2) m_viewbox_x2 = m_window_x2;
|
||||
if(m_viewbox_y2 > m_window_y2) m_viewbox_y2 = m_window_y2;
|
||||
|
||||
m_buffer_x1 = int(floor(m_viewbox_x1));
|
||||
m_buffer_y1 = int(floor(m_viewbox_y1));
|
||||
m_buffer_x2 = int( ceil(m_viewbox_x2));
|
||||
m_buffer_y2 = int( ceil(m_viewbox_y2));
|
||||
|
||||
m_viewbox_x1 -= m_buffer_x1;
|
||||
m_viewbox_y1 -= m_buffer_y1;
|
||||
m_viewbox_x2 -= m_buffer_x1;
|
||||
m_viewbox_y2 -= m_buffer_y1;
|
||||
|
||||
m_viewport.transform(&m_dx, &m_dy);
|
||||
m_zoom.transform(&m_dx, &m_dy);
|
||||
m_dx -= m_viewbox_x1 + m_viewbox_dx;
|
||||
m_dy -= m_viewbox_y1 + m_viewbox_dy;
|
||||
}
|
||||
update();
|
||||
if(!wflag)
|
||||
{
|
||||
m_buffer_x1 = int(floor(m_device_x1));
|
||||
m_buffer_y1 = int(floor(m_device_y1));
|
||||
m_buffer_x2 = int(ceil(m_device_x2));
|
||||
m_buffer_y2 = int(ceil(m_device_y2));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
update();
|
||||
m_viewbox_x1 = vbx;
|
||||
m_viewbox_y1 = vby;
|
||||
m_viewbox_x2 = vbx + vbw;
|
||||
m_viewbox_y2 = vby + vbh;
|
||||
m_viewport.transform(&m_viewbox_x1, &m_viewbox_y1);
|
||||
m_viewport.transform(&m_viewbox_x2, &m_viewbox_y2);
|
||||
m_zoom.transform(&m_viewbox_x1, &m_viewbox_y1);
|
||||
m_zoom.transform(&m_viewbox_x2, &m_viewbox_y2);
|
||||
m_clip_x1 = m_viewbox_x1;
|
||||
m_clip_y1 = m_viewbox_y1;
|
||||
m_clip_x2 = m_viewbox_x2;
|
||||
m_clip_y2 = m_viewbox_y2;
|
||||
double w = m_buffer_x2 - m_buffer_x1;
|
||||
double h = m_buffer_y2 - m_buffer_y1;
|
||||
if(m_clip_x1 < 0) m_clip_x1 = 0;
|
||||
if(m_clip_x2 > w) m_clip_x2 = w;
|
||||
if(m_clip_y1 < 0) m_clip_y1 = 0;
|
||||
if(m_clip_y2 > h) m_clip_y2 = h;
|
||||
}
|
||||
++m_viewBox_level;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
364
DesktopEditor/agg-2.4/svg/agg_svg_transformer.h
Normal file
364
DesktopEditor/agg-2.4/svg/agg_svg_transformer.h
Normal file
@ -0,0 +1,364 @@
|
||||
#ifndef AGG_SVG_TRANSFORMER_INCLUDED
|
||||
#define AGG_SVG_TRANSFORMER_INCLUDED
|
||||
|
||||
#include "agg_trans_affine.h"
|
||||
#include "agg_trans_viewport.h"
|
||||
|
||||
#include "agg_svg_basics.h"
|
||||
#include "agg_svg_defines.h"
|
||||
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
// The transformer class integrates the viewport, additional zoom, and
|
||||
// arbitary affine transformations.
|
||||
//
|
||||
// USAGE:
|
||||
// transformer tr;
|
||||
// tr.viewBox(. . .);
|
||||
// . . .
|
||||
// tr.transform(&x, &y);
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
class transformer
|
||||
{
|
||||
public:
|
||||
//-------------------------------------------------------------
|
||||
transformer() :
|
||||
m_affine(),
|
||||
m_viewport(),
|
||||
m_zoom(),
|
||||
m_transformer(),
|
||||
m_viewBox_level(0),
|
||||
m_scale(1.0),
|
||||
m_dx(0),
|
||||
m_dy(0),
|
||||
m_device_x1(0),
|
||||
m_device_y1(0),
|
||||
m_device_x2(1),
|
||||
m_device_y2(1),
|
||||
m_window_x1(0),
|
||||
m_window_y1(0),
|
||||
m_window_x2(-1),
|
||||
m_window_y2(-1),
|
||||
m_viewbox_x1(0),
|
||||
m_viewbox_y1(0),
|
||||
m_viewbox_x2(-1),
|
||||
m_viewbox_y2(-1),
|
||||
m_viewbox_dx(0),
|
||||
m_viewbox_dy(0),
|
||||
m_buffer_x1(0),
|
||||
m_buffer_y1(0),
|
||||
m_buffer_x2(-1),
|
||||
m_buffer_y2(-1),
|
||||
m_clip_x1(0),
|
||||
m_clip_y1(0),
|
||||
m_clip_x2(-1),
|
||||
m_clip_y2(-1)
|
||||
{
|
||||
m_viewport.preserve_aspect_ratio(0.5, 0.5, agg::aspect_ratio_meet);
|
||||
m_zoom.preserve_aspect_ratio(0.5, 0.5, agg::aspect_ratio_meet);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void reset()
|
||||
{
|
||||
*this = transformer();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void window(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
m_viewBox_level = 0;
|
||||
m_dx = 0;
|
||||
m_dy = 0;
|
||||
m_window_x1 = x1;
|
||||
m_window_y1 = y1;
|
||||
m_window_x2 = x2;
|
||||
m_window_y2 = y2;
|
||||
m_viewbox_x1 = x1;
|
||||
m_viewbox_y1 = y1;
|
||||
m_viewbox_x2 = x2;
|
||||
m_viewbox_y2 = y2;
|
||||
m_viewbox_dx = 0;
|
||||
m_viewbox_dy = 0;
|
||||
m_buffer_x1 = x1;
|
||||
m_buffer_y1 = y1;
|
||||
m_buffer_x2 = x2;
|
||||
m_buffer_y2 = y2;
|
||||
m_clip_x1 = x1;
|
||||
m_clip_y1 = y1;
|
||||
m_clip_x2 = x2;
|
||||
m_clip_y2 = y2;
|
||||
m_viewport.device_viewport(x1, y1, x2, y2);
|
||||
m_viewport.world_viewport(x1, y1, x2, y2);
|
||||
m_zoom.device_viewport(x1, y1, x2, y2);
|
||||
m_zoom.world_viewport(x1, y1, x2, y2);
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void viewBox(const agg::trans_viewport& vp);
|
||||
|
||||
void viewBox(double scx, double scy, double scw, double sch,
|
||||
double vbx, double vby, double vbw, double vbh,
|
||||
uniform_scaling_e align_type,
|
||||
window_fit_logic_e meet_or_slice,
|
||||
bool separate_window);
|
||||
|
||||
//-------------------------------------------------------------
|
||||
unsigned viewBox_level() const { return m_viewBox_level; }
|
||||
|
||||
//-------------------------------------------------------------
|
||||
bool is_visible(double x1, double y1, double x2, double y2) const
|
||||
{
|
||||
agg::rect_d cb(m_clip_x1, m_clip_y1, m_clip_x2, m_clip_y2);
|
||||
return cb.clip(agg::rect_d(x1, y1, x2, y2));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void zoom(double wx1, double wy1, double wx2, double wy2,
|
||||
double sx1, double sy1, double sx2, double sy2)
|
||||
{
|
||||
m_zoom.device_viewport(sx1, sy1, sx2, sy2);
|
||||
m_zoom.world_viewport(wx1, wy1, wx2, wy2);
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void zoom(double wx1, double wy1, double wx2, double wy2)
|
||||
{
|
||||
m_zoom.world_viewport(wx1, wy1, wx2, wy2);
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void zoom(double* x1, double* y1, double* x2, double* y2) const
|
||||
{
|
||||
m_zoom.transform(x1, y1);
|
||||
m_zoom.transform(x2, y2);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void inverse_zoom(double* x1, double* y1, double* x2, double* y2) const
|
||||
{
|
||||
m_zoom.inverse_transform(x1, y1);
|
||||
m_zoom.inverse_transform(x2, y2);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void device_viewport(double* x1, double* y1, double* x2, double* y2) const
|
||||
{
|
||||
m_viewport.device_viewport(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void world_viewport(double* x1, double* y1, double* x2, double* y2) const
|
||||
{
|
||||
m_viewport.world_viewport(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
const agg::trans_viewport& viewport() const { return m_viewport; }
|
||||
agg::trans_viewport& viewport() { return m_viewport; }
|
||||
|
||||
//-------------------------------------------------------------
|
||||
const agg::trans_viewport& zoom() const { return m_zoom; }
|
||||
agg::trans_viewport& zoom() { return m_zoom; }
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void transform(const agg::trans_affine& mtx)
|
||||
{
|
||||
m_affine.premultiply(mtx);
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void transform(double a0, double a1, double a2,
|
||||
double a3, double a4, double a5)
|
||||
{
|
||||
m_affine.premultiply(agg::trans_affine(a0, a1, a2, a3, a4, a5));
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void translate(double dx, double dy)
|
||||
{
|
||||
m_affine.premultiply(agg::trans_affine_translation(dx, dy));
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void rotate(double angle)
|
||||
{
|
||||
m_affine.premultiply(agg::trans_affine_rotation(angle));
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void rotate(double angle, double cx, double cy)
|
||||
{
|
||||
agg::trans_affine_translation m(-cx, -cy);
|
||||
m *= agg::trans_affine_rotation(angle);
|
||||
m *= agg::trans_affine_translation(cx, cy);
|
||||
m_affine.premultiply(m);
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void scale(double s)
|
||||
{
|
||||
m_affine.premultiply(agg::trans_affine_scaling(s));
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void scale(double sx, double sy)
|
||||
{
|
||||
m_affine.premultiply(agg::trans_affine_scaling(sx, sy));
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void skew(double sx, double sy)
|
||||
{
|
||||
m_affine.premultiply(agg::trans_affine_skewing(sx, sy));
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void skew_x(double s)
|
||||
{
|
||||
m_affine.premultiply(agg::trans_affine_skewing(s, 0.0));
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void skew_y(double s)
|
||||
{
|
||||
m_affine.premultiply(agg::trans_affine_skewing(0.0, s));
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
unsigned byte_size_affine() const
|
||||
{
|
||||
return 6 * sizeof(double);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void serialize_affine(agg::int8u* ptr) const
|
||||
{
|
||||
double mtx[6];
|
||||
m_affine.store_to(mtx);
|
||||
memcpy(ptr, mtx, sizeof(mtx));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void deserialize_affine(const agg::int8u* ptr)
|
||||
{
|
||||
double mtx[6];
|
||||
memcpy(mtx, ptr, sizeof(mtx));
|
||||
m_affine.load_from(mtx);
|
||||
update();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void transform(double* x, double* y) const
|
||||
{
|
||||
m_transformer.transform(x, y);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
void inverse_transform(double* x, double* y) const
|
||||
{
|
||||
m_transformer.inverse_transform(x, y);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
bool is_valid() const
|
||||
{
|
||||
return m_viewport.is_valid() &&
|
||||
m_zoom.is_valid() &&
|
||||
m_buffer_x2 > m_buffer_x1 &&
|
||||
m_buffer_y2 > m_buffer_y1;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
double scale() const
|
||||
{
|
||||
return m_scale;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
const agg::trans_affine& transform() const
|
||||
{
|
||||
return m_transformer;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
double device_x1() const { return m_device_x1; }
|
||||
double device_y1() const { return m_device_y1; }
|
||||
double device_x2() const { return m_device_x2; }
|
||||
double device_y2() const { return m_device_y2; }
|
||||
|
||||
int window_x1() const { return m_window_x1; }
|
||||
int window_y1() const { return m_window_y1; }
|
||||
int window_x2() const { return m_window_x2; }
|
||||
int window_y2() const { return m_window_y2; }
|
||||
|
||||
double clip_x1() const { return m_clip_x1; }
|
||||
double clip_y1() const { return m_clip_y1; }
|
||||
double clip_x2() const { return m_clip_x2; }
|
||||
double clip_y2() const { return m_clip_y2; }
|
||||
|
||||
int buffer_x1() const { return m_buffer_x1; }
|
||||
int buffer_y1() const { return m_buffer_y1; }
|
||||
int buffer_x2() const { return m_buffer_x2; }
|
||||
int buffer_y2() const { return m_buffer_y2; }
|
||||
|
||||
private:
|
||||
void update();
|
||||
void invalidate();
|
||||
|
||||
agg::trans_affine m_affine;
|
||||
agg::trans_viewport m_viewport;
|
||||
agg::trans_viewport m_zoom;
|
||||
agg::trans_affine m_transformer;
|
||||
unsigned m_viewBox_level;
|
||||
double m_scale;
|
||||
double m_dx;
|
||||
double m_dy;
|
||||
double m_device_x1;
|
||||
double m_device_y1;
|
||||
double m_device_x2;
|
||||
double m_device_y2;
|
||||
int m_window_x1;
|
||||
int m_window_y1;
|
||||
int m_window_x2;
|
||||
int m_window_y2;
|
||||
double m_viewbox_x1;
|
||||
double m_viewbox_y1;
|
||||
double m_viewbox_x2;
|
||||
double m_viewbox_y2;
|
||||
double m_viewbox_dx;
|
||||
double m_viewbox_dy;
|
||||
double m_clip_x1;
|
||||
double m_clip_y1;
|
||||
double m_clip_x2;
|
||||
double m_clip_y2;
|
||||
int m_buffer_x1;
|
||||
int m_buffer_y1;
|
||||
int m_buffer_x2;
|
||||
int m_buffer_y2;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
70
DesktopEditor/agg-2.4/svg/agg_svg_utils.cpp
Normal file
70
DesktopEditor/agg-2.4/svg/agg_svg_utils.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
|
||||
#include "agg_svg_utils.h"
|
||||
#include <cstdlib> // for wcstombs
|
||||
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
namespace aux
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
const unsigned char is_numeric_helper::s_set[] = "0123456789+-.eE";
|
||||
//-------------------------------------------------------------------------
|
||||
const unsigned char is_wsp_helper::s_set[] = " \t\n\r";
|
||||
//-------------------------------------------------------------------------
|
||||
}
|
||||
std::string to_str(const wchar_t* chars, int len )
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
if( len==0 ) len = (int)wcslen( chars );
|
||||
|
||||
std::string result_str;
|
||||
if (len <= 512)
|
||||
{
|
||||
char buf[512];
|
||||
wcstombs(buf, chars, len);
|
||||
|
||||
return std::string( buf, len );
|
||||
|
||||
}else
|
||||
{
|
||||
std::vector<char> vecch;
|
||||
vecch.reserve(len);
|
||||
|
||||
wcstombs( &vecch[0], chars, len );
|
||||
return std::string( &vecch[0], len );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
std::wstring to_wstr(const char* chars, int len )
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
if( len == 0 ) len = (int)strlen(chars);
|
||||
|
||||
std::wstring result_str;
|
||||
if (len <= 512)
|
||||
{
|
||||
wchar_t buf[512];
|
||||
mbstowcs(buf, chars, len);
|
||||
|
||||
return std::wstring( buf, len );
|
||||
|
||||
}else
|
||||
{
|
||||
std::vector<wchar_t> vecwch;
|
||||
vecwch.reserve(len);
|
||||
|
||||
mbstowcs( &vecwch[0], chars, len );
|
||||
return std::wstring( &vecwch[0], len );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
194
DesktopEditor/agg-2.4/svg/agg_svg_utils.h
Normal file
194
DesktopEditor/agg-2.4/svg/agg_svg_utils.h
Normal file
@ -0,0 +1,194 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef AGG_SVG_UTILS_INCLUDED
|
||||
#define AGG_SVG_UTILS_INCLUDED
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cstdlib> // for atof
|
||||
#include <cstring>
|
||||
#include "agg_svg_parse_real.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
namespace aux
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
struct is_numeric_helper
|
||||
{
|
||||
is_numeric_helper() { init_mask(m_set_mask, s_set); }
|
||||
|
||||
bool operator()(unsigned c) const
|
||||
{
|
||||
return (m_set_mask[(c >> 3) & (256/8-1)] & (1 << (c & 7)))!= 0;
|
||||
}
|
||||
|
||||
private:
|
||||
static void init_mask(unsigned char* mask,
|
||||
const unsigned char* char_set);
|
||||
|
||||
unsigned char m_set_mask[256/8];
|
||||
|
||||
static const unsigned char s_set[];
|
||||
};
|
||||
//---------------------------------------------------------------------
|
||||
inline void is_numeric_helper::init_mask(unsigned char* mask,
|
||||
const unsigned char* char_set)
|
||||
{
|
||||
using namespace std;
|
||||
memset(mask, 0, 256/8);
|
||||
while(*char_set)
|
||||
{
|
||||
unsigned c = unsigned(*char_set++) & 0xFF;
|
||||
mask[c >> 3] |= 1 << (c & 7);
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
struct is_wsp_helper
|
||||
{
|
||||
is_wsp_helper() { init_mask(m_set_mask, s_set); }
|
||||
|
||||
bool operator()(unsigned c) const
|
||||
{
|
||||
return (m_set_mask[(c >> 3) & (256/8-1)] & (1 << (c & 7)))!= 0;
|
||||
}
|
||||
|
||||
private:
|
||||
static void init_mask(unsigned char* mask,
|
||||
const unsigned char* char_set);
|
||||
|
||||
unsigned char m_set_mask[256/8];
|
||||
|
||||
static const unsigned char s_set[];
|
||||
};
|
||||
//---------------------------------------------------------------------
|
||||
inline void is_wsp_helper::init_mask(unsigned char* mask,
|
||||
const unsigned char* char_set)
|
||||
{
|
||||
using namespace std;
|
||||
memset(mask, 0, 256/8);
|
||||
while(*char_set)
|
||||
{
|
||||
unsigned c = unsigned(*char_set++) & 0xFF;
|
||||
mask[c >> 3] |= 1 << (c & 7);
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
} // namespace aux
|
||||
//-------------------------------------------------------------------------
|
||||
std::string to_str (const wchar_t* chars, int len = 0);
|
||||
std::wstring to_wstr(const char* chars, int len = 0);
|
||||
//-------------------------------------------------------------------------
|
||||
inline bool is_wsp_or_eol(char c)
|
||||
{
|
||||
static aux::is_wsp_helper helper;
|
||||
return helper(c);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline bool is_wsp( char c)
|
||||
{
|
||||
return c == ' ' || c == '\t';
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline bool is_numeric(char c)
|
||||
{
|
||||
static aux::is_numeric_helper helper;
|
||||
return helper(c);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline double to_double(const char* str)
|
||||
{
|
||||
using namespace std;
|
||||
while(*str == ' ') ++str;
|
||||
|
||||
double val;
|
||||
const char* endptr;
|
||||
parse_real pd;
|
||||
if (!pd.parse(str, str + strlen(str), &val, &endptr))
|
||||
return 0.;
|
||||
return val;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline const char* next_number(const char* str)
|
||||
{
|
||||
while(*str && (*str == ' ' || *str == ',' || *str == ';')) ++str;
|
||||
while(*str && !(*str == ' ' || *str == ',' || *str == ';')) ++str;
|
||||
return str;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline const char* get_token(const char* str, char* buf, unsigned max_len)
|
||||
{
|
||||
while(*str && (*str == ' ' || *str == ',' || *str == ';')) ++str;
|
||||
while(*str && !(*str == ' ' || *str == ',' || *str == ';'))
|
||||
{
|
||||
if(max_len == 0) break;
|
||||
*buf++ = *str++;
|
||||
--max_len;
|
||||
}
|
||||
*buf = 0;
|
||||
return str;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline void left_trim(const char*& str)
|
||||
{
|
||||
while( is_wsp(*str) ) ++str;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline void left_trim(char*& str_begin, char* str_end )
|
||||
{
|
||||
using namespace std;
|
||||
while(str_begin < str_end && isspace(*str_begin)) ++str_begin;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline void right_trim(char* str_begin, char*& str_end,
|
||||
char additionalTokenToSkip = ' ')
|
||||
{
|
||||
using namespace std;
|
||||
char* ts = str_end;
|
||||
while(str_end > str_begin &&
|
||||
(*str_end == additionalTokenToSkip || isspace(*str_end))) --str_end;
|
||||
if(str_end < ts) ++str_end;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline void right_trim( const char* str )
|
||||
{
|
||||
using namespace std;
|
||||
char* p = const_cast<char*>(str) + strlen(str)-1;
|
||||
while( p >= str && isspace(*p) ) { *p=0x0; --p; }
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline bool str_starts( const char* str1, char ch )
|
||||
{
|
||||
return ( str1[0] == ch );
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline bool str_starts( const char* str1, const char* str2 )
|
||||
{
|
||||
return ( strncmp( str1, str2, strlen(str2) )==0 );
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline bool str_ends( const char* str1, char ch )
|
||||
{
|
||||
return ( str1[ strlen(str1)-1 ] == ch );
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
inline bool str_ends( const char* str1, const char* str2 )
|
||||
{
|
||||
size_t len1 = strlen( str1 );
|
||||
size_t len2 = strlen( str2 );
|
||||
|
||||
if( len1 < len2 )
|
||||
return false;
|
||||
|
||||
return ( strncmp( str1+len1-len2, str2, len2)==0 );
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
68
DesktopEditor/agg-2.4/svg/member_comparer.h
Normal file
68
DesktopEditor/agg-2.4/svg/member_comparer.h
Normal file
@ -0,0 +1,68 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef AGG_SVG_MEMBER_COMPARER_INCLUDED
|
||||
#define AGG_SVG_MEMBER_COMPARER_INCLUDED
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <functional> // for std::less
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace agg
|
||||
{
|
||||
namespace svg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
template <class T, class Type, class comparer>
|
||||
struct member_comparer
|
||||
{
|
||||
//---------------------------------------------------------------------
|
||||
typedef Type result_type;
|
||||
typedef T class_type;
|
||||
//---------------------------------------------------------------------
|
||||
member_comparer(Type T::*PtrToMember, comparer comp = comparer())
|
||||
: m_PtrToMember(PtrToMember),
|
||||
m_comparer(comp)
|
||||
{}
|
||||
//---------------------------------------------------------------------
|
||||
bool operator()(class_type const& lhs, class_type const& rhs) const
|
||||
{
|
||||
return m_comparer(lhs.*m_PtrToMember, rhs.*m_PtrToMember);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
bool operator()(Type const& lhs, class_type const& rhs, int = 0) const
|
||||
{
|
||||
return m_comparer(lhs, rhs.*m_PtrToMember);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
bool operator()(class_type const& lhs, Type const& rhs) const
|
||||
{
|
||||
return m_comparer(lhs.*m_PtrToMember, rhs);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
private:
|
||||
Type T::*m_PtrToMember;
|
||||
comparer m_comparer;
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
template <class T, class Type, class comparer>
|
||||
inline
|
||||
member_comparer<T, Type, comparer>
|
||||
make_comparer(Type T::*PtrToMember, comparer comp)
|
||||
{
|
||||
return member_comparer<T, Type, comparer>(PtrToMember, comp);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
template <class T, class Type>
|
||||
inline
|
||||
member_comparer<T, Type, std::less<Type> >
|
||||
make_comparer(Type T::*PtrToMember)
|
||||
{
|
||||
return member_comparer<T, Type, std::less<Type> >
|
||||
(PtrToMember, std::less<Type>());
|
||||
}
|
||||
|
||||
} // namespace svg
|
||||
|
||||
} // namespace agg
|
||||
|
||||
#endif // #ifndef AGG_SVG_MEMBER_COMPARER_INCLUDED
|
||||
|
||||
|
||||
|
||||
409
DesktopEditor/agg-2.4/svg/svg_test.cpp
Normal file
409
DesktopEditor/agg-2.4/svg/svg_test.cpp
Normal file
@ -0,0 +1,409 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "agg_scanline_p.h"
|
||||
#include "platform/agg_platform_support.h"
|
||||
#include "ctrl/agg_slider_ctrl.h"
|
||||
#include "agg_svg_exception.h"
|
||||
#include "agg_svg_parser.h"
|
||||
#include "agg_svg_indexation_interpreter.h"
|
||||
#include "agg_svg_rendering_interpreter.h"
|
||||
#include "agg_svg_attributes_map.h"
|
||||
#include "agg_svg_rasterizer.h"
|
||||
|
||||
enum { flip_y_e = false };
|
||||
|
||||
class the_application : public agg::platform_support
|
||||
{
|
||||
agg::svg::dom_storage m_storage;
|
||||
agg::svg::dom_storage::map_type m_id2elem_map;
|
||||
agg::svg::attributes_map m_attr_map;
|
||||
agg::svg::global_settings m_settings;
|
||||
agg::svg::attributes m_attributes;
|
||||
agg::svg::frame_buffer_rgba m_frame_buffer;
|
||||
agg::svg::rasterizer m_rasterizer;
|
||||
agg::svg::renderer_rgba m_renderer;
|
||||
agg::svg::pipeline m_pipeline;
|
||||
agg::svg::gradient_lut_cache m_gradient_lut_cache;
|
||||
|
||||
//agg::slider_ctrl<agg::rgba8> m_expand;
|
||||
agg::slider_ctrl<agg::rgba8> m_gamma;
|
||||
//agg::slider_ctrl<agg::rgba8> m_scale;
|
||||
//agg::slider_ctrl<agg::rgba8> m_rotate;
|
||||
|
||||
enum tool_type_e {tool_none, tool_zoom, tool_pan};
|
||||
|
||||
tool_type_e m_current_tool;
|
||||
|
||||
int m_x1;
|
||||
int m_y1;
|
||||
int m_x2;
|
||||
int m_y2;
|
||||
bool m_drag_flag;
|
||||
|
||||
public:
|
||||
|
||||
the_application(agg::pix_format_e format, bool flip_y) :
|
||||
agg::platform_support(format, flip_y),
|
||||
//m_expand(5, 5, 256-5, 11, !flip_y),
|
||||
m_gamma (5, 5, 256-5, 20, !flip_y),
|
||||
//m_scale (256+5, 5, 512-5, 11, !flip_y),
|
||||
//m_rotate(256+5, 5+15, 512-5, 11+15, !flip_y),
|
||||
m_x1(0),
|
||||
m_y1(0),
|
||||
m_x2(0),
|
||||
m_y2(0),
|
||||
m_drag_flag(false),
|
||||
m_attributes(m_settings),
|
||||
m_renderer(m_rasterizer, m_frame_buffer),
|
||||
m_current_tool(tool_none)
|
||||
{
|
||||
//add_ctrl(m_expand);
|
||||
add_ctrl(m_gamma);
|
||||
//add_ctrl(m_scale);
|
||||
//add_ctrl(m_rotate);
|
||||
|
||||
//m_expand.label("Expand=%3.2f");
|
||||
//m_expand.range(-1, 1.2);
|
||||
//m_expand.value(0.0);
|
||||
|
||||
m_gamma.label("Gamma=%3.2f");
|
||||
m_gamma.range(0.0, 3.0);
|
||||
m_gamma.value(1.0);
|
||||
|
||||
//m_scale.label("Scale=%3.2f");
|
||||
//m_scale.range(0.2, 10.0);
|
||||
//m_scale.value(1.0);
|
||||
|
||||
//m_rotate.label("Rotate=%3.2f");
|
||||
//m_rotate.range(-180.0, 180.0);
|
||||
//m_rotate.value(0.0);
|
||||
}
|
||||
|
||||
void swap_int(int* n1, int* n2)
|
||||
{
|
||||
int temp;
|
||||
|
||||
temp = *n1;
|
||||
*n1 = *n2;
|
||||
*n2 = temp;
|
||||
}
|
||||
|
||||
void normalize_rect(int* x1, int* y1, int* x2, int* y2)
|
||||
{
|
||||
if (*x1 > *x2)
|
||||
{
|
||||
swap_int(x1, x2);
|
||||
}
|
||||
if (*y1 > *y2)
|
||||
{
|
||||
swap_int(y1, y2);
|
||||
}
|
||||
}
|
||||
|
||||
void update_zoom()
|
||||
{
|
||||
if (m_current_tool == tool_zoom)
|
||||
{
|
||||
int x1 = m_x1;
|
||||
int y1 = m_y1;
|
||||
int x2 = m_x2;
|
||||
int y2 = m_y2;
|
||||
|
||||
normalize_rect(&x1, &y1, &x2, &y2);
|
||||
|
||||
m_attributes.set_zoom(x1, y1, x2, y2);
|
||||
}
|
||||
else if (m_current_tool == tool_pan)
|
||||
{
|
||||
int offset_x = m_x2 - m_x1;
|
||||
int offset_y = m_y2 - m_y1;
|
||||
|
||||
int x1 = -offset_x;
|
||||
int y1 = -offset_y;
|
||||
int x2 = rbuf_window().width() - offset_x;
|
||||
int y2 = rbuf_window().height() - offset_y;
|
||||
|
||||
m_attributes.set_zoom(x1, y1, x2, y2);
|
||||
}
|
||||
}
|
||||
|
||||
void indexation()
|
||||
{
|
||||
agg::svg::indexation_interpreter consumer(m_id2elem_map);
|
||||
|
||||
m_storage.traverse(consumer);
|
||||
|
||||
m_id2elem_map.sort_state(agg::svg::on);
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
m_id2elem_map.clear();
|
||||
m_attributes.clear();
|
||||
m_renderer.reset();
|
||||
}
|
||||
|
||||
void parse_svg(const char* fname)
|
||||
{
|
||||
if(!fname)
|
||||
return;
|
||||
|
||||
m_attributes.initial_zoom();
|
||||
m_storage.clear();
|
||||
reset();
|
||||
|
||||
agg::svg::parser p(m_storage, m_attr_map);
|
||||
p.parse(fname);
|
||||
indexation();
|
||||
}
|
||||
|
||||
void on_resize(int sx, int sy)
|
||||
{
|
||||
m_frame_buffer.create(sx, sy, flip_y_e);
|
||||
}
|
||||
|
||||
void draw(agg::rendering_buffer& rbuf, double expand, double gamma)
|
||||
{
|
||||
agg::svg::renderer_rgba::pixfmt_type pixfmt(rbuf);
|
||||
agg::svg::renderer_rgba::renderer_base_type rbase(pixfmt);
|
||||
|
||||
m_rasterizer.gamma(gamma);
|
||||
m_settings.gamma(gamma);
|
||||
|
||||
m_attributes.window(0, 0, rbuf.width(), rbuf.height());
|
||||
|
||||
m_frame_buffer.clear(agg::svg::color_type(255, 255, 255));
|
||||
|
||||
m_renderer.attach(m_frame_buffer);
|
||||
|
||||
agg::svg::rendering_interpreter rin( m_pipeline,
|
||||
m_attributes,
|
||||
m_renderer,
|
||||
m_id2elem_map,
|
||||
m_gradient_lut_cache
|
||||
);
|
||||
#ifdef EXPAND_PATHS
|
||||
rin.expand(expand);
|
||||
#endif
|
||||
|
||||
m_storage.traverse(rin);
|
||||
|
||||
assert(0 == m_attributes.num_sessions());
|
||||
|
||||
if (m_settings.gamma() != 1.0)
|
||||
{
|
||||
m_frame_buffer.pixfmt().apply_gamma_inv(m_settings.gamma_lut());
|
||||
}
|
||||
|
||||
if(m_frame_buffer.is_valid())
|
||||
{
|
||||
rbase.copy_from(m_frame_buffer.ren_buf());
|
||||
|
||||
if (m_current_tool == tool_zoom)
|
||||
{
|
||||
agg::rgba8 color(0, 0, 0, 255);
|
||||
|
||||
rbase.blend_hline(m_x1, m_y1, m_x2, color, agg::cover_full);
|
||||
rbase.blend_hline(m_x1, m_y2, m_x2, color, agg::cover_full);
|
||||
rbase.blend_vline(m_x1, m_y1, m_y2, color, agg::cover_full);
|
||||
rbase.blend_vline(m_x2, m_y1, m_y2, color, agg::cover_full);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rbase.clear(agg::svg::color_type(255, 255, 255));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void on_draw()
|
||||
{
|
||||
try
|
||||
{
|
||||
typedef agg::pixfmt_bgra32 pixfmt;
|
||||
typedef agg::renderer_base<pixfmt> renderer_base;
|
||||
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
|
||||
|
||||
pixfmt pixf(rbuf_window());
|
||||
renderer_base rb(pixf);
|
||||
renderer_solid ren(rb);
|
||||
|
||||
rb.clear(agg::rgba(1,1,1));
|
||||
|
||||
agg::rasterizer_scanline_aa<> ras;
|
||||
agg::scanline_p8 sl;
|
||||
|
||||
//ras.gamma(agg::gamma_power(m_gamma.value()));
|
||||
|
||||
start_timer();
|
||||
draw(rbuf_window(), 0.0/*m_expand.value()*/, m_gamma.value());
|
||||
double tm = elapsed_time();
|
||||
|
||||
ras.gamma(agg::gamma_none());
|
||||
//agg::render_ctrl(ras, sl, rb, m_expand);
|
||||
agg::render_ctrl(ras, sl, rb, m_gamma);
|
||||
//agg::render_ctrl(ras, sl, rb, m_scale);
|
||||
//agg::render_ctrl(ras, sl, rb, m_rotate);
|
||||
|
||||
char buf[128];
|
||||
agg::gsv_text t;
|
||||
t.size(10.0);
|
||||
t.flip(true);
|
||||
|
||||
agg::conv_stroke<agg::gsv_text> pt(t);
|
||||
pt.width(1.5);
|
||||
|
||||
//sprintf(buf, "Vertices=%d Time=%.3f ms", vertex_count, tm);
|
||||
sprintf(buf, "Time=%.3f ms", tm);
|
||||
|
||||
t.start_point(4.0, 40.0);
|
||||
t.text(buf);
|
||||
|
||||
ras.add_path(pt);
|
||||
ren.color(agg::rgba(0,0,0));
|
||||
agg::render_scanlines(ras, sl, ren);
|
||||
}
|
||||
catch (agg::svg::exception&)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
virtual void on_mouse_button_down(int x, int y, unsigned flags)
|
||||
{
|
||||
if (flags & agg::mouse_left)
|
||||
m_current_tool = tool_zoom;
|
||||
|
||||
if (flags & agg::mouse_right)
|
||||
m_current_tool = tool_pan;
|
||||
|
||||
m_x1 = x;
|
||||
m_y1 = y;
|
||||
m_x2 = x;
|
||||
m_y2 = y;
|
||||
m_drag_flag = true;
|
||||
}
|
||||
|
||||
virtual void on_mouse_move(int x, int y, unsigned flags)
|
||||
{
|
||||
if(flags == 0)
|
||||
{
|
||||
m_drag_flag = false;
|
||||
}
|
||||
|
||||
if (m_drag_flag)
|
||||
{
|
||||
m_x2 = x;
|
||||
m_y2 = y;
|
||||
|
||||
if (m_current_tool == tool_zoom)
|
||||
{
|
||||
force_redraw();
|
||||
}
|
||||
else if (m_current_tool == tool_pan)
|
||||
{
|
||||
update_zoom();
|
||||
m_x1 = x;
|
||||
m_y1 = y;
|
||||
force_redraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void zoom_out(int x, int y)
|
||||
{
|
||||
int d = 100;
|
||||
|
||||
int x1 = -d;
|
||||
int y1 = -d;
|
||||
int x2 = rbuf_window().width() + d;
|
||||
int y2 = rbuf_window().height() + d;
|
||||
|
||||
int w = x2 - x1;
|
||||
int h = y2 - y1;
|
||||
|
||||
int cx = x1 + w/2;
|
||||
int cy = y1 + h/2;
|
||||
|
||||
int dx = x - cx;
|
||||
int dy = y - cy;
|
||||
|
||||
m_attributes.set_zoom(x1 + dx, y1 + dy, x2 + dx, y2 + dy);
|
||||
force_redraw();
|
||||
}
|
||||
|
||||
virtual void on_mouse_button_up(int x, int y, unsigned flags)
|
||||
{
|
||||
if ((flags & agg::kbd_shift) && m_x1 == x && m_y1 == y)
|
||||
{
|
||||
zoom_out(x,y);
|
||||
m_drag_flag = false;
|
||||
m_current_tool = tool_none;
|
||||
}
|
||||
|
||||
if (m_drag_flag)
|
||||
{
|
||||
if (m_current_tool == tool_zoom)
|
||||
{
|
||||
if(x != m_x1 && y != m_y1)
|
||||
{
|
||||
m_x2 = x;
|
||||
m_y2 = y;
|
||||
update_zoom();
|
||||
}
|
||||
force_redraw();
|
||||
}
|
||||
m_drag_flag = false;
|
||||
}
|
||||
m_current_tool = tool_none;
|
||||
}
|
||||
|
||||
virtual void on_key(int x, int y, unsigned key, unsigned flags)
|
||||
{
|
||||
if(key == agg::key_home)
|
||||
{
|
||||
m_attributes.initial_zoom();
|
||||
force_redraw();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int agg_main(int argc, char* argv[])
|
||||
{
|
||||
the_application app(agg::svg::pix_format, flip_y_e);
|
||||
|
||||
const char* fname = "tiger.svg";
|
||||
if(argc <= 1)
|
||||
{
|
||||
FILE* fd = fopen(app.full_file_name(fname), "r");
|
||||
if(fd == 0)
|
||||
{
|
||||
app.message("Usage: svg_test <svg_file>\n"
|
||||
"Download http://antigrain.com/svg/tiger.svg");
|
||||
return 1;
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
fname = argv[1];
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
app.parse_svg(app.full_file_name(fname));
|
||||
}
|
||||
catch (agg::svg::exception& e)
|
||||
{
|
||||
app.message(e.msg());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(app.init(512, 600, agg::window_resize))
|
||||
{
|
||||
return app.run();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user