Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Index: CMakeLists.txt
- ===================================================================
- --- CMakeLists.txt (revision 50)
- +++ CMakeLists.txt (working copy)
- @@ -302,6 +302,8 @@
- ./svg_viewer/agg_svg_path_renderer.h
- ./svg_viewer/agg_svg_path_tokenizer.cpp
- ./svg_viewer/agg_svg_path_tokenizer.h
- + ./svg_viewer/agg_svg_gradient.cpp
- + ./svg_viewer/agg_svg_gradient.h
- )
- ENDIF ( agg_USE_EXPAT )
- Index: svg_viewer/agg_svg_gradient.cpp
- ===================================================================
- --- svg_viewer/agg_svg_gradient.cpp (revision 0)
- +++ svg_viewer/agg_svg_gradient.cpp (working copy)
- @@ -0,0 +1,197 @@
- +//----------------------------------------------------------------------------
- +// 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
- +//----------------------------------------------------------------------------
- +//
- +// Gunnar Roth: add support for linear and radial gradients(support xlink attr),
- +// shape gradient opaqueness, rounded rects, circles,ellipses. support a command (arc) in pathes.
- +// set new origin correctly to last postion on z command in a path( was set to 0,0 before).
- +// enable parsing of colors written as rgb()
- +// some code was inspired by code from Haiku OS
- +/*
- +* Copyright 2006-2007, Haiku. All rights reserved.
- +* Distributed under the terms of the MIT License.
- +*
- +* Authors:
- +* Stephan Aßmus <superstippi@gmx.de>
- +*/
- +//
- +
- +#include <stdio.h>
- +#include <stdlib.h>
- +
- +
- +
- +#include "agg_svg_gradient.h"
- +#include <vector>
- +#include "agg_trans_affine.h"
- +#include "agg_gradient_lut.h"
- +
- +
- +
- +
- +
- +
- +namespace agg {
- + namespace svg {
- +
- +
- +
- + // constructor
- + gradient::gradient()
- + :
- + m_type(GRADIENT_LINEAR),
- + m_id(""),
- + m_colcnt(0),
- + m_opaque(1.0)
- + {
- + }
- +
- + // destructor
- + gradient::~gradient()
- + {
- +
- + }
- +
- + // SetID
- + void
- + gradient::set_id(const char* id)
- + {
- + m_id = id;
- + }
- +
- + // ID
- + const char*
- + gradient::id() const
- + {
- + return m_id.c_str();
- + }
- +
- + // AddStop
- + void
- + gradient::add_stop(double offset, rgba8 color)
- + {
- + m_colcnt++;
- + m_gradient_lut.add_color(offset,color);
- + }
- +
- + // SetTransformation
- + void
- + gradient::set_transformation(const trans_affine& transform)
- + {
- + m_transform.multiply(transform);
- + }
- + // constructor
- + linear_gradient::linear_gradient()
- + : gradient()
- + {
- + }
- +
- + // destructor
- + linear_gradient::~linear_gradient()
- + {
- + }
- +
- + // MakeGradient
- +
- + void linear_gradient::realize()
- + {
- +
- + set_type(GRADIENT_LINEAR);
- + // setup the gradient transform
- + point_d start(-lut_range, -lut_range);
- + point_d end(lut_range, -lut_range);
- + std::string coordinate;
- + if (find_string("x1", &coordinate) )
- + start.x = atof(coordinate.c_str());
- + if (find_string("y1", &coordinate) )
- + start.y = atof(coordinate.c_str());
- + if (find_string("x2", &coordinate) )
- + end.x = atof(coordinate.c_str());
- + if (find_string("y2", &coordinate) )
- + end.y = atof(coordinate.c_str());
- +
- +
- + // the transformed parallelogram
- + double parl[6];
- + parl[0] = start.x;
- + parl[1] = start.y;
- + parl[2] = end.x;
- + parl[3] = end.y;
- + parl[4] = end.x - (end.y - start.y);
- + parl[5] = end.y + (end.x - start.x);
- + trans_affine transform(-lut_range, -lut_range, lut_range, lut_range, parl);
- + m_transform.premultiply(transform);
- + m_gradient_lut.build_lut(1.0);
- + }
- +
- + // constructor
- + radial_gradient::radial_gradient()
- + : gradient()
- + {
- + }
- +
- + // destructor
- + radial_gradient::~radial_gradient()
- + {
- + }
- +
- + // MakeGradient
- +
- + void radial_gradient::realize()
- + {
- + //printf("SVGRadialGradient::MakeGradient()\n");
- + // TODO: handle userSpaceOnUse/objectBoundingBox
- +
- + set_type(GRADIENT_CIRCULAR);
- +
- + double cx = 0.0;
- + double cy = 0.0;
- + double r = 100.0;
- + double fx = 0.0;
- + double fy = 0.0;
- +
- + std::string value;
- + if (find_string("cx", &value) )
- + cx = atof(value.c_str());
- + if (find_string("cy", &value) )
- + cy = atof(value.c_str());
- + if (find_string("r", &value) )
- + r = atof(value.c_str());
- +/*
- + if (FindString("fx", &value) )
- + {
- + fx = atof(value.c_str());
- + if (FindString("fy", &value) )
- + fy = atof(value.c_str());
- + SetType(GRADIENT_CIRCULAR_FOCAL);
- + }
- +*/
- +
- +
- + // the transformed parallelogram
- + double parl[6];
- + parl[0] = cx - r;
- + parl[1] = cy - r;
- + parl[2] = cx + r;
- + parl[3] = cy - r;
- + parl[4] = cx + r;
- + parl[5] = cy + r;
- +
- + trans_affine transform(-lut_range, -lut_range, lut_range, lut_range, parl);
- + m_transform.premultiply(transform);
- + m_gradient_lut.build_lut(1.0);
- + }
- +
- + } // namespace svg
- +} // namespace agg
- \ No newline at end of file
- Index: svg_viewer/agg_svg_gradient.h
- ===================================================================
- --- svg_viewer/agg_svg_gradient.h (revision 0)
- +++ svg_viewer/agg_svg_gradient.h (working copy)
- @@ -0,0 +1,274 @@
- +//----------------------------------------------------------------------------
- +// 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
- +//----------------------------------------------------------------------------
- +//
- +// Gunnar Roth: add support for linear and radial gradients(support xlink attr),
- +// shape gradient opaqueness, rounded rects, circles,ellipses. support a command (arc) in pathes.
- +// set new origin correctly to last postion on z command in a path( was set to 0,0 before).
- +// enable parsing of colors written as rgb()
- +// some code was inspired by code from Haiku OS
- +/*
- +* Copyright 2006-2007, Haiku. All rights reserved.
- +* Distributed under the terms of the MIT License.
- +*
- +* Authors:
- +* Stephan Aßmus <superstippi@gmx.de>
- +*/
- +//
- +
- +#ifndef SVG_GRADIENTS_H
- +#define SVG_GRADIENTS_H
- +
- +
- +#include <agg_color_rgba.h>
- +#include <agg_trans_affine.h>
- +
- +
- +#include <String.h>
- +#include <string>
- +#include <map>
- +#include "agg_gradient_lut.h"
- +
- +
- +namespace agg {
- + namespace svg {
- +
- + template<class ColorInterpolator,
- + unsigned ColorLutSize=256> class gradient_lut_opaque
- + {
- + public:
- + typedef ColorInterpolator interpolator_type;
- + typedef typename interpolator_type::color_type color_type;
- + enum { color_lut_size = ColorLutSize };
- +
- + //--------------------------------------------------------------------
- + gradient_lut_opaque() : m_color_lut(color_lut_size) {}
- +
- + // Build Gradient Lut
- + // First, call remove_all(), then add_color() at least twice,
- + // then build_lut(). Argument "offset" in add_color must be
- + // in range [0...1] and defines a color stop as it is described
- + // in SVG specification, section Gradients and Patterns.
- + // The simplest linear gradient is:
- + // gradient_lut.add_color(0.0, start_color);
- + // gradient_lut.add_color(1.0, end_color);
- + //--------------------------------------------------------------------
- + void remove_all();
- + void add_color(double offset, const color_type& color);
- + void build_lut(double opaque );
- +
- + // Size-index Interface. This class can be used directly as the
- + // ColorF in span_gradient. All it needs is two access methods
- + // size() and operator [].
- + //--------------------------------------------------------------------
- + static unsigned size()
- + {
- + return color_lut_size;
- + }
- + const color_type& operator [] (unsigned i) const
- + {
- + return m_color_lut[i];
- + }
- +
- + private:
- + //--------------------------------------------------------------------
- + struct color_point
- + {
- + double offset;
- + color_type color;
- +
- + color_point() {}
- + color_point(double off, const color_type& c) :
- + offset(off), color(c)
- + {
- + if(offset < 0.0) offset = 0.0;
- + if(offset > 1.0) offset = 1.0;
- + }
- + };
- + typedef agg::pod_bvector<color_point, 4> color_profile_type;
- + typedef agg::pod_array<color_type> color_lut_type;
- +
- + static bool offset_less(const color_point& a, const color_point& b)
- + {
- + return a.offset < b.offset;
- + }
- + static bool offset_equal(const color_point& a, const color_point& b)
- + {
- + return a.offset == b.offset;
- + }
- +
- + //--------------------------------------------------------------------
- + color_profile_type m_color_profile;
- + color_lut_type m_color_lut;
- + };
- +
- +
- +
- + //------------------------------------------------------------------------
- + template<class T, unsigned S>
- + void gradient_lut_opaque<T,S>::remove_all()
- + {
- + m_color_profile.remove_all();
- + }
- +
- + //------------------------------------------------------------------------
- + template<class T, unsigned S>
- + void gradient_lut_opaque<T,S>::add_color(double offset, const color_type& color)
- + {
- + m_color_profile.add(color_point(offset, color));
- + }
- +
- + //------------------------------------------------------------------------
- + template<class T, unsigned S>
- + void gradient_lut_opaque<T,S>::build_lut(double opaque)
- + {
- + quick_sort(m_color_profile, offset_less);
- + m_color_profile.cut_at(remove_duplicates(m_color_profile, offset_equal));
- + if(m_color_profile.size() >= 2)
- + {
- + unsigned i;
- + unsigned start = uround(m_color_profile[0].offset * color_lut_size);
- + unsigned end;
- + color_type c = m_color_profile[0].color;
- + c.opacity(c.opacity() * opaque);
- + for(i = 0; i < start; i++)
- + {
- + m_color_lut[i] = c;
- + }
- + for(i = 1; i < m_color_profile.size(); i++)
- + {
- + end = uround(m_color_profile[i].offset * color_lut_size);
- + color_type c1 = m_color_profile[i-1].color;
- + c1.opacity(c1.opacity() * opaque);
- + color_type c2 = m_color_profile[i].color;
- + c2.opacity(c2.opacity() * opaque);
- + interpolator_type ci(c1,
- + c2 ,
- + end - start + 1);
- + while(start < end)
- + {
- + m_color_lut[start] = ci.color();
- + ++ci;
- + ++start;
- + }
- + }
- + c = m_color_profile.last().color;
- + c.opacity(c.opacity() * opaque);
- + for(; end < m_color_lut.size(); end++)
- + {
- + m_color_lut[end] = c;
- + }
- + }
- + }
- + class gradient {
- + public:
- + static const int lut_range = 128;
- + typedef gradient_lut_opaque<agg::color_interpolator<agg::rgba8>, lut_range * 2> color_func_type;
- + enum gradients_type {
- + GRADIENT_LINEAR = 0,
- + GRADIENT_CIRCULAR,
- + GRADIENT_CIRCULAR_FOCAL,
- + GRADIENT_DIAMOND,
- + GRADIENT_CONIC,
- + GRADIENT_XY,
- + GRADIENT_SQRT_XY
- + };
- + gradient();
- + virtual ~gradient();
- +
- + void set_id(const char* id);
- + const char* id() const;
- + void set_opaque(double opaque)
- + {
- + if(opaque != m_opaque)
- + {
- + m_opaque = opaque;
- + m_gradient_lut.build_lut(m_opaque);
- + }
- + }
- + virtual void add_stop(double offset, rgba8 color);
- + void set_transformation(const trans_affine& transform);
- + virtual void realize() = 0;
- +
- +
- + void add_string(const char *name, const char *string)
- + {
- + m_mapStrings[name] = string;
- + }
- +
- + color_func_type &lut()
- + {
- + return m_gradient_lut;
- + }
- +
- + void set_type(gradients_type type)
- + {
- + m_type = type;
- + }
- + gradients_type type() const
- + { return m_type; }
- +
- + const trans_affine & transform()
- + {
- + return m_transform;
- + }
- + unsigned count_colors()
- + {
- + return m_colcnt;
- + }
- + std::string xlink()
- + {
- + std::string xlink;
- + find_string("xlink:href",&xlink);
- + return xlink;
- + }
- +
- + protected:
- + bool find_string(const char * key,std::string * pVal ) const
- + {
- + std::map<std::string,std::string>::const_iterator it = m_mapStrings.find(key);
- + if(it == m_mapStrings.end())
- + return false;
- + *pVal=it->second;
- + return true;
- + }
- + trans_affine m_transform;
- + color_func_type m_gradient_lut;
- + unsigned m_colcnt;
- + private:
- + std::map<std::string,std::string> m_mapStrings;
- + gradients_type m_type;
- + double m_opaque;
- + std::string m_id;
- + };
- +
- + class linear_gradient : public gradient {
- + public:
- + linear_gradient();
- + virtual ~linear_gradient();
- +
- + virtual void realize();
- + };
- +
- + class radial_gradient : public gradient {
- + public:
- + radial_gradient();
- + virtual ~radial_gradient();
- + virtual void realize();
- + };
- +
- + } // namespace svg
- +} // namespace agg
- +
- +#endif // SVG_GRADIENTS_H
- \ No newline at end of file
- Index: svg_viewer/agg_svg_parser.cpp
- ===================================================================
- --- svg_viewer/agg_svg_parser.cpp (revision 50)
- +++ svg_viewer/agg_svg_parser.cpp (working copy)
- @@ -13,6 +13,19 @@
- // http://www.antigrain.com
- //----------------------------------------------------------------------------
- //
- +// Gunnar Roth: add support for linear and radial gradients(support xlink attr),
- +// shape gradient opaqueness, rounded rects, circles,ellipses. support a command (arc) in pathes.
- +// set new origin correctly to last postion on z command in a path( was set to 0,0 before).
- +// enable parsing of colors written as rgb()
- +// some code was inspired by code from Haiku OS
- +/*
- +* Copyright 2006-2007, Haiku. All rights reserved.
- +* Distributed under the terms of the MIT License.
- +*
- +* Authors:
- +* Stephan Aßmus <superstippi@gmx.de>
- +*/
- +//
- // SVG parser.
- //
- //----------------------------------------------------------------------------
- @@ -22,7 +35,7 @@
- #include <ctype.h>
- #include "agg_svg_parser.h"
- #include "expat.h"
- -
- +#include "agg_svg_gradient.h"
- namespace agg
- {
- namespace svg
- @@ -185,7 +198,99 @@
- { "zzzzzzzzzzz",0,0,0, 0 }
- };
- + //-------------------------------------------------------------
- + int cmp_color(const void* p1, const void* p2)
- + {
- + return strcmp(((named_color*)p1)->name, ((named_color*)p2)->name);
- + }
- + //-------------------------------------------------------------
- + rgba8 parse_color(const char* str)
- + {
- + while(*str == ' ') ++str;
- + if (*str == '#') {
- + str++;
- + int32 length = strlen(str);
- + unsigned c = 0;
- + if (length == 3) {
- + // if there are only 3 byte, than it means that we
- + // need to expand the color (#f60 -> #ff6600)
- + // TODO: There must be an easier way...
- + char expanded[7];
- + expanded[0] = *str;
- + expanded[1] = *str++;
- + expanded[2] = *str;
- + expanded[3] = *str++;
- + expanded[4] = *str;
- + expanded[5] = *str++;
- + expanded[6] = 0;
- + sscanf(expanded, "%x", &c);
- + } else {
- + sscanf(str, "%x", &c);
- + }
- + return rgb8_packed(c);
- + }
- + else if(*str == 'r')
- + {
- + int r,g,b;
- + sscanf(str,"rgb(%d,%d,%d)",&r,&g,&b);
- + return rgba8(r,g,b);
- + }
- + else
- + {
- + named_color c;
- + unsigned len = strlen(str);
- + if(len > sizeof(c.name) - 1)
- + {
- + throw exception("parse_color: Invalid color name '%s'", str);
- + }
- + strcpy(c.name, str);
- + const void* p = bsearch(&c,
- + colors,
- + sizeof(colors) / sizeof(colors[0]),
- + sizeof(colors[0]),
- + cmp_color);
- + if(p == 0)
- + {
- + throw exception("parse_color: Invalid color name '%s'", str);
- + }
- + const named_color* pc = (const named_color*)p;
- + return rgba8(pc->r, pc->g, pc->b, pc->a);
- + }
- + }
- + double parse_double(const char* str)
- + {
- + while(*str == ' ') ++str;
- + double value = atof(str);
- + // handle percent
- + int32 length = strlen(str);
- + if (str[length - 1] == '%')
- + value /= 100.0;
- + return value;
- + }
- +// parse_url
- + char*
- + parse_url(const char* str)
- + {
- + const char* begin = str;
- + while (*begin != '#')
- + begin++;
- +
- + begin++;
- + const char* end = begin;
- + while (*end != ')')
- + end++;
- +
- + end--;
- +
- + int32 length = end - begin + 2;
- + char* result = new char[length];
- + memcpy(result, begin, length - 1);
- + result[length - 1] = 0;
- +
- + return result;
- +}
- +
- //------------------------------------------------------------------------
- parser::~parser()
- {
- @@ -207,7 +312,8 @@
- m_attr_name(new char[128]),
- m_attr_value(new char[1024]),
- m_attr_name_len(127),
- - m_attr_value_len(1023)
- + m_attr_value_len(1023),
- + m_tags_ignored(false)
- {
- m_title[0] = 0;
- }
- @@ -264,7 +370,11 @@
- void parser::start_element(void* data, const char* el, const char** attr)
- {
- parser& self = *(parser*)data;
- -
- + if (strcmp(el, "svg") == 0)
- + {
- + self.parse_svg(attr);
- + }
- + else
- if(strcmp(el, "title") == 0)
- {
- self.m_title_flag = true;
- @@ -288,6 +398,16 @@
- self.m_path_flag = true;
- }
- else
- + if (strcmp(el, "circle") == 0)
- + {
- + self.parse_circle(attr);
- + }
- + else
- + if (strcmp(el, "ellipse") == 0)
- + {
- + self.parse_ellipse(attr);
- + }
- + else
- if(strcmp(el, "rect") == 0)
- {
- self.parse_rect(attr);
- @@ -307,11 +427,26 @@
- {
- self.parse_poly(attr, true);
- }
- + else
- + if (strcmp(el, "linearGradient") == 0 || strcmp(el, "radialGradient") == 0)
- + {
- + self.parse_gradient(attr, strcmp(el, "radialGradient") == 0);
- + }
- + else
- + if (strcmp(el, "stop") == 0)
- + {
- + self.parse_gradient_stop(attr);
- + }
- //else
- //if(strcmp(el, "<OTHER_ELEMENTS>") == 0)
- //{
- //}
- // . . .
- + else
- + {
- + fprintf(stderr, "SVGParser igoring tag: \"%s\"\n", el);
- + self.m_tags_ignored = true;
- + }
- }
- @@ -334,6 +469,12 @@
- {
- self.m_path_flag = false;
- }
- + else
- + if (strcmp(el, "linearGradient") == 0 || strcmp(el, "radialGradient") == 0)
- + {
- + self.m_path.end_gradient();
- + }
- +
- //else
- //if(strcmp(el, "<OTHER_ELEMENTS>") == 0)
- //{
- @@ -361,6 +502,55 @@
- }
- }
- +// parse_svg
- + void parser::parse_svg(const char** attr)
- + {
- + double width = 0.0;
- + double height = 0.0;
- + rect_d viewBox(0.0, 0.0, -1.0, -1.0);
- +
- + for (int i = 0; attr[i]; i += 2) {
- + if (strcmp(attr[i], "width") == 0)
- + {
- + width = parse_double(attr[i + 1]);
- + }
- + else
- + if (strcmp(attr[i], "height") == 0)
- + {
- + height = parse_double(attr[i + 1]);
- + }
- + else
- + if (strcmp(attr[i], "viewBox") == 0)
- + {
- + m_tokenizer.set_path_str(attr[i + 1]);
- + if(!m_tokenizer.next())
- + {
- + throw exception("parse_svg (viewBox): Too few coordinates");
- + }
- + viewBox.x1 = m_tokenizer.last_number();
- + if(!m_tokenizer.next())
- + {
- + throw exception("parse_svg (viewBox): Too few coordinates");
- + }
- + viewBox.y1 = m_tokenizer.last_number();
- + if(!m_tokenizer.next())
- + {
- + throw exception("parse_svg (viewBox): Too few coordinates");
- + }
- + viewBox.x2 = m_tokenizer.last_number();
- + if(!m_tokenizer.next())
- + {
- + throw exception("parse_svg (viewBox): Too few coordinates");
- + }
- + viewBox.y2 = m_tokenizer.last_number();
- + }
- + }
- + if (width >= 0.0 && height >= 0.0) {
- + //set viewBox
- + } else {
- + throw exception("parse_svg: Invalid width or height\n");
- + }
- + }
- //------------------------------------------------------------------------
- void parser::parse_attr(const char** attr)
- @@ -410,53 +600,10 @@
- }
- - //-------------------------------------------------------------
- - int cmp_color(const void* p1, const void* p2)
- - {
- - return strcmp(((named_color*)p1)->name, ((named_color*)p2)->name);
- - }
- - //-------------------------------------------------------------
- - rgba8 parse_color(const char* str)
- - {
- - while(*str == ' ') ++str;
- - unsigned c = 0;
- - if(*str == '#')
- - {
- - sscanf(str + 1, "%x", &c);
- - return rgb8_packed(c);
- - }
- - else
- - {
- - named_color c;
- - unsigned len = strlen(str);
- - if(len > sizeof(c.name) - 1)
- - {
- - throw exception("parse_color: Invalid color name '%s'", str);
- - }
- - strcpy(c.name, str);
- - const void* p = bsearch(&c,
- - colors,
- - sizeof(colors) / sizeof(colors[0]),
- - sizeof(colors[0]),
- - cmp_color);
- - if(p == 0)
- - {
- - throw exception("parse_color: Invalid color name '%s'", str);
- - }
- - const named_color* pc = (const named_color*)p;
- - return rgba8(pc->r, pc->g, pc->b, pc->a);
- - }
- - }
- - double parse_double(const char* str)
- - {
- - while(*str == ' ') ++str;
- - return atof(str);
- - }
- -
- //-------------------------------------------------------------
- bool parser::parse_attr(const char* name, const char* value)
- {
- @@ -465,12 +612,21 @@
- parse_style(value);
- }
- else
- + if(strcmp(name, "opacity") == 0) {
- + m_path.opacity(parse_double(value));
- + } else
- if(strcmp(name, "fill") == 0)
- {
- if(strcmp(value, "none") == 0)
- {
- m_path.fill_none();
- }
- + else if (strncmp(value, "url", 3) == 0)
- + {
- + char* url = parse_url(value);
- + m_path.fill_url(url);
- + delete[] url;
- + }
- else
- {
- m_path.fill(parse_color(value));
- @@ -482,12 +638,22 @@
- m_path.fill_opacity(parse_double(value));
- }
- else
- + if(strcmp(name, "fill-rule") == 0)
- + {
- + m_path.even_odd(strcmp(value, "evenodd") == 0);
- + }
- + else
- if(strcmp(name, "stroke") == 0)
- {
- if(strcmp(value, "none") == 0)
- {
- m_path.stroke_none();
- }
- + else if (strncmp(value, "url", 3) == 0) {
- + char* url = parse_url(value);
- + m_path.stroke_url(url);
- + delete[] url;
- + }
- else
- {
- m_path.stroke(parse_color(value));
- @@ -525,8 +691,17 @@
- else
- if(strcmp(name, "transform") == 0)
- {
- - parse_transform(value);
- + m_path.transform().premultiply(parse_transform(value));
- }
- + else
- + if (strcmp(name, "stop-color") == 0)
- + {
- + m_gradient_stop_color = parse_color(value);
- + }
- + else
- + if (strcmp(name, "stop-opacity") == 0) {
- + m_gradient_stop_color.opacity(parse_double(value));
- + }
- //else
- //if(strcmp(el, "<OTHER_ATTRIBUTES>") == 0)
- //{
- @@ -617,7 +792,89 @@
- }
- + // parse_circle
- + void
- + parser::parse_circle(const char** attr)
- + {
- + int i;
- + double cx = 0.0;
- + double cy = 0.0;
- + double r = 0.0;
- + m_path.begin_path();
- + for(i = 0; attr[i]; i += 2) {
- + if (!parse_attr(attr[i], attr[i + 1])) {
- + if(strcmp(attr[i], "cx") == 0) cx = parse_double(attr[i + 1]);
- + if(strcmp(attr[i], "cy") == 0) cy = parse_double(attr[i + 1]);
- + if(strcmp(attr[i], "r") == 0) r = parse_double(attr[i + 1]);
- + }
- + }
- +
- +
- + if (r != 0.0) {
- + if (r < 0.0) throw exception("parse_circle: Invalid radius: %f", r);
- +
- + m_path.move_to(cx, cy - r);
- + m_path.curve4(cx + r * 0.56, cy - r,
- + cx + r, cy - r * 0.56,
- + cx + r, cy);
- + m_path.curve4(cx + r, cy + r * 0.56,
- + cx + r * 0.56, cy + r,
- + cx, cy + r);
- + m_path.curve4(cx - r * 0.56, cy + r,
- + cx - r, cy + r * 0.56,
- + cx - r, cy);
- + m_path.curve4(cx - r, cy - r * 0.56,
- + cx - r * 0.56, cy - r,
- + cx, cy - r);
- + m_path.close_subpath();
- + }
- + m_path.end_path();
- + }
- +
- + // parse_ellipse
- + void
- + parser::parse_ellipse(const char** attr)
- + {
- + int i;
- + double cx = 0.0;
- + double cy = 0.0;
- + double rx = 0.0;
- + double ry = 0.0;
- +
- + m_path.begin_path();
- + for(i = 0; attr[i]; i += 2) {
- + if (!parse_attr(attr[i], attr[i + 1])) {
- + if(strcmp(attr[i], "cx") == 0) cx = parse_double(attr[i + 1]);
- + if(strcmp(attr[i], "cy") == 0) cy = parse_double(attr[i + 1]);
- + if(strcmp(attr[i], "rx") == 0) rx = parse_double(attr[i + 1]);
- + if(strcmp(attr[i], "ry") == 0) ry = parse_double(attr[i + 1]);
- + }
- + }
- +
- +
- + if (rx != 0.0 && ry != 0.0) {
- + if (rx < 0.0) throw exception("parse_ellipse: Invalid x-radius: %f", rx);
- + if (ry < 0.0) throw exception("parse_ellipse: Invalid y-radius: %f", ry);
- +
- + m_path.move_to(cx, cy - ry);
- + m_path.curve4(cx + rx * 0.56, cy - ry,
- + cx + rx, cy - ry * 0.56,
- + cx + rx, cy);
- + m_path.curve4(cx + rx, cy + ry * 0.56,
- + cx + rx * 0.56, cy + ry,
- + cx, cy + ry);
- + m_path.curve4(cx - rx * 0.56, cy + ry,
- + cx - rx, cy + ry * 0.56,
- + cx - rx, cy);
- + m_path.curve4(cx - rx, cy - ry * 0.56,
- + cx - rx * 0.56, cy - ry,
- + cx, cy - ry);
- + m_path.close_subpath();
- + }
- + m_path.end_path();
- + }
- +
- //-------------------------------------------------------------
- void parser::parse_rect(const char** attr)
- {
- @@ -626,7 +883,8 @@
- double y = 0.0;
- double w = 0.0;
- double h = 0.0;
- -
- + double rx = 0.0;
- + double ry = 0.0;
- m_path.begin_path();
- for(i = 0; attr[i]; i += 2)
- {
- @@ -636,9 +894,9 @@
- if(strcmp(attr[i], "y") == 0) y = parse_double(attr[i + 1]);
- if(strcmp(attr[i], "width") == 0) w = parse_double(attr[i + 1]);
- if(strcmp(attr[i], "height") == 0) h = parse_double(attr[i + 1]);
- - // rx - to be implemented
- - // ry - to be implemented
- - }
- + if(strcmp(attr[i], "rx") == 0) rx = parse_double(attr[i + 1]);
- + if(strcmp(attr[i], "ry") == 0) ry = parse_double(attr[i + 1]);
- + }
- }
- @@ -646,12 +904,18 @@
- {
- if(w < 0.0) throw exception("parse_rect: Invalid width: %f", w);
- if(h < 0.0) throw exception("parse_rect: Invalid height: %f", h);
- -
- - m_path.move_to(x, y);
- - m_path.line_to(x + w, y);
- - m_path.line_to(x + w, y + h);
- - m_path.line_to(x, y + h);
- - m_path.close_subpath();
- + if(rx >0 || ry > 0)
- + {
- + m_path.roundrect(x,y,x+w,y+h,rx,ry);
- + }
- + else
- + {
- + m_path.move_to(x, y);
- + m_path.line_to(x + w, y);
- + m_path.line_to(x + w, y + h);
- + m_path.line_to(x, y + h);
- + m_path.close_subpath();
- + }
- }
- m_path.end_path();
- }
- @@ -731,18 +995,19 @@
- }
- //-------------------------------------------------------------
- - void parser::parse_transform(const char* str)
- + trans_affine parser::parse_transform(const char* str)
- {
- + trans_affine transform;
- while(*str)
- {
- if(islower(*str))
- {
- - if(strncmp(str, "matrix", 6) == 0) str += parse_matrix(str); else
- - if(strncmp(str, "translate", 9) == 0) str += parse_translate(str); else
- - if(strncmp(str, "rotate", 6) == 0) str += parse_rotate(str); else
- - if(strncmp(str, "scale", 5) == 0) str += parse_scale(str); else
- - if(strncmp(str, "skewX", 5) == 0) str += parse_skew_x(str); else
- - if(strncmp(str, "skewY", 5) == 0) str += parse_skew_y(str); else
- + if(strncmp(str, "matrix", 6) == 0) str += parse_matrix(str,transform); else
- + if(strncmp(str, "translate", 9) == 0) str += parse_translate(str,transform); else
- + if(strncmp(str, "rotate", 6) == 0) str += parse_rotate(str,transform); else
- + if(strncmp(str, "scale", 5) == 0) str += parse_scale(str,transform); else
- + if(strncmp(str, "skewX", 5) == 0) str += parse_skew_x(str,transform); else
- + if(strncmp(str, "skewY", 5) == 0) str += parse_skew_y(str,transform); else
- {
- ++str;
- }
- @@ -752,9 +1017,70 @@
- ++str;
- }
- }
- + return transform;
- }
- + // parse_gradient
- + void
- + parser::parse_gradient(const char** attr, bool radial)
- + {
- + // printf("parser::parse_gradient(%s)\n", attr[0]);
- + m_path.start_gradient(radial);
- +
- + for (int32 i = 0; attr[i]; i += 2)
- + {
- + /* if(!parse_attr(attr[i], attr[i + 1]))
- + {*/
- + if (strcmp(attr[i], "id") == 0)
- + m_path.current_gradient()->set_id(attr[i + 1]);
- + else if(strcmp(attr[i], "gradientTransform") == 0) {
- + m_path.current_gradient()->set_transformation(parse_transform(attr[i + 1]));
- + } else
- + m_path.current_gradient()->add_string(attr[i], attr[i + 1]);
- + /*}*/
- + }
- + }
- +
- + // parse_gradient_stop
- + void
- + parser::parse_gradient_stop(const char** attr)
- + {
- + // printf("parser::parse_gradient_stop(%s)\n", attr[0]);
- +
- + double offset = 0.0;
- + rgba8 color;
- + for (int32 i = 0; attr[i]; i += 2) {
- + if (strcmp(attr[i], "offset") == 0) {
- + offset = parse_double(attr[i + 1]);
- + } else
- + if (strcmp(attr[i], "style") == 0) {
- + parse_style(attr[i + 1]);
- + // here we get a bit hacky, in order not to change too much code at once...
- + // historically, parse_style() was for parsing path attributes only, but
- + // it comes in handy here as well, and I added "stop-color" and "stop-opacity"
- + // to parse_name_value(). It remembers the color in "fGradientStopColor".
- + // The color will of course be broken if the "style" attribute did not contain
- + // any valid stuff.
- + color = m_gradient_stop_color;
- + } else
- + if (strcmp(attr[i], "stop-color") == 0) {
- + color = parse_color(attr[i + 1]);
- + } else
- + if (strcmp(attr[i], "stop-opacity") == 0) {
- + color.opacity(parse_double(attr[i + 1]));
- + }
- + }
- +
- + // printf(" offset: %f, color: %d, %d, %d, %d\n", offset, color.r, color.g, color.b, color.a);
- +
- + if (gradient* gradient = m_path.current_gradient()) {
- + gradient->add_stop(offset, color);
- + } else {
- + throw exception("parse_gradient_stop() outside of gradient tag!\n");
- + }
- + }
- +
- //-------------------------------------------------------------
- static bool is_numeric(char c)
- {
- @@ -801,7 +1127,7 @@
- }
- //-------------------------------------------------------------
- - unsigned parser::parse_matrix(const char* str)
- + unsigned parser::parse_matrix(const char* str, trans_affine& transform)
- {
- double args[6];
- unsigned na = 0;
- @@ -810,37 +1136,37 @@
- {
- throw exception("parse_matrix: Invalid number of arguments");
- }
- - m_path.transform().premultiply(trans_affine(args[0], args[1], args[2], args[3], args[4], args[5]));
- + transform.premultiply(trans_affine(args[0], args[1], args[2], args[3], args[4], args[5]));
- return len;
- }
- //-------------------------------------------------------------
- - unsigned parser::parse_translate(const char* str)
- + unsigned parser::parse_translate(const char* str, trans_affine& transform)
- {
- double args[2];
- unsigned na = 0;
- unsigned len = parse_transform_args(str, args, 2, &na);
- if(na == 1) args[1] = 0.0;
- - m_path.transform().premultiply(trans_affine_translation(args[0], args[1]));
- + transform.premultiply(trans_affine_translation(args[0], args[1]));
- return len;
- }
- //-------------------------------------------------------------
- - unsigned parser::parse_rotate(const char* str)
- + unsigned parser::parse_rotate(const char* str, trans_affine& transform)
- {
- double args[3];
- unsigned na = 0;
- unsigned len = parse_transform_args(str, args, 3, &na);
- if(na == 1)
- {
- - m_path.transform().premultiply(trans_affine_rotation(deg2rad(args[0])));
- + transform.premultiply(trans_affine_rotation(deg2rad(args[0])));
- }
- else if(na == 3)
- {
- trans_affine t = trans_affine_translation(-args[1], -args[2]);
- t *= trans_affine_rotation(deg2rad(args[0]));
- t *= trans_affine_translation(args[1], args[2]);
- - m_path.transform().premultiply(t);
- + transform.premultiply(t);
- }
- else
- {
- @@ -850,33 +1176,33 @@
- }
- //-------------------------------------------------------------
- - unsigned parser::parse_scale(const char* str)
- + unsigned parser::parse_scale(const char* str, trans_affine& transform)
- {
- double args[2];
- unsigned na = 0;
- unsigned len = parse_transform_args(str, args, 2, &na);
- if(na == 1) args[1] = args[0];
- - m_path.transform().premultiply(trans_affine_scaling(args[0], args[1]));
- + transform.premultiply(trans_affine_scaling(args[0], args[1]));
- return len;
- }
- //-------------------------------------------------------------
- - unsigned parser::parse_skew_x(const char* str)
- + unsigned parser::parse_skew_x(const char* str, trans_affine& transform)
- {
- double arg;
- unsigned na = 0;
- unsigned len = parse_transform_args(str, &arg, 1, &na);
- - m_path.transform().premultiply(trans_affine_skewing(deg2rad(arg), 0.0));
- + transform.premultiply(trans_affine_skewing(deg2rad(arg), 0.0));
- return len;
- }
- //-------------------------------------------------------------
- - unsigned parser::parse_skew_y(const char* str)
- + unsigned parser::parse_skew_y(const char* str, trans_affine& transform)
- {
- double arg;
- unsigned na = 0;
- unsigned len = parse_transform_args(str, &arg, 1, &na);
- - m_path.transform().premultiply(trans_affine_skewing(0.0, deg2rad(arg)));
- + transform.premultiply(trans_affine_skewing(0.0, deg2rad(arg)));
- return len;
- }
- Index: svg_viewer/agg_svg_parser.h
- ===================================================================
- --- svg_viewer/agg_svg_parser.h (revision 50)
- +++ svg_viewer/agg_svg_parser.h (working copy)
- @@ -12,6 +12,18 @@
- // mcseemagg@yahoo.com
- // http://www.antigrain.com
- //----------------------------------------------------------------------------
- +// Gunnar Roth: add support for linear and radial gradients(support xlink attr),
- +// shape gradient opaqueness, rounded rects, circles,ellipses. support a command (arc) in pathes.
- +// set new origin correctly to last postion on z command in a path( was set to 0,0 before).
- +// enable parsing of colors written as rgb()
- +// some code was inspired by code from Haiku OS
- +/*
- +* Copyright 2006-2007, Haiku. All rights reserved.
- +* Distributed under the terms of the MIT License.
- +*
- +* Authors:
- +* Stephan Aßmus <superstippi@gmx.de>
- +*/
- //
- // SVG parser.
- //
- @@ -38,27 +50,35 @@
- void parse(const char* fname);
- const char* title() const { return m_title; }
- + bool tags_ignored() const
- + { return m_tags_ignored; }
- +
- private:
- // XML event handlers
- static void start_element(void* data, const char* el, const char** attr);
- static void end_element(void* data, const char* el);
- static void content(void* data, const char* s, int len);
- + void parse_svg(const char** attr);
- void parse_attr(const char** attr);
- void parse_path(const char** attr);
- void parse_poly(const char** attr, bool close_flag);
- + void parse_circle(const char** attr);
- + void parse_ellipse(const char** attr);
- void parse_rect(const char** attr);
- void parse_line(const char** attr);
- void parse_style(const char* str);
- - void parse_transform(const char* str);
- + trans_affine parse_transform(const char* str);
- + void parse_gradient(const char** attr, bool radial);
- + void parse_gradient_stop(const char** attr);
- - 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);
- + unsigned parse_matrix(const char* str, trans_affine& transform);
- + unsigned parse_translate(const char* str, trans_affine& transform);
- + unsigned parse_rotate(const char* str, trans_affine& transform);
- + unsigned parse_scale(const char* str, trans_affine& transform);
- + unsigned parse_skew_x(const char* str, trans_affine& transform);
- + unsigned parse_skew_y(const char* str, trans_affine& transform);
- bool parse_attr(const char* name, const char* value);
- bool parse_name_value(const char* nv_start, const char* nv_end);
- @@ -77,6 +97,10 @@
- char* m_attr_value;
- unsigned m_attr_name_len;
- unsigned m_attr_value_len;
- + rgba8 m_gradient_stop_color;
- +
- +bool m_tags_ignored;
- +
- };
- }
- Index: svg_viewer/agg_svg_path_renderer.cpp
- ===================================================================
- --- svg_viewer/agg_svg_path_renderer.cpp (revision 50)
- +++ svg_viewer/agg_svg_path_renderer.cpp (working copy)
- @@ -13,6 +13,19 @@
- // http://www.antigrain.com
- //----------------------------------------------------------------------------
- //
- +// Gunnar Roth: add support for linear and radial gradients(support xlink attr),
- +// shape gradient opaqueness, rounded rects, circles,ellipses. support a command (arc) in pathes.
- +// set new origin correctly to last postion on z command in a path( was set to 0,0 before).
- +// enable parsing of colors written as rgb()
- +// some code was inspired by code from Haiku OS
- +/*
- +* Copyright 2006-2007, Haiku. All rights reserved.
- +* Distributed under the terms of the MIT License.
- +*
- +* Authors:
- +* Stephan Aßmus <superstippi@gmx.de>
- +*/
- +//
- // SVG path renderer.
- //
- //----------------------------------------------------------------------------
- @@ -26,7 +39,9 @@
- {
- //------------------------------------------------------------------------
- - path_renderer::path_renderer() :
- + path_renderer::path_renderer()
- + :
- + m_cur_gradient(NULL),
- m_curved(m_storage),
- m_curved_count(m_curved),
- @@ -163,7 +178,19 @@
- m_storage.curve4(x2, y2, x, y);
- }
- }
- -
- +// elliptical_arc
- +void
- +path_renderer::elliptical_arc(double rx, double ry, double angle,
- + bool large_arc_flag, bool sweep_flag,
- + double x, double y, bool rel)
- + {
- + angle = angle / 180.0 * pi;
- + if (rel) {
- + m_storage.arc_rel(rx, ry, angle, large_arc_flag, sweep_flag, x, y);
- + } else {
- + m_storage.arc_to(rx, ry, angle, large_arc_flag, sweep_flag, x, y);
- + }
- + }
- //------------------------------------------------------------------------
- void path_renderer::close_subpath()
- {
- @@ -223,7 +250,8 @@
- //------------------------------------------------------------------------
- void path_renderer::stroke_width(double w)
- {
- - cur_attr().stroke_width = w;
- + path_attributes& attr = cur_attr();
- + attr.stroke_width = w;
- }
- //------------------------------------------------------------------------
- @@ -231,13 +259,31 @@
- {
- cur_attr().fill_flag = false;
- }
- +// fill_url
- + void path_renderer::fill_url(const char* url)
- + {
- + sprintf(cur_attr().fill_url, "%s", url);
- + }
- +
- //------------------------------------------------------------------------
- void path_renderer::stroke_none()
- {
- cur_attr().stroke_flag = false;
- }
- -
- +// stroke_url
- + void
- + path_renderer::stroke_url(const char* url)
- + {
- + sprintf(cur_attr().stroke_url, "%s", url);
- + }
- +
- + // opacity
- + void
- + path_renderer::opacity(double op)
- + {
- + cur_attr().opacity *= op;
- + }
- //------------------------------------------------------------------------
- void path_renderer::fill_opacity(double op)
- {
- @@ -277,6 +323,7 @@
- //------------------------------------------------------------------------
- void path_renderer::parse_path(path_tokenizer& tok)
- {
- + char lastCmd = 0;
- while(tok.next())
- {
- double arg[10];
- @@ -287,7 +334,10 @@
- case 'M': case 'm':
- arg[0] = tok.last_number();
- arg[1] = tok.next(cmd);
- - move_to(arg[0], arg[1], cmd == 'm');
- + if (lastCmd != cmd)
- + move_to(arg[0], arg[1], cmd == 'm');
- + else
- + line_to(arg[0], arg[1], lastCmd == 'm');
- break;
- case 'L': case 'l':
- @@ -337,11 +387,30 @@
- curve4(arg[0], arg[1], arg[2], arg[3], cmd == 's');
- break;
- - case 'A': case 'a':
- - throw exception("parse_path: Command A: NOT IMPLEMENTED YET");
- + case 'A': case 'a': {
- + arg[0] = tok.last_number();
- + for(i = 1; i < 3; i++) {
- + arg[i] = tok.next(cmd);
- + }
- + bool large_arc_flag = tok.next(cmd) ? true : false;
- + bool sweep_flag = tok.next(cmd) ? true : false;
- + for(i = 3; i < 5; i++) {
- + arg[i] = tok.next(cmd);
- + }
- + elliptical_arc(arg[0], arg[1], arg[2],
- + large_arc_flag, sweep_flag,
- + arg[3], arg[4], cmd == 'a');
- + break;
- + }
- case 'Z': case 'z':
- - close_subpath();
- + {
- + double x = m_storage.last_x();
- + double y = m_storage.last_y();
- + close_subpath();
- + move_to(x,y,false);
- + }
- +
- break;
- default:
- @@ -351,9 +420,68 @@
- throw exception(buf);
- }
- }
- + lastCmd = cmd;
- }
- }
- +
- + void path_renderer::start_gradient(bool radial)
- + {
- + if (m_cur_gradient) {
- + fprintf(stderr, "path_renderer::StartGradient() - ERROR: "
- + "previous gradient (%s) not finished!\n",
- + m_cur_gradient->id());
- + }
- +
- + if (radial)
- + m_cur_gradient = new radial_gradient();
- + else
- + m_cur_gradient = new linear_gradient();
- +
- + add_gradient(m_cur_gradient);
- + }
- +
- +
- + void path_renderer::end_gradient()
- + {
- + if (m_cur_gradient) {
- + m_cur_gradient->realize();
- + } else {
- + fprintf(stderr, "path_renderer::EndGradient() - "
- + "ERROR: no gradient started!\n");
- + }
- + m_cur_gradient = NULL;
- + }
- +
- + // #pragma mark -
- +
- + // _AddGradient
- + void
- + path_renderer::add_gradient(gradient* gradient)
- + {
- + if (gradient) {
- + m_gradients.push_back(gradient);
- + }
- + }
- +
- + // _GradientAt
- + gradient*
- + path_renderer::gradient_at(int32 index) const
- + {
- + return m_gradients.at(index);
- + }
- +
- + // _FindGradient
- + gradient*
- + path_renderer::find_gradient(const char* name) const
- + {
- + for (int32 i = 0; gradient* g = gradient_at(i); i++) {
- + if (strcmp(g->id(), name) == 0)
- + return g;
- + }
- + return NULL;
- + }
- +
- }
- }
- Index: svg_viewer/agg_svg_path_renderer.h
- ===================================================================
- --- svg_viewer/agg_svg_path_renderer.h (revision 50)
- +++ svg_viewer/agg_svg_path_renderer.h (working copy)
- @@ -12,7 +12,20 @@
- // mcseemagg@yahoo.com
- // http://www.antigrain.com
- //----------------------------------------------------------------------------
- +// Gunnar Roth: add support for linear and radial gradients(support xlink attr),
- +// shape gradient opaqueness, rounded rects, circles,ellipses. support a command (arc) in pathes.
- +// set new origin correctly to last postion on z command in a path( was set to 0,0 before).
- +// enable parsing of colors written as rgb()
- +// some code was inspired by code from Haiku OS
- +/*
- +* Copyright 2006-2007, Haiku. All rights reserved.
- +* Distributed under the terms of the MIT License.
- +*
- +* Authors:
- +* Stephan Aßmus <superstippi@gmx.de>
- +*/
- //
- +//
- // SVG path renderer.
- //
- //----------------------------------------------------------------------------
- @@ -29,7 +42,12 @@
- #include "agg_bounding_rect.h"
- #include "agg_rasterizer_scanline_aa.h"
- #include "agg_svg_path_tokenizer.h"
- -
- +#include <vector>
- +#include "agg_svg_gradient.h"
- +#include "agg_span_gradient.h"
- +#include "agg_span_allocator.h"
- +#include "agg_span_interpolator_linear.h"
- +#include "agg_rounded_rect.h"
- namespace agg
- {
- namespace svg
- @@ -56,6 +74,7 @@
- +class gradient;
- //============================================================================
- // Basic path attributes
- @@ -64,6 +83,7 @@
- unsigned index;
- rgba8 fill_color;
- rgba8 stroke_color;
- + double opacity;
- bool fill_flag;
- bool stroke_flag;
- bool even_odd_flag;
- @@ -73,20 +93,26 @@
- double stroke_width;
- trans_affine transform;
- + char stroke_url[64];
- + char fill_url[64];
- +
- // Empty constructor
- path_attributes() :
- index(0),
- fill_color(rgba(0,0,0)),
- stroke_color(rgba(0,0,0)),
- + opacity(1.0),
- fill_flag(true),
- stroke_flag(false),
- - even_odd_flag(false),
- + even_odd_flag(true),
- line_join(miter_join),
- line_cap(butt_cap),
- miter_limit(4.0),
- stroke_width(1.0),
- transform()
- {
- + stroke_url[0] = 0;
- + fill_url[0] = 0;
- }
- // Copy constructor
- @@ -94,6 +120,7 @@
- index(attr.index),
- fill_color(attr.fill_color),
- stroke_color(attr.stroke_color),
- + opacity(attr.opacity),
- fill_flag(attr.fill_flag),
- stroke_flag(attr.stroke_flag),
- even_odd_flag(attr.even_odd_flag),
- @@ -103,6 +130,8 @@
- stroke_width(attr.stroke_width),
- transform(attr.transform)
- {
- + sprintf(stroke_url, "%s", attr.stroke_url);
- + sprintf(fill_url, "%s", attr.fill_url);
- }
- // Copy constructor with new index value
- @@ -110,6 +139,7 @@
- index(idx),
- fill_color(attr.fill_color),
- stroke_color(attr.stroke_color),
- + opacity(attr.opacity),
- fill_flag(attr.fill_flag),
- stroke_flag(attr.stroke_flag),
- even_odd_flag(attr.even_odd_flag),
- @@ -119,6 +149,8 @@
- stroke_width(attr.stroke_width),
- transform(attr.transform)
- {
- + sprintf(stroke_url, "%s", attr.stroke_url);
- + sprintf(fill_url, "%s", attr.fill_url);
- }
- };
- @@ -139,8 +171,14 @@
- typedef conv_transform<curved_count> curved_trans;
- typedef conv_contour<curved_trans> curved_trans_contour;
- + typedef agg::span_allocator<rgba8> span_allocator_type;
- +
- path_renderer();
- -
- + ~path_renderer()
- + {
- + for(size_t i = 0; i < m_gradients.size(); i++)
- + delete m_gradients[i];
- + }
- void remove_all();
- // Use these functions as follows:
- @@ -165,6 +203,29 @@
- double x, double y, bool rel=false);
- void curve4(double x2, double y2, // S, s
- double x, double y, bool rel=false);
- + void elliptical_arc(double rx, double ry,
- + double angle,
- + bool large_arc_flag,
- + bool sweep_flag,
- + double x, double y,
- + bool rel = false); // A, a
- + void roundrect(double x1, double y1, // C, c
- + double x2, double y2,double rx, double ry,bool rel = false)
- + {
- + if(rel)
- + {
- + m_storage.rel_to_abs(&x1, &y1);
- + m_storage.rel_to_abs(&x2, &y2);
- +
- + }
- + agg::rounded_rect rc;
- + rc.rect(x1, y1, x2, y2);
- + rc.radius(rx,ry);
- + rc.normalize_radius();
- + m_storage.concat_path(rc,0);
- +
- +
- + }
- void close_subpath(); // Z, z
- // template<class VertexSource>
- @@ -189,7 +250,10 @@
- void even_odd(bool flag);
- void stroke_width(double w);
- void fill_none();
- + void fill_url(const char* url);
- void stroke_none();
- + void stroke_url(const char* url);
- + void opacity(double op);
- void fill_opacity(double op);
- void stroke_opacity(double op);
- void line_join(line_join_e join);
- @@ -221,21 +285,79 @@
- agg::bounding_rect(trans, *this, 0, m_attr_storage.size(), x1, y1, x2, y2);
- }
- + template<class Rasterizer, class Scanline, class RendererBase,class GradientFunction>
- + void render_gradient(Rasterizer& ras,
- + Scanline& sl,
- + RendererBase& rb, const trans_affine& mtx,
- + GradientFunction gradient_func, gradient::color_func_type &lut, int start,int end)
- + {
- + typedef agg::span_interpolator_linear<> interpolator_type;
- + interpolator_type span_interpolator(mtx);
- +
- + typedef agg::span_gradient<rgba8,
- + interpolator_type,
- + GradientFunction,
- + gradient::color_func_type> span_gradient_type;
- +
- + span_gradient_type span_gradient(span_interpolator,
- + gradient_func,
- + lut,
- + start, end);
- +
- + agg::render_scanlines_aa(ras, sl, rb, m_alloc, span_gradient);
- +
- + }
- + template<class Rasterizer, class Scanline, class RendererBase>
- + void render_gradient(Rasterizer& ras,
- + Scanline& sl,
- + RendererBase& rb, const char * gradient_url,double opaque)
- + {
- + if (gradient* g = find_gradient(gradient_url))
- + {
- + gradient* gl = NULL;
- + if(g->count_colors() == 0)
- + {
- + std::string & xlink = g->xlink();
- + gl = find_gradient(xlink.c_str() + 1);
- + }
- + trans_affine mtxgr = g->transform();
- + mtxgr.multiply(m_transform);
- + mtxgr.invert();
- + if(gl)
- + gl->set_opaque(opaque);
- + else
- + g->set_opaque(opaque);
- + gradient::color_func_type &lut = gl ? gl->lut() : g->lut();
- + if(g->type() == gradient::GRADIENT_CIRCULAR)
- + {
- + gradient_circle gradient_func;
- + render_gradient(ras,sl,rb,mtxgr,gradient_func,lut, 0, gradient::lut_range);
- + }
- + else if(g->type() == gradient::GRADIENT_LINEAR)
- + { gradient_x gradient_func;
- + render_gradient(ras,sl,rb,mtxgr,gradient_func,lut,-gradient::lut_range,gradient::lut_range);
- + }
- + }
- +
- + }
- // 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>
- + template<class Rasterizer, class Scanline, class RendererBase>
- void render(Rasterizer& ras,
- Scanline& sl,
- - Renderer& ren,
- + RendererBase& rb,
- const trans_affine& mtx,
- const rect_i& cb,
- double opacity=1.0)
- {
- unsigned i;
- + typedef agg::renderer_scanline_aa_solid<RendererBase> renderer_solid;
- + renderer_solid ren(rb);
- 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++)
- {
- @@ -262,11 +384,17 @@
- 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.fill_url[0] != 0)
- + {
- + render_gradient(ras,sl,rb,attr.fill_url,attr.opacity);
- + }
- + else
- + {
- + color = attr.fill_color;
- + color.opacity(color.opacity() * opacity*attr.opacity);
- + ren.color(color);
- + agg::render_scanlines(ras, sl, ren);
- + }
- }
- if(attr.stroke_flag)
- @@ -289,15 +417,29 @@
- 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);
- + if(attr.stroke_url[0] != 0)
- + {
- + render_gradient(ras,sl,rb,attr.stroke_url,attr.opacity);
- + }
- + else
- + {
- + color = attr.stroke_color;
- + color.opacity(color.opacity() * opacity * attr.opacity);
- + ren.color(color);
- + agg::render_scanlines(ras, sl, ren);
- + }
- +
- }
- }
- }
- -
- + void start_gradient(bool radial = false);
- + void end_gradient();
- + gradient* current_gradient() const
- + { return m_cur_gradient; }
- private:
- + void add_gradient(gradient* gradient);
- + gradient* gradient_at(int32 index) const;
- + gradient* find_gradient(const char* name) const;
- path_attributes& cur_attr();
- path_storage m_storage;
- @@ -305,6 +447,10 @@
- attr_storage m_attr_stack;
- trans_affine m_transform;
- + span_allocator_type m_alloc;
- + std::vector<gradient*> m_gradients;
- + gradient* m_cur_gradient;
- +
- curved m_curved;
- curved_count m_curved_count;
- Index: svg_viewer/agg_svg_path_tokenizer.cpp
- ===================================================================
- --- svg_viewer/agg_svg_path_tokenizer.cpp (revision 50)
- +++ svg_viewer/agg_svg_path_tokenizer.cpp (working copy)
- @@ -12,7 +12,15 @@
- // mcseemagg@yahoo.com
- // http://www.antigrain.com
- //----------------------------------------------------------------------------
- +//change from haiku
- //
- +// Copyright 2006, Haiku. All rights reserved.
- +// Distributed under the terms of the MIT License.
- +// Authors:
- +//Stephan Aßmus <superstippi@gmx.de>
- +//
- +// Adrien Destugues: Fix parsing of numbers in svg files : the code used obsolete atod
- +//instead of strtod and led to numbers in the form 2.5e-4 to make the parsing fail as 'e' was interpreted as the end of the number.
- // SVG path tokenizer.
- //
- //----------------------------------------------------------------------------
- @@ -116,22 +124,9 @@
- //------------------------------------------------------------------------
- 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);
- + char* end;
- + m_last_number = strtod(m_path, &end);
- + m_path = end;
- return true;
- }
- Index: svg_viewer/svg_test.cpp
- ===================================================================
- --- svg_viewer/svg_test.cpp (revision 50)
- +++ svg_viewer/svg_test.cpp (working copy)
- @@ -1,3 +1,20 @@
- +//----------------------------------------------------------------------------
- +// 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
- +//----------------------------------------------------------------------------
- +//^
- +// Gunnar Roth : pass base renderer instead of solid renderer to render function.
- +
- #include <stdio.h>
- #include <stdlib.h>
- #include "agg_basics.h"
- @@ -113,7 +130,7 @@
- m_path.expand(m_expand.value());
- start_timer();
- - m_path.render(ras, sl, ren, mtx, rb.clip_box(), 1.0);
- + m_path.render(ras, sl, rb, mtx, rb.clip_box(), 1.0);
- double tm = elapsed_time();
- unsigned vertex_count = m_path.vertex_count();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement