Advertisement
Guest User

Patch for Agg Svg Viewer Enhancements

a guest
Aug 11th, 2012
478
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 59.35 KB | None | 0 0
  1. Index: CMakeLists.txt
  2. ===================================================================
  3. --- CMakeLists.txt  (revision 50)
  4. +++ CMakeLists.txt  (working copy)
  5. @@ -302,6 +302,8 @@
  6.          ./svg_viewer/agg_svg_path_renderer.h
  7.          ./svg_viewer/agg_svg_path_tokenizer.cpp
  8.          ./svg_viewer/agg_svg_path_tokenizer.h
  9. +        ./svg_viewer/agg_svg_gradient.cpp
  10. +        ./svg_viewer/agg_svg_gradient.h
  11.          )
  12.  ENDIF ( agg_USE_EXPAT )
  13.  
  14. Index: svg_viewer/agg_svg_gradient.cpp
  15. ===================================================================
  16. --- svg_viewer/agg_svg_gradient.cpp (revision 0)
  17. +++ svg_viewer/agg_svg_gradient.cpp (working copy)
  18. @@ -0,0 +1,197 @@
  19. +//----------------------------------------------------------------------------
  20. +// Anti-Grain Geometry - Version 2.3
  21. +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
  22. +//
  23. +// Permission to copy, use, modify, sell and distribute this software
  24. +// is granted provided this copyright notice appears in all copies.
  25. +// This software is provided "as is" without express or implied
  26. +// warranty, and with no claim as to its suitability for any purpose.
  27. +//
  28. +//----------------------------------------------------------------------------
  29. +// Contact: mcseem@antigrain.com
  30. +//          mcseemagg@yahoo.com
  31. +//          http://www.antigrain.com
  32. +//----------------------------------------------------------------------------
  33. +//
  34. +// Gunnar Roth: add support for linear and radial gradients(support xlink attr),
  35. +// shape gradient opaqueness, rounded rects, circles,ellipses. support a command (arc)  in pathes.
  36. +// set new origin correctly to last postion on z command in a path( was set to 0,0 before).
  37. +// enable parsing of colors written as rgb()
  38. +// some code was inspired by code from Haiku OS
  39. +/*
  40. +* Copyright 2006-2007, Haiku. All rights reserved.
  41. +* Distributed under the terms of the MIT License.
  42. +*
  43. +* Authors:
  44. +* Stephan Aßmus <superstippi@gmx.de>
  45. +*/
  46. +//
  47. +
  48. +#include <stdio.h>
  49. +#include <stdlib.h>
  50. +
  51. +
  52. +
  53. +#include "agg_svg_gradient.h"
  54. +#include <vector>
  55. +#include "agg_trans_affine.h"
  56. +#include "agg_gradient_lut.h"
  57. +
  58. +
  59. +
  60. +
  61. +
  62. +
  63. +namespace agg {
  64. +   namespace svg {
  65. +
  66. +
  67. +
  68. +       // constructor
  69. +       gradient::gradient()
  70. +           :
  71. +           m_type(GRADIENT_LINEAR),
  72. +           m_id(""),
  73. +           m_colcnt(0),
  74. +           m_opaque(1.0)
  75. +       {
  76. +       }
  77. +
  78. +       // destructor
  79. +       gradient::~gradient()
  80. +       {
  81. +          
  82. +       }
  83. +
  84. +       // SetID
  85. +       void
  86. +           gradient::set_id(const char* id)
  87. +       {
  88. +           m_id = id;
  89. +       }
  90. +
  91. +       // ID
  92. +       const char*
  93. +           gradient::id() const
  94. +       {
  95. +           return m_id.c_str();
  96. +       }
  97. +
  98. +       // AddStop
  99. +       void
  100. +           gradient::add_stop(double offset, rgba8 color)
  101. +       {
  102. +           m_colcnt++;
  103. +           m_gradient_lut.add_color(offset,color);
  104. +       }
  105. +
  106. +       // SetTransformation
  107. +       void
  108. +           gradient::set_transformation(const trans_affine& transform)
  109. +       {
  110. +           m_transform.multiply(transform);
  111. +       }
  112. +       // constructor
  113. +       linear_gradient::linear_gradient()
  114. +           : gradient()
  115. +       {
  116. +       }
  117. +
  118. +       // destructor
  119. +       linear_gradient::~linear_gradient()
  120. +       {
  121. +       }
  122. +
  123. +       // MakeGradient
  124. +      
  125. +       void linear_gradient::realize()
  126. +       {
  127. +
  128. +           set_type(GRADIENT_LINEAR);
  129. +           // setup the gradient transform
  130. +           point_d start(-lut_range, -lut_range);
  131. +           point_d end(lut_range, -lut_range);
  132. +           std::string coordinate;
  133. +           if (find_string("x1", &coordinate) )
  134. +               start.x = atof(coordinate.c_str());
  135. +           if (find_string("y1", &coordinate) )
  136. +               start.y = atof(coordinate.c_str());
  137. +           if (find_string("x2", &coordinate) )
  138. +               end.x = atof(coordinate.c_str());
  139. +           if (find_string("y2", &coordinate) )
  140. +               end.y = atof(coordinate.c_str());
  141. +
  142. +
  143. +           // the transformed parallelogram
  144. +           double parl[6];
  145. +           parl[0] = start.x;
  146. +           parl[1] = start.y;
  147. +           parl[2] = end.x;
  148. +           parl[3] = end.y;
  149. +           parl[4] = end.x - (end.y - start.y);
  150. +           parl[5] = end.y + (end.x - start.x);
  151. +           trans_affine transform(-lut_range, -lut_range, lut_range, lut_range, parl);
  152. +           m_transform.premultiply(transform);
  153. +           m_gradient_lut.build_lut(1.0);     
  154. +       }
  155. +
  156. +       // constructor
  157. +       radial_gradient::radial_gradient()
  158. +           : gradient()
  159. +       {
  160. +       }
  161. +
  162. +       // destructor
  163. +       radial_gradient::~radial_gradient()
  164. +       {
  165. +       }
  166. +
  167. +       // MakeGradient
  168. +      
  169. +       void    radial_gradient::realize()
  170. +       {
  171. +           //printf("SVGRadialGradient::MakeGradient()\n");
  172. +           // TODO: handle userSpaceOnUse/objectBoundingBox
  173. +          
  174. +           set_type(GRADIENT_CIRCULAR);
  175. +
  176. +           double cx = 0.0;
  177. +           double cy = 0.0;
  178. +           double r = 100.0;
  179. +           double fx = 0.0;
  180. +           double fy = 0.0;
  181. +
  182. +           std::string value;
  183. +           if (find_string("cx", &value) )
  184. +               cx = atof(value.c_str());
  185. +           if (find_string("cy", &value) )
  186. +               cy = atof(value.c_str());
  187. +           if (find_string("r", &value) )
  188. +               r = atof(value.c_str());
  189. +/*
  190. +           if (FindString("fx", &value) )
  191. +           {
  192. +               fx = atof(value.c_str());
  193. +               if (FindString("fy", &value) )
  194. +                   fy = atof(value.c_str());
  195. +               SetType(GRADIENT_CIRCULAR_FOCAL);
  196. +           }
  197. +*/
  198. +
  199. +
  200. +           // the transformed parallelogram
  201. +           double parl[6];
  202. +           parl[0] = cx - r;
  203. +           parl[1] = cy - r;
  204. +           parl[2] = cx + r;
  205. +           parl[3] = cy - r;
  206. +           parl[4] = cx + r;
  207. +           parl[5] = cy + r;
  208. +
  209. +           trans_affine transform(-lut_range, -lut_range, lut_range, lut_range, parl);
  210. +           m_transform.premultiply(transform);
  211. +           m_gradient_lut.build_lut(1.0);
  212. +       }
  213. +
  214. +   } // namespace svg
  215. +} // namespace agg
  216. \ No newline at end of file
  217. Index: svg_viewer/agg_svg_gradient.h
  218. ===================================================================
  219. --- svg_viewer/agg_svg_gradient.h   (revision 0)
  220. +++ svg_viewer/agg_svg_gradient.h   (working copy)
  221. @@ -0,0 +1,274 @@
  222. +//----------------------------------------------------------------------------
  223. +// Anti-Grain Geometry - Version 2.3
  224. +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
  225. +//
  226. +// Permission to copy, use, modify, sell and distribute this software
  227. +// is granted provided this copyright notice appears in all copies.
  228. +// This software is provided "as is" without express or implied
  229. +// warranty, and with no claim as to its suitability for any purpose.
  230. +//
  231. +//----------------------------------------------------------------------------
  232. +// Contact: mcseem@antigrain.com
  233. +//          mcseemagg@yahoo.com
  234. +//          http://www.antigrain.com
  235. +//----------------------------------------------------------------------------
  236. +//
  237. +// Gunnar Roth: add support for linear and radial gradients(support xlink attr),
  238. +// shape gradient opaqueness, rounded rects, circles,ellipses. support a command (arc)  in pathes.
  239. +// set new origin correctly to last postion on z command in a path( was set to 0,0 before).
  240. +// enable parsing of colors written as rgb()
  241. +// some code was inspired by code from Haiku OS
  242. +/*
  243. +* Copyright 2006-2007, Haiku. All rights reserved.
  244. +* Distributed under the terms of the MIT License.
  245. +*
  246. +* Authors:
  247. +* Stephan Aßmus <superstippi@gmx.de>
  248. +*/
  249. +//
  250. +
  251. +#ifndef SVG_GRADIENTS_H
  252. +#define SVG_GRADIENTS_H
  253. +
  254. +
  255. +#include <agg_color_rgba.h>
  256. +#include <agg_trans_affine.h>
  257. +
  258. +
  259. +#include <String.h>
  260. +#include <string>
  261. +#include <map>
  262. +#include "agg_gradient_lut.h"
  263. +
  264. +
  265. +namespace agg {
  266. +   namespace svg {
  267. +
  268. +       template<class ColorInterpolator,
  269. +           unsigned ColorLutSize=256> class gradient_lut_opaque
  270. +       {
  271. +       public:
  272. +           typedef ColorInterpolator interpolator_type;
  273. +           typedef typename interpolator_type::color_type color_type;
  274. +           enum { color_lut_size = ColorLutSize };
  275. +
  276. +           //--------------------------------------------------------------------
  277. +           gradient_lut_opaque() : m_color_lut(color_lut_size) {}
  278. +
  279. +           // Build Gradient Lut
  280. +           // First, call remove_all(), then add_color() at least twice,
  281. +           // then build_lut(). Argument "offset" in add_color must be
  282. +           // in range [0...1] and defines a color stop as it is described
  283. +           // in SVG specification, section Gradients and Patterns.
  284. +           // The simplest linear gradient is:
  285. +           //    gradient_lut.add_color(0.0, start_color);
  286. +           //    gradient_lut.add_color(1.0, end_color);
  287. +           //--------------------------------------------------------------------
  288. +           void remove_all();
  289. +           void add_color(double offset, const color_type& color);
  290. +           void build_lut(double opaque );
  291. +
  292. +           // Size-index Interface. This class can be used directly as the
  293. +           // ColorF in span_gradient. All it needs is two access methods
  294. +           // size() and operator [].
  295. +           //--------------------------------------------------------------------
  296. +           static unsigned size()
  297. +           {
  298. +               return color_lut_size;
  299. +           }
  300. +           const color_type& operator [] (unsigned i) const
  301. +           {
  302. +               return m_color_lut[i];
  303. +           }
  304. +
  305. +       private:
  306. +           //--------------------------------------------------------------------
  307. +           struct color_point
  308. +           {
  309. +               double     offset;
  310. +               color_type color;
  311. +
  312. +               color_point() {}
  313. +               color_point(double off, const color_type& c) :
  314. +               offset(off), color(c)
  315. +               {
  316. +                   if(offset < 0.0) offset = 0.0;
  317. +                   if(offset > 1.0) offset = 1.0;
  318. +               }
  319. +           };
  320. +           typedef agg::pod_bvector<color_point, 4> color_profile_type;
  321. +           typedef agg::pod_array<color_type>       color_lut_type;
  322. +
  323. +           static bool offset_less(const color_point& a, const color_point& b)
  324. +           {
  325. +               return a.offset < b.offset;
  326. +           }
  327. +           static bool offset_equal(const color_point& a, const color_point& b)
  328. +           {
  329. +               return a.offset == b.offset;
  330. +           }
  331. +
  332. +           //--------------------------------------------------------------------
  333. +           color_profile_type  m_color_profile;
  334. +           color_lut_type      m_color_lut;
  335. +       };
  336. +
  337. +
  338. +
  339. +       //------------------------------------------------------------------------
  340. +       template<class T, unsigned S>
  341. +       void gradient_lut_opaque<T,S>::remove_all()
  342. +       {
  343. +           m_color_profile.remove_all();
  344. +       }
  345. +
  346. +       //------------------------------------------------------------------------
  347. +       template<class T, unsigned S>
  348. +       void gradient_lut_opaque<T,S>::add_color(double offset, const color_type& color)
  349. +       {
  350. +           m_color_profile.add(color_point(offset, color));
  351. +       }
  352. +
  353. +       //------------------------------------------------------------------------
  354. +       template<class T, unsigned S>
  355. +       void gradient_lut_opaque<T,S>::build_lut(double opaque)
  356. +       {
  357. +           quick_sort(m_color_profile, offset_less);
  358. +           m_color_profile.cut_at(remove_duplicates(m_color_profile, offset_equal));
  359. +           if(m_color_profile.size() >= 2)
  360. +           {
  361. +               unsigned i;
  362. +               unsigned start = uround(m_color_profile[0].offset * color_lut_size);
  363. +               unsigned end;
  364. +               color_type c = m_color_profile[0].color;
  365. +               c.opacity(c.opacity() * opaque);
  366. +               for(i = 0; i < start; i++)
  367. +               {
  368. +                   m_color_lut[i] = c;
  369. +               }
  370. +               for(i = 1; i < m_color_profile.size(); i++)
  371. +               {
  372. +                   end  = uround(m_color_profile[i].offset * color_lut_size);
  373. +                   color_type c1 = m_color_profile[i-1].color;
  374. +                   c1.opacity(c1.opacity() * opaque);
  375. +                   color_type c2 = m_color_profile[i].color;
  376. +                   c2.opacity(c2.opacity() * opaque);
  377. +                   interpolator_type ci(c1,
  378. +                       c2 ,
  379. +                       end - start + 1);
  380. +                   while(start < end)
  381. +                   {
  382. +                       m_color_lut[start] = ci.color();
  383. +                       ++ci;
  384. +                       ++start;
  385. +                   }
  386. +               }
  387. +               c = m_color_profile.last().color;
  388. +               c.opacity(c.opacity() * opaque);
  389. +               for(; end < m_color_lut.size(); end++)
  390. +               {
  391. +                   m_color_lut[end] = c;
  392. +               }
  393. +           }
  394. +       }
  395. +       class gradient {
  396. +       public:
  397. +           static const int lut_range = 128;
  398. +           typedef gradient_lut_opaque<agg::color_interpolator<agg::rgba8>, lut_range * 2> color_func_type;
  399. +           enum gradients_type {
  400. +               GRADIENT_LINEAR = 0,
  401. +               GRADIENT_CIRCULAR,
  402. +               GRADIENT_CIRCULAR_FOCAL,
  403. +               GRADIENT_DIAMOND,
  404. +               GRADIENT_CONIC,
  405. +               GRADIENT_XY,
  406. +               GRADIENT_SQRT_XY
  407. +           };
  408. +           gradient();
  409. +           virtual ~gradient();
  410. +
  411. +           void    set_id(const char* id);
  412. +           const char* id() const;
  413. +           void set_opaque(double opaque)
  414. +           {
  415. +               if(opaque != m_opaque)
  416. +               {
  417. +                   m_opaque = opaque;
  418. +                   m_gradient_lut.build_lut(m_opaque);
  419. +               }
  420. +           }
  421. +           virtual void    add_stop(double offset, rgba8 color);
  422. +           void    set_transformation(const trans_affine& transform);
  423. +           virtual void realize() = 0;
  424. +
  425. +          
  426. +           void add_string(const char *name, const char *string)
  427. +           {
  428. +               m_mapStrings[name] = string;
  429. +           }
  430. +
  431. +           color_func_type &lut()
  432. +           {
  433. +               return m_gradient_lut;
  434. +           }
  435. +
  436. +           void    set_type(gradients_type type)
  437. +           {
  438. +               m_type = type;
  439. +           }
  440. +           gradients_type  type() const
  441. +           { return m_type; }
  442. +
  443. +           const trans_affine & transform()
  444. +           {
  445. +               return m_transform;
  446. +           }
  447. +           unsigned count_colors()
  448. +           {
  449. +               return m_colcnt;
  450. +           }
  451. +           std::string xlink()
  452. +           {
  453. +               std::string xlink;
  454. +               find_string("xlink:href",&xlink);
  455. +               return xlink;
  456. +           }
  457. +
  458. +       protected:
  459. +           bool find_string(const char * key,std::string * pVal ) const
  460. +           {
  461. +               std::map<std::string,std::string>::const_iterator it = m_mapStrings.find(key);
  462. +               if(it == m_mapStrings.end())
  463. +                   return false;
  464. +               *pVal=it->second;
  465. +               return true;
  466. +           }
  467. +           trans_affine m_transform;
  468. +           color_func_type m_gradient_lut;
  469. +           unsigned m_colcnt;
  470. +       private:
  471. +           std::map<std::string,std::string> m_mapStrings;
  472. +           gradients_type  m_type;
  473. +           double m_opaque;
  474. +           std::string m_id;
  475. +       };
  476. +
  477. +       class linear_gradient : public gradient {
  478. +       public:
  479. +           linear_gradient();
  480. +           virtual ~linear_gradient();
  481. +
  482. +           virtual void realize();
  483. +       };
  484. +
  485. +       class radial_gradient : public gradient {
  486. +       public:
  487. +           radial_gradient();
  488. +           virtual ~radial_gradient();
  489. +           virtual void realize();
  490. +       };
  491. +
  492. +   } // namespace svg
  493. +} // namespace agg
  494. +
  495. +#endif // SVG_GRADIENTS_H
  496. \ No newline at end of file
  497. Index: svg_viewer/agg_svg_parser.cpp
  498. ===================================================================
  499. --- svg_viewer/agg_svg_parser.cpp   (revision 50)
  500. +++ svg_viewer/agg_svg_parser.cpp   (working copy)
  501. @@ -13,6 +13,19 @@
  502.  //          http://www.antigrain.com
  503.  //----------------------------------------------------------------------------
  504.  //
  505. +// Gunnar Roth: add support for linear and radial gradients(support xlink attr),
  506. +// shape gradient opaqueness, rounded rects, circles,ellipses. support a command (arc)  in pathes.
  507. +// set new origin correctly to last postion on z command in a path( was set to 0,0 before).
  508. +// enable parsing of colors written as rgb()
  509. +// some code was inspired by code from Haiku OS
  510. +/*
  511. +* Copyright 2006-2007, Haiku. All rights reserved.
  512. +* Distributed under the terms of the MIT License.
  513. +*
  514. +* Authors:
  515. +* Stephan Aßmus <superstippi@gmx.de>
  516. +*/
  517. +//
  518.  // SVG parser.
  519.  //
  520.  //----------------------------------------------------------------------------
  521. @@ -22,7 +35,7 @@
  522.  #include <ctype.h>
  523.  #include "agg_svg_parser.h"
  524.  #include "expat.h"
  525. -
  526. +#include "agg_svg_gradient.h"
  527.  namespace agg
  528.  {
  529.  namespace svg
  530. @@ -185,7 +198,99 @@
  531.          { "zzzzzzzzzzz",0,0,0, 0 }
  532.      };
  533.  
  534. +    //-------------------------------------------------------------
  535. +    int cmp_color(const void* p1, const void* p2)
  536. +    {
  537. +        return strcmp(((named_color*)p1)->name, ((named_color*)p2)->name);
  538. +    }
  539.  
  540. +    //-------------------------------------------------------------
  541. +    rgba8 parse_color(const char* str)
  542. +    {
  543. +        while(*str == ' ') ++str;
  544. +        if (*str == '#') {
  545. +          str++;
  546. +          int32 length = strlen(str);
  547. +          unsigned c = 0;
  548. +          if (length == 3) {
  549. +            // if there are only 3 byte, than it means that we
  550. +            // need to expand the color (#f60 -> #ff6600)
  551. +            // TODO: There must be an easier way...
  552. +            char expanded[7];
  553. +            expanded[0] = *str;
  554. +            expanded[1] = *str++;
  555. +            expanded[2] = *str;
  556. +            expanded[3] = *str++;
  557. +            expanded[4] = *str;
  558. +            expanded[5] = *str++;
  559. +            expanded[6] = 0;
  560. +            sscanf(expanded, "%x", &c);
  561. +            } else {
  562. +            sscanf(str, "%x", &c);
  563. +          }
  564. +          return rgb8_packed(c);
  565. +        }
  566. +       else if(*str == 'r')
  567. +       {
  568. +           int r,g,b;
  569. +           sscanf(str,"rgb(%d,%d,%d)",&r,&g,&b);
  570. +           return rgba8(r,g,b);
  571. +       }
  572. +        else
  573. +        {
  574. +            named_color c;
  575. +            unsigned len = strlen(str);
  576. +            if(len > sizeof(c.name) - 1)
  577. +            {
  578. +                throw exception("parse_color: Invalid color name '%s'", str);
  579. +            }
  580. +            strcpy(c.name, str);
  581. +            const void* p = bsearch(&c,
  582. +                                    colors,
  583. +                                    sizeof(colors) / sizeof(colors[0]),
  584. +                                    sizeof(colors[0]),
  585. +                                    cmp_color);
  586. +            if(p == 0)
  587. +            {
  588. +                throw exception("parse_color: Invalid color name '%s'", str);
  589. +            }
  590. +            const named_color* pc = (const named_color*)p;
  591. +            return rgba8(pc->r, pc->g, pc->b, pc->a);
  592. +        }
  593. +    }
  594. +    double parse_double(const char* str)
  595. +    {
  596. +        while(*str == ' ') ++str;
  597. +        double value = atof(str);
  598. +        // handle percent
  599. +        int32 length = strlen(str);
  600. +        if (str[length - 1] == '%')
  601. +        value /= 100.0;
  602. +        return value;
  603. +    }
  604. +// parse_url
  605. +    char*
  606. +    parse_url(const char* str)
  607. +    {
  608. +    const char* begin = str;
  609. +    while (*begin != '#')
  610. +    begin++;
  611. +    
  612. +    begin++;
  613. +    const char* end = begin;
  614. +    while (*end != ')')
  615. +    end++;
  616. +    
  617. +    end--;
  618. +    
  619. +    int32 length = end - begin + 2;
  620. +    char* result = new char[length];
  621. +    memcpy(result, begin, length - 1);
  622. +    result[length - 1] = 0;
  623. +    
  624. +    return result;
  625. +}
  626. +
  627.      //------------------------------------------------------------------------
  628.      parser::~parser()
  629.      {
  630. @@ -207,7 +312,8 @@
  631.          m_attr_name(new char[128]),
  632.          m_attr_value(new char[1024]),
  633.          m_attr_name_len(127),
  634. -        m_attr_value_len(1023)
  635. +        m_attr_value_len(1023),
  636. +        m_tags_ignored(false)
  637.      {
  638.          m_title[0] = 0;
  639.      }
  640. @@ -264,7 +370,11 @@
  641.      void parser::start_element(void* data, const char* el, const char** attr)
  642.      {
  643.          parser& self = *(parser*)data;
  644. -
  645. +        if (strcmp(el, "svg") == 0)
  646. +        {
  647. +          self.parse_svg(attr);
  648. +        }
  649. +        else
  650.          if(strcmp(el, "title") == 0)
  651.          {
  652.              self.m_title_flag = true;
  653. @@ -288,6 +398,16 @@
  654.              self.m_path_flag = true;
  655.          }
  656.          else
  657. +        if (strcmp(el, "circle") == 0)
  658. +        {
  659. +          self.parse_circle(attr);
  660. +        }
  661. +        else
  662. +        if (strcmp(el, "ellipse") == 0)
  663. +        {
  664. +          self.parse_ellipse(attr);
  665. +        }
  666. +        else
  667.          if(strcmp(el, "rect") == 0)
  668.          {
  669.              self.parse_rect(attr);
  670. @@ -307,11 +427,26 @@
  671.          {
  672.              self.parse_poly(attr, true);
  673.          }
  674. +        else
  675. +        if (strcmp(el, "linearGradient") == 0 || strcmp(el, "radialGradient") == 0)
  676. +        {
  677. +          self.parse_gradient(attr, strcmp(el, "radialGradient") == 0);
  678. +        }
  679. +        else
  680. +        if (strcmp(el, "stop") == 0)
  681. +        {
  682. +          self.parse_gradient_stop(attr);
  683. +        }
  684.          //else
  685.          //if(strcmp(el, "<OTHER_ELEMENTS>") == 0)
  686.          //{
  687.          //}
  688.          // . . .
  689. +        else
  690. +        {
  691. +          fprintf(stderr, "SVGParser igoring tag: \"%s\"\n", el);
  692. +          self.m_tags_ignored = true;
  693. +        }
  694.      }
  695.  
  696.  
  697. @@ -334,6 +469,12 @@
  698.          {
  699.              self.m_path_flag = false;
  700.          }
  701. +        else
  702. +        if (strcmp(el, "linearGradient") == 0 || strcmp(el, "radialGradient") == 0)
  703. +        {
  704. +        self.m_path.end_gradient();
  705. +        }
  706. +
  707.          //else
  708.          //if(strcmp(el, "<OTHER_ELEMENTS>") == 0)
  709.          //{
  710. @@ -361,6 +502,55 @@
  711.          }
  712.      }
  713.  
  714. +// parse_svg
  715. +    void parser::parse_svg(const char** attr)
  716. +    {
  717. +    double width = 0.0;
  718. +    double height = 0.0;
  719. +    rect_d viewBox(0.0, 0.0, -1.0, -1.0);
  720. +    
  721. +    for (int i = 0; attr[i]; i += 2) {
  722. +        if (strcmp(attr[i], "width") == 0)
  723. +        {
  724. +            width = parse_double(attr[i + 1]);
  725. +        }
  726. +        else
  727. +        if (strcmp(attr[i], "height") == 0)
  728. +        {
  729. +            height = parse_double(attr[i + 1]);
  730. +        }
  731. +        else
  732. +        if (strcmp(attr[i], "viewBox") == 0)
  733. +        {
  734. +            m_tokenizer.set_path_str(attr[i + 1]);
  735. +            if(!m_tokenizer.next())
  736. +            {
  737. +                throw exception("parse_svg (viewBox): Too few coordinates");
  738. +            }
  739. +            viewBox.x1 = m_tokenizer.last_number();
  740. +            if(!m_tokenizer.next())
  741. +            {
  742. +                throw exception("parse_svg (viewBox): Too few coordinates");
  743. +            }
  744. +            viewBox.y1 = m_tokenizer.last_number();
  745. +            if(!m_tokenizer.next())
  746. +            {
  747. +                throw exception("parse_svg (viewBox): Too few coordinates");
  748. +            }
  749. +            viewBox.x2 = m_tokenizer.last_number();
  750. +            if(!m_tokenizer.next())
  751. +            {
  752. +                throw exception("parse_svg (viewBox): Too few coordinates");
  753. +            }
  754. +            viewBox.y2 = m_tokenizer.last_number();
  755. +        }
  756. +    }
  757. +    if (width >= 0.0 && height >= 0.0) {
  758. +        //set viewBox
  759. +    } else {
  760. +        throw exception("parse_svg: Invalid width or height\n");
  761. +    }
  762. +    }
  763.  
  764.      //------------------------------------------------------------------------
  765.      void parser::parse_attr(const char** attr)
  766. @@ -410,53 +600,10 @@
  767.      }
  768.  
  769.  
  770. -    //-------------------------------------------------------------
  771. -    int cmp_color(const void* p1, const void* p2)
  772. -    {
  773. -        return strcmp(((named_color*)p1)->name, ((named_color*)p2)->name);
  774. -    }
  775.  
  776. -    //-------------------------------------------------------------
  777. -    rgba8 parse_color(const char* str)
  778. -    {
  779. -        while(*str == ' ') ++str;
  780. -        unsigned c = 0;
  781. -        if(*str == '#')
  782. -        {
  783. -            sscanf(str + 1, "%x", &c);
  784. -            return rgb8_packed(c);
  785. -        }
  786. -        else
  787. -        {
  788. -            named_color c;
  789. -            unsigned len = strlen(str);
  790. -            if(len > sizeof(c.name) - 1)
  791. -            {
  792. -                throw exception("parse_color: Invalid color name '%s'", str);
  793. -            }
  794. -            strcpy(c.name, str);
  795. -            const void* p = bsearch(&c,
  796. -                                    colors,
  797. -                                    sizeof(colors) / sizeof(colors[0]),
  798. -                                    sizeof(colors[0]),
  799. -                                    cmp_color);
  800. -            if(p == 0)
  801. -            {
  802. -                throw exception("parse_color: Invalid color name '%s'", str);
  803. -            }
  804. -            const named_color* pc = (const named_color*)p;
  805. -            return rgba8(pc->r, pc->g, pc->b, pc->a);
  806. -        }
  807. -    }
  808.  
  809. -    double parse_double(const char* str)
  810. -    {
  811. -        while(*str == ' ') ++str;
  812. -        return atof(str);
  813. -    }
  814.  
  815.  
  816. -
  817.      //-------------------------------------------------------------
  818.      bool parser::parse_attr(const char* name, const char* value)
  819.      {
  820. @@ -465,12 +612,21 @@
  821.              parse_style(value);
  822.          }
  823.          else
  824. +        if(strcmp(name, "opacity") == 0) {
  825. +          m_path.opacity(parse_double(value));
  826. +        } else
  827.          if(strcmp(name, "fill") == 0)
  828.          {
  829.              if(strcmp(value, "none") == 0)
  830.              {
  831.                  m_path.fill_none();
  832.              }
  833. +            else if (strncmp(value, "url", 3) == 0)
  834. +            {
  835. +              char* url = parse_url(value);
  836. +              m_path.fill_url(url);
  837. +              delete[] url;
  838. +            }
  839.              else
  840.              {
  841.                  m_path.fill(parse_color(value));
  842. @@ -482,12 +638,22 @@
  843.              m_path.fill_opacity(parse_double(value));
  844.          }
  845.          else
  846. +        if(strcmp(name, "fill-rule") == 0)
  847. +        {
  848. +           m_path.even_odd(strcmp(value, "evenodd") == 0);
  849. +        }
  850. +        else
  851.          if(strcmp(name, "stroke") == 0)
  852.          {
  853.              if(strcmp(value, "none") == 0)
  854.              {
  855.                  m_path.stroke_none();
  856.              }
  857. +            else if (strncmp(value, "url", 3) == 0) {
  858. +              char* url = parse_url(value);
  859. +              m_path.stroke_url(url);
  860. +              delete[] url;
  861. +            }
  862.              else
  863.              {
  864.                  m_path.stroke(parse_color(value));
  865. @@ -525,8 +691,17 @@
  866.          else
  867.          if(strcmp(name, "transform") == 0)
  868.          {
  869. -            parse_transform(value);
  870. +            m_path.transform().premultiply(parse_transform(value));
  871.          }
  872. +        else
  873. +        if (strcmp(name, "stop-color") == 0)
  874. +        {
  875. +          m_gradient_stop_color = parse_color(value);
  876. +        }
  877. +        else
  878. +        if (strcmp(name, "stop-opacity") == 0) {
  879. +          m_gradient_stop_color.opacity(parse_double(value));
  880. +        }
  881.          //else
  882.          //if(strcmp(el, "<OTHER_ATTRIBUTES>") == 0)
  883.          //{
  884. @@ -617,7 +792,89 @@
  885.  
  886.      }
  887.  
  888. +   // parse_circle
  889. +   void
  890. +       parser::parse_circle(const char** attr)
  891. +   {
  892. +       int i;
  893. +       double cx = 0.0;
  894. +       double cy = 0.0;
  895. +       double r = 0.0;
  896.  
  897. +       m_path.begin_path();
  898. +       for(i = 0; attr[i]; i += 2) {
  899. +           if (!parse_attr(attr[i], attr[i + 1])) {
  900. +               if(strcmp(attr[i], "cx") == 0)  cx = parse_double(attr[i + 1]);
  901. +               if(strcmp(attr[i], "cy") == 0)  cy = parse_double(attr[i + 1]);
  902. +               if(strcmp(attr[i], "r") == 0)   r = parse_double(attr[i + 1]);
  903. +           }
  904. +       }
  905. +
  906. +
  907. +       if (r != 0.0) {
  908. +           if (r < 0.0) throw exception("parse_circle: Invalid radius: %f", r);
  909. +
  910. +           m_path.move_to(cx, cy - r);
  911. +           m_path.curve4(cx + r * 0.56, cy - r,
  912. +               cx + r, cy - r * 0.56,
  913. +               cx + r, cy);
  914. +           m_path.curve4(cx + r, cy + r * 0.56,
  915. +               cx + r * 0.56, cy + r,
  916. +               cx, cy + r);
  917. +           m_path.curve4(cx - r * 0.56, cy + r,
  918. +               cx - r, cy + r * 0.56,
  919. +               cx - r, cy);
  920. +           m_path.curve4(cx - r, cy - r * 0.56,
  921. +               cx - r * 0.56, cy - r,
  922. +               cx, cy - r);
  923. +           m_path.close_subpath();
  924. +       }
  925. +       m_path.end_path();
  926. +   }
  927. +
  928. +   // parse_ellipse
  929. +   void
  930. +       parser::parse_ellipse(const char** attr)
  931. +   {
  932. +       int i;
  933. +       double cx = 0.0;
  934. +       double cy = 0.0;
  935. +       double rx = 0.0;
  936. +       double ry = 0.0;
  937. +
  938. +       m_path.begin_path();
  939. +       for(i = 0; attr[i]; i += 2) {
  940. +           if (!parse_attr(attr[i], attr[i + 1])) {
  941. +               if(strcmp(attr[i], "cx") == 0)  cx = parse_double(attr[i + 1]);
  942. +               if(strcmp(attr[i], "cy") == 0)  cy = parse_double(attr[i + 1]);
  943. +               if(strcmp(attr[i], "rx") == 0)  rx = parse_double(attr[i + 1]);
  944. +               if(strcmp(attr[i], "ry") == 0)  ry = parse_double(attr[i + 1]);
  945. +           }
  946. +       }
  947. +
  948. +
  949. +       if (rx != 0.0 && ry != 0.0) {
  950. +           if (rx < 0.0) throw exception("parse_ellipse: Invalid x-radius: %f", rx);
  951. +           if (ry < 0.0) throw exception("parse_ellipse: Invalid y-radius: %f", ry);
  952. +
  953. +           m_path.move_to(cx, cy - ry);
  954. +           m_path.curve4(cx + rx * 0.56, cy - ry,
  955. +               cx + rx, cy - ry * 0.56,
  956. +               cx + rx, cy);
  957. +           m_path.curve4(cx + rx, cy + ry * 0.56,
  958. +               cx + rx * 0.56, cy + ry,
  959. +               cx, cy + ry);
  960. +           m_path.curve4(cx - rx * 0.56, cy + ry,
  961. +               cx - rx, cy + ry * 0.56,
  962. +               cx - rx, cy);
  963. +           m_path.curve4(cx - rx, cy - ry * 0.56,
  964. +               cx - rx * 0.56, cy - ry,
  965. +               cx, cy - ry);
  966. +           m_path.close_subpath();
  967. +       }
  968. +       m_path.end_path();
  969. +   }
  970. +
  971.      //-------------------------------------------------------------
  972.      void parser::parse_rect(const char** attr)
  973.      {
  974. @@ -626,7 +883,8 @@
  975.          double y = 0.0;
  976.          double w = 0.0;
  977.          double h = 0.0;
  978. -
  979. +       double rx = 0.0;
  980. +       double ry = 0.0;
  981.          m_path.begin_path();
  982.          for(i = 0; attr[i]; i += 2)
  983.          {
  984. @@ -636,9 +894,9 @@
  985.                  if(strcmp(attr[i], "y") == 0)      y = parse_double(attr[i + 1]);
  986.                  if(strcmp(attr[i], "width") == 0)  w = parse_double(attr[i + 1]);
  987.                  if(strcmp(attr[i], "height") == 0) h = parse_double(attr[i + 1]);
  988. -                // rx - to be implemented
  989. -                // ry - to be implemented
  990. -            }
  991. +               if(strcmp(attr[i], "rx") == 0)      rx = parse_double(attr[i + 1]);
  992. +               if(strcmp(attr[i], "ry") == 0)      ry = parse_double(attr[i + 1]);
  993. +           }
  994.          }
  995.  
  996.  
  997. @@ -646,12 +904,18 @@
  998.          {
  999.              if(w < 0.0) throw exception("parse_rect: Invalid width: %f", w);
  1000.              if(h < 0.0) throw exception("parse_rect: Invalid height: %f", h);
  1001. -
  1002. -            m_path.move_to(x,     y);
  1003. -            m_path.line_to(x + w, y);
  1004. -            m_path.line_to(x + w, y + h);
  1005. -            m_path.line_to(x,     y + h);
  1006. -            m_path.close_subpath();
  1007. +           if(rx >0 || ry > 0)
  1008. +           {
  1009. +               m_path.roundrect(x,y,x+w,y+h,rx,ry);
  1010. +           }
  1011. +           else
  1012. +           {
  1013. +               m_path.move_to(x,     y);
  1014. +               m_path.line_to(x + w, y);
  1015. +               m_path.line_to(x + w, y + h);
  1016. +               m_path.line_to(x,     y + h);
  1017. +               m_path.close_subpath();
  1018. +           }
  1019.          }
  1020.          m_path.end_path();
  1021.      }
  1022. @@ -731,18 +995,19 @@
  1023.      }
  1024.  
  1025.      //-------------------------------------------------------------
  1026. -    void parser::parse_transform(const char* str)
  1027. +    trans_affine parser::parse_transform(const char* str)
  1028.      {
  1029. +        trans_affine transform;
  1030.          while(*str)
  1031.          {
  1032.              if(islower(*str))
  1033.              {
  1034. -                if(strncmp(str, "matrix", 6) == 0)    str += parse_matrix(str);    else
  1035. -                if(strncmp(str, "translate", 9) == 0) str += parse_translate(str); else
  1036. -                if(strncmp(str, "rotate", 6) == 0)    str += parse_rotate(str);    else
  1037. -                if(strncmp(str, "scale", 5) == 0)     str += parse_scale(str);     else
  1038. -                if(strncmp(str, "skewX", 5) == 0)     str += parse_skew_x(str);    else
  1039. -                if(strncmp(str, "skewY", 5) == 0)     str += parse_skew_y(str);    else
  1040. +                if(strncmp(str, "matrix", 6) == 0)    str += parse_matrix(str,transform);    else
  1041. +                if(strncmp(str, "translate", 9) == 0) str += parse_translate(str,transform); else
  1042. +                if(strncmp(str, "rotate", 6) == 0)    str += parse_rotate(str,transform);    else
  1043. +                if(strncmp(str, "scale", 5) == 0)     str += parse_scale(str,transform);     else
  1044. +                if(strncmp(str, "skewX", 5) == 0)     str += parse_skew_x(str,transform);    else
  1045. +                if(strncmp(str, "skewY", 5) == 0)     str += parse_skew_y(str,transform);    else
  1046.                  {
  1047.                      ++str;
  1048.                  }
  1049. @@ -752,9 +1017,70 @@
  1050.                  ++str;
  1051.              }
  1052.          }
  1053. +        return transform;
  1054.      }
  1055.  
  1056. +   // parse_gradient
  1057. +   void
  1058. +       parser::parse_gradient(const char** attr, bool radial)
  1059. +   {
  1060. +       // printf("parser::parse_gradient(%s)\n", attr[0]);
  1061.  
  1062. +       m_path.start_gradient(radial);
  1063. +
  1064. +       for (int32 i = 0; attr[i]; i += 2)
  1065. +       {
  1066. +           /* if(!parse_attr(attr[i], attr[i + 1]))
  1067. +           {*/
  1068. +           if (strcmp(attr[i], "id") == 0)
  1069. +               m_path.current_gradient()->set_id(attr[i + 1]);
  1070. +           else if(strcmp(attr[i], "gradientTransform") == 0) {
  1071. +               m_path.current_gradient()->set_transformation(parse_transform(attr[i + 1]));
  1072. +           } else
  1073. +               m_path.current_gradient()->add_string(attr[i], attr[i + 1]);
  1074. +            /*}*/
  1075. +       }
  1076. +   }
  1077. +
  1078. +   // parse_gradient_stop
  1079. +   void
  1080. +       parser::parse_gradient_stop(const char** attr)
  1081. +   {
  1082. +       // printf("parser::parse_gradient_stop(%s)\n", attr[0]);
  1083. +
  1084. +       double offset = 0.0;
  1085. +       rgba8 color;
  1086. +       for (int32 i = 0; attr[i]; i += 2) {
  1087. +           if (strcmp(attr[i], "offset") == 0) {
  1088. +               offset = parse_double(attr[i + 1]);
  1089. +           } else
  1090. +               if (strcmp(attr[i], "style") == 0) {
  1091. +                   parse_style(attr[i + 1]);
  1092. +                   // here we get a bit hacky, in order not to change too much code at once...
  1093. +                   // historically, parse_style() was for parsing path attributes only, but
  1094. +                   // it comes in handy here as well, and I added "stop-color" and "stop-opacity"
  1095. +                   // to parse_name_value(). It remembers the color in "fGradientStopColor".
  1096. +                   // The color will of course be broken if the "style" attribute did not contain
  1097. +                   // any valid stuff.
  1098. +                   color = m_gradient_stop_color;
  1099. +               } else
  1100. +                   if (strcmp(attr[i], "stop-color") == 0) {
  1101. +                       color = parse_color(attr[i + 1]);
  1102. +                   } else
  1103. +                       if (strcmp(attr[i], "stop-opacity") == 0) {
  1104. +                           color.opacity(parse_double(attr[i + 1]));
  1105. +                       }
  1106. +       }
  1107. +
  1108. +       // printf(" offset: %f, color: %d, %d, %d, %d\n", offset, color.r, color.g, color.b, color.a);
  1109. +
  1110. +       if (gradient* gradient = m_path.current_gradient()) {
  1111. +           gradient->add_stop(offset, color);
  1112. +       } else {
  1113. +           throw exception("parse_gradient_stop() outside of gradient tag!\n");
  1114. +       }
  1115. +   }
  1116. +
  1117.      //-------------------------------------------------------------
  1118.      static bool is_numeric(char c)
  1119.      {
  1120. @@ -801,7 +1127,7 @@
  1121.      }
  1122.  
  1123.      //-------------------------------------------------------------
  1124. -    unsigned parser::parse_matrix(const char* str)
  1125. +    unsigned parser::parse_matrix(const char* str, trans_affine& transform)
  1126.      {
  1127.          double args[6];
  1128.          unsigned na = 0;
  1129. @@ -810,37 +1136,37 @@
  1130.          {
  1131.              throw exception("parse_matrix: Invalid number of arguments");
  1132.          }
  1133. -        m_path.transform().premultiply(trans_affine(args[0], args[1], args[2], args[3], args[4], args[5]));
  1134. +        transform.premultiply(trans_affine(args[0], args[1], args[2], args[3], args[4], args[5]));
  1135.          return len;
  1136.      }
  1137.  
  1138.      //-------------------------------------------------------------
  1139. -    unsigned parser::parse_translate(const char* str)
  1140. +    unsigned parser::parse_translate(const char* str, trans_affine& transform)
  1141.      {
  1142.          double args[2];
  1143.          unsigned na = 0;
  1144.          unsigned len = parse_transform_args(str, args, 2, &na);
  1145.          if(na == 1) args[1] = 0.0;
  1146. -        m_path.transform().premultiply(trans_affine_translation(args[0], args[1]));
  1147. +        transform.premultiply(trans_affine_translation(args[0], args[1]));
  1148.          return len;
  1149.      }
  1150.  
  1151.      //-------------------------------------------------------------
  1152. -    unsigned parser::parse_rotate(const char* str)
  1153. +    unsigned parser::parse_rotate(const char* str, trans_affine& transform)
  1154.      {
  1155.          double args[3];
  1156.          unsigned na = 0;
  1157.          unsigned len = parse_transform_args(str, args, 3, &na);
  1158.          if(na == 1)
  1159.          {
  1160. -            m_path.transform().premultiply(trans_affine_rotation(deg2rad(args[0])));
  1161. +            transform.premultiply(trans_affine_rotation(deg2rad(args[0])));
  1162.          }
  1163.          else if(na == 3)
  1164.          {
  1165.              trans_affine t = trans_affine_translation(-args[1], -args[2]);
  1166.              t *= trans_affine_rotation(deg2rad(args[0]));
  1167.              t *= trans_affine_translation(args[1], args[2]);
  1168. -            m_path.transform().premultiply(t);
  1169. +            transform.premultiply(t);
  1170.          }
  1171.          else
  1172.          {
  1173. @@ -850,33 +1176,33 @@
  1174.      }
  1175.  
  1176.      //-------------------------------------------------------------
  1177. -    unsigned parser::parse_scale(const char* str)
  1178. +    unsigned parser::parse_scale(const char* str, trans_affine& transform)
  1179.      {
  1180.          double args[2];
  1181.          unsigned na = 0;
  1182.          unsigned len = parse_transform_args(str, args, 2, &na);
  1183.          if(na == 1) args[1] = args[0];
  1184. -        m_path.transform().premultiply(trans_affine_scaling(args[0], args[1]));
  1185. +        transform.premultiply(trans_affine_scaling(args[0], args[1]));
  1186.          return len;
  1187.      }
  1188.  
  1189.      //-------------------------------------------------------------
  1190. -    unsigned parser::parse_skew_x(const char* str)
  1191. +    unsigned parser::parse_skew_x(const char* str, trans_affine& transform)
  1192.      {
  1193.          double arg;
  1194.          unsigned na = 0;
  1195.          unsigned len = parse_transform_args(str, &arg, 1, &na);
  1196. -        m_path.transform().premultiply(trans_affine_skewing(deg2rad(arg), 0.0));
  1197. +        transform.premultiply(trans_affine_skewing(deg2rad(arg), 0.0));
  1198.          return len;
  1199.      }
  1200.  
  1201.      //-------------------------------------------------------------
  1202. -    unsigned parser::parse_skew_y(const char* str)
  1203. +    unsigned parser::parse_skew_y(const char* str, trans_affine& transform)
  1204.      {
  1205.          double arg;
  1206.          unsigned na = 0;
  1207.          unsigned len = parse_transform_args(str, &arg, 1, &na);
  1208. -        m_path.transform().premultiply(trans_affine_skewing(0.0, deg2rad(arg)));
  1209. +        transform.premultiply(trans_affine_skewing(0.0, deg2rad(arg)));
  1210.          return len;
  1211.      }
  1212.  
  1213. Index: svg_viewer/agg_svg_parser.h
  1214. ===================================================================
  1215. --- svg_viewer/agg_svg_parser.h (revision 50)
  1216. +++ svg_viewer/agg_svg_parser.h (working copy)
  1217. @@ -12,6 +12,18 @@
  1218.  //          mcseemagg@yahoo.com
  1219.  //          http://www.antigrain.com
  1220.  //----------------------------------------------------------------------------
  1221. +// Gunnar Roth: add support for linear and radial gradients(support xlink attr),
  1222. +// shape gradient opaqueness, rounded rects, circles,ellipses. support a command (arc)  in pathes.
  1223. +// set new origin correctly to last postion on z command in a path( was set to 0,0 before).
  1224. +// enable parsing of colors written as rgb()
  1225. +// some code was inspired by code from Haiku OS
  1226. +/*
  1227. +* Copyright 2006-2007, Haiku. All rights reserved.
  1228. +* Distributed under the terms of the MIT License.
  1229. +*
  1230. +* Authors:
  1231. +* Stephan Aßmus <superstippi@gmx.de>
  1232. +*/
  1233.  //
  1234.  // SVG parser.
  1235.  //
  1236. @@ -38,27 +50,35 @@
  1237.  
  1238.          void parse(const char* fname);
  1239.          const char* title() const { return m_title; }
  1240. +        bool   tags_ignored() const
  1241. +        { return m_tags_ignored; }
  1242.  
  1243. +
  1244.      private:
  1245.          // XML event handlers
  1246.          static void start_element(void* data, const char* el, const char** attr);
  1247.          static void end_element(void* data, const char* el);
  1248.          static void content(void* data, const char* s, int len);
  1249.  
  1250. +        void parse_svg(const char** attr);
  1251.          void parse_attr(const char** attr);
  1252.          void parse_path(const char** attr);
  1253.          void parse_poly(const char** attr, bool close_flag);
  1254. +        void parse_circle(const char** attr);
  1255. +        void parse_ellipse(const char** attr);
  1256.          void parse_rect(const char** attr);
  1257.          void parse_line(const char** attr);
  1258.          void parse_style(const char* str);
  1259. -        void parse_transform(const char* str);
  1260. +        trans_affine parse_transform(const char* str);
  1261. +        void parse_gradient(const char** attr, bool radial);
  1262. +        void parse_gradient_stop(const char** attr);
  1263.  
  1264. -        unsigned parse_matrix(const char* str);
  1265. -        unsigned parse_translate(const char* str);
  1266. -        unsigned parse_rotate(const char* str);
  1267. -        unsigned parse_scale(const char* str);
  1268. -        unsigned parse_skew_x(const char* str);
  1269. -        unsigned parse_skew_y(const char* str);
  1270. +        unsigned parse_matrix(const char* str, trans_affine& transform);
  1271. +        unsigned parse_translate(const char* str, trans_affine& transform);
  1272. +        unsigned parse_rotate(const char* str, trans_affine& transform);
  1273. +        unsigned parse_scale(const char* str, trans_affine& transform);
  1274. +        unsigned parse_skew_x(const char* str, trans_affine& transform);
  1275. +        unsigned parse_skew_y(const char* str, trans_affine& transform);
  1276.          
  1277.          bool parse_attr(const char* name, const char* value);
  1278.          bool parse_name_value(const char* nv_start, const char* nv_end);
  1279. @@ -77,6 +97,10 @@
  1280.          char*          m_attr_value;
  1281.          unsigned       m_attr_name_len;
  1282.          unsigned       m_attr_value_len;
  1283. +       rgba8          m_gradient_stop_color;
  1284. +
  1285. +bool   m_tags_ignored;
  1286. +
  1287.      };
  1288.  
  1289.  }
  1290. Index: svg_viewer/agg_svg_path_renderer.cpp
  1291. ===================================================================
  1292. --- svg_viewer/agg_svg_path_renderer.cpp    (revision 50)
  1293. +++ svg_viewer/agg_svg_path_renderer.cpp    (working copy)
  1294. @@ -13,6 +13,19 @@
  1295.  //          http://www.antigrain.com
  1296.  //----------------------------------------------------------------------------
  1297.  //
  1298. +// Gunnar Roth: add support for linear and radial gradients(support xlink attr),
  1299. +// shape gradient opaqueness, rounded rects, circles,ellipses. support a command (arc)  in pathes.
  1300. +// set new origin correctly to last postion on z command in a path( was set to 0,0 before).
  1301. +// enable parsing of colors written as rgb()
  1302. +// some code was inspired by code from Haiku OS
  1303. +/*
  1304. +* Copyright 2006-2007, Haiku. All rights reserved.
  1305. +* Distributed under the terms of the MIT License.
  1306. +*
  1307. +* Authors:
  1308. +* Stephan Aßmus <superstippi@gmx.de>
  1309. +*/
  1310. +//
  1311.  // SVG path renderer.
  1312.  //
  1313.  //----------------------------------------------------------------------------
  1314. @@ -26,7 +39,9 @@
  1315.  {
  1316.  
  1317.      //------------------------------------------------------------------------
  1318. -    path_renderer::path_renderer() :
  1319. +    path_renderer::path_renderer()
  1320. +       :
  1321. +        m_cur_gradient(NULL),
  1322.          m_curved(m_storage),
  1323.          m_curved_count(m_curved),
  1324.  
  1325. @@ -163,7 +178,19 @@
  1326.              m_storage.curve4(x2, y2, x, y);
  1327.          }
  1328.      }
  1329. -
  1330. +// elliptical_arc
  1331. +void
  1332. +path_renderer::elliptical_arc(double rx, double ry, double angle,
  1333. +                               bool large_arc_flag, bool sweep_flag,
  1334. +                               double x, double y, bool rel)
  1335. +    {
  1336. +       angle = angle / 180.0 * pi;
  1337. +       if (rel) {
  1338. +         m_storage.arc_rel(rx, ry, angle, large_arc_flag, sweep_flag, x, y);
  1339. +       } else {
  1340. +         m_storage.arc_to(rx, ry, angle, large_arc_flag, sweep_flag, x, y);
  1341. +       }
  1342. +    }
  1343.      //------------------------------------------------------------------------
  1344.      void path_renderer::close_subpath()
  1345.      {
  1346. @@ -223,7 +250,8 @@
  1347.      //------------------------------------------------------------------------
  1348.      void path_renderer::stroke_width(double w)
  1349.      {
  1350. -        cur_attr().stroke_width = w;
  1351. +       path_attributes& attr = cur_attr();
  1352. +        attr.stroke_width = w;
  1353.      }
  1354.  
  1355.      //------------------------------------------------------------------------
  1356. @@ -231,13 +259,31 @@
  1357.      {
  1358.          cur_attr().fill_flag = false;
  1359.      }
  1360. +// fill_url
  1361.  
  1362. +    void path_renderer::fill_url(const char* url)
  1363. +    {
  1364. +      sprintf(cur_attr().fill_url, "%s", url);
  1365. +    }
  1366. +
  1367.      //------------------------------------------------------------------------
  1368.      void path_renderer::stroke_none()
  1369.      {
  1370.          cur_attr().stroke_flag = false;
  1371.      }
  1372. -
  1373. +// stroke_url
  1374. +    void
  1375. +    path_renderer::stroke_url(const char* url)
  1376. +    {
  1377. +      sprintf(cur_attr().stroke_url, "%s", url);
  1378. +    }
  1379. +    
  1380. +    // opacity
  1381. +    void
  1382. +    path_renderer::opacity(double op)
  1383. +    {
  1384. +      cur_attr().opacity *= op;
  1385. +    }
  1386.      //------------------------------------------------------------------------
  1387.      void path_renderer::fill_opacity(double op)
  1388.      {
  1389. @@ -277,6 +323,7 @@
  1390.      //------------------------------------------------------------------------
  1391.      void path_renderer::parse_path(path_tokenizer& tok)
  1392.      {
  1393. +        char lastCmd = 0;
  1394.          while(tok.next())
  1395.          {
  1396.              double arg[10];
  1397. @@ -287,7 +334,10 @@
  1398.                  case 'M': case 'm':
  1399.                      arg[0] = tok.last_number();
  1400.                      arg[1] = tok.next(cmd);
  1401. -                    move_to(arg[0], arg[1], cmd == 'm');
  1402. +                    if (lastCmd != cmd)
  1403. +                      move_to(arg[0], arg[1], cmd == 'm');
  1404. +                    else
  1405. +                      line_to(arg[0], arg[1], lastCmd == 'm');
  1406.                      break;
  1407.  
  1408.                  case 'L': case 'l':
  1409. @@ -337,11 +387,30 @@
  1410.                      curve4(arg[0], arg[1], arg[2], arg[3], cmd == 's');
  1411.                      break;
  1412.  
  1413. -                case 'A': case 'a':
  1414. -                    throw exception("parse_path: Command A: NOT IMPLEMENTED YET");
  1415. +                case 'A': case 'a': {
  1416. +                    arg[0] = tok.last_number();
  1417. +                    for(i = 1; i < 3; i++) {
  1418. +                      arg[i] = tok.next(cmd);
  1419. +                    }
  1420. +                   bool large_arc_flag = tok.next(cmd) ? true : false;
  1421. +                   bool sweep_flag = tok.next(cmd) ? true : false;
  1422. +                    for(i = 3; i < 5; i++) {
  1423. +                       arg[i] = tok.next(cmd);
  1424. +                    }
  1425. +                    elliptical_arc(arg[0], arg[1], arg[2],
  1426. +                                    large_arc_flag, sweep_flag,
  1427. +                                    arg[3], arg[4], cmd == 'a');
  1428. +                    break;
  1429. +                    }
  1430.  
  1431.                  case 'Z': case 'z':
  1432. -                    close_subpath();
  1433. +                   {
  1434. +                       double x = m_storage.last_x();
  1435. +                       double y = m_storage.last_y();
  1436. +                       close_subpath();
  1437. +                       move_to(x,y,false);
  1438. +                   }
  1439. +
  1440.                      break;
  1441.  
  1442.                  default:
  1443. @@ -351,9 +420,68 @@
  1444.                      throw exception(buf);
  1445.                  }
  1446.              }
  1447. +            lastCmd = cmd;
  1448.          }
  1449.      }
  1450.  
  1451. +  
  1452. +   void path_renderer::start_gradient(bool radial)
  1453. +   {
  1454. +       if (m_cur_gradient) {
  1455. +           fprintf(stderr, "path_renderer::StartGradient() - ERROR: "
  1456. +               "previous gradient (%s) not finished!\n",
  1457. +               m_cur_gradient->id());
  1458. +       }
  1459. +
  1460. +       if (radial)
  1461. +           m_cur_gradient = new radial_gradient();
  1462. +       else
  1463. +           m_cur_gradient = new linear_gradient();
  1464. +
  1465. +       add_gradient(m_cur_gradient);
  1466. +   }
  1467. +
  1468. +
  1469. +   void path_renderer::end_gradient()
  1470. +   {
  1471. +       if (m_cur_gradient) {
  1472. +           m_cur_gradient->realize();
  1473. +       } else {
  1474. +           fprintf(stderr, "path_renderer::EndGradient() - "
  1475. +               "ERROR: no gradient started!\n");
  1476. +       }
  1477. +       m_cur_gradient = NULL;
  1478. +   }
  1479. +
  1480. +   // #pragma mark -
  1481. +
  1482. +   // _AddGradient
  1483. +   void
  1484. +       path_renderer::add_gradient(gradient* gradient)
  1485. +   {
  1486. +       if (gradient) {
  1487. +           m_gradients.push_back(gradient);
  1488. +       }
  1489. +   }
  1490. +
  1491. +   // _GradientAt
  1492. +   gradient*
  1493. +       path_renderer::gradient_at(int32 index) const
  1494. +   {
  1495. +       return m_gradients.at(index);
  1496. +   }
  1497. +
  1498. +   // _FindGradient
  1499. +   gradient*
  1500. +       path_renderer::find_gradient(const char* name) const
  1501. +   {
  1502. +       for (int32 i = 0; gradient* g = gradient_at(i); i++) {
  1503. +           if (strcmp(g->id(), name) == 0)
  1504. +               return g;
  1505. +       }
  1506. +       return NULL;
  1507. +   }
  1508. +
  1509.  }
  1510.  }
  1511.  
  1512. Index: svg_viewer/agg_svg_path_renderer.h
  1513. ===================================================================
  1514. --- svg_viewer/agg_svg_path_renderer.h  (revision 50)
  1515. +++ svg_viewer/agg_svg_path_renderer.h  (working copy)
  1516. @@ -12,7 +12,20 @@
  1517.  //          mcseemagg@yahoo.com
  1518.  //          http://www.antigrain.com
  1519.  //----------------------------------------------------------------------------
  1520. +// Gunnar Roth: add support for linear and radial gradients(support xlink attr),
  1521. +// shape gradient opaqueness, rounded rects, circles,ellipses. support a command (arc)  in pathes.
  1522. +// set new origin correctly to last postion on z command in a path( was set to 0,0 before).
  1523. +// enable parsing of colors written as rgb()
  1524. +// some code was inspired by code from Haiku OS
  1525. +/*
  1526. +* Copyright 2006-2007, Haiku. All rights reserved.
  1527. +* Distributed under the terms of the MIT License.
  1528. +*
  1529. +* Authors:
  1530. +* Stephan Aßmus <superstippi@gmx.de>
  1531. +*/
  1532.  //
  1533. +//
  1534.  // SVG path renderer.
  1535.  //
  1536.  //----------------------------------------------------------------------------
  1537. @@ -29,7 +42,12 @@
  1538.  #include "agg_bounding_rect.h"
  1539.  #include "agg_rasterizer_scanline_aa.h"
  1540.  #include "agg_svg_path_tokenizer.h"
  1541. -
  1542. +#include <vector>
  1543. +#include "agg_svg_gradient.h"
  1544. +#include "agg_span_gradient.h"
  1545. +#include "agg_span_allocator.h"
  1546. +#include "agg_span_interpolator_linear.h"
  1547. +#include "agg_rounded_rect.h"
  1548.  namespace agg
  1549.  {
  1550.  namespace svg
  1551. @@ -56,6 +74,7 @@
  1552.  
  1553.  
  1554.  
  1555. +class gradient;
  1556.  
  1557.      //============================================================================
  1558.      // Basic path attributes
  1559. @@ -64,6 +83,7 @@
  1560.          unsigned     index;
  1561.          rgba8        fill_color;
  1562.          rgba8        stroke_color;
  1563. +        double      opacity;
  1564.          bool         fill_flag;
  1565.          bool         stroke_flag;
  1566.          bool         even_odd_flag;
  1567. @@ -73,20 +93,26 @@
  1568.          double       stroke_width;
  1569.          trans_affine transform;
  1570.  
  1571. +        char   stroke_url[64];
  1572. +        char   fill_url[64];
  1573. +
  1574.          // Empty constructor
  1575.          path_attributes() :
  1576.              index(0),
  1577.              fill_color(rgba(0,0,0)),
  1578.              stroke_color(rgba(0,0,0)),
  1579. +            opacity(1.0),
  1580.              fill_flag(true),
  1581.              stroke_flag(false),
  1582. -            even_odd_flag(false),
  1583. +            even_odd_flag(true),
  1584.              line_join(miter_join),
  1585.              line_cap(butt_cap),
  1586.              miter_limit(4.0),
  1587.              stroke_width(1.0),
  1588.              transform()
  1589.          {
  1590. +           stroke_url[0] = 0;
  1591. +           fill_url[0] = 0;
  1592.          }
  1593.  
  1594.          // Copy constructor
  1595. @@ -94,6 +120,7 @@
  1596.              index(attr.index),
  1597.              fill_color(attr.fill_color),
  1598.              stroke_color(attr.stroke_color),
  1599. +            opacity(attr.opacity),
  1600.              fill_flag(attr.fill_flag),
  1601.              stroke_flag(attr.stroke_flag),
  1602.              even_odd_flag(attr.even_odd_flag),
  1603. @@ -103,6 +130,8 @@
  1604.              stroke_width(attr.stroke_width),
  1605.              transform(attr.transform)
  1606.          {
  1607. +           sprintf(stroke_url, "%s", attr.stroke_url);
  1608. +           sprintf(fill_url, "%s", attr.fill_url);
  1609.          }
  1610.  
  1611.          // Copy constructor with new index value
  1612. @@ -110,6 +139,7 @@
  1613.              index(idx),
  1614.              fill_color(attr.fill_color),
  1615.              stroke_color(attr.stroke_color),
  1616. +            opacity(attr.opacity),
  1617.              fill_flag(attr.fill_flag),
  1618.              stroke_flag(attr.stroke_flag),
  1619.              even_odd_flag(attr.even_odd_flag),
  1620. @@ -119,6 +149,8 @@
  1621.              stroke_width(attr.stroke_width),
  1622.              transform(attr.transform)
  1623.          {
  1624. +           sprintf(stroke_url, "%s", attr.stroke_url);
  1625. +           sprintf(fill_url, "%s", attr.fill_url);
  1626.          }
  1627.      };
  1628.  
  1629. @@ -139,8 +171,14 @@
  1630.          typedef conv_transform<curved_count>   curved_trans;
  1631.          typedef conv_contour<curved_trans>     curved_trans_contour;
  1632.  
  1633. +       typedef agg::span_allocator<rgba8> span_allocator_type;
  1634. +
  1635.          path_renderer();
  1636. -
  1637. +       ~path_renderer()
  1638. +       {
  1639. +           for(size_t i = 0; i < m_gradients.size(); i++)
  1640. +               delete m_gradients[i];
  1641. +       }
  1642.          void remove_all();
  1643.  
  1644.          // Use these functions as follows:
  1645. @@ -165,6 +203,29 @@
  1646.                      double x,  double y, bool rel=false);
  1647.          void curve4(double x2, double y2,                   // S, s
  1648.                      double x,  double y, bool rel=false);
  1649. +        void   elliptical_arc(double rx, double ry,
  1650. +                        double angle,
  1651. +                        bool large_arc_flag,
  1652. +                        bool sweep_flag,
  1653. +                        double x, double y,
  1654. +                        bool rel = false); // A, a
  1655. +       void roundrect(double x1, double y1,                   // C, c
  1656. +           double x2, double y2,double rx, double ry,bool rel = false)
  1657. +       {
  1658. +           if(rel)
  1659. +           {
  1660. +               m_storage.rel_to_abs(&x1, &y1);
  1661. +               m_storage.rel_to_abs(&x2, &y2);
  1662. +
  1663. +           }
  1664. +           agg::rounded_rect rc;
  1665. +           rc.rect(x1, y1, x2, y2);
  1666. +           rc.radius(rx,ry);
  1667. +           rc.normalize_radius();
  1668. +           m_storage.concat_path(rc,0);
  1669. +
  1670. +          
  1671. +       }
  1672.          void close_subpath();                               // Z, z
  1673.  
  1674.  //        template<class VertexSource>
  1675. @@ -189,7 +250,10 @@
  1676.          void even_odd(bool flag);
  1677.          void stroke_width(double w);
  1678.          void fill_none();
  1679. +        void fill_url(const char* url);
  1680.          void stroke_none();
  1681. +        void stroke_url(const char* url);
  1682. +        void opacity(double op);
  1683.          void fill_opacity(double op);
  1684.          void stroke_opacity(double op);
  1685.          void line_join(line_join_e join);
  1686. @@ -221,21 +285,79 @@
  1687.              agg::bounding_rect(trans, *this, 0, m_attr_storage.size(), x1, y1, x2, y2);
  1688.          }
  1689.  
  1690. +       template<class Rasterizer, class Scanline, class RendererBase,class GradientFunction>
  1691. +       void render_gradient(Rasterizer& ras,
  1692. +           Scanline& sl,
  1693. +           RendererBase& rb, const trans_affine& mtx,
  1694. +           GradientFunction gradient_func, gradient::color_func_type &lut, int start,int end)
  1695. +       {
  1696. +           typedef agg::span_interpolator_linear<> interpolator_type;
  1697. +           interpolator_type     span_interpolator(mtx);
  1698. +
  1699. +           typedef agg::span_gradient<rgba8,
  1700. +               interpolator_type,
  1701. +               GradientFunction,
  1702. +               gradient::color_func_type> span_gradient_type;
  1703. +
  1704. +           span_gradient_type    span_gradient(span_interpolator,
  1705. +               gradient_func,
  1706. +               lut,
  1707. +               start, end);
  1708. +
  1709. +           agg::render_scanlines_aa(ras, sl, rb, m_alloc, span_gradient);
  1710. +          
  1711. +       }
  1712. +       template<class Rasterizer, class Scanline, class RendererBase>
  1713. +       void render_gradient(Rasterizer& ras,
  1714. +           Scanline& sl,
  1715. +           RendererBase& rb, const char * gradient_url,double opaque)
  1716. +       {
  1717. +           if (gradient* g = find_gradient(gradient_url))
  1718. +           {
  1719. +               gradient* gl = NULL;
  1720. +               if(g->count_colors() == 0)
  1721. +               {
  1722. +                   std::string & xlink = g->xlink();
  1723. +                   gl = find_gradient(xlink.c_str() + 1);
  1724. +               }
  1725. +               trans_affine mtxgr = g->transform();
  1726. +               mtxgr.multiply(m_transform);
  1727. +               mtxgr.invert();
  1728. +               if(gl)
  1729. +                   gl->set_opaque(opaque);
  1730. +               else
  1731. +                   g->set_opaque(opaque);
  1732. +               gradient::color_func_type &lut = gl ? gl->lut() : g->lut();
  1733. +               if(g->type() == gradient::GRADIENT_CIRCULAR)
  1734. +               {
  1735. +                   gradient_circle    gradient_func;
  1736. +                   render_gradient(ras,sl,rb,mtxgr,gradient_func,lut, 0, gradient::lut_range);
  1737. +               }
  1738. +               else if(g->type() == gradient::GRADIENT_LINEAR)
  1739. +               {   gradient_x    gradient_func;
  1740. +                   render_gradient(ras,sl,rb,mtxgr,gradient_func,lut,-gradient::lut_range,gradient::lut_range);                               
  1741. +               }
  1742. +           }                  
  1743. +
  1744. +       }
  1745.          // Rendering. One can specify two additional parameters:
  1746.          // trans_affine and opacity. They can be used to transform the whole
  1747.          // image and/or to make it translucent.
  1748. -        template<class Rasterizer, class Scanline, class Renderer>
  1749. +        template<class Rasterizer, class Scanline, class RendererBase>
  1750.          void render(Rasterizer& ras,
  1751.                      Scanline& sl,
  1752. -                    Renderer& ren,
  1753. +                    RendererBase& rb,
  1754.                      const trans_affine& mtx,
  1755.                      const rect_i& cb,
  1756.                      double opacity=1.0)
  1757.          {
  1758.              unsigned i;
  1759. +           typedef agg::renderer_scanline_aa_solid<RendererBase> renderer_solid;
  1760.  
  1761. +           renderer_solid ren(rb);
  1762.              ras.clip_box(cb.x1, cb.y1, cb.x2, cb.y2);
  1763.              m_curved_count.count(0);
  1764. +          
  1765.  
  1766.              for(i = 0; i < m_attr_storage.size(); i++)
  1767.              {
  1768. @@ -262,11 +384,17 @@
  1769.                          m_curved_trans_contour.miter_limit(attr.miter_limit);
  1770.                          ras.add_path(m_curved_trans_contour, attr.index);
  1771.                      }
  1772. -
  1773. -                    color = attr.fill_color;
  1774. -                    color.opacity(color.opacity() * opacity);
  1775. -                    ren.color(color);
  1776. -                    agg::render_scanlines(ras, sl, ren);
  1777. +                   if(attr.fill_url[0] != 0)
  1778. +                   {
  1779. +                       render_gradient(ras,sl,rb,attr.fill_url,attr.opacity);
  1780. +                   }
  1781. +                   else
  1782. +                   {
  1783. +                       color = attr.fill_color;
  1784. +                       color.opacity(color.opacity() * opacity*attr.opacity);
  1785. +                       ren.color(color);
  1786. +                       agg::render_scanlines(ras, sl, ren);
  1787. +                   }
  1788.                  }
  1789.  
  1790.                  if(attr.stroke_flag)
  1791. @@ -289,15 +417,29 @@
  1792.                      ras.reset();
  1793.                      ras.filling_rule(fill_non_zero);
  1794.                      ras.add_path(m_curved_stroked_trans, attr.index);
  1795. -                    color = attr.stroke_color;
  1796. -                    color.opacity(color.opacity() * opacity);
  1797. -                    ren.color(color);
  1798. -                    agg::render_scanlines(ras, sl, ren);
  1799. +                    if(attr.stroke_url[0] != 0)
  1800. +                   {
  1801. +                       render_gradient(ras,sl,rb,attr.stroke_url,attr.opacity);
  1802. +                   }
  1803. +                   else
  1804. +                   {
  1805. +                       color = attr.stroke_color;
  1806. +                       color.opacity(color.opacity() * opacity * attr.opacity);
  1807. +                       ren.color(color);
  1808. +                       agg::render_scanlines(ras, sl, ren);
  1809. +                   }
  1810. +
  1811.                  }
  1812.              }
  1813.          }
  1814. -
  1815. +        void   start_gradient(bool radial = false);
  1816. +        void   end_gradient();
  1817. +        gradient*  current_gradient() const
  1818. +        { return m_cur_gradient; }
  1819.      private:
  1820. +        void   add_gradient(gradient* gradient);
  1821. +        gradient*  gradient_at(int32 index) const;
  1822. +        gradient*  find_gradient(const char* name) const;
  1823.          path_attributes& cur_attr();
  1824.  
  1825.          path_storage   m_storage;
  1826. @@ -305,6 +447,10 @@
  1827.          attr_storage   m_attr_stack;
  1828.          trans_affine   m_transform;
  1829.  
  1830. +       span_allocator_type m_alloc;
  1831. +        std::vector<gradient*> m_gradients;
  1832. +        gradient*  m_cur_gradient;
  1833. +
  1834.          curved                       m_curved;
  1835.          curved_count                 m_curved_count;
  1836.  
  1837. Index: svg_viewer/agg_svg_path_tokenizer.cpp
  1838. ===================================================================
  1839. --- svg_viewer/agg_svg_path_tokenizer.cpp   (revision 50)
  1840. +++ svg_viewer/agg_svg_path_tokenizer.cpp   (working copy)
  1841. @@ -12,7 +12,15 @@
  1842.  //          mcseemagg@yahoo.com
  1843.  //          http://www.antigrain.com
  1844.  //----------------------------------------------------------------------------
  1845. +//change from haiku
  1846.  //
  1847. +// Copyright 2006, Haiku. All rights reserved.
  1848. +// Distributed under the terms of the MIT License.
  1849. +// Authors:
  1850. +//Stephan Aßmus <superstippi@gmx.de>
  1851. +//
  1852. +// Adrien Destugues: Fix parsing of numbers in svg files : the code used obsolete atod
  1853. +//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.
  1854.  // SVG path tokenizer.
  1855.  //
  1856.  //----------------------------------------------------------------------------
  1857. @@ -116,22 +124,9 @@
  1858.      //------------------------------------------------------------------------
  1859.      bool path_tokenizer::parse_number()
  1860.      {
  1861. -        char buf[256]; // Should be enough for any number
  1862. -        char* buf_ptr = buf;
  1863. -
  1864. -        // Copy all sign characters
  1865. -        while(buf_ptr < buf+255 && *m_path == '-' || *m_path == '+')
  1866. -        {
  1867. -            *buf_ptr++ = *m_path++;
  1868. -        }
  1869. -
  1870. -        // Copy all numeric characters
  1871. -        while(buf_ptr < buf+255 && is_numeric(*m_path))
  1872. -        {
  1873. -            *buf_ptr++ = *m_path++;
  1874. -        }
  1875. -        *buf_ptr = 0;
  1876. -        m_last_number = atof(buf);
  1877. +        char* end;
  1878. +        m_last_number = strtod(m_path, &end);
  1879. +        m_path = end;
  1880.          return true;
  1881.      }
  1882.  
  1883. Index: svg_viewer/svg_test.cpp
  1884. ===================================================================
  1885. --- svg_viewer/svg_test.cpp (revision 50)
  1886. +++ svg_viewer/svg_test.cpp (working copy)
  1887. @@ -1,3 +1,20 @@
  1888. +//----------------------------------------------------------------------------
  1889. +// Anti-Grain Geometry - Version 2.3
  1890. +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
  1891. +//
  1892. +// Permission to copy, use, modify, sell and distribute this software
  1893. +// is granted provided this copyright notice appears in all copies.
  1894. +// This software is provided "as is" without express or implied
  1895. +// warranty, and with no claim as to its suitability for any purpose.
  1896. +//
  1897. +//----------------------------------------------------------------------------
  1898. +// Contact: mcseem@antigrain.com
  1899. +//          mcseemagg@yahoo.com
  1900. +//          http://www.antigrain.com
  1901. +//----------------------------------------------------------------------------
  1902. +//^
  1903. +// Gunnar Roth : pass base renderer instead of solid renderer to render function.
  1904. +
  1905.  #include <stdio.h>
  1906.  #include <stdlib.h>
  1907.  #include "agg_basics.h"
  1908. @@ -113,7 +130,7 @@
  1909.          
  1910.          m_path.expand(m_expand.value());
  1911.          start_timer();
  1912. -        m_path.render(ras, sl, ren, mtx, rb.clip_box(), 1.0);
  1913. +        m_path.render(ras, sl, rb, mtx, rb.clip_box(), 1.0);
  1914.          double tm = elapsed_time();
  1915.          unsigned vertex_count = m_path.vertex_count();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement