[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r10689: Implement TextSnapshot bette
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r10689: Implement TextSnapshot better; all tests of implemented methods pass. |
Date: |
Wed, 11 Mar 2009 14:41:02 +0100 |
User-agent: |
Bazaar (1.5) |
------------------------------------------------------------
revno: 10689
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Wed 2009-03-11 14:41:02 +0100
message:
Implement TextSnapshot better; all tests of implemented methods pass.
Selections are now queried directly from the StaticText characters.
Derive two new classes from generic_character (now DisplayObject) into
Shape and StaticText so that they can more easily be used differently
(for TextSnapshot). The inheritance of DisplayObject from character
(should be: InteractiveObject) is still the wrong way round.
Rename shape.h to Geometry.h to avoid any conflicts with Shape.h.
removed:
libcore/generic_character.cpp
libcore/generic_character.h
libcore/shape.h
added:
libcore/DisplayObject.cpp
libcore/DisplayObject.h
libcore/Geometry.h
libcore/Shape.cpp
libcore/Shape.h
libcore/StaticText.cpp
libcore/StaticText.h
modified:
backend/PathParser.h
backend/render_handler.h
backend/render_handler_agg.cpp
libcore/BitmapMovieInstance.cpp
libcore/Button.cpp
libcore/Makefile.am
libcore/MovieClip.cpp
libcore/MovieClip.h
libcore/asobj/TextSnapshot_as.cpp
libcore/asobj/TextSnapshot_as.h
libcore/character.h
libcore/parser/BitmapMovieDefinition.cpp
libcore/parser/BitmapMovieDefinition.h
libcore/parser/SWFMovieDefinition.h
libcore/parser/character_def.cpp
libcore/parser/character_def.h
libcore/parser/shape_character_def.cpp
libcore/parser/shape_character_def.h
libcore/parser/sprite_definition.cpp
libcore/parser/sprite_definition.h
libcore/swf/DefineButtonTag.cpp
libcore/swf/DefineButtonTag.h
libcore/swf/DefineEditTextTag.cpp
libcore/swf/DefineEditTextTag.h
libcore/swf/DefineFontAlignZonesTag.cpp
libcore/swf/DefineTextTag.cpp
libcore/swf/DefineTextTag.h
libcore/swf/DefineVideoStreamTag.cpp
libcore/swf/DefineVideoStreamTag.h
libcore/swf/TextRecord.cpp
libcore/swf/TextRecord.h
libcore/swf/tag_loaders.cpp
testsuite/DummyMovieDefinition.h
testsuite/libcore.all/EdgeTest.cpp
testsuite/misc-ming.all/TextSnapshotTest.c
------------------------------------------------------------
revno: 10684.1.1
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-03-10 21:43:50 +0100
message:
Begin rearranging inheritance to reflect AS3 classes better; this makes
handling StaticText objects easier for TextSnapshot, and also prepares
for implementing AS3.
generic_character becomes DisplayObject, from which Shape and StaticText
inherit directly.
character should derive from DisplayObject as InteractiveDisplayObject,
not be its base class, but this is not yet implemented.
All character_defs now require a createDisplayObject() method. This
unfortunately includes BitmapMovieDefinition and SWFMovieDefinition, but
that reflects the existing bad design.
removed:
libcore/generic_character.cpp
libcore/generic_character.h
libcore/shape.h
added:
libcore/DisplayObject.cpp
libcore/DisplayObject.h
libcore/Geometry.h
libcore/Shape.cpp
libcore/Shape.h
libcore/StaticText.cpp
libcore/StaticText.h
modified:
backend/render_handler.h
backend/render_handler_agg.cpp
libcore/BitmapMovieInstance.cpp
libcore/Button.cpp
libcore/Makefile.am
libcore/MovieClip.cpp
libcore/MovieClip.h
libcore/asobj/TextSnapshot_as.cpp
libcore/asobj/TextSnapshot_as.h
libcore/character.h
libcore/parser/BitmapMovieDefinition.cpp
libcore/parser/BitmapMovieDefinition.h
libcore/parser/SWFMovieDefinition.h
libcore/parser/character_def.cpp
libcore/parser/character_def.h
libcore/parser/shape_character_def.cpp
libcore/parser/shape_character_def.h
libcore/parser/sprite_definition.cpp
libcore/parser/sprite_definition.h
libcore/swf/DefineButtonTag.cpp
libcore/swf/DefineButtonTag.h
libcore/swf/DefineEditTextTag.cpp
libcore/swf/DefineEditTextTag.h
libcore/swf/DefineFontAlignZonesTag.cpp
libcore/swf/DefineTextTag.cpp
libcore/swf/DefineTextTag.h
libcore/swf/DefineVideoStreamTag.cpp
libcore/swf/DefineVideoStreamTag.h
libcore/swf/tag_loaders.cpp
testsuite/libcore.all/EdgeTest.cpp
------------------------------------------------------------
revno: 10684.1.2
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Wed 2009-03-11 07:34:47 +0100
message:
Tidy up getStaticText so that it only returns StaticTexts, which disrupts
the
inheritance chain less.
Clean up inheritance in the new classes: keep pointers to polymorphic
classes as ungeneric as possible.
modified:
libcore/DisplayObject.cpp
libcore/DisplayObject.h
libcore/Shape.h
libcore/StaticText.cpp
libcore/StaticText.h
libcore/asobj/TextSnapshot_as.cpp
libcore/asobj/TextSnapshot_as.h
libcore/character.h
libcore/parser/character_def.h
testsuite/DummyMovieDefinition.h
------------------------------------------------------------
revno: 10684.1.3
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Wed 2009-03-11 10:39:20 +0100
message:
Ugly version of working TextSnapshot (selection).
modified:
libcore/StaticText.cpp
libcore/StaticText.h
libcore/asobj/TextSnapshot_as.cpp
libcore/asobj/TextSnapshot_as.h
libcore/swf/DefineTextTag.cpp
libcore/swf/DefineTextTag.h
libcore/swf/TextRecord.h
------------------------------------------------------------
revno: 10684.1.4
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Wed 2009-03-11 11:14:31 +0100
message:
Clean up and document more.
modified:
libcore/DisplayObject.h
libcore/StaticText.cpp
libcore/StaticText.h
libcore/asobj/TextSnapshot_as.cpp
libcore/asobj/TextSnapshot_as.h
libcore/character.h
------------------------------------------------------------
revno: 10684.1.5
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Wed 2009-03-11 11:16:46 +0100
message:
Passing selection tests in TextSnapshotTest.
modified:
testsuite/misc-ming.all/TextSnapshotTest.c
------------------------------------------------------------
revno: 10684.1.6
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Wed 2009-03-11 11:36:40 +0100
message:
Document StaticText.
Drop unnecessary functor operator.
Reduce debugging.
modified:
libcore/StaticText.h
libcore/swf/TextRecord.cpp
libcore/swf/TextRecord.h
=== modified file 'backend/PathParser.h'
--- a/backend/PathParser.h 2009-02-25 22:33:03 +0000
+++ b/backend/PathParser.h 2009-03-11 13:41:02 +0000
@@ -15,11 +15,11 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-#ifndef __PATH_PARSER_H
-#define __PATH_PARSER_H
-
-
-#include "shape.h"
+#ifndef GNASH_PATH_PARSER_H
+#define GNASH_PATH_PARSER_H
+
+
+#include "Geometry.h"
#include <vector>
#include <deque>
#include "cxform.h"
=== modified file 'backend/render_handler.h'
--- a/backend/render_handler.h 2009-01-22 20:10:39 +0000
+++ b/backend/render_handler.h 2009-03-10 20:43:50 +0000
@@ -147,7 +147,7 @@
#include "gnash.h" // Quality
#include "shape_character_def.h"
-#include "generic_character.h"
+#include "DisplayObject.h"
#include "Range2d.h"
// Forward declarations.
@@ -159,7 +159,6 @@
class cxform;
class shape_character_def;
- class generic_character;
class GnashImage;
}
=== modified file 'backend/render_handler_agg.cpp'
--- a/backend/render_handler_agg.cpp 2009-01-22 22:02:00 +0000
+++ b/backend/render_handler_agg.cpp 2009-03-10 20:43:50 +0000
@@ -126,7 +126,7 @@
#include "Range2d.h"
#include "shape_character_def.h"
-#include "generic_character.h"
+#include "DisplayObject.h"
#include <agg_rendering_buffer.h>
#include <agg_renderer_base.h>
=== modified file 'libcore/BitmapMovieInstance.cpp'
--- a/libcore/BitmapMovieInstance.cpp 2009-02-25 22:33:03 +0000
+++ b/libcore/BitmapMovieInstance.cpp 2009-03-10 20:43:50 +0000
@@ -18,7 +18,7 @@
#include "BitmapMovieInstance.h"
#include "BitmapMovieDefinition.h"
#include "fill_style.h"
-#include "shape.h" // for class path and class edge
+#include "Geometry.h" // for class path and class edge
#include "render.h" // for ::display
namespace gnash {
@@ -34,7 +34,7 @@
character_def* chdef = def->get_character_def(1);
assert(chdef);
boost::intrusive_ptr<character> ch =
- chdef->create_character_instance(this, 1);
+ chdef->createDisplayObject(this, 1);
const int depth = 1 + character::staticDepthOffset;
place_character(ch.get(), depth);
=== modified file 'libcore/Button.cpp'
--- a/libcore/Button.cpp 2009-01-22 20:10:39 +0000
+++ b/libcore/Button.cpp 2009-03-10 20:43:50 +0000
@@ -741,7 +741,7 @@
character::staticDepthOffset + 1;
int ch_id = bdef.m_character_id;
- character* ch =
bdef.m_character_def->create_character_instance(
+ character* ch = bdef.m_character_def->createDisplayObject(
this, ch_id);
ch->setMatrix(mat, true); // update caches
ch->set_cxform(cx);
@@ -904,7 +904,7 @@
int ch_id = bdef.m_character_id;
character* ch =
- bdef.m_character_def->create_character_instance(this, ch_id);
+ bdef.m_character_def->createDisplayObject(this, ch_id);
ch->setMatrix(mat, true); // update caches
// TODO: who cares about color, depth etc.
@@ -937,7 +937,7 @@
int ch_depth = bdef.m_button_layer+character::staticDepthOffset+1;
int ch_id = bdef.m_character_id;
- character* ch = bdef.m_character_def->create_character_instance(
+ character* ch = bdef.m_character_def->createDisplayObject(
this, ch_id);
ch->setMatrix(mat, true); // update caches
ch->set_cxform(cx);
=== added file 'libcore/DisplayObject.cpp'
--- a/libcore/DisplayObject.cpp 1970-01-01 00:00:00 +0000
+++ b/libcore/DisplayObject.cpp 2009-03-11 06:34:47 +0000
@@ -0,0 +1,56 @@
+// DisplayObject.cpp: Mouse/Character handling, for Gnash.
+//
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "DisplayObject.h"
+
+namespace gnash
+{
+
+void
+DisplayObject::add_invalidated_bounds(InvalidatedRanges& ranges,
+ bool force)
+{
+ ranges.add(m_old_invalidated_ranges);
+ if (isVisible() && (m_invalidated||force))
+ {
+ rect bounds;
+ bounds.expand_to_transformed_rect(getWorldMatrix(),
+ getDefinition()->get_bound());
+
+ ranges.add(bounds.getRange());
+ }
+}
+
+
+bool
+DisplayObject::pointInShape(boost::int32_t x, boost::int32_t y) const
+{
+ SWFMatrix wm = getWorldMatrix();
+ SWFMatrix wm_inverse = wm.invert();
+ point lp(x, y);
+ wm_inverse.transform(lp);
+ return getDefinition()->point_test_local(lp.x, lp.y, wm);
+}
+
+} // namespace gnash
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:
=== added file 'libcore/DisplayObject.h'
--- a/libcore/DisplayObject.h 1970-01-01 00:00:00 +0000
+++ b/libcore/DisplayObject.h 2009-03-11 10:14:31 +0000
@@ -0,0 +1,126 @@
+//
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef GNASH_DISPLAY_OBJECT_H
+#define GNASH_DISPLAY_OBJECT_H
+
+#include "smart_ptr.h" // GNASH_USE_GC
+#include "character.h" // for inheritance
+#include "character_def.h"
+
+#include <cassert>
+
+namespace gnash {
+ class character_def;
+ class StaticText;
+ namespace SWF {
+ class TextRecord;
+ }
+}
+
+namespace gnash {
+
+/// The base class for all rendered objects on the Stage.
+//
+/// Objects of type DisplayObject are non-interactive.
+class DisplayObject : public character
+{
+
+public:
+
+ DisplayObject(character* parent, int id)
+ :
+ character(parent, id)
+ {
+ }
+
+ virtual ~DisplayObject() {}
+
+ /// Render the DisplayObject.
+ //
+ /// All DisplayObjects must have a display() function.
+ virtual void display() = 0;
+
+ /// Whether the DisplayObject can handle a mouse event.
+ //
+ /// Normal DisplayObjects apparently cannot handle
+ /// mouse events.
+ /// @return true if the DisplayObject can handle mouse
+ /// events
+ virtual bool can_handle_mouse_event() const
+ {
+ return false;
+ }
+
+ /// Search for StaticText objects
+ //
+ /// If this is a StaticText object and contains SWF::TextRecords, these
+ /// are written to the passed parameter.
+ /// @ return 0 if this object is not a StaticText or contains no text.
+ virtual StaticText* getStaticText(std::vector<const SWF::TextRecord*>&,
+ size_t&)
+ {
+ return 0;
+ }
+
+ rect getBounds() const
+ {
+ return getDefinition()->get_bound();
+ }
+
+ /// Generic character is NEVER a mouse entity by default, so
+ /// the default implementation of this method always returns NULL.
+ /// Override it from subclasses that do can be mouse entities.
+ ///
+ /// If you need to check for a generic character to contain a
+ /// given point, use the pointInShape() function instead.
+ ///
+ virtual character* get_topmost_mouse_entity(boost::int32_t /*x*/,
+ boost::int32_t /*y*/)
+ {
+ return 0;
+ }
+
+ // See dox in character.h
+ virtual bool pointInShape(boost::int32_t x, boost::int32_t y) const;
+
+ void add_invalidated_bounds(InvalidatedRanges& ranges, bool force);
+
+protected:
+
+ /// Retrieve the immutable definition of this DisplayObject.
+ //
+ /// All subclasses must override this, but may return 0. In
+ /// this case, they must also override any functions that
+ /// call getDefinition().
+ /// @ return The immutable character_def of this DisplayObject
+ /// or 0 if none exists.
+ virtual character_def* getDefinition() const = 0;
+
+};
+
+
+} // namespace gnash
+
+
+#endif
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:
=== added file 'libcore/Geometry.h'
--- a/libcore/Geometry.h 1970-01-01 00:00:00 +0000
+++ b/libcore/Geometry.h 2009-03-10 20:43:50 +0000
@@ -0,0 +1,594 @@
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+
+#ifndef GNASH_GEOMETRY_H
+#define GNASH_GEOMETRY_H
+
+#include "dsodefs.h"
+#include "SWFMatrix.h"
+
+#include <vector> // for path composition
+#include <cmath> // sqrt
+
+
+// Forward declarations
+namespace gnash {
+ class rect;
+}
+
+namespace gnash {
+
+ /// \brief
+ /// Defines an edge with a control point and an anchor point.
+ ///
+ /// Could be a quadratic bezier curve, or a straight line(degenerated curve).
+ ///
+ class Edge
+ {
+ public:
+
+ // Quadratic bezier: point = p0 * t^2 + p1 * 2t(1-t) + p2 * (1-t)^2
+ point cp; // control point, TWIPS
+ point ap; // anchor point, TWIPS
+
+ Edge()
+ :
+ cp(0, 0), ap(0, 0)
+ { };
+
+ Edge(boost::int32_t cx, boost::int32_t cy, boost::int32_t ax,
boost::int32_t ay)
+ :
+ cp(cx, cy), ap(ax, ay)
+ { }
+
+ Edge(const Edge& from)
+ :
+ cp(from.cp), ap(from.ap)
+ { }
+
+ Edge(const point& ncp, const point& nap)
+ :
+ cp(ncp), ap(nap)
+ { }
+
+ bool isStraight() const
+ {
+ return cp == ap;
+ }
+
+ // TODO: drop this!
+ bool is_straight() const { return isStraight(); }
+
+ /// Transform the edge according to the given SWFMatrix.
+ void transform(const SWFMatrix& mat)
+ {
+ mat.transform(ap);
+ mat.transform(cp);
+ }
+
+ /// Return squared distance between point pt and segment A-B
+ static double
+ squareDistancePtSeg(const point& p, const point& A, const point& B)
+ {
+ boost::int32_t dx = B.x - A.x;
+ boost::int32_t dy = B.y - A.y;
+
+ if ( dx == 0 && dy == 0 )
+ {
+ return p.squareDistance(A);
+ }
+
+ boost::int32_t pdx = p.x - A.x;
+ boost::int32_t pdy = p.y - A.y;
+
+ double u = ( (double)(pdx) * dx + (double)(pdy) * dy ) / (
(double)(dx)*dx + (double)(dy)*dy );
+
+ if (u <= 0)
+ {
+ return p.squareDistance(A);
+ }
+
+ if (u >= 1)
+ {
+ return p.squareDistance(B);
+ }
+
+ point px(A, B, u); // FIXME: this interpolation introduce a precision
loss (point is int-based)
+ return p.squareDistance(px);
+ }
+
+ /// Return distance between point pt and segment A-B
+ static double
+ distancePtSeg(const point& pt, const point& A, const point& B)
+ {
+ double square = squareDistancePtSeg(pt, A, B);
+ return std::sqrt(square);
+ }
+
+ /// Find point of the quadratic curve defined by points A,C,B
+ //
+ /// @param A The first point
+ /// @param C The second point (control point)
+ /// @param B The third point (anchor point)
+ /// @param ret The point to write result into
+ /// @param t the step factor between 0 and 1
+ ///
+
+ static point
+ pointOnCurve(const point& A,
+ const point& C,
+ const point& B, float t)
+ {
+ point Q1(A, C, t);
+ point Q2(C, B, t);
+ point R(Q1, Q2, t);
+
+ return R;
+ }
+
+ /// Return square distance between point pt and the point on curve found by
+ /// applying the T parameter to the quadratic bezier curve function
+ //
+ /// @param A The first point of the bezier curve
+ /// @param C The second point of the bezier curve (control point)
+ /// @param B The third point of the bezier curve (anchor point)
+ /// @param p The point we want to compute distance from
+ /// @param t the step factor between 0 and 1
+ ///
+ static boost::int64_t squareDistancePtCurve(const point& A,
+ const point& C,
+ const point& B,
+ const point& p, float t)
+ {
+ return p.squareDistance( pointOnCurve(A, C, B, t) );
+ }
+ };
+
+
+ ///\brief
+ /// A subset of a shape, a series of edges sharing a single set of styles.
+ class DSOEXPORT Path
+ {
+ public:
+ /// Left fill style index (1-based)
+ unsigned m_fill0;
+
+ /// Right fill style index (1-based)
+ unsigned m_fill1;
+
+ /// Line style index (1-based)
+ unsigned m_line;
+
+ /// Start point of the path
+ point ap;
+
+ /// Edges forming the path
+ std::vector<Edge> m_edges;
+
+ /// This flag is set when the path is the first one of a new "sub-shape".
+ /// All paths with a higher index in the list belong to the same
+ /// shape unless they have m_new_shape==true on their own.
+ /// Sub-shapes affect the order in which outlines and shapes are rendered.
+ bool m_new_shape;
+
+ /// Default constructor
+ //
+ /// @param newShape
+ /// True if this path starts a new subshape
+ ///
+ Path(bool newShape = false)
+ :
+ m_new_shape(newShape)
+ {
+ reset(0, 0, 0, 0, 0);
+ }
+
+ Path(const Path& from)
+ :
+ m_fill0(from.m_fill0),
+ m_fill1(from.m_fill1),
+ m_line(from.m_line),
+ ap(from.ap),
+ m_edges(from.m_edges),
+ m_new_shape(from.m_new_shape)
+ {
+ }
+
+ /// Initialize a path
+ //
+ /// @param ax
+ /// X coordinate of path origin in TWIPS
+ ///
+ /// @param ay
+ /// Y coordinate in path origin in TWIPS
+ ///
+ /// @param fill0
+ /// Fill style index for left fill (1-based).
+ /// Zero means NO style.
+ ///
+ /// @param fill1
+ /// Fill style index for right fill (1-based)
+ /// Zero means NO style.
+ ///
+ /// @param line
+ /// Line style index for right fill (1-based).
+ /// Zero means NO style.
+ ///
+ /// @param newShape
+ /// True if this path starts a new subshape
+ Path(boost::int32_t ax, boost::int32_t ay,
+ unsigned fill0, unsigned fill1, unsigned line,
+ bool newShape)
+ :
+ m_new_shape(newShape)
+ {
+ reset(ax, ay, fill0, fill1, line);
+ }
+
+ /// Re-initialize a path, maintaining the "new shape" flag untouched
+ //
+ /// @param ax
+ /// X coordinate of path origin in TWIPS
+ ///
+ /// @param ay
+ /// Y coordinate in path origin in TWIPS
+ ///
+ /// @param fill0
+ /// Fill style index for left fill
+ ///
+ /// @param fill1
+ /// Fill style index for right fill
+ //
+ /// @param line
+ /// Line style index for right fill
+ ///
+ void reset(boost::int32_t ax, boost::int32_t ay,
+ unsigned fill0, unsigned fill1, unsigned line)
+ // Reset all our members to the given values, and clear our edge list.
+ {
+ ap.x = ax;
+ ap.y = ay;
+ m_fill0 = fill0;
+ m_fill1 = fill1;
+ m_line = line;
+
+ m_edges.resize(0);
+ assert(is_empty());
+ }
+
+ /// Return true if we have no edges.
+ bool is_empty() const
+ {
+ return m_edges.empty();
+ }
+
+ /// Expand given rect to include bounds of this path
+ //
+ /// @param r
+ /// The rectangle to expand with our own bounds
+ ///
+ /// @param thickness
+ /// The thickess of our lines, half the thickness will
+ /// be added in all directions in swf8+, all of it will
+ /// in swf7-
+ ///
+ /// @param swfVersion
+ /// SWF version to use.
+ ///
+ void
+ expandBounds(rect& r, unsigned int thickness, int swfVersion) const
+ {
+ const Path& p = *this;
+ size_t nedges = m_edges.size();
+
+ if ( ! nedges ) return; // this path adds nothing
+
+ if (thickness)
+ {
+ // NOTE: Half of thickness would be enough (and correct) for
+ // radius, but that would not match how Flash calculates the
+ // bounds using the drawing API.
+ unsigned int radius = swfVersion < 8 ? thickness : thickness/2;
+
+ r.expand_to_circle(ap.x, ap.y, radius);
+ for (unsigned int j = 0; j<nedges; j++)
+ {
+ r.expand_to_circle(m_edges[j].ap.x, m_edges[j].ap.y, radius);
+ r.expand_to_circle(m_edges[j].cp.x, m_edges[j].cp.y, radius);
+ }
+ }
+ else
+ {
+ r.expand_to_point(ap.x, ap.y);
+ for (unsigned int j = 0; j<nedges; j++)
+ {
+ r.expand_to_point(m_edges[j].ap.x, p.m_edges[j].ap.y);
+ r.expand_to_point(m_edges[j].cp.x, p.m_edges[j].cp.y);
+ }
+ }
+ }
+
+ /// @{ Primitives for the Drawing API
+ ///
+ /// Name of these functions track Ming interface
+ ///
+
+ /// Draw a straight line.
+ //
+ /// Point coordinates are relative to path origin
+ /// and expressed in TWIPS.
+ ///
+ /// @param x
+ /// X coordinate in TWIPS
+ ///
+ /// @param y
+ /// Y coordinate in TWIPS
+ ///
+ void
+ drawLineTo(boost::int32_t dx, boost::int32_t dy)
+ {
+ m_edges.push_back(Edge(dx, dy, dx, dy));
+ }
+
+ /// Draw a curve.
+ //
+ /// Offset values are relative to path origin and
+ /// expressed in TWIPS.
+ ///
+ /// @param cx
+ /// Control point's X coordinate.
+ ///
+ /// @param cy
+ /// Control point's Y coordinate.
+ ///
+ /// @param ax
+ /// Anchor point's X ordinate.
+ ///
+ /// @param ay
+ /// Anchor point's Y ordinate.
+ ///
+ void
+ drawCurveTo(boost::int32_t cdx, boost::int32_t cdy, boost::int32_t adx,
boost::int32_t ady)
+ {
+ m_edges.push_back(Edge(cdx, cdy, adx, ady));
+ }
+
+ /// Remove all edges and reset style infomation
+ void clear()
+ {
+ m_edges.resize(0);
+ m_fill0 = m_fill1 = m_line = 0;
+ }
+
+ /// @} Primitives for the Drawing API
+
+
+ /// Returns true if the last and the first point of the path match
+ bool isClosed() const
+ {
+ if ( m_edges.empty() )
+ {
+ return true;
+ }
+ else
+ {
+ return m_edges.back().ap == ap;
+ }
+ }
+
+ /// Close this path with a straight line, if not already closed
+ void close()
+ {
+ if ( m_edges.empty() ) return;
+
+ // Close it with a straight edge if needed
+ const Edge& lastedge = m_edges.back();
+ if ( lastedge.ap != ap )
+ {
+ Edge newedge(ap, ap);
+ m_edges.push_back(newedge);
+ }
+ }
+
+ /// \brief
+ /// Return true if the given point is within the given squared distance
+ /// from this path edges.
+ //
+ /// NOTE: if the path is empty, false is returned.
+ ///
+ bool
+ withinSquareDistance(const point& p, double dist) const
+ {
+ size_t nedges = m_edges.size();
+
+ if ( ! nedges ) return false;
+
+ point px(ap);
+ for (size_t i=0; i<nedges; ++i)
+ {
+ const Edge& e = m_edges[i];
+ point np(e.ap);
+
+ if ( e.isStraight() )
+ {
+ double d = Edge::squareDistancePtSeg(p, px, np);
+
+ if ( d <= dist ) return true;
+ }
+ else
+ {
+
+ const point& A = px;
+ const point& C = e.cp;
+ const point& B = e.ap;
+
+ // Approximate the curve to segCount segments
+ // and compute distance of query point from each
+ // segment.
+ //
+ // TODO: find an apprpriate value for segCount based
+ // on rendering scale ?
+ //
+ int segCount = 10;
+ point p0(A.x, A.y);
+ for (int i=1; i<=segCount; ++i)
+ {
+ float t1 = (float)(i) / segCount;
+ point p1 = Edge::pointOnCurve(A, C, B, t1);
+
+ // distance from point and segment being an approximation
+ // of the curve
+ double d = Edge::squareDistancePtSeg(p, p0, p1);
+ if ( d <= dist ) return true;
+
+ p0.setTo(p1.x, p1.y);
+ }
+ }
+ px = np;
+ }
+
+ return false;
+ }
+
+ /// Transform all path coordinates according to the given SWFMatrix.
+ void transform(const SWFMatrix& mat)
+ {
+ mat.transform(ap);
+ std::vector<Edge>::iterator it = m_edges.begin(), ie =
m_edges.end();
+ for(; it != ie; it++)
+ {
+ (*it).transform(mat);
+ }
+ }
+
+ /// Set this path as the start of a new (sub)shape
+ void setNewShape()
+ {
+ m_new_shape=true;
+ }
+
+ /// Return true if this path starts a new (sub)shape
+ bool getNewShape() const
+ {
+ return m_new_shape;
+ }
+
+ /// Return true if this path contains no edges
+ bool empty() const
+ {
+ return is_empty();
+ }
+
+ /// Set the fill to use on the left side
+ //
+ /// @param f
+ /// The fill index (1-based).
+ /// When this path is added to a shape_character_def,
+ /// the index (decremented by 1) will reference an element
+ /// in the fill_style vector defined for that shape.
+ /// If zero, no fill will be active.
+ ///
+ void setLeftFill(unsigned f)
+ {
+ m_fill0 = f;
+ }
+
+ unsigned getLeftFill() const
+ {
+ return m_fill0;
+ }
+
+ /// Set the fill to use on the left side
+ //
+ /// @param f
+ /// The fill index (1-based).
+ /// When this path is added to a shape_character_def,
+ /// the index (decremented by 1) will reference an element
+ /// in the fill_style vector defined for that shape.
+ /// If zero, no fill will be active.
+ ///
+ void setRightFill(unsigned f)
+ {
+ m_fill1 = f;
+ }
+
+ unsigned getRightFill() const
+ {
+ return m_fill1;
+ }
+
+ /// Set the line style to use for this path
+ //
+ /// @param f
+ /// The line_style index (1-based).
+ /// When this path is added to a shape_character_def,
+ /// the index (decremented by 1) will reference an element
+ /// in the line_style vector defined for that shape.
+ /// If zero, no fill will be active.
+ ///
+ void setLineStyle(unsigned i)
+ {
+ m_line = i;
+ }
+
+ unsigned getLineStyle() const
+ {
+ return m_line;
+ }
+
+ /// Return the number of edges in this path
+ size_t size() const
+ {
+ return m_edges.size();
+ }
+
+ /// Return a reference to the Nth edge
+ Edge& operator[] (size_t n)
+ {
+ return m_edges[n];
+ }
+
+ /// Return a const reference to the Nth edge
+ const Edge& operator[] (size_t n) const
+ {
+ return m_edges[n];
+ }
+
+ /// Returns true if this path begins a new subshape. <-- VERIFYME
+ bool isNewShape() const
+ {
+ return m_new_shape;
+ }
+
+ }; // end of class Path
+
+
+ typedef Edge edge;
+ typedef Path path;
+
+} // end namespace gnash
+
+#endif // GNASH_SHAPE_H
+
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 8
+// tab-width: 8
+// indent-tabs-mode: t
+// End:
=== modified file 'libcore/Makefile.am'
--- a/libcore/Makefile.am 2009-02-27 06:46:40 +0000
+++ b/libcore/Makefile.am 2009-03-10 20:43:50 +0000
@@ -63,6 +63,8 @@
cxform.cpp \
DynamicShape.cpp \
Bitmap.cpp \
+ Shape.cpp \
+ StaticText.cpp \
TextField.cpp \
BlurFilter.cpp \
GlowFilter.cpp \
@@ -73,7 +75,7 @@
BevelFilter.cpp \
GradientBevelFilter.cpp \
parser/filter_factory.cpp \
- generic_character.cpp \
+ DisplayObject.cpp \
SWFMatrix.cpp \
movie_instance.cpp \
movie_root.cpp \
@@ -161,7 +163,9 @@
parser/filter_factory.h \
Font.h \
fontlib.h \
- generic_character.h \
+ Shape.h \
+ StaticText.h \
+ DisplayObject.h \
gnash.h \
GnashKey.h \
impl.h \
@@ -174,7 +178,7 @@
rect.h \
render.h \
ExportableResource.h \
- shape.h \
+ Geometry.h \
MovieClip.h \
SWFStream.h \
styles.h \
=== modified file 'libcore/MovieClip.cpp'
--- a/libcore/MovieClip.cpp 2009-03-10 06:23:07 +0000
+++ b/libcore/MovieClip.cpp 2009-03-10 20:43:50 +0000
@@ -482,7 +482,7 @@
character(parent, id),
m_root(r),
_drawable(new DynamicShape()),
- _drawable_inst(_drawable->create_character_instance(this, 0)),
+ _drawable_inst(_drawable->createDisplayObject(this, 0)),
m_play_state(PLAY),
m_current_frame(0),
m_has_looped(false),
@@ -1528,7 +1528,7 @@
if (existing_char) return NULL;
boost::intrusive_ptr<character> ch =
- cdef->create_character_instance(this, tag->getID());
+ cdef->createDisplayObject(this, tag->getID());
if (tag->hasName()) ch->set_name(tag->getName());
else if (ch->wantsInstanceName())
@@ -1600,7 +1600,7 @@
else
{
boost::intrusive_ptr<character> ch =
- cdef->create_character_instance(this, tag->getID());
+ cdef->createDisplayObject(this, tag->getID());
// TODO: check if we can drop this for REPLACE!
// should we rename the character when it's REPLACE tag?
@@ -3220,7 +3220,7 @@
boost::int32_t depthValue = static_cast<boost::int32_t>(depth);
boost::intrusive_ptr<character> newch =
- exported_movie->create_character_instance(movieclip.get(), 0);
+ exported_movie->createDisplayObject(movieclip.get(), 0);
#ifndef GNASH_USE_GC
assert(newch->get_ref_count() > 0);
=== modified file 'libcore/MovieClip.h'
--- a/libcore/MovieClip.h 2009-03-05 14:03:05 +0000
+++ b/libcore/MovieClip.h 2009-03-10 20:43:50 +0000
@@ -102,8 +102,8 @@
/// to be deprecated if every instance has a reference to its
/// definition, which should know its id...
///
- MovieClip(movie_definition* def,
- movie_instance* root, character* parent, int id);
+ MovieClip(movie_definition* def, movie_instance* root,
+ character* parent, int id);
virtual ~MovieClip();
=== added file 'libcore/Shape.cpp'
--- a/libcore/Shape.cpp 1970-01-01 00:00:00 +0000
+++ b/libcore/Shape.cpp 2009-03-10 20:43:50 +0000
@@ -0,0 +1,37 @@
+// Shape.cpp: Mouse/Character handling, for Gnash.
+//
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Shape.h"
+
+namespace gnash
+{
+
+void
+Shape::display()
+{
+ _def->display(this); // pass in transform info
+ clear_invalidated();
+}
+
+} // namespace gnash
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:
=== added file 'libcore/Shape.h'
--- a/libcore/Shape.h 1970-01-01 00:00:00 +0000
+++ b/libcore/Shape.h 2009-03-11 06:34:47 +0000
@@ -0,0 +1,82 @@
+//
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef GNASH_SHAPE_H
+#define GNASH_SHAPE_H
+
+#include "smart_ptr.h" // GNASH_USE_GC
+#include "DisplayObject.h"
+#include "shape_character_def.h"
+#include <cassert>
+
+// Forward declarations
+namespace gnash {
+ class character_def;
+}
+
+namespace gnash {
+
+/// For characters that don't store unusual state in their instances.
+class Shape : public DisplayObject
+{
+
+public:
+
+ Shape(shape_character_def* def, character* parent, int id)
+ :
+ DisplayObject(parent, id),
+ _def(def)
+ {
+ assert(_def);
+ }
+
+ virtual void display();
+
+protected:
+
+ character_def* getDefinition() const
+ {
+ return _def.get();
+ }
+
+#ifdef GNASH_USE_GC
+ /// Mark reachable resources (for the GC)
+ void markReachableResources() const
+ {
+ assert(isReachable());
+ _def->setReachable();
+ markCharacterReachable();
+ }
+#endif
+
+private:
+
+ const boost::intrusive_ptr<shape_character_def> _def;
+
+};
+
+
+} // namespace gnash
+
+
+#endif
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:
=== added file 'libcore/StaticText.cpp'
--- a/libcore/StaticText.cpp 1970-01-01 00:00:00 +0000
+++ b/libcore/StaticText.cpp 2009-03-11 10:14:31 +0000
@@ -0,0 +1,53 @@
+// Shape.cpp: Mouse/Character handling, for Gnash.
+//
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "StaticText.h"
+#include "swf/DefineTextTag.h"
+
+namespace gnash
+{
+
+StaticText*
+StaticText::getStaticText(std::vector<const SWF::TextRecord*>& to,
+ size_t& numChars)
+{
+ _selectedText.clear();
+
+ if (_def->extractStaticText(to, numChars)) {
+ _selectedText.resize(numChars);
+ return this;
+ }
+
+ return 0;
+}
+
+
+void
+StaticText::display()
+{
+ _def->display(this); // pass in transform info
+ clear_invalidated();
+}
+
+} // namespace gnash
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:
=== added file 'libcore/StaticText.h'
--- a/libcore/StaticText.h 1970-01-01 00:00:00 +0000
+++ b/libcore/StaticText.h 2009-03-11 10:36:40 +0000
@@ -0,0 +1,130 @@
+//
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef GNASH_STATIC_TEXT_H
+#define GNASH_STATIC_TEXT_H
+
+#include "smart_ptr.h" // GNASH_USE_GC
+#include "character.h" // for inheritance
+#include "DisplayObject.h"
+#include "swf/DefineTextTag.h"
+
+#include <boost/dynamic_bitset.hpp>
+#include <cassert>
+
+// Forward declarations
+namespace gnash {
+ class character_def;
+ namespace SWF {
+ class TextRecord;
+ }
+}
+
+namespace gnash {
+
+/// Static text fields, SWF-defined with read-only text.
+//
+/// StaticText objects hold mutable selection and color information.
+class StaticText : public DisplayObject
+{
+public:
+
+ StaticText(SWF::DefineTextTag* def, character* parent, int id)
+ :
+ DisplayObject(parent, id),
+ _def(def)
+ {
+ assert(_def);
+ }
+
+ /// Return a pointer to this if our definition contains any static text.
+ //
+ /// This is non-const because a TextSnapshot needs to add selection and
+ /// color information to this StaticText. It also resets selection.
+ //
+ /// @param to A vector of pointers to TextRecords containing text.
+ /// @param numChars The total number of characters in all TextRecords is
+ /// written to this variable.
+ /// Note: This function always removes any existing selection and resizes
+ /// the bitset to the number of characters in all TextRecords.
+ virtual StaticText* getStaticText(std::vector<const SWF::TextRecord*>& to,
+ size_t& numChars);
+
+ virtual void display();
+
+ void setSelected(size_t pos, bool selected) {
+ _selectedText.set(pos, selected);
+ }
+
+ /// Return a bitset showing which characters (by index) are selected.
+ //
+ /// Note: mutable information is meaningless until the StaticText is
+ /// queried with getStaticText(). This is because under normal
+ /// circumstances there is no need for it.
+ /// Note also: the size() member of boost::dynamic_bitset returns 0 before
+ /// getStaticText() is called; afterwards it is equivalent to the
+ /// number of characters in the StaticText's definition.
+ const boost::dynamic_bitset<>& getSelected() const {
+ return _selectedText;
+ }
+
+ void setSelectionColor(boost::uint32_t color);
+
+protected:
+
+ character_def* getDefinition() const {
+ return _def.get();
+ }
+
+#ifdef GNASH_USE_GC
+ /// Mark reachable resources (for the GC)
+ void markReachableResources() const
+ {
+ assert(isReachable());
+ _def->setReachable();
+ markCharacterReachable();
+ }
+#endif
+
+private:
+
+ const boost::intrusive_ptr<SWF::DefineTextTag> _def;
+
+ /// A bitmask indicating which static text characters are selected
+ //
+ /// This is only present for static text fields, and only after
+ /// a TextSnapshot has queried the character for text.
+ boost::dynamic_bitset<> _selectedText;
+
+ /// The color of the background for selected characters.
+ //
+ /// This is alawys opaque.
+ rgba _selectionColor;
+
+};
+
+
+} // end namespace gnash
+
+
+#endif // GNASH_GENERIC_CHARACTER_H
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:
=== modified file 'libcore/asobj/TextSnapshot_as.cpp'
--- a/libcore/asobj/TextSnapshot_as.cpp 2009-03-10 12:22:29 +0000
+++ b/libcore/asobj/TextSnapshot_as.cpp 2009-03-11 10:14:31 +0000
@@ -28,7 +28,7 @@
#include "smart_ptr.h" // for boost intrusive_ptr
#include "builtin_function.h" // need builtin_function
#include "Object.h" // for getObjectInterface
-#include "generic_character.h"
+#include "StaticText.h"
#include "DisplayList.h"
#include "MovieClip.h"
#include "Font.h"
@@ -39,7 +39,6 @@
#include <boost/algorithm/string/compare.hpp>
#include <boost/dynamic_bitset.hpp>
#include <algorithm>
-#include <numeric>
namespace gnash {
@@ -69,16 +68,6 @@
namespace {
-/// Accumulate the number of glyphs in a TextRecord.
-struct CountRecords
-{
- size_t operator()(size_t c, const TextSnapshot_as::Records::value_type t) {
- const SWF::TextRecord::Glyphs& glyphs = t->glyphs();
- size_t ret = c + glyphs.size();
- return ret;
- }
-};
-
/// Locate static text in a character.
//
/// Static text (TextRecords) are added to a vector, which should
@@ -94,15 +83,17 @@
{}
void operator()(character* ch) {
+
+ /// This is not tested.
if (ch->isUnloaded()) return;
TextSnapshot_as::Records text;
- generic_character* tf;
+ StaticText* tf;
+ size_t numChars;
- if ((tf = ch->getStaticText(text))) {
+ if ((tf = ch->getStaticText(text, numChars))) {
_fields.push_back(std::make_pair(tf, text));
- _count = std::accumulate(text.begin(), text.end(), _count,
- CountRecords());
+ _count += numChars;
}
}
@@ -122,31 +113,71 @@
as_object(getTextSnapshotInterface()),
_textFields(),
_valid(mc),
- _count(getTextFields(mc, _textFields)),
- _selected(_count)
+ _count(getTextFields(mc, _textFields))
{
}
void
TextSnapshot_as::setSelected(size_t start, size_t end, bool selected)
{
- start = std::min(start, _selected.size());
- end = std::min(end, _selected.size());
+ /// If there are no TextFields, there is nothing to do.
+ if (_textFields.empty()) return;
+
+ start = std::min(start, _count);
+ end = std::min(end, _count);
+
+ TextFields::const_iterator field = _textFields.begin();
+
+ size_t totalChars = field->first->getSelected().size();
+ size_t fieldStartIndex = 0;
for (size_t i = start; i < end; ++i) {
- _selected.set(i, selected);
+
+ /// Find the field containing the start index.
+ while (totalChars <= i) {
+ fieldStartIndex = totalChars;
+ ++field;
+
+ if (field == _textFields.end()) return;
+
+ const boost::dynamic_bitset<>& sel = field->first->getSelected();
+ totalChars += sel.size();
+ continue;
+ }
+ field->first->setSelected(i - fieldStartIndex, selected);
}
}
bool
TextSnapshot_as::getSelected(size_t start, size_t end) const
{
- start = std::min(start, _selected.size());
- end = std::min(end, _selected.size());
+
+ if (_textFields.empty()) return false;
+
+ start = std::min(start, _count);
+ end = std::min(end, _count);
+
+ TextFields::const_iterator field = _textFields.begin();
+
+ size_t totalChars = field->first->getSelected().size();
+ size_t fieldStartIndex = 0;
for (size_t i = start; i < end; ++i) {
- if (_selected.test(i)) return true;
+
+ /// Find the field containing the start index.
+ while (totalChars <= i) {
+ fieldStartIndex = totalChars;
+ ++field;
+ if (field == _textFields.end()) return false;
+
+ const boost::dynamic_bitset<>& sel = field->first->getSelected();
+ totalChars += sel.size();
+ continue;
+ }
+
+ if (field->first->getSelected().test(i - fieldStartIndex)) return true;
}
+
return false;
}
@@ -168,6 +199,9 @@
const Records& rec = field->second;
const SWFMatrix& mat = field->first->getMatrix();
+ const boost::dynamic_bitset<>& selected = field->first->getSelected();
+
+ const std::string::size_type fieldStartIndex = pos;
for (Records::const_iterator j = rec.begin(), end = rec.end();
j != end; ++j) {
@@ -199,7 +233,8 @@
as_object* el = new as_object;
el->init_member("indexInRun", pos);
- el->init_member("selected", _selected.test(pos));
+ el->init_member("selected",
+ selected.test(pos - fieldStartIndex));
el->init_member("font", font->name());
el->init_member("color", tr->color().toRGBA());
el->init_member("height", TWIPS_TO_PIXELS(tr->textHeight()));
@@ -227,7 +262,7 @@
}
void
-TextSnapshot_as::makeString(std::string& to, bool newline,
+TextSnapshot_as::makeString(std::string& to, bool newline, bool selectedOnly,
std::string::size_type start, std::string::size_type len) const
{
@@ -241,6 +276,10 @@
if (newline && pos > start) to += '\n';
const Records& records = field->second;
+ const boost::dynamic_bitset<>& selected = field->first->getSelected();
+
+ /// Remember the position at the beginning of the StaticText.
+ const std::string::size_type fieldStartIndex = pos;
for (Records::const_iterator j = records.begin(), end = records.end();
j != end; ++j) {
@@ -267,7 +306,9 @@
continue;
}
- to += font->codeTableLookup(k->index, true);
+ if (!selectedOnly || selected.test(pos - fieldStartIndex)) {
+ to += font->codeTableLookup(k->index, true);
+ }
++pos;
if (pos - start == len) return;
}
@@ -289,7 +330,7 @@
end = std::max(start + 1, end);
std::string snapshot;
- makeString(snapshot, nl, start, end - start);
+ makeString(snapshot, nl, false, start, end - start);
return snapshot;
@@ -300,15 +341,7 @@
{
std::string sel;
- for (size_t i = 0, e = _selected.size(); i != e; ++i) {
- while (!_selected.test(i)) {
- ++i;
- if (i == e) return sel;
- }
- size_t start = i;
- while (_selected.test(i) && i != e) ++i;
- makeString(sel, newline, start, i - start);
- }
+ makeString(sel, newline, true);
return sel;
}
=== modified file 'libcore/asobj/TextSnapshot_as.h'
--- a/libcore/asobj/TextSnapshot_as.h 2009-03-10 08:50:13 +0000
+++ b/libcore/asobj/TextSnapshot_as.h 2009-03-11 10:14:31 +0000
@@ -20,12 +20,11 @@
#define GNASH_ASOBJ_TEXTSNAPSHOT_H
#include "as_object.h"
-#include <boost/dynamic_bitset.hpp>
// Forward declarations.
namespace gnash {
- class generic_character;
+ class StaticText;
class Array_as;
namespace SWF {
class TextRecord;
@@ -44,7 +43,7 @@
/// Should remain in the order of insertion
/// We should only ever iterate from begin to end, so there's no
/// performance issue.
- typedef std::vector<std::pair<generic_character*, Records> > TextFields;
+ typedef std::vector<std::pair<StaticText*, Records> > TextFields;
/// Construct a TextSnapshot_as from a MovieClip.
//
@@ -79,7 +78,17 @@
private:
+ /// Generate a string from the TextRecords in this TextSnapshot.
+ //
+ /// @param to The string to write to
+ /// @param newline If true, newlines are written after every
+ /// StaticText in this TextSnapshot
+ /// @param selectedOnly Only write character that are selected to.
+ /// @param start The start index
+ /// @param len The number of StaticText characters to traverse.
+ /// This includes non-selected characters.
void makeString(std::string& to, bool newline = false,
+ bool selectedOnly = false,
std::string::size_type start = 0,
std::string::size_type len = std::string::npos) const;
@@ -97,15 +106,6 @@
/// afresh every time.
const size_t _count;
- /// Characters in the text run are selected individually.
- //
- /// Storing selection information along with the characters themselves
- /// means that a separate object is necessary for each character.
- /// Using a dynamic bitset prevents this, and generally
- /// saves a lot of memory (32 bytes for boost's dynamic bitset against
- /// one byte per character, possibly packed, for a bool in an object).
- boost::dynamic_bitset<> _selected;
-
};
} // end of gnash namespace
=== modified file 'libcore/character.h'
--- a/libcore/character.h 2009-03-09 14:22:03 +0000
+++ b/libcore/character.h 2009-03-11 10:14:31 +0000
@@ -49,7 +49,7 @@
class ExecutableCode;
class action_buffer;
class movie_definition;
- class generic_character;
+ class StaticText;
namespace SWF {
class TextRecord;
}
@@ -417,9 +417,9 @@
/// Allow extraction of static text.
//
/// Default is a no-op, implemented only for DefineText though
- /// generic_character.
- virtual generic_character* getStaticText(
- std::vector<const SWF::TextRecord*>& /*to*/) {
+ /// DisplayObject.
+ virtual StaticText* getStaticText(std::vector<const SWF::TextRecord*>&,
+ size_t&) {
return 0;
}
=== removed file 'libcore/generic_character.cpp'
--- a/libcore/generic_character.cpp 2009-03-09 14:22:03 +0000
+++ b/libcore/generic_character.cpp 1970-01-01 00:00:00 +0000
@@ -1,71 +0,0 @@
-// generic_character.cpp: Mouse/Character handling, for Gnash.
-//
-// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-//
-
-#include "generic_character.h"
-
-namespace gnash
-{
-
-void
-generic_character::add_invalidated_bounds(InvalidatedRanges& ranges,
- bool force)
-{
- ranges.add(m_old_invalidated_ranges);
- if (isVisible() && (m_invalidated||force))
- {
- rect bounds;
- bounds.expand_to_transformed_rect(getWorldMatrix(),
- m_def->get_bound());
- ranges.add(bounds.getRange());
- }
-}
-
-
-bool
-generic_character::pointInShape(boost::int32_t x, boost::int32_t y) const
-{
- SWFMatrix wm = getWorldMatrix();
- SWFMatrix wm_inverse = wm.invert();
- point lp(x, y);
- wm_inverse.transform(lp);
- return m_def->point_test_local(lp.x, lp.y, wm);
-}
-
-
-generic_character*
-generic_character::getStaticText(std::vector<const SWF::TextRecord*>& to)
-{
- if (m_def->extractStaticText(to)) return this;
- return 0;
-}
-
-void
-generic_character::display()
-{
- m_def->display(this); // pass in transform info
-
- clear_invalidated();
-}
-
-} // namespace gnash
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:
=== removed file 'libcore/generic_character.h'
--- a/libcore/generic_character.h 2009-03-09 14:22:03 +0000
+++ b/libcore/generic_character.h 1970-01-01 00:00:00 +0000
@@ -1,124 +0,0 @@
-//
-// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-#ifndef GNASH_GENERIC_CHARACTER_H
-#define GNASH_GENERIC_CHARACTER_H
-
-#include "smart_ptr.h" // GNASH_USE_GC
-#include "character.h" // for inheritance
-#include "shape_character_def.h" // for add_invalidated_bounds
-
-#include <cassert>
-
-namespace gnash {
-
- // Forward declarations
- class character_def;
-
- namespace SWF {
- class TextRecord;
- }
-
-}
-
-namespace gnash {
-
-/// For characters that don't store unusual state in their instances.
-//
-/// @@AFAICT this is only used for shape characters
-///
-class generic_character : public character
-{
-
-protected:
-
- boost::intrusive_ptr<character_def> m_def;
-
-#ifdef GNASH_USE_GC
- /// Mark reachabe resources (for the GC)
- //
- /// These are:
- /// - this char's definition (m_def)
- ///
- void markReachableResources() const
- {
- assert(isReachable());
- m_def->setReachable();
-
- markCharacterReachable();
- }
-#endif // GNASH_USE_GC
-
-public:
-
- generic_character(character_def* def, character* parent, int id)
- :
- character(parent, id),
- m_def(def)
- {
- assert(m_def);
- }
-
- /// generic characters can not handle mouse events, so
- /// the default implementation returns false.
- /// override in your subclass to change this
- virtual bool can_handle_mouse_event() const {
- return false;
- }
-
- virtual generic_character* getStaticText(
- std::vector<const SWF::TextRecord*>& /*to*/);
-
- virtual void display();
-
- rect getBounds() const
- {
- return m_def->get_bound();
- }
-
- /// Generic character is NEVER a mouse entity by default, so
- /// the default implementation of this method always returns NULL.
- /// Override it from subclasses that do can be mouse entities.
- ///
- /// If you need to check for a generic character to contain a
- /// given point, use the pointInShape() function instead.
- ///
- virtual character* get_topmost_mouse_entity(boost::int32_t /*x*/,
- boost::int32_t /*y*/)
- {
- return NULL;
- }
-
- // See dox in character.h
- virtual bool pointInShape(boost::int32_t x, boost::int32_t y) const;
-
- void add_invalidated_bounds(InvalidatedRanges& ranges, bool force);
-
-
-};
-
-
-} // end namespace gnash
-
-
-#endif // GNASH_GENERIC_CHARACTER_H
-
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:
=== modified file 'libcore/parser/BitmapMovieDefinition.cpp'
--- a/libcore/parser/BitmapMovieDefinition.cpp 2009-02-25 22:33:03 +0000
+++ b/libcore/parser/BitmapMovieDefinition.cpp 2009-03-10 20:43:50 +0000
@@ -21,14 +21,13 @@
#include "BitmapMovieInstance.h"
#include "BitmapMovieDefinition.h"
#include "fill_style.h"
-#include "shape.h" // for class path and class edge
+#include "Geometry.h" // for class path and class edge
#include "render.h" // for ::display
#include "GnashImage.h"
#include "log.h"
namespace gnash {
-
shape_character_def*
BitmapMovieDefinition::getShapeDef()
{
=== modified file 'libcore/parser/BitmapMovieDefinition.h'
--- a/libcore/parser/BitmapMovieDefinition.h 2009-02-25 22:33:03 +0000
+++ b/libcore/parser/BitmapMovieDefinition.h 2009-03-10 20:43:50 +0000
@@ -54,7 +54,12 @@
/// - image->size() bytes (for get_bytes_loaded()/get_bytes_total())
/// - provided url
///
- BitmapMovieDefinition(std::auto_ptr<GnashImage> image, const
std::string& url);
+ BitmapMovieDefinition(std::auto_ptr<GnashImage> image,
+ const std::string& url);
+
+ virtual character* createDisplayObject(character* parent, int id) {
+ return 0;
+ }
// Discard id, always return the only shape character we have
virtual character_def* get_character_def(int /*id*/)
=== modified file 'libcore/parser/SWFMovieDefinition.h'
--- a/libcore/parser/SWFMovieDefinition.h 2009-02-25 22:33:03 +0000
+++ b/libcore/parser/SWFMovieDefinition.h 2009-03-10 20:43:50 +0000
@@ -385,12 +385,16 @@
///
movie_instance* create_movie_instance(character* parent=0);
+ virtual character* createDisplayObject(character* parent, int id) {
+ return 0;
+ }
+
virtual const std::string& get_url() const { return _url; }
const rect& get_bound() const {
// It is required that get_bound() is implemented in character definition
// classes. However, it makes no sense to call it for movie interfaces.
- // get_bound() is currently only used by generic_character which normally
+ // get_bound() is currently only used by DisplayObject which normally
// is used only shape character definitions. See character_def.h to learn
// why it is virtual anyway.
abort(); // should not be called
=== modified file 'libcore/parser/character_def.cpp'
--- a/libcore/parser/character_def.cpp 2009-02-09 03:22:05 +0000
+++ b/libcore/parser/character_def.cpp 2009-03-10 20:43:50 +0000
@@ -21,18 +21,11 @@
#endif
#include "character_def.h"
-#include "generic_character.h"
#include "render_handler.h" // for destruction of render_cache_manager
namespace gnash
{
-character*
-character_def::create_character_instance(character* parent, int id)
-{
- return new generic_character(this, parent, id);
-}
-
character_def::~character_def()
{
delete m_render_cache;
=== modified file 'libcore/parser/character_def.h'
--- a/libcore/parser/character_def.h 2009-03-09 20:45:43 +0000
+++ b/libcore/parser/character_def.h 2009-03-11 06:34:47 +0000
@@ -64,15 +64,6 @@
{
}
- /// Return any text defined as static.
- //
- /// This is used for MovieClip.getTextSnapshot() and should only be
- /// implemented in DefineTextTag. Default is a no-op
- virtual bool extractStaticText(std::vector<const SWF::TextRecord*>& /*to*/)
- {
- return false;
- }
-
/// Return true if the specified point is on the interior of our shape.
//
/// Point coordinates are local coords (TWIPS)
@@ -89,12 +80,11 @@
/// Should stick the result in a boost::intrusive_ptr immediately.
//
- /// default is to make a generic_character
+ /// default is to make a DisplayObject
///
- virtual character* create_character_instance(character* parent,
- int id);
+ virtual character* createDisplayObject(character* parent, int id) = 0;
- // Declared as virtual here because generic_character needs access to it
+ // Declared as virtual here because DisplayObject needs access to it
virtual const rect& get_bound() const = 0;
/// Cache holder for renderer (contents depend on renderer handler)
=== modified file 'libcore/parser/shape_character_def.cpp'
--- a/libcore/parser/shape_character_def.cpp 2009-01-22 20:10:39 +0000
+++ b/libcore/parser/shape_character_def.cpp 2009-03-10 20:43:50 +0000
@@ -28,10 +28,10 @@
#include "impl.h"
#include "log.h"
#include "render.h"
+#include "Shape.h"
#include "SWFStream.h"
#include "MovieClip.h"
-#include <cfloat>
#include <algorithm>
// Define the macro below to always compute bounds for shape characters
@@ -41,6 +41,12 @@
namespace gnash
{
+character*
+shape_character_def::createDisplayObject(character* parent, int id)
+{
+ return new Shape(this, parent, id);
+}
+
// Read fill styles, and push them onto the given style array.
static void
read_fill_styles(std::vector<fill_style>& styles, SWFStream& in,
=== modified file 'libcore/parser/shape_character_def.h'
--- a/libcore/parser/shape_character_def.h 2009-01-22 14:36:37 +0000
+++ b/libcore/parser/shape_character_def.h 2009-03-10 20:43:50 +0000
@@ -11,7 +11,7 @@
#include "character_def.h" // for inheritance of shape_character_def
#include "smart_ptr.h" // GNASH_USE_GC
-#include "shape.h" // for path
+#include "Geometry.h" // for path
#include "rect.h" // for composition
#include "fill_style.h" // for fill style
#include "styles.h" // for line style
@@ -53,6 +53,8 @@
virtual bool point_test_local(boost::int32_t x, boost::int32_t y,
const SWFMatrix& wm);
+ virtual character* createDisplayObject(character* parent, int id);
+
/// \brief
/// Read a shape definition as included in DEFINEFONT*,
/// DEFINESHAPE* or DEFINEMORPH* tag
=== modified file 'libcore/parser/sprite_definition.cpp'
--- a/libcore/parser/sprite_definition.cpp 2009-01-22 20:10:39 +0000
+++ b/libcore/parser/sprite_definition.cpp 2009-03-10 20:43:50 +0000
@@ -39,14 +39,12 @@
namespace gnash {
character*
-sprite_definition::create_character_instance(character* parent,
- int id)
+sprite_definition::createDisplayObject(character* parent, int id)
{
#ifdef DEBUG_REGISTER_CLASS
log_debug(_("Instantiating sprite_def %p"), (void*)this);
#endif
- MovieClip* si = new MovieClip(this,
- parent->get_root(), parent, id);
+ MovieClip* si = new MovieClip(this, parent->get_root(), parent, id);
return si;
}
=== modified file 'libcore/parser/sprite_definition.h'
--- a/libcore/parser/sprite_definition.h 2009-02-25 22:33:03 +0000
+++ b/libcore/parser/sprite_definition.h 2009-03-10 20:43:50 +0000
@@ -243,8 +243,7 @@
// the parent movie's display list.
//
// overloads from character_def
- virtual character* create_character_instance(
- character* parent, int id);
+ virtual character* createDisplayObject(character* parent, int id);
private:
@@ -326,7 +325,7 @@
const rect& get_bound() const {
// It is required that get_bound() is implemented in character definition
// classes. However, it makes no sense to call it for sprite definitions.
- // get_bound() is currently only used by generic_character which normally
+ // get_bound() is currently only used by DisplayObject which normally
// is used only shape character definitions. See character_def.h to learn
// why it is virtual anyway.
abort(); // should not be called
=== removed file 'libcore/shape.h'
--- a/libcore/shape.h 2009-02-25 22:33:03 +0000
+++ b/libcore/shape.h 1970-01-01 00:00:00 +0000
@@ -1,594 +0,0 @@
-// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-//
-
-
-#ifndef GNASH_SHAPE_H
-#define GNASH_SHAPE_H
-
-#include "dsodefs.h"
-#include "SWFMatrix.h"
-
-#include <vector> // for path composition
-#include <cmath> // sqrt
-
-
-// Forward declarations
-namespace gnash {
- class rect;
-}
-
-namespace gnash {
-
- /// \brief
- /// Defines an edge with a control point and an anchor point.
- ///
- /// Could be a quadratic bezier curve, or a straight line(degenerated curve).
- ///
- class Edge
- {
- public:
-
- // Quadratic bezier: point = p0 * t^2 + p1 * 2t(1-t) + p2 * (1-t)^2
- point cp; // control point, TWIPS
- point ap; // anchor point, TWIPS
-
- Edge()
- :
- cp(0, 0), ap(0, 0)
- { };
-
- Edge(boost::int32_t cx, boost::int32_t cy, boost::int32_t ax,
boost::int32_t ay)
- :
- cp(cx, cy), ap(ax, ay)
- { }
-
- Edge(const Edge& from)
- :
- cp(from.cp), ap(from.ap)
- { }
-
- Edge(const point& ncp, const point& nap)
- :
- cp(ncp), ap(nap)
- { }
-
- bool isStraight() const
- {
- return cp == ap;
- }
-
- // TODO: drop this!
- bool is_straight() const { return isStraight(); }
-
- /// Transform the edge according to the given SWFMatrix.
- void transform(const SWFMatrix& mat)
- {
- mat.transform(ap);
- mat.transform(cp);
- }
-
- /// Return squared distance between point pt and segment A-B
- static double
- squareDistancePtSeg(const point& p, const point& A, const point& B)
- {
- boost::int32_t dx = B.x - A.x;
- boost::int32_t dy = B.y - A.y;
-
- if ( dx == 0 && dy == 0 )
- {
- return p.squareDistance(A);
- }
-
- boost::int32_t pdx = p.x - A.x;
- boost::int32_t pdy = p.y - A.y;
-
- double u = ( (double)(pdx) * dx + (double)(pdy) * dy ) / (
(double)(dx)*dx + (double)(dy)*dy );
-
- if (u <= 0)
- {
- return p.squareDistance(A);
- }
-
- if (u >= 1)
- {
- return p.squareDistance(B);
- }
-
- point px(A, B, u); // FIXME: this interpolation introduce a precision
loss (point is int-based)
- return p.squareDistance(px);
- }
-
- /// Return distance between point pt and segment A-B
- static double
- distancePtSeg(const point& pt, const point& A, const point& B)
- {
- double square = squareDistancePtSeg(pt, A, B);
- return std::sqrt(square);
- }
-
- /// Find point of the quadratic curve defined by points A,C,B
- //
- /// @param A The first point
- /// @param C The second point (control point)
- /// @param B The third point (anchor point)
- /// @param ret The point to write result into
- /// @param t the step factor between 0 and 1
- ///
-
- static point
- pointOnCurve(const point& A,
- const point& C,
- const point& B, float t)
- {
- point Q1(A, C, t);
- point Q2(C, B, t);
- point R(Q1, Q2, t);
-
- return R;
- }
-
- /// Return square distance between point pt and the point on curve found by
- /// applying the T parameter to the quadratic bezier curve function
- //
- /// @param A The first point of the bezier curve
- /// @param C The second point of the bezier curve (control point)
- /// @param B The third point of the bezier curve (anchor point)
- /// @param p The point we want to compute distance from
- /// @param t the step factor between 0 and 1
- ///
- static boost::int64_t squareDistancePtCurve(const point& A,
- const point& C,
- const point& B,
- const point& p, float t)
- {
- return p.squareDistance( pointOnCurve(A, C, B, t) );
- }
- };
-
-
- ///\brief
- /// A subset of a shape, a series of edges sharing a single set of styles.
- class DSOEXPORT Path
- {
- public:
- /// Left fill style index (1-based)
- unsigned m_fill0;
-
- /// Right fill style index (1-based)
- unsigned m_fill1;
-
- /// Line style index (1-based)
- unsigned m_line;
-
- /// Start point of the path
- point ap;
-
- /// Edges forming the path
- std::vector<Edge> m_edges;
-
- /// This flag is set when the path is the first one of a new "sub-shape".
- /// All paths with a higher index in the list belong to the same
- /// shape unless they have m_new_shape==true on their own.
- /// Sub-shapes affect the order in which outlines and shapes are rendered.
- bool m_new_shape;
-
- /// Default constructor
- //
- /// @param newShape
- /// True if this path starts a new subshape
- ///
- Path(bool newShape = false)
- :
- m_new_shape(newShape)
- {
- reset(0, 0, 0, 0, 0);
- }
-
- Path(const Path& from)
- :
- m_fill0(from.m_fill0),
- m_fill1(from.m_fill1),
- m_line(from.m_line),
- ap(from.ap),
- m_edges(from.m_edges),
- m_new_shape(from.m_new_shape)
- {
- }
-
- /// Initialize a path
- //
- /// @param ax
- /// X coordinate of path origin in TWIPS
- ///
- /// @param ay
- /// Y coordinate in path origin in TWIPS
- ///
- /// @param fill0
- /// Fill style index for left fill (1-based).
- /// Zero means NO style.
- ///
- /// @param fill1
- /// Fill style index for right fill (1-based)
- /// Zero means NO style.
- ///
- /// @param line
- /// Line style index for right fill (1-based).
- /// Zero means NO style.
- ///
- /// @param newShape
- /// True if this path starts a new subshape
- Path(boost::int32_t ax, boost::int32_t ay,
- unsigned fill0, unsigned fill1, unsigned line,
- bool newShape)
- :
- m_new_shape(newShape)
- {
- reset(ax, ay, fill0, fill1, line);
- }
-
- /// Re-initialize a path, maintaining the "new shape" flag untouched
- //
- /// @param ax
- /// X coordinate of path origin in TWIPS
- ///
- /// @param ay
- /// Y coordinate in path origin in TWIPS
- ///
- /// @param fill0
- /// Fill style index for left fill
- ///
- /// @param fill1
- /// Fill style index for right fill
- //
- /// @param line
- /// Line style index for right fill
- ///
- void reset(boost::int32_t ax, boost::int32_t ay,
- unsigned fill0, unsigned fill1, unsigned line)
- // Reset all our members to the given values, and clear our edge list.
- {
- ap.x = ax;
- ap.y = ay;
- m_fill0 = fill0;
- m_fill1 = fill1;
- m_line = line;
-
- m_edges.resize(0);
- assert(is_empty());
- }
-
- /// Return true if we have no edges.
- bool is_empty() const
- {
- return m_edges.empty();
- }
-
- /// Expand given rect to include bounds of this path
- //
- /// @param r
- /// The rectangle to expand with our own bounds
- ///
- /// @param thickness
- /// The thickess of our lines, half the thickness will
- /// be added in all directions in swf8+, all of it will
- /// in swf7-
- ///
- /// @param swfVersion
- /// SWF version to use.
- ///
- void
- expandBounds(rect& r, unsigned int thickness, int swfVersion) const
- {
- const Path& p = *this;
- size_t nedges = m_edges.size();
-
- if ( ! nedges ) return; // this path adds nothing
-
- if (thickness)
- {
- // NOTE: Half of thickness would be enough (and correct) for
- // radius, but that would not match how Flash calculates the
- // bounds using the drawing API.
- unsigned int radius = swfVersion < 8 ? thickness : thickness/2;
-
- r.expand_to_circle(ap.x, ap.y, radius);
- for (unsigned int j = 0; j<nedges; j++)
- {
- r.expand_to_circle(m_edges[j].ap.x, m_edges[j].ap.y, radius);
- r.expand_to_circle(m_edges[j].cp.x, m_edges[j].cp.y, radius);
- }
- }
- else
- {
- r.expand_to_point(ap.x, ap.y);
- for (unsigned int j = 0; j<nedges; j++)
- {
- r.expand_to_point(m_edges[j].ap.x, p.m_edges[j].ap.y);
- r.expand_to_point(m_edges[j].cp.x, p.m_edges[j].cp.y);
- }
- }
- }
-
- /// @{ Primitives for the Drawing API
- ///
- /// Name of these functions track Ming interface
- ///
-
- /// Draw a straight line.
- //
- /// Point coordinates are relative to path origin
- /// and expressed in TWIPS.
- ///
- /// @param x
- /// X coordinate in TWIPS
- ///
- /// @param y
- /// Y coordinate in TWIPS
- ///
- void
- drawLineTo(boost::int32_t dx, boost::int32_t dy)
- {
- m_edges.push_back(Edge(dx, dy, dx, dy));
- }
-
- /// Draw a curve.
- //
- /// Offset values are relative to path origin and
- /// expressed in TWIPS.
- ///
- /// @param cx
- /// Control point's X coordinate.
- ///
- /// @param cy
- /// Control point's Y coordinate.
- ///
- /// @param ax
- /// Anchor point's X ordinate.
- ///
- /// @param ay
- /// Anchor point's Y ordinate.
- ///
- void
- drawCurveTo(boost::int32_t cdx, boost::int32_t cdy, boost::int32_t adx,
boost::int32_t ady)
- {
- m_edges.push_back(Edge(cdx, cdy, adx, ady));
- }
-
- /// Remove all edges and reset style infomation
- void clear()
- {
- m_edges.resize(0);
- m_fill0 = m_fill1 = m_line = 0;
- }
-
- /// @} Primitives for the Drawing API
-
-
- /// Returns true if the last and the first point of the path match
- bool isClosed() const
- {
- if ( m_edges.empty() )
- {
- return true;
- }
- else
- {
- return m_edges.back().ap == ap;
- }
- }
-
- /// Close this path with a straight line, if not already closed
- void close()
- {
- if ( m_edges.empty() ) return;
-
- // Close it with a straight edge if needed
- const Edge& lastedge = m_edges.back();
- if ( lastedge.ap != ap )
- {
- Edge newedge(ap, ap);
- m_edges.push_back(newedge);
- }
- }
-
- /// \brief
- /// Return true if the given point is within the given squared distance
- /// from this path edges.
- //
- /// NOTE: if the path is empty, false is returned.
- ///
- bool
- withinSquareDistance(const point& p, double dist) const
- {
- size_t nedges = m_edges.size();
-
- if ( ! nedges ) return false;
-
- point px(ap);
- for (size_t i=0; i<nedges; ++i)
- {
- const Edge& e = m_edges[i];
- point np(e.ap);
-
- if ( e.isStraight() )
- {
- double d = Edge::squareDistancePtSeg(p, px, np);
-
- if ( d <= dist ) return true;
- }
- else
- {
-
- const point& A = px;
- const point& C = e.cp;
- const point& B = e.ap;
-
- // Approximate the curve to segCount segments
- // and compute distance of query point from each
- // segment.
- //
- // TODO: find an apprpriate value for segCount based
- // on rendering scale ?
- //
- int segCount = 10;
- point p0(A.x, A.y);
- for (int i=1; i<=segCount; ++i)
- {
- float t1 = (float)(i) / segCount;
- point p1 = Edge::pointOnCurve(A, C, B, t1);
-
- // distance from point and segment being an approximation
- // of the curve
- double d = Edge::squareDistancePtSeg(p, p0, p1);
- if ( d <= dist ) return true;
-
- p0.setTo(p1.x, p1.y);
- }
- }
- px = np;
- }
-
- return false;
- }
-
- /// Transform all path coordinates according to the given SWFMatrix.
- void transform(const SWFMatrix& mat)
- {
- mat.transform(ap);
- std::vector<Edge>::iterator it = m_edges.begin(), ie =
m_edges.end();
- for(; it != ie; it++)
- {
- (*it).transform(mat);
- }
- }
-
- /// Set this path as the start of a new (sub)shape
- void setNewShape()
- {
- m_new_shape=true;
- }
-
- /// Return true if this path starts a new (sub)shape
- bool getNewShape() const
- {
- return m_new_shape;
- }
-
- /// Return true if this path contains no edges
- bool empty() const
- {
- return is_empty();
- }
-
- /// Set the fill to use on the left side
- //
- /// @param f
- /// The fill index (1-based).
- /// When this path is added to a shape_character_def,
- /// the index (decremented by 1) will reference an element
- /// in the fill_style vector defined for that shape.
- /// If zero, no fill will be active.
- ///
- void setLeftFill(unsigned f)
- {
- m_fill0 = f;
- }
-
- unsigned getLeftFill() const
- {
- return m_fill0;
- }
-
- /// Set the fill to use on the left side
- //
- /// @param f
- /// The fill index (1-based).
- /// When this path is added to a shape_character_def,
- /// the index (decremented by 1) will reference an element
- /// in the fill_style vector defined for that shape.
- /// If zero, no fill will be active.
- ///
- void setRightFill(unsigned f)
- {
- m_fill1 = f;
- }
-
- unsigned getRightFill() const
- {
- return m_fill1;
- }
-
- /// Set the line style to use for this path
- //
- /// @param f
- /// The line_style index (1-based).
- /// When this path is added to a shape_character_def,
- /// the index (decremented by 1) will reference an element
- /// in the line_style vector defined for that shape.
- /// If zero, no fill will be active.
- ///
- void setLineStyle(unsigned i)
- {
- m_line = i;
- }
-
- unsigned getLineStyle() const
- {
- return m_line;
- }
-
- /// Return the number of edges in this path
- size_t size() const
- {
- return m_edges.size();
- }
-
- /// Return a reference to the Nth edge
- Edge& operator[] (size_t n)
- {
- return m_edges[n];
- }
-
- /// Return a const reference to the Nth edge
- const Edge& operator[] (size_t n) const
- {
- return m_edges[n];
- }
-
- /// Returns true if this path begins a new subshape. <-- VERIFYME
- bool isNewShape() const
- {
- return m_new_shape;
- }
-
- }; // end of class Path
-
-
- typedef Edge edge;
- typedef Path path;
-
-} // end namespace gnash
-
-#endif // GNASH_SHAPE_H
-
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 8
-// tab-width: 8
-// indent-tabs-mode: t
-// End:
=== modified file 'libcore/swf/DefineButtonTag.cpp'
--- a/libcore/swf/DefineButtonTag.cpp 2009-01-22 20:10:39 +0000
+++ b/libcore/swf/DefineButtonTag.cpp 2009-03-10 20:43:50 +0000
@@ -22,7 +22,7 @@
#include "smart_ptr.h" // GNASH_USE_GC
#include "DefineButtonTag.h"
-#include "Button.h" // for create_character_instance()
+#include "Button.h" // for createDisplayObject()
#include "DefineButtonCxformTag.h"
#include "swf.h"
#include "SWFStream.h" // for read()
@@ -419,7 +419,7 @@
character*
-DefineButtonTag::create_character_instance(character* parent, int id)
+DefineButtonTag::createDisplayObject(character* parent, int id)
{
character* ch = new Button(*this, parent, id);
return ch;
=== modified file 'libcore/swf/DefineButtonTag.h'
--- a/libcore/swf/DefineButtonTag.h 2009-01-22 20:10:39 +0000
+++ b/libcore/swf/DefineButtonTag.h 2009-03-10 20:43:50 +0000
@@ -193,14 +193,14 @@
virtual ~DefineButtonTag();
/// Create a mutable instance of our definition.
- character* create_character_instance(character* parent, int id);
+ character* createDisplayObject(character* parent, int id);
const rect& get_bound() const {
// It is required that get_bound() is implemented in character
// definition classes. However, button character definitions do
// not have shape definitions themselves. Instead, they hold a list
// of shape_character_def. get_bound() is currently only used
- // by generic_character which normally is used only shape character
+ // by DisplayObject which normally is used only shape character
// definitions. See character_def.h to learn why it is virtual anyway.
// get_button_bound() is used for buttons.
abort(); // should not be called
=== modified file 'libcore/swf/DefineEditTextTag.cpp'
--- a/libcore/swf/DefineEditTextTag.cpp 2009-01-22 20:10:39 +0000
+++ b/libcore/swf/DefineEditTextTag.cpp 2009-03-10 20:43:50 +0000
@@ -39,7 +39,7 @@
}
character*
-DefineEditTextTag::create_character_instance(character* parent, int id)
+DefineEditTextTag::createDisplayObject(character* parent, int id)
{
// Resolve the font, if possible
getFont();
=== modified file 'libcore/swf/DefineEditTextTag.h'
--- a/libcore/swf/DefineEditTextTag.h 2009-03-05 09:16:32 +0000
+++ b/libcore/swf/DefineEditTextTag.h 2009-03-10 20:43:50 +0000
@@ -67,7 +67,7 @@
const rect& get_bound() const { return _rect; }
- character* create_character_instance(character* parent, int id);
+ character* createDisplayObject(character* parent, int id);
/// Return a reference to the default text associated
/// with this EditText definition.
=== modified file 'libcore/swf/DefineFontAlignZonesTag.cpp'
--- a/libcore/swf/DefineFontAlignZonesTag.cpp 2009-01-22 20:10:39 +0000
+++ b/libcore/swf/DefineFontAlignZonesTag.cpp 2009-03-10 20:43:50 +0000
@@ -20,7 +20,6 @@
#include "Font.h"
#include "log.h"
-#include "shape.h"
#include "SWFStream.h"
#include "movie_definition.h"
#include "DefineFontAlignZonesTag.h"
=== modified file 'libcore/swf/DefineTextTag.cpp'
--- a/libcore/swf/DefineTextTag.cpp 2009-03-09 14:59:05 +0000
+++ b/libcore/swf/DefineTextTag.cpp 2009-03-11 09:39:20 +0000
@@ -13,6 +13,10 @@
#include "swf.h"
#include "TextRecord.h"
#include "Font.h"
+#include "StaticText.h"
+
+#include <algorithm>
+#include <numeric>
namespace gnash {
namespace SWF {
@@ -43,14 +47,27 @@
};
+character*
+DefineTextTag::createDisplayObject(character* parent, int id)
+{
+ return new StaticText(this, parent, id);
+}
+
+
bool
-DefineTextTag::extractStaticText(std::vector<const TextRecord*>& to)
+DefineTextTag::extractStaticText(std::vector<const TextRecord*>& to,
+ size_t& numChars)
{
if (_textRecords.empty()) return false;
+ /// Insert pointers to all our TextRecords into to.
std::transform(_textRecords.begin(), _textRecords.end(),
std::back_inserter(to), CreatePointer<TextRecord>());
+ /// Count the number of characters in this definition's text records.
+ numChars = std::accumulate(_textRecords.begin(), _textRecords.end(),
+ 0, TextRecord::RecordCounter());
+
return true;
}
=== modified file 'libcore/swf/DefineTextTag.h'
--- a/libcore/swf/DefineTextTag.h 2009-03-09 14:22:03 +0000
+++ b/libcore/swf/DefineTextTag.h 2009-03-11 09:39:20 +0000
@@ -58,7 +58,14 @@
}
/// Extract static text from TextRecords.
- bool extractStaticText(std::vector<const TextRecord*>& to);
+ //
+ /// @param to Will be filled with pointers to TextRecords
+ /// if any are present
+ /// @param size Will contain the number of characters in this
+ /// StaticText definition.
+ bool extractStaticText(std::vector<const TextRecord*>& to, size_t& size);
+
+ virtual character* createDisplayObject(character* parent, int id);
private:
=== modified file 'libcore/swf/DefineVideoStreamTag.cpp'
--- a/libcore/swf/DefineVideoStreamTag.cpp 2009-01-22 20:10:39 +0000
+++ b/libcore/swf/DefineVideoStreamTag.cpp 2009-03-10 20:43:50 +0000
@@ -133,7 +133,7 @@
}
character*
-DefineVideoStreamTag::create_character_instance(character* parent, int id)
+DefineVideoStreamTag::createDisplayObject(character* parent, int id)
{
character* ch = new Video(this, parent, id);
return ch;
=== modified file 'libcore/swf/DefineVideoStreamTag.h'
--- a/libcore/swf/DefineVideoStreamTag.h 2009-01-22 20:10:39 +0000
+++ b/libcore/swf/DefineVideoStreamTag.h 2009-03-10 20:43:50 +0000
@@ -83,7 +83,7 @@
~DefineVideoStreamTag();
- character* create_character_instance(character* parent, int id);
+ character* createDisplayObject(character* parent, int id);
/// Read tag SWF::DEFINEVIDEOSTREAM
//
=== modified file 'libcore/swf/TextRecord.cpp'
--- a/libcore/swf/TextRecord.cpp 2009-03-10 08:50:13 +0000
+++ b/libcore/swf/TextRecord.cpp 2009-03-11 10:36:40 +0000
@@ -235,11 +235,7 @@
// Draw the character using the filled outline.
if (glyph)
{
-#ifdef GNASH_DEBUG_TEXT_RENDERING
- log_debug(_("render shape glyph using filled outline
(render::draw_glyph)"));
-#endif
-
- gnash::render::draw_glyph(glyph, mat, textColor);
+ render::draw_glyph(glyph, mat, textColor);
}
}
x += ge.advance;
=== modified file 'libcore/swf/TextRecord.h'
--- a/libcore/swf/TextRecord.h 2009-03-10 08:50:13 +0000
+++ b/libcore/swf/TextRecord.h 2009-03-11 10:36:40 +0000
@@ -62,7 +62,16 @@
{}
typedef std::vector<GlyphEntry> Glyphs;
- Glyphs _glyphs;
+
+ /// Accumulate the number of glyphs in a TextRecord.
+ struct RecordCounter
+ {
+ size_t operator()(size_t c, const TextRecord& t) {
+ const Glyphs& glyphs = t.glyphs();
+ size_t ret = c + glyphs.size();
+ return ret;
+ }
+ };
/// Read a TextRecord from the stream
//
@@ -154,6 +163,8 @@
private:
+ Glyphs _glyphs;
+
/// The text color.
rgba _color;
=== modified file 'libcore/swf/tag_loaders.cpp'
--- a/libcore/swf/tag_loaders.cpp 2009-02-10 11:33:38 +0000
+++ b/libcore/swf/tag_loaders.cpp 2009-03-10 20:43:50 +0000
@@ -30,7 +30,7 @@
#include "fontlib.h"
#include "log.h"
#include "morph2_character_def.h"
-#include "shape.h"
+#include "Geometry.h"
#include "SWFStream.h"
#include "styles.h"
#include "timers.h"
=== modified file 'testsuite/DummyMovieDefinition.h'
--- a/testsuite/DummyMovieDefinition.h 2009-02-25 22:33:03 +0000
+++ b/testsuite/DummyMovieDefinition.h 2009-03-11 06:34:47 +0000
@@ -50,6 +50,8 @@
public:
+ virtual character* createDisplayObject(character*, int id) { return 0; }
+
/// Default constructor
//
=== modified file 'testsuite/libcore.all/EdgeTest.cpp'
--- a/testsuite/libcore.all/EdgeTest.cpp 2009-02-25 22:33:03 +0000
+++ b/testsuite/libcore.all/EdgeTest.cpp 2009-03-10 20:43:50 +0000
@@ -20,7 +20,7 @@
#endif
#include "gnash.h" // for point !!
-#include "shape.h" // for edge
+#include "Geometry.h" // for edge
#include <iostream>
#include <sstream>
#include <cassert>
=== modified file 'testsuite/misc-ming.all/TextSnapshotTest.c'
--- a/testsuite/misc-ming.all/TextSnapshotTest.c 2009-03-10 12:22:29
+0000
+++ b/testsuite/misc-ming.all/TextSnapshotTest.c 2009-03-11 10:16:46
+0000
@@ -184,7 +184,7 @@
// Selected text is stored in the textfield and reset when a new
// snapshot is taken.
add_actions(mo, "ts2 = new TextSnapshot(this);");
- xcheck_equals(mo, "ts.getSelectedText(false)", "''");
+ check_equals(mo, "ts.getSelectedText(false)", "''");
check_equals(mo, "ts2.getCount()", "64");
check_equals(mo, "ts2.getSelectedText()", "''");
add_actions(mo, "ts2 = this.getTextSnapshot();");
@@ -193,12 +193,12 @@
add_actions(mo, "ts2.setSelected(3, 10, true);");
check_equals(mo, "ts2.getSelectedText(false).length", "7");
- xcheck_equals(mo, "ts.getSelectedText(false).length", "7");
+ check_equals(mo, "ts.getSelectedText(false).length", "7");
add_actions(mo, "ts.setSelectedColor(0xffff00);");
add_actions(mo, "ts2.setSelectedColor(0x0000ff);");
- xcheck_equals(mo, "ts.getSelectedText(false)", "'st text'");
+ check_equals(mo, "ts.getSelectedText(false)", "'st text'");
add_actions(mo, "ri = ts.getTextRunInfo(4, 10);");
check_equals(mo, "typeof(ri)", "'object'");
check(mo, "ri instanceof Array");
@@ -238,7 +238,7 @@
check_equals(mo, "ri[3].selected", "true");
check_equals(mo, "ri[4].selected", "true");
check_equals(mo, "ri[5].selected", "true");
- xcheck_equals(mo, "ri[6].selected", "false");
+ check_equals(mo, "ri[6].selected", "false");
check_equals(mo, "ri[2].matrix_tx", "29.75");
check_equals(mo, "ri[2].matrix_ty", "200");
@@ -260,7 +260,7 @@
add_actions(mo, "ts.setSelected(0, 10, true);");
add_actions(mo, "ts.setSelected(15, 20, false);");
- xcheck_equals(mo, "ts2.getSelectedText().length", "10");
+ check_equals(mo, "ts2.getSelectedText().length", "10");
add_actions(mo, "ri2 = ts.getTextRunInfo(0, 100);");
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r10689: Implement TextSnapshot better; all tests of implemented methods pass.,
Benjamin Wolsey <=