[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r10660: Test and partly implement Te
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r10660: Test and partly implement TextSnapshot class. |
Date: |
Thu, 05 Mar 2009 17:24:37 +0100 |
User-agent: |
Bazaar (1.5) |
------------------------------------------------------------
revno: 10660
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Thu 2009-03-05 17:24:37 +0100
message:
Test and partly implement TextSnapshot class.
added:
testsuite/misc-ming.all/TextSnapshotTest.c
modified:
libcore/Font.cpp
libcore/Font.h
libcore/MovieClip.cpp
libcore/asobj/Error_as.cpp
libcore/asobj/TextSnapshot_as.cpp
libcore/asobj/TextSnapshot_as.h
libcore/character.h
libcore/generic_character.cpp
libcore/generic_character.h
libcore/parser/character_def.h
libcore/swf/DefineEditTextTag.h
libcore/swf/DefineTextTag.cpp
libcore/swf/DefineTextTag.h
testsuite/actionscript.all/TextSnapshot.as
testsuite/misc-ming.all/Makefile.am
------------------------------------------------------------
revno: 10659.1.1
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Thu 2009-03-05 09:57:36 +0100
message:
Initial tests for TextSnapshot.
added:
testsuite/misc-ming.all/TextSnapshotTest.c
modified:
testsuite/misc-ming.all/Makefile.am
------------------------------------------------------------
revno: 10659.1.2
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Thu 2009-03-05 10:16:32 +0100
message:
Clean up header.
modified:
libcore/swf/DefineEditTextTag.h
------------------------------------------------------------
revno: 10659.1.3
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Thu 2009-03-05 10:16:53 +0100
message:
Code cleanups.
modified:
libcore/Font.cpp
libcore/Font.h
------------------------------------------------------------
revno: 10659.1.4
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Thu 2009-03-05 11:58:01 +0100
message:
Implement reverse lookup in code table, that is, return the unicode
character
of a given glyph. This is for TextSnapshot, which is certainly implemented
as a special class/method of MovieClip because doing this is inefficient.
modified:
libcore/Font.cpp
libcore/Font.h
------------------------------------------------------------
revno: 10659.1.5
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Thu 2009-03-05 12:00:05 +0100
message:
Add virtual getStaticText() to character class for retrieving a string
from
static text fields.
Add virtual extractStaticText() to character_def for querying definitions
for
static text.
Implement extractStaticText in DefineTextTag. It uses
Font::codeTableLookup().
Add MovieClip::getTextSnapshot() to query the display list for static
text,
which is then added to a string.
modified:
libcore/MovieClip.cpp
libcore/MovieClip.h
libcore/character.h
libcore/generic_character.cpp
libcore/generic_character.h
libcore/parser/character_def.h
libcore/swf/DefineTextTag.cpp
libcore/swf/DefineTextTag.h
------------------------------------------------------------
revno: 10659.1.6
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Thu 2009-03-05 12:14:47 +0100
message:
Check that TextSnapshot can't be constructed with a string arg either.
modified:
testsuite/actionscript.all/TextSnapshot.as
------------------------------------------------------------
revno: 10659.1.7
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Thu 2009-03-05 12:28:26 +0100
message:
Implement TextSnapshot constructor. This isn't ideal, but like many other
classes works for the majority of cases.
modified:
libcore/MovieClip.cpp
libcore/asobj/TextSnapshot_as.cpp
libcore/asobj/TextSnapshot_as.h
testsuite/misc-ming.all/TextSnapshotTest.c
------------------------------------------------------------
revno: 10659.1.8
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Thu 2009-03-05 15:03:05 +0100
message:
More tests for TextSnapshot.
Rework so that a pointer to all static Text character is kept in
TextSnapshot_as. This is necessary for highlighting, which will
require either access to the TextRecords or transform information (or
both).
Implement getText() and getCount() properly.
modified:
libcore/MovieClip.cpp
libcore/MovieClip.h
libcore/asobj/TextSnapshot_as.cpp
libcore/asobj/TextSnapshot_as.h
libcore/character.h
libcore/generic_character.cpp
libcore/generic_character.h
libcore/parser/character_def.h
libcore/swf/DefineTextTag.cpp
libcore/swf/DefineTextTag.h
testsuite/actionscript.all/TextSnapshot.as
testsuite/misc-ming.all/TextSnapshotTest.c
------------------------------------------------------------
revno: 10659.1.9
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Thu 2009-03-05 15:48:15 +0100
message:
Get VM from fn_call.
modified:
libcore/asobj/Error_as.cpp
------------------------------------------------------------
revno: 10659.1.10
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Thu 2009-03-05 15:48:57 +0100
message:
Add tests for overridden TextSnapshot.
modified:
testsuite/misc-ming.all/TextSnapshotTest.c
------------------------------------------------------------
revno: 10659.1.11
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Thu 2009-03-05 16:10:14 +0100
message:
Consolidate and clean up constructor code.
modified:
libcore/MovieClip.cpp
libcore/asobj/TextSnapshot_as.cpp
libcore/asobj/TextSnapshot_as.h
testsuite/misc-ming.all/TextSnapshotTest.c
------------------------------------------------------------
revno: 10659.1.12
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Thu 2009-03-05 16:30:33 +0100
message:
Minor fixes, xcheck->check.
modified:
libcore/asobj/TextSnapshot_as.cpp
libcore/asobj/TextSnapshot_as.h
testsuite/actionscript.all/TextSnapshot.as
testsuite/misc-ming.all/TextSnapshotTest.c
------------------------------------------------------------
revno: 10659.1.13
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Thu 2009-03-05 16:47:09 +0100
message:
Make TextSnapshotTest-Runner run in make check.
modified:
testsuite/misc-ming.all/Makefile.am
=== modified file 'libcore/Font.cpp'
--- a/libcore/Font.cpp 2009-02-09 03:22:05 +0000
+++ b/libcore/Font.cpp 2009-03-05 10:58:01 +0000
@@ -31,6 +31,26 @@
namespace gnash {
+namespace {
+
+/// Reverse lookup of Glyph in CodeTable.
+//
+/// Inefficient, which is probably why TextSnapshot was designed like it
+/// is.
+class CodeLookup
+{
+public:
+ CodeLookup(const int glyph) : _glyph(glyph) {}
+
+ bool operator()(const std::pair<const boost::uint16_t, int>& p) {
+ return p.second == _glyph;
+ }
+
+private:
+ int _glyph;
+};
+
+}
Font::GlyphInfo::GlyphInfo()
:
@@ -171,6 +191,19 @@
_name = name;
}
+
+boost::uint16_t
+Font::codeTableLookup(int glyph, bool embedded) const
+{
+ const CodeTable& ctable = (embedded && _embeddedCodeTable) ?
+ *_embeddedCodeTable : _deviceCodeTable;
+
+ CodeTable::const_iterator it = std::find_if(ctable.begin(), ctable.end(),
+ CodeLookup(glyph));
+ assert (it != ctable.end());
+ return it->first;
+}
+
int
Font::get_glyph_index(boost::uint16_t code, bool embedded) const
{
@@ -185,7 +218,7 @@
return glyph_index;
}
- // Try adding an os font, of possible
+ // Try adding an os font, if possible
if ( ! embedded )
{
glyph_index = const_cast<Font*>(this)->add_os_glyph(code);
=== modified file 'libcore/Font.h'
--- a/libcore/Font.h 2009-02-09 03:22:05 +0000
+++ b/libcore/Font.h 2009-03-05 10:58:01 +0000
@@ -51,30 +51,22 @@
public:
boost::uint16_t m_char0, m_char1;
- bool operator==(const kerning_pair& k) const
+ bool operator==(const kerning_pair& k) const
{
return m_char0 == k.m_char0 && m_char1 == k.m_char1;
}
-
-
};
// for use in standard algorithms
-inline bool operator< (const kerning_pair& p1, const kerning_pair& p2)
+inline bool
+operator< (const kerning_pair& p1, const kerning_pair& p2)
{
- if ( p1.m_char0 < p2.m_char0 )
- {
- return true;
- }
- else if ( p1.m_char0 == p2.m_char0 )
- {
- if ( p1.m_char1 < p2.m_char1 ) return true;
- else return false;
- }
- else
- {
- return false;
- }
+ if (p1.m_char0 < p2.m_char0) return true;
+ if (p1.m_char0 == p2.m_char0) {
+ if (p1.m_char1 < p2.m_char1) return true;
+ }
+
+ return false;
}
/// \brief
@@ -106,6 +98,8 @@
~Font();
+ boost::uint16_t codeTableLookup(int glyph, bool embedded) const;
+
/// Return true if this font matches given name and flags
//
/// @param name
@@ -137,7 +131,7 @@
/// (would be a programming error most likely)
///
///
- shape_character_def* get_glyph(int glyph_index, bool embedded) const;
+ shape_character_def* get_glyph(int glyph_index, bool embedded) const;
/// Get name of this font.
const std::string& get_name() const { return _name; }
=== modified file 'libcore/MovieClip.cpp'
--- a/libcore/MovieClip.cpp 2009-03-03 16:26:50 +0000
+++ b/libcore/MovieClip.cpp 2009-03-05 16:24:37 +0000
@@ -58,7 +58,6 @@
#include "flash/geom/Matrix_as.h"
#include "ExportableResource.h"
-
#ifdef USE_SWFTREE
# include "tree.hh"
#endif
@@ -201,23 +200,256 @@
};
+/// Search the DisplayList for static text.
+class StaticTextFinder
+{
+public:
+ StaticTextFinder(std::string& to) : _to(to) {}
+
+ void operator()(character* ch) {
+ ch->getStaticText(_to);
+ }
+
+private:
+ std::string& _to;
+};
+
+/// Find a character hit by the given coordinates.
+//
+/// This class takes care about taking masks layers into
+/// account, but nested masks aren't properly tested yet.
+///
+class MouseEntityFinder
+{
+public:
+
+ /// @param wp
+ /// Query point in world coordinate space
+ ///
+ /// @param pp
+ /// Query point in parent coordinate space
+ ///
+MouseEntityFinder(point wp, point pp)
+ :
+ _highestHiddenDepth(std::numeric_limits<int>::min()),
+ _m(NULL),
+ _candidates(),
+ _wp(wp),
+ _pp(pp),
+ _checked(false)
+ {}
+
+ void operator() (character* ch)
+ {
+ assert(!_checked);
+ if ( ch->get_depth() <= _highestHiddenDepth )
+ {
+ if ( ch->isMaskLayer() )
+ {
+ log_debug(_("CHECKME: nested mask in MouseEntityFinder. "
+ "This mask is %s at depth %d outer mask masked "
+ "up to depth %d."),
+ ch->getTarget(), ch->get_depth(),
+ _highestHiddenDepth);
+ // Hiding mask still in effect...
+ }
+ return;
+ }
+
+ if ( ch->isMaskLayer() )
+ {
+ if ( ! ch->pointInShape(_wp.x, _wp.y) )
+ {
+#ifdef DEBUG_MOUSE_ENTITY_FINDING
+ log_debug(_("Character %s at depth %d is a mask not hitting "
+ "the query point %g,%g and masking up to "
+ "depth %d"), ch->getTarget(), ch->get_depth(),
+ _wp.x, _wp.y, ch->get_clip_depth());
+#endif
+ _highestHiddenDepth = ch->get_clip_depth();
+ }
+ else
+ {
+#ifdef DEBUG_MOUSE_ENTITY_FINDING
+ log_debug(_("Character %s at depth %d is a mask hitting the "
+ "query point %g,%g"),
+ ch->getTarget(), ch->get_depth(), _wp.x, _wp.y);
+#endif
+ }
+ return;
+ }
+ if (! ch->isVisible()) return;
+
+ _candidates.push_back(ch);
+ }
+
+ void checkCandidates()
+ {
+ if (_checked) return;
+ for (Candidates::reverse_iterator i=_candidates.rbegin(),
+ e=_candidates.rend(); i!=e; ++i) {
+ character* ch = *i;
+ character* te = ch->get_topmost_mouse_entity(_pp.x, _pp.y);
+ if (te) {
+ _m = te;
+ break;
+ }
+ }
+ _checked = true;
+ }
+
+ character* getEntity()
+ {
+ checkCandidates();
+#ifdef DEBUG_MOUSE_ENTITY_FINDING
+ if ( _m )
+ {
+ log_debug(_("MouseEntityFinder found character %s (depth %d) "
+ "hitting point %g,%g"),
+ _m->getTarget(), _m->get_depth(), _wp.x, _wp.y);
+ }
+#endif // DEBUG_MOUSE_ENTITY_FINDING
+ return _m;
+ }
+
+private:
+
+ /// Highest depth hidden by a mask
+ //
+ /// This will be -1 initially, and set
+ /// the the depth of a mask when the mask
+ /// doesn't contain the query point, while
+ /// scanning a DisplayList bottom-up
+ ///
+ int _highestHiddenDepth;
+
+ character* _m;
+
+ typedef std::vector<character*> Candidates;
+ Candidates _candidates;
+
+ /// Query point in world coordinate space
+ point _wp;
+
+ /// Query point in parent coordinate space
+ point _pp;
+
+ bool _checked;
+
+};
+
+/// Find the first character whose shape contain the point
+//
+/// Point coordinates in world TWIPS
+///
+class ShapeContainerFinder
+{
+public:
+
+ ShapeContainerFinder(boost::int32_t x, boost::int32_t y)
+ :
+ _found(false),
+ _x(x),
+ _y(y)
+ {}
+
+ bool operator() (character* ch) {
+ if (ch->pointInShape(_x, _y)) {
+ _found = true;
+ return false;
+ }
+ return true;
+ }
+
+ bool hitFound() { return _found; }
+
+private:
+ bool _found;
+ boost::int32_t _x;
+ boost::int32_t _y;
+};
+
+/// Find the first visible character whose shape contain the point
+//
+/// Point coordinates in world TWIPS
+///
+class VisibleShapeContainerFinder
+{
+public:
+
+ VisibleShapeContainerFinder(boost::int32_t x, boost::int32_t y)
+ :
+ _found(false),
+ _x(x),
+ _y(y)
+ {}
+
+ bool operator() (character* ch)
+ {
+ if (ch->pointInVisibleShape(_x, _y)) {
+ _found = true;
+ return false;
+ }
+ return true;
+ }
+
+ bool hitFound() { return _found; }
+
+private:
+ bool _found;
+ boost::int32_t _x;
+ boost::int32_t _y;
+};
+
+/// Find the first hitable character whose shape contain the point
+//
+/// Point coordinates in world TWIPS
+///
+class HitableShapeContainerFinder
+{
+public:
+ HitableShapeContainerFinder(boost::int32_t x, boost::int32_t y)
+ :
+ _found(false),
+ _x(x),
+ _y(y)
+ {}
+
+ bool operator() (character* ch)
+ {
+ if (ch->isDynamicMask()) return true;
+ if (ch->pointInShape(_x, _y)) {
+ _found = true;
+ return false;
+ }
+ return true;
+ }
+
+ bool hitFound() { return _found; }
+
+private:
+ bool _found;
+ boost::int32_t _x; // TWIPS
+ boost::int32_t _y; // TWIPS
+};
+
/// A DisplayList visitor used to compute its overall bounds.
//
-class BoundsFinder {
+class BoundsFinder
+{
public:
- rect& _bounds;
- BoundsFinder(rect& b)
- :
- _bounds(b)
- {}
- void operator() (character* ch)
- {
+ BoundsFinder(rect& b) : _bounds(b) {}
+
+ void operator() (character* ch) {
// don't include bounds of unloaded characters
if ( ch->isUnloaded() ) return;
rect chb = ch->getBounds();
SWFMatrix m = ch->getMatrix();
_bounds.expand_to_transformed_rect(m, chb);
}
+
+private:
+ rect& _bounds;
};
/// A DisplayList visitor used to extract script characters
@@ -225,9 +457,8 @@
/// Script characters are characters created or transformed
/// by ActionScript.
///
-class ScriptObjectsFinder {
- std::vector<character*>& _dynamicChars;
- std::vector<character*>& _staticChars;
+class ScriptObjectsFinder
+{
public:
ScriptObjectsFinder(std::vector<character*>& dynamicChars,
std::vector<character*>& staticChars)
@@ -236,8 +467,7 @@
_staticChars(staticChars)
{}
- void operator() (character* ch)
- {
+ void operator() (character* ch) {
// don't include bounds of unloaded characters
if ( ch->isUnloaded() ) return;
@@ -246,15 +476,15 @@
//if ( ! ch->get_accept_anim_moves() )
//if ( ch->isDynamic() )
int depth = ch->get_depth();
- if ( depth < character::lowerAccessibleBound || depth >= 0 )
- {
+ if (depth < character::lowerAccessibleBound || depth >= 0) {
_dynamicChars.push_back(ch);
}
- else
- {
- _staticChars.push_back(ch);
- }
+ else _staticChars.push_back(ch);
}
+
+private:
+ std::vector<character*>& _dynamicChars;
+ std::vector<character*>& _staticChars;
};
} // anonymous namespace
@@ -1483,236 +1713,6 @@
return can_handle_mouse_event();
}
-/// Find a character hit by the given coordinates.
-//
-/// This class takes care about taking masks layers into
-/// account, but nested masks aren't properly tested yet.
-///
-class MouseEntityFinder {
-
- /// Highest depth hidden by a mask
- //
- /// This will be -1 initially, and set
- /// the the depth of a mask when the mask
- /// doesn't contain the query point, while
- /// scanning a DisplayList bottom-up
- ///
- int _highestHiddenDepth;
-
- character* _m;
-
- typedef std::vector<character*> Candidates;
- Candidates _candidates;
-
- /// Query point in world coordinate space
- point _wp;
-
- /// Query point in parent coordinate space
- point _pp;
-
- bool _checked;
-
-public:
-
- /// @param wp
- /// Query point in world coordinate space
- ///
- /// @param pp
- /// Query point in parent coordinate space
- ///
- MouseEntityFinder(point wp, point pp)
- :
- _highestHiddenDepth(std::numeric_limits<int>::min()),
- _m(NULL),
- _candidates(),
- _wp(wp),
- _pp(pp),
- _checked(false)
- {}
-
- void operator() (character* ch)
- {
- assert(!_checked);
- if ( ch->get_depth() <= _highestHiddenDepth )
- {
- if ( ch->isMaskLayer() )
- {
- log_debug(_("CHECKME: nested mask in MouseEntityFinder. "
- "This mask is %s at depth %d outer mask masked "
- "up to depth %d."),
- ch->getTarget(), ch->get_depth(),
- _highestHiddenDepth);
- // Hiding mask still in effect...
- }
- return;
- }
-
- if ( ch->isMaskLayer() )
- {
- if ( ! ch->pointInShape(_wp.x, _wp.y) )
- {
-#ifdef DEBUG_MOUSE_ENTITY_FINDING
- log_debug(_("Character %s at depth %d is a mask not hitting "
- "the query point %g,%g and masking up to "
- "depth %d"), ch->getTarget(), ch->get_depth(),
- _wp.x, _wp.y, ch->get_clip_depth());
-#endif
- _highestHiddenDepth = ch->get_clip_depth();
- }
- else
- {
-#ifdef DEBUG_MOUSE_ENTITY_FINDING
- log_debug(_("Character %s at depth %d is a mask hitting the "
- "query point %g,%g"),
- ch->getTarget(), ch->get_depth(), _wp.x, _wp.y);
-#endif
- }
-
- return;
- }
-
- if ( ! ch->isVisible() ) return;
-
- _candidates.push_back(ch);
-
- }
-
- void checkCandidates()
- {
- if ( _checked ) return;
- for (Candidates::reverse_iterator i=_candidates.rbegin(),
- e=_candidates.rend(); i!=e; ++i)
- {
- character* ch = *i;
- character* te = ch->get_topmost_mouse_entity(_pp.x, _pp.y);
- if ( te )
- {
- _m = te;
- break;
- }
- }
- _checked = true;
- }
-
- character* getEntity()
- {
- checkCandidates();
-#ifdef DEBUG_MOUSE_ENTITY_FINDING
- if ( _m )
- {
- log_debug(_("MouseEntityFinder found character %s (depth %d) "
- "hitting point %g,%g"),
- _m->getTarget(), _m->get_depth(), _wp.x, _wp.y);
- }
-#endif // DEBUG_MOUSE_ENTITY_FINDING
- return _m;
- }
-
-};
-
-/// Find the first character whose shape contain the point
-//
-/// Point coordinates in world TWIPS
-///
-class ShapeContainerFinder {
-
- bool _found;
- boost::int32_t _x;
- boost::int32_t _y;
-
-public:
-
- ShapeContainerFinder(boost::int32_t x, boost::int32_t y)
- :
- _found(false),
- _x(x),
- _y(y)
- { }
-
- bool operator() (character* ch)
- {
- if ( ch->pointInShape(_x, _y) )
- {
- _found = true;
- return false;
- }
- else return true;
- }
-
- bool hitFound() { return _found; }
-
-};
-
-/// Find the first visible character whose shape contain the point
-//
-/// Point coordinates in world TWIPS
-///
-class VisibleShapeContainerFinder {
-
- bool _found;
- boost::int32_t _x;
- boost::int32_t _y;
-
-public:
-
- VisibleShapeContainerFinder(boost::int32_t x, boost::int32_t y)
- :
- _found(false),
- _x(x),
- _y(y)
- {}
-
- bool operator() (character* ch)
- {
- if ( ch->pointInVisibleShape(_x, _y) )
- {
- _found = true;
- return false;
- }
- else return true;
- }
-
- bool hitFound() { return _found; }
-
-};
-
-/// Find the first hitable character whose shape contain the point
-//
-/// Point coordinates in world TWIPS
-///
-class HitableShapeContainerFinder {
- bool _found;
- boost::int32_t _x; // TWIPS
- boost::int32_t _y; // TWIPS
-
-public:
- HitableShapeContainerFinder(boost::int32_t x, boost::int32_t y)
- :
- _found(false),
- _x(x),
- _y(y)
- {}
-
- bool operator() (character* ch)
- {
- if( ch->isDynamicMask() )
- {
- return true;
- }
- else if ( ch->pointInShape(_x, _y) )
- {
- _found = true;
- return false;
- }
- else
- {
- return true;
- }
- }
-
- bool hitFound() { return _found; }
-};
-
bool
MovieClip::pointInShape(boost::int32_t x, boost::int32_t y) const
{
@@ -4059,11 +4059,29 @@
as_value
movieclip_getTextSnapshot(const fn_call& fn)
{
- boost::intrusive_ptr<MovieClip> movieclip =
- ensureType<MovieClip>(fn.this_ptr);
-
- LOG_ONCE( log_unimpl("MovieClip.getTextSnapshot()") );
- return as_value();
+ boost::intrusive_ptr<MovieClip> obj = ensureType<MovieClip>(fn.this_ptr);
+
+ // If not found, construction fails.
+ as_value textSnapshot(fn.env().find_object("TextSnapshot"));
+
+ boost::intrusive_ptr<as_function> tsCtor = textSnapshot.to_as_function();
+
+ if (!tsCtor) {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror("MovieClip.getTextSnapshot: failed to construct "
+ "TextSnapshot (object probably overridden)");
+ );
+ return as_value();
+ }
+
+ // Construct a flash.geom.Transform object with "this" as argument.
+ std::auto_ptr<std::vector<as_value> > args(new std::vector<as_value>);
+ args->push_back(obj.get());
+
+ boost::intrusive_ptr<as_object> ts =
+ tsCtor->constructInstance(fn.env(), args);
+
+ return as_value(ts.get());
}
=== modified file 'libcore/asobj/Error_as.cpp'
--- a/libcore/asobj/Error_as.cpp 2009-01-22 20:10:39 +0000
+++ b/libcore/asobj/Error_as.cpp 2009-03-05 14:48:15 +0000
@@ -121,7 +121,7 @@
boost::intrusive_ptr<Error_as> err = new Error_as;
- string_table& st = err->getVM().getStringTable();
+ string_table& st = fn.getVM().getStringTable();
if (fn.nargs > 0)
{
err->set_member(st.find("message"), fn.arg(0));
=== modified file 'libcore/asobj/TextSnapshot_as.cpp'
--- a/libcore/asobj/TextSnapshot_as.cpp 2009-03-04 18:28:12 +0000
+++ b/libcore/asobj/TextSnapshot_as.cpp 2009-03-05 15:30:33 +0000
@@ -28,6 +28,11 @@
#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 "DisplayList.h"
+#include "MovieClip.h"
+
+#include <algorithm>
namespace gnash {
@@ -47,13 +52,87 @@
void attachTextSnapshotInterface(as_object& o);
as_object* getTextSnapshotInterface();
+
+ void setTextReachable( const TextSnapshot_as::TextFields::value_type& vt);
+
}
-TextSnapshot_as::TextSnapshot_as()
+namespace {
+
+class TextFinder
+{
+public:
+ TextFinder(TextSnapshot_as::TextFields& fields) : _fields(fields) {}
+
+ void operator()(character* ch) {
+ if (ch->isUnloaded()) return;
+ std::string text;
+ generic_character* tf;
+ if ((tf = ch->getStaticText(text))) {
+ _fields.push_back(std::make_pair(tf, text));
+ }
+ }
+
+private:
+ TextSnapshot_as::TextFields& _fields;
+};
+
+} // anonymous namespace
+
+
+TextSnapshot_as::TextSnapshot_as(const MovieClip* mc)
:
- as_object(getTextSnapshotInterface())
-{
-}
+ as_object(getTextSnapshotInterface()),
+ _valid(mc)
+{
+ if (mc) {
+ const DisplayList& dl = mc->getDisplayList();
+
+ TextFinder finder(_textFields);
+ dl.visitAll(finder);
+ }
+}
+
+void
+TextSnapshot_as::markReachableResources() const
+{
+ std::for_each(_textFields.begin(), _textFields.end(), setTextReachable);
+}
+
+void
+TextSnapshot_as::makeString(std::string& to, bool newline) const
+{
+ for (TextFields::const_iterator it = _textFields.begin(),
+ e = _textFields.end(); it != e; ++it)
+ {
+ if (newline && it != _textFields.begin()) to += '\n';
+ to += it->second;
+ }
+}
+
+const std::string
+TextSnapshot_as::getText(boost::int32_t start, boost::int32_t end, bool nl)
+ const
+{
+ std::string snapshot;
+ makeString(snapshot, nl);
+
+ const std::string::size_type len = snapshot.size();
+
+ if (len == 0) return std::string();
+
+ // Start is always moved to between 0 and len - 1.
+ start = std::max(start, 0);
+ start = std::min<std::string::size_type>(len - 1, start);
+
+ // End is always moved to between start and end. We don't really care
+ // about end.
+ end = std::max(start + 1, end);
+
+ return snapshot.substr(start, end - start);
+
+}
+
void
TextSnapshot_as::init(as_object& global)
@@ -66,7 +145,6 @@
cl=new builtin_function(&textsnapshot_ctor,
getTextSnapshotInterface());
}
- // Register _global.TextSnapshot
global.init_member("TextSnapshot", cl.get());
}
@@ -119,10 +197,27 @@
log_unimpl (__FUNCTION__);
return as_value();
}
-as_value textsnapshot_getCount(const fn_call& /*fn*/) {
- log_unimpl (__FUNCTION__);
- return as_value();
+
+as_value
+textsnapshot_getCount(const fn_call& fn)
+{
+ boost::intrusive_ptr<TextSnapshot_as> ts =
+ ensureType<TextSnapshot_as>(fn.this_ptr);
+
+ if (!ts->valid()) return as_value();
+
+ if (fn.nargs)
+ {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror("TextSnapshot.getCount takes no arguments");
+ );
+ return as_value();
+ }
+
+
+ return ts->getCount();
}
+
as_value textsnapshot_getSelected(const fn_call& /*fn*/) {
log_unimpl (__FUNCTION__);
return as_value();
@@ -131,10 +226,33 @@
log_unimpl (__FUNCTION__);
return as_value();
}
-as_value textsnapshot_getText(const fn_call& /*fn*/) {
- log_unimpl (__FUNCTION__);
- return as_value();
+
+as_value
+textsnapshot_getText(const fn_call& fn)
+{
+ boost::intrusive_ptr<TextSnapshot_as> ts =
+ ensureType<TextSnapshot_as>(fn.this_ptr);
+
+ if (!ts->valid()) return as_value();
+
+ if (fn.nargs < 2 || fn.nargs > 3)
+ {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror("TextSnapshot.getText requires exactly 2 arguments");
+ );
+ return as_value();
+ }
+
+ boost::int32_t start = fn.arg(0).to_int();
+ boost::int32_t end = fn.arg(1).to_int();
+
+ const bool newline = (fn.nargs > 2) ? fn.arg(2).to_bool() : false;
+
+ return ts->getText(start, end, newline);
+
}
+
+
as_value textsnapshot_hitTestTextNearPos(const fn_call& /*fn*/) {
log_unimpl (__FUNCTION__);
return as_value();
@@ -149,13 +267,17 @@
}
as_value
-textsnapshot_ctor(const fn_call& /* fn */)
-{
- boost::intrusive_ptr<as_object> obj = new TextSnapshot_as;
-
- return as_value(obj.get()); // will keep alive
-}
-
+textsnapshot_ctor(const fn_call& fn)
+{
+ MovieClip* mc = (fn.nargs == 1) ? fn.arg(0).to_sprite() : 0;
+ return as_value(new TextSnapshot_as(mc));
+}
+
+void
+setTextReachable(const TextSnapshot_as::TextFields::value_type& vt)
+{
+ vt.first->setReachable();
+}
} // anonymous namespace
-} // end of gnash namespace
+} // gnash namespace
=== modified file 'libcore/asobj/TextSnapshot_as.h'
--- a/libcore/asobj/TextSnapshot_as.h 2009-03-04 17:52:33 +0000
+++ b/libcore/asobj/TextSnapshot_as.h 2009-03-05 15:30:33 +0000
@@ -23,14 +23,51 @@
namespace gnash {
+class generic_character;
+
class TextSnapshot_as: public as_object
{
public:
- TextSnapshot_as();
+ /// 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*, std::string> >
TextFields;
+
+ TextSnapshot_as(const MovieClip* mc);
+
+ std::string::size_type getCount() {
+ std::string snapshot;
+ makeString(snapshot);
+ return snapshot.size();
+ }
+
+ const std::string getText(boost::int32_t start, boost::int32_t end,
+ bool nl) const;
static void init(as_object& global);
+
+ static void construct(const std::string& snapshot);
+
+ bool valid() const { return _valid; }
+
+protected:
+
+ void markReachableResources() const;
+
+private:
+
+ void makeString(std::string& to, bool newline = false) const;
+
+ TextFields _textFields;
+
+ /// Whether the object is valid, i.e. it was constructed with a MovieClip.
+ //
+ /// This should be deducible from another member, but since there seems
+ /// to be no point in storing the MovieClip this bool will do instead.
+ bool _valid;
+
};
} // end of gnash namespace
=== modified file 'libcore/character.h'
--- a/libcore/character.h 2009-01-26 09:04:28 +0000
+++ b/libcore/character.h 2009-03-05 14:03:05 +0000
@@ -49,6 +49,7 @@
class ExecutableCode;
class action_buffer;
class movie_definition;
+ class generic_character;
}
namespace gnash {
@@ -408,7 +409,15 @@
void add_event_handler(const event_id& id, const action_buffer& code);
/// Render this character
- virtual void display() {}
+ virtual void display() {}
+
+ /// Allow extraction of static text.
+ //
+ /// Default is a no-op, implemented only for DefineText though
+ /// generic_character.
+ virtual generic_character* getStaticText(std::string& /*to*/) {
+ return 0;
+ }
/// Returns local, untransformed height of this character in TWIPS
//
=== modified file 'libcore/generic_character.cpp'
--- a/libcore/generic_character.cpp 2009-01-22 20:10:39 +0000
+++ b/libcore/generic_character.cpp 2009-03-05 14:03:05 +0000
@@ -48,6 +48,13 @@
}
+generic_character*
+generic_character::getStaticText(std::string& to)
+{
+ if (m_def->extractStaticText(to)) return this;
+ return 0;
+}
+
void
generic_character::display()
{
=== modified file 'libcore/generic_character.h'
--- a/libcore/generic_character.h 2009-02-25 22:33:03 +0000
+++ b/libcore/generic_character.h 2009-03-05 14:03:05 +0000
@@ -72,6 +72,8 @@
return false;
}
+ virtual generic_character* getStaticText(std::string& to);
+
virtual void display();
rect getBounds() const
=== modified file 'libcore/parser/character_def.h'
--- a/libcore/parser/character_def.h 2009-02-09 03:22:05 +0000
+++ b/libcore/parser/character_def.h 2009-03-05 14:03:05 +0000
@@ -43,18 +43,14 @@
///
class character_def : public ExportableResource
{
-private:
- int m_id;
-
- // don't assign-to
- character_def& operator= (const character_def&);
public:
- character_def()
+
+ character_def()
:
- m_id(-1),
- m_render_cache(NULL)
- {
- }
+ m_render_cache(0),
+ _id(-1)
+ {
+ }
virtual ~character_def();
@@ -63,7 +59,16 @@
{
}
- /// Return true if the specified point is on the interior of our shape.
+ /// 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::string& /*to*/)
+ {
+ return false;
+ }
+
+ /// Return true if the specified point is on the interior of our shape.
//
/// Point coordinates are local coords (TWIPS)
///
@@ -87,15 +92,13 @@
// Declared as virtual here because generic_character needs access to it
virtual const rect& get_bound() const = 0;
-public:
-
- /// Cache holder for renderer (contents depend on renderer handler)
- /// Will be deleted by destructor of the character_def.
- /// We could store by auto_ptr, but I'm afraid that would mean
- /// including render_handler.h in this header, which I don't like.
- /// (REF: PIMPL)
- ///
- render_cache_manager* m_render_cache;
+ /// Cache holder for renderer (contents depend on renderer handler)
+ /// Will be deleted by destructor of the character_def.
+ /// We could store by auto_ptr, but I'm afraid that would mean
+ /// including render_handler.h in this header, which I don't like.
+ /// (REF: PIMPL)
+ ///
+ render_cache_manager* m_render_cache;
protected:
@@ -124,18 +127,23 @@
character_def(const character_def& o)
:
ExportableResource(),
- m_id(o.m_id),
- m_render_cache(NULL)
+ m_render_cache(0),
+ _id(o._id)
{}
+private:
+
+ int _id;
+
+ // don't assign-to
+ character_def& operator= (const character_def&);
};
} // namespace gnash
-#endif // GNASH_CHARACTER_DEF_H
-
+#endif
// Local Variables:
// mode: C++
=== modified file 'libcore/swf/DefineEditTextTag.h'
--- a/libcore/swf/DefineEditTextTag.h 2009-01-22 20:10:39 +0000
+++ b/libcore/swf/DefineEditTextTag.h 2009-03-05 09:16:32 +0000
@@ -69,14 +69,6 @@
character* create_character_instance(character* parent, int id);
- /// How many of these are necessary?
-
- /// Get width of this definition in twips (by definition)
- //float width() const { return _rect.width(); }
-
- /// Get height of this definition in twips (by definition)
- //float height() const { return _rect.height(); }
-
/// Return a reference to the default text associated
/// with this EditText definition.
const std::string& defaultText() const {
=== modified file 'libcore/swf/DefineTextTag.cpp'
--- a/libcore/swf/DefineTextTag.cpp 2009-01-05 09:32:03 +0000
+++ b/libcore/swf/DefineTextTag.cpp 2009-03-05 14:03:05 +0000
@@ -12,6 +12,7 @@
#include "log.h"
#include "swf.h"
#include "TextRecord.h"
+#include "Font.h"
namespace gnash {
namespace SWF {
@@ -33,6 +34,36 @@
m.add_character(id, t.release());
}
+class DecodeRecord
+{
+public:
+
+ DecodeRecord(std::string& to) : _to(to) {}
+
+ void operator()(const TextRecord& tr) {
+
+ const Font* font = tr.getFont();
+ if (!font) return;
+
+ const TextRecord::Glyphs& glyphs = tr.glyphs();
+
+ for (TextRecord::Glyphs::const_iterator it = glyphs.begin(),
+ e = glyphs.end(); it != e; ++it) {
+ _to += font->codeTableLookup(it->index, true);
+ }
+ }
+private:
+ std::string& _to;
+};
+
+
+bool
+DefineTextTag::extractStaticText(std::string& to)
+{
+ std::for_each(_textRecords.begin(), _textRecords.end(), DecodeRecord(to));
+ return true;
+}
+
void
DefineText2Tag::loader(SWFStream& in, TagType tag, movie_definition& m,
const RunInfo& /*r*/)
=== modified file 'libcore/swf/DefineTextTag.h'
--- a/libcore/swf/DefineTextTag.h 2009-01-22 20:10:39 +0000
+++ b/libcore/swf/DefineTextTag.h 2009-03-05 14:03:05 +0000
@@ -57,6 +57,9 @@
return _rect;
}
+ /// Extract static text from TextRecords.
+ bool extractStaticText(std::string& to);
+
private:
/// DefineText2Tag::loader also constructs a DefineTextTag.
=== modified file 'testsuite/actionscript.all/TextSnapshot.as'
--- a/testsuite/actionscript.all/TextSnapshot.as 2009-03-04 17:52:33
+0000
+++ b/testsuite/actionscript.all/TextSnapshot.as 2009-03-05 15:30:33
+0000
@@ -69,8 +69,29 @@
check_equals (typeof(textsnapshotObj.setSelectColor), 'function');
check_equals (typeof(textsnapshotObj.setSelected), 'function');
+ gh = new TextSnapshot("hello");
+ check_equals(gh.toString(), "[object Object]");
+ check_equals(gh.getCount.toString(), "[type Function]");
+ check_equals(gh.getCount(), undefined);
+
+ o = {};
+ gh = new TextSnapshot(o);
+ check_equals(gh.toString(), "[object Object]");
+ check_equals(gh.getCount.toString(), "[type Function]");
+ check_equals(gh.getCount(), undefined);
+
+ gh = new TextSnapshot(this);
+ check_equals(gh.toString(), "[object Object]");
+ check_equals(gh.getCount.toString(), "[type Function]");
+ check_equals(gh.getCount(), 0);
+
+ gh = new TextSnapshot(this, true);
+ check_equals(gh.toString(), "[object Object]");
+ check_equals(gh.getCount.toString(), "[type Function]");
+ check_equals(gh.getCount(), undefined);
+
ts = _root.getTextSnapshot();
- xcheck(ts instanceof TextSnapshot);
+ check(ts instanceof TextSnapshot);
check(!ts.hasOwnProperty('findText'));
check(!ts.hasOwnProperty('getCount'));
check(!ts.hasOwnProperty('getSelected'));
@@ -82,12 +103,12 @@
// getText() and getCount()
- xcheck_equals(typeof(ts.getCount()), "number");
+ check_equals(typeof(ts.getCount()), "number");
check_equals(typeof(ts.getCount(0)), "undefined");
check_equals(typeof(ts.getCount("a")), "undefined");
check_equals(typeof(ts.getCount(true)), "undefined");
check_equals(typeof(ts.getCount(0, 1)), "undefined");
- xcheck_equals(ts.getCount(), 0);
+ check_equals(ts.getCount(), 0);
check_equals(typeof(ts.findText()), "undefined");
check_equals(typeof(ts.findText("a")), "undefined");
@@ -117,7 +138,7 @@
_root.createTextField("tf", 10, 30, 30, 100, 100);
_root.tf.text = "ghjkab";
ts = _root.getTextSnapshot();
- xcheck_equals(ts.getCount(), 0);
+ check_equals(ts.getCount(), 0);
xcheck_equals(ts.findText(1, "a", true), -1);
xcheck_equals(ts.findText(1, "a", false), -1);
@@ -162,16 +183,16 @@
check_equals(typeof(ts.getText(0)), "undefined");
check_equals(typeof(ts.getText("a")), "undefined");
check_equals(typeof(ts.getText(new Date())), "undefined");
- xcheck_equals(typeof(ts.getText(0, 1)), "string");
- xcheck_equals(typeof(ts.getText(1, 0)), "string");
- xcheck_equals(typeof(ts.getText(-1, 3)), "string");
- xcheck_equals(typeof(ts.getText(1, 0)), "string");
- xcheck_equals(typeof(ts.getText(1, 0)), "string");
- xcheck_equals(typeof(ts.getText(0, "a")), "string");
- xcheck_equals(typeof(ts.getText("b", 0)), "string");
- xcheck_equals(typeof(ts.getText(true, false)), "string");
- xcheck_equals(typeof(ts.getText(0, 10, 10)), "string");
- xcheck_equals(typeof(ts.getText(0, 10, true)), "string");
+ check_equals(typeof(ts.getText(0, 1)), "string");
+ check_equals(typeof(ts.getText(1, 0)), "string");
+ check_equals(typeof(ts.getText(-1, 3)), "string");
+ check_equals(typeof(ts.getText(1, 0)), "string");
+ check_equals(typeof(ts.getText(1, 0)), "string");
+ check_equals(typeof(ts.getText(0, "a")), "string");
+ check_equals(typeof(ts.getText("b", 0)), "string");
+ check_equals(typeof(ts.getText(true, false)), "string");
+ check_equals(typeof(ts.getText(0, 10, 10)), "string");
+ check_equals(typeof(ts.getText(0, 10, true)), "string");
check_equals(typeof(ts.getText(0, 10, "a", 11)), "undefined");
check_equals(typeof(ts.getText(0, 10, 10, "hello")), "undefined");
check_equals(typeof(ts.getText(0, 10, true, [3, 4])), "undefined");
@@ -222,6 +243,6 @@
check_equals(typeof(ts.setSelected(0, 10, 10, "hello")), "undefined");
check_equals(typeof(ts.setSelected(0, 10, true, [3, 4])), "undefined");
- totals(155);
+ totals(167);
#endif // OUTPUT_VERSION > 5
=== modified file 'testsuite/misc-ming.all/Makefile.am'
--- a/testsuite/misc-ming.all/Makefile.am 2009-02-25 22:33:03 +0000
+++ b/testsuite/misc-ming.all/Makefile.am 2009-03-05 15:47:09 +0000
@@ -77,6 +77,7 @@
SpriteButtonEventsTest-Runner \
DefineTextTest \
DefineTextTest-Runner \
+ TextSnapshotTest \
DefineEditTextTest \
DefineEditTextTest-Runner \
DefineEditTextVariableNameTest \
@@ -237,6 +238,7 @@
endif
check_SCRIPTS = \
+ TextSnapshotTest-Runner \
timeline_var_test-Runner \
place_object_testrunner \
place_object_test2runner \
@@ -391,6 +393,16 @@
DefineTextTest.swf \
$(NULL)
+TextSnapshotTest.swf: TextSnapshotTest
+ ./TextSnapshotTest $(top_srcdir)/testsuite/media
+
+TextSnapshotTest_SOURCES = TextSnapshotTest.c
+TextSnapshotTest_LDADD = libgnashmingutils.la
+
+TextSnapshotTest-Runner: $(srcdir)/../generic-testrunner.sh
TextSnapshotTest.swf
+ sh $< $(top_builddir) TextSnapshotTest.swf > $@
+ chmod 755 $@
+
DefineEditTextTest.swf: DefineEditTextTest
./DefineEditTextTest $(top_srcdir)/testsuite/media
@@ -1928,6 +1940,7 @@
loadMovieTestRunner \
eventSoundTest1-Runner \
DrawingApiTestRunner \
+ TextSnapshotTest-Runner \
action_execution_order_test1runner \
action_execution_order_test2runner \
action_execution_order_test3runner \
=== added file 'testsuite/misc-ming.all/TextSnapshotTest.c'
--- a/testsuite/misc-ming.all/TextSnapshotTest.c 1970-01-01 00:00:00
+0000
+++ b/testsuite/misc-ming.all/TextSnapshotTest.c 2009-03-05 15:30:33
+0000
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2005, 2006, 2007, 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
+ *
+ *
+ */
+
+/*
+ * Uses both "embedded" font and device fonts.
+ * The text written is 'Hello world' in both cases.
+ * Text at the bottom is the one with embedded fonts.
+ *
+ * TODO: add a testrunner for pixel checking.
+ * TODO: test autoSize and wordWrap interaction (what takes precedence?)
+ *
+ * run as ./DefineEditTextTest
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ming.h>
+
+#include "ming_utils.h"
+
+#define OUTPUT_VERSION 8
+#define OUTPUT_FILENAME "TextSnapshotTest.swf"
+
+SWFDisplayItem
+add_text_field(SWFMovie mo, SWFFont font, const char* text);
+
+SWFDisplayItem
+add_text_field(SWFMovie mo, SWFFont font, const char* text)
+{
+ SWFText tf;
+
+ tf = newSWFText();
+
+ SWFText_setFont(tf, font);
+
+
+ SWFText_addString(tf, text, NULL);
+
+ return SWFMovie_add(mo, (SWFBlock)tf);
+}
+
+int
+main(int argc, char** argv)
+{
+ SWFMovie mo;
+ const char *srcdir=".";
+ char fdbfont[256];
+ SWFMovieClip dejagnuclip;
+
+ /*********************************************
+ *
+ * Initialization
+ *
+ *********************************************/
+
+ if ( argc>1 ) srcdir=argv[1];
+ else
+ {
+ fprintf(stderr, "Usage: %s <mediadir>\n", argv[0]);
+ return 1;
+ }
+
+ sprintf(fdbfont, "%s/Bitstream-Vera-Sans.fdb", srcdir);
+
+ puts("Setting things up");
+
+ Ming_init();
+ Ming_useSWFVersion (OUTPUT_VERSION);
+ //Ming_setScale(20.0); /* so we talk twips */
+
+ mo = newSWFMovie();
+ SWFMovie_setRate(mo, 1.0);
+ SWFMovie_setDimension(mo, 800, 600);
+
+ dejagnuclip = get_dejagnu_clip((SWFBlock)get_default_font(srcdir), 10, 0, 0,
800, 600);
+ SWFMovie_add(mo, (SWFBlock)dejagnuclip);
+ SWFMovie_nextFrame(mo); // 1st frame
+
+
+ /*********************************************
+ *
+ * Add some textfields
+ *
+ *********************************************/
+ {
+ SWFDisplayItem it;
+ FILE *font_file = fopen(fdbfont, "r");
+ if ( font_file == NULL )
+ {
+ perror(fdbfont);
+ exit(1);
+ }
+ SWFBrowserFont bfont = newSWFBrowserFont("_sans");
+ SWFFont efont = loadSWFFontFromFile(font_file);
+
+ it = add_text_field(mo, efont, "First text");
+ SWFDisplayItem_setName(it, "dtext1");
+ SWFDisplayItem_moveTo(it, 0, 200);
+ it = add_text_field(mo, efont, "Zweites Textfeld");
+ SWFDisplayItem_setName(it, "etext1");
+ SWFDisplayItem_moveTo(it, 0, 300);
+
+ it = add_text_field(mo, efont, "Some more static text here... abcdefgh");
+ SWFDisplayItem_setName(it, "dtext2");
+ SWFDisplayItem_moveTo(it, 0, 400);
+ }
+ SWFMovie_nextFrame(mo);
+
+ add_actions(mo, "createTextField('dynamictext1', 99, 10, 10, 10, 10);"
+ "this.dynamictext1.text = 'Dynamic Text';");
+
+ add_actions(mo, "ts = this.getTextSnapshot();");
+ check(mo, "ts instanceof TextSnapshot");
+ check_equals(mo, "ts.getCount()", "64");
+
+ check_equals(mo, "ts.getText(0, 1)", "'F'");
+ check_equals(mo, "ts.getText(3, 3)", "'s'");
+ check_equals(mo, "ts.getText(-5, 5)", "'First'");
+ check_equals(mo, "ts.getText(10, 6)", "'Z'");
+ check_equals(mo, "ts.getText(0, 100)", "'First textZweites TextfeldSome more
"
+ "static text here... abcdefgh'");
+ add_actions(mo, "ss = ts.getText(100, 110);");
+ check_equals(mo, "typeof(ss)", "'string'");
+ check_equals(mo, "ss", "'h'");
+ check_equals(mo, "ss.length", "1");
+
+ check_equals(mo, "ts.getText(0, 100, true)",
+ "'First text\nZweites Textfeld\nSome more "
+ "static text here... abcdefgh'");
+
+ add_actions(mo, "ts.setSelected(0, 30, true);");
+
+ add_actions(mo, "ts = this.getTextSnapshot();");
+ check_equals(mo, "typeof(ts)", "'object'");
+ add_actions(mo, "backup = TextSnapshot;");
+ add_actions(mo, "TextSnapshot = undefined;");
+ add_actions(mo, "t = new TextSnapshot();");
+ check_equals(mo, "typeof(t)", "'undefined'");
+
+ check_equals(mo, "typeof(TextSnapshot)", "'undefined'");
+ add_actions(mo, "ts = this.getTextSnapshot();");
+ xcheck_equals(mo, "typeof(ts)", "'undefined'");
+ add_actions(mo, "TextSnapshot = backup;");
+ add_actions(mo, "ts = this.getTextSnapshot();");
+ check_equals(mo, "typeof(ts)", "'object'");
+
+ add_actions(mo, "backup = TextSnapshot.prototype;");
+ add_actions(mo, "TextSnapshot.prototype = undefined;");
+ add_actions(mo, "ts = this.getTextSnapshot();");
+ check_equals(mo, "typeof(ts)", "'object'");
+ add_actions(mo, "TextSnapshot.prototype = backup;");
+ add_actions(mo, "ts = this.getTextSnapshot();");
+ check_equals(mo, "typeof(ts)", "'object'");
+
+
+ add_actions(mo, "totals(); stop();");
+
+
+
+
+ SWFMovie_nextFrame(mo);
+
+ /*****************************************************
+ *
+ * Output movie
+ *
+ *****************************************************/
+ puts("Saving " OUTPUT_FILENAME );
+
+ SWFMovie_save(mo, OUTPUT_FILENAME);
+
+ return 0;
+}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r10660: Test and partly implement TextSnapshot class.,
Benjamin Wolsey <=