incubator-ooo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From p..@apache.org
Subject svn commit: r1184758 [3/17] - in /incubator/ooo/trunk/main: ./ agg/inc/ agg/source/ solenv/config/
Date Sun, 16 Oct 2011 04:13:21 GMT
Modified: incubator/ooo/trunk/main/agg/inc/agg_font_cache_manager.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/agg/inc/agg_font_cache_manager.h?rev=1184758&r1=1184757&r2=1184758&view=diff
==============================================================================
--- incubator/ooo/trunk/main/agg/inc/agg_font_cache_manager.h (original)
+++ incubator/ooo/trunk/main/agg/inc/agg_font_cache_manager.h Sun Oct 16 04:13:16 2011
@@ -1,5 +1,5 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
 //
 // Permission to copy, use, modify, sell and distribute this software 
@@ -39,7 +39,7 @@ namespace agg
         int8u*          data;
         unsigned        data_size;
         glyph_data_type data_type;
-        rect            bounds;
+        rect_i          bounds;
         double          advance_x;
         double          advance_y;
     };
@@ -49,12 +49,16 @@ namespace agg
     class font_cache
     {
     public:
-        enum { block_size = 16384-16 };
+        enum block_size_e { block_size = 16384-16 };
 
         //--------------------------------------------------------------------
-        font_cache(const char* font_signature) : 
+        font_cache() : 
             m_allocator(block_size),
             m_font_signature(0)
+        {}
+
+        //--------------------------------------------------------------------
+        void signature(const char* font_signature)
         {
             m_font_signature = (char*)m_allocator.allocate(strlen(font_signature) + 1);
             strcpy(m_font_signature, font_signature);
@@ -83,7 +87,7 @@ namespace agg
                                  unsigned        glyph_index,
                                  unsigned        data_size,
                                  glyph_data_type data_type,
-                                 const rect&     bounds,
+                                 const rect_i&   bounds,
                                  double          advance_x,
                                  double          advance_y)
         {
@@ -103,18 +107,18 @@ namespace agg
                 (glyph_cache*)m_allocator.allocate(sizeof(glyph_cache),
                                                    sizeof(double));
 
-            glyph->glyph_index = glyph_index;
-            glyph->data        = m_allocator.allocate(data_size);
-            glyph->data_size   = data_size;
-            glyph->data_type   = data_type;
-            glyph->bounds      = bounds;
-            glyph->advance_x   = advance_x;
-            glyph->advance_y   = advance_y;
+            glyph->glyph_index        = glyph_index;
+            glyph->data               = m_allocator.allocate(data_size);
+            glyph->data_size          = data_size;
+            glyph->data_type          = data_type;
+            glyph->bounds             = bounds;
+            glyph->advance_x          = advance_x;
+            glyph->advance_y          = advance_y;
             return m_glyphs[msb][lsb] = glyph;
         }
 
     private:
-        pod_allocator   m_allocator;
+        block_allocator m_allocator;
         glyph_cache**   m_glyphs[256];
         char*           m_font_signature;
     };
@@ -135,14 +139,14 @@ namespace agg
             unsigned i;
             for(i = 0; i < m_num_fonts; ++i)
             {
-                delete m_fonts[i];
+                obj_allocator<font_cache>::deallocate(m_fonts[i]);
             }
-            delete [] m_fonts;
+            pod_allocator<font_cache*>::deallocate(m_fonts, m_max_fonts);
         }
 
         //--------------------------------------------------------------------
         font_cache_pool(unsigned max_fonts=32) : 
-            m_fonts(new font_cache* [max_fonts]),
+            m_fonts(pod_allocator<font_cache*>::allocate(max_fonts)),
             m_max_fonts(max_fonts),
             m_num_fonts(0),
             m_cur_font(0)
@@ -157,8 +161,9 @@ namespace agg
             {
                 if(reset_cache)
                 {
-                    delete m_fonts[idx];
-                    m_fonts[idx] = new font_cache(font_signature);
+                    obj_allocator<font_cache>::deallocate(m_fonts[idx]);
+                    m_fonts[idx] = obj_allocator<font_cache>::allocate();
+                    m_fonts[idx]->signature(font_signature);
                 }
                 m_cur_font = m_fonts[idx];
             }
@@ -166,13 +171,14 @@ namespace agg
             {
                 if(m_num_fonts >= m_max_fonts)
                 {
-                    delete m_fonts[0];
+                    obj_allocator<font_cache>::deallocate(m_fonts[0]);
                     memcpy(m_fonts, 
                            m_fonts + 1, 
                            (m_max_fonts - 1) * sizeof(font_cache*));
                     m_num_fonts = m_max_fonts - 1;
                 }
-                m_fonts[m_num_fonts] = new font_cache(font_signature);
+                m_fonts[m_num_fonts] = obj_allocator<font_cache>::allocate();
+                m_fonts[m_num_fonts]->signature(font_signature);
                 m_cur_font = m_fonts[m_num_fonts];
                 ++m_num_fonts;
             }
@@ -196,7 +202,7 @@ namespace agg
                                  unsigned        glyph_index,
                                  unsigned        data_size,
                                  glyph_data_type data_type,
-                                 const rect&     bounds,
+                                 const rect_i&   bounds,
                                  double          advance_x,
                                  double          advance_y)
         {
@@ -270,6 +276,12 @@ namespace agg
         {}
 
         //--------------------------------------------------------------------
+        void reset_last_glyph()
+        {
+            m_prev_glyph = m_last_glyph = 0;
+        }
+
+        //--------------------------------------------------------------------
         const glyph_cache* glyph(unsigned glyph_code)
         {
             synchronize();

Modified: incubator/ooo/trunk/main/agg/inc/agg_gamma_functions.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/agg/inc/agg_gamma_functions.h?rev=1184758&r1=1184757&r2=1184758&view=diff
==============================================================================
--- incubator/ooo/trunk/main/agg/inc/agg_gamma_functions.h (original)
+++ incubator/ooo/trunk/main/agg/inc/agg_gamma_functions.h Sun Oct 16 04:13:16 2011
@@ -1,5 +1,5 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
 //
 // Permission to copy, use, modify, sell and distribute this software 

Modified: incubator/ooo/trunk/main/agg/inc/agg_gamma_lut.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/agg/inc/agg_gamma_lut.h?rev=1184758&r1=1184757&r2=1184758&view=diff
==============================================================================
--- incubator/ooo/trunk/main/agg/inc/agg_gamma_lut.h (original)
+++ incubator/ooo/trunk/main/agg/inc/agg_gamma_lut.h Sun Oct 16 04:13:16 2011
@@ -1,5 +1,5 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
 //
 // Permission to copy, use, modify, sell and distribute this software 
@@ -27,14 +27,16 @@ namespace agg
              unsigned HiResShift=8> class gamma_lut
     {
     public:
-        enum
+        typedef gamma_lut<LoResT, HiResT, GammaShift, HiResShift> self_type;
+
+        enum gamma_scale_e
         {
             gamma_shift = GammaShift,
             gamma_size  = 1 << gamma_shift,
             gamma_mask  = gamma_size - 1
         };
 
-        enum
+        enum hi_res_scale_e
         {
             hi_res_shift = HiResShift,
             hi_res_size  = 1 << hi_res_shift,
@@ -43,14 +45,14 @@ namespace agg
 
         ~gamma_lut()
         {
-            delete [] m_inv_gamma;
-            delete [] m_dir_gamma;
+            pod_allocator<LoResT>::deallocate(m_inv_gamma, hi_res_size);
+            pod_allocator<HiResT>::deallocate(m_dir_gamma, gamma_size);
         }
 
         gamma_lut() : 
             m_gamma(1.0), 
-            m_dir_gamma(new HiResT[gamma_size]),
-            m_inv_gamma(new LoResT[hi_res_size])
+            m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)),
+            m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size))
         {
             unsigned i;
             for(i = 0; i < gamma_size; i++)
@@ -66,8 +68,8 @@ namespace agg
 
         gamma_lut(double g) :
             m_gamma(1.0), 
-            m_dir_gamma(new HiResT[gamma_size]),
-            m_inv_gamma(new LoResT[hi_res_size])
+            m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)),
+            m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size))
         {
             gamma(g);
         }
@@ -79,13 +81,15 @@ namespace agg
             unsigned i;
             for(i = 0; i < gamma_size; i++)
             {
-                m_dir_gamma[i] = (HiResT)(pow(double(i) / double(gamma_mask), m_gamma) * double(hi_res_mask) + 0.5);
+                m_dir_gamma[i] = (HiResT)
+                    uround(pow(i / double(gamma_mask), m_gamma) * double(hi_res_mask));
             }
 
             double inv_g = 1.0 / g;
             for(i = 0; i < hi_res_size; i++)
             {
-                m_inv_gamma[i] = (LoResT)(pow(double(i) / double(hi_res_mask), inv_g) * double(gamma_mask) + 0.5);
+                m_inv_gamma[i] = (LoResT)
+                    uround(pow(i / double(hi_res_mask), inv_g) * double(gamma_mask));
             }
         }
 
@@ -105,6 +109,9 @@ namespace agg
         }
 
     private:
+        gamma_lut(const self_type&);
+        const self_type& operator = (const self_type&);
+
         double m_gamma;
         HiResT* m_dir_gamma;
         LoResT* m_inv_gamma;

Modified: incubator/ooo/trunk/main/agg/inc/agg_glyph_raster_bin.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/agg/inc/agg_glyph_raster_bin.h?rev=1184758&r1=1184757&r2=1184758&view=diff
==============================================================================
--- incubator/ooo/trunk/main/agg/inc/agg_glyph_raster_bin.h (original)
+++ incubator/ooo/trunk/main/agg/inc/agg_glyph_raster_bin.h Sun Oct 16 04:13:16 2011
@@ -1,5 +1,5 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
 //
 // Permission to copy, use, modify, sell and distribute this software 

Modified: incubator/ooo/trunk/main/agg/inc/agg_gsv_text.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/agg/inc/agg_gsv_text.h?rev=1184758&r1=1184757&r2=1184758&view=diff
==============================================================================
--- incubator/ooo/trunk/main/agg/inc/agg_gsv_text.h (original)
+++ incubator/ooo/trunk/main/agg/inc/agg_gsv_text.h Sun Oct 16 04:13:16 2011
@@ -1,5 +1,5 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
 //
 // Permission to copy, use, modify, sell and distribute this software 
@@ -20,7 +20,7 @@
 #ifndef AGG_GSV_TEXT_INCLUDED
 #define AGG_GSV_TEXT_INCLUDED
 
-#include "agg_basics.h"
+#include "agg_array.h"
 #include "agg_conv_stroke.h"
 #include "agg_conv_transform.h"
 
@@ -43,7 +43,6 @@ namespace agg
         };
 
     public:
-        ~gsv_text();
         gsv_text();
 
         void font(const void* font);
@@ -54,8 +53,10 @@ namespace agg
         void line_space(double line_space);
         void start_point(double x, double y);
         void text(const char* text);
+        
+        double text_width();
 
-        void rewind(unsigned id);
+        void rewind(unsigned path_id);
         unsigned vertex(double* x, double* y);
 
     private:
@@ -80,30 +81,28 @@ namespace agg
         }
 
     private:
-        double      m_x;
-        double      m_y;
-        double      m_start_x;
-        double      m_width;
-        double      m_height;
-        double      m_space;
-        double      m_line_space;
-        char        m_chr[2];
-        char*       m_text;
-        char*       m_text_buf;
-        unsigned    m_buf_size;
-        char*       m_cur_chr;
-        const void* m_font;
-        char*       m_loaded_font;
-        status      m_status;
-        bool        m_big_endian;
-        bool        m_flip;
-
-        int8u*      m_indices;
-        int8*       m_glyphs;
-        int8*       m_bglyph;
-        int8*       m_eglyph;
-        double      m_w;
-        double      m_h;
+        double          m_x;
+        double          m_y;
+        double          m_start_x;
+        double          m_width;
+        double          m_height;
+        double          m_space;
+        double          m_line_space;
+        char            m_chr[2];
+        char*           m_text;
+        pod_array<char> m_text_buf;
+        char*           m_cur_chr;
+        const void*     m_font;
+        pod_array<char> m_loaded_font;
+        status          m_status;
+        bool            m_big_endian;
+        bool            m_flip;
+        int8u*          m_indices;
+        int8*           m_glyphs;
+        int8*           m_bglyph;
+        int8*           m_eglyph;
+        double          m_w;
+        double          m_h;
     };
 
 
@@ -129,9 +128,9 @@ namespace agg
             m_trans->transformer(trans);
         }
 
-        void rewind(unsigned id) 
+        void rewind(unsigned path_id) 
         { 
-            m_trans.rewind(id); 
+            m_trans.rewind(path_id); 
             m_polyline.line_join(round_join);
             m_polyline.line_cap(round_cap);
         }

Added: incubator/ooo/trunk/main/agg/inc/agg_image_accessors.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/agg/inc/agg_image_accessors.h?rev=1184758&view=auto
==============================================================================
--- incubator/ooo/trunk/main/agg/inc/agg_image_accessors.h (added)
+++ incubator/ooo/trunk/main/agg/inc/agg_image_accessors.h Sun Oct 16 04:13:16 2011
@@ -0,0 +1,481 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software 
+// is granted provided this copyright notice appears in all copies. 
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+//          mcseemagg@yahoo.com
+//          http://www.antigrain.com
+//----------------------------------------------------------------------------
+
+#ifndef AGG_IMAGE_ACCESSORS_INCLUDED
+#define AGG_IMAGE_ACCESSORS_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+
+    //-----------------------------------------------------image_accessor_clip
+    template<class PixFmt> class image_accessor_clip
+    {
+    public:
+        typedef PixFmt   pixfmt_type;
+        typedef typename pixfmt_type::color_type color_type;
+        typedef typename pixfmt_type::order_type order_type;
+        typedef typename pixfmt_type::value_type value_type;
+        enum pix_width_e { pix_width = pixfmt_type::pix_width };
+
+        image_accessor_clip() {}
+        explicit image_accessor_clip(const pixfmt_type& pixf, 
+                                     const color_type& bk) : 
+            m_pixf(&pixf)
+        {
+            pixfmt_type::make_pix(m_bk_buf, bk);
+        }
+
+        void attach(const pixfmt_type& pixf)
+        {
+            m_pixf = &pixf;
+        }
+
+        void background_color(const color_type& bk)
+        {
+            pixfmt_type::make_pix(m_bk_buf, bk);
+        }
+
+    private:
+        AGG_INLINE const int8u* pixel() const
+        {
+            if(m_y >= 0 && m_y < (int)m_pixf->height() &&
+               m_x >= 0 && m_x < (int)m_pixf->width())
+            {
+                return m_pixf->pix_ptr(m_x, m_y);
+            }
+            return m_bk_buf;
+        }
+
+    public:
+        AGG_INLINE const int8u* span(int x, int y, unsigned len)
+        {
+            m_x = m_x0 = x;
+            m_y = y;
+            if(y >= 0 && y < (int)m_pixf->height() &&
+               x >= 0 && x+(int)len <= (int)m_pixf->width())
+            {
+                return m_pix_ptr = m_pixf->pix_ptr(x, y);
+            }
+            m_pix_ptr = 0;
+            return pixel();
+        }
+
+        AGG_INLINE const int8u* next_x()
+        {
+            if(m_pix_ptr) return m_pix_ptr += pix_width;
+            ++m_x;
+            return pixel();
+        }
+
+        AGG_INLINE const int8u* next_y()
+        {
+            ++m_y;
+            m_x = m_x0;
+            if(m_pix_ptr && 
+               m_y >= 0 && m_y < (int)m_pixf->height())
+            {
+                return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
+            }
+            m_pix_ptr = 0;
+            return pixel();
+        }
+
+    private:
+        const pixfmt_type* m_pixf;
+        int8u              m_bk_buf[4];
+        int                m_x, m_x0, m_y;
+        const int8u*       m_pix_ptr;
+    };
+
+
+
+
+    //--------------------------------------------------image_accessor_no_clip
+    template<class PixFmt> class image_accessor_no_clip
+    {
+    public:
+        typedef PixFmt   pixfmt_type;
+        typedef typename pixfmt_type::color_type color_type;
+        typedef typename pixfmt_type::order_type order_type;
+        typedef typename pixfmt_type::value_type value_type;
+        enum pix_width_e { pix_width = pixfmt_type::pix_width };
+
+        image_accessor_no_clip() {}
+        explicit image_accessor_no_clip(const pixfmt_type& pixf) : 
+            m_pixf(&pixf) 
+        {}
+
+        void attach(const pixfmt_type& pixf)
+        {
+            m_pixf = &pixf;
+        }
+
+        AGG_INLINE const int8u* span(int x, int y, unsigned)
+        {
+            m_x = x;
+            m_y = y;
+            return m_pix_ptr = m_pixf->pix_ptr(x, y);
+        }
+
+        AGG_INLINE const int8u* next_x()
+        {
+            return m_pix_ptr += pix_width;
+        }
+
+        AGG_INLINE const int8u* next_y()
+        {
+            ++m_y;
+            return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
+        }
+
+    private:
+        const pixfmt_type* m_pixf;
+        int                m_x, m_y;
+        const int8u*       m_pix_ptr;
+    };
+
+
+
+
+    //----------------------------------------------------image_accessor_clone
+    template<class PixFmt> class image_accessor_clone
+    {
+    public:
+        typedef PixFmt   pixfmt_type;
+        typedef typename pixfmt_type::color_type color_type;
+        typedef typename pixfmt_type::order_type order_type;
+        typedef typename pixfmt_type::value_type value_type;
+        enum pix_width_e { pix_width = pixfmt_type::pix_width };
+
+        image_accessor_clone() {}
+        explicit image_accessor_clone(const pixfmt_type& pixf) : 
+            m_pixf(&pixf) 
+        {}
+
+        void attach(const pixfmt_type& pixf)
+        {
+            m_pixf = &pixf;
+        }
+
+    private:
+        AGG_INLINE const int8u* pixel() const
+        {
+            register int x = m_x;
+            register int y = m_y;
+            if(x < 0) x = 0;
+            if(y < 0) y = 0;
+            if(x >= (int)m_pixf->width())  x = m_pixf->width() - 1;
+            if(y >= (int)m_pixf->height()) y = m_pixf->height() - 1;
+            return m_pixf->pix_ptr(x, y);
+        }
+
+    public:
+        AGG_INLINE const int8u* span(int x, int y, unsigned len)
+        {
+            m_x = m_x0 = x;
+            m_y = y;
+            if(y >= 0 && y < (int)m_pixf->height() &&
+               x >= 0 && x+len <= (int)m_pixf->width())
+            {
+                return m_pix_ptr = m_pixf->pix_ptr(x, y);
+            }
+            m_pix_ptr = 0;
+            return pixel();
+        }
+
+        AGG_INLINE const int8u* next_x()
+        {
+            if(m_pix_ptr) return m_pix_ptr += pix_width;
+            ++m_x;
+            return pixel();
+        }
+
+        AGG_INLINE const int8u* next_y()
+        {
+            ++m_y;
+            m_x = m_x0;
+            if(m_pix_ptr && 
+               m_y >= 0 && m_y < (int)m_pixf->height())
+            {
+                return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
+            }
+            m_pix_ptr = 0;
+            return pixel();
+        }
+
+    private:
+        const pixfmt_type* m_pixf;
+        int                m_x, m_x0, m_y;
+        const int8u*       m_pix_ptr;
+    };
+
+
+
+
+
+    //-----------------------------------------------------image_accessor_wrap
+    template<class PixFmt, class WrapX, class WrapY> class image_accessor_wrap
+    {
+    public:
+        typedef PixFmt   pixfmt_type;
+        typedef typename pixfmt_type::color_type color_type;
+        typedef typename pixfmt_type::order_type order_type;
+        typedef typename pixfmt_type::value_type value_type;
+        enum pix_width_e { pix_width = pixfmt_type::pix_width };
+
+        image_accessor_wrap() {}
+        explicit image_accessor_wrap(const pixfmt_type& pixf) : 
+            m_pixf(&pixf), 
+            m_wrap_x(pixf.width()), 
+            m_wrap_y(pixf.height())
+        {}
+
+        void attach(const pixfmt_type& pixf)
+        {
+            m_pixf = &pixf;
+        }
+
+        AGG_INLINE const int8u* span(int x, int y, unsigned)
+        {
+            m_x = x;
+            m_row_ptr = m_pixf->row_ptr(m_wrap_y(y));
+            return m_row_ptr + m_wrap_x(x) * pix_width;
+        }
+
+        AGG_INLINE const int8u* next_x()
+        {
+            int x = ++m_wrap_x;
+            return m_row_ptr + x * pix_width;
+        }
+
+        AGG_INLINE const int8u* next_y()
+        {
+            m_row_ptr = m_pixf->row_ptr(++m_wrap_y);
+            return m_row_ptr + m_wrap_x(m_x) * pix_width;
+        }
+
+    private:
+        const pixfmt_type* m_pixf;
+        const int8u*       m_row_ptr;
+        int                m_x;
+        WrapX              m_wrap_x;
+        WrapY              m_wrap_y;
+    };
+
+
+
+
+    //--------------------------------------------------------wrap_mode_repeat
+    class wrap_mode_repeat
+    {
+    public:
+        wrap_mode_repeat() {}
+        wrap_mode_repeat(unsigned size) : 
+            m_size(size), 
+            m_add(size * (0x3FFFFFFF / size)),
+            m_value(0)
+        {}
+
+        AGG_INLINE unsigned operator() (int v)
+        { 
+            return m_value = (unsigned(v) + m_add) % m_size; 
+        }
+
+        AGG_INLINE unsigned operator++ ()
+        {
+            ++m_value;
+            if(m_value >= m_size) m_value = 0;
+            return m_value;
+        }
+    private:
+        unsigned m_size;
+        unsigned m_add;
+        unsigned m_value;
+    };
+
+
+    //---------------------------------------------------wrap_mode_repeat_pow2
+    class wrap_mode_repeat_pow2
+    {
+    public:
+        wrap_mode_repeat_pow2() {}
+        wrap_mode_repeat_pow2(unsigned size) : m_value(0)
+        {
+            m_mask = 1;
+            while(m_mask < size) m_mask = (m_mask << 1) | 1;
+            m_mask >>= 1;
+        }
+        AGG_INLINE unsigned operator() (int v)
+        { 
+            return m_value = unsigned(v) & m_mask;
+        }
+        AGG_INLINE unsigned operator++ ()
+        {
+            ++m_value;
+            if(m_value > m_mask) m_value = 0;
+            return m_value;
+        }
+    private:
+        unsigned m_mask;
+        unsigned m_value;
+    };
+
+
+    //----------------------------------------------wrap_mode_repeat_auto_pow2
+    class wrap_mode_repeat_auto_pow2
+    {
+    public:
+        wrap_mode_repeat_auto_pow2() {}
+        wrap_mode_repeat_auto_pow2(unsigned size) :
+            m_size(size),
+            m_add(size * (0x3FFFFFFF / size)),
+            m_mask((m_size & (m_size-1)) ? 0 : m_size-1),
+            m_value(0)
+        {}
+
+        AGG_INLINE unsigned operator() (int v) 
+        { 
+            if(m_mask) return m_value = unsigned(v) & m_mask;
+            return m_value = (unsigned(v) + m_add) % m_size;
+        }
+        AGG_INLINE unsigned operator++ ()
+        {
+            ++m_value;
+            if(m_value >= m_size) m_value = 0;
+            return m_value;
+        }
+
+    private:
+        unsigned m_size;
+        unsigned m_add;
+        unsigned m_mask;
+        unsigned m_value;
+    };
+
+
+    //-------------------------------------------------------wrap_mode_reflect
+    class wrap_mode_reflect
+    {
+    public:
+        wrap_mode_reflect() {}
+        wrap_mode_reflect(unsigned size) : 
+            m_size(size), 
+            m_size2(size * 2),
+            m_add(m_size2 * (0x3FFFFFFF / m_size2)),
+            m_value(0)
+        {}
+
+        AGG_INLINE unsigned operator() (int v)
+        { 
+            m_value = (unsigned(v) + m_add) % m_size2;
+            if(m_value >= m_size) return m_size2 - m_value - 1;
+            return m_value;
+        }
+
+        AGG_INLINE unsigned operator++ ()
+        {
+            ++m_value;
+            if(m_value >= m_size2) m_value = 0;
+            if(m_value >= m_size) return m_size2 - m_value - 1;
+            return m_value;
+        }
+    private:
+        unsigned m_size;
+        unsigned m_size2;
+        unsigned m_add;
+        unsigned m_value;
+    };
+
+
+
+    //--------------------------------------------------wrap_mode_reflect_pow2
+    class wrap_mode_reflect_pow2
+    {
+    public:
+        wrap_mode_reflect_pow2() {}
+        wrap_mode_reflect_pow2(unsigned size) : m_value(0)
+        {
+            m_mask = 1;
+            m_size = 1;
+            while(m_mask < size) 
+            {
+                m_mask = (m_mask << 1) | 1;
+                m_size <<= 1;
+            }
+        }
+        AGG_INLINE unsigned operator() (int v)
+        { 
+            m_value = unsigned(v) & m_mask;
+            if(m_value >= m_size) return m_mask - m_value;
+            return m_value;
+        }
+        AGG_INLINE unsigned operator++ ()
+        {
+            ++m_value;
+            m_value &= m_mask;
+            if(m_value >= m_size) return m_mask - m_value;
+            return m_value;
+        }
+    private:
+        unsigned m_size;
+        unsigned m_mask;
+        unsigned m_value;
+    };
+
+
+
+    //---------------------------------------------wrap_mode_reflect_auto_pow2
+    class wrap_mode_reflect_auto_pow2
+    {
+    public:
+        wrap_mode_reflect_auto_pow2() {}
+        wrap_mode_reflect_auto_pow2(unsigned size) :
+            m_size(size),
+            m_size2(size * 2),
+            m_add(m_size2 * (0x3FFFFFFF / m_size2)),
+            m_mask((m_size2 & (m_size2-1)) ? 0 : m_size2-1),
+            m_value(0)
+        {}
+
+        AGG_INLINE unsigned operator() (int v) 
+        { 
+            m_value = m_mask ? unsigned(v) & m_mask : 
+                              (unsigned(v) + m_add) % m_size2;
+            if(m_value >= m_size) return m_size2 - m_value - 1;
+            return m_value;            
+        }
+        AGG_INLINE unsigned operator++ ()
+        {
+            ++m_value;
+            if(m_value >= m_size2) m_value = 0;
+            if(m_value >= m_size) return m_size2 - m_value - 1;
+            return m_value;
+        }
+
+    private:
+        unsigned m_size;
+        unsigned m_size2;
+        unsigned m_add;
+        unsigned m_mask;
+        unsigned m_value;
+    };
+
+
+}
+
+
+#endif

Modified: incubator/ooo/trunk/main/agg/inc/agg_image_filters.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/agg/inc/agg_image_filters.h?rev=1184758&r1=1184757&r2=1184758&view=diff
==============================================================================
--- incubator/ooo/trunk/main/agg/inc/agg_image_filters.h (original)
+++ incubator/ooo/trunk/main/agg/inc/agg_image_filters.h Sun Oct 16 04:13:16 2011
@@ -1,5 +1,5 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
 //
 // Permission to copy, use, modify, sell and distribute this software 
@@ -20,23 +20,26 @@
 #ifndef AGG_IMAGE_FILTERS_INCLUDED
 #define AGG_IMAGE_FILTERS_INCLUDED
 
-#include <math.h>
-#include "agg_basics.h"
+#include "agg_array.h"
+#include "agg_math.h"
 
 namespace agg
 {
 
     // See Implementation agg_image_filters.cpp 
 
-    enum
+    enum image_filter_scale_e
     {
         image_filter_shift = 14,                      //----image_filter_shift
-        image_filter_size  = 1 << image_filter_shift, //----image_filter_size 
-        image_filter_mask  = image_filter_size - 1,   //----image_filter_mask 
+        image_filter_scale = 1 << image_filter_shift, //----image_filter_scale 
+        image_filter_mask  = image_filter_scale - 1   //----image_filter_mask 
+    };
 
+    enum image_subpixel_scale_e
+    {
         image_subpixel_shift = 8,                         //----image_subpixel_shift
-        image_subpixel_size  = 1 << image_subpixel_shift, //----image_subpixel_size 
-        image_subpixel_mask  = image_subpixel_size - 1    //----image_subpixel_mask 
+        image_subpixel_scale = 1 << image_subpixel_shift, //----image_subpixel_scale 
+        image_subpixel_mask  = image_subpixel_scale - 1   //----image_subpixel_mask 
     };
 
 
@@ -44,22 +47,19 @@ namespace agg
     class image_filter_lut
     {
     public:
-        ~image_filter_lut();
-        image_filter_lut();
-
         template<class FilterF> void calculate(const FilterF& filter,
                                                bool normalization=true)
         {
             double r = filter.radius();
-            realloc(r);
+            realloc_lut(r);
             unsigned i;
             unsigned pivot = diameter() << (image_subpixel_shift - 1);
             for(i = 0; i < pivot; i++)
             {
-                double x = double(i) / double(image_subpixel_size);
+                double x = double(i) / double(image_subpixel_scale);
                 double y = filter.calc_weight(x);
                 m_weight_array[pivot + i] = 
-                m_weight_array[pivot - i] = int16(y * image_filter_size + 0.5);
+                m_weight_array[pivot - i] = (int16)iround(y * image_filter_scale);
             }
             unsigned end = (diameter() << image_subpixel_shift) - 1;
             m_weight_array[0] = m_weight_array[end];
@@ -69,30 +69,29 @@ namespace agg
             }
         }
 
+        image_filter_lut() : m_radius(0), m_diameter(0), m_start(0) {}
+
         template<class FilterF> image_filter_lut(const FilterF& filter, 
-                                                 bool normalization=true) : 
-            m_weight_array(0),
-            m_max_size(0)
+                                                 bool normalization=true)
         {
             calculate(filter, normalization);
         }
 
-        double       radius()       const { return m_radius;       }
-        unsigned     diameter()     const { return m_diameter;     }
-        int          start()        const { return m_start;        }
-        const int16* weight_array() const { return m_weight_array; }
+        double       radius()       const { return m_radius;   }
+        unsigned     diameter()     const { return m_diameter; }
+        int          start()        const { return m_start;    }
+        const int16* weight_array() const { return &m_weight_array[0]; }
         void         normalize();
 
     private:
-        void realloc(double radius);
+        void realloc_lut(double radius);
         image_filter_lut(const image_filter_lut&);
         const image_filter_lut& operator = (const image_filter_lut&);
 
-        double   m_radius;
-        unsigned m_diameter;
-        int      m_start;
-        int16*   m_weight_array;
-        unsigned m_max_size;
+        double           m_radius;
+        unsigned         m_diameter;
+        int              m_start;
+        pod_array<int16> m_weight_array;
     };
 
 
@@ -312,7 +311,7 @@ namespace agg
         static double radius() { return 3.2383; } 
         static double calc_weight(double x)
         {
-            return (x == 0.0) ? pi / 4.0 : j1(pi * x) / (2.0 * x);
+            return (x == 0.0) ? pi / 4.0 : besj(pi * x, 1) / (2.0 * x);
         }
     };
 

Modified: incubator/ooo/trunk/main/agg/inc/agg_line_aa_basics.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/agg/inc/agg_line_aa_basics.h?rev=1184758&r1=1184757&r2=1184758&view=diff
==============================================================================
--- incubator/ooo/trunk/main/agg/inc/agg_line_aa_basics.h (original)
+++ incubator/ooo/trunk/main/agg/inc/agg_line_aa_basics.h Sun Oct 16 04:13:16 2011
@@ -1,5 +1,5 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
 //
 // Permission to copy, use, modify, sell and distribute this software 
@@ -24,44 +24,58 @@ namespace agg
     // See Implementation agg_line_aa_basics.cpp 
 
     //-------------------------------------------------------------------------
-    enum
+    enum line_subpixel_scale_e
     {
-        line_subpixel_shift = 8,                        //----line_subpixel_shift
-        line_subpixel_size  = 1 << line_subpixel_shift, //----line_subpixel_size 
-        line_subpixel_mask  = line_subpixel_size - 1    //----line_subpixel_mask 
+        line_subpixel_shift = 8,                          //----line_subpixel_shift
+        line_subpixel_scale  = 1 << line_subpixel_shift,  //----line_subpixel_scale
+        line_subpixel_mask  = line_subpixel_scale - 1,    //----line_subpixel_mask
+        line_max_coord      = (1 << 28) - 1,              //----line_max_coord
+        line_max_length = 1 << (line_subpixel_shift + 10) //----line_max_length
     };
 
     //-------------------------------------------------------------------------
-    enum
+    enum line_mr_subpixel_scale_e
     {
         line_mr_subpixel_shift = 4,                           //----line_mr_subpixel_shift
-        line_mr_subpixel_size  = 1 << line_mr_subpixel_shift, //----line_mr_subpixel_size 
-        line_mr_subpixel_mask  = line_mr_subpixel_size - 1    //----line_mr_subpixel_mask 
+        line_mr_subpixel_scale = 1 << line_mr_subpixel_shift, //----line_mr_subpixel_scale 
+        line_mr_subpixel_mask  = line_mr_subpixel_scale - 1   //----line_mr_subpixel_mask 
     };
 
     //------------------------------------------------------------------line_mr
-    inline int line_mr(int x) 
+    AGG_INLINE int line_mr(int x) 
     { 
-        return x >> ((int)line_subpixel_shift - (int)line_mr_subpixel_shift); 
+        return x >> (line_subpixel_shift - line_mr_subpixel_shift); 
     }
 
     //-------------------------------------------------------------------line_hr
-    inline int line_hr(int x) 
+    AGG_INLINE int line_hr(int x) 
     { 
-        return x << ((int)line_subpixel_shift - (int)line_mr_subpixel_shift); 
+        return x << (line_subpixel_shift - line_mr_subpixel_shift); 
     }
 
     //---------------------------------------------------------------line_dbl_hr
-    inline int line_dbl_hr(int x) 
+    AGG_INLINE int line_dbl_hr(int x) 
     { 
         return x << line_subpixel_shift;
     }
 
     //---------------------------------------------------------------line_coord
-    inline int line_coord(double x)
+    struct line_coord
     {
-        return int(x * line_subpixel_size);
-    }
+        AGG_INLINE static int conv(double x)
+        {
+            return iround(x * line_subpixel_scale);
+        }
+    };
+
+    //-----------------------------------------------------------line_coord_sat
+    struct line_coord_sat
+    {
+        AGG_INLINE static int conv(double x)
+        {
+            return saturation<line_max_coord>::iround(x * line_subpixel_scale);
+        }
+    };
 
     //==========================================================line_parameters
     struct line_parameters
@@ -96,6 +110,29 @@ namespace agg
         {
             return s_diagonal_quadrant[octant] == s_diagonal_quadrant[lp.octant];
         }
+
+        //---------------------------------------------------------------------
+        void divide(line_parameters& lp1, line_parameters& lp2) const
+        {
+            int xmid = (x1 + x2) >> 1;
+            int ymid = (y1 + y2) >> 1;
+            int len2 = len >> 1;
+
+            lp1 = *this;
+            lp2 = *this;
+
+            lp1.x2  = xmid;
+            lp1.y2  = ymid;
+            lp1.len = len2;
+            lp1.dx  = abs(lp1.x2 - lp1.x1);
+            lp1.dy  = abs(lp1.y2 - lp1.y1);
+
+            lp2.x1  = xmid;
+            lp2.y1  = ymid;
+            lp2.len = len2;
+            lp2.dx  = abs(lp2.x2 - lp2.x1);
+            lp2.dy  = abs(lp2.y2 - lp2.y1);
+        }
         
         //---------------------------------------------------------------------
         int x1, y1, x2, y2, dx, dy, sx, sy;
@@ -105,8 +142,8 @@ namespace agg
         int octant;
 
         //---------------------------------------------------------------------
-        static int8u s_orthogonal_quadrant[8];
-        static int8u s_diagonal_quadrant[8];
+        static const int8u s_orthogonal_quadrant[8];
+        static const int8u s_diagonal_quadrant[8];
     };
 
 
@@ -123,9 +160,9 @@ namespace agg
     void inline fix_degenerate_bisectrix_start(const line_parameters& lp, 
                                                int* x, int* y)
     {
-        int d = int((double(*x - lp.x2) * double(lp.y2 - lp.y1) - 
-                     double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
-        if(d < line_subpixel_size)
+        int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) - 
+                        double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
+        if(d < line_subpixel_scale/2)
         {
             *x = lp.x1 + (lp.y2 - lp.y1);
             *y = lp.y1 - (lp.x2 - lp.x1);
@@ -137,9 +174,9 @@ namespace agg
     void inline fix_degenerate_bisectrix_end(const line_parameters& lp, 
                                              int* x, int* y)
     {
-        int d = int((double(*x - lp.x2) * double(lp.y2 - lp.y1) - 
-                     double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
-        if(d < line_subpixel_size)
+        int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) - 
+                        double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
+        if(d < line_subpixel_scale/2)
         {
             *x = lp.x2 + (lp.y2 - lp.y1);
             *y = lp.y2 - (lp.x2 - lp.x1);

Modified: incubator/ooo/trunk/main/agg/inc/agg_math.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/agg/inc/agg_math.h?rev=1184758&r1=1184757&r2=1184758&view=diff
==============================================================================
--- incubator/ooo/trunk/main/agg/inc/agg_math.h (original)
+++ incubator/ooo/trunk/main/agg/inc/agg_math.h Sun Oct 16 04:13:16 2011
@@ -1,5 +1,5 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
 //
 // Permission to copy, use, modify, sell and distribute this software 
@@ -12,6 +12,9 @@
 //          mcseemagg@yahoo.com
 //          http://www.antigrain.com
 //----------------------------------------------------------------------------
+// Bessel function (besj) was adapted for use in AGG library by Andy Wilk 
+// Contact: castor.vulgaris@gmail.com
+//----------------------------------------------------------------------------
 
 #ifndef AGG_MATH_INCLUDED
 #define AGG_MATH_INCLUDED
@@ -22,30 +25,34 @@
 namespace agg
 {
 
-    const double intersection_epsilon = 1.0e-8;
-
-    //------------------------------------------------------calc_point_location
-    AGG_INLINE double calc_point_location(double x1, double y1, 
-                                          double x2, double y2, 
-                                          double x,  double y)
+    //------------------------------------------------------vertex_dist_epsilon
+    // Coinciding points maximal distance (Epsilon)
+    const double vertex_dist_epsilon = 1e-14;
+
+    //-----------------------------------------------------intersection_epsilon
+    // See calc_intersection
+    const double intersection_epsilon = 1.0e-30;
+
+    //------------------------------------------------------------cross_product
+    AGG_INLINE double cross_product(double x1, double y1, 
+                                    double x2, double y2, 
+                                    double x,  double y)
     {
         return (x - x2) * (y2 - y1) - (y - y2) * (x2 - x1);
     }
 
-
     //--------------------------------------------------------point_in_triangle
     AGG_INLINE bool point_in_triangle(double x1, double y1, 
                                       double x2, double y2, 
                                       double x3, double y3, 
                                       double x,  double y)
     {
-        bool cp1 = calc_point_location(x1, y1, x2, y2, x, y) < 0.0;
-        bool cp2 = calc_point_location(x2, y2, x3, y3, x, y) < 0.0;
-        bool cp3 = calc_point_location(x3, y3, x1, y1, x, y) < 0.0;
+        bool cp1 = cross_product(x1, y1, x2, y2, x, y) < 0.0;
+        bool cp2 = cross_product(x2, y2, x3, y3, x, y) < 0.0;
+        bool cp3 = cross_product(x3, y3, x1, y1, x, y) < 0.0;
         return cp1 == cp2 && cp2 == cp3 && cp3 == cp1;
     }
 
-
     //-----------------------------------------------------------calc_distance
     AGG_INLINE double calc_distance(double x1, double y1, double x2, double y2)
     {
@@ -54,17 +61,76 @@ namespace agg
         return sqrt(dx * dx + dy * dy);
     }
 
+    //--------------------------------------------------------calc_sq_distance
+    AGG_INLINE double calc_sq_distance(double x1, double y1, double x2, double y2)
+    {
+        double dx = x2-x1;
+        double dy = y2-y1;
+        return dx * dx + dy * dy;
+    }
 
-    //------------------------------------------------calc_point_line_distance
-    AGG_INLINE double calc_point_line_distance(double x1, double y1, 
+    //------------------------------------------------calc_line_point_distance
+    AGG_INLINE double calc_line_point_distance(double x1, double y1, 
                                                double x2, double y2, 
                                                double x,  double y)
     {
         double dx = x2-x1;
         double dy = y2-y1;
-        return ((x - x2) * dy - (y - y2) * dx) / sqrt(dx * dx + dy * dy);
+        double d = sqrt(dx * dx + dy * dy);
+        if(d < vertex_dist_epsilon)
+        {
+            return calc_distance(x1, y1, x, y);
+        }
+        return ((x - x2) * dy - (y - y2) * dx) / d;
     }
 
+    //-------------------------------------------------------calc_line_point_u
+    AGG_INLINE double calc_segment_point_u(double x1, double y1, 
+                                           double x2, double y2, 
+                                           double x,  double y)
+    {
+        double dx = x2 - x1;
+        double dy = y2 - y1;
+
+        if(dx == 0 && dy == 0)
+        {
+	        return 0;
+        }
+
+        double pdx = x - x1;
+        double pdy = y - y1;
+
+        return (pdx * dx + pdy * dy) / (dx * dx + dy * dy);
+    }
+
+    //---------------------------------------------calc_line_point_sq_distance
+    AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1, 
+                                                     double x2, double y2, 
+                                                     double x,  double y,
+                                                     double u)
+    {
+        if(u <= 0)
+        {
+	        return calc_sq_distance(x, y, x1, y1);
+        }
+        else 
+        if(u >= 1)
+        {
+	        return calc_sq_distance(x, y, x2, y2);
+        }
+        return calc_sq_distance(x, y, x1 + u * (x2 - x1), y1 + u * (y2 - y1));
+    }
+
+    //---------------------------------------------calc_line_point_sq_distance
+    AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1, 
+                                                     double x2, double y2, 
+                                                     double x,  double y)
+    {
+        return 
+            calc_segment_point_sq_distance(
+                x1, y1, x2, y2, x, y,
+                calc_segment_point_u(x1, y1, x2, y2, x, y));
+    }
 
     //-------------------------------------------------------calc_intersection
     AGG_INLINE bool calc_intersection(double ax, double ay, double bx, double by,
@@ -80,6 +146,32 @@ namespace agg
         return true;
     }
 
+    //-----------------------------------------------------intersection_exists
+    AGG_INLINE bool intersection_exists(double x1, double y1, double x2, double y2,
+                                        double x3, double y3, double x4, double y4)
+    {
+        // It's less expensive but you can't control the 
+        // boundary conditions: Less or LessEqual
+        double dx1 = x2 - x1;
+        double dy1 = y2 - y1;
+        double dx2 = x4 - x3;
+        double dy2 = y4 - y3;
+        return ((x3 - x2) * dy1 - (y3 - y2) * dx1 < 0.0) != 
+               ((x4 - x2) * dy1 - (y4 - y2) * dx1 < 0.0) &&
+               ((x1 - x4) * dy2 - (y1 - y4) * dx2 < 0.0) !=
+               ((x2 - x4) * dy2 - (y2 - y4) * dx2 < 0.0);
+
+        // It's is more expensive but more flexible 
+        // in terms of boundary conditions.
+        //--------------------
+        //double den  = (x2-x1) * (y4-y3) - (y2-y1) * (x4-x3);
+        //if(fabs(den) < intersection_epsilon) return false;
+        //double nom1 = (x4-x3) * (y1-y3) - (y4-y3) * (x1-x3);
+        //double nom2 = (x2-x1) * (y1-y3) - (y2-y1) * (x1-x3);
+        //double ua = nom1 / den;
+        //double ub = nom2 / den;
+        //return ua >= 0.0 && ua <= 1.0 && ub >= 0.0 && ub <= 1.0;
+    }
 
     //--------------------------------------------------------calc_orthogonal
     AGG_INLINE void calc_orthogonal(double thickness,
@@ -90,11 +182,10 @@ namespace agg
         double dx = x2 - x1;
         double dy = y2 - y1;
         double d = sqrt(dx*dx + dy*dy); 
-        *x = thickness * dy / d;
-        *y = thickness * dx / d;
+        *x =  thickness * dy / d;
+        *y = -thickness * dx / d;
     }
 
-
     //--------------------------------------------------------dilate_triangle
     AGG_INLINE void dilate_triangle(double x1, double y1,
                                     double x2, double y2,
@@ -108,10 +199,10 @@ namespace agg
         double dy2=0.0; 
         double dx3=0.0;
         double dy3=0.0; 
-        double loc = calc_point_location(x1, y1, x2, y2, x3, y3);
+        double loc = cross_product(x1, y1, x2, y2, x3, y3);
         if(fabs(loc) > intersection_epsilon)
         {
-            if(calc_point_location(x1, y1, x2, y2, x3, y3) > 0.0) 
+            if(cross_product(x1, y1, x2, y2, x3, y3) > 0.0) 
             {
                 d = -d;
             }
@@ -119,12 +210,20 @@ namespace agg
             calc_orthogonal(d, x2, y2, x3, y3, &dx2, &dy2);
             calc_orthogonal(d, x3, y3, x1, y1, &dx3, &dy3);
         }
-        *x++ = x1 + dx1;  *y++ = y1 - dy1;
-        *x++ = x2 + dx1;  *y++ = y2 - dy1;
-        *x++ = x2 + dx2;  *y++ = y2 - dy2;
-        *x++ = x3 + dx2;  *y++ = y3 - dy2;
-        *x++ = x3 + dx3;  *y++ = y3 - dy3;
-        *x++ = x1 + dx3;  *y++ = y1 - dy3;
+        *x++ = x1 + dx1;  *y++ = y1 + dy1;
+        *x++ = x2 + dx1;  *y++ = y2 + dy1;
+        *x++ = x2 + dx2;  *y++ = y2 + dy2;
+        *x++ = x3 + dx2;  *y++ = y3 + dy2;
+        *x++ = x3 + dx3;  *y++ = y3 + dy3;
+        *x++ = x1 + dx3;  *y++ = y1 + dy3;
+    }
+
+    //------------------------------------------------------calc_triangle_area
+    AGG_INLINE double calc_triangle_area(double x1, double y1,
+                                         double x2, double y2,
+                                         double x3, double y3)
+    {
+        return (x1*y2 - x2*y1 + x2*y3 - x3*y2 + x3*y1 - x1*y3) * 0.5;
     }
 
     //-------------------------------------------------------calc_polygon_area
@@ -223,7 +322,7 @@ namespace agg
             }
         }
 
-        //This is calculation sqrt itself.
+        //This code calculates the sqrt.
         bit -= 9;
         if(bit > 0)
         {
@@ -241,6 +340,97 @@ namespace agg
 
 
 
+    //--------------------------------------------------------------------besj
+    // Function BESJ calculates Bessel function of first kind of order n
+    // Arguments:
+    //     n - an integer (>=0), the order
+    //     x - value at which the Bessel function is required
+    //--------------------
+    // C++ Mathematical Library
+    // Convereted from equivalent FORTRAN library
+    // Converetd by Gareth Walker for use by course 392 computational project
+    // All functions tested and yield the same results as the corresponding
+    // FORTRAN versions.
+    //
+    // If you have any problems using these functions please report them to
+    // M.Muldoon@UMIST.ac.uk
+    //
+    // Documentation available on the web
+    // http://www.ma.umist.ac.uk/mrm/Teaching/392/libs/392.html
+    // Version 1.0   8/98
+    // 29 October, 1999
+    //--------------------
+    // Adapted for use in AGG library by Andy Wilk (castor.vulgaris@gmail.com)
+    //------------------------------------------------------------------------
+    inline double besj(double x, int n)
+    {
+        if(n < 0)
+        {
+            return 0;
+        }
+        double d = 1E-6;
+        double b = 0;
+        if(fabs(x) <= d) 
+        {
+            if(n != 0) return 0;
+            return 1;
+        }
+        double b1 = 0; // b1 is the value from the previous iteration
+        // Set up a starting order for recurrence
+        int m1 = (int)fabs(x) + 6;
+        if(fabs(x) > 5) 
+        {
+            m1 = (int)(fabs(1.4 * x + 60 / x));
+        }
+        int m2 = (int)(n + 2 + fabs(x) / 4);
+        if (m1 > m2) 
+        {
+            m2 = m1;
+        }
+    
+        // Apply recurrence down from curent max order
+        for(;;) 
+        {
+            double c3 = 0;
+            double c2 = 1E-30;
+            double c4 = 0;
+            int m8 = 1;
+            if (m2 / 2 * 2 == m2) 
+            {
+                m8 = -1;
+            }
+            int imax = m2 - 2;
+            for (int i = 1; i <= imax; i++) 
+            {
+                double c6 = 2 * (m2 - i) * c2 / x - c3;
+                c3 = c2;
+                c2 = c6;
+                if(m2 - i - 1 == n)
+                {
+                    b = c6;
+                }
+                m8 = -1 * m8;
+                if (m8 > 0)
+                {
+                    c4 = c4 + 2 * c6;
+                }
+            }
+            double c6 = 2 * c2 / x - c3;
+            if(n == 0)
+            {
+                b = c6;
+            }
+            c4 += c6;
+            b /= c4;
+            if(fabs(b - b1) < d)
+            {
+                return b;
+            }
+            b1 = b;
+            m2 += 3;
+        }
+    }
+
 }
 
 

Modified: incubator/ooo/trunk/main/agg/inc/agg_math_stroke.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/agg/inc/agg_math_stroke.h?rev=1184758&r1=1184757&r2=1184758&view=diff
==============================================================================
--- incubator/ooo/trunk/main/agg/inc/agg_math_stroke.h (original)
+++ incubator/ooo/trunk/main/agg/inc/agg_math_stroke.h Sun Oct 16 04:13:16 2011
@@ -1,5 +1,5 @@
 //----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
 //
 // Permission to copy, use, modify, sell and distribute this software 
@@ -36,297 +36,483 @@ namespace agg
     //------------------------------------------------------------line_join_e
     enum line_join_e
     {
-        miter_join,
-        miter_join_revert,
-        round_join,
-        bevel_join
+        miter_join         = 0,
+        miter_join_revert  = 1,
+        round_join         = 2,
+        bevel_join         = 3,
+        miter_join_round   = 4
     };
 
-    // Minimal angle to calculate round joins, less than 0.1 degree.
-    const double stroke_theta = 0.001; //----stroke_theta
 
+    //-----------------------------------------------------------inner_join_e
+    enum inner_join_e
+    {
+        inner_bevel,
+        inner_miter,
+        inner_jag,
+        inner_round
+    };
 
-    //--------------------------------------------------------stroke_calc_arc
-    template<class VertexConsumer>
-    void stroke_calc_arc(VertexConsumer& out_vertices,
-                         double x,   double y, 
-                         double dx1, double dy1, 
-                         double dx2, double dy2,
-                         double width,
-                         double approximation_scale)
+    //------------------------------------------------------------math_stroke
+    template<class VertexConsumer> class math_stroke
     {
+    public:
         typedef typename VertexConsumer::value_type coord_type;
 
-        //// Check if we actually need the arc (this optimization works bad)
-        ////-----------------
-        //double dd = calc_distance(dx1, dy1, dx2, dy2);
-        //if(dd < 1.0/approximation_scale)
-        //{
-        //    out_vertices.add(coord_type(x + dx1, y + dy1));
-        //    if(dd > 0.25/approximation_scale)
-        //    {
-        //        out_vertices.add(coord_type(x + dx2, y + dy2));
-        //    }
-        //    return;
-        //}
+        math_stroke();
 
-        double a1 = atan2(dy1, dx1);
-        double a2 = atan2(dy2, dx2);
-        double da = a1 - a2;
+        void line_cap(line_cap_e lc)     { m_line_cap = lc; }
+        void line_join(line_join_e lj)   { m_line_join = lj; }
+        void inner_join(inner_join_e ij) { m_inner_join = ij; }
+
+        line_cap_e   line_cap()   const { return m_line_cap; }
+        line_join_e  line_join()  const { return m_line_join; }
+        inner_join_e inner_join() const { return m_inner_join; }
+
+        void width(double w);
+        void miter_limit(double ml) { m_miter_limit = ml; }
+        void miter_limit_theta(double t);
+        void inner_miter_limit(double ml) { m_inner_miter_limit = ml; }
+        void approximation_scale(double as) { m_approx_scale = as; }
+
+        double width() const { return m_width * 2.0; }
+        double miter_limit() const { return m_miter_limit; }
+        double inner_miter_limit() const { return m_inner_miter_limit; }
+        double approximation_scale() const { return m_approx_scale; }
+
+        void calc_cap(VertexConsumer& vc,
+                      const vertex_dist& v0, 
+                      const vertex_dist& v1, 
+                      double len);
+
+        void calc_join(VertexConsumer& vc,
+                       const vertex_dist& v0, 
+                       const vertex_dist& v1, 
+                       const vertex_dist& v2,
+                       double len1, 
+                       double len2);
+
+    private:
+        AGG_INLINE void add_vertex(VertexConsumer& vc, double x, double y)
+        {
+            vc.add(coord_type(x, y));
+        }
+
+        void calc_arc(VertexConsumer& vc,
+                      double x,   double y, 
+                      double dx1, double dy1, 
+                      double dx2, double dy2);
+
+        void calc_miter(VertexConsumer& vc,
+                        const vertex_dist& v0, 
+                        const vertex_dist& v1, 
+                        const vertex_dist& v2,
+                        double dx1, double dy1, 
+                        double dx2, double dy2,
+                        line_join_e lj,
+                        double mlimit,
+                        double dbevel);
+
+        double       m_width;
+        double       m_width_abs;
+        double       m_width_eps;
+        int          m_width_sign;
+        double       m_miter_limit;
+        double       m_inner_miter_limit;
+        double       m_approx_scale;
+        line_cap_e   m_line_cap;
+        line_join_e  m_line_join;
+        inner_join_e m_inner_join;
+    };
+
+    //-----------------------------------------------------------------------
+    template<class VC> math_stroke<VC>::math_stroke() :
+        m_width(0.5),
+        m_width_abs(0.5),
+        m_width_eps(0.5/1024.0),
+        m_width_sign(1),
+        m_miter_limit(4.0),
+        m_inner_miter_limit(1.01),
+        m_approx_scale(1.0),
+        m_line_cap(butt_cap),
+        m_line_join(miter_join),
+        m_inner_join(inner_miter)
+    {
+    }
 
-        if(fabs(da) < stroke_theta)
+    //-----------------------------------------------------------------------
+    template<class VC> void math_stroke<VC>::width(double w)
+    { 
+        m_width = w * 0.5; 
+        if(m_width < 0)
+        {
+            m_width_abs  = -m_width;
+            m_width_sign = -1;
+        }
+        else
         {
-            out_vertices.add(coord_type((x + x + dx1 + dx2) * 0.5, 
-                                        (y + y + dy1 + dy2) * 0.5));
-            return;
+            m_width_abs  = m_width;
+            m_width_sign = 1;
         }
+        m_width_eps = m_width / 1024.0;
+    }
 
-        bool ccw = da > 0.0 && da < pi;
+    //-----------------------------------------------------------------------
+    template<class VC> void math_stroke<VC>::miter_limit_theta(double t)
+    { 
+        m_miter_limit = 1.0 / sin(t * 0.5) ;
+    }
 
-        if(width < 0) width = -width;
-        da = fabs(1.0 / (width * approximation_scale));
-        if(!ccw)
+    //-----------------------------------------------------------------------
+    template<class VC> 
+    void math_stroke<VC>::calc_arc(VC& vc,
+                                   double x,   double y, 
+                                   double dx1, double dy1, 
+                                   double dx2, double dy2)
+    {
+        double a1 = atan2(dy1 * m_width_sign, dx1 * m_width_sign);
+        double a2 = atan2(dy2 * m_width_sign, dx2 * m_width_sign);
+        double da = a1 - a2;
+        int i, n;
+
+        da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
+
+        add_vertex(vc, x + dx1, y + dy1);
+        if(m_width_sign > 0)
         {
             if(a1 > a2) a2 += 2 * pi;
-            while(a1 < a2)
+            n = int((a2 - a1) / da);
+            da = (a2 - a1) / (n + 1);
+            a1 += da;
+            for(i = 0; i < n; i++)
             {
-                out_vertices.add(coord_type(x + cos(a1) * width, y + sin(a1) * width));
+                add_vertex(vc, x + cos(a1) * m_width, y + sin(a1) * m_width);
                 a1 += da;
             }
         }
         else
         {
             if(a1 < a2) a2 -= 2 * pi;
-            while(a1 > a2)
+            n = int((a1 - a2) / da);
+            da = (a1 - a2) / (n + 1);
+            a1 -= da;
+            for(i = 0; i < n; i++)
             {
-                out_vertices.add(coord_type(x + cos(a1) * width, y + sin(a1) * width));
+                add_vertex(vc, x + cos(a1) * m_width, y + sin(a1) * m_width);
                 a1 -= da;
             }
         }
-        out_vertices.add(coord_type(x + dx2, y + dy2));
+        add_vertex(vc, x + dx2, y + dy2);
     }
 
-
-
-    //-------------------------------------------------------stroke_calc_miter
-    template<class VertexConsumer>
-    void stroke_calc_miter(VertexConsumer& out_vertices,
-                           const vertex_dist& v0, 
-                           const vertex_dist& v1, 
-                           const vertex_dist& v2,
-                           double dx1, double dy1, 
-                           double dx2, double dy2,
-                           double width,
-                           bool revert_flag,
-                           double miter_limit)
+    //-----------------------------------------------------------------------
+    template<class VC> 
+    void math_stroke<VC>::calc_miter(VC& vc,
+                                     const vertex_dist& v0, 
+                                     const vertex_dist& v1, 
+                                     const vertex_dist& v2,
+                                     double dx1, double dy1, 
+                                     double dx2, double dy2,
+                                     line_join_e lj,
+                                     double mlimit,
+                                     double dbevel)
     {
-        typedef typename VertexConsumer::value_type coord_type;
-
-        double xi = v1.x;
-        double yi = v1.y;
-
-        if(!calc_intersection(v0.x + dx1, v0.y - dy1,
-                              v1.x + dx1, v1.y - dy1,
-                              v1.x + dx2, v1.y - dy2,
-                              v2.x + dx2, v2.y - dy2,
-                              &xi, &yi))
+        double xi  = v1.x;
+        double yi  = v1.y;
+        double di  = 1;
+        double lim = m_width_abs * mlimit;
+        bool miter_limit_exceeded = true; // Assume the worst
+        bool intersection_failed  = true; // Assume the worst
+
+        if(calc_intersection(v0.x + dx1, v0.y - dy1,
+                             v1.x + dx1, v1.y - dy1,
+                             v1.x + dx2, v1.y - dy2,
+                             v2.x + dx2, v2.y - dy2,
+                             &xi, &yi))
         {
-            // The calculation didn't succeed, most probaly
-            // the three points lie one straight line
+            // Calculation of the intersection succeeded
+            //---------------------
+            di = calc_distance(v1.x, v1.y, xi, yi);
+            if(di <= lim)
+            {
+                // Inside the miter limit
+                //---------------------
+                add_vertex(vc, xi, yi);
+                miter_limit_exceeded = false;
+            }
+            intersection_failed = false;
+        }
+        else
+        {
+            // Calculation of the intersection failed, most probably
+            // the three points lie one straight line. 
+            // First check if v0 and v2 lie on the opposite sides of vector: 
+            // (v1.x, v1.y) -> (v1.x+dx1, v1.y-dy1), that is, the perpendicular
+            // to the line determined by vertices v0 and v1.
+            // This condition determines whether the next line segments continues
+            // the previous one or goes back.
             //----------------
-            if(calc_distance(dx1, -dy1, dx2, -dy2) < width * 0.025)
+            double x2 = v1.x + dx1;
+            double y2 = v1.y - dy1;
+            if((cross_product(v0.x, v0.y, v1.x, v1.y, x2, y2) < 0.0) == 
+               (cross_product(v1.x, v1.y, v2.x, v2.y, x2, y2) < 0.0))
             {
                 // This case means that the next segment continues 
                 // the previous one (straight line)
                 //-----------------
-                out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1));
-            }
-            else
-            {
-                // This case means that the next segment goes back  
-                //-----------------
-                if(revert_flag)
-                {
-                    out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1));
-                    out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2));
-                }
-                else
-                {
-                    // If no miter-revert, calcuate new dx1, dy1, dx2, dy2
-                    out_vertices.add(coord_type(v1.x + dx1 + dy1 * miter_limit, 
-                                                v1.y - dy1 + dx1 * miter_limit));
-                    out_vertices.add(coord_type(v1.x + dx2 - dy2 * miter_limit, 
-                                                v1.y - dy2 - dx2 * miter_limit));
-                }
+                add_vertex(vc, v1.x + dx1, v1.y - dy1);
+                miter_limit_exceeded = false;
             }
         }
-        else
+
+        if(miter_limit_exceeded)
         {
-            double d1 = calc_distance(v1.x, v1.y, xi, yi);
-            double lim = width * miter_limit;
-            if(d1 > lim)
-            {
-                // Miter limit exceeded
-                //------------------------
-                if(revert_flag)
+            // Miter limit exceeded
+            //------------------------
+            switch(lj)
+            {
+            case miter_join_revert:
+                // For the compatibility with SVG, PDF, etc, 
+                // we use a simple bevel join instead of
+                // "smart" bevel
+                //-------------------
+                add_vertex(vc, v1.x + dx1, v1.y - dy1);
+                add_vertex(vc, v1.x + dx2, v1.y - dy2);
+                break;
+
+            case miter_join_round:
+                calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
+                break;
+
+            default:
+                // If no miter-revert, calculate new dx1, dy1, dx2, dy2
+                //----------------
+                if(intersection_failed)
                 {
-                    // For the compatibility with SVG, PDF, etc, 
-                    // we use a simple bevel join instead of
-                    // "smart" bevel
-                    //-------------------
-                    out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1));
-                    out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2));
+                    mlimit *= m_width_sign;
+                    add_vertex(vc, v1.x + dx1 + dy1 * mlimit, 
+                                   v1.y - dy1 + dx1 * mlimit);
+                    add_vertex(vc, v1.x + dx2 - dy2 * mlimit, 
+                                   v1.y - dy2 - dx2 * mlimit);
                 }
                 else
                 {
-                    // Smart bevel that cuts the miter at the limit point
-                    //-------------------
-                    d1  = lim / d1;
                     double x1 = v1.x + dx1;
                     double y1 = v1.y - dy1;
                     double x2 = v1.x + dx2;
                     double y2 = v1.y - dy2;
-
-                    x1 += (xi - x1) * d1;
-                    y1 += (yi - y1) * d1;
-                    x2 += (xi - x2) * d1;
-                    y2 += (yi - y2) * d1;
-                    out_vertices.add(coord_type(x1, y1));
-                    out_vertices.add(coord_type(x2, y2));
+                    di = (lim - dbevel) / (di - dbevel);
+                    add_vertex(vc, x1 + (xi - x1) * di, 
+                                   y1 + (yi - y1) * di);
+                    add_vertex(vc, x2 + (xi - x2) * di, 
+                                   y2 + (yi - y2) * di);
                 }
-            }
-            else
-            {
-                // Inside the miter limit
-                //---------------------
-                out_vertices.add(coord_type(xi, yi));
+                break;
             }
         }
     }
 
-
-
-
-
-
     //--------------------------------------------------------stroke_calc_cap
-    template<class VertexConsumer>
-    void stroke_calc_cap(VertexConsumer& out_vertices,
-                         const vertex_dist& v0, 
-                         const vertex_dist& v1, 
-                         double len,
-                         line_cap_e line_cap,
-                         double width,
-                         double approximation_scale)
+    template<class VC> 
+    void math_stroke<VC>::calc_cap(VC& vc,
+                                   const vertex_dist& v0, 
+                                   const vertex_dist& v1, 
+                                   double len)
     {
-        typedef typename VertexConsumer::value_type coord_type;
+        vc.remove_all();
 
-        out_vertices.remove_all();
-
-        double dx1 = width * (v1.y - v0.y) / len;
-        double dy1 = width * (v1.x - v0.x) / len;
+        double dx1 = (v1.y - v0.y) / len;
+        double dy1 = (v1.x - v0.x) / len;
         double dx2 = 0;
         double dy2 = 0;
 
-        if(line_cap == square_cap)
-        {
-            dx2 = dy1;
-            dy2 = dx1;
-        }
+        dx1 *= m_width;
+        dy1 *= m_width;
 
-        if(line_cap == round_cap)
+        if(m_line_cap != round_cap)
         {
-            double a1 = atan2(dy1, -dx1);
-            double a2 = a1 + pi;
-            double da = fabs(1.0 / (width * approximation_scale));
-            while(a1 < a2)
+            if(m_line_cap == square_cap)
             {
-                out_vertices.add(coord_type(v0.x + cos(a1) * width, 
-                                            v0.y + sin(a1) * width));
-                a1 += da;
+                dx2 = dy1 * m_width_sign;
+                dy2 = dx1 * m_width_sign;
             }
-            out_vertices.add(coord_type(v0.x + dx1, v0.y - dy1));
+            add_vertex(vc, v0.x - dx1 - dx2, v0.y + dy1 - dy2);
+            add_vertex(vc, v0.x + dx1 - dx2, v0.y - dy1 - dy2);
         }
         else
         {
-            out_vertices.add(coord_type(v0.x - dx1 - dx2, v0.y + dy1 - dy2));
-            out_vertices.add(coord_type(v0.x + dx1 - dx2, v0.y - dy1 - dy2));
+            double da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
+            double a1;
+            int i;
+            int n = int(pi / da);
+
+            da = pi / (n + 1);
+            add_vertex(vc, v0.x - dx1, v0.y + dy1);
+            if(m_width_sign > 0)
+            {
+                a1 = atan2(dy1, -dx1);
+                a1 += da;
+                for(i = 0; i < n; i++)
+                {
+                    add_vertex(vc, v0.x + cos(a1) * m_width, 
+                                   v0.y + sin(a1) * m_width);
+                    a1 += da;
+                }
+            }
+            else
+            {
+                a1 = atan2(-dy1, dx1);
+                a1 -= da;
+                for(i = 0; i < n; i++)
+                {
+                    add_vertex(vc, v0.x + cos(a1) * m_width, 
+                                   v0.y + sin(a1) * m_width);
+                    a1 -= da;
+                }
+            }
+            add_vertex(vc, v0.x + dx1, v0.y - dy1);
         }
     }
 
-
-
-    //-------------------------------------------------------stroke_calc_join
-    template<class VertexConsumer>
-    void stroke_calc_join(VertexConsumer& out_vertices,
-                          const vertex_dist& v0, 
-                          const vertex_dist& v1, 
-                          const vertex_dist& v2,
-                          double len1, 
-                          double len2,
-                          double width, 
-                          line_join_e line_join,
-                          line_join_e inner_line_join,
-                          double miter_limit,
-                          double inner_miter_limit,
-                          double approximation_scale)
+    //-----------------------------------------------------------------------
+    template<class VC> 
+    void math_stroke<VC>::calc_join(VC& vc,
+                                    const vertex_dist& v0, 
+                                    const vertex_dist& v1, 
+                                    const vertex_dist& v2,
+                                    double len1, 
+                                    double len2)
     {
-        typedef typename VertexConsumer::value_type coord_type;
-
-        double dx1, dy1, dx2, dy2;
-
-        dx1 = width * (v1.y - v0.y) / len1;
-        dy1 = width * (v1.x - v0.x) / len1;
-
-        dx2 = width * (v2.y - v1.y) / len2;
-        dy2 = width * (v2.x - v1.x) / len2;
+        double dx1 = m_width * (v1.y - v0.y) / len1;
+        double dy1 = m_width * (v1.x - v0.x) / len1;
+        double dx2 = m_width * (v2.y - v1.y) / len2;
+        double dy2 = m_width * (v2.x - v1.x) / len2;
 
-        out_vertices.remove_all();
+        vc.remove_all();
 
-        if(calc_point_location(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y) > 0.0)
+        double cp = cross_product(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y);
+        if(cp != 0 && (cp > 0) == (m_width > 0))
         {
             // Inner join
             //---------------
-            stroke_calc_miter(out_vertices,
-                              v0, v1, v2, dx1, dy1, dx2, dy2, 
-                              width,                                   
-                              inner_line_join == miter_join_revert, 
-                              inner_miter_limit);
+            double limit = ((len1 < len2) ? len1 : len2) / m_width_abs;
+            if(limit < m_inner_miter_limit)
+            {
+                limit = m_inner_miter_limit;
+            }
+
+            switch(m_inner_join)
+            {
+            default: // inner_bevel
+                add_vertex(vc, v1.x + dx1, v1.y - dy1);
+                add_vertex(vc, v1.x + dx2, v1.y - dy2);
+                break;
+
+            case inner_miter:
+                calc_miter(vc,
+                           v0, v1, v2, dx1, dy1, dx2, dy2, 
+                           miter_join_revert, 
+                           limit, 0);
+                break;
+
+            case inner_jag:
+            case inner_round:
+                cp = (dx1-dx2) * (dx1-dx2) + (dy1-dy2) * (dy1-dy2);
+                if(cp < len1 * len1 && cp < len2 * len2)
+                {
+                    calc_miter(vc,
+                               v0, v1, v2, dx1, dy1, dx2, dy2, 
+                               miter_join_revert, 
+                               limit, 0);
+                }
+                else
+                {
+                    if(m_inner_join == inner_jag)
+                    {
+                        add_vertex(vc, v1.x + dx1, v1.y - dy1);
+                        add_vertex(vc, v1.x,       v1.y      );
+                        add_vertex(vc, v1.x + dx2, v1.y - dy2);
+                    }
+                    else
+                    {
+                        add_vertex(vc, v1.x + dx1, v1.y - dy1);
+                        add_vertex(vc, v1.x,       v1.y      );
+                        calc_arc(vc, v1.x, v1.y, dx2, -dy2, dx1, -dy1);
+                        add_vertex(vc, v1.x,       v1.y      );
+                        add_vertex(vc, v1.x + dx2, v1.y - dy2);
+                    }
+                }
+                break;
+            }
         }
         else
         {
             // Outer join
             //---------------
-            switch(line_join)
+
+            // Calculate the distance between v1 and 
+            // the central point of the bevel line segment
+            //---------------
+            double dx = (dx1 + dx2) / 2;
+            double dy = (dy1 + dy2) / 2;
+            double dbevel = sqrt(dx * dx + dy * dy);
+
+            if(m_line_join == round_join || m_line_join == bevel_join)
             {
-            case miter_join:
-                stroke_calc_miter(out_vertices, 
-                                  v0, v1, v2, dx1, dy1, dx2, dy2, 
-                                  width,                                   
-                                  false, 
-                                  miter_limit);
-                break;
+                // This is an optimization that reduces the number of points 
+                // in cases of almost collinear segments. If there's no
+                // visible difference between bevel and miter joins we'd rather
+                // use miter join because it adds only one point instead of two. 
+                //
+                // Here we calculate the middle point between the bevel points 
+                // and then, the distance between v1 and this middle point. 
+                // At outer joins this distance always less than stroke width, 
+                // because it's actually the height of an isosceles triangle of
+                // v1 and its two bevel points. If the difference between this
+                // width and this value is small (no visible bevel) we can 
+                // add just one point. 
+                //
+                // The constant in the expression makes the result approximately 
+                // the same as in round joins and caps. You can safely comment 
+                // out this entire "if".
+                //-------------------
+                if(m_approx_scale * (m_width_abs - dbevel) < m_width_eps)
+                {
+                    if(calc_intersection(v0.x + dx1, v0.y - dy1,
+                                         v1.x + dx1, v1.y - dy1,
+                                         v1.x + dx2, v1.y - dy2,
+                                         v2.x + dx2, v2.y - dy2,
+                                         &dx, &dy))
+                    {
+                        add_vertex(vc, dx, dy);
+                    }
+                    else
+                    {
+                        add_vertex(vc, v1.x + dx1, v1.y - dy1);
+                    }
+                    return;
+                }
+            }
 
+            switch(m_line_join)
+            {
+            case miter_join:
             case miter_join_revert:
-                stroke_calc_miter(out_vertices, 
-                                  v0, v1, v2, dx1, dy1, dx2, dy2, 
-                                  width,                                   
-                                  true, 
-                                  miter_limit);
+            case miter_join_round:
+                calc_miter(vc, 
+                           v0, v1, v2, dx1, dy1, dx2, dy2, 
+                           m_line_join, 
+                           m_miter_limit,
+                           dbevel);
                 break;
 
             case round_join:
-                stroke_calc_arc(out_vertices, 
-                                v1.x, v1.y, dx1, -dy1, dx2, -dy2, 
-                                width, approximation_scale);
+                calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
                 break;
 
             default: // Bevel join
-                out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1));
-                if(calc_distance(dx1, dy1, dx2, dy2) > approximation_scale * 0.25)
-                {
-                    out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2));
-                }
+                add_vertex(vc, v1.x + dx1, v1.y - dy1);
+                add_vertex(vc, v1.x + dx2, v1.y - dy2);
                 break;
             }
         }

Added: incubator/ooo/trunk/main/agg/inc/agg_path_length.h
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/agg/inc/agg_path_length.h?rev=1184758&view=auto
==============================================================================
--- incubator/ooo/trunk/main/agg/inc/agg_path_length.h (added)
+++ incubator/ooo/trunk/main/agg/inc/agg_path_length.h Sun Oct 16 04:13:16 2011
@@ -0,0 +1,65 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software 
+// is granted provided this copyright notice appears in all copies. 
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+//          mcseemagg@yahoo.com
+//          http://www.antigrain.com
+//----------------------------------------------------------------------------
+#ifndef AGG_PATH_LENGTH_INCLUDED
+#define AGG_PATH_LENGTH_INCLUDED
+
+#include "agg_math.h"
+
+namespace agg
+{
+    template<class VertexSource> 
+    double path_length(VertexSource& vs, unsigned path_id = 0)
+    {
+        double len = 0.0;
+        double start_x = 0.0;
+        double start_y = 0.0;
+        double x1 = 0.0;
+        double y1 = 0.0;
+        double x2 = 0.0;
+        double y2 = 0.0;
+        bool first = true;
+
+        unsigned cmd;
+        vs.rewind(path_id);
+        while(!is_stop(cmd = vs.vertex(&x2, &y2)))
+        {
+            if(is_vertex(cmd))
+            {
+                if(first || is_move_to(cmd))
+                {
+                    start_x = x2;
+                    start_y = y2;
+                }
+                else
+                {
+                    len += calc_distance(x1, y1, x2, y2);
+                }
+                x1 = x2;
+                y1 = y2;
+                first = false;
+            }
+            else
+            {
+                if(is_close(cmd) && !first)
+                {
+                    len += calc_distance(x1, y1, start_x, start_y);
+                }
+            }
+        }
+        return len;
+    }
+}
+
+#endif



Mime
View raw message