[Top][All Lists]
[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);
}
}
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r10549: Make rendering interface more consistent and simple to use.,
Benjamin Wolsey <=