gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/trunk r10549: Make rendering interface mor


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r10549: Make rendering interface more consistent and simple to use.
Date: Wed, 21 Jan 2009 12:37:15 +0100
User-agent: Bazaar (1.5)

------------------------------------------------------------
revno: 10549
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Wed 2009-01-21 12:37:15 +0100
message:
  Make rendering interface more consistent and simple to use.
  
  Clean up agg to use ctors properly, reduce code duplication, and replace
  long-winded manual loops to make refactoring easier.
removed:
  backend/render_handler_agg_compat.h
modified:
  backend/Makefile.am
  backend/render_handler.h
  backend/render_handler_agg.cpp
  backend/render_handler_agg_style.h
  backend/render_handler_cairo.cpp
  backend/render_handler_ogl.cpp
  libcore/TextField.cpp
  libcore/cxform.cpp
  libcore/render.cpp
  libcore/render.h
  libcore/swf/TextRecord.cpp
    ------------------------------------------------------------
    revno: 10545.1.6
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Mon 2009-01-19 15:42:24 +0100
    message:
      More clean ups, and drop unused caching code, at least until someone 
wants to
      use it.
    modified:
      backend/render_handler_agg.cpp
    ------------------------------------------------------------
    revno: 10545.1.7
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Mon 2009-01-19 16:30:49 +0100
    message:
      Drop unused header, consolidate agg renderer code more.
    removed:
      backend/render_handler_agg_compat.h
    modified:
      backend/Makefile.am
      backend/render_handler_agg.cpp
    ------------------------------------------------------------
    revno: 10545.1.8
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Mon 2009-01-19 17:35:55 +0100
    message:
      Modify draw_line_strip (agg only).
    modified:
      backend/render_handler.h
      backend/render_handler_agg.cpp
      libcore/TextField.cpp
      libcore/render.cpp
      libcore/render.h
      libcore/swf/TextRecord.cpp
    ------------------------------------------------------------
    revno: 10545.1.9
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Mon 2009-01-19 18:17:03 +0100
    message:
      Comments.
    modified:
      backend/render_handler_agg.cpp
    ------------------------------------------------------------
    revno: 10545.1.10
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Mon 2009-01-19 21:00:32 +0100
    message:
      Minor refactoring.
    modified:
      backend/render_handler_agg.cpp
    ------------------------------------------------------------
    revno: 10545.1.11
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Mon 2009-01-19 21:49:36 +0100
    message:
      Don't delay construction of elements; construction in a ctor-initializer
      allows some compiler optimizations.
      
      Encapsulate variables better.
    modified:
      backend/render_handler_agg_style.h
    ------------------------------------------------------------
    revno: 10545.1.12
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Mon 2009-01-19 22:02:39 +0100
    message:
      Fix initialization order.
    modified:
      backend/render_handler_agg_style.h
    ------------------------------------------------------------
    revno: 10545.1.13
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Tue 2009-01-20 09:11:19 +0100
    message:
      Reduce number of operations in cxform::transform, as it's called a lot.
    modified:
      libcore/cxform.cpp
    ------------------------------------------------------------
    revno: 10545.1.14
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Tue 2009-01-20 12:01:18 +0100
    message:
      Minor refactoring.
    modified:
      backend/render_handler_agg_style.h
    ------------------------------------------------------------
    revno: 10545.1.15
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Wed 2009-01-21 09:45:36 +0100
    message:
      Minor cleanups, fix ogl and cairo builds.
    modified:
      backend/render_handler_agg.cpp
      backend/render_handler_agg_style.h
      backend/render_handler_cairo.cpp
      backend/render_handler_ogl.cpp
    ------------------------------------------------------------
    revno: 10545.1.16
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Wed 2009-01-21 09:58:44 +0100
    message:
      Silence logging.
    modified:
      backend/render_handler_agg.cpp
=== modified file 'backend/Makefile.am'
--- a/backend/Makefile.am       2008-11-12 15:29:13 +0000
+++ b/backend/Makefile.am       2009-01-19 15:30:49 +0000
@@ -57,7 +57,6 @@
        render_handler.h \
        render_handler_agg.h \
        render_handler_agg_bitmap.h \
-       render_handler_agg_compat.h \
        render_handler_agg_style.h \
        render_handler_cairo.h \
        render_handler_ogl.h \

=== modified file 'backend/render_handler.h'
--- a/backend/render_handler.h  2009-01-19 08:05:42 +0000
+++ b/backend/render_handler.h  2009-01-19 16:35:55 +0000
@@ -263,7 +263,7 @@
     /// @color the color to be used to draw the line strip.
     ///
     /// @mat the SWFMatrix to be used to transform the vertices.
-    virtual void draw_line_strip(const boost::int16_t* coords, int 
vertex_count,
+    virtual void drawLine(const std::vector<point>& coords,
             const rgba& color, const SWFMatrix& mat) = 0;
         
     /// Draw a simple, solid filled polygon with a thin (~1 pixel) outline.

=== modified file 'backend/render_handler_agg.cpp'
--- a/backend/render_handler_agg.cpp    2009-01-19 10:38:11 +0000
+++ b/backend/render_handler_agg.cpp    2009-01-21 08:58:44 +0000
@@ -15,9 +15,6 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
- 
-
-
 // Original version by Udo Giacomozzi and Hannes Mayr, 
 // INDUNET GmbH (www.indunet.it)
 
@@ -146,11 +143,6 @@
 #include <agg_scanline_bin.h>
 #include <agg_scanline_p.h>
 #include <agg_renderer_scanline.h>
-// must only include if render_scanlines_compound_layered is not defined
-//#if ! HAVE_AGG_SCANLINES_COMPOUND_LAYERED
-//#warning including compound
-//#include "render_handler_agg_compat.h"
-//#endif
 #include <agg_rasterizer_scanline_aa.h>
 #include <agg_rasterizer_compound_aa.h>
 #include <agg_span_allocator.h>
@@ -184,12 +176,16 @@
 
 #include <boost/numeric/conversion/converter.hpp>
 
-using namespace gnash;
-
 namespace gnash {
 
 namespace {
 
+class AlphaMask;
+
+typedef std::vector<geometry::Range2d<int> > ClipBounds;
+typedef std::vector<AlphaMask*> AlphaMasks;
+typedef std::vector<path> GnashPaths;
+
 template <class Rasterizer>
 inline void applyClipBox(Rasterizer& ras, const geometry::Range2d<int>& bounds)
 {
@@ -201,6 +197,104 @@
             );  
 }
 
+/// Analyzes a set of paths to detect real presence of fills and/or outlines
+/// TODO: This should be something the character tells us and should be 
+/// cached. 
+void
+analyzePaths(const GnashPaths &paths, bool& have_shape,
+    bool& have_outline)
+{
+
+    have_shape = false;
+    have_outline = false;
+
+    const int pcount = paths.size();
+
+    for (int pno=0; pno<pcount; ++pno) {
+
+        const path &the_path = paths[pno];
+
+        if ((the_path.m_fill0 > 0) || (the_path.m_fill1 > 0)) {
+            have_shape = true;
+            if (have_outline) return; // have both
+        }
+
+        if (the_path.m_line > 0) {
+            have_outline = true;
+            if (have_shape) return; // have both
+        }
+    }
+}
+
+/// In-place transformation of Gnash paths to AGG paths.
+class GnashToAggPath
+{
+public:
+
+    typedef std::vector<agg::path_storage> AggPaths;
+
+    GnashToAggPath(AggPaths& dest)
+        :
+        _dest(dest),
+        _it(_dest.begin())
+    {
+    }
+
+    class EdgeToPath
+    {
+
+    public:
+        EdgeToPath(AggPaths::value_type& path)
+            :
+            _path(path)
+        {}
+
+        void operator()(const edge& edge)
+        {
+            if (edge.is_straight()) {
+                _path.line_to(TWIPS_TO_SHIFTED_PIXELS(edge.ap.x), 
+                                    TWIPS_TO_SHIFTED_PIXELS(edge.ap.y));
+            }
+            else {
+                _path.curve3(TWIPS_TO_SHIFTED_PIXELS(edge.cp.x), 
+                         TWIPS_TO_SHIFTED_PIXELS(edge.cp.y),
+                         TWIPS_TO_SHIFTED_PIXELS(edge.ap.x), 
+                         TWIPS_TO_SHIFTED_PIXELS(edge.ap.y));             
+            }
+        }
+
+    private:
+        agg::path_storage& _path;
+    };
+
+    void operator()(const path& in)
+    {
+        agg::path_storage& p = *_it;
+
+        p.move_to(TWIPS_TO_SHIFTED_PIXELS(in.ap.x), 
+                            TWIPS_TO_SHIFTED_PIXELS(in.ap.y));
+
+        std::for_each(in.m_edges.begin(), in.m_edges.end(), EdgeToPath(p));
+        ++_it;
+    }
+
+private:
+    std::vector<agg::path_storage>& _dest;
+    AggPaths::iterator _it;
+
+};
+
+
+/// Transposes Gnash paths to AGG paths, which can be used for both outlines
+/// and shapes. Subshapes are ignored (ie. all paths are converted). Converts 
+/// TWIPS to pixels on the fly.
+inline void
+buildPaths(std::vector<agg::path_storage>& dest, const GnashPaths& paths) 
+{
+    dest.resize(paths.size());
+    std::for_each(paths.begin(), paths.end(), GnashToAggPath(dest));
+} 
+
 // --- ALPHA MASK BUFFER CONTAINER 
---------------------------------------------
 // How masks are implemented: A mask is basically a full alpha buffer. Each 
 // pixel in the alpha buffer defines the fraction of color values that are
@@ -223,8 +317,8 @@
 class AlphaMask 
 {
 
-    typedef agg::renderer_base<agg::pixfmt_gray8> renderer_base;
-    typedef agg::alpha_mask_gray8 amask_type;
+    typedef agg::renderer_base<agg::pixfmt_gray8> Renderer;
+    typedef agg::alpha_mask_gray8 Mask;
 
 public:
 
@@ -264,11 +358,11 @@
         }
     }
     
-    renderer_base& get_rbase() {
+    Renderer& get_rbase() {
         return _rbase;
     }
     
-    amask_type& get_amask() {
+    const Mask& getMask() const {
         return _amask;
     }    
     
@@ -281,73 +375,209 @@
     agg::pixfmt_gray8 _pixf;    
     
     // renderer base
-    renderer_base _rbase;
+    Renderer _rbase;
     
     // alpha mask
-    amask_type _amask;
+    Mask _amask;
     
     // in-memory buffer
     boost::scoped_array<boost::uint8_t> _buffer;
     
 };
 
+/// Class for rendering lines.
+template<typename PixelFormat>
+class LineRenderer
+{
+public:
+    typedef agg::renderer_base<PixelFormat> BaseRenderer;
+    typedef agg::renderer_scanline_aa_solid<BaseRenderer> Renderer;
+    typedef agg::rasterizer_scanline_aa<> Rasterizer;
+    typedef agg::conv_stroke<agg::path_storage> Stroke;
+
+    LineRenderer(const ClipBounds& clipbounds, BaseRenderer& baseRenderer)
+        :
+        _clipbounds(clipbounds),
+        _renderer(baseRenderer)
+    {}
+
+    template<typename ScanLine>
+    void render(ScanLine& sl, Stroke& stroke, const rgba& color)
+    {
+        for (ClipBounds::const_iterator i = _clipbounds.begin(),
+                e = _clipbounds.end(); i != e; ++i) {
+
+            const ClipBounds::value_type& bounds = *i;
+              
+            applyClipBox<Rasterizer> (_ras, bounds);
+
+            // The vectorial pipeline
+            _ras.add_path(stroke);
+
+            // Set the color and render the scanlines
+            _renderer.color(agg::rgba8_pre(color.m_r, color.m_g, 
+                        color.m_b, color.m_a));
+
+            agg::render_scanlines(_ras, sl, _renderer);
+
+        }
+    }
+
+private:
+
+    const ClipBounds& _clipbounds;
+    Rasterizer _ras;
+    Renderer _renderer;
+
+};
+
+/// Class for rendering video frames.
+//
+/// Templated functions are used to allow using different types,
+/// particularly for high and low quality rendering. 
+//
+/// At present, this is bound to the renderer's ClipBounds. In future it
+/// may be useful to pass BlendMode, Cxform, and custom clipbounds as well
+/// as a caller-provided rendering buffer. This also applies to the 
+/// rest of the renderer API.
+//
+/// @param SourceFormat     The format of the video frame to be rendered
+/// @param PixelFormat      The format to render to.
+template <typename PixelFormat, typename SourceFormat = agg::pixfmt_rgb24_pre>
+class VideoRenderer
+{
+
+public:
+
+    /// Fixed types for video frame rendering.
+
+    /// Render the pixels using this renderer
+    typedef typename agg::renderer_base<PixelFormat> Renderer;
+    typedef agg::span_interpolator_linear<> Interpolator;
+    typedef agg::span_allocator<agg::rgba8> SpanAllocator;
+    typedef agg::rasterizer_scanline_aa<> Rasterizer;
+    
+    // cloning image accessor is used to avoid disturbing pixels at
+    // the edges for rotated video. 
+    typedef agg::image_accessor_clone<SourceFormat> Accessor;
+
+    /// Types used for different quality.
+    //
+    /// This (affects scaling) is only presently used when smoothing is
+    /// requested in high quality.
+    typedef agg::span_image_filter_rgb_nn<Accessor, Interpolator>
+        LowQualityFilter;
+
+    typedef agg::span_image_filter_rgb_bilinear<Accessor, Interpolator>
+        HighQualityFilter;
+
+    typedef agg::trans_affine Matrix;
+
+    VideoRenderer(const ClipBounds& clipbounds, GnashImage* frame,
+            Matrix& mat, Quality quality)
+        :
+        _buf(frame->data(), frame->width(), frame->height(),
+                frame->pitch()),
+        _pixf(_buf),
+        _accessor(_pixf),
+        _interpolator(mat),
+        _clipbounds(clipbounds),
+        _quality(quality)
+    {}
+
+    /// Change the rendering quality required.
+    void setQuality(Quality quality)
+    {
+        _quality = quality;
+    }
+
+    /// Set whether smoothing is requested
+    void smooth(bool b)
+    {
+        _smoothing = b;
+    }
+
+    void render(agg::path_storage& path, Renderer& rbase,
+            const AlphaMasks& masks)
+    {
+        switch (_quality)
+        {
+            case QUALITY_BEST:
+            case QUALITY_HIGH:
+                if (_smoothing) {
+                    renderFrame<HighQualityFilter>(path, rbase, masks);
+                }
+                else renderFrame<LowQualityFilter>(path, rbase, masks);
+                break;
+            case QUALITY_MEDIUM:
+            case QUALITY_LOW:
+                // FIXME: Should this be still lower quality?
+                renderFrame<LowQualityFilter>(path, rbase, masks);
+                break;
+        }
+    }
+    
+private:
+
+    /// Render a frame with or without alpha masks active.
+    template<typename SpanGenerator>
+    void renderFrame(agg::path_storage& path, Renderer& rbase,
+            const AlphaMasks& masks)
+    {
+        SpanGenerator sg(_accessor, _interpolator);
+        if (masks.empty()) {
+            // No mask active
+            agg::scanline_u8 sl;
+            renderScanlines(path, rbase, sl, sg);
+        }
+        else {
+            // Untested.
+            typedef agg::scanline_u8_am<agg::alpha_mask_gray8> Scanline;
+            Scanline sl(masks.back()->getMask());
+            renderScanlines(path, rbase, sl, sg);
+        }
+    } 
+
+    template<typename Scanline, typename SpanGenerator>
+    void renderScanlines(agg::path_storage& path, Renderer& rbase,
+            Scanline& sl, SpanGenerator& sg)
+    {
+        Rasterizer _ras;
+        for (ClipBounds::const_iterator i = _clipbounds.begin(),
+            e = _clipbounds.end(); i != e; ++i)
+        {
+            const ClipBounds::value_type& cb = *i;
+            applyClipBox<Rasterizer> (_ras, cb);
+
+            _ras.add_path(path);
+
+            agg::render_scanlines_aa(_ras, sl, rbase, _sa, sg);
+        }
+    }
+    
+    // rendering buffer is used to access the frame pixels here        
+    agg::rendering_buffer _buf;
+
+    SourceFormat _pixf;
+    
+    Accessor _accessor;
+         
+    Interpolator _interpolator;
+    
+    SpanAllocator _sa;
+
+    const ClipBounds& _clipbounds;
+
+    /// Quality of renderering
+    Quality _quality;
+
+    /// Whether smoothing is required.
+    bool _smoothing;
+};    
+            
 }
 
 
-// --- CACHE 
-------------------------------------------------------------------
-/// This class holds a completely transformed path (fixed position). Speeds
-/// up characters that stay fixed on a certain position on the stage. 
-// ***CURRENTLY***NOT***USED***
-
-class agg_transformed_path 
-{
-public:
-  /// Original transformation SWFMatrix 
-  SWFMatrix m_mat;  
-  
-  /// Normal or rounded coordinates?
-  bool m_rounded;
-  
-  /// Number of cache hits 
-  int m_hits;
-  
-  /// Contents of this cache item (AGG path).  
-  std::vector <agg::path_storage> m_data;
-};
-
-class agg_cache_manager : private render_cache_manager
-{
-
-  std::vector <agg_transformed_path> m_items;
-
-  /// Looks for a matching pre-computed path in the cache list
-  /// Returns NULL if no cache item matches 
-  std::vector <agg::path_storage>* search(const SWFMatrix& mat, bool rounded) {
-  
-    const size_t ccount = m_items.size();
-    
-    for (size_t cno=0; cno<ccount; ++cno) {    
-      agg_transformed_path& item = m_items[cno];
-          
-      if ((item.m_mat == mat) && (item.m_rounded == rounded)) {
-      
-        // Found it!
-        return &item.m_data;
-      
-      }    
-    }
-    
-    // could not find a matching item
-    return NULL;
-  
-  }
-  
-
-};
-
-
-
-
 // --- RENDER HANDLER 
----------------------------------------------------------
 // The class is implemented using templates so that it supports any kind of
 // pixel format. LUT (look up tables) are not supported, however.
@@ -357,160 +587,6 @@
 class render_handler_agg : public render_handler_agg_base
 {
   
-    typedef typename std::vector<geometry::Range2d<int> > ClipBounds;
-    typedef typename std::vector<AlphaMask*> AlphaMasks;
-
-private:
-    typedef agg::renderer_base<PixelFormat> renderer_base;
-
-    // renderer base
-    std::auto_ptr<renderer_base> m_rbase;
-
-    typedef agg::conv_stroke< agg::conv_curve<agg::path_storage> > stroke_type;
-
-    int xres;
-    int yres;
-    int bpp;  // bits per pixel
-    gnash::SWFMatrix stage_matrix;  // conversion from TWIPS to pixels
-    bool scale_set;
-
-
-    /// Class for rendering video frames.
-    //
-    /// Templated functions are used to allow using different types,
-    /// particularly for high and low quality rendering. 
-    //
-    /// At present, this is bound to the renderer's ClipBounds. In future it
-    /// may be useful to pass BlendMode, Cxform, and custom clipbounds as well
-    /// as a caller-provided rendering buffer. This also applies to the 
-    /// rest of the renderer API.
-    class VideoRenderer
-    {
-
-    public:
-
-        /// Fixed types for video frame rendering.
-        typedef agg::span_interpolator_linear<> Interpolator;
-        typedef agg::pixfmt_rgb24_pre BaseFormat;
-        typedef agg::span_allocator<agg::rgba8> SpanAllocator;
-        typedef agg::rasterizer_scanline_aa<> Rasterizer;
-        typedef agg::image_accessor_clone<BaseFormat> Accessor;
-
-        /// Types used for different quality.
-        //
-        /// This (affects scaling) is only presently used when smoothing is
-        /// requested in high quality.
-        typedef typename agg::span_image_filter_rgb_nn<Accessor,
-                Interpolator> LowQualityFilter;
-
-        typedef typename agg::span_image_filter_rgb_bilinear<Accessor,
-                Interpolator> HighQualityFilter;
-
-        typedef agg::trans_affine Matrix;
-
-        VideoRenderer(const ClipBounds& clipbounds, GnashImage* frame,
-                Matrix& mat, Quality quality)
-            :
-            _buf(frame->data(), frame->width(), frame->height(),
-                    frame->pitch()),
-            _pixf(_buf),
-            _accessor(_pixf),
-            _interpolator(mat),
-            _clipbounds(clipbounds),
-            _quality(quality)
-        {}
-
-        /// Change the rendering quality required.
-        void setQuality(Quality quality)
-        {
-            _quality = quality;
-        }
-
-        /// Set whether smoothing is requested
-        void smooth(bool b)
-        {
-            _smoothing = b;
-        }
-
-        void renderFrame(agg::path_storage& path, renderer_base& rbase,
-                const AlphaMasks& masks)
-        {
-            switch (_quality)
-            {
-                case QUALITY_BEST:
-                case QUALITY_HIGH:
-                    if (_smoothing) {
-                        renderFrame<HighQualityFilter>(path, rbase, masks);
-                    }
-                    else renderFrame<LowQualityFilter>(path, rbase, masks);
-                    break;
-                case QUALITY_MEDIUM:
-                case QUALITY_LOW:
-                    // FIXME: Should this be still lower quality?
-                    renderFrame<LowQualityFilter>(path, rbase, masks);
-                    break;
-            }
-        }
-        
-    private:
-
-        /// Render a frame with or without alpha masks active.
-        template<typename SpanGenerator>
-        void renderFrame(agg::path_storage& path, renderer_base& rbase,
-                const AlphaMasks& masks)
-        {
-            SpanGenerator sg(_accessor, _interpolator);
-            if (masks.empty()) {
-                // No mask active
-                agg::scanline_u8 sl;
-                renderScanlines(path, rbase, sl, sg);
-            }
-            else {
-                // Untested.
-                typedef agg::scanline_u8_am<agg::alpha_mask_gray8> Scanline;
-                Scanline sl(masks.back()->get_amask());
-                renderScanlines(path, rbase, sl, sg);
-            }
-        } 
-
-        template<typename Scanline, typename SpanGenerator>
-        void renderScanlines(agg::path_storage& path, renderer_base& rbase,
-                Scanline& sl, SpanGenerator& sg)
-        {
-            Rasterizer _ras;
-            for (ClipBounds::const_iterator i = _clipbounds.begin(),
-                e = _clipbounds.end(); i != e; ++i)
-            {
-                const ClipBounds::value_type& cb = *i;
-                applyClipBox<Rasterizer> (_ras, cb);
-
-                _ras.add_path(path);
-
-                agg::render_scanlines_aa(_ras, sl, rbase, _sa, sg);
-            }
-        }
-        
-        // rendering buffer is used to access the frame pixels here        
-        agg::rendering_buffer _buf;
-        BaseFormat _pixf;
-        
-        // cloning image accessor is used to avoid disturbing pixels at
-        // the edges for rotated video. 
-        Accessor _accessor;
-             
-        Interpolator _interpolator;
-        
-        SpanAllocator _sa;
- 
-        const ClipBounds& _clipbounds;
- 
-        /// Quality of renderering
-        Quality _quality;
- 
-        /// Whether smoothing is required.
-        bool _smoothing;
-    };    
-                
 public:
 
     // Given an image, returns a pointer to a bitmap_info class
@@ -539,7 +615,7 @@
         SWFMatrix mat = stage_matrix;
         mat.concatenate(*source_mat);
         
-        // compute video scaling relative to video obejct size
+        // compute video scaling relative to video object size
         double vscaleX = bounds->width() /
             static_cast<double>(frame->width());
         
@@ -557,12 +633,6 @@
         // Apply video scale
         img_mtx *= agg::trans_affine_scaling(1.0 / vscaleX, 1.0 / vscaleY);
         
-        // TODO: keep this alive and only update image / matrix? I've no
-        // idea how much reallocation that would save.
-        VideoRenderer vr(_clipbounds, frame, img_mtx, _quality);
-
-        vr.smooth(smooth);
-
         // make a path for the video outline
         point a, b, c, d;
         mat.transform(&a, point(bounds->get_x_min(), bounds->get_y_min()));
@@ -580,9 +650,15 @@
         // renderer base for the stage buffer (not the frame image!)
         renderer_base& rbase = *m_rbase;
         
+        // TODO: keep this alive and only update image / matrix? I've no
+        // idea how much reallocation that would save.
+        VideoRenderer<PixelFormat> vr(_clipbounds, frame, img_mtx, _quality);
+
+        vr.smooth(smooth);
+
         // If smoothing is requested and _quality is set to HIGH or BEST,
         // use high-quality interpolation.
-        vr.renderFrame(path, rbase, m_alpha_mask);
+        vr.render(path, rbase, _alphaMasks);
                 
     } 
 
@@ -605,11 +681,6 @@
     set_scale(1.0f, 1.0f);
   }   
 
-  // Destructor
-  ~render_handler_agg()
-  {
-  }
-
   /// Initializes the rendering buffer. The memory pointed by "mem" is not
   /// owned by the renderer and init_buffer() may be called multiple times
   /// when the buffer size changes, for example. However, bits_per_pixel must
@@ -653,9 +724,10 @@
     if ( ! _clipbounds.empty() )
     {
         const agg::rgba8& col = agg::rgba8_pre(bg.m_r, bg.m_g, bg.m_b, bg.m_a);
-        for (unsigned int i=0, n=_clipbounds.size(); i<n; ++i) 
+        for (ClipBounds::const_iterator i = _clipbounds.begin(),
+                e = _clipbounds.end(); i!= e; ++i) 
         {
-          clear_framebuffer(_clipbounds[i], col);
+            clear_framebuffer(*i, col);
         }
     }
     
@@ -663,179 +735,159 @@
     m_drawing_mask = false;
   }
   
-  /// renderer_base.clear() does no clipping which clears the whole framebuffer
-  /// even if we update just a small portion of the screen. The result would be
-  /// still correct, but slower. 
-  /// This function clears only a certain portion of the screen, while /not/ 
-  /// being notably slower for a fullscreen clear. 
-  void clear_framebuffer(const geometry::Range2d<int>& region,
+    // renderer_base.clear() does no clipping which clears the
+    // whole framebuffer even if we update just a small portion
+    // of the screen. The result would be still correct, but slower. 
+    // This function clears only a certain portion of the screen, while /not/ 
+    // being notably slower for a fullscreen clear. 
+    void clear_framebuffer(const geometry::Range2d<int>& region,
         const agg::rgba8& color)
-  {
-      assert(region.isFinite());
-      
-      // add 1 to width since we have still to draw a pixel when 
-      // getMinX==getMaxX     
-      unsigned int width=region.width()+1;
-      
-      // <Udo> Note: We don't need to check for width/height anymore because
-      // Range2d will take care that getMinX <= getMaxX and it's okay when
-      // region.width()==0 because in that case getMinX==getMaxX and we have
-      // still a pixel to draw. 
-
-      const unsigned int left=region.getMinX();
-
-      for (unsigned int y=region.getMinY(), maxy=region.getMaxY();
-        y<=maxy; ++y) 
-      {
-        m_pixf->copy_hline(left, y, width, color);
-      }
-  }
-
-  void  end_display()
-  // Clean up after rendering a frame.  Client program is still
-  // responsible for calling glSwapBuffers() or whatever.
-  {
-  
-    if (m_drawing_mask) 
-      log_debug(_("Warning: rendering ended while drawing a mask"));
-      
-    while (! m_alpha_mask.empty()) {
-      log_debug(_("Warning: rendering ended while masks were still active"));
-      disable_mask();      
-    }
-  
-    // nothing to do
-  }
-
-  
-  // Draw the line strip formed by the sequence of points.
-  void draw_line_strip(const boost::int16_t* coords, int vertex_count,
-          const rgba& color, const SWFMatrix& line_mat)
-  {
-    assert(m_pixf.get());
-
-    SWFMatrix mat = stage_matrix;
-    mat.concatenate(line_mat);    
-
-    if ( _clipbounds.empty() ) return;
-
-    point pnt;
-    
-    renderer_base& rbase = *m_rbase;
-    
-    typedef agg::rasterizer_scanline_aa<> ras_type;
-    ras_type ras;    
-
-    // TODO: avoid reconstructing scanline_aa_solid ?
-    agg::renderer_scanline_aa_solid<
-      agg::renderer_base<PixelFormat> > ren_sl(rbase);
-      
-    // -- create path --
-    agg::path_storage path;
-    agg::conv_stroke<agg::path_storage> stroke(path);
-    stroke.width(1);
-    stroke.line_cap(agg::round_cap);
-    stroke.line_join(agg::round_join);
-    path.remove_all(); // Not obligatory in this case
-
-    const boost::int16_t *vertex = coords;
-    
-    mat.transform(&pnt, point(vertex[0], vertex[1]));
-    path.move_to(pnt.x, pnt.y);
-
-    for (vertex += 2;  vertex_count > 1;  vertex_count--, vertex += 2) {
-      mat.transform(&pnt, point(vertex[0], vertex[1]));
-      path.line_to(pnt.x, pnt.y);
-    }
-    
-    // -- render --
-    
-    if (m_alpha_mask.empty()) {
-    
-      // No mask active
-      
-      agg::scanline_p8 sl;      
-      
-      for (unsigned int cno=0; cno<_clipbounds.size(); ++cno) {
-      
-        const ClipBounds::value_type& bounds = _clipbounds[cno];
-              
-        applyClipBox<ras_type> (ras, bounds);
-        
-        // The vectorial pipeline
-        ras.add_path(stroke);
-    
-        // Set the color and render the scanlines
-        ren_sl.color(agg::rgba8_pre(color.m_r, color.m_g, color.m_b, 
color.m_a));
-        
-        agg::render_scanlines(ras, sl, ren_sl);     
-        
-      }
-      
-    } else {
-    
-      // Mask is active!
-
-      typedef agg::scanline_u8_am<agg::alpha_mask_gray8> sl_type;
-      
-      sl_type sl(m_alpha_mask.back()->get_amask());      
-      
-      for (unsigned int cno=0; cno<_clipbounds.size(); ++cno) {
-      
-        const ClipBounds::value_type& bounds = _clipbounds[cno];
-              
-        applyClipBox<ras_type> (ras, bounds);
-        
-        // The vectorial pipeline
-        ras.add_path(stroke);
-    
-        // Set the color and render the scanlines
-        ren_sl.color(agg::rgba8_pre(color.m_r, color.m_g, color.m_b, 
color.m_a));
-        
-        agg::render_scanlines(ras, sl, ren_sl);     
-        
-      }
-    
-    }
-
-  } // draw_line_strip
-
-
-  void begin_submit_mask()
-  {
-    // Set flag so that rendering of shapes is simplified (only solid fill) 
-    m_drawing_mask = true;
-    
-    AlphaMask* new_mask = new AlphaMask(xres, yres);
-    
-    for (unsigned int cno=0; cno<_clipbounds.size(); ++cno)  
-      new_mask->clear(_clipbounds[cno]);
-    
-    m_alpha_mask.push_back(new_mask);
-    
-  }
-
-  void end_submit_mask()
-  {
-    m_drawing_mask = false;
-  }
-
-  void disable_mask()
-  {
-      assert( ! m_alpha_mask.empty() );
-      delete m_alpha_mask.back();
-      m_alpha_mask.pop_back();
-  }
+    {
+        assert(region.isFinite());
+
+        // add 1 to width since we have still to draw a pixel when 
+        // getMinX==getMaxX     
+        unsigned int width=region.width()+1;
+
+        // <Udo> Note: We don't need to check for width/height anymore because
+        // Range2d will take care that getMinX <= getMaxX and it's okay when
+        // region.width()==0 because in that case getMinX==getMaxX and we have
+        // still a pixel to draw. 
+
+        const unsigned int left=region.getMinX();
+
+        for (unsigned int y=region.getMinY(), maxy=region.getMaxY();
+            y<=maxy; ++y) {
+              m_pixf->copy_hline(left, y, width, color);
+        }
+    }
+
+    // Clean up after rendering a frame. 
+    void end_display()
+    {
+        if (m_drawing_mask) {
+            log_debug(_("Warning: rendering ended while drawing a mask"));
+        }
+
+        while (! _alphaMasks.empty()) {
+            log_debug(_("Warning: rendering ended while masks "
+                        "were still active"));
+            disable_mask();      
+        }
+    }
+
+  
+
+    // Draw the line strip formed by the sequence of points.
+    void drawLine(const std::vector<point>& coords, const rgba& color,
+            const SWFMatrix& line_mat)
+    {
+
+        assert(m_pixf.get());
+        
+        if (_clipbounds.empty()) return;
+        if (coords.empty()) return;
+
+        SWFMatrix mat = stage_matrix;
+        mat.concatenate(line_mat);    
+
+        LineRenderer<PixelFormat> lr(_clipbounds, *m_rbase);
+
+        // -- create path --
+        agg::path_storage path;
+
+        typename LineRenderer<PixelFormat>::Stroke stroke(path);
+        stroke.width(1);
+        stroke.line_cap(agg::round_cap);
+        stroke.line_join(agg::round_join);
+
+        typedef std::vector<point> Points;
+        
+        // We've asserted that it has at least one element.
+        Points::const_iterator i = coords.begin();
+
+        point pnt;
+
+        mat.transform(&pnt, *i);
+        path.move_to(pnt.x, pnt.y);
+
+        ++i;
+
+        for (const Points::const_iterator e = coords.end(); i != e; ++i)
+        {
+            mat.transform(&pnt, *i);
+            path.line_to(pnt.x, pnt.y);
+        }
+
+        if (_alphaMasks.empty()) {
+            // No mask active
+            agg::scanline_p8 sl;      
+            lr.render(sl, stroke, color);
+        }
+        else {
+            // Mask is active!
+            typedef agg::scanline_u8_am<agg::alpha_mask_gray8> sl_type;
+            sl_type sl(_alphaMasks.back()->getMask());      
+            lr.render(sl, stroke, color);
+        }
+
+    } 
+
+
+    void begin_submit_mask()
+    {
+        // Set flag so that rendering of shapes is simplified (only solid 
fill) 
+        m_drawing_mask = true;
+
+        AlphaMask* new_mask = new AlphaMask(xres, yres);
+
+        for (ClipBounds::const_iterator i = _clipbounds.begin(), 
+                e = _clipbounds.end(); i != e; ++i) {
+            new_mask->clear(*i);
+        }
+
+        _alphaMasks.push_back(new_mask);
+    }
+
+    void end_submit_mask()
+    {
+        m_drawing_mask = false;
+    }
+
+    void disable_mask()
+    {
+        assert( ! _alphaMasks.empty() );
+        delete _alphaMasks.back();
+        _alphaMasks.pop_back();
+    }
   
 
   void draw_glyph(shape_character_def *def,
       const SWFMatrix& mat, const rgba& color) 
   {
-    std::vector<path> paths;
+    
+    // select relevant clipping bounds
+    if (def->get_bound().is_null()) {
+        return;
+        // Why would we want to do this?
+        //select_all_clipbounds();  
+    } 
+    else select_clipbounds(def, mat);
+    
+    if (_clipbounds_selected.empty()) return; 
+      
+    GnashPaths paths;
     apply_matrix_to_path(def->get_paths(), paths, mat);
+
+    // If it's a mask, we don't need the rest.
+    if (m_drawing_mask) {
+      draw_mask_shape(paths, false);
+      return;
+    }
+
     // convert gnash paths to agg paths.
     std::vector<agg::path_storage> agg_paths;    
-    build_agg_paths(agg_paths, paths);
+    buildPaths(agg_paths, paths);
  
     // make sure m_single_fill_styles contains the required color 
     need_single_fill_style(color);
@@ -844,20 +896,7 @@
     agg_style_handler sh;
     build_agg_styles(sh, m_single_fill_styles, mat, m_neutral_cxform);
     
-    // select relevant clipping bounds
-    if (def->get_bound().is_null())   // can happen (spaces? to be 
investigated..)
-      select_all_clipbounds();
-    else
-      select_clipbounds(def, mat);
-    
-    
-    if (_clipbounds_selected.empty()) return; // nothing to draw
-      
-    // draw the shape
-    if (m_drawing_mask)
-      draw_mask_shape(paths, false);
-    else
-      draw_shape(-1, paths, agg_paths, sh, false);
+    draw_shape(-1, paths, agg_paths, sh, false);
     
     // NOTE: Do not use even-odd filling rule for glyphs!
     
@@ -883,8 +922,8 @@
     const rect& ch_bounds = def->get_bound();
 
     if (ch_bounds.is_null()) {
-      log_debug(_("Warning: select_clipbounds encountered a character 
definition "
-        "with null bounds"));
+      log_debug(_("Warning: select_clipbounds encountered a character "
+                  "definition with null bounds"));
       return;
     }   
 
@@ -915,149 +954,118 @@
   
   void select_all_clipbounds() {
   
-    const unsigned int count = _clipbounds.size();
-
-    if (_clipbounds_selected.size() == count)
-      return; // already all selected
+    if (_clipbounds_selected.size() == _clipbounds.size()) return; 
   
     _clipbounds_selected.clear();
-    _clipbounds_selected.resize(count);
+    _clipbounds_selected.reserve(_clipbounds.size());
     
-    for (unsigned int cno=0; cno<count; ++cno) 
-      _clipbounds_selected[cno] = &_clipbounds[cno];
+    for (ClipBounds::const_iterator i = _clipbounds.begin(),
+            e = _clipbounds.end(); i != e; ++i)
+    {
+      _clipbounds_selected.push_back(&(*i));
+    }
   }
 
-  void draw_shape_character(shape_character_def *def, 
-    const SWFMatrix& mat,
-    const cxform& cx,
+    void draw_shape_character(shape_character_def *def, 
+    const SWFMatrix& mat, const cxform& cx,
     const std::vector<fill_style>& fill_styles,
-    const std::vector<line_style>& line_styles) {
-    
-    bool have_shape, have_outline;
-
-    analyze_paths(def->get_paths(), have_shape, have_outline);
-
-    if (!have_shape && !have_outline)
-    {
-        return; // invisible character
-    }    
-
-    std::vector< path > paths;
-    std::vector< agg::path_storage > agg_paths;  
-    std::vector< agg::path_storage > agg_paths_rounded;  
-
-    apply_matrix_to_path(def->get_paths(), paths, mat);
-    //assert(def->get_paths().size() == paths.size());
-
-    // Flash only aligns outlines. Probably this is done at rendering
-    // level.
-    if (have_outline)
-      build_agg_paths_rounded(agg_paths_rounded, paths, line_styles);   
-    if (have_shape)
-      build_agg_paths(agg_paths, paths);
-    
-    if (m_drawing_mask) {
-      
-      // Shape is drawn inside a mask, skip sub-shapes handling and outlines
-      draw_mask_shape(paths, false);   // never use even-odd for masks
-    
-    } else {
-    
-      // select ranges
-      select_clipbounds(def, mat);
-      
-      if (_clipbounds_selected.empty()) {
-        log_debug(_("Warning: AGG renderer skipping a whole character"));
-        return; // nothing to draw!?
-      }
-    
-      // prepare fill styles
-      agg_style_handler sh;
-      if (have_shape)
-        build_agg_styles(sh, fill_styles, mat, cx);
-      
-      // We need to separate sub-shapes during rendering. 
-      const unsigned int subshape_count = count_sub_shapes(paths);
-     
-      for (unsigned int subshape=0; subshape<subshape_count; ++subshape)
-      {
-        if (have_shape)
-        {
-          draw_shape(subshape, paths, agg_paths, sh, true);    
-        }
-        if (have_outline)      
-        {
-          draw_outlines(subshape, paths, agg_paths_rounded, line_styles, cx, 
mat);
-        }
-      }
-      
-    } // if not drawing mask
-    
-    // Clear selected clipbounds to ease debugging 
-    _clipbounds_selected.clear();
-    
-  } // draw_shape_character
-  
-  
-  /// Analyzes a set of paths to detect real presence of fills and/or outlines
-  /// TODO: This should be something the character tells us and should be 
-  /// cached. 
-  void analyze_paths(const std::vector<path> &paths, bool& have_shape,
-    bool& have_outline) {
-    
-    have_shape=false;
-    have_outline=false;
-    
-    const int pcount = paths.size();
-    
-    for (int pno=0; pno<pcount; ++pno) {
-    
-      const path &the_path = paths[pno];
-    
-      if ((the_path.m_fill0>0) || (the_path.m_fill1>0)) {
-        have_shape=true;
-        if (have_outline) return; // have both
-      }
-    
-      if (the_path.m_line>0) {
-        have_outline=true;
-        if (have_shape) return; // have both
-      }
-    
-    }
-    
-  }
-
-/// Takes a path and translates it using the given SWFMatrix. The new path
-/// is stored in paths_out. Both paths_in and paths_out are expected to
-/// be in TWIPS.
-void apply_matrix_to_path(const std::vector<path> &paths_in, 
-      std::vector<path>& paths_out, const SWFMatrix &source_mat) 
-{
-
-    SWFMatrix mat;
-    // make sure paths_out is also in TWIPS to keep accuracy.
-    mat.concatenate_scale(20.0,  20.0);
-    mat.concatenate(stage_matrix);
-    mat.concatenate(source_mat);
-
-    //size_t pcnt = paths_in.size();
-    paths_out = paths_in; // copy paths, then transform in place
-    typedef std::vector<path> PathVect;
-    for (PathVect::iterator i=paths_out.begin(), e=paths_out.end(); i!=e; ++i)
-    {
-        path  &p = *i;
-        p.transform(mat);
-        //paths_out.push_back( p );
-    }
-} // apply_matrix
+    const std::vector<line_style>& line_styles)
+    {
+    
+        bool have_shape, have_outline;
+
+        analyzePaths(def->get_paths(), have_shape, have_outline);
+
+        if (!have_shape && !have_outline) {
+            // Early return for invisible character.
+            return; 
+        }    
+
+        GnashPaths paths;
+        apply_matrix_to_path(def->get_paths(), paths, mat);
+
+        // Masks apparently do not use agg_paths, so return
+        // early
+        if (m_drawing_mask) {
+
+            // Shape is drawn inside a mask, skip sub-shapes handling and
+            // outlines
+            draw_mask_shape(paths, false); 
+            return;
+        }
+
+        std::vector<agg::path_storage> agg_paths;  
+        std::vector<agg::path_storage> agg_paths_rounded;  
+
+        // Flash only aligns outlines. Probably this is done at rendering
+        // level.
+        if (have_outline) {
+            buildPaths_rounded(agg_paths_rounded, paths, line_styles);   
+        }
+
+        if (have_shape) {
+            buildPaths(agg_paths, paths);
+        }
+        
+        // select ranges
+        select_clipbounds(def, mat);
+
+        if (_clipbounds_selected.empty()) {
+            log_debug(_("Warning: AGG renderer skipping a whole character"));
+            return; 
+        }
+
+        // prepare fill styles
+        agg_style_handler sh;
+        if (have_shape) build_agg_styles(sh, fill_styles, mat, cx);
+
+        // We need to separate sub-shapes during rendering. 
+        const unsigned int subshape_count = count_sub_shapes(paths);
+
+        for (unsigned int subshape=0; subshape<subshape_count; ++subshape)
+        {
+            if (have_shape) {
+                draw_shape(subshape, paths, agg_paths, sh, true);    
+            }
+            if (have_outline)      {
+                draw_outlines(subshape, paths, agg_paths_rounded,
+                        line_styles, cx, mat);
+            }
+        }
+
+        // Clear selected clipbounds to ease debugging 
+        _clipbounds_selected.clear();
+
+    } // draw_shape_character
+  
+  
+    /// Takes a path and translates it using the given SWFMatrix. The new path
+    /// is stored in paths_out. Both paths_in and paths_out are expected to
+    /// be in TWIPS.
+    void apply_matrix_to_path(const GnashPaths &paths_in, 
+          GnashPaths& paths_out, const SWFMatrix &source_mat) 
+    {
+
+        SWFMatrix mat;
+        // make sure paths_out is also in TWIPS to keep accuracy.
+        mat.concatenate_scale(20.0,  20.0);
+        mat.concatenate(stage_matrix);
+        mat.concatenate(source_mat);
+
+        // Copy paths for in-place transform
+        paths_out = paths_in;
+
+        /// Transform all the paths using the matrix.
+        std::for_each(paths_out.begin(), paths_out.end(), 
+                std::bind2nd(std::mem_fun_ref(&path::transform), mat));
+    } 
 
 
   /// A shape can have sub-shapes. This can happen when there are multiple
   /// layers of the same frame count. Flash combines them to one single shape.
   /// The problem with sub-shapes is, that outlines can be hidden by other
   /// layers so they must be rendered separately. 
-  unsigned int count_sub_shapes(const std::vector<path> &path_in)
+  unsigned int count_sub_shapes(const GnashPaths &path_in)
   {
     unsigned int sscount=1;
     const size_t pcnt = path_in.size();
@@ -1072,45 +1080,7 @@
     return sscount;
   }
 
-  /// Transposes Gnash paths to AGG paths, which can be used for both outlines
-  /// and shapes. Subshapes are ignored (ie. all paths are converted). 
Converts 
-  /// TWIPS to pixels on the fly.
-  void build_agg_paths(std::vector<agg::path_storage>& dest, const 
std::vector<path>& paths) 
-  {
-    //const double subpixel_offset = 0.5; // unused, should be ?
-    size_t pcnt = paths.size();
-    dest.resize(pcnt);
-    
-    for (size_t pno=0; pno<pcnt; ++pno)
-    {
-        const path& path_in_sub = paths[pno]; 
-        agg::path_storage& new_path = dest[pno];
-
-        new_path.move_to(TWIPS_TO_SHIFTED_PIXELS(path_in_sub.ap.x), 
-                          TWIPS_TO_SHIFTED_PIXELS(path_in_sub.ap.y));
-
-        const size_t ecnt = path_in_sub.m_edges.size();
-        for (size_t eno=0; eno<ecnt; ++eno)
-        {
-            const edge& this_edge = path_in_sub.m_edges[eno];             
-            if (this_edge.is_straight())
-            {
-                new_path.line_to(TWIPS_TO_SHIFTED_PIXELS(this_edge.ap.x), 
-                                  TWIPS_TO_SHIFTED_PIXELS(this_edge.ap.y));
-            }
-            else
-            {
-                new_path.curve3(TWIPS_TO_SHIFTED_PIXELS(this_edge.cp.x), 
-                                 TWIPS_TO_SHIFTED_PIXELS(this_edge.cp.y),
-                                 TWIPS_TO_SHIFTED_PIXELS(this_edge.ap.x), 
-                                 TWIPS_TO_SHIFTED_PIXELS(this_edge.ap.y));     
  
-            }
-        }// end of for    
-    } // end of for  
-    
-  } //build_agg_paths
-
-  // Version of build_agg_paths that uses rounded coordinates (pixel hinting)
+  // Version of buildPaths that uses rounded coordinates (pixel hinting)
   // for line styles that want it.  
   // This is used for outlines which are aligned to the pixel grid to avoid
   // anti-aliasing problems (a perfect horizontal line being drawn over two
@@ -1122,14 +1092,14 @@
   // Also, single segments of a path may be aligned or not depending on 
   // the segment properties (this matches MM player behaviour)
   //
-  // This function - in contrast to build_agg_paths() - also checks noClose 
+  // This function - in contrast to buildPaths() - also checks noClose 
   // flag and automatically closes polygons.
   //
   // TODO: Flash never aligns lines that are wider than 1 pixel on *screen*,
   // but we currently don't check the width.  
-  void build_agg_paths_rounded(std::vector<agg::path_storage>& dest, 
-    const std::vector< path >& paths, 
-    const std::vector<line_style>& line_styles) {
+  void buildPaths_rounded(std::vector<agg::path_storage>& dest, 
+    const GnashPaths& paths, const std::vector<line_style>& line_styles)
+  {
 
     const float subpixel_offset = 0.5f;
     
@@ -1166,7 +1136,7 @@
 
       // avoid extra edge when doing implicit close later
       if (closed && ecount && 
-        this_path.m_edges.back().is_straight()) ecount--;      
+        this_path.m_edges.back().is_straight()) --ecount;  
       
       for (size_t eno=0; eno<ecount; ++eno) {
         
@@ -1262,7 +1232,7 @@
         new_path.close_polygon();
     
     }
-  } //build_agg_paths_rounded
+  } //buildPaths_rounded
     
   // Initializes the internal styles class for AGG renderer
   void build_agg_styles(agg_style_handler& sh, 
@@ -1347,8 +1317,10 @@
         {            
           rgba color = cx.transform(fill_styles[fno].get_color());
 
-          // add the color to our self-made style handler (basically just a 
list)
-          sh.add_color(agg::rgba8_pre(color.m_r, color.m_g, color.m_b, 
color.m_a));
+          // add the color to our self-made style handler (basically
+          // just a list)
+          sh.add_color(agg::rgba8_pre(color.m_r, color.m_g, color.m_b,
+                      color.m_a));
         } 
         
       } // switch
@@ -1373,11 +1345,11 @@
   /// @param subshape_id
   ///    Defines which subshape to draw. -1 means all subshapes.
   ///
-  void draw_shape(int subshape_id, const std::vector<path> &paths,
+  void draw_shape(int subshape_id, const GnashPaths &paths,
     const std::vector<agg::path_storage>& agg_paths,  
     agg_style_handler& sh, int even_odd) {
     
-    if (m_alpha_mask.empty()) {
+    if (_alphaMasks.empty()) {
     
       // No mask active, use normal scanline renderer
       
@@ -1394,7 +1366,7 @@
       
       typedef agg::scanline_u8_am<agg::alpha_mask_gray8> scanline_type;
       
-      scanline_type sl(m_alpha_mask.back()->get_amask());
+      scanline_type sl(_alphaMasks.back()->getMask());
       
       draw_shape_impl<scanline_type> (subshape_id, paths, agg_paths, 
         sh, even_odd, sl);
@@ -1407,7 +1379,7 @@
   /// one with and one without an alpha mask. This makes drawing without masks
   /// much faster.  
   template <class scanline_type>
-  void draw_shape_impl(int subshape_id, const std::vector<path> &paths,
+  void draw_shape_impl(int subshape_id, const GnashPaths &paths,
     const std::vector<agg::path_storage>& agg_paths,
     agg_style_handler& sh, int even_odd, scanline_type& sl) {
     /*
@@ -1485,8 +1457,6 @@
         rasc.add_path(curve);
       
       }
-      //log_debug("%d edges\n", edge_count);
-      
               
       agg::render_scanlines_compound_layered(rasc, sl, rbase, alloc, sh);
     }
@@ -1498,9 +1468,10 @@
 
   // very similar to draw_shape but used for generating masks. There are no
   // fill styles nor subshapes and such. Just render plain solid shapes.
-  void draw_mask_shape(const std::vector<path> &paths, int even_odd) {
+  void draw_mask_shape(const GnashPaths &paths, int even_odd)
+  {
 
-    unsigned int mask_count = m_alpha_mask.size();
+    unsigned int mask_count = _alphaMasks.size();
     
     if (mask_count < 2) {
     
@@ -1519,7 +1490,7 @@
       
       typedef agg::scanline_u8_am<agg::alpha_mask_gray8> scanline_type;
       
-      scanline_type sl(m_alpha_mask[mask_count-2]->get_amask());
+      scanline_type sl(_alphaMasks[mask_count-2]->getMask());
       
       draw_mask_shape_impl<scanline_type> (paths, even_odd, sl);
         
@@ -1529,13 +1500,13 @@
   
   
   template <class scanline_type>
-  void draw_mask_shape_impl(const std::vector<path> &paths, int even_odd,
+  void draw_mask_shape_impl(const GnashPaths &paths, int even_odd,
     scanline_type& sl) {
     
     typedef agg::pixfmt_gray8 pixfmt;
     typedef agg::renderer_base<pixfmt> renderer_base;
     
-    assert(!m_alpha_mask.empty());
+    assert(!_alphaMasks.empty());
     
     // dummy style handler
     typedef agg_mask_style_handler sh_type;
@@ -1546,7 +1517,7 @@
     rasc_type rasc;
     
     // renderer base
-    renderer_base& rbase = m_alpha_mask.back()->get_rbase();
+    renderer_base& rbase = _alphaMasks.back()->get_rbase();
     
     // solid fills
     typedef agg::renderer_scanline_aa_solid< renderer_base > ren_sl_type;
@@ -1554,7 +1525,7 @@
     
     // span allocator
     typedef agg::span_allocator<agg::gray8> alloc_type;
-    alloc_type alloc;   // why does gray8 not work?
+    alloc_type alloc; 
       
 
     // activate even-odd filling rule
@@ -1565,7 +1536,7 @@
       
     
     // push paths to AGG
-    agg::path_storage path; // be carefull about this name 
+    agg::path_storage path; // be careful about this name 
     agg::conv_curve< agg::path_storage > curve(path);
 
     for (size_t pno=0, pcount=paths.size(); pno < pcount; ++pno) {
@@ -1612,12 +1583,12 @@
 
 
   /// Just like draw_shapes() except that it draws an outline.
-  void draw_outlines(int subshape_id, const std::vector<path> &paths,
+  void draw_outlines(int subshape_id, const GnashPaths &paths,
     const std::vector<agg::path_storage>& agg_paths,
     const std::vector<line_style> &line_styles, const cxform& cx,
     const SWFMatrix& linestyle_matrix) {
     
-    if (m_alpha_mask.empty()) {
+    if (_alphaMasks.empty()) {
     
       // No mask active, use normal scanline renderer
       
@@ -1634,7 +1605,7 @@
       
       typedef agg::scanline_u8_am<agg::alpha_mask_gray8> scanline_type;
       
-      scanline_type sl(m_alpha_mask.back()->get_amask());
+      scanline_type sl(_alphaMasks.back()->getMask());
       
       draw_outlines_impl<scanline_type> (subshape_id, paths, agg_paths,
         line_styles, cx, linestyle_matrix, sl);
@@ -1646,7 +1617,7 @@
 
   /// Template for draw_outlines(), see draw_shapes_impl().
   template <class scanline_type>
-  void draw_outlines_impl(int subshape_id, const std::vector<path> &paths,
+  void draw_outlines_impl(int subshape_id, const GnashPaths &paths,
     const std::vector<agg::path_storage>& agg_paths,
     const std::vector<line_style> &line_styles, const cxform& cx, 
     const SWFMatrix& linestyle_matrix, scanline_type& sl) {
@@ -1663,11 +1634,8 @@
     // when there really are no outlines to draw...
     
     // use avg between x and y scale
-    const float stroke_scale =
-      (fabsf(linestyle_matrix.get_x_scale()) + 
-       fabsf(linestyle_matrix.get_y_scale())) 
-      / 2.0f
-      * get_stroke_scale();
+    const float stroke_scale = (std::abs(linestyle_matrix.get_x_scale()) + 
+       std::abs(linestyle_matrix.get_y_scale())) / 2.0f * get_stroke_scale();
     
     
     // AGG stuff
@@ -1850,13 +1818,13 @@
   void draw_poly(const point* corners, size_t corner_count, const rgba& fill, 
     const rgba& outline, const SWFMatrix& mat, bool masked) {
     
-    if (masked && !m_alpha_mask.empty()) {
+    if (masked && !_alphaMasks.empty()) {
     
       // apply mask
       
       typedef agg::scanline_u8_am<agg::alpha_mask_gray8> sl_type; 
       
-      sl_type sl(m_alpha_mask.back()->get_amask());
+      sl_type sl(_alphaMasks.back()->getMask());
          
       draw_poly_impl<sl_type> (corners, corner_count, fill, outline, sl, mat); 
      
     
@@ -2020,40 +1988,37 @@
     return bpp/8;
   }  
   
-private:  // private methods  
-
-  /// Returns the cache manager instance of the given character definition.
-  /// Allocates a new manager if necessary.
-  agg_cache_manager* get_cache_of(character_def* def) {
-  
-    if (def->m_render_cache == NULL) {
-      def->m_render_cache = new agg_cache_manager;
-    }
-    
-    return def->m_render_cache;
-  
-  }
-  
 private:  // private variables
 
-  // Output size.
-  float m_display_width;
-  float m_display_height;
-
-  agg::rendering_buffer m_rbuf;  
-
-  std::auto_ptr<PixelFormat> m_pixf;
-  
-  /// clipping rectangle
-  ClipBounds _clipbounds;
-  std::vector< geometry::Range2d<int>* > _clipbounds_selected;
-  
-  // this flag is set while a mask is drawn
-  bool m_drawing_mask; 
-  
-  // Alpha mask stack
-  AlphaMasks m_alpha_mask;
-};  // end class render_handler_agg
+    typedef agg::renderer_base<PixelFormat> renderer_base;
+
+    // renderer base
+    std::auto_ptr<renderer_base> m_rbase;
+
+    int xres;
+    int yres;
+    int bpp;  // bits per pixel
+    gnash::SWFMatrix stage_matrix;  // conversion from TWIPS to pixels
+    bool scale_set;
+
+    // Output size.
+    float m_display_width;
+    float m_display_height;
+
+    agg::rendering_buffer m_rbuf;  
+
+    std::auto_ptr<PixelFormat> m_pixf;
+
+    /// clipping rectangle
+    ClipBounds _clipbounds;
+    std::vector< geometry::Range2d<int>* > _clipbounds_selected;
+
+    // this flag is set while a mask is drawn
+    bool m_drawing_mask; 
+
+    // Alpha mask stack
+    AlphaMasks _alphaMasks;
+};
 
 
 

=== removed file 'backend/render_handler_agg_compat.h'
--- a/backend/render_handler_agg_compat.h       2006-10-09 15:23:45 +0000
+++ b/backend/render_handler_agg_compat.h       1970-01-01 00:00:00 +0000
@@ -1,202 +0,0 @@
-#ifndef GNASH_AGG_RENDERER_SCANLINE_INCLUDED
-#define GNASH_AGG_RENDERER_SCANLINE_INCLUDED
-
-//
-// This file has been included to support the AGG2 package
-// found in debian testing, which laks the
-// render_scanlines_coumpund_layered function
-//
-// It should only define it if not defined, but dunno how to check ...
-//
-
-namespace agg {
-
-typedef unsigned char cover_type;
-
-    //=======================================render_scanlines_compound_layered
-    template<class Rasterizer, 
-             class ScanlineAA, 
-             class BaseRenderer, 
-             class SpanAllocator,
-             class StyleHandler>
-    void render_scanlines_compound_layered(Rasterizer& ras, 
-                                           ScanlineAA& sl_aa,
-                                           BaseRenderer& ren,
-                                           SpanAllocator& alloc,
-                                           StyleHandler& sh)
-    {
-        if(ras.rewind_scanlines())
-        {
-            int min_x = ras.min_x();
-            int len = ras.max_x() - min_x + 2;
-            sl_aa.reset(min_x, ras.max_x());
-
-            typedef typename BaseRenderer::color_type color_type;
-            color_type* color_span   = alloc.allocate(len * 2);
-            color_type* mix_buffer   = color_span + len;
-            cover_type* cover_buffer = ras.allocate_cover_buffer(len);
-            unsigned num_spans;
-
-            unsigned num_styles;
-            unsigned style;
-            bool     solid;
-            while((num_styles = ras.sweep_styles()) > 0)
-            {
-                typename ScanlineAA::const_iterator span_aa;
-                if(num_styles == 1)
-                {
-                    // Optimization for a single style. Happens often
-                    //-------------------------
-                    if(ras.sweep_scanline(sl_aa, 0))
-                    {
-                        style = ras.style(0);
-                        if(sh.is_solid(style))
-                        {
-                            // Just solid fill
-                            //-----------------------
-                            render_scanline_aa_solid(sl_aa, ren, 
sh.color(style));
-                        }
-                        else
-                        {
-                            // Arbitrary span generator
-                            //-----------------------
-                            span_aa   = sl_aa.begin();
-                            num_spans = sl_aa.num_spans();
-                            for(;;)
-                            {
-                                len = span_aa->len;
-                                sh.generate_span(color_span, 
-                                                 span_aa->x, 
-                                                 sl_aa.y(), 
-                                                 len, 
-                                                 style);
-
-                                ren.blend_color_hspan(span_aa->x, 
-                                                      sl_aa.y(), 
-                                                      span_aa->len,
-                                                      color_span,
-                                                      span_aa->covers);
-                                if(--num_spans == 0) break;
-                                ++span_aa;
-                            }
-                        }
-                    }
-                }
-                else
-                {
-                    int      sl_start = ras.scanline_start();
-                    unsigned sl_len   = ras.scanline_length();
-
-                    if(sl_len)
-                    {
-                        memset(mix_buffer + sl_start - min_x, 
-                               0, 
-                               sl_len * sizeof(color_type));
-
-                        memset(cover_buffer + sl_start - min_x, 
-                               0, 
-                               sl_len * sizeof(cover_type));
-
-                        int sl_y = 0x7FFFFFFF;
-                        unsigned i;
-                        for(i = 0; i < num_styles; i++)
-                        {
-                            style = ras.style(i);
-                            solid = sh.is_solid(style);
-
-                            if(ras.sweep_scanline(sl_aa, i))
-                            {
-                                unsigned    cover;
-                                color_type* colors;
-                                color_type* cspan;
-                                cover_type* src_covers;
-                                cover_type* dst_covers;
-                                span_aa   = sl_aa.begin();
-                                num_spans = sl_aa.num_spans();
-                                sl_y      = sl_aa.y();
-                                if(solid)
-                                {
-                                    // Just solid fill
-                                    //-----------------------
-                                    for(;;)
-                                    {
-                                        color_type c = sh.color(style);
-                                        len    = span_aa->len;
-                                        colors = mix_buffer + span_aa->x - 
min_x;
-                                        src_covers = span_aa->covers;
-                                        dst_covers = cover_buffer + span_aa->x 
- min_x;
-                                        do
-                                        {
-                                            cover = *src_covers;
-                                            if(*dst_covers + cover > 
cover_full)
-                                            {
-                                                cover = cover_full - 
*dst_covers;
-                                            }
-                                            if(cover)
-                                            {
-                                                colors->add(c, cover);
-                                                *dst_covers += cover;
-                                            }
-                                            ++colors;
-                                            ++src_covers;
-                                            ++dst_covers;
-                                        }
-                                        while(--len);
-                                        if(--num_spans == 0) break;
-                                        ++span_aa;
-                                    }
-                                }
-                                else
-                                {
-                                    // Arbitrary span generator
-                                    //-----------------------
-                                    for(;;)
-                                    {
-                                        len = span_aa->len;
-                                        colors = mix_buffer + span_aa->x - 
min_x;
-                                        cspan  = color_span;
-                                        sh.generate_span(cspan, 
-                                                         span_aa->x, 
-                                                         sl_aa.y(), 
-                                                         len, 
-                                                         style);
-                                        src_covers = span_aa->covers;
-                                        dst_covers = cover_buffer + span_aa->x 
- min_x;
-                                        do
-                                        {
-                                            cover = *src_covers;
-                                            if(*dst_covers + cover > 
cover_full)
-                                            {
-                                                cover = cover_full - 
*dst_covers;
-                                            }
-                                            if(cover)
-                                            {
-                                                colors->add(*cspan, cover);
-                                                *dst_covers += cover;
-                                            }
-                                            ++cspan;
-                                            ++colors;
-                                            ++src_covers;
-                                            ++dst_covers;
-                                        }
-                                        while(--len);
-                                        if(--num_spans == 0) break;
-                                        ++span_aa;
-                                    }
-                                }
-                            }
-                        }
-                        ren.blend_color_hspan(sl_start, 
-                                              sl_y, 
-                                              sl_len,
-                                              mix_buffer + sl_start - min_x,
-                                              0,
-                                              cover_full);
-                    } //if(sl_len)
-                } //if(num_styles == 1) ... else
-            } //while((num_styles = ras.sweep_styles()) > 0)
-        } //if(ras.rewind_scanlines())
-    }
-} // end of namespace agg
-
-#endif

=== modified file 'backend/render_handler_agg_style.h'
--- a/backend/render_handler_agg_style.h        2009-01-08 19:49:09 +0000
+++ b/backend/render_handler_agg_style.h        2009-01-21 08:45:36 +0000
@@ -40,18 +40,34 @@
 class agg_style_base 
 {
 public:
-  // for solid styles:
-  bool m_is_solid;   
-  agg::rgba8 m_color; // defined here for easy access
+
+  agg_style_base(bool solid, const agg::rgba8& color = agg::rgba8(0,0,0,0))
+    :
+    _solid(solid),
+    _color(color)
+  {
+  }
   
-  // for non-solid styles:
-  virtual void generate_span(agg::rgba8* span, int x, int y, unsigned len)=0;
-
   // Everytime a class has a virtual method it should
   // also have a virtual destructor. This will ensure
   // that the destructor for the *derived* class is invoked
   // when deleting a pointer to base class !!
   virtual ~agg_style_base() {}
+
+  bool solid() const { return _solid; }
+
+  agg::rgba8 color() const { return _color; }
+
+  // for non-solid styles:
+  virtual void generate_span(agg::rgba8* span, int x, int y, unsigned len) = 0;
+
+private:
+
+  // for solid styles:
+  bool _solid;
+
+  agg::rgba8 _color; 
+  
 };
 
 
@@ -61,10 +77,10 @@
 {
 public:
 
-  agg_style_solid(const agg::rgba8& color) {
-    m_is_solid = true;
-    m_color = color;
-    
+  agg_style_solid(const agg::rgba8& color)
+    :
+    agg_style_base(true, color)
+  {
 #ifdef DEBUG_LIMIT_COLOR_ALPHA
     m_color.a = m_color.a>127 ? 127 : m_color.a;
 #endif    
@@ -78,27 +94,6 @@
 };
 
 
-// Simple hack to get rid of that additional parameter for the 
-// image_accessor_clip constructor which breaks template usage. 
-/*
-template <class PixelFormat>
-class image_accessor_clip_transp : public agg::image_accessor_clip<PixelFormat>
-{
-public:
-  image_accessor_clip_transp(const PixelFormat& pixf)  
-  {
-    agg::image_accessor_clip<PixelFormat>::image_accessor_clip(pixf, 
-      agg::rgba8_pre(255, 0, 0, 0));
-  }
-};
-
-The image_accessor_clip_transp above does not work correctly. The alpha value
-for the background color supplied to image_accessor_clip seems to be ignored
-(at least for agg::pixfmt_rgb24). Even if alpha=0 you can see that red color
-tone at the borders. So the current workaround is to use image_accessor_clone
-which repeats the pixels at the edges. This should be no problem as the clipped
-bitmap format is most probably only used for rectangular bitmaps anyway. 
-*/
 #define image_accessor_clip_transp agg::image_accessor_clone
 
 
@@ -107,7 +102,7 @@
 /// It can have any transformation SWFMatrix and color transform. Any pixel 
format
 /// can be used, too. 
 template <class PixelFormat, class span_allocator_type, class img_source_type,
-  class interpolator_type, class sg_type>
+       class interpolator_type, class sg_type>
 class agg_style_bitmap : public agg_style_base
 {
 public:
@@ -115,47 +110,38 @@
   agg_style_bitmap(int width, int height, int rowlen, boost::uint8_t* data, 
     const gnash::SWFMatrix& mat, const gnash::cxform& cx)
     :
+    agg_style_base(false),
+    m_cx(cx),
     m_rbuf(data, width, height, rowlen),  
     m_pixf(m_rbuf),
     m_img_src(m_pixf),
-    m_tr(),       // initialize later
+    m_tr(mat.sx / 65535.0, mat.shx / 65535.0, mat.shy / 65535.0,
+            mat.sy / 65535.0, mat.tx, mat.ty),
     m_interpolator(m_tr),
     m_sg(m_img_src, m_interpolator)
   {
-  
-    m_is_solid = false;
     
     // Convert the transformation SWFMatrix to AGG's class. It's basically the
     // same and we could even use gnash::SWFMatrix since AGG does not require
     // a real AGG descendant (templates!). However, it's better to use AGG's
     // class as this should be faster (avoid type conversion).
-    m_tr=agg::trans_affine(
-      mat.sx/65536.0, mat.shx/65536.0, 
-      mat.shy/65536.0, mat.sy/65536.0, 
-      mat.tx, mat.ty);
-            
-    m_cx = cx;
-      
   }
   
   virtual ~agg_style_bitmap() {
   }
     
-  void generate_span(agg::rgba8* span, int x, int y, unsigned len)
-  {
-    m_sg.generate(span, x, y, len);
-    // Apply color transform
-    // TODO: Check if this can be optimized
-    if (!m_cx.is_identity()) {      
-      for (unsigned int i=0; i<len; i++) {
-        m_cx.transform(span->r, span->g, span->b, span->a);
-        span->premultiply();
-        ++span;
-      }
-    }  
-  }
-    
-  
+    void generate_span(agg::rgba8* span, int x, int y, unsigned len)
+    {
+        m_sg.generate(span, x, y, len);
+        // Apply color transform
+        // TODO: Check if this can be optimized
+        if (m_cx.is_identity()) return;
+        for (unsigned int i=0; i<len; i++) {
+            m_cx.transform(span->r, span->g, span->b, span->a);
+            span->premultiply();
+            ++span;
+        }  
+    }
   
 private:
 
@@ -191,44 +177,37 @@
 template <class color_type, class span_allocator_type, class 
interpolator_type, 
   class gradient_func_type, class gradient_adaptor_type, class 
color_func_type, 
   class sg_type>
-class agg_style_gradient : public agg_style_base {
+class agg_style_gradient : public agg_style_base
+{
 public:
 
   agg_style_gradient(const gnash::fill_style& fs,
         const gnash::SWFMatrix& mat, const gnash::cxform& cx,
         int norm_size)
     :
-    m_tr(),
+    agg_style_base(false),
+    m_cx(cx),
+    m_tr(mat.sx / 65536.0, mat.shx/65536.0, mat.shy / 65536.0,
+            mat.sy / 65536.0, mat.tx, mat.ty),
     m_span_interpolator(m_tr),
     m_gradient_func(),
     m_gradient_adaptor(m_gradient_func),
     m_sg(m_span_interpolator, m_gradient_adaptor, m_gradient_lut, 0, 
norm_size),
     m_need_premultiply(false)
   {
-  
-    m_is_solid = false;
-    
-    m_tr=agg::trans_affine(
-      mat.sx / 65536.0, mat.shx/65536.0, 
-      mat.shy / 65536.0, mat.sy / 65536.0, 
-      mat.tx, mat.ty);
-      
-    m_cx = cx;
-            
     // Build gradient lookup table
     m_gradient_lut.remove_all(); 
     
-    for (int i=0; i<fs.get_color_stop_count(); i++) {
+    for (int i = 0, e = fs.get_color_stop_count(); i != e; ++i) {
     
-      const gradient_record gr = fs.get_color_stop(i); 
+      const gradient_record& gr = fs.get_color_stop(i); 
       rgba trans_color = m_cx.transform(gr.m_color);
       
 #ifdef DEBUG_LIMIT_COLOR_ALPHA
       trans_color.m_a = trans_color.m_a>127 ? 127 : trans_color.m_a;
 #endif
 
-      if (trans_color.m_a < 255) 
-        m_need_premultiply=true;    
+      if (trans_color.m_a < 255) m_need_premultiply = true;    
       
       m_gradient_lut.add_color(gr.m_ratio/255.0, agg::rgba8(trans_color.m_r, 
         trans_color.m_g, trans_color.m_b, trans_color.m_a));
@@ -249,9 +228,12 @@
   {
     m_sg.generate(span, x, y, len);
     
-    if (m_need_premultiply)
-      while (len--)
-        (span++)->premultiply();
+    if (!m_need_premultiply) return;
+      
+    while (len--) {
+        span->premultiply();
+        ++span;
+    }
   }
   
   // Provide access to our gradient adaptor to allow re-initialization of
@@ -263,7 +245,6 @@
   }
   
 protected:
-
   
   // Color transform
   gnash::cxform m_cx;
@@ -318,7 +299,7 @@
     /// Called by AGG to ask if a certain style is a solid color
     bool is_solid(unsigned style) const {
       assert(style < m_styles.size());
-      return m_styles[style]->m_is_solid; 
+      return m_styles[style]->solid(); 
     }
     
     /// Adds a new solid fill color style
@@ -332,7 +313,7 @@
         const gnash::cxform& cx, bool repeat, bool smooth)
     {
 
-      if (bi==NULL) {
+      if (!bi) {
         // See server/styles.h comments about when NULL return is possible.
         // Don't warn here, we already warn at parse-time
         //log_debug("WARNING: add_bitmap called with bi=NULL");
@@ -627,10 +608,12 @@
     
       typedef agg::rgba8 color_type;            
       typedef agg::span_allocator<color_type> span_allocator_type;
-      typedef agg::span_interpolator_linear<agg::trans_affine> 
interpolator_type;
+      typedef agg::span_interpolator_linear<agg::trans_affine> 
+          interpolator_type;
       typedef agg::gradient_radial gradient_func_type;
       typedef gradient_func_type gradient_adaptor_type;
-      typedef agg::gradient_lut<agg::color_interpolator<color_type>, 256> 
color_func_type;
+      typedef agg::gradient_lut<agg::color_interpolator<color_type>, 256> 
+          color_func_type;
       typedef agg::span_gradient<color_type,
                                  interpolator_type,
                                  gradient_adaptor_type,
@@ -644,8 +627,9 @@
       gnash::SWFMatrix transl;
       transl.set_translation(-32, -32);
       transl.concatenate(mat);    
-      
-      st_type* st = new st_type(fs, transl, cx, 64/2);  // div 2 because we 
need radius, not diameter     
+
+      // div 2 because we need radius, not diameter      
+      st_type* st = new st_type(fs, transl, cx, 64/2); 
         
       // NOTE: The value 64 is based on the bitmap texture used by other
       // Gnash renderers which is normally 64x64 pixels for radial gradients.  
     
@@ -669,7 +653,7 @@
         interpolator_type, gradient_func_type, gradient_adaptor_type,
         color_func_type, sg_type> st_type;
             
-      // move the center of the focal fill (not it's focal point) to where it 
+      // move the center of the focal fill (not its focal point) to where it 
       // should be.
       gnash::SWFMatrix transl;      
       transl.set_translation(-32, -32);
@@ -685,10 +669,10 @@
     }
 
     /// Returns the color of a certain fill style (solid)
-    const agg::rgba8& color(unsigned style) const 
+    agg::rgba8 color(unsigned style) const 
     {
         if (style < m_styles.size())
-            return m_styles[style]->m_color;
+            return m_styles[style]->color();
 
         return m_transparent;
     }

=== modified file 'backend/render_handler_cairo.cpp'
--- a/backend/render_handler_cairo.cpp  2009-01-16 18:17:27 +0000
+++ b/backend/render_handler_cairo.cpp  2009-01-21 08:45:36 +0000
@@ -628,25 +628,24 @@
     _stage_mat.y0 = yoff;
   }
     
-  virtual void  draw_line_strip(const boost::int16_t coords[], int 
vertex_count,
-      const rgba& color, const SWFMatrix& mat)
+  virtual void drawLine(const std::vector<point>& coords, const rgba& color,
+          const SWFMatrix& mat)
   {
+    
+    if (coords.empty()) return;
+
     CairoScopeMatrix mat_transformer(_cr, mat);
 
-    if (vertex_count < 2) {
-      return;
-    }
-
-    double x, y;
-    x = coords[0];
-    y = coords[1];
+    std::vector<point>::const_iterator i = coords.begin();
+    
+    double x = i->x, y = i->y;
     snap_to_half_pixel(_cr, x, y);
 
     cairo_move_to(_cr, x, y);
 
-    for (int i = 2; i < vertex_count * 2; i += 2) {
-      x = coords[i];
-      y = coords[i+1];
+    for (std::vector<point>::const_iterator e = coords.end();
+            i != e; ++i) {
+      double x = i->x, y = i->y;
       snap_to_half_pixel(_cr, x, y);
       cairo_line_to(_cr, x, y);
     }

=== modified file 'backend/render_handler_ogl.cpp'
--- a/backend/render_handler_ogl.cpp    2009-01-16 18:17:27 +0000
+++ b/backend/render_handler_ogl.cpp    2009-01-21 11:37:15 +0000
@@ -235,7 +235,27 @@
   return point(0.5 * (a.x + b.x), 0.5 * (a.y + b.y));
 }
 
-
+namespace {
+
+class
+PointSerializer
+{
+public:
+    PointSerializer(std::vector<boost::int16_t>& dest)
+        :
+        _dest(dest)
+    {}
+    
+    void operator()(const point& p)
+    {
+        _dest.push_back(p.x);
+        _dest.push_back(p.y);
+    }
+private:
+    std::vector<boost::int16_t>& _dest;
+};
+
+}
 
 // Unfortunately, we can't use OpenGL as-is to interpolate the curve for us. It
 // is legal for Flash coordinates to be outside of the viewport, which will
@@ -866,26 +886,32 @@
 
     glFlush(); // Make OpenGL execute all commands in the buffer.
   }
-    
+  
   /// Draw a line-strip directly, using a thin, solid line. 
   //
   /// Can be used to draw empty boxes and cursors.
-  virtual void
-  draw_line_strip(const boost::int16_t* coords, int vertex_count, const rgba& 
color,
+  virtual void drawLine(const std::vector<point>& coords, const rgba& color,
                   const SWFMatrix& mat)
   {
     oglScopeMatrix scope_mat(mat);
 
+    const size_t numPoints = coords.size();
+
     glColor3ub(color.m_r, color.m_g, color.m_b);
 
+    std::vector<boost::int16_t> pointList;
+    pointList.reserve(numPoints * 2);
+    std::for_each(coords.begin(), coords.end(), PointSerializer(pointList));
+
     // Send the line-strip to OpenGL
     glEnableClientState(GL_VERTEX_ARRAY);
-    glVertexPointer(2, GL_SHORT, 0 /* tight packing */, coords);
-    glDrawArrays(GL_LINE_STRIP, 0, vertex_count);
+    glVertexPointer(2, GL_SHORT, 0 /* tight packing */, &pointList.front());
+    glDrawArrays(GL_LINE_STRIP, 0, numPoints);
 
     // Draw a dot on the beginning and end coordinates to round lines.
-    //   glVertexPointer: skip all but the first and last coordinates in the 
line.
-    glVertexPointer(2, GL_SHORT, (sizeof(boost::int16_t) * 2) * (vertex_count 
- 1), coords);
+    // glVertexPointer: skip all but the first and last coordinates in the 
line.
+    glVertexPointer(2, GL_SHORT, (sizeof(boost::int16_t) * 2) *
+            (numPoints - 1), &pointList.front());
     glEnable(GL_POINT_SMOOTH); // Draw a round (antialiased) point.
     glDrawArrays(GL_POINTS, 0, 2);
     glDisable(GL_POINT_SMOOTH);

=== modified file 'libcore/TextField.cpp'
--- a/libcore/TextField.cpp     2008-12-28 09:40:28 +0000
+++ b/libcore/TextField.cpp     2009-01-19 16:35:55 +0000
@@ -44,10 +44,12 @@
 #include "TextFormat_as.h" // for getTextFormat/setTextFormat
 #include "GnashKey.h" // key::code
 #include "TextRecord.h"
+#include "Point2d.h"
 
 #include <algorithm> // std::min
 #include <string>
 #include <boost/algorithm/string/case_conv.hpp>
+#include <boost/assign/list_of.hpp>
 
 // Text fields have a fixed 2 pixel padding for each side (regardless of 
border)
 #define PADDING_TWIPS 40 
@@ -290,13 +292,11 @@
     boost::uint16_t y = static_cast<boost::uint16_t>(m_ycursor);
     boost::uint16_t h = getFontHeight();
 
-    boost::int16_t box[4];
-    box[0] = x;
-    box[1] = y;
-    box[2] = x;
-    box[3] = y + h;
+    const std::vector<point> box = boost::assign::list_of
+        (point(x, y))
+        (point(x, y + h));
     
-    render::draw_line_strip(box, 2, rgba(0,0,0,255), mat);    // draw line
+    render::drawLine(box, rgba(0,0,0,255), mat);
 }
 
 void

=== modified file 'libcore/cxform.cpp'
--- a/libcore/cxform.cpp        2008-10-20 17:06:14 +0000
+++ b/libcore/cxform.cpp        2009-01-20 08:11:19 +0000
@@ -68,22 +68,20 @@
 void    cxform::transform(boost::uint8_t& r, boost::uint8_t& g, 
boost::uint8_t& b, boost::uint8_t& a) const
 {
     // force conversion to int16 first, kind of optimization.
-    int16_t rt = (int16_t)r;
-    int16_t gt = (int16_t)g;
-    int16_t bt = (int16_t)b;
-    int16_t at = (int16_t)a;
+    boost::uint16_t rt = r;
+    boost::uint16_t gt = g;
+    boost::uint16_t bt = b;
+    boost::uint16_t at = a;
     
     rt = (rt * ra >> 8) + rb;
     gt = (gt * ga >> 8) + gb;
     bt = (bt * ba >> 8) + bb;
     at = (at * aa >> 8) + ab;
 
-    using utility::clamp;
-    
-    r = (uint8_t)(clamp<int16_t>(rt, 0, 255));
-    g = (uint8_t)(clamp<int16_t>(gt, 0, 255));
-    b = (uint8_t)(clamp<int16_t>(bt, 0, 255));
-    a = (uint8_t)(clamp<int16_t>(at, 0, 255));
+    r = std::min<boost::uint16_t>(rt, 255);
+    g = std::min<boost::uint16_t>(gt, 255);
+    b = std::min<boost::uint16_t>(bt, 255);
+    a = std::min<boost::uint16_t>(at, 255);
 }
 
 void    cxform::read_rgb(SWFStream& in)

=== modified file 'libcore/render.cpp'
--- a/libcore/render.cpp        2009-01-16 18:00:27 +0000
+++ b/libcore/render.cpp        2009-01-19 16:35:55 +0000
@@ -131,12 +131,12 @@
        }
 
 
-       void    draw_line_strip(const boost::int16_t coords[], int 
vertex_count, const rgba& color, const SWFMatrix& mat)
+       void drawLine(const std::vector<point>& coords, const rgba& color, 
const SWFMatrix& mat)
        {
 #ifdef DEBUG_RENDER_CALLS
                GNASH_REPORT_FUNCTION;
 #endif
-               if (s_render_handler) s_render_handler->draw_line_strip(coords, 
vertex_count, color, mat);
+               if (s_render_handler) s_render_handler->drawLine(coords, color, 
mat);
 }
 
 

=== modified file 'libcore/render.h'
--- a/libcore/render.h  2009-01-16 18:00:27 +0000
+++ b/libcore/render.h  2009-01-19 16:35:55 +0000
@@ -71,8 +71,8 @@
                void    end_display();
 
                /// See render_handler::draw_line_strip (in 
backend/render_handler.h)
-               void    draw_line_strip(const boost::int16_t coords[],
-                               int vertex_count, const rgba& color, const 
SWFMatrix& mat);
+               void drawLine(const std::vector<point>& coords, const rgba& 
color,
+                const SWFMatrix& mat);
 
                /// See render_handler::draw_poly (in backend/render_handler.h)
                DSOEXPORT void  draw_poly(const point* corners, int 
corner_count,

=== modified file 'libcore/swf/TextRecord.cpp'
--- a/libcore/swf/TextRecord.cpp        2009-01-05 09:32:03 +0000
+++ b/libcore/swf/TextRecord.cpp        2009-01-19 16:35:55 +0000
@@ -27,6 +27,7 @@
 #include "fill_style.h"
 #include "Font.h"
 
+#include <boost/assign/list_of.hpp>
 #include <vector>
 
 namespace gnash {
@@ -223,16 +224,13 @@
                 //       square is not hard-coded anymore but can be
                 //       queried from the font class
                 //
-                static const boost::int16_t s_empty_char_box[5 * 2] =
-                {
-                     32,   32,
-                    480,   32,
-                    480, -656,
-                     32, -656,
-                     32,   32
-                };
-                render::draw_line_strip(s_empty_char_box, 5,
-                        textColor, mat);  
+                static const std::vector<point> emptyCharBox = 
boost::assign::list_of
+                     (point(32, 32))
+                     (point(480, 32))
+                     (point(480, -656))
+                     (point(32, -656))
+                     (point(32,32));
+                render::drawLine(emptyCharBox, textColor, mat);  
 #endif
 
             }
@@ -271,13 +269,11 @@
             // 1/4 the EM square offset far from baseline 
             boost::int16_t posY = int(y+int((unitsPerEM/4)*scale));
 
-            boost::int16_t underline[2 * 2] =
-            {
-                startX,   posY,
-                  endX,   posY,
-            };
-            render::draw_line_strip(underline, 2, textColor,
-                    base_matrix);
+            const std::vector<point> underline = boost::assign::list_of
+                (point(startX, posY))
+                (point(endX, posY));
+
+            render::drawLine(underline, textColor, base_matrix);
         }
     }
 }


reply via email to

[Prev in Thread] Current Thread [Next in Thread]