[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r10779: Major reorganization of the
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r10779: Major reorganization of the messy half of Gnash to match the neater half |
Date: |
Tue, 07 Apr 2009 18:32:11 +0200 |
User-agent: |
Bazaar (1.5) |
------------------------------------------------------------
revno: 10779
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Tue 2009-04-07 18:32:11 +0200
message:
Major reorganization of the messy half of Gnash to match the neater half
and implement the suppposed design consistently. Add a proper DisplayObject
for MorphShape. The main changes are:
- Rename character_def to DefinitionTag.
- Rename shape_character_def to DefineShapeTag.
- Move almost all parsing under the swf directory.
- Make DefinitionTags really immutable and non-copyable.
- Only faked definition tag now in MovieClip (though BitmapMovieDefinition
also comes close).
- Use the presence of a DefinitionTag to distinguish SWF-defined from
dynamic DisplayObjects (except in MovieClip).
- Make DynamicShape and ShapeRecord normal, non-refcounted or GC classes
for stack allocation and smart-pointer usage.
- Much more const correctness.
- More logical design with proper class documentation.
- Smaller and more consistent renderer interface for shape drawing.
- GC resources reduced for all glyphs, morph definitions, dynamic shapes,
BitmapMovies.
removed:
libcore/Sprite.h
libcore/parser/character_def.cpp
added:
libcore/Geometry.cpp
libcore/MorphShape.cpp
libcore/MorphShape.h
libcore/swf/ShapeRecord.cpp
libcore/swf/ShapeRecord.h
renamed:
libcore/parser/character_def.h => libcore/swf/DefinitionTag.h
libcore/parser/morph2_character_def.cpp => libcore/swf/DefineMorphShapeTag.cpp
libcore/parser/morph2_character_def.h => libcore/swf/DefineMorphShapeTag.h
libcore/parser/shape_character_def.cpp => libcore/swf/DefineShapeTag.cpp
libcore/parser/shape_character_def.h => libcore/swf/DefineShapeTag.h
modified:
backend/Makefile.am
backend/PathParser.cpp
backend/PathParser.h
backend/render_handler.h
backend/render_handler_agg.cpp
backend/render_handler_cairo.cpp
backend/render_handler_ogl.cpp
backend/render_handler_ogl.h
cygnal/Makefile.am
gui/Makefile.am
libcore/Bitmap.cpp
libcore/Bitmap.h
libcore/BitmapMovieInstance.cpp
libcore/Button.cpp
libcore/DisplayObject.h
libcore/DynamicShape.cpp
libcore/DynamicShape.h
libcore/ExportableResource.h
libcore/Font.cpp
libcore/Font.h
libcore/FreetypeGlyphsProvider.cpp
libcore/FreetypeGlyphsProvider.h
libcore/Geometry.h
libcore/InteractiveObject.h
libcore/Makefile.am
libcore/MouseButtonState.h
libcore/MovieClip.cpp
libcore/MovieClip.h
libcore/Shape.cpp
libcore/Shape.h
libcore/StaticText.cpp
libcore/StaticText.h
libcore/TextField.cpp
libcore/Video.cpp
libcore/as_environment.cpp
libcore/fill_style.h
libcore/fontlib.cpp
libcore/impl.cpp
libcore/movie_root.cpp
libcore/parser/BitmapMovieDefinition.cpp
libcore/parser/BitmapMovieDefinition.h
libcore/parser/Makefile.am
libcore/parser/SWFMovieDefinition.cpp
libcore/parser/SWFMovieDefinition.h
libcore/parser/movie_definition.h
libcore/parser/sprite_definition.cpp
libcore/parser/sprite_definition.h
libcore/render.cpp
libcore/render.h
libcore/swf/DefineButtonCxformTag.cpp
libcore/swf/DefineButtonSoundTag.cpp
libcore/swf/DefineButtonTag.cpp
libcore/swf/DefineButtonTag.h
libcore/swf/DefineEditTextTag.h
libcore/swf/DefineFontTag.cpp
libcore/swf/DefineTextTag.cpp
libcore/swf/DefineTextTag.h
libcore/swf/DefineVideoStreamTag.h
libcore/swf/TextRecord.cpp
libcore/swf/TextRecord.h
libcore/swf/VideoFrameTag.cpp
libcore/swf/VideoFrameTag.h
libcore/swf/tag_loaders.cpp
libcore/swf/tag_loaders.h
testsuite/Makefile.am
testsuite/libcore.all/ClassSizes.cpp
testsuite/libcore.all/EdgeTest.cpp
testsuite/libcore.all/Makefile.am
testsuite/misc-ming.all/Makefile.am
testsuite/misc-swfc.all/Makefile.am
testsuite/misc-swfmill.all/Makefile.am
testsuite/movies.all/Makefile.am
testsuite/samples/Makefile.am
utilities/Makefile.am
libcore/swf/DefinitionTag.h
libcore/swf/DefineMorphShapeTag.cpp
libcore/swf/DefineMorphShapeTag.h
libcore/swf/DefineShapeTag.cpp
libcore/swf/DefineShapeTag.h
------------------------------------------------------------
revno: 10771.1.1
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Sun 2009-04-05 13:11:30 +0200
message:
Alter header guards.
modified:
libcore/DisplayObject.h
libcore/StaticText.h
------------------------------------------------------------
revno: 10771.1.2
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Sun 2009-04-05 13:28:44 +0200
message:
Minor cleanup.
modified:
libcore/parser/movie_definition.h
------------------------------------------------------------
revno: 10771.1.3
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Sun 2009-04-05 13:45:17 +0200
message:
Drop Sprite.h, as its information was either wrong or not very useful.
removed:
libcore/Sprite.h
modified:
libcore/Makefile.am
------------------------------------------------------------
revno: 10771.1.4
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Mon 2009-04-06 10:16:33 +0200
message:
Add MorphShape class. This is mainly for AVM2, but also helps separate
parsing and execution for AVM1 by storing mutable state information in
a DisplayObject, not a character definition.
added:
libcore/MorphShape.cpp
libcore/MorphShape.h
modified:
backend/render_handler.h
backend/render_handler_agg.cpp
libcore/Makefile.am
libcore/MovieClip.cpp
libcore/fill_style.h
libcore/movie_root.cpp
libcore/parser/character_def.h
libcore/parser/morph2_character_def.cpp
libcore/parser/morph2_character_def.h
libcore/parser/shape_character_def.cpp
libcore/parser/shape_character_def.h
libcore/swf/tag_loaders.cpp
------------------------------------------------------------
revno: 10771.1.5
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Mon 2009-04-06 10:56:17 +0200
message:
Restrict renderer interface to drawShape and drawMorph, each taking a
definition and a DisplayObject. This is much neater and more consistent.
modified:
backend/render_handler.h
backend/render_handler_agg.cpp
libcore/Bitmap.cpp
libcore/Shape.cpp
libcore/parser/morph2_character_def.cpp
libcore/parser/shape_character_def.cpp
libcore/parser/shape_character_def.h
libcore/render.cpp
libcore/render.h
------------------------------------------------------------
revno: 10771.1.6
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Mon 2009-04-06 12:18:59 +0200
message:
Move non-class-specific hit and crossing tests to Geometry.h. Drop
duplicated functions. Remove class typedef and use the actual name
everywhere. Indentation.
modified:
backend/render_handler_agg.cpp
libcore/Bitmap.cpp
libcore/DynamicShape.cpp
libcore/DynamicShape.h
libcore/Geometry.h
libcore/Makefile.am
libcore/MorphShape.cpp
libcore/MorphShape.h
libcore/Shape.cpp
libcore/parser/BitmapMovieDefinition.cpp
libcore/parser/shape_character_def.cpp
libcore/parser/shape_character_def.h
------------------------------------------------------------
revno: 10771.1.7
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Mon 2009-04-06 12:24:21 +0200
message:
Add Geometry.cpp.
added:
libcore/Geometry.cpp
------------------------------------------------------------
revno: 10771.1.8
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Mon 2009-04-06 13:16:20 +0200
message:
Register MorphShape as a live char so that advance is called.
modified:
libcore/MorphShape.cpp
libcore/MorphShape.h
libcore/MovieClip.cpp
libcore/Video.cpp
libcore/parser/sprite_definition.cpp
------------------------------------------------------------
revno: 10771.1.9
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Mon 2009-04-06 13:31:51 +0200
message:
Fix EdgeTest by using correct class name.
modified:
testsuite/libcore.all/EdgeTest.cpp
------------------------------------------------------------
revno: 10771.1.10
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Mon 2009-04-06 15:27:04 +0200
message:
Re-add pointTestLocal to shape_character_def, as DynamicShape has to
override
it. Remove from base class character_def as it only make sense for
shape-like
characters. It also reveals StaticText had been using the default
implementation. MorphShape uses geometry::pointTest directly.
Initialize MorphShape members to match shape1 on construction instead of
the messy way it was done before.
modified:
libcore/DynamicShape.h
libcore/Geometry.cpp
libcore/Geometry.h
libcore/MorphShape.cpp
libcore/Shape.cpp
libcore/StaticText.cpp
libcore/parser/character_def.h
libcore/parser/morph2_character_def.cpp
libcore/parser/shape_character_def.cpp
libcore/parser/shape_character_def.h
------------------------------------------------------------
revno: 10771.1.11
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Mon 2009-04-06 17:32:26 +0200
message:
There are two ways of morphing: either a PlaceObject tag with a move flag,
or remove and re-add the morph shape with a different ratio. Call morph()
in the stagePlacementCallback if ratio is not 0 to handle the second
(less efficient) case.
modified:
libcore/MorphShape.cpp
libcore/MorphShape.h
------------------------------------------------------------
revno: 10771.1.12
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Mon 2009-04-06 18:21:49 +0200
message:
Merge from trunk.
Drop advance() code, as it messes up the morph timing in relation to
MovieClip's advance. MorphShape isn't a LiveChar anymore; morphing is
done on display() again.
modified:
libcore/MorphShape.cpp
libcore/MorphShape.h
pythonmodule/gnashPythonExample.py
pythonmodule/gnashpython.cpp
pythonmodule/gnashpython.h
pythonmodule/pyGnash.cpp
------------------------------------------------------------
revno: 10771.1.13
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Mon 2009-04-06 19:08:48 +0200
message:
Indentation, minor correction.
modified:
libcore/parser/shape_character_def.cpp
------------------------------------------------------------
revno: 10771.1.14
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Mon 2009-04-06 20:29:44 +0200
message:
Construct morph definition directly from SWFStream.
modified:
libcore/parser/morph2_character_def.cpp
libcore/parser/morph2_character_def.h
libcore/swf/tag_loaders.cpp
------------------------------------------------------------
revno: 10771.1.15
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Mon 2009-04-06 21:22:40 +0200
message:
Add ShapeRecord, a neutral container for shape information.
added:
libcore/swf/ShapeRecord.cpp
libcore/swf/ShapeRecord.h
modified:
libcore/Makefile.am
------------------------------------------------------------
revno: 10771.1.16
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Mon 2009-04-06 22:29:42 +0200
message:
Use ShapeRecord in morph shapes.
modified:
backend/Makefile.am
cygnal/Makefile.am
gui/Makefile.am
libcore/MorphShape.cpp
libcore/parser/morph2_character_def.cpp
libcore/parser/morph2_character_def.h
libcore/parser/shape_character_def.cpp
libcore/parser/shape_character_def.h
libcore/swf/ShapeRecord.cpp
libcore/swf/ShapeRecord.h
utilities/Makefile.am
------------------------------------------------------------
revno: 10771.1.17
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 07:03:54 +0200
message:
Const correctness. The morph class no longer needs shape_character_def.
Fix invalidated bounds of morph for display. Needs testing for AS bounds
in AVM2.
modified:
libcore/MorphShape.cpp
libcore/MorphShape.h
libcore/parser/morph2_character_def.cpp
libcore/parser/morph2_character_def.h
libcore/parser/shape_character_def.h
------------------------------------------------------------
revno: 10771.1.18
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 08:52:54 +0200
message:
Move morph parsing under swf directory.
renamed:
libcore/parser/morph2_character_def.cpp =>
libcore/swf/DefineMorphShapeTag.cpp
libcore/parser/morph2_character_def.h => libcore/swf/DefineMorphShapeTag.h
modified:
backend/render_handler.h
backend/render_handler_agg.cpp
libcore/Makefile.am
libcore/MorphShape.cpp
libcore/MorphShape.h
libcore/impl.cpp
libcore/parser/Makefile.am
libcore/parser/character_def.h
libcore/render.cpp
libcore/render.h
libcore/swf/ShapeRecord.h
libcore/swf/tag_loaders.cpp
libcore/swf/tag_loaders.h
libcore/swf/DefineMorphShapeTag.cpp
libcore/swf/DefineMorphShapeTag.h
------------------------------------------------------------
revno: 10771.1.19
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 09:18:30 +0200
message:
Start separating DynamicShape and shape_character_def. No display after
this commit.
modified:
libcore/DynamicShape.cpp
libcore/DynamicShape.h
libcore/swf/ShapeRecord.h
------------------------------------------------------------
revno: 10771.1.20
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 11:19:54 +0200
message:
Separate DynamicShape completely from shape_character_def.
DynamicShape is not refcounted, so management is always up to the users
(not yet implemented properly).
DynamicShape is used for Fonts (glyphs), Bitmaps, BitmapMovies and the
movie_root drawable.
All character_defs should now be immutable and noncopyable.
modified:
backend/render_handler.h
backend/render_handler_agg.cpp
libcore/Bitmap.cpp
libcore/Bitmap.h
libcore/BitmapMovieInstance.cpp
libcore/DynamicShape.cpp
libcore/DynamicShape.h
libcore/Font.cpp
libcore/Font.h
libcore/FreetypeGlyphsProvider.cpp
libcore/FreetypeGlyphsProvider.h
libcore/Geometry.cpp
libcore/MovieClip.cpp
libcore/MovieClip.h
libcore/Shape.cpp
libcore/Shape.h
libcore/parser/BitmapMovieDefinition.cpp
libcore/parser/BitmapMovieDefinition.h
libcore/parser/character_def.h
libcore/parser/shape_character_def.cpp
libcore/parser/shape_character_def.h
libcore/render.cpp
libcore/render.h
libcore/swf/DefineFontTag.cpp
libcore/swf/TextRecord.cpp
libcore/swf/tag_loaders.cpp
testsuite/Makefile.am
testsuite/misc-ming.all/Makefile.am
------------------------------------------------------------
revno: 10771.1.21
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 11:49:53 +0200
message:
Drop most of shape_character_def interface now it's not used.
modified:
libcore/Shape.cpp
libcore/as_environment.cpp
libcore/parser/shape_character_def.cpp
libcore/parser/shape_character_def.h
libcore/swf/DefineMorphShapeTag.cpp
libcore/swf/ShapeRecord.cpp
testsuite/movies.all/Makefile.am
testsuite/samples/Makefile.am
------------------------------------------------------------
revno: 10771.1.22
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 13:14:10 +0200
message:
Add documentation for various classes. Const correct definitions and
member functions. Add libcore/swf to testsuite Makefiles so the testsuite
builds and runs again. One failure.
modified:
libcore/DisplayObject.h
libcore/DynamicShape.cpp
libcore/DynamicShape.h
libcore/Font.cpp
libcore/Font.h
libcore/FreetypeGlyphsProvider.cpp
libcore/FreetypeGlyphsProvider.h
libcore/Shape.h
libcore/StaticText.cpp
libcore/StaticText.h
libcore/TextField.cpp
libcore/parser/shape_character_def.cpp
libcore/parser/shape_character_def.h
libcore/swf/DefineFontTag.cpp
libcore/swf/DefineMorphShapeTag.cpp
libcore/swf/DefineTextTag.cpp
libcore/swf/DefineTextTag.h
libcore/swf/ShapeRecord.h
libcore/swf/TextRecord.cpp
libcore/swf/TextRecord.h
testsuite/misc-swfc.all/Makefile.am
testsuite/misc-swfmill.all/Makefile.am
------------------------------------------------------------
revno: 10771.1.23
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 14:23:59 +0200
message:
Use ShapeRecord, not DynamicShape for Freetype font walking. This trades
a bit of code duplication (could be reduced) for a much cleaner interface
and less memory per glyph.
modified:
libcore/DynamicShape.cpp
libcore/FreetypeGlyphsProvider.cpp
------------------------------------------------------------
revno: 10771.1.24
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 14:28:39 +0200
message:
Boilerplate and file descriptions.
modified:
libcore/Geometry.cpp
libcore/Geometry.h
libcore/MorphShape.cpp
libcore/MorphShape.h
libcore/Shape.cpp
libcore/Shape.h
libcore/StaticText.cpp
libcore/StaticText.h
libcore/swf/ShapeRecord.cpp
libcore/swf/ShapeRecord.h
------------------------------------------------------------
revno: 10771.1.25
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 14:34:43 +0200
message:
Move shape_character_def and character_def. Rename to DefineShapeTag
and DefinitionTag.
renamed:
libcore/parser/character_def.cpp => libcore/swf/DefinitionTag.cpp
libcore/parser/character_def.h => libcore/swf/DefinitionTag.h
libcore/parser/shape_character_def.cpp => libcore/swf/DefineShapeTag.cpp
libcore/parser/shape_character_def.h => libcore/swf/DefineShapeTag.h
modified:
backend/render_handler.h
backend/render_handler_agg.cpp
backend/render_handler_cairo.cpp
backend/render_handler_ogl.cpp
libcore/Bitmap.h
libcore/Button.cpp
libcore/DisplayObject.h
libcore/DynamicShape.h
libcore/ExportableResource.h
libcore/Font.h
libcore/FreetypeGlyphsProvider.h
libcore/Geometry.h
libcore/InteractiveObject.h
libcore/Makefile.am
libcore/MouseButtonState.h
libcore/MovieClip.cpp
libcore/MovieClip.h
libcore/Shape.h
libcore/StaticText.cpp
libcore/StaticText.h
libcore/fontlib.cpp
libcore/parser/BitmapMovieDefinition.cpp
libcore/parser/Makefile.am
libcore/parser/SWFMovieDefinition.cpp
libcore/parser/SWFMovieDefinition.h
libcore/parser/movie_definition.h
libcore/parser/sprite_definition.h
libcore/render.cpp
libcore/render.h
libcore/swf/DefineButtonCxformTag.cpp
libcore/swf/DefineButtonSoundTag.cpp
libcore/swf/DefineButtonTag.cpp
libcore/swf/DefineButtonTag.h
libcore/swf/DefineEditTextTag.h
libcore/swf/DefineMorphShapeTag.h
libcore/swf/DefineTextTag.h
libcore/swf/DefineVideoStreamTag.h
libcore/swf/VideoFrameTag.cpp
libcore/swf/VideoFrameTag.h
libcore/swf/tag_loaders.cpp
libcore/swf/DefinitionTag.cpp
libcore/swf/DefinitionTag.h
libcore/swf/DefineShapeTag.cpp
libcore/swf/DefineShapeTag.h
------------------------------------------------------------
revno: 10771.1.26
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 14:45:25 +0200
message:
Rename more.
removed:
libcore/swf/DefinitionTag.cpp
modified:
libcore/Makefile.am
libcore/Shape.h
libcore/impl.cpp
libcore/parser/SWFMovieDefinition.h
libcore/parser/movie_definition.h
libcore/parser/sprite_definition.h
libcore/swf/DefineShapeTag.cpp
libcore/swf/DefineShapeTag.h
libcore/swf/DefinitionTag.h
libcore/swf/tag_loaders.cpp
libcore/swf/tag_loaders.h
------------------------------------------------------------
revno: 10771.1.27
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 14:46:29 +0200
message:
Rename some functions mangled by sed.
modified:
libcore/MovieClip.cpp
libcore/TextField.cpp
libcore/parser/SWFMovieDefinition.cpp
libcore/parser/SWFMovieDefinition.h
libcore/parser/movie_definition.h
libcore/swf/DefineButtonCxformTag.cpp
libcore/swf/DefineButtonSoundTag.cpp
libcore/swf/DefineButtonTag.cpp
libcore/swf/VideoFrameTag.cpp
libcore/swf/tag_loaders.cpp
------------------------------------------------------------
revno: 10771.1.28
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 14:51:13 +0200
message:
Fix a couple of function names.
modified:
libcore/parser/sprite_definition.h
------------------------------------------------------------
revno: 10771.1.29
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 14:52:56 +0200
message:
Fix another couple of function names.
modified:
libcore/parser/SWFMovieDefinition.cpp
------------------------------------------------------------
revno: 10771.1.30
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 14:56:44 +0200
message:
Drop old drawShape renderer function.
modified:
backend/render_handler.h
backend/render_handler_agg.cpp
libcore/MovieClip.cpp
libcore/render.cpp
libcore/render.h
------------------------------------------------------------
revno: 10771.1.31
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 15:07:42 +0200
message:
Move under namespace SWF as expected.
modified:
libcore/swf/DefineShapeTag.cpp
------------------------------------------------------------
revno: 10771.1.32
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 15:13:16 +0200
message:
Header cleanup.
modified:
libcore/DisplayObject.h
libcore/InteractiveObject.h
libcore/MouseButtonState.h
libcore/parser/movie_definition.h
------------------------------------------------------------
revno: 10771.1.33
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 15:26:18 +0200
message:
Restore renderer bounds check and silence DynamicShape::display logging.
modified:
backend/render_handler_agg.cpp
libcore/DynamicShape.cpp
------------------------------------------------------------
revno: 10771.1.34
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 15:42:26 +0200
message:
Enable the bounds test again so that the whole testsuite passes.
modified:
libcore/Geometry.cpp
libcore/Shape.cpp
------------------------------------------------------------
revno: 10771.1.35
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 15:44:07 +0200
message:
Silence debugging.
modified:
libcore/Geometry.cpp
------------------------------------------------------------
revno: 10771.1.36
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 16:00:27 +0200
message:
Fix cairo build.
modified:
backend/PathParser.cpp
backend/PathParser.h
backend/render_handler_cairo.cpp
------------------------------------------------------------
revno: 10771.1.37
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 16:32:06 +0200
message:
Make sure all MorphShape's invalidated bounds are returned in getBounds().
This isn't really what it's for, but was how it worked before.
modified:
backend/render_handler.h
backend/render_handler_agg.cpp
backend/render_handler_cairo.cpp
libcore/MorphShape.cpp
libcore/MorphShape.h
libcore/render.cpp
libcore/render.h
libcore/swf/DefineMorphShapeTag.cpp
libcore/swf/ShapeRecord.cpp
libcore/swf/ShapeRecord.h
------------------------------------------------------------
revno: 10771.1.38
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 16:38:20 +0200
message:
Drop morph includes again.
modified:
backend/render_handler_cairo.cpp
------------------------------------------------------------
revno: 10771.1.39
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Tue 2009-04-07 16:45:34 +0200
message:
Fix OGL build.
modified:
backend/render_handler_ogl.cpp
backend/render_handler_ogl.h
=== modified file 'backend/Makefile.am'
--- a/backend/Makefile.am 2009-01-22 20:10:39 +0000
+++ b/backend/Makefile.am 2009-04-06 20:29:42 +0000
@@ -36,6 +36,7 @@
-I$(top_srcdir)/libnet \
-I$(top_srcdir)/libcore \
-I$(top_srcdir)/libcore/parser \
+ -I$(top_srcdir)/libcore/swf \
-I$(top_srcdir)/libbase \
-I$(top_srcdir)/backend \
$(PTHREAD_CFLAGS) \
=== modified file 'backend/PathParser.cpp'
--- a/backend/PathParser.cpp 2009-02-25 22:33:03 +0000
+++ b/backend/PathParser.cpp 2009-04-07 14:00:27 +0000
@@ -36,7 +36,7 @@
return _fill_type == FILL_LEFT ? _path->m_edges.back().ap : _path->ap;
}
-PathParser::PathParser(const std::vector<path>& paths, size_t numstyles)
+PathParser::PathParser(const std::vector<Path>& paths, size_t numstyles)
: _paths(paths),
_num_styles(numstyles),
_shape_origin(0, 0),
@@ -54,7 +54,7 @@
for (size_t i = 0; i < _paths.size(); ++i) {
- if (_paths[i].is_empty()) {
+ if (_paths[i].empty()) {
continue;
}
@@ -129,9 +129,9 @@
this, _1));
} else {
- for (std::vector<edge>::const_reverse_iterator prev = edges.rbegin(),
+ for (std::vector<Edge>::const_reverse_iterator prev = edges.rbegin(),
it = boost::next(prev), end = edges.rend(); it != end; ++it, ++prev) {
- if ((*prev).isStraight()) {
+ if ((*prev).straight()) {
lineTo((*it).ap);
} else {
line_to(Edge((*prev).cp, (*it).ap));
@@ -145,9 +145,9 @@
}
void
-PathParser::line_to(const edge& curve)
+PathParser::line_to(const Edge& curve)
{
- if (curve.isStraight()) {
+ if (curve.straight()) {
lineTo(curve.ap);
} else {
curveTo(curve);
=== modified file 'backend/PathParser.h'
--- a/backend/PathParser.h 2009-03-11 13:41:02 +0000
+++ b/backend/PathParser.h 2009-04-07 14:00:27 +0000
@@ -39,7 +39,7 @@
UnivocalPath() : _path(NULL), _fill_type(FILL_LEFT) {}
- UnivocalPath(const path* path, fill_type filltype)
+ UnivocalPath(const Path* path, fill_type filltype)
: _path(path),
_fill_type(filltype)
{
@@ -48,7 +48,7 @@
const point& startPoint() const;
const point& endPoint() const;
- const path* _path;
+ const Path* _path;
fill_type _fill_type;
};
@@ -62,7 +62,7 @@
public:
/// @param paths list of Flash paths to be 'parsed'.
/// @param num_styles count of fill styles pointed to by the first argument.
- PathParser(const std::vector<path>& paths, size_t num_styles);
+ PathParser(const std::vector<Path>& paths, size_t num_styles);
virtual ~PathParser() { }
@@ -95,7 +95,7 @@
virtual void moveTo(const point& p) = 0;
/// Draw the given curve using the path pencil.
- virtual void curveTo(const edge& curve) = 0;
+ virtual void curveTo(const Edge& curve) = 0;
/// Draw a straight line to the given point.
virtual void lineTo(const point& p) = 0;
@@ -113,9 +113,9 @@
bool closed_shape();
- void line_to(const edge& curve);
+ void line_to(const Edge& curve);
- const std::vector<path>& _paths;
+ const std::vector<Path>& _paths;
const size_t _num_styles;
point _shape_origin;
point _cur_endpoint;
=== modified file 'backend/render_handler.h'
--- a/backend/render_handler.h 2009-04-03 09:18:40 +0000
+++ b/backend/render_handler.h 2009-04-07 14:32:06 +0000
@@ -146,7 +146,7 @@
#include "dsodefs.h" // for DSOEXPORT
#include "gnash.h" // Quality
-#include "shape_character_def.h"
+#include "DefineShapeTag.h"
#include "DisplayObject.h"
#include "Range2d.h"
@@ -158,7 +158,14 @@
class SWFMatrix;
class cxform;
- class shape_character_def;
+ namespace SWF {
+ class DefineMorphShapeTag;
+ class ShapeRecord;
+ }
+ class DefineShapeTag;
+
+ class Shape;
+ class MorphShape;
class GnashImage;
}
@@ -283,38 +290,8 @@
const rgba& fill, const rgba& outline, const SWFMatrix& mat,
bool masked) = 0;
-
- /// \brief
- /// Draws the given character definition with the stateful properties
- /// of the given instance.
- //
- /// Normally this does not need to be re-implemented in
- /// render handler implementations. Instead, see the version without
- /// character instance.
- ///
- virtual void drawShape(shape_character_def *def, DisplayObject *inst)
- {
- // check if the character needs to be rendered at all
- rect cur_bounds;
-
- cur_bounds.expand_to_transformed_rect(inst->getWorldMatrix(),
- def->get_bound());
-
- if (!bounds_in_clipping_area(cur_bounds))
- {
- return; // no need to draw
- }
-
- // render the character
- drawShape(def, inst->getWorldMatrix(),
- inst->get_world_cxform());
- }
-
- /// \brief
- /// Draws the given character definition with the given transformations and
- /// styles.
- virtual void drawShape(shape_character_def *def,
- const SWFMatrix& mat, const cxform& cx) = 0;
+ virtual void drawShape(const SWF::ShapeRecord& shape, const cxform& cx,
+ const SWFMatrix& worldMat) = 0;
/// \brief
/// Draws a glyph (font character).
@@ -330,8 +307,8 @@
/// @param mat
///
/// @param color
- virtual void draw_glyph(shape_character_def *def, const SWFMatrix& mat,
- const rgba& color) = 0;
+ virtual void drawGlyph(const SWF::ShapeRecord& rec, const rgba& color,
+ const SWFMatrix& mat) = 0;
/// ==================================================================
=== modified file 'backend/render_handler_agg.cpp'
--- a/backend/render_handler_agg.cpp 2009-04-03 09:18:40 +0000
+++ b/backend/render_handler_agg.cpp 2009-04-07 14:32:06 +0000
@@ -120,8 +120,12 @@
#include "render_handler.h"
#include "render_handler_agg.h"
#include "Range2d.h"
-#include "shape_character_def.h"
+#include "swf/DefineMorphShapeTag.h"
+#include "swf/ShapeRecord.h"
+#include "DefineShapeTag.h"
#include "DisplayObject.h"
+#include "MorphShape.h"
+#include "Shape.h"
#include "GnashNumeric.h"
#include <agg_rendering_buffer.h>
@@ -181,7 +185,7 @@
typedef std::vector<agg::path_storage> AggPaths;
typedef std::vector<geometry::Range2d<int> > ClipBounds;
typedef std::vector<AlphaMask*> AlphaMasks;
-typedef std::vector<path> GnashPaths;
+typedef std::vector<Path> GnashPaths;
template <class Rasterizer>
inline void applyClipBox(Rasterizer& ras, const geometry::Range2d<int>& bounds)
@@ -209,7 +213,7 @@
for (int pno=0; pno<pcount; ++pno) {
- const path &the_path = paths[pno];
+ const Path &the_path = paths[pno];
if ((the_path.m_fill0 > 0) || (the_path.m_fill1 > 0)) {
have_shape = true;
@@ -233,9 +237,9 @@
_shift(shift)
{}
- void operator()(const edge& edge)
+ void operator()(const Edge& edge)
{
- if (edge.is_straight()) {
+ if (edge.straight()) {
_path.line_to(twipsToPixels(edge.ap.x) + _shift,
twipsToPixels(edge.ap.y) + _shift);
}
@@ -265,7 +269,7 @@
{
}
- void operator()(const path& in)
+ void operator()(const Path& in)
{
agg::path_storage& p = *_it;
@@ -859,22 +863,20 @@
}
- void draw_glyph(shape_character_def *def,
- const SWFMatrix& mat, const rgba& color)
+ void drawGlyph(const SWF::ShapeRecord& shape, const rgba& color,
+ const SWFMatrix& mat)
{
// select relevant clipping bounds
- if (def->get_bound().is_null()) {
+ if (shape.getBounds().is_null()) {
return;
- // Why would we want to do this?
- //select_all_clipbounds();
}
- else select_clipbounds(def, mat);
+ select_clipbounds(shape.getBounds(), mat);
if (_clipbounds_selected.empty()) return;
GnashPaths paths;
- apply_matrix_to_path(def->paths(), paths, mat);
+ apply_matrix_to_path(shape.paths(), paths, mat);
// If it's a mask, we don't need the rest.
if (m_drawing_mask) {
@@ -907,18 +909,16 @@
/// rendering of characters outside a particular clipping range.
/// "_clipbounds_selected" is used by draw_shape() and draw_outline() and
/// *must* be initialized prior to using those function.
- void select_clipbounds(const shape_character_def *def,
- const SWFMatrix& source_mat) {
+ void select_clipbounds(const rect& objectBounds, const SWFMatrix& source_mat)
+ {
SWFMatrix mat = stage_matrix;
mat.concatenate(source_mat);
_clipbounds_selected.clear();
_clipbounds_selected.reserve(_clipbounds.size());
-
- const rect& ch_bounds = def->get_bound();
- if (ch_bounds.is_null()) {
+ if (objectBounds.is_null()) {
log_debug(_("Warning: select_clipbounds encountered a character "
"definition with null bounds"));
return;
@@ -926,7 +926,7 @@
rect bounds;
bounds.set_null();
- bounds.expand_to_transformed_rect(mat, ch_bounds);
+ bounds.expand_to_transformed_rect(mat, objectBounds);
const geometry::Range2d<float>& range_float = bounds.getRange();
@@ -956,30 +956,54 @@
_clipbounds_selected.clear();
_clipbounds_selected.reserve(_clipbounds.size());
- for (ClipBounds::const_iterator i = _clipbounds.begin(),
+ for (ClipBounds::iterator i = _clipbounds.begin(),
e = _clipbounds.end(); i != e; ++i)
{
_clipbounds_selected.push_back(&(*i));
}
}
- void drawShape(shape_character_def *def,
- const SWFMatrix& mat, const cxform& cx)
- {
-
- const std::vector<fill_style>& fill_styles = def->fillStyles();
- const std::vector<line_style>& line_styles = def->lineStyles();
+ void drawShape(const SWF::ShapeRecord& shape, const cxform& cx,
+ const SWFMatrix& worldMat)
+ {
+ // check if the character needs to be rendered at all
+ rect cur_bounds;
+
+ cur_bounds.expand_to_transformed_rect(worldMat, shape.getBounds());
+
+ if (!render_handler::bounds_in_clipping_area(cur_bounds))
+ {
+ return; // no need to draw
+ }
+
+ const SWF::ShapeRecord::FillStyles& fillStyles = shape.fillStyles();
+ const SWF::ShapeRecord::LineStyles& lineStyles = shape.lineStyles();
+ const SWF::ShapeRecord::Paths& paths = shape.paths();
+
+ // select ranges
+ select_clipbounds(shape.getBounds(), worldMat);
+
+ // render the DisplayObject's shape.
+ drawShape(fillStyles, lineStyles, paths, worldMat, cx);
+ }
+
+ void drawShape(const std::vector<fill_style>& fill_styles,
+ const std::vector<line_style>& line_styles,
+ const std::vector<Path>& objpaths, const SWFMatrix& mat,
+ const cxform& cx)
+ {
+
bool have_shape, have_outline;
- analyzePaths(def->paths(), have_shape, have_outline);
+ analyzePaths(objpaths, have_shape, have_outline);
if (!have_shape && !have_outline) {
// Early return for invisible character.
return;
- }
+ }
GnashPaths paths;
- apply_matrix_to_path(def->paths(), paths, mat);
+ apply_matrix_to_path(objpaths, paths, mat);
// Masks apparently do not use agg_paths, so return
// early
@@ -991,21 +1015,19 @@
return;
}
- AggPaths agg_paths;
- AggPaths agg_paths_rounded;
+ AggPaths agg_paths;
+ AggPaths agg_paths_rounded;
// Flash only aligns outlines. Probably this is done at rendering
// level.
if (have_outline) {
- buildPaths_rounded(agg_paths_rounded, paths, line_styles);
+ buildPaths_rounded(agg_paths_rounded, paths, line_styles);
}
if (have_shape) {
buildPaths(agg_paths, paths);
}
- // select ranges
- select_clipbounds(def, mat);
if (_clipbounds_selected.empty()) {
log_debug(_("Warning: AGG renderer skipping a whole character"));
@@ -1022,9 +1044,9 @@
for (unsigned int subshape=0; subshape<subshape_count; ++subshape)
{
if (have_shape) {
- draw_shape(subshape, paths, agg_paths, sh, true);
+ draw_shape(subshape, paths, agg_paths, sh, true);
}
- if (have_outline) {
+ if (have_outline) {
draw_outlines(subshape, paths, agg_paths_rounded,
line_styles, cx, mat);
}
@@ -1032,10 +1054,8 @@
// Clear selected clipbounds to ease debugging
_clipbounds_selected.clear();
+ }
- } // drawShape
-
-
/// Takes a path and translates it using the given SWFMatrix. The new path
/// is stored in paths_out. Both paths_in and paths_out are expected to
/// be in TWIPS.
@@ -1054,7 +1074,7 @@
/// Transform all the paths using the matrix.
std::for_each(paths_out.begin(), paths_out.end(),
- boost::bind(&path::transform, _1, mat));
+ boost::bind(&Path::transform, _1, mat));
}
@@ -1068,7 +1088,7 @@
const size_t pcnt = path_in.size();
for (size_t pno=0; pno<pcnt; ++pno) {
- const path& this_path = path_in[pno];
+ const Path& this_path = path_in[pno];
if (this_path.m_new_shape)
sscount++;
@@ -1106,7 +1126,7 @@
for (size_t pno=0; pno<pcount; ++pno) {
- const path& this_path = paths[pno];
+ const Path& this_path = paths[pno];
agg::path_storage& new_path = dest[pno];
bool hinting=false, closed=false, hairline=false;
@@ -1133,16 +1153,16 @@
// avoid extra edge when doing implicit close later
if (closed && ecount &&
- this_path.m_edges.back().is_straight()) --ecount;
+ this_path.m_edges.back().straight()) --ecount;
for (size_t eno=0; eno<ecount; ++eno) {
- const edge& this_edge = this_path.m_edges[eno];
+ const Edge& this_edge = this_path.m_edges[eno];
float this_ax = twipsToPixels(this_edge.ap.x);
float this_ay = twipsToPixels(this_edge.ap.y);
- if (hinting || this_edge.is_straight()) {
+ if (hinting || this_edge.straight()) {
// candidate for alignment?
bool align_x = hinting || (hairline && (prev_ax == this_ax));
@@ -1450,7 +1470,7 @@
for (size_t pno=0; pno<pcount; ++pno) {
- const path &this_path_gnash = paths[pno];
+ const Path &this_path_gnash = paths[pno];
agg::path_storage &this_path_agg =
const_cast<agg::path_storage&>(agg_paths[pno]);
@@ -1490,7 +1510,7 @@
// very similar to draw_shape but used for generating masks. There are no
// fill styles nor subshapes and such. Just render plain solid shapes.
- void draw_mask_shape(const GnashPaths &paths, bool even_odd)
+ void draw_mask_shape(const GnashPaths& paths, bool even_odd)
{
const AlphaMasks::size_type mask_count = _alphaMasks.size();
@@ -1523,7 +1543,7 @@
template <class scanline_type>
- void draw_mask_shape_impl(const GnashPaths &paths, bool even_odd,
+ void draw_mask_shape_impl(const GnashPaths& paths, bool even_odd,
scanline_type& sl) {
typedef agg::pixfmt_gray8 pixfmt;
@@ -1665,7 +1685,7 @@
for (size_t pno=0, pcount=paths.size(); pno<pcount; ++pno) {
- const path& this_path_gnash = paths[pno];
+ const Path& this_path_gnash = paths[pno];
agg::path_storage &this_path_agg =
const_cast<agg::path_storage&>(agg_paths[pno]);
=== modified file 'backend/render_handler_cairo.cpp'
--- a/backend/render_handler_cairo.cpp 2009-04-03 09:18:40 +0000
+++ b/backend/render_handler_cairo.cpp 2009-04-07 14:38:20 +0000
@@ -40,6 +40,7 @@
#include "GnashImage.h"
#include <cmath>
#include "PathParser.h"
+#include "swf/ShapeRecord.h"
namespace gnash {
@@ -286,7 +287,7 @@
class CairoPathRunner : public PathParser
{
public:
- CairoPathRunner(const std::vector<path>& paths,
+ CairoPathRunner(const std::vector<Path>& paths,
const std::vector<fill_style>& fill_styles, cairo_t* context)
: PathParser(paths, fill_styles.size()),
_cr(context),
@@ -329,7 +330,7 @@
cairo_move_to(_cr, x, y);
}
- virtual void curveTo(const edge& cur_edge)
+ virtual void curveTo(const Edge& cur_edge)
{
const float two_thirds = 2.0/3.0;
const float one_third = 1 - two_thirds;
@@ -403,8 +404,8 @@
class DSOEXPORT render_handler_cairo: public render_handler
{
- typedef std::vector<path> PathVec;
- typedef std::vector<const path*> PathPtrVec;
+ typedef std::vector<Path> PathVec;
+ typedef std::vector<const Path*> PathPtrVec;
public:
render_handler_cairo()
@@ -740,7 +741,7 @@
_masks.pop_back();
}
- void add_path(cairo_t* cr, const path& cur_path)
+ void add_path(cairo_t* cr, const Path& cur_path)
{
double x = cur_path.ap.x;
double y = cur_path.ap.y;
@@ -748,11 +749,11 @@
snap_to_half_pixel(cr, x, y);
cairo_move_to(cr, x, y);
- for (std::vector<edge>::const_iterator it = cur_path.m_edges.begin(),
+ for (std::vector<Edge>::const_iterator it = cur_path.m_edges.begin(),
end = cur_path.m_edges.end(); it != end; ++it) {
- const edge& cur_edge = *it;
+ const Edge& cur_edge = *it;
- if (cur_edge.is_straight()) {
+ if (cur_edge.straight()) {
x = cur_edge.ap.x;
y = cur_edge.ap.y;
snap_to_half_pixel(cr, x, y);
@@ -852,7 +853,7 @@
{
for (PathVec::const_iterator it = path_vec.begin(), end = path_vec.end();
it != end; ++it) {
- const path& cur_path = *it;
+ const Path& cur_path = *it;
if (!cur_path.m_line) {
continue;
}
@@ -889,7 +890,7 @@
++it;
for (;it != end; ++it) {
- const path& cur_path = *it;
+ const Path& cur_path = *it;
if (cur_path.m_new_shape) {
subshapes.push_back(it);
@@ -905,7 +906,7 @@
{
for (PathVec::const_iterator it = path_vec.begin(), end = path_vec.end();
it != end; ++it) {
- const path& cur_path = *it;
+ const Path& cur_path = *it;
if (cur_path.m_fill0 || cur_path.m_fill1) {
_masks.back().push_back(cur_path);
@@ -918,7 +919,7 @@
{
for (PathVec::const_iterator it = path_vec.begin(), end = path_vec.end();
it != end; ++it) {
- const path& cur_path = *it;
+ const Path& cur_path = *it;
add_path(_cr, cur_path);
}
@@ -926,18 +927,17 @@
/// Takes a path and translates it using the given SWFMatrix.
void
- apply_matrix_to_paths(std::vector<path>& paths, const SWFMatrix& mat)
+ apply_matrix_to_paths(std::vector<Path>& paths, const SWFMatrix& mat)
{
std::for_each(paths.begin(), paths.end(),
- boost::bind(&path::transform, _1, boost::ref(mat)));
+ boost::bind(&Path::transform, _1, boost::ref(mat)));
}
-
- virtual void drawShape(shape_character_def *def,
- const SWFMatrix& mat,
- const cxform& cx)
+
+ virtual void drawShape(const SWF::ShapeRecord& shape, const cxform& cx,
+ const SWFMatrix& mat)
{
- const PathVec& path_vec = def->paths();
+ const PathVec& path_vec = shape.paths();
if (!path_vec.size()) {
return;
@@ -957,8 +957,8 @@
std::vector<PathVec::const_iterator> subshapes = find_subshapes(path_vec);
- const std::vector<fill_style>& fill_styles = def->fillStyles();
- const std::vector<line_style>& line_styles = def->lineStyles();
+ const std::vector<fill_style>& fill_styles = shape.fillStyles();
+ const std::vector<line_style>& line_styles = shape.lineStyles();
for (size_t i = 0; i < subshapes.size()-1; ++i) {
PathVec subshape_paths;
@@ -975,8 +975,8 @@
}
- virtual void draw_glyph(shape_character_def *def, const SWFMatrix& mat,
- const rgba& color)
+ virtual void drawGlyph(const SWF::ShapeRecord& rec, const rgba& color,
+ const SWFMatrix& mat)
{
cxform dummy_cx;
@@ -987,7 +987,7 @@
glyph_fs.push_back(coloring);
- const PathVec& path_vec = def->paths();
+ const PathVec& path_vec = rec.paths();
std::vector<line_style> dummy_ls;
=== modified file 'backend/render_handler_ogl.cpp'
--- a/backend/render_handler_ogl.cpp 2009-04-03 09:18:40 +0000
+++ b/backend/render_handler_ogl.cpp 2009-04-07 14:45:34 +0000
@@ -24,7 +24,7 @@
#include <cmath>
#include "render_handler.h"
-
+#include "swf/ShapeRecord.h"
#include "gnash.h"
#include "RGBA.h"
#include "GnashImage.h"
@@ -168,7 +168,7 @@
#endif // OSMESA_TESTING
-typedef std::vector<path> PathVec;
+typedef std::vector<Path> PathVec;
class oglScopeEnable : public boost::noncopyable
{
@@ -290,21 +290,21 @@
-std::vector<oglVertex> interpolate(const std::vector<edge>& edges, const
float& anchor_x,
- const float& anchor_y)
+std::vector<oglVertex> interpolate(const std::vector<Edge>& edges,
+ const float& anchor_x, const float& anchor_y)
{
point anchor(anchor_x, anchor_y);
std::vector<oglVertex> shape_points;
shape_points.push_back(oglVertex(anchor));
- for (std::vector<edge>::const_iterator it = edges.begin(), end = edges.end();
+ for (std::vector<Edge>::const_iterator it = edges.begin(), end = edges.end();
it != end; ++it) {
- const edge& the_edge = *it;
+ const Edge& the_edge = *it;
point target(the_edge.ap.x, the_edge.ap.y);
- if (the_edge.is_straight()) {
+ if (the_edge.straight()) {
shape_points.push_back(oglVertex(target));
} else {
point control(the_edge.cp.x, the_edge.cp.y);
@@ -1032,7 +1032,7 @@
}
#if 0
- void print_path(const path& path)
+ void print_path(const Path& path)
{
std::cout << "Origin: ("
<< path.ap.x
@@ -1064,28 +1064,28 @@
#endif
- path reverse_path(const path& cur_path)
+ Path reverse_path(const Path& cur_path)
{
- const edge& cur_end = cur_path.m_edges.back();
+ const Edge& cur_end = cur_path.m_edges.back();
float prev_cx = cur_end.cp.x;
float prev_cy = cur_end.cp.y;
- path newpath(cur_end.ap.x, cur_end.ap.y, cur_path.m_fill1,
cur_path.m_fill0, cur_path.m_line, cur_path.m_new_shape);
+ Path newpath(cur_end.ap.x, cur_end.ap.y, cur_path.m_fill1,
cur_path.m_fill0, cur_path.m_line, cur_path.m_new_shape);
float prev_ax = cur_end.ap.x;
float prev_ay = cur_end.ap.y;
- for (std::vector<edge>::const_reverse_iterator it =
cur_path.m_edges.rbegin()+1, end = cur_path.m_edges.rend();
+ for (std::vector<Edge>::const_reverse_iterator it =
cur_path.m_edges.rbegin()+1, end = cur_path.m_edges.rend();
it != end; ++it) {
- const edge& cur_edge = *it;
+ const Edge& cur_edge = *it;
if (prev_ax == prev_cx && prev_ay == prev_cy) {
prev_cx = cur_edge.ap.x;
prev_cy = cur_edge.ap.y;
}
- edge newedge(prev_cx, prev_cy, cur_edge.ap.x, cur_edge.ap.y);
+ Edge newedge(prev_cx, prev_cy, cur_edge.ap.x, cur_edge.ap.y);
newpath.m_edges.push_back(newedge);
@@ -1096,14 +1096,14 @@
}
- edge newlastedge(prev_cx, prev_cy, cur_path.ap.x, cur_path.ap.y);
+ Edge newlastedge(prev_cx, prev_cy, cur_path.ap.x, cur_path.ap.y);
newpath.m_edges.push_back(newlastedge);
return newpath;
}
- const path* find_connecting_path(const path& to_connect,
- std::list<const path*> path_refs)
+ const Path* find_connecting_path(const Path& to_connect,
+ std::list<const Path*> path_refs)
{
float target_x = to_connect.m_edges.back().ap.x;
@@ -1114,9 +1114,9 @@
return NULL;
}
- for (std::list<const path*>::const_iterator it = path_refs.begin(), end =
path_refs.end();
+ for (std::list<const Path*>::const_iterator it = path_refs.begin(), end =
path_refs.end();
it != end; ++it) {
- const path* cur_path = *it;
+ const Path* cur_path = *it;
if (cur_path == &to_connect) {
@@ -1144,7 +1144,7 @@
for (PathVec::const_iterator it = paths.begin(), end = paths.end();
it != end; ++it) {
- const path& cur_path = *it;
+ const Path& cur_path = *it;
if (cur_path.m_edges.empty()) {
continue;
@@ -1155,14 +1155,14 @@
normalized.push_back(cur_path);
normalized.back().m_fill0 = 0;
- path newpath = reverse_path(cur_path);
+ Path newpath = reverse_path(cur_path);
newpath.m_fill0 = 0;
normalized.push_back(newpath);
} else if (cur_path.m_fill0) {
// Left fill style.
- path newpath = reverse_path(cur_path);
+ Path newpath = reverse_path(cur_path);
newpath.m_fill0 = 0;
normalized.push_back(newpath);
@@ -1198,7 +1198,7 @@
for (int pno=0; pno<pcount; pno++) {
- const path &the_path = paths[pno];
+ const Path &the_path = paths[pno];
if ((the_path.m_fill0>0) || (the_path.m_fill1>0)) {
have_shape=true;
@@ -1347,7 +1347,7 @@
for (PathVec::const_iterator it = path_vec.begin(), end = path_vec.end();
it != end; ++it) {
- const path& cur_path = *it;
+ const Path& cur_path = *it;
if (!cur_path.m_edges.size()) {
continue;
@@ -1361,10 +1361,10 @@
return pathpoints;
}
- typedef std::vector<const path*> PathPtrVec;
+ typedef std::vector<const Path*> PathPtrVec;
static void
- draw_point(const edge& point_edge)
+ draw_point(const Edge& point_edge)
{
glVertex2d(point_edge.ap.x, point_edge.ap.y);
}
@@ -1377,7 +1377,7 @@
for (PathVec::const_iterator it = path_vec.begin(), end = path_vec.end();
it != end; ++it) {
- const path& cur_path = *it;
+ const Path& cur_path = *it;
if (!cur_path.m_line) {
continue;
@@ -1415,19 +1415,19 @@
std::list<PathPtrVec> get_contours(const PathPtrVec &paths)
{
- std::list<const path*> path_refs;
+ std::list<const Path*> path_refs;
std::list<PathPtrVec> contours;
for (PathPtrVec::const_iterator it = paths.begin(), end = paths.end();
it != end; ++it) {
- const path* cur_path = *it;
+ const Path* cur_path = *it;
path_refs.push_back(cur_path);
}
- for (std::list<const path*>::const_iterator it = path_refs.begin(), end =
path_refs.end();
+ for (std::list<const Path*>::const_iterator it = path_refs.begin(), end =
path_refs.end();
it != end; ++it) {
- const path* cur_path = *it;
+ const Path* cur_path = *it;
if (cur_path->m_edges.empty()) {
continue;
@@ -1441,13 +1441,13 @@
contour.push_back(cur_path);
- const path* connector = find_connecting_path(*cur_path, path_refs);
+ const Path* connector = find_connecting_path(*cur_path, path_refs);
while (connector) {
contour.push_back(connector);
- const path* tmp = connector;
- connector = find_connecting_path(*connector, std::list<const
path*>(boost::next(it), end));
+ const Path* tmp = connector;
+ connector = find_connecting_path(*connector, std::list<const
Path*>(boost::next(it), end));
// make sure we don't iterate over the connecting path in the for loop.
path_refs.remove(tmp);
@@ -1465,7 +1465,7 @@
{
for (PathVec::const_iterator it = path_vec.begin(), end = path_vec.end();
it != end; ++it) {
- const path& cur_path = *it;
+ const Path& cur_path = *it;
if (cur_path.m_fill0 || cur_path.m_fill1) {
_masks.back().push_back(cur_path);
@@ -1480,7 +1480,7 @@
PathPtrVec paths;
for (PathVec::const_iterator it = path_vec.begin(), end = path_vec.end();
it != end; ++it) {
- const path& cur_path = *it;
+ const Path& cur_path = *it;
if (cur_path.m_fill0 == style) {
paths.push_back(&cur_path);
@@ -1507,7 +1507,7 @@
++it;
for (;it != end; ++it) {
- const path& cur_path = *it;
+ const Path& cur_path = *it;
if (cur_path.m_new_shape) {
subshapes.push_back(it);
@@ -1523,10 +1523,10 @@
/// Takes a path and translates it using the given SWFMatrix.
void
- apply_matrix_to_paths(std::vector<path>& paths, const SWFMatrix& mat)
+ apply_matrix_to_paths(std::vector<Path>& paths, const SWFMatrix& mat)
{
std::for_each(paths.begin(), paths.end(),
- boost::bind(&path::transform, _1, boost::ref(mat)));
+ boost::bind(&Path::transform, _1, boost::ref(mat)));
//for_each(paths, &path::transform, mat);
}
@@ -1560,7 +1560,7 @@
for (PathPtrVec::const_iterator it = refs.begin(), end = refs.end();
it != end; ++it) {
- const path& cur_path = *(*it);
+ const Path& cur_path = *(*it);
assert(pathpoints.find(&cur_path) != pathpoints.end());
@@ -1607,11 +1607,11 @@
// 5. Profit!
virtual void
- drawShape(shape_character_def *def, const SWFMatrix& mat,
- const cxform& cx)
+ drawShape(const SWF::ShapeRecord& shape, const cxform& cx,
+ const SWFMatrix& mat)
{
- const PathVec& path_vec = def->paths();
+ const PathVec& path_vec = shape.paths();
if (!path_vec.size()) {
// No paths. Nothing to draw...
@@ -1638,8 +1638,8 @@
std::vector<PathVec::const_iterator> subshapes = find_subshapes(path_vec);
- const std::vector<fill_style>& fill_styles = def->fillStyles();
- const std::vector<line_style>& line_styles = def->lineStyles();
+ const std::vector<fill_style>& fill_styles = shape.fillStyles();
+ const std::vector<line_style>& line_styles = shape.lineStyles();
for (size_t i = 0; i < subshapes.size()-1; ++i) {
PathVec subshape_paths;
@@ -1655,8 +1655,8 @@
}
}
- virtual void draw_glyph(shape_character_def *def, const SWFMatrix& mat,
- const rgba& c)
+ virtual void drawGlyph(const SWF::ShapeRecord& rec, const rgba& c,
+ const SWFMatrix& mat)
{
if (_drawing_mask) abort();
cxform dummy_cx;
@@ -1671,7 +1671,7 @@
oglScopeMatrix scope_mat(mat);
- draw_subshape(def->paths(), mat, dummy_cx, glyph_fs, dummy_ls);
+ draw_subshape(rec.paths(), mat, dummy_cx, glyph_fs, dummy_ls);
}
virtual void set_scale(float xscale, float yscale) {
=== modified file 'backend/render_handler_ogl.h'
--- a/backend/render_handler_ogl.h 2009-01-22 20:10:39 +0000
+++ b/backend/render_handler_ogl.h 2009-04-07 14:45:34 +0000
@@ -56,7 +56,7 @@
-typedef std::vector<const path*> PathRefs;
+typedef std::vector<const Path*> PathRefs;
@@ -76,7 +76,7 @@
GLdouble _z;
};
-typedef std::map< const path*, std::vector<oglVertex> > PathPointMap;
+typedef std::map<const Path*, std::vector<oglVertex> > PathPointMap;
class Tesselator
{
@@ -111,7 +111,7 @@
class WholeShape
{
public:
- void newPath(const path& new_path)
+ void newPath(const Path& new_path)
{
PathRefs refs;
refs.push_back(&new_path);
@@ -119,7 +119,7 @@
shape.push_back(refs);
}
- void addPath(const path& add_path)
+ void addPath(const Path& add_path)
{
PathRefs& refs = shape.back();
refs.push_back(&add_path);
=== modified file 'cygnal/Makefile.am'
--- a/cygnal/Makefile.am 2009-03-19 23:14:43 +0000
+++ b/cygnal/Makefile.am 2009-04-06 20:29:42 +0000
@@ -56,6 +56,7 @@
-I$(top_srcdir)/backend \
-I$(top_srcdir)/libcore \
-I$(top_srcdir)/libcore/asobj \
+ -I$(top_srcdir)/libcore/swf \
-I$(top_srcdir)/libcore/parser \
-I$(top_srcdir)/libcore/vm \
-DLOCALEDIR=\"$(localedir)\" \
=== modified file 'gui/Makefile.am'
--- a/gui/Makefile.am 2009-02-27 06:46:40 +0000
+++ b/gui/Makefile.am 2009-04-06 20:29:42 +0000
@@ -37,6 +37,7 @@
-I$(top_srcdir)/libamf \
-I$(top_srcdir)/libnet \
-I$(top_srcdir)/libcore \
+ -I$(top_srcdir)/libcore/swf \
-I$(top_srcdir)/libcore/parser \
-I$(top_srcdir)/libcore/vm \
-I$(top_srcdir)/libltdl \
=== modified file 'libcore/Bitmap.cpp'
--- a/libcore/Bitmap.cpp 2009-04-03 09:18:40 +0000
+++ b/libcore/Bitmap.cpp 2009-04-07 09:19:54 +0000
@@ -30,11 +30,10 @@
DisplayObject(parent, id),
_bitmapData(bd),
_bitmapInfo(0),
- _shapeDef(new DynamicShape),
_width(_bitmapData->getWidth()),
_height(_bitmapData->getHeight())
{
- _shapeDef->set_bound(rect(0, 0, _width * 20, _height * 20));
+ _shape.setBounds(rect(0, 0, _width * 20, _height * 20));
}
@@ -61,9 +60,7 @@
void
Bitmap::display()
{
- assert(_shapeDef);
-
- _shapeDef->display(this);
+ _shape.display(*this);
clear_invalidated();
}
@@ -84,7 +81,7 @@
rect
Bitmap::getBounds() const
{
- return _shapeDef->get_bound();
+ return _shape.getBounds();
}
void
@@ -126,7 +123,7 @@
/// set _bitmapData to 0 to avoid any further interaction.
if (data.empty()) {
_bitmapData = 0;
- _shapeDef->set_bound(rect());
+ _shape.clear();
return;
}
@@ -137,24 +134,21 @@
const int w = _width * 20;
const int h = _height * 20;
- if (!_shapeDef) {
- }
-
SWFMatrix mat;
mat.set_scale(1.0 / 20, 1.0 / 20);
fill_style fill(_bitmapInfo.get(), mat);
- const size_t fillLeft = _shapeDef->add_fill_style(fill);
-
-
- path bmpath(w, h, fillLeft, 0, 0, false);
+ const size_t fillLeft = _shape.add_fill_style(fill);
+
+
+ Path bmpath(w, h, fillLeft, 0, 0, false);
bmpath.drawLineTo(w, 0);
bmpath.drawLineTo(0, 0);
bmpath.drawLineTo(0, h);
bmpath.drawLineTo(w, h);
- _shapeDef->add_path(bmpath);
+ _shape.add_path(bmpath);
- _shapeDef->finalize();
+ _shape.finalize();
}
=== modified file 'libcore/Bitmap.h'
--- a/libcore/Bitmap.h 2009-04-03 09:18:40 +0000
+++ b/libcore/Bitmap.h 2009-04-07 12:34:43 +0000
@@ -54,15 +54,9 @@
protected:
- /// This should really have an optional definition.
- virtual character_def* getDefinition() const {
- return _shapeDef.get();
- }
-
void markReachableObjects() const {
if (_bitmapData) _bitmapData->setReachable();
if (_bitmapInfo) _bitmapInfo->setReachable();
- if (_shapeDef) _shapeDef->setReachable();
}
private:
@@ -80,8 +74,8 @@
/// The current bitmap information is stored here.
boost::intrusive_ptr<BitmapInfo> _bitmapInfo;
- /// FIXME: using shape_character_def is unpleasant.
- boost::intrusive_ptr<DynamicShape> _shapeDef;
+ /// FIXME: using DefineShapeTag is unpleasant.
+ DynamicShape _shape;
/// This is cached to save querying the BitmapData often
size_t _width;
=== modified file 'libcore/BitmapMovieInstance.cpp'
--- a/libcore/BitmapMovieInstance.cpp 2009-04-03 09:48:13 +0000
+++ b/libcore/BitmapMovieInstance.cpp 2009-04-07 09:19:54 +0000
@@ -31,10 +31,8 @@
// We need to assign a DisplayObject id to the instance, or an assertion
// will fail in DisplayObject.cpp (parent==NULL || id != -1)
- character_def* chdef = def->get_character_def(1);
- assert(chdef);
- boost::intrusive_ptr<DisplayObject> ch =
- chdef->createDisplayObject(this, 1);
+ assert(def);
+ boost::intrusive_ptr<DisplayObject> ch = def->createDisplayObject(this,
1);
const int depth = 1 + DisplayObject::staticDepthOffset;
placeDisplayObject(ch.get(), depth);
=== modified file 'libcore/Button.cpp'
--- a/libcore/Button.cpp 2009-04-05 07:43:04 +0000
+++ b/libcore/Button.cpp 2009-04-07 12:34:43 +0000
@@ -735,7 +735,7 @@
DisplayObject::staticDepthOffset + 1;
int ch_id = bdef._id;
- DisplayObject* ch = bdef.m_character_def->createDisplayObject(
+ DisplayObject* ch = bdef.m_DefinitionTag->createDisplayObject(
this, ch_id);
ch->setMatrix(mat, true); // update caches
ch->set_cxform(cx);
@@ -898,7 +898,7 @@
int ch_id = bdef._id;
DisplayObject* ch =
- bdef.m_character_def->createDisplayObject(this, ch_id);
+ bdef.m_DefinitionTag->createDisplayObject(this, ch_id);
ch->setMatrix(mat, true); // update caches
// TODO: who cares about color, depth etc.
@@ -931,7 +931,7 @@
int ch_depth = bdef.m_button_layer+DisplayObject::staticDepthOffset+1;
int ch_id = bdef._id;
- DisplayObject* ch = bdef.m_character_def->createDisplayObject(
+ DisplayObject* ch = bdef.m_DefinitionTag->createDisplayObject(
this, ch_id);
ch->setMatrix(mat, true); // update caches
ch->set_cxform(cx);
=== modified file 'libcore/DisplayObject.h'
--- a/libcore/DisplayObject.h 2009-04-05 07:43:04 +0000
+++ b/libcore/DisplayObject.h 2009-04-07 13:13:16 +0000
@@ -16,14 +16,13 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-#ifndef GNASH_CHARACTER_H
-#define GNASH_CHARACTER_H
+#ifndef GNASH_DISPLAY_OBJECT_H
+#define GNASH_DISPLAY_OBJECT_H
#ifdef HAVE_CONFIG_H
#include "gnashconfig.h" // USE_SWFTREE
#endif
-#include "character_def.h"
#include "smart_ptr.h" // GNASH_USE_GC
#include "event_id.h" // for inlines
#include "as_object.h" // for inheritance
@@ -67,9 +66,21 @@
//
/// Derived classes include InteractiveObject, StaticText, Bitmap,
/// Video, and Shape.
+//
+/// All DisplayObjects may be constructed during SWF parsing. In this case
+/// they are constructed using an immutable, non-copyable SWF::DefinitionTag.
+/// This tag should never be changed!
+//
+/// Most DisplayObjects may also be constructed dynamically. In AS3, Bitmaps
+/// and Shapes can be dynamically created. Dynamically-created DisplayObjects
+/// must not have a SWF::DefinitionTag!
+//
+/// The presence of a definition tag may be used to distinguish static from
+/// dynamic DisplayObjects, but tags are not always stored. They are not
+/// stored in most InteractiveObjects because most properties can be
+/// overridden during SWF execution.
class DisplayObject : public as_object
{
-
public:
DisplayObject(DisplayObject* parent, int id);
=== modified file 'libcore/DynamicShape.cpp'
--- a/libcore/DynamicShape.cpp 2009-03-12 07:54:13 +0000
+++ b/libcore/DynamicShape.cpp 2009-04-07 13:26:18 +0000
@@ -15,47 +15,43 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-
-
#include "DynamicShape.h"
-
-#include <algorithm>
-
+#include "render.h"
+
+#include <vector>
namespace gnash {
DynamicShape::DynamicShape()
:
- shape_character_def(),
_currpath(0),
_currfill(0),
_currline(0),
_x(0),
_y(0),
- _changed(0)
+ _changed(false)
{}
void
DynamicShape::clear()
{
- //clear_meshes();
- _paths.clear();
- _fill_styles.clear();
- _line_styles.clear();
- _bound.set_null();
- _currpath=0; // or would point to invalid memory
- _currfill = _currline = 0; // or would point to cleared m_fill_style
and m_line_styles respectively
-
+ _shape.clear();
+ _currpath = 0;
+ _currfill = _currline = 0;
// TODO: worth setting _changed=true ?
}
void
-DynamicShape::add_path(const path& pth)
-{
- _paths.push_back(pth);
- _currpath = &(_paths.back());
- //compute_bound(&m_bound);
+DynamicShape::display(const DisplayObject& inst)
+{
+ render::drawShape(_shape, inst.get_world_cxform(), inst.getWorldMatrix());
+}
+
+void
+DynamicShape::add_path(const Path& pth)
+{
+ _shape.addPath(pth);
+ _currpath = &_shape.currentPath();
}
void
@@ -86,7 +82,7 @@
// TODO: how to know wheter the fill should be set
// as *left* or *right* fill ?
// A quick test shows that *left* always work fine !
- path newPath(_x, _y, _currfill, 0, _currline, true); // new fill start
new subshapes
+ Path newPath(_x, _y, _currfill, 0, _currline, true); // new fill start
new subshapes
add_path(newPath);
}
@@ -102,7 +98,7 @@
// TODO: how to know wheter the fill should be set
// as *left* or *right* fill ?
// A quick test shows that *left* always work fine !
- path newPath(_x, _y, _currfill, 0, _currline, true); // new fill start
new subshapes
+ Path newPath(_x, _y, _currfill, 0, _currline, true); // new fill start
new subshapes
add_path(newPath);
}
@@ -118,7 +114,7 @@
// TODO: how to know wheter the fill should be set
// as *left* or *right* fill ?
// A quick test shows that *left* always work fine !
- path newPath(_x, _y, _currfill, 0, _currline, true); // new fill start
new subshapes
+ Path newPath(_x, _y, _currfill, 0, _currline, true);
add_path(newPath);
}
@@ -128,18 +124,17 @@
// Close any pending filled path
if ( _currpath && _currfill) _currpath->close();
- // The DrawingApiTest.swf file shows we should NOT
- // necessarely end the current fill when starting a new one.
- //endFill();
+ // The DrawingApiTest.swf file shows we should not
+ // end the current fill when starting a new one.
// A quick test shows that *left* always work fine !
// More than that, using a *right* fill seems to break the tests !
- path newPath(_x, _y, _currfill, 0, _currline, newShape);
+ Path newPath(_x, _y, _currfill, 0, _currline, newShape);
add_path(newPath);
}
void
-DynamicShape::finalize()
+DynamicShape::finalize() const
{
// Nothing to do if not changed
if ( ! _changed ) return;
@@ -147,8 +142,8 @@
// Close any pending filled path (_currpath should be last path)
if ( _currpath && _currfill)
{
- assert(!_paths.empty());
- assert(_currpath == &(_paths.back()));
+ assert(!_shape.paths().empty());
+ assert(_currpath == &(_shape.paths().back()));
_currpath->close();
}
@@ -200,19 +195,24 @@
_currpath->drawLineTo(x, y);
// Update bounds
- unsigned thickness = _currline ?
_line_styles[_currline-1].getThickness() : 0;
+ rect bounds = _shape.getBounds();
+
+ unsigned thickness = _currline ?
+ _shape.lineStyles()[_currline-1].getThickness() : 0;
if ( _currpath->size() == 1 ) {
- _currpath->expandBounds(_bound, thickness, swfVersion);
+ _currpath->expandBounds(bounds, thickness, swfVersion);
} else {
- _bound.expand_to_circle(x, y, swfVersion < 8 ? thickness :
thickness/2.0);
+ bounds.expand_to_circle(x, y, swfVersion < 8 ? thickness :
thickness/2.0);
}
+ _shape.setBounds(bounds);
+
// Update current pen position
_x = x;
_y = y;
// Mark as changed
- changed();
+ _changed = true;
}
void
@@ -224,46 +224,42 @@
_currpath->drawCurveTo(cx, cy, ax, ay);
- // Update bounds
- unsigned thickness = _currline ?
_line_styles[_currline-1].getThickness() : 0;
+ rect bounds = _shape.getBounds();
+
+ unsigned thickness = _currline ?
+ _shape.lineStyles()[_currline-1].getThickness() : 0;
if ( _currpath->size() == 1 ) {
- _currpath->expandBounds(_bound, thickness, swfVersion);
+ _currpath->expandBounds(bounds, thickness, swfVersion);
}
else {
- _bound.expand_to_circle(ax, ay,
+ bounds.expand_to_circle(ax, ay,
swfVersion < 8 ? thickness : thickness/2.0);
- _bound.expand_to_circle(cx, cy,
+ bounds.expand_to_circle(cx, cy,
swfVersion < 8 ? thickness : thickness/2.0);
}
+ _shape.setBounds(bounds);
+
// Update current pen position
_x = ax;
_y = ay;
// Mark as changed
- changed();
+ _changed = true;
}
size_t
DynamicShape::add_fill_style(const fill_style& stl)
{
- FillStyles& v = _fill_styles;
-
- // TODO: check if the style is already in our list
- // (needs operator== defined for fill_style)
- v.push_back(stl);
- return v.size(); // 1-based !
+ _shape.addFillStyle(stl);
+ return _shape.fillStyles().size();
}
size_t
DynamicShape::add_line_style(const line_style& stl)
{
- LineStyles& v = _line_styles;
-
- // TODO: check if the style is already in our list
- // (needs operator== defined for line_style)
- v.push_back(stl);
- return v.size(); // 1-based !
+ _shape.addLineStyle(stl);
+ return _shape.lineStyles().size();
}
} // end namespace gnash
=== modified file 'libcore/DynamicShape.h'
--- a/libcore/DynamicShape.h 2009-02-25 22:33:03 +0000
+++ b/libcore/DynamicShape.h 2009-04-07 12:34:43 +0000
@@ -20,26 +20,30 @@
#ifndef GNASH_DYNAMIC_SHAPE_H
#define GNASH_DYNAMIC_SHAPE_H
-#include "shape_character_def.h" // for inheritance
-#include "styles.h" // for cap_style_e and join_style_e enums
-
+#include "fill_style.h"
+#include "styles.h"
+#include "swf/ShapeRecord.h"
namespace gnash {
- class fill_style;
+ class DisplayObject;
}
namespace gnash {
-/// \brief
-/// Represents the outline of one or more shapes, along with
-/// information on fill and line styles.
-class DynamicShape : public shape_character_def
+/// The DynamicShape class represents a mutable shape.
+//
+/// It is provides mutating functions for the SWF::ShapeRecord class that
+/// are used in the Flash drawing API.
+//
+/// DynamicShape objects are not refcounted, so must be stack-allocated or
+/// wrapped in smart pointers.
+class DynamicShape
{
public:
DynamicShape();
- virtual ~DynamicShape() {}
+ ~DynamicShape() {}
/// Remove all paths and style informations
void clear();
@@ -60,14 +64,27 @@
void beginFill(const rgba& color);
/// Start drawing with a linear gradient fill
- void beginLinearGradientFill(const std::vector<gradient_record>& grad,
const SWFMatrix& mat);
+ void beginLinearGradientFill(const std::vector<gradient_record>& grad,
+ const SWFMatrix& mat);
/// Start drawing with a radial gradient fill
- void beginRadialGradientFill(const std::vector<gradient_record>& grad,
const SWFMatrix& mat);
+ void beginRadialGradientFill(const std::vector<gradient_record>& grad,
+ const SWFMatrix& mat);
/// Close an existing filled path, if any.
void endFill();
+ const rect& getBounds() const {
+ return _shape.getBounds();
+ }
+
+ void setBounds(const rect& bounds) {
+ _shape.setBounds(bounds);
+ }
+
+ /// Display a DynamicShape object.
+ void display(const DisplayObject& inst);
+
/// Set current line style and start a new path.
//
/// @param thickness
@@ -122,11 +139,11 @@
///
size_t add_line_style(const line_style& stl);
- // Override from shape_character_def to call ::finalize
+ // Override from DefineShapeTag to call ::finalize
// NOTE: this is not correct in that a call to hitTest should
// not force closing the path being drawn.
- // Instead, the closeup should be "temporary" and int
- // the point_test_local itself (but only for dynamic drawing).
+ // Instead, the closeup should be "temporary" and in
+ // the pointTestLocal itself (but only for dynamic drawing).
// We need to add a testcase for this as we currently have none.
// The testcase would look like this:
//
@@ -139,26 +156,31 @@
// would result in a triangle and a stroke, which should fail the
last hitTest(2,8).
//
//
- bool point_test_local(boost::int32_t x, boost::int32_t y,
- const SWFMatrix& wm)
+ bool pointTestLocal(boost::int32_t x, boost::int32_t y,
+ const SWFMatrix& wm) const
{
finalize();
- return shape_character_def::point_test_local(x, y, wm);
+ return geometry::pointTest(_shape.paths(), _shape.lineStyles(),
x, y,
+ wm);
}
+ const SWF::ShapeRecord& shapeRecord() const {
+ return _shape;
+ }
+
/// Add a path, updating _currpath and recomputing bounds
//
/// TODO: make private? Only current user is BitmapMovieDefinition.
/// It needs this function unless we provide a mean to add a
/// Bitmap-Filled path
///
- void add_path(const path& pth);
+ void add_path(const Path& pth);
/// Always call this function before displaying !
//
/// It will take care of cleaning up the drawing
/// and setting up correct fill styles
- void finalize();
+ void finalize() const;
private:
@@ -170,10 +192,9 @@
/// for origin, fill and line styles.
///
/// If newShape is true the new shape will start a new subshape.
- ///
void startNewPath(bool newShape);
- path* _currpath;
+ Path* _currpath;
size_t _currfill;
@@ -185,10 +206,12 @@
// Current pen Y position
boost::int32_t _y;
- // Call this function when the drawing changes !
- void changed() { _changed = true; }
+ mutable bool _changed;
- bool _changed;
+ /// The actual SWF::ShapeRecord wrapped by this class.
+ //
+ /// Mutable for lazy finalization.
+ mutable SWF::ShapeRecord _shape;
};
} // end namespace gnash
=== modified file 'libcore/ExportableResource.h'
--- a/libcore/ExportableResource.h 2009-02-25 22:33:03 +0000
+++ b/libcore/ExportableResource.h 2009-04-07 12:34:43 +0000
@@ -29,7 +29,7 @@
/// A class for SWF resources that may be exported
//
-/// They are: character_def, sound_sample, and font.
+/// They are: DefinitionTag, sound_sample, and font.
/// These may be held in the export map of a SWFMovieDefinition.
class ExportableResource : public ref_counted
{
=== modified file 'libcore/Font.cpp'
--- a/libcore/Font.cpp 2009-04-03 09:18:40 +0000
+++ b/libcore/Font.cpp 2009-04-07 11:14:10 +0000
@@ -23,11 +23,12 @@
#include "smart_ptr.h" // GNASH_USE_GC
#include "Font.h"
#include "log.h"
-#include "shape_character_def.h"
+#include "ShapeRecord.h"
#include "DefineFontTag.h"
#include "FreetypeGlyphsProvider.h"
#include <utility> // for std::make_pair
+#include <memory>
namespace gnash {
@@ -54,28 +55,27 @@
Font::GlyphInfo::GlyphInfo()
:
- glyph(),
advance(0)
{}
-Font::GlyphInfo::GlyphInfo(boost::intrusive_ptr<shape_character_def> glyph,
+Font::GlyphInfo::GlyphInfo(std::auto_ptr<SWF::ShapeRecord> glyph,
float advance)
:
- glyph(glyph.get()),
+ glyph(glyph.release()),
advance(advance)
{}
Font::GlyphInfo::GlyphInfo(const GlyphInfo& o)
:
- glyph(o.glyph.get()),
+ glyph(o.glyph),
advance(o.advance)
{}
+
#ifdef GNASH_USE_GC
void
Font::GlyphInfo::markReachableResources() const
{
- if ( glyph ) glyph->setReachable();
}
#endif
@@ -109,7 +109,7 @@
{
}
-shape_character_def*
+SWF::ShapeRecord*
Font::get_glyph(int index, bool embedded) const
{
// What to do if embedded is true and this is a
@@ -296,10 +296,9 @@
float advance;
// Get the vectorial glyph
- boost::intrusive_ptr<shape_character_def> sh =
- _ftProvider->getGlyph(code, advance);
+ std::auto_ptr<SWF::ShapeRecord> sh = _ftProvider->getGlyph(code, advance);
- if (!sh) {
+ if (!sh.get()) {
log_error("Could not create shape "
"glyph for DisplayObject code %u (%c) with "
"device font %s (%p)", code, code, _name,
@@ -371,8 +370,6 @@
/// Mark reachable resources (for the GC)
//
/// Reachable resources are:
-/// - shape_character_defs (vector glyphs, devide and embeded)
-///
void
Font::markReachableResources() const
{
=== modified file 'libcore/Font.h'
--- a/libcore/Font.h 2009-04-03 09:18:40 +0000
+++ b/libcore/Font.h 2009-04-07 12:34:43 +0000
@@ -29,13 +29,14 @@
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/cstdint.hpp>
+#include <memory>
#include <vector>
#include <map>
namespace gnash {
- class shape_character_def;
class FreetypeGlyphsProvider;
namespace SWF {
+ class ShapeRecord;
class DefineFontTag;
}
}
@@ -93,7 +94,6 @@
///
/// @param italic
/// Whether to use the italic variant of the font.
- ///
Font(const std::string& name, bool bold=false, bool italic=false);
~Font();
@@ -110,7 +110,6 @@
///
/// @param italic
/// Italic flag
- ///
bool matches(const std::string& name, bool bold, bool italic) const;
void testInvariant()
@@ -120,23 +119,22 @@
/// Get glyph by index.
//
/// @param glyph_index
- /// Index of the glyph. See get_glyph_index() to obtain by
DisplayObject code.
+ /// Index of the glyph. See get_glyph_index() to obtain by
character code.
///
/// @param embedded
/// If true, queries the 'embedded' glyphs table,
/// otherwise, looks in the 'device' font table.
///
/// @return
- /// The glyph outline, or NULL if out of range.
- /// (would be a programming error most likely)
- ///
- ///
- shape_character_def* get_glyph(int glyph_index, bool embedded) const;
+ /// The glyph outline, or NULL if out of range. (would be a
+ /// programming error most likely). The ShapeRecord is owned by
+ /// the Font class.
+ SWF::ShapeRecord* get_glyph(int glyph_index, bool embedded) const;
/// Get name of this font.
const std::string& name() const { return _name; }
- /// Return the glyph index for a given DisplayObject code
+ /// Return the glyph index for a given character code
//
/// @param code
/// Character code to fetch the corresponding glyph index of.
@@ -158,7 +156,7 @@
/// Return the advance value for the given glyph index
//
/// @param glyph_index
- /// Index of the glyph. See get_glyph_index() to obtain by
DisplayObject code.
+ /// Index of the glyph. See get_glyph_index() to obtain by
character code.
///
/// @param embedded
/// If true, queries the 'embedded' glyphs table,
@@ -215,18 +213,19 @@
// no glyph, default textured glyph, 0 advance
GlyphInfo();
- // given glyph and advance, default textured glyph
- GlyphInfo(boost::intrusive_ptr<shape_character_def> glyph,
- float advance);
+ /// Construct default textured glyph
+ //
+ /// Takes ownership of the SWF::ShapeRecord.
+ GlyphInfo(std::auto_ptr<SWF::ShapeRecord> glyph, float advance);
- GlyphInfo(const GlyphInfo&);
+ GlyphInfo(const GlyphInfo& o);
#ifdef GNASH_USE_GC
/// Mark any glyph and texture glyph resources as reachable
void markReachableResources() const;
#endif
- boost::intrusive_ptr<shape_character_def> glyph;
+ boost::shared_ptr<SWF::ShapeRecord> glyph;
float advance;
};
@@ -322,7 +321,7 @@
/// Mark reachable resources (for the GC)
//
/// Reachable resources are:
- /// - shape_character_defs (vector glyphs)
+ /// - DefineShapeTags (vector glyphs)
///
void markReachableResources() const;
#endif // GNASH_USE_GC
=== modified file 'libcore/FreetypeGlyphsProvider.cpp'
--- a/libcore/FreetypeGlyphsProvider.cpp 2009-04-03 09:18:40 +0000
+++ b/libcore/FreetypeGlyphsProvider.cpp 2009-04-07 12:23:59 +0000
@@ -25,7 +25,7 @@
#include "GnashImage.h" // for create_alpha
#include "GnashException.h"
#include "render.h"
-#include "DynamicShape.h"
+#include "ShapeRecord.h"
#include "log.h"
#ifdef USE_FREETYPE
@@ -70,24 +70,39 @@
//
/// See FT_Outline_Decompose function of freetype2 lib
///
-class OutlineWalker {
+class OutlineWalker
+{
public:
/// Create an outline walker drawing to the given DynamiShape
//
/// @param sh
- /// The DynamiShape to draw to. Externally owned.
+ /// The DynamicShape to draw to. Externally owned.
///
/// @param scale
/// The scale to apply to coordinates.
/// This is to match an arbitrary EM
///
- OutlineWalker(DynamicShape& sh, float scale)
+ OutlineWalker(SWF::ShapeRecord& sh, float scale)
:
- _sh(sh),
- _scale(scale)
- {}
+ _shape(sh),
+ _scale(scale),
+ _currPath(0),
+ _x(0),
+ _y(0)
+ {
+ fill_style f;
+ f.setSolid(rgba(255, 255, 255, 255));
+ _shape.addFillStyle(f);
+ _shape.addPath(Path(_x, _y, 1, 0, 0, true));
+ _currPath = &_shape.currentPath();
+ }
+
+ void finish()
+ {
+ _currPath->close();
+ }
~OutlineWalker() {}
@@ -121,26 +136,25 @@
/// falling in the middle of the two control points.
///
static int
- walkCubicTo(FT_CONST FT_Vector* ctrl1, FT_CONST FT_Vector* ctrl2,
FT_CONST FT_Vector* to, void* ptr)
+ walkCubicTo(FT_CONST FT_Vector* ctrl1, FT_CONST FT_Vector* ctrl2,
+ FT_CONST FT_Vector* to, void* ptr)
{
OutlineWalker* walker = static_cast<OutlineWalker*>(ptr);
return walker->cubicTo(ctrl1, ctrl2, to);
}
private:
-
- DynamicShape& _sh;
-
- float _scale;
-
- int moveTo(const FT_Vector* to)
+
+ int moveTo(const FT_Vector* to)
{
#ifdef DEBUG_OUTLINE_DECOMPOSITION
log_debug("moveTo: %ld,%ld", to->x, to->y);
#endif
- boost::int32_t x = static_cast<boost::int32_t>(to->x * _scale);
- boost::int32_t y = static_cast<boost::int32_t>(to->y * _scale);
- _sh.moveTo(x, -y);
+ _x = static_cast<boost::int32_t>(to->x * _scale);
+ _y = - static_cast<boost::int32_t>(to->y * _scale);
+ _currPath->close();
+ _shape.addPath(Path(_x, _y, 1, 0, 0, false));
+ _currPath = &_shape.currentPath();
return 0;
}
@@ -149,10 +163,10 @@
#ifdef DEBUG_OUTLINE_DECOMPOSITION
log_debug("lineTo: %ld,%ld", to->x, to->y);
#endif
- static const int swfVersion = 6; // we have no thickness, so 6
is fine
- boost::int32_t x = static_cast<boost::int32_t>(to->x * _scale);
- boost::int32_t y = static_cast<boost::int32_t>(to->y * _scale);
- _sh.lineTo(x, -y, swfVersion);
+ _x = static_cast<boost::int32_t>(to->x * _scale);
+ _y = - static_cast<boost::int32_t>(to->y * _scale);
+ _currPath->drawLineTo(_x, _y);
+ expandBounds(_x, _y);
return 0;
}
@@ -161,12 +175,12 @@
#ifdef DEBUG_OUTLINE_DECOMPOSITION
log_debug("conicTo: %ld,%ld %ld,%ld", ctrl->x, ctrl->y, to->x,
to->y);
#endif
- boost::int32_t x1 = static_cast<boost::int32_t>(ctrl->x * _scale);
- boost::int32_t y1 = static_cast<boost::int32_t>(ctrl->y * _scale);
- boost::int32_t x2 = static_cast<boost::int32_t>(to->x * _scale);
- boost::int32_t y2 = static_cast<boost::int32_t>(to->y * _scale);
- static const int swfVersion = 6; // we have no thickness, so 6 is fine
- _sh.curveTo(x1, -y1, x2, -y2, swfVersion);
+ boost::int32_t x1 = static_cast<boost::int32_t>(ctrl->x * _scale);
+ boost::int32_t y1 = static_cast<boost::int32_t>(ctrl->y * _scale);
+ _x = static_cast<boost::int32_t>(to->x * _scale);
+ _y = - static_cast<boost::int32_t>(to->y * _scale);
+ _currPath->drawCurveTo(x1, -y1, _x, _y);
+ expandBounds(x1, -y1, _x, _y);
return 0;
}
@@ -174,21 +188,47 @@
cubicTo(const FT_Vector* ctrl1, const FT_Vector* ctrl2, const
FT_Vector* to)
{
#ifdef DEBUG_OUTLINE_DECOMPOSITION
- log_debug("cubicTo: %ld,%ld %ld,%ld %ld,%ld", ctrl1->x,
ctrl1->y, ctrl2->x, ctrl2->y, to->x, to->y);
+ log_debug("cubicTo: %ld,%ld %ld,%ld %ld,%ld", ctrl1->x,
+ ctrl1->y, ctrl2->x, ctrl2->y, to->x, to->y);
#endif
-
float x = ctrl1->x + ( (ctrl2->x - ctrl1->x) * 0.5 );
float y = ctrl1->y + ( (ctrl2->y - ctrl1->y) * 0.5 );
boost::int32_t x1 = static_cast<boost::int32_t>(x * _scale);
boost::int32_t y1 = static_cast<boost::int32_t>(y * _scale);
- boost::int32_t x2 = static_cast<boost::int32_t>(to->x * _scale);
- boost::int32_t y2 = static_cast<boost::int32_t>(to->y * _scale);
+ _x = static_cast<boost::int32_t>(to->x * _scale);
+ _y = - static_cast<boost::int32_t>(to->y * _scale);
- static const int swfVersion = 6; // we have no thickness, so 6
is fine
- _sh.curveTo(x1, -y1, x2, -y2, swfVersion);
- return 0;
+ _currPath->drawCurveTo(x1, -y1, _x, _y);
+ expandBounds(x1, -y1, _x, _y);
+ return 0;
}
-
+
+ void expandBounds(int x, int y) {
+ rect bounds = _shape.getBounds();
+ if (_currPath->size() == 1) _currPath->expandBounds(bounds, 0, 6);
+ else {
+ bounds.expand_to_circle(x, y, 0);
+ }
+ _shape.setBounds(bounds);
+ }
+
+ void expandBounds(int ax, int ay, int cx, int cy) {
+ rect bounds = _shape.getBounds();
+ if (_currPath->size() == 1) _currPath->expandBounds(bounds, 0, 6);
+ else {
+ bounds.expand_to_circle(ax, ay, 0);
+ bounds.expand_to_circle(cx, cy, 0);
+ }
+ _shape.setBounds(bounds);
+ }
+
+ SWF::ShapeRecord& _shape;
+
+ const float _scale;
+
+ Path* _currPath;
+
+ boost::int32_t _x, _y;
};
@@ -402,16 +442,18 @@
#endif // ndef USE_FREETYPE
#ifdef USE_FREETYPE
-boost::intrusive_ptr<shape_character_def>
+std::auto_ptr<SWF::ShapeRecord>
FreetypeGlyphsProvider::getGlyph(boost::uint16_t code, float& advance)
{
- boost::intrusive_ptr<DynamicShape> sh;
-
- FT_Error error = FT_Load_Char(m_face, code,
FT_LOAD_NO_BITMAP|FT_LOAD_NO_SCALE);
- if ( error != 0 )
- {
- log_error("Error loading freetype outline glyph for char '%c'
(error: %d)", code, error);
- return sh.get();
+ std::auto_ptr<SWF::ShapeRecord> glyph;
+
+ FT_Error error = FT_Load_Char(m_face, code, FT_LOAD_NO_BITMAP |
+ FT_LOAD_NO_SCALE);
+
+ if (error) {
+ log_error("Error loading freetype outline glyph for char '%c' "
+ "(error: %d)", code, error);
+ return glyph;
}
// Scale advance by current scale, to match expected output coordinate
space
@@ -431,22 +473,13 @@
static_cast<char>((gf>>16)&0xff),
static_cast<char>((gf>>8)&0xff),
static_cast<char>(gf&0xff));
- return 0;
+ return glyph;
}
- //assert(m_face->glyph->format == FT_GLYPH_FORMAT_OUTLINE);
FT_Outline* outline = &(m_face->glyph->outline);
- //FT_BBox glyphBox;
- //FT_Outline_Get_BBox(outline, &glyphBox);
- //rect r(glyphBox.xMin, glyphBox.yMin, glyphBox.xMax, glyphBox.yMax);
- //log_debug("Glyph for DisplayObject '%c' has computed bounds %s",
code, r.toString().c_str());
-
- sh = new DynamicShape();
- sh->beginFill(rgba(255, 255, 255, 255));
-
FT_Outline_Funcs walk;
- walk.move_to = OutlineWalker::walkMoveTo;
+ walk.move_to = OutlineWalker::walkMoveTo;
walk.line_to = OutlineWalker::walkLineTo;
walk.conic_to = OutlineWalker::walkConicTo;
walk.cubic_to = OutlineWalker::walkCubicTo;
@@ -456,8 +489,10 @@
#ifdef DEBUG_OUTLINE_DECOMPOSITION
log_debug("Decomposing glyph outline for DisplayObject %u", code);
#endif
+
+ glyph.reset(new SWF::ShapeRecord);
- OutlineWalker walker(*sh, scale);
+ OutlineWalker walker(*glyph, scale);
FT_Outline_Decompose(outline, &walk, &walker);
#ifdef DEBUG_OUTLINE_DECOMPOSITION
@@ -466,10 +501,13 @@
code, bound.toString());
#endif
- return sh.get();
+ walker.finish();
+
+ return glyph;
}
#else // ndef(USE_FREETYPE)
-boost::intrusive_ptr<shape_character_def>
+
+SWF::ShapeRecord*
FreetypeGlyphsProvider::getGlyph(boost::uint16_t, float& advance)
{
abort(); // should never be called...
=== modified file 'libcore/FreetypeGlyphsProvider.h'
--- a/libcore/FreetypeGlyphsProvider.h 2009-04-03 09:18:40 +0000
+++ b/libcore/FreetypeGlyphsProvider.h 2009-04-07 12:34:43 +0000
@@ -35,7 +35,9 @@
// Forward declarations
namespace gnash {
- class shape_character_def;
+ namespace SWF {
+ class ShapeRecord;
+ }
}
@@ -50,7 +52,7 @@
/// but I think the actual size could change between glyphs (see the 'box'
/// parameter of getRenderedGlyph() method).
///
-/// Vectorial glyphs are instances of a shape_character_def, same class
+/// Vectorial glyphs are instances of a DefineShapeTag, same class
/// resulting from parsing of embedded fonts.
///
class FreetypeGlyphsProvider
@@ -96,11 +98,12 @@
/// Output parameter... units to advance horizontally from this
/// glyph to the next, in unitsPerEM() units.
///
- /// @return A shape_character_def in unitsPerEM() coordinates,
+ /// @return A DefineShapeTag in unitsPerEM() coordinates,
/// or a NULL pointer if the given DisplayObject code
/// doesn't exist in this font.
///
- boost::intrusive_ptr<shape_character_def> getGlyph(boost::uint16_t
code, float& advance);
+ std::auto_ptr<SWF::ShapeRecord> getGlyph(boost::uint16_t code,
+ float& advance);
/// Return the number of units of glyphs EM
//
=== added file 'libcore/Geometry.cpp'
--- a/libcore/Geometry.cpp 1970-01-01 00:00:00 +0000
+++ b/libcore/Geometry.cpp 2009-04-07 13:44:07 +0000
@@ -0,0 +1,301 @@
+// 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 <cmath>
+#include "Geometry.h"
+
+namespace gnash {
+namespace geometry {
+
+namespace {
+
+// TODO: this should be moved to libgeometry or something
+// Finds the quadratic bezier curve crossings with the line Y.
+// The function can have zero, one or two solutions (cross1, cross2). The
+// return value of the function is the number of solutions.
+// x0, y0 = start point of the curve
+// x1, y1 = end point of the curve (anchor, aka ax|ay)
+// cx, cy = control point of the curve
+// If there are two crossings, cross1 is the nearest to x0|y0 on the curve.
+int curve_x_crossings(float x0, float y0, float x1, float y1,
+ float cx, float cy, float y, float &cross1, float &cross2)
+{
+ int count=0;
+
+ // check if any crossings possible
+ if ( ((y0 < y) && (y1 < y) && (cy < y))
+ || ((y0 > y) && (y1 > y) && (cy > y)) )
+ {
+ // all above or below -- no possibility of crossing
+ return 0;
+ }
+
+ // Quadratic bezier is:
+ //
+ // p = (1-t)^2 * a0 + 2t(1-t) * c + t^2 * a1
+ //
+ // We need to solve for x at y.
+
+ // Use the quadratic formula.
+
+ // Numerical Recipes suggests this variation:
+ // q = -0.5 [b +sgn(b) sqrt(b^2 - 4ac)]
+ // x1 = q/a; x2 = c/q;
+
+ float A = y1 + y0 - 2 * cy;
+ float B = 2 * (cy - y0);
+ float C = y0 - y;
+
+ float rad = B * B - 4 * A * C;
+
+ if (rad < 0)
+ {
+ return 0;
+ }
+ else
+ {
+ float q;
+ float sqrt_rad = std::sqrt(rad);
+ if (B < 0)
+ {
+ q = -0.5f * (B - sqrt_rad);
+ }
+ else
+ {
+ q = -0.5f * (B + sqrt_rad);
+ }
+
+ // The old-school way.
+ // float t0 = (-B + sqrt_rad) / (2 * A);
+ // float t1 = (-B - sqrt_rad) / (2 * A);
+
+ if (q != 0)
+ {
+ float t1 = C / q;
+ if (t1 >= 0 && t1 < 1)
+ {
+ float x_at_t1 =
+ x0 + 2 * (cx - x0) * t1 + (x1 + x0 - 2 * cx) * t1 * t1;
+
+ count++;
+ assert(count==1);
+ cross1 = x_at_t1; // order is important!
+ }
+ }
+
+ if (A != 0)
+ {
+ float t0 = q / A;
+ if (t0 >= 0 && t0 < 1)
+ {
+ float x_at_t0 =
+ x0 + 2 * (cx - x0) * t0 + (x1 + x0 - 2 * cx) * t0 * t0;
+
+ count++;
+ // order is important!
+ if (count == 2) cross2 = x_at_t0;
+ else cross1 = x_at_t0;
+ }
+ }
+
+ }
+
+ return count;
+}
+
+} // anonymous namespace
+
+bool
+pointTest(const std::vector<Path>& paths,
+ const std::vector<line_style>& lineStyles, boost::int32_t x,
+ boost::int32_t y, const SWFMatrix& wm)
+{
+
+ /*
+ Principle:
+ For the fill of the shape, we project a ray from the test point to the left
+ side of the shape counting all crossings. When a line or curve segment is
+ crossed we add 1 if the left fill style is set. Regardless of the left fill
+ style we subtract 1 from the counter then the right fill style is set.
+ This is true when the line goes in downward direction. If it goes upward,
+ the fill styles are reversed.
+
+ The final counter value reveals if the point is inside the shape (and
+ depends on filling rule, see below).
+ This method should not depend on subshapes and work for some malformed
+ shapes situations:
+ - wrong fill side (eg. left side set for a clockwise drawen rectangle)
+ - intersecting paths
+ */
+ point pt(x, y);
+
+ // later we will need non-zero for glyphs... (TODO)
+ bool even_odd = true;
+
+ unsigned npaths = paths.size();
+ int counter = 0;
+
+ // browse all paths
+ for (unsigned pno=0; pno<npaths; pno++)
+ {
+ const Path& pth = paths[pno];
+ unsigned nedges = pth.m_edges.size();
+
+ float next_pen_x = pth.ap.x;
+ float next_pen_y = pth.ap.y;
+ float pen_x, pen_y;
+
+ if (pth.m_new_shape)
+ {
+ if (( even_odd && (counter % 2) != 0) ||
+ (!even_odd && (counter != 0)) )
+ {
+ // the point is inside the previous subshape, so exit now
+ return true;
+ }
+
+ counter=0;
+ }
+ if (pth.empty()) continue;
+
+ // If the path has a line style, check for strokes there
+ if (pth.m_line != 0 )
+ {
+ assert(lineStyles.size() >= pth.m_line);
+ const line_style& ls = lineStyles[pth.m_line-1];
+ double thickness = ls.getThickness();
+ if (! thickness )
+ {
+ thickness = 20; // at least ONE PIXEL thick.
+ }
+ else if ((!ls.scaleThicknessVertically()) &&
+ (!ls.scaleThicknessHorizontally()) )
+ {
+ // TODO: pass the SWFMatrix to withinSquareDistance instead ?
+ double xScale = wm.get_x_scale();
+ double yScale = wm.get_y_scale();
+ thickness *= std::max(xScale, yScale);
+ }
+ else if (ls.scaleThicknessVertically() !=
+ ls.scaleThicknessHorizontally())
+ {
+ LOG_ONCE(log_unimpl("Collision detection for "
+ "unidirectionally scaled strokes"));
+ }
+
+ double dist = thickness / 2.0;
+ double sqdist = dist * dist;
+ if (pth.withinSquareDistance(pt, sqdist))
+ return true;
+ }
+
+ // browse all edges of the path
+ for (unsigned eno=0; eno<nedges; eno++)
+ {
+ const Edge& edg = pth.m_edges[eno];
+ pen_x = next_pen_x;
+ pen_y = next_pen_y;
+ next_pen_x = edg.ap.x;
+ next_pen_y = edg.ap.y;
+
+ float cross1, cross2;
+ int dir1, dir2 = 0; // +1 = downward, -1 = upward
+ int crosscount = 0;
+
+ if (edg.straight())
+ {
+ // ignore horizontal lines
+ // TODO: better check for small difference?
+ if (edg.ap.y == pen_y)
+ {
+ continue;
+ }
+ // does this line cross the Y coordinate?
+ if ( ((pen_y <= y) && (edg.ap.y >= y))
+ || ((pen_y >= y) && (edg.ap.y <= y)) )
+ {
+
+ // calculate X crossing
+ cross1 = pen_x + (edg.ap.x - pen_x) *
+ (y - pen_y) / (edg.ap.y - pen_y);
+
+ if (pen_y > edg.ap.y)
+ dir1 = -1; // upward
+ else
+ dir1 = +1; // downward
+
+ crosscount = 1;
+ }
+ else
+ {
+ // no crossing found
+ crosscount = 0;
+ }
+ }
+ else
+ {
+ // ==> curve case
+ crosscount = curve_x_crossings(pen_x, pen_y, edg.ap.x,
edg.ap.y,
+ edg.cp.x, edg.cp.y, y, cross1, cross2);
+ dir1 = pen_y > y ? -1 : +1;
+ dir2 = dir1 * (-1); // second crossing always in opposite dir.
+ } // curve
+
+ // ==> we have now:
+ // - one (cross1) or two (cross1, cross2) ray crossings (X
+ // coordinate)
+ // - dir1/dir2 tells the direction of the crossing
+ // (+1 = downward, -1 = upward)
+ // - crosscount tells the number of crossings
+
+ // need at least one crossing
+ if (crosscount == 0)
+ {
+ continue;
+ }
+
+ bool touched = false;
+
+ // check first crossing
+ if (cross1 <= x)
+ {
+ if (pth.m_fill0 > 0) counter += dir1;
+ if (pth.m_fill1 > 0) counter -= dir1;
+
+ touched = true;
+ }
+
+ // check optional second crossing (only possible with curves)
+ if ( (crosscount > 1) && (cross2 <= x) )
+ {
+ if (pth.m_fill0 > 0) counter += dir2;
+ if (pth.m_fill1 > 0) counter -= dir2;
+
+ touched = true;
+ }
+
+ }// for edge
+ } // for path
+
+ return ( (even_odd && (counter % 2) != 0) ||
+ (!even_odd && (counter != 0)) );
+}
+
+} // namespace geometry
+} // namespace gnash
+
+
=== modified file 'libcore/Geometry.h'
--- a/libcore/Geometry.h 2009-03-10 20:43:50 +0000
+++ b/libcore/Geometry.h 2009-04-07 12:34:43 +0000
@@ -15,12 +15,13 @@
// 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 "styles.h"
+#include "log.h"
#include <vector> // for path composition
#include <cmath> // sqrt
@@ -28,54 +29,56 @@
// Forward declarations
namespace gnash {
- class rect;
+ 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:
-
+/// \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
+ point ap; // anchor point, TWIPS
Edge()
:
- cp(0, 0), ap(0, 0)
- { };
+ 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(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)
- { }
+ :
+ cp(from.cp),
+ ap(from.ap)
+ {}
Edge(const point& ncp, const point& nap)
- :
- cp(ncp), ap(nap)
- { }
+ :
+ cp(ncp),
+ ap(nap)
+ {}
- bool isStraight() const
+ bool straight() 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)
+ void transform(const SWFMatrix& mat)
{
mat.transform(ap);
mat.transform(cp);
@@ -96,7 +99,8 @@
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 );
+ double u = ( (double)(pdx) * dx + (double)(pdy) * dy ) /
+ ( (double)(dx)*dx + (double)(dy)*dy );
if (u <= 0)
{
@@ -130,9 +134,7 @@
///
static point
- pointOnCurve(const point& A,
- const point& C,
- const point& B, float t)
+ pointOnCurve(const point& A, const point& C, const point& B, float t)
{
point Q1(A, C, t);
point Q2(C, B, t);
@@ -151,20 +153,19 @@
/// @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)
+ const point& C,
+ const point& B,
+ const point& p, float t)
{
- return p.squareDistance( pointOnCurve(A, C, B, 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:
+};
+
+
+/// 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;
@@ -189,53 +190,53 @@
/// Default constructor
//
/// @param newShape
- /// True if this path starts a new subshape
+ /// True if this path starts a new subshape
///
Path(bool newShape = false)
- :
- m_new_shape(newShape)
+ :
+ m_new_shape(newShape)
{
- reset(0, 0, 0, 0, 0);
+ 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)
+ :
+ 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
+ /// X coordinate of path origin in TWIPS
///
/// @param ay
- /// Y coordinate in path origin in TWIPS
+ /// Y coordinate in path origin in TWIPS
///
/// @param fill0
- /// Fill style index for left fill (1-based).
- /// Zero means NO style.
+ /// 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.
+ /// 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.
+ /// Line style index for right fill (1-based).
+ /// Zero means NO style.
///
/// @param newShape
- /// True if this path starts a new subshape
+ /// 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)
+ unsigned fill0, unsigned fill1, unsigned line,
+ bool newShape)
+ :
+ m_new_shape(newShape)
{
reset(ax, ay, fill0, fill1, line);
}
@@ -243,22 +244,22 @@
/// Re-initialize a path, maintaining the "new shape" flag untouched
//
/// @param ax
- /// X coordinate of path origin in TWIPS
+ /// X coordinate of path origin in TWIPS
///
/// @param ay
- /// Y coordinate in path origin in TWIPS
+ /// Y coordinate in path origin in TWIPS
///
/// @param fill0
- /// Fill style index for left fill
+ /// Fill style index for left fill
///
/// @param fill1
- /// Fill style index for right fill
+ /// Fill style index for right fill
//
/// @param line
- /// Line style index for right fill
+ /// Line style index for right fill
///
- void reset(boost::int32_t ax, boost::int32_t ay,
- unsigned fill0, unsigned fill1, unsigned line)
+ 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;
@@ -268,32 +269,26 @@
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();
+ assert(empty());
}
/// Expand given rect to include bounds of this path
//
/// @param r
- /// The rectangle to expand with our own bounds
+ /// 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-
+ /// 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.
+ /// SWF version to use.
///
void
expandBounds(rect& r, unsigned int thickness, int swfVersion) const
{
- const Path& p = *this;
+ const Path& p = *this;
size_t nedges = m_edges.size();
if ( ! nedges ) return; // this path adds nothing
@@ -302,7 +297,7 @@
{
// 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.
+ // bounds using the drawing API.
unsigned int radius = swfVersion < 8 ? thickness : thickness/2;
r.expand_to_circle(ap.x, ap.y, radius);
@@ -334,10 +329,10 @@
/// and expressed in TWIPS.
///
/// @param x
- /// X coordinate in TWIPS
+ /// X coordinate in TWIPS
///
/// @param y
- /// Y coordinate in TWIPS
+ /// Y coordinate in TWIPS
///
void
drawLineTo(boost::int32_t dx, boost::int32_t dy)
@@ -351,16 +346,16 @@
/// expressed in TWIPS.
///
/// @param cx
- /// Control point's X coordinate.
+ /// Control point's X coordinate.
///
/// @param cy
- /// Control point's Y coordinate.
+ /// Control point's Y coordinate.
///
/// @param ax
- /// Anchor point's X ordinate.
+ /// Anchor point's X ordinate.
///
/// @param ay
- /// Anchor point's Y ordinate.
+ /// Anchor point's Y ordinate.
///
void
drawCurveTo(boost::int32_t cdx, boost::int32_t cdy, boost::int32_t adx,
boost::int32_t ady)
@@ -379,20 +374,14 @@
/// Returns true if the last and the first point of the path match
- bool isClosed() const
+ bool isClosed() const
{
- if ( m_edges.empty() )
- {
- return true;
- }
- else
- {
- return m_edges.back().ap == ap;
- }
+ if (m_edges.empty()) return true;
+ return m_edges.back().ap == ap;
}
/// Close this path with a straight line, if not already closed
- void close()
+ void close()
{
if ( m_edges.empty() ) return;
@@ -414,94 +403,93 @@
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;
+ 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.straight())
+ {
+ 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)
+ 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);
- }
- }
+ 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()
+ void setNewShape()
{
- m_new_shape=true;
+ m_new_shape=true;
}
/// Return true if this path starts a new (sub)shape
- bool getNewShape() const
+ bool getNewShape() const
{
return m_new_shape;
}
/// Return true if this path contains no edges
- bool empty() const
+ bool empty() const
{
- return is_empty();
+ return m_edges.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.
+ /// The fill index (1-based).
+ /// When this path is added to a DefineShapeTag,
+ /// 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)
{
@@ -516,11 +504,11 @@
/// 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.
+ /// The fill index (1-based).
+ /// When this path is added to a DefineShapeTag,
+ /// 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)
{
@@ -535,11 +523,11 @@
/// 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.
+ /// The line_style index (1-based).
+ /// When this path is added to a DefineShapeTag,
+ /// 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)
{
@@ -574,16 +562,22 @@
{
return m_new_shape;
}
-
- }; // end of class Path
-
-
- typedef Edge edge;
- typedef Path path;
-
-} // end namespace gnash
-
-#endif // GNASH_SHAPE_H
+
+}; // end of class Path
+
+namespace geometry
+{
+
+bool pointTest(const std::vector<Path>& paths,
+ const std::vector<line_style>& lineStyles, boost::int32_t x,
+ boost::int32_t y, const SWFMatrix& wm);
+
+} // namespace geometry
+
+
+} // namespace gnash
+
+#endif // GNASH_GEOMETRY_H
// Local Variables:
=== modified file 'libcore/InteractiveObject.h'
--- a/libcore/InteractiveObject.h 2009-04-04 15:35:18 +0000
+++ b/libcore/InteractiveObject.h 2009-04-07 13:13:16 +0000
@@ -20,12 +20,10 @@
#include "smart_ptr.h" // GNASH_USE_GC
#include "DisplayObject.h" // for inheritance
-#include "character_def.h"
#include <cassert>
namespace gnash {
- class character_def;
class StaticText;
namespace SWF {
class TextRecord;
=== modified file 'libcore/Makefile.am'
--- a/libcore/Makefile.am 2009-04-04 15:35:18 +0000
+++ b/libcore/Makefile.am 2009-04-07 12:45:25 +0000
@@ -61,9 +61,11 @@
DisplayObject.cpp \
CharacterProxy.cpp \
cxform.cpp \
+ Geometry.cpp \
DynamicShape.cpp \
Bitmap.cpp \
Shape.cpp \
+ MorphShape.cpp \
StaticText.cpp \
TextField.cpp \
BlurFilter.cpp \
@@ -91,11 +93,14 @@
swf/DefineButtonTag.cpp \
swf/DefineFontTag.cpp \
swf/VideoFrameTag.cpp \
+ swf/ShapeRecord.cpp \
swf/SoundInfoRecord.cpp \
swf/TextRecord.cpp \
swf/tag_loaders.cpp \
swf/DefineFontAlignZonesTag.cpp \
+ swf/DefineShapeTag.cpp \
swf/DefineEditTextTag.cpp \
+ swf/DefineMorphShapeTag.cpp \
swf/CSMTextSettingsTag.cpp \
swf/PlaceObject2Tag.cpp \
swf/RemoveObjectTag.cpp \
@@ -122,7 +127,6 @@
noinst_HEADERS = \
Property.h \
PropertyList.h \
- Sprite.h \
StreamProvider.h \
StringPredicates.h \
URLAccessManager.h \
@@ -164,6 +168,7 @@
Font.h \
fontlib.h \
Shape.h \
+ MorphShape.h \
StaticText.h \
InteractiveObject.h \
gnash.h \
@@ -190,6 +195,10 @@
swf/ControlTag.h \
swf/DefineFontAlignZonesTag.h \
swf/CSMTextSettingsTag.h \
+ swf/DefineShapeTag.h \
+ swf/DefinitionTag.h \
+ swf/DefineMorphShapeTag.h \
+ swf/ShapeRecord.h \
swf/SoundInfoRecord.h \
swf/TextRecord.h \
swf/DefineButtonSoundTag.h \
=== added file 'libcore/MorphShape.cpp'
--- a/libcore/MorphShape.cpp 1970-01-01 00:00:00 +0000
+++ b/libcore/MorphShape.cpp 2009-04-07 14:32:06 +0000
@@ -0,0 +1,99 @@
+// MorphShape.cpp: MorphShape 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 "MorphShape.h"
+#include "VM.h"
+#include "fill_style.h"
+#include "swf/ShapeRecord.h"
+#include "Geometry.h"
+#include "SWFMatrix.h"
+
+namespace gnash
+{
+
+
+MorphShape::MorphShape(const SWF::DefineMorphShapeTag* const def,
+ DisplayObject* parent, int id)
+ :
+ DisplayObject(parent, id),
+ _def(def),
+ _shape(_def->shape1())
+{
+}
+
+bool
+MorphShape::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);
+
+ // FIXME: if the shape contains non-scaled strokes
+ // we can't rely on boundary itself for a quick
+ // way out. Bounds supposedly already include
+ // thickness, so we might keep a flag telling us
+ // whether *non_scaled* strokes are present
+ // and if not still use the boundary check.
+ // NOTE: just skipping this test breaks a corner-case
+ // in DrawingApiTest (kind of a fill-leakage making
+ // the collision detection find you inside a self-crossing
+ // shape).
+ if (!_shape.getBounds().point_test(lp.x, lp.y)) return false;
+
+ return geometry::pointTest(_shape.paths(), _shape.lineStyles(),
+ lp.x, lp.y, wm);
+}
+
+void
+MorphShape::display()
+{
+ morph();
+ _def->display(*this);
+ clear_invalidated();
+}
+
+inline double
+MorphShape::currentRatio() const
+{
+ return get_ratio() / 65535.0;
+}
+
+rect
+MorphShape::getBounds() const
+{
+ // TODO: optimize this more.
+ rect bounds = _shape.getBounds();
+ bounds.expand_to_rect(_def->shape2().getBounds());
+ return bounds;
+}
+
+void
+MorphShape::morph()
+{
+ _shape.setLerp(_def->shape1(), _def->shape2(), currentRatio());
+}
+
+
+} // namespace gnash
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:
=== added file 'libcore/MorphShape.h'
--- a/libcore/MorphShape.h 1970-01-01 00:00:00 +0000
+++ b/libcore/MorphShape.h 2009-04-07 14:32:06 +0000
@@ -0,0 +1,87 @@
+// MorphShape.h: the MorphShape DisplayObject implementation 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
+
+#ifndef GNASH_MORPH_SHAPE_H
+#define GNASH_MORPH_SHAPE_H
+
+#include "smart_ptr.h" // GNASH_USE_GC
+#include "DisplayObject.h"
+#include "Geometry.h"
+#include "swf/DefineMorphShapeTag.h"
+#include <cassert>
+
+namespace gnash {
+
+/// A DisplayObject that tweens between two shapes.
+//
+/// A MorphShape has no properties of its own, but its inherited properties
+/// may be read in AS3 using a reference to the object created with
+/// getChildAt().
+class MorphShape : public DisplayObject
+{
+
+public:
+
+ MorphShape(const SWF::DefineMorphShapeTag* const def,
+ DisplayObject* parent, int id);
+
+ virtual void display();
+
+ virtual rect getBounds() const;
+
+ virtual bool pointInShape(boost::int32_t x, boost::int32_t y) const;
+
+ const SWF::ShapeRecord& shape() const {
+ return _shape;
+ }
+
+protected:
+
+#ifdef GNASH_USE_GC
+ /// Mark reachable resources (for the GC)
+ void markReachableResources() const
+ {
+ assert(isReachable());
+ _def->setReachable();
+ markDisplayObjectReachable();
+ }
+#endif
+
+private:
+
+ void morph();
+
+ double currentRatio() const;
+
+ const boost::intrusive_ptr<const SWF::DefineMorphShapeTag> _def;
+
+ SWF::ShapeRecord _shape;
+
+};
+
+
+} // namespace gnash
+
+
+#endif
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:
=== modified file 'libcore/MouseButtonState.h'
--- a/libcore/MouseButtonState.h 2009-04-04 15:35:18 +0000
+++ b/libcore/MouseButtonState.h 2009-04-07 13:13:16 +0000
@@ -8,8 +8,6 @@
#define GNASH_MOUSE_BUTTON_STATE_H
#include "smart_ptr.h" // GNASH_USE_GC
-#include "character_def.h"
-#include "smart_ptr.h" // for composition and inlines
#include "InteractiveObject.h" // for use in intrusive_ptr
// Forward declarations
=== modified file 'libcore/MovieClip.cpp'
--- a/libcore/MovieClip.cpp 2009-04-05 07:43:04 +0000
+++ b/libcore/MovieClip.cpp 2009-04-07 12:56:44 +0000
@@ -60,6 +60,7 @@
#include "flash/geom/Matrix_as.h"
#include "ExportableResource.h"
#include "GnashNumeric.h"
+#include "Shape.h"
#ifdef USE_SWFTREE
# include "tree.hh"
@@ -484,7 +485,7 @@
InteractiveObject(parent, id),
m_root(r),
_drawable(new DynamicShape()),
- _drawable_inst(_drawable->createDisplayObject(this, 0)),
+ _drawable_inst(new Shape(_drawable, this, 0)),
m_play_state(PLAY),
m_current_frame(0),
m_has_looped(false),
@@ -828,7 +829,7 @@
newmovieclip->set_event_handlers(get_event_handlers());
// Copy drawable
- newmovieclip->_drawable = new DynamicShape(*_drawable);
+ newmovieclip->_drawable.reset(new DynamicShape(*_drawable));
newmovieclip->set_cxform(get_cxform());
newmovieclip->copyMatrix(*this); // copy SWFMatrix and caches
@@ -1163,6 +1164,7 @@
TAG_DLIST|TAG_ACTION);
}
}
+
}
#ifdef GNASH_DEBUG
else
@@ -1512,7 +1514,7 @@
assert(m_def);
assert(tag);
- character_def* cdef = m_def->get_character_def(tag->getID());
+ SWF::DefinitionTag* cdef = m_def->getDefinitionTag(tag->getID());
if (!cdef)
{
IF_VERBOSE_MALFORMED_SWF(
@@ -1577,7 +1579,7 @@
assert(m_def != NULL);
assert(tag != NULL);
- character_def* cdef = m_def->get_character_def(tag->getID());
+ SWF::DefinitionTag* cdef = m_def->getDefinitionTag(tag->getID());
if (cdef == NULL)
{
log_error(_("movieclip::replace_display_object(): "
@@ -1973,9 +1975,9 @@
}
DisplayObject*
-MovieClip::getDisplayObject(int /* DisplayObject_id */)
+MovieClip::getDisplayObject(int /* id */)
{
- //return m_def->get_character_def(DisplayObject_id);
+ //return m_def->getDefinitionTag(id);
// @@ TODO -- look through our dlist for a match
log_unimpl(_("%s doesn't even check for a char"),
__PRETTY_FUNCTION__);
@@ -2560,7 +2562,7 @@
rect bounds;
BoundsFinder f(bounds);
const_cast<DisplayList&>(m_display_list).visitAll(f);
- rect drawableBounds = _drawable->get_bound();
+ rect drawableBounds = _drawable->getBounds();
bounds.expand_to_rect(drawableBounds);
return bounds;
@@ -2645,8 +2647,6 @@
m_display_list.visitAll(marker);
- _drawable->setReachable();
-
_drawable_inst->setReachable();
m_as_environment.markReachableResources();
@@ -2813,13 +2813,15 @@
#ifdef USE_SWFTREE
-class MovieInfoVisitor {
+class MovieInfoVisitor
+{
DisplayObject::InfoTree& _tr;
DisplayObject::InfoTree::iterator _it;
public:
- MovieInfoVisitor(DisplayObject::InfoTree& tr,
DisplayObject::InfoTree::iterator it)
+ MovieInfoVisitor(DisplayObject::InfoTree& tr,
+ DisplayObject::InfoTree::iterator it)
:
_tr(tr),
_it(it)
@@ -3155,8 +3157,8 @@
return as_value();
}
- character_def* exported_movie =
- dynamic_cast<character_def*>(exported.get());
+ SWF::DefinitionTag* exported_movie =
+ dynamic_cast<SWF::DefinitionTag*>(exported.get());
if (!exported_movie)
{
=== modified file 'libcore/MovieClip.h'
--- a/libcore/MovieClip.h 2009-04-05 07:47:59 +0000
+++ b/libcore/MovieClip.h 2009-04-07 12:34:43 +0000
@@ -896,18 +896,10 @@
/// The canvas for dynamic drawing
//
- /// WARNING: since DynamicShape is a character_def, which is
- /// in turn a ref_counted, we'd better keep
- /// this by intrusive_ptr, even if we're the sole
- /// owners. The problem is in case a pointer to this
- /// instance ever gets passed to some function wrapping
- /// it into an intrusive_ptr, in which case the stack
- /// object will be destroyed, with horrible consequences ...
- ///
- boost::intrusive_ptr<DynamicShape> _drawable;
+ boost::shared_ptr<DynamicShape> _drawable;
/// The need of an instance here is due to the renderer
- /// insising on availability a shape_character_def instance
+ /// insising on availability a DefineShapeTag instance
/// that has a parent (why?)
///
boost::intrusive_ptr<DisplayObject> _drawable_inst;
=== modified file 'libcore/Shape.cpp'
--- a/libcore/Shape.cpp 2009-04-03 11:03:31 +0000
+++ b/libcore/Shape.cpp 2009-04-07 13:42:26 +0000
@@ -1,4 +1,4 @@
-// Shape.cpp: Mouse/Character handling, for Gnash.
+// Shape.cpp: Shape DisplayObject implementation for Gnash.
//
// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
//
@@ -29,13 +29,33 @@
SWFMatrix wm_inverse = wm.invert();
point lp(x, y);
wm_inverse.transform(lp);
- return _def->point_test_local(lp.x, lp.y, wm);
+
+ // FIXME: if the shape contains non-scaled strokes
+ // we can't rely on boundary itself for a quick
+ // way out. Bounds supposedly already include
+ // thickness, so we might keep a flag telling us
+ // whether *non_scaled* strokes are present
+ // and if not still use the boundary check.
+ // NOTE: just skipping this test breaks a corner-case
+ // in DrawingApiTest (kind of a fill-leakage making
+ // the collision detection find you inside a self-crossing
+ // shape).
+ if (_def) {
+ if (!_def->get_bound().point_test(lp.x, lp.y)) return false;
+ return _def->pointTestLocal(lp.x, lp.y, wm);
+ }
+ assert(_shape.get());
+
+ if (!_shape->getBounds().point_test(lp.x, lp.y)) return false;
+ return _shape->pointTestLocal(lp.x, lp.y, wm);
+
}
void
Shape::display()
{
- _def->display(this); // pass in transform info
+ if (_def) _def->display(*this);
+ else _shape->display(*this);
clear_invalidated();
}
=== modified file 'libcore/Shape.h'
--- a/libcore/Shape.h 2009-04-03 11:03:31 +0000
+++ b/libcore/Shape.h 2009-04-07 12:45:25 +0000
@@ -1,3 +1,4 @@
+// Shape.h: Shape DisplayObject implementation for Gnash.
//
// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
//
@@ -20,23 +21,38 @@
#include "smart_ptr.h" // GNASH_USE_GC
#include "DisplayObject.h"
-#include "shape_character_def.h"
+#include "DefineShapeTag.h"
+#include "DynamicShape.h"
+
#include <cassert>
+#include <boost/shared_ptr.hpp>
// Forward declarations
namespace gnash {
- class character_def;
+ class DefinitionTag;
}
namespace gnash {
/// For DisplayObjects that don't store unusual state in their instances.
+//
+/// A Shape may be either statically constructed during parsing or,
+/// in AS3, dynamically constructed. A SWF-parsed Shape has an immutable
+/// SWF::DefinitionTag. A dynamic Shape object has a DynamicShape.
class Shape : public DisplayObject
{
public:
- Shape(shape_character_def* def, DisplayObject* parent, int id)
+ Shape(boost::shared_ptr<DynamicShape> sh, DisplayObject* parent, int id)
+ :
+ DisplayObject(parent, id),
+ _shape(sh)
+ {
+ assert(_shape.get());
+ }
+
+ Shape(const SWF::DefineShapeTag* const def, DisplayObject* parent, int
id)
:
DisplayObject(parent, id),
_def(def)
@@ -47,7 +63,7 @@
virtual void display();
virtual rect getBounds() const {
- return _def->get_bound();
+ return _def ? _def->get_bound() : _shape->getBounds();
}
virtual bool pointInShape(boost::int32_t x, boost::int32_t y) const;
@@ -59,14 +75,16 @@
void markReachableResources() const
{
assert(isReachable());
- _def->setReachable();
+ if (_def) _def->setReachable();
markDisplayObjectReachable();
}
#endif
private:
- const boost::intrusive_ptr<shape_character_def> _def;
+ const boost::intrusive_ptr<const SWF::DefineShapeTag> _def;
+
+ boost::shared_ptr<DynamicShape> _shape;
};
=== removed file 'libcore/Sprite.h'
--- a/libcore/Sprite.h 2009-04-03 09:18:40 +0000
+++ b/libcore/Sprite.h 1970-01-01 00:00:00 +0000
@@ -1,41 +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
-
-//------------------------------------------------------------------
-// NOTE: this header is still here just as a place-holder for
-// Doxygen page about Sprites
-//------------------------------------------------------------------
-
-/// \page Sprite Sprites and MovieClips
-///
-/// A Sprite, or MovieClip, is a mini movie-within-a-movie.
-///
-/// It doesn't define its own DisplayObjects;
-/// it uses the DisplayObjects from the parent
-/// movie, but it has its own frame counter, display list, etc.
-///
-/// @@ are we sure it doesn't define its own chars ?
-///
-/// The sprite implementation is divided into
-/// gnash::sprite_definition and gnash::MovieClip.
-///
-/// The _definition holds the immutable data for a sprite (as read
-/// from an SWF stream), while the _instance contains the state for
-/// a specific run of if (frame being played, mouse state, timers,
-/// display list as updated by actions, ...)
-///
-
=== modified file 'libcore/StaticText.cpp'
--- a/libcore/StaticText.cpp 2009-04-03 11:03:31 +0000
+++ b/libcore/StaticText.cpp 2009-04-07 12:34:43 +0000
@@ -1,4 +1,4 @@
-// Shape.cpp: Mouse/Character handling, for Gnash.
+// StaticText.cpp: StaticText DisplayObject implementation for Gnash.
//
// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
//
@@ -38,20 +38,19 @@
}
bool
-StaticText::pointInShape(boost::int32_t x, boost::int32_t y) const
+StaticText::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 _def->point_test_local(lp.x, lp.y, wm);
+ // TODO: this has never worked as it relied on the default
+ // pointTestLocal in DefinitionTag, which returned false. There are
+ // no tests for whether StaticText has a proper hit test.
+ return false;
}
void
StaticText::display()
{
- _def->display(this); // pass in transform info
+ _def->display(*this);
clear_invalidated();
}
=== modified file 'libcore/StaticText.h'
--- a/libcore/StaticText.h 2009-04-03 11:03:31 +0000
+++ b/libcore/StaticText.h 2009-04-07 12:34:43 +0000
@@ -1,3 +1,4 @@
+// StaticText.h: StaticText DisplayObject implementation for Gnash.
//
// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
//
@@ -28,7 +29,7 @@
// Forward declarations
namespace gnash {
- class character_def;
+ class DefinitionTag;
namespace SWF {
class TextRecord;
}
@@ -43,7 +44,8 @@
{
public:
- StaticText(SWF::DefineTextTag* def, DisplayObject* parent, int id)
+ StaticText(const SWF::DefineTextTag* const def, DisplayObject* parent,
+ int id)
:
DisplayObject(parent, id),
_def(def)
@@ -104,7 +106,7 @@
private:
- const boost::intrusive_ptr<SWF::DefineTextTag> _def;
+ const boost::intrusive_ptr<const SWF::DefineTextTag> _def;
/// A bitmask indicating which static text DisplayObjects are selected
//
@@ -123,7 +125,7 @@
} // end namespace gnash
-#endif // GNASH_GENERIC_CHARACTER_H
+#endif
// Local Variables:
=== modified file 'libcore/TextField.cpp'
--- a/libcore/TextField.cpp 2009-04-04 15:35:18 +0000
+++ b/libcore/TextField.cpp 2009-04-07 12:46:29 +0000
@@ -343,7 +343,7 @@
m.concatenate_translation(_bounds.get_x_min(), _bounds.get_y_min());
}
- SWF::TextRecord::displayRecords(m, this, _textRecords, _embedFonts);
+ SWF::TextRecord::displayRecords(m, *this, _textRecords, _embedFonts);
if (m_has_focus) show_cursor(wmat);
@@ -987,7 +987,7 @@
int last_space_glyph = -1;
int last_line_start_record = 0;
- unsigned int DisplayObject_idx = 0;
+ unsigned int idx = 0;
m_xcursor = x;
m_ycursor = y;
@@ -1286,12 +1286,12 @@
}
- if (m_cursor > DisplayObject_idx)
+ if (m_cursor > idx)
{
m_xcursor = x;
m_ycursor = y;
}
- DisplayObject_idx++;
+ idx++;
// TODO: HTML markup
}
=== modified file 'libcore/Video.cpp'
--- a/libcore/Video.cpp 2009-04-03 09:18:40 +0000
+++ b/libcore/Video.cpp 2009-04-06 11:16:20 +0000
@@ -263,8 +263,6 @@
Video::advance()
{
if (_ns) {
- //_ns->advance();
-
// NOTE: only needed for gstreamer:
if (_ns->newFrameReady()) set_invalidated();
}
=== modified file 'libcore/as_environment.cpp'
--- a/libcore/as_environment.cpp 2009-04-03 09:48:13 +0000
+++ b/libcore/as_environment.cpp 2009-04-07 09:49:53 +0000
@@ -20,7 +20,6 @@
#include "smart_ptr.h" // GNASH_USE_GC
#include "as_environment.h"
#include "MovieClip.h"
-#include "shape_character_def.h"
#include "as_value.h"
#include "VM.h"
#include "log.h"
=== modified file 'libcore/fill_style.h'
--- a/libcore/fill_style.h 2009-04-03 09:48:13 +0000
+++ b/libcore/fill_style.h 2009-04-06 08:16:33 +0000
@@ -253,7 +253,7 @@
///
rgba sample_gradient(boost::uint8_t ratio) const;
- friend class morph2_character_def;
+ friend class MorphShape;
// For BITMAP or GRADIENT types
SWFMatrix _matrix;
=== modified file 'libcore/fontlib.cpp'
--- a/libcore/fontlib.cpp 2008-11-14 00:46:35 +0000
+++ b/libcore/fontlib.cpp 2009-04-07 12:34:43 +0000
@@ -13,7 +13,7 @@
#include "impl.h"
#include "log.h"
#include "render.h"
-#include "shape_character_def.h"
+#include "DefineShapeTag.h"
#include "styles.h"
#include "movie_definition.h"
=== modified file 'libcore/impl.cpp'
--- a/libcore/impl.cpp 2009-02-10 11:33:38 +0000
+++ b/libcore/impl.cpp 2009-04-07 12:45:25 +0000
@@ -36,6 +36,7 @@
#include "ScriptLimitsTag.h"
#include "BitmapMovieDefinition.h"
#include "DefineFontAlignZonesTag.h"
+#include "DefineShapeTag.h"
#include "DefineButtonCxformTag.h"
#include "CSMTextSettingsTag.h"
#include "DefineFontTag.h"
@@ -50,6 +51,7 @@
#include "StartSoundTag.h"
#include "StreamSoundBlockTag.h"
#include "DefineButtonSoundTag.h"
+#include "DefineMorphShapeTag.h"
#include "DefineVideoStreamTag.h"
#include "DefineFontNameTag.h"
#include "VideoFrameTag.h"
@@ -107,7 +109,7 @@
// TODO: use null_loader here ?
register_tag_loader(SWF::END, end_loader);
- register_tag_loader(SWF::DEFINESHAPE, define_shape_loader);
+ register_tag_loader(SWF::DEFINESHAPE, DefineShapeTag::loader);
register_tag_loader(SWF::FREECHARACTER, fixme_loader); // 03
register_tag_loader(SWF::PLACEOBJECT, PlaceObject2Tag::loader);
register_tag_loader(SWF::REMOVEOBJECT, RemoveObjectTag::loader); // 05
@@ -136,7 +138,7 @@
register_tag_loader(SWF::SOUNDSTREAMBLOCK, StreamSoundBlockTag::loader);
register_tag_loader(SWF::DEFINELOSSLESS, define_bits_lossless_2_loader);
register_tag_loader(SWF::DEFINEBITSJPEG2, define_bits_jpeg2_loader);
- register_tag_loader(SWF::DEFINESHAPE2, define_shape_loader);
+ register_tag_loader(SWF::DEFINESHAPE2, DefineShapeTag::loader);
register_tag_loader(SWF::DEFINEBUTTONCXFORM,
DefineButtonCxformTag::loader); // 23
// "protect" tag; we're not an authoring tool so we don't care.
// (might be nice to dump the password instead..)
@@ -148,7 +150,7 @@
register_tag_loader(SWF::SYNCFRAME, fixme_loader); // 29
// 30 - _UNKNOWN_ unimplemented
register_tag_loader(SWF::FREEALL, fixme_loader); // 31
- register_tag_loader(SWF::DEFINESHAPE3, define_shape_loader);
+ register_tag_loader(SWF::DEFINESHAPE3, DefineShapeTag::loader);
register_tag_loader(SWF::DEFINETEXT2, DefineText2Tag::loader);
// 37
register_tag_loader(SWF::DEFINEBUTTON2, DefineButton2Tag::loader);
@@ -166,7 +168,8 @@
register_tag_loader(SWF::DEFINEBEHAVIOR, fixme_loader); // 44
register_tag_loader(SWF::SOUNDSTREAMHEAD2, sound_stream_head_loader); // 45
- register_tag_loader(SWF::DEFINEMORPHSHAPE, define_shape_morph_loader);
+ // 46
+ register_tag_loader(SWF::DEFINEMORPHSHAPE, DefineMorphShapeTag::loader);
register_tag_loader(SWF::FRAMETAG, fixme_loader); // 47
// 48
register_tag_loader(SWF::DEFINEFONT2, DefineFontTag::loader);
@@ -208,10 +211,11 @@
// TODO: Alexis reference says these are 83, 84. The 67,68 comes from
Tamarin.
// Figure out which one is correct (possibly both are).
- register_tag_loader(SWF::DEFINESHAPE4_, define_shape_loader); // 67
- register_tag_loader(SWF::DEFINEMORPHSHAPE2_, define_shape_morph_loader);
// 68
-
- register_tag_loader(SWF::FILEATTRIBUTES, file_attributes_loader); // 69
+ register_tag_loader(SWF::DEFINESHAPE4_, DefineShapeTag::loader); // 67
+ // 68
+ register_tag_loader(SWF::DEFINEMORPHSHAPE2_, DefineMorphShapeTag::loader);
+ // 69
+ register_tag_loader(SWF::FILEATTRIBUTES, file_attributes_loader);
register_tag_loader(SWF::PLACEOBJECT3, PlaceObject2Tag::loader); // 70
register_tag_loader(SWF::IMPORTASSETS2, import_loader); // 71
@@ -225,8 +229,9 @@
register_tag_loader(SWF::METADATA, metadata_loader); // 77
register_tag_loader(SWF::DEFINESCALINGGRID, fixme_loader); // 78
register_tag_loader(SWF::DOABCDEFINE, abc_loader); // 82 -- AS3 codeblock.
- register_tag_loader(SWF::DEFINESHAPE4, define_shape_loader); // 83
- register_tag_loader(SWF::DEFINEMORPHSHAPE2, define_shape_morph_loader); //
84
+ register_tag_loader(SWF::DEFINESHAPE4, DefineShapeTag::loader); // 83
+ // 84
+ register_tag_loader(SWF::DEFINEMORPHSHAPE2, DefineMorphShapeTag::loader);
register_tag_loader(SWF::DEFINESCENEANDFRAMELABELDATA,define_scene_frame_label_loader);
//86
// 88
register_tag_loader(SWF::DEFINEFONTNAME, DefineFontNameTag::loader);
=== modified file 'libcore/movie_root.cpp'
--- a/libcore/movie_root.cpp 2009-04-04 20:08:19 +0000
+++ b/libcore/movie_root.cpp 2009-04-06 08:16:33 +0000
@@ -2037,8 +2037,7 @@
void
movie_root::advanceLiveChar(boost::intrusive_ptr<DisplayObject> ch)
{
-
- if ( ! ch->isUnloaded() )
+ if (!ch->isUnloaded())
{
#ifdef GNASH_DEBUG
log_debug(" advancing DisplayObject %s", ch->getTarget());
=== modified file 'libcore/parser/BitmapMovieDefinition.cpp'
--- a/libcore/parser/BitmapMovieDefinition.cpp 2009-04-03 09:18:40 +0000
+++ b/libcore/parser/BitmapMovieDefinition.cpp 2009-04-07 12:34:43 +0000
@@ -25,29 +25,28 @@
#include "render.h" // for ::display
#include "GnashImage.h"
#include "log.h"
+#include "Shape.h"
namespace gnash {
-shape_character_def*
-BitmapMovieDefinition::getShapeDef()
+DisplayObject*
+BitmapMovieDefinition::createDisplayObject(DisplayObject* parent, int id)
{
- if ( _shapedef ) return _shapedef.get();
// It's possible for this to fail.
if (!_bitmap.get()) return 0;
- // Create the shape definition
- _shapedef = new DynamicShape();
+ if (!_shape.get()) _shape.reset(new DynamicShape);
// Set its boundaries
- _shapedef->set_bound(_framesize);
+ _shape->setBounds(_framesize);
// Add the bitmap fill style (fill style 0)
SWFMatrix mat;
mat.set_scale(1.0/20, 1.0/20); // bitmap fills get SWFMatrix reversed
fill_style bmFill(_bitmap.get(), mat);
- const size_t fillLeft = _shapedef->add_fill_style(bmFill);
+ const size_t fillLeft = _shape->add_fill_style(bmFill);
// Define a rectangle filled with the bitmap style
@@ -61,7 +60,7 @@
log_parse(_("Creating a shape_definition wrapping a %g x %g
bitmap"), w, h);
);
- path bmPath(w, h, fillLeft, 0, 0, false);
+ Path bmPath(w, h, fillLeft, 0, 0, false);
bmPath.drawLineTo(w, 0);
bmPath.drawLineTo(0, 0);
bmPath.drawLineTo(0, h);
@@ -69,9 +68,9 @@
// Add the path
- _shapedef->add_path(bmPath);
+ _shape->add_path(bmPath);
- return _shapedef.get();
+ return new Shape(_shape, parent, id);
}
BitmapMovieDefinition::BitmapMovieDefinition(
@@ -87,15 +86,14 @@
_bytesTotal(image->size()),
_bitmap(render::createBitmapInfo(image))
{
- // Do not create shape_character_def now (why?)
+ // Do not create DefineShapeTag now (why?)
}
#ifdef GNASH_USE_GC
void
BitmapMovieDefinition::markReachableResources() const
{
- if ( _shapedef.get() ) _shapedef->setReachable();
- if ( _bitmap.get() ) _bitmap->setReachable();
+ if (_bitmap.get()) _bitmap->setReachable();
}
#endif // GNASH_USE_GC
=== modified file 'libcore/parser/BitmapMovieDefinition.h'
--- a/libcore/parser/BitmapMovieDefinition.h 2009-04-03 09:18:40 +0000
+++ b/libcore/parser/BitmapMovieDefinition.h 2009-04-07 09:19:54 +0000
@@ -58,15 +58,7 @@
BitmapMovieDefinition(std::auto_ptr<GnashImage> image,
const std::string& url);
- virtual DisplayObject* createDisplayObject(DisplayObject*, int) {
- return 0;
- }
-
- // Discard id, always return the only shape DisplayObject we have
- virtual character_def* get_character_def(int /*id*/)
- {
- return getShapeDef();
- }
+ virtual DisplayObject* createDisplayObject(DisplayObject*, int);
virtual int get_version() const {
return _version;
@@ -160,13 +152,7 @@
boost::intrusive_ptr<BitmapInfo> _bitmap;
- boost::intrusive_ptr<DynamicShape> _shapedef;
-
- /// Get the shape DisplayObject definition for this bitmap movie
- //
- /// It will create the definition the first time it's called
- ///
- shape_character_def* getShapeDef();
+ boost::shared_ptr<DynamicShape> _shape;
};
=== modified file 'libcore/parser/Makefile.am'
--- a/libcore/parser/Makefile.am 2009-02-27 06:46:40 +0000
+++ b/libcore/parser/Makefile.am 2009-04-07 12:34:43 +0000
@@ -47,23 +47,17 @@
abc_block.cpp \
action_buffer.cpp \
BitmapMovieDefinition.cpp \
- character_def.cpp \
SWFMovieDefinition.cpp \
- morph2_character_def.cpp \
- shape_character_def.cpp \
sound_definition.cpp \
sprite_definition.cpp
noinst_HEADERS = \
abc_block.h \
action_buffer.h \
- character_def.h \
BitmapMovieDefinition.h \
- morph2_character_def.h \
movie_definition.h \
SWFMovieDefinition.h \
Namespace.h \
- shape_character_def.h \
sound_definition.h \
sprite_definition.h
=== modified file 'libcore/parser/SWFMovieDefinition.cpp'
--- a/libcore/parser/SWFMovieDefinition.cpp 2009-04-03 09:48:13 +0000
+++ b/libcore/parser/SWFMovieDefinition.cpp 2009-04-07 12:52:56 +0000
@@ -226,21 +226,21 @@
//assert(m_jpeg_in->get() == NULL);
}
-void SWFMovieDefinition::addDisplayObject(int DisplayObject_id, character_def*
c)
+void SWFMovieDefinition::addDisplayObject(int id, SWF::DefinitionTag* c)
{
assert(c);
boost::mutex::scoped_lock lock(_dictionaryMutex);
- _dictionary.addDisplayObject(DisplayObject_id, c);
+ _dictionary.addDisplayObject(id, c);
}
-character_def*
-SWFMovieDefinition::get_character_def(int DisplayObject_id)
+SWF::DefinitionTag*
+SWFMovieDefinition::getDefinitionTag(int id)
{
boost::mutex::scoped_lock lock(_dictionaryMutex);
- boost::intrusive_ptr<character_def> ch =
- _dictionary.getDisplayObject(DisplayObject_id);
+ boost::intrusive_ptr<SWF::DefinitionTag> ch =
+ _dictionary.getDisplayObject(id);
#ifndef GNASH_USE_GC
assert(ch == NULL || ch->get_ref_count() > 1);
#endif
@@ -277,9 +277,9 @@
}
BitmapInfo*
-SWFMovieDefinition::getBitmap(int DisplayObject_id)
+SWFMovieDefinition::getBitmap(int id)
{
- Bitmaps::iterator it = _bitmaps.find(DisplayObject_id);
+ Bitmaps::iterator it = _bitmaps.find(id);
if (it == _bitmaps.end()) return 0;
return it->second.get();
@@ -293,9 +293,9 @@
}
-sound_sample* SWFMovieDefinition::get_sound_sample(int DisplayObject_id)
+sound_sample* SWFMovieDefinition::get_sound_sample(int id)
{
- SoundSampleMap::iterator it = m_sound_samples.find(DisplayObject_id);
+ SoundSampleMap::iterator it = m_sound_samples.find(id);
if ( it == m_sound_samples.end() ) return NULL;
boost::intrusive_ptr<sound_sample> ch = it->second;
@@ -306,14 +306,14 @@
return ch.get();
}
-void SWFMovieDefinition::add_sound_sample(int DisplayObject_id, sound_sample*
sam)
+void SWFMovieDefinition::add_sound_sample(int id, sound_sample* sam)
{
assert(sam);
IF_VERBOSE_PARSE(
log_parse(_("Add sound sample %d assigning id %d"),
- DisplayObject_id, sam->m_sound_handler_id);
+ id, sam->m_sound_handler_id);
)
- m_sound_samples.insert(std::make_pair(DisplayObject_id,
+ m_sound_samples.insert(std::make_pair(id,
boost::intrusive_ptr<sound_sample>(sam)));
}
@@ -510,7 +510,7 @@
return o;
}
-boost::intrusive_ptr<character_def>
+boost::intrusive_ptr<SWF::DefinitionTag>
CharacterDictionary::getDisplayObject(int id)
{
CharacterIterator it = _map.find(id);
@@ -519,7 +519,7 @@
IF_VERBOSE_PARSE(
log_parse(_("Could not find char %d, dump is: %s"), id, *this);
);
- return boost::intrusive_ptr<character_def>();
+ return boost::intrusive_ptr<SWF::DefinitionTag>();
}
return it->second;
@@ -527,7 +527,7 @@
void
CharacterDictionary::addDisplayObject(int id,
- boost::intrusive_ptr<character_def> c)
+ boost::intrusive_ptr<SWF::DefinitionTag> c)
{
//log_debug(_("CharacterDictionary: add char %d"), id);
_map[id] = c;
@@ -927,7 +927,7 @@
add_font(id, f);
++importedSyms;
}
- else if (character_def* ch = dynamic_cast<character_def*>(res.get()))
+ else if (SWF::DefinitionTag* ch =
dynamic_cast<SWF::DefinitionTag*>(res.get()))
{
// Add this DisplayObject to the loading movie.
addDisplayObject(id, ch);
=== modified file 'libcore/parser/SWFMovieDefinition.h'
--- a/libcore/parser/SWFMovieDefinition.h 2009-04-03 09:48:13 +0000
+++ b/libcore/parser/SWFMovieDefinition.h 2009-04-07 12:46:29 +0000
@@ -31,7 +31,7 @@
#include "GnashImageJpeg.h"
#include "IOChannel.h"
#include "movie_definition.h" // for inheritance
-#include "character_def.h" // for boost::intrusive_ptr visibility of dtor
+#include "DefinitionTag.h" // for boost::intrusive_ptr visibility of dtor
#include "StringPredicates.h"
#include "rect.h"
#include "GnashNumeric.h"
@@ -117,9 +117,9 @@
/// The container used by this dictionary
//
- /// It contains pairs of 'int' and 'boost::intrusive_ptr<character_def>'
+ /// It contains pairs of 'int' and 'boost::intrusive_ptr<DefinitionTag>'
///
- typedef std::map<int, boost::intrusive_ptr<character_def> >
+ typedef std::map<int, boost::intrusive_ptr<SWF::DefinitionTag> >
CharacterContainer;
typedef CharacterContainer::iterator CharacterIterator;
@@ -130,13 +130,13 @@
//
/// returns a NULL if the id is unknown.
///
- boost::intrusive_ptr<character_def> getDisplayObject(int id);
+ boost::intrusive_ptr<SWF::DefinitionTag> getDisplayObject(int id);
/// Add a Character assigning it the given id
//
/// replaces any existing DisplayObject with the same id
///
- void addDisplayObject(int id, boost::intrusive_ptr<character_def> c);
+ void addDisplayObject(int id, boost::intrusive_ptr<SWF::DefinitionTag>
c);
/// Return an iterator to the first dictionary element
CharacterIterator begin() { return _map.begin(); }
@@ -246,14 +246,14 @@
virtual void importResources(boost::intrusive_ptr<movie_definition>
source,
Imports& imports);
- void addDisplayObject(int DisplayObject_id, character_def* c);
+ void addDisplayObject(int DisplayObject_id, SWF::DefinitionTag* c);
/// \brief
/// Return a DisplayObject from the dictionary
/// NOTE: call add_ref() on the return or put in a
boost::intrusive_ptr<>
/// TODO: return a boost::intrusive_ptr<> directly...
///
- character_def* get_character_def(int DisplayObject_id);
+ SWF::DefinitionTag* getDefinitionTag(int DisplayObject_id);
// See dox in movie_definition
//
@@ -395,7 +395,7 @@
// It is required that get_bound() is implemented in DisplayObject
definition
// classes. However, it makes no sense to call it for movie interfaces.
// get_bound() is currently only used by DisplayObject which normally
- // is used only shape DisplayObject definitions. See character_def.h to
learn
+ // is used only shape DisplayObject definitions. See DefinitionTag.h to
learn
// why it is virtual anyway.
abort(); // should not be called
static rect unused;
=== removed file 'libcore/parser/character_def.cpp'
--- a/libcore/parser/character_def.cpp 2009-03-10 20:43:50 +0000
+++ b/libcore/parser/character_def.cpp 1970-01-01 00:00:00 +0000
@@ -1,39 +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
-
-
-#ifdef HAVE_CONFIG_H
-#include "gnashconfig.h"
-#endif
-
-#include "character_def.h"
-#include "render_handler.h" // for destruction of render_cache_manager
-
-namespace gnash
-{
-
-character_def::~character_def()
-{
- delete m_render_cache;
-}
-
-} // end of namespace gnash
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:
=== modified file 'libcore/parser/movie_definition.h'
--- a/libcore/parser/movie_definition.h 2009-04-03 09:48:13 +0000
+++ b/libcore/parser/movie_definition.h 2009-04-07 13:13:16 +0000
@@ -51,7 +51,7 @@
#include "gnashconfig.h" // for USE_SWFTREE
#endif
-#include "character_def.h" // for inheritance
+#include "swf/DefinitionTag.h"
#include "GnashImageJpeg.h"
#include <string>
@@ -78,7 +78,7 @@
/// This is the shared constant source info, the one that cannot
/// be changed by ActionScript code.
///
-/// The class derives from character_def to allow a movie
+/// The class derives from DefinitionTag to allow a movie
/// to be put in the CharacterDictionary. This is probably
/// unneeded for top-level movies, because they don't need
/// to be put in any CharacterDictionary... anyway the
@@ -90,10 +90,10 @@
/// This design is uncomfortable when it comes to programmatically
/// created DisplayObjects, in that they do NOT have any *fixed* definition.
/// A possible workaround to this would be not *requiring* DisplayObject
-/// instances to have an associated character_def. I'll work on this
+/// instances to have an associated DefinitionTag. I'll work on this
/// --strk 2006-12-05.
///
-class movie_definition : public character_def
+class movie_definition : public SWF::DefinitionTag
{
public:
typedef std::vector<ControlTag*> PlayList;
@@ -195,7 +195,7 @@
/// @return NULL if no DisplayObject with the given ID is found
/// (this is the default)
///
- virtual character_def* get_character_def(int /*id*/)
+ virtual DefinitionTag* getDefinitionTag(int /*id*/)
{
return NULL;
}
@@ -232,7 +232,7 @@
/// This method is here to be called by DEFINE tags loaders.
/// The default implementation does nothing.
///
- virtual void addDisplayObject(int /*id*/, character_def* /*ch*/)
+ virtual void addDisplayObject(int /*id*/, DefinitionTag* /*ch*/)
{
}
@@ -445,7 +445,7 @@
virtual const std::string& getDescriptiveMetadata() const
{
- static const std::string s("");
+ static const std::string s;
return s;
}
=== modified file 'libcore/parser/sprite_definition.cpp'
--- a/libcore/parser/sprite_definition.cpp 2009-04-03 09:18:40 +0000
+++ b/libcore/parser/sprite_definition.cpp 2009-04-06 11:16:20 +0000
@@ -52,10 +52,10 @@
sprite_definition::~sprite_definition()
{
// Release our playlist data.
- for (PlayListMap::iterator i=m_playlist.begin(), e=m_playlist.end();
i!=e; ++i)
+ for (PlayListMap::iterator i=m_playlist.begin(), e=m_playlist.end();
+ i != e; ++i)
{
PlayList& pl = i->second;
-
deleteAllChecked(pl);
}
}
=== modified file 'libcore/parser/sprite_definition.h'
--- a/libcore/parser/sprite_definition.h 2009-04-03 09:48:13 +0000
+++ b/libcore/parser/sprite_definition.h 2009-04-07 12:51:13 +0000
@@ -169,7 +169,7 @@
virtual void addBitmap(int /*id*/, boost::intrusive_ptr<BitmapInfo>
/*im*/)
{
IF_VERBOSE_MALFORMED_SWF (
- log_swferror(_("add_bitmap_character_def appears in sprite
tags"));
+ log_swferror(_("add_bitmap_SWF::DefinitionTag appears in sprite
tags"));
);
}
@@ -224,16 +224,16 @@
}
/// \brief
- /// Get a character_def from this Sprite's root movie
+ /// Get a SWF::DefinitionTag from this Sprite's root movie
/// CharacterDictionary.
///
- virtual character_def* get_character_def(int id)
+ virtual SWF::DefinitionTag* getDefinitionTag(int id)
{
- return m_movie_def.get_character_def(id);
+ return m_movie_def.getDefinitionTag(id);
}
/// Delegate call to associated root movie
- virtual void addDisplayObject(int id, character_def* ch)
+ virtual void addDisplayObject(int id, SWF::DefinitionTag* ch)
{
m_movie_def.addDisplayObject(id, ch);
}
@@ -242,7 +242,7 @@
// instance is created to live (temporarily) on some level on
// the parent movie's display list.
//
- // overloads from character_def
+ // overloads from SWF::DefinitionTag
virtual DisplayObject* createDisplayObject(DisplayObject* parent, int
id);
@@ -326,7 +326,7 @@
// It is required that get_bound() is implemented in DisplayObject
definition
// classes. However, it makes no sense to call it for sprite definitions.
// get_bound() is currently only used by DisplayObject which normally
- // is used only shape DisplayObject definitions. See character_def.h to
learn
+ // is used only shape DisplayObject definitions. See SWF::DefinitionTag.h
to learn
// why it is virtual anyway.
abort(); // should not be called
static rect unused;
=== modified file 'libcore/render.cpp'
--- a/libcore/render.cpp 2009-04-03 09:18:40 +0000
+++ b/libcore/render.cpp 2009-04-07 14:32:06 +0000
@@ -151,22 +151,23 @@
}
-void drawShape(shape_character_def *def, DisplayObject *inst)
+void
+drawShape(const SWF::ShapeRecord& shape, const cxform& cx,
+ const SWFMatrix& worldMat)
{
#ifdef DEBUG_RENDER_CALLS
GNASH_REPORT_FUNCTION;
#endif
- if (s_render_handler) s_render_handler->drawShape(def, inst);
+ if (s_render_handler) s_render_handler->drawShape(shape, cx,
worldMat);
}
-void draw_glyph(shape_character_def *def,
- const SWFMatrix& mat,
- const rgba& color)
+void drawGlyph(const SWF::ShapeRecord& rec, const rgba& color,
+ const SWFMatrix& mat)
{
#ifdef DEBUG_RENDER_CALLS
GNASH_REPORT_FUNCTION;
#endif
- if (s_render_handler) s_render_handler->draw_glyph(def, mat,
color);
+ if (s_render_handler) s_render_handler->drawGlyph(rec, color,
mat);
}
bool bounds_in_clipping_area(const rect& bounds) {
=== modified file 'libcore/render.h'
--- a/libcore/render.h 2009-04-03 09:48:13 +0000
+++ b/libcore/render.h 2009-04-07 14:32:06 +0000
@@ -30,6 +30,9 @@
namespace gnash {
class rgba;
class GnashImage;
+ namespace SWF {
+ class ShapeRecord;
+ }
}
namespace gnash {
@@ -78,13 +81,13 @@
DSOEXPORT void draw_poly(const point* corners, int
corner_count,
const rgba& fill, const rgba& outline, const
SWFMatrix& mat,
bool masked);
-
- /// See render_handler::draw_Shape (in backend/render_handler.h)
- void drawShape(shape_character_def *def, DisplayObject *inst);
+
+ void drawShape(const SWF::ShapeRecord& shape, const cxform& cx,
+ const SWFMatrix& worldMat);
/// See render_handler::draw_glyph (in backend/render_handler.h)
- void draw_glyph(shape_character_def *def, const SWFMatrix& mat,
- const rgba& color);
+ void drawGlyph(const SWF::ShapeRecord& rec, const rgba& color,
+ const SWFMatrix& mat);
/// See render_handler::bounds_in_clipping_area (in
backend/render_handler.h)
bool bounds_in_clipping_area(const rect& bounds);
=== modified file 'libcore/swf/DefineButtonCxformTag.cpp'
--- a/libcore/swf/DefineButtonCxformTag.cpp 2009-04-03 09:18:40 +0000
+++ b/libcore/swf/DefineButtonCxformTag.cpp 2009-04-07 12:46:29 +0000
@@ -40,7 +40,7 @@
log_debug("DefineButtonCxformTag: ButtonId=%d", buttonID);
);
- character_def* chdef = m.get_character_def(buttonID);
+ DefinitionTag* chdef = m.getDefinitionTag(buttonID);
if (!chdef)
{
IF_VERBOSE_MALFORMED_SWF(
=== modified file 'libcore/swf/DefineButtonSoundTag.cpp'
--- a/libcore/swf/DefineButtonSoundTag.cpp 2009-04-03 09:18:40 +0000
+++ b/libcore/swf/DefineButtonSoundTag.cpp 2009-04-07 12:46:29 +0000
@@ -43,7 +43,7 @@
in.ensureBytes(2);
int id = in.read_u16();
- character_def* chdef = m.get_character_def(id);
+ DefinitionTag* chdef = m.getDefinitionTag(id);
if (!chdef)
{
IF_VERBOSE_MALFORMED_SWF(
=== modified file 'libcore/swf/DefineButtonTag.cpp'
--- a/libcore/swf/DefineButtonTag.cpp 2009-04-03 09:48:13 +0000
+++ b/libcore/swf/DefineButtonTag.cpp 2009-04-07 12:46:29 +0000
@@ -103,7 +103,7 @@
bool
ButtonRecord::is_valid()
{
- return (m_character_def != NULL);
+ return (m_DefinitionTag != NULL);
}
static std::string
@@ -159,11 +159,11 @@
_id = in.read_u16();
// Get DisplayObject definition now (safer)
- m_character_def = m.get_character_def(_id);
+ m_DefinitionTag = m.getDefinitionTag(_id);
// If no DisplayObject with given ID is found in the movie
// definition, we print an error, but keep parsing.
- if (!m_character_def)
+ if (!m_DefinitionTag)
{
IF_VERBOSE_MALFORMED_SWF(
log_swferror(_(" button record for states [%s] refer to "
@@ -176,7 +176,7 @@
IF_VERBOSE_PARSE(
log_parse(_(" button record for states [%s] contain "
"DisplayObject %d (%s)"),
computeButtonStatesString(flags),
- _id, typeName(*m_character_def));
+ _id, typeName(*m_DefinitionTag));
);
}
=== modified file 'libcore/swf/DefineButtonTag.h'
--- a/libcore/swf/DefineButtonTag.h 2009-04-03 09:48:13 +0000
+++ b/libcore/swf/DefineButtonTag.h 2009-04-07 12:34:43 +0000
@@ -21,7 +21,7 @@
#define GNASH_SWF_DEFINEBUTTONTAG_H
#include "smart_ptr.h" // GNASH_USE_GC
-#include "character_def.h"
+#include "DefinitionTag.h"
#include "sound_definition.h"
#include "rect.h" // for get_bound
#include "SWFMatrix.h" // for composition
@@ -78,7 +78,7 @@
int _id;
// Who owns this ?
- character_def* m_character_def;
+ DefinitionTag* m_DefinitionTag;
int m_button_layer;
SWFMatrix m_button_matrix;
@@ -89,7 +89,7 @@
ButtonRecord()
:
- m_character_def(0)
+ m_DefinitionTag(0)
{
}
@@ -113,11 +113,11 @@
/// Mark all reachable resources (for GC)
//
/// Reachable resources are:
- /// - m_character_def (??) what's it !?
+ /// - m_DefinitionTag (??) what's it !?
///
void markReachableResources() const
{
- if ( m_character_def ) m_character_def->setReachable();
+ if ( m_DefinitionTag ) m_DefinitionTag->setReachable();
}
#endif // GNASH_USE_GC
@@ -179,7 +179,7 @@
};
/// A class for parsing DefineButton and DefineButton2 tags.
-class DefineButtonTag : public character_def
+class DefineButtonTag : public DefinitionTag
{
public:
@@ -199,9 +199,9 @@
// It is required that get_bound() is implemented in
DisplayObject
// definition classes. However, button DisplayObject definitions do
// not have shape definitions themselves. Instead, they hold a list
- // of shape_character_def. get_bound() is currently only used
+ // of DefineShapeTag. get_bound() is currently only used
// by DisplayObject which normally is used only shape DisplayObject
- // definitions. See character_def.h to learn why it is virtual anyway.
+ // definitions. See DefinitionTag.h to learn why it is virtual anyway.
// get_button_bound() is used for buttons.
abort(); // should not be called
static rect unused;
=== modified file 'libcore/swf/DefineEditTextTag.h'
--- a/libcore/swf/DefineEditTextTag.h 2009-04-03 09:18:40 +0000
+++ b/libcore/swf/DefineEditTextTag.h 2009-04-07 12:34:43 +0000
@@ -23,7 +23,7 @@
#endif
#include "rect.h"
-#include "character_def.h"
+#include "DefinitionTag.h"
#include "swf.h" // for TagType definition
#include "RGBA.h"
#include "TextField.h"
@@ -54,7 +54,7 @@
/// The tag will then be used to start playing the specific block
/// in sync with the frame playhead.
///
-class DefineEditTextTag : public character_def
+class DefineEditTextTag : public DefinitionTag
{
public:
=== modified file 'libcore/swf/DefineFontTag.cpp'
--- a/libcore/swf/DefineFontTag.cpp 2009-04-03 09:18:40 +0000
+++ b/libcore/swf/DefineFontTag.cpp 2009-04-07 11:14:10 +0000
@@ -23,7 +23,7 @@
#include "RunInfo.h"
#include "swf.h"
#include "movie_definition.h"
-#include "shape_character_def.h"
+#include "ShapeRecord.h"
// Based on the public domain work of Thatcher Ulrich <address@hidden> 2003
@@ -175,10 +175,7 @@
}
// Create & read the shape.
- shape_character_def* s = new shape_character_def;
- s->read(in, SWF::DEFINEFONT, false, m);
-
- _glyphTable[i].glyph = s;
+ _glyphTable[i].glyph.reset(new ShapeRecord(in, SWF::DEFINEFONT, m));
}
}
@@ -280,14 +277,12 @@
if ( ! in.seek(new_pos) )
{
- throw ParserException(_("Glyphs offset table corrupted in
DefineFont2/3 tag"));
+ throw ParserException(_("Glyphs offset table corrupted in "
+ "DefineFont2/3 tag"));
}
// Create & read the shape.
- shape_character_def* s = new shape_character_def;
- s->read(in, SWF::DEFINEFONT2, false, m); // .. or DEFINEFONT3
actually..
-
- _glyphTable[i].glyph = s;
+ _glyphTable[i].glyph.reset(new ShapeRecord(in, SWF::DEFINEFONT2, m));
}
unsigned long current_position = in.tell();
=== renamed file 'libcore/parser/morph2_character_def.cpp' =>
'libcore/swf/DefineMorphShapeTag.cpp'
--- a/libcore/parser/morph2_character_def.cpp 2009-04-03 09:18:40 +0000
+++ b/libcore/swf/DefineMorphShapeTag.cpp 2009-04-07 14:32:06 +0000
@@ -1,4 +1,4 @@
-// morph2_character_def.cpp: Load and render morphing shapes, for Gnash.
+// DefineMorphShapeTag.cpp: Load and parse morphing shapes, for Gnash.
//
// Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
//
@@ -18,11 +18,12 @@
//
-// Based on the public domain morph2.cpp of:
+// Based on the public domain morph.cpp of:
// Thatcher Ulrich <address@hidden>, Mike Shaver <address@hidden> 2003,
// Vitalij Alexeev <address@hidden> 2004.
-#include "morph2_character_def.h"
+#include "DefineMorphShapeTag.h"
+#include "MorphShape.h"
#include "SWFStream.h"
#include "render.h"
#include "movie_definition.h"
@@ -30,210 +31,64 @@
#include "GnashNumeric.h"
namespace gnash {
-
-/// Functors for path and style manipulation.
-namespace {
-
-template<typename T>
-class Lerp
-{
-public:
- Lerp(typename T::const_iterator style1, typename T::const_iterator style2,
- const double ratio)
- :
- _style1(style1),
- _style2(style2),
- _ratio(ratio)
- {}
-
- void operator()(typename T::value_type& st)
- {
- st.set_lerp(*_style1, *_style2, _ratio);
- ++_style1, ++_style2;
- }
-
-private:
- typename T::const_iterator _style1;
- typename T::const_iterator _style2;
- const double _ratio;
-};
-
-// Facilities for working with list of paths.
-class PathList
-{
- typedef shape_character_def::Paths Paths;
-public:
-
- PathList(const Paths& paths)
- :
- _paths(paths),
- _currpath(0),
- _curredge(0),
- _nedges(computeNumberOfEdges(_paths))
- {}
-
- /// Return number of edges in the path list
- size_t size() const
- {
- return _nedges;
- }
-
- /// Get next edge in the path list.
- //
- /// After last edge in the list has been fetched,
- /// next call to this function will return first
- /// edge again.
- ///
- const edge& getNextEdge()
- {
- const edge& ret = _paths[_currpath][_curredge];
- if ( ++_curredge >= _paths[_currpath].size() )
- {
- if ( ++_currpath >= _paths.size() )
- {
- // this is not really needed,
- // but it's simpler to do so that
- // to make next call fail or abort..
- _currpath = 0;
- _curredge = 0;
- }
- }
- return ret;
- }
-
- /// Compute total number of edges
- static size_t computeNumberOfEdges(const Paths& paths)
- {
- size_t count=0;
- for (Paths::const_iterator i = paths.begin(), e = paths.end();
- i != e; ++i) {
-
- count += i->size();
- }
- return count;
- }
-
-private:
-
- const Paths& _paths;
-
- size_t _currpath;
-
- size_t _curredge;
-
- size_t _nedges;
-
-};
-
-} // anonymous namespace
-
-morph2_character_def::morph2_character_def()
- :
- m_shape1(new shape_character_def),
- m_shape2(new shape_character_def)
-{
-}
-
-
-morph2_character_def::~morph2_character_def()
-{
-}
-
-void
-morph2_character_def::display(DisplayObject* inst)
-{
-
- const double ratio = inst->get_ratio() / 65535.0;
-
- // bounds
- rect new_bound;
- new_bound.set_lerp(m_shape1->get_bound(), m_shape2->get_bound(), ratio);
- set_bound(new_bound);
-
- // fill styles
- const FillStyles::const_iterator fs1 = m_shape1->fillStyles().begin();
- const FillStyles::const_iterator fs2 = m_shape2->fillStyles().begin();
-
- std::for_each(_fill_styles.begin(), _fill_styles.end(),
- Lerp<FillStyles>(fs1, fs2, ratio));
-
- // line styles
- const LineStyles::const_iterator ls1 = m_shape1->lineStyles().begin();
- const LineStyles::const_iterator ls2 = m_shape2->lineStyles().begin();
-
- std::for_each(_line_styles.begin(), _line_styles.end(),
- Lerp<LineStyles>(ls1, ls2, ratio));
-
- // This is used for cases in which number
- // of paths in start shape and end shape are not
- // the same.
- path empty_path;
- edge empty_edge;
-
- // shape
- const Paths& paths1 = m_shape1->paths();
- const Paths& paths2 = m_shape2->paths();
- for (size_t i = 0, k = 0, n = 0; i < _paths.size(); i++)
- {
- path& p = _paths[i];
- const path& p1 = i < paths1.size() ? paths1[i] : empty_path;
- const path& p2 = n < paths2.size() ? paths2[n] : empty_path;
-
- const float new_ax = flerp(p1.ap.x, p2.ap.x, ratio);
- const float new_ay = flerp(p1.ap.y, p2.ap.y, ratio);
-
- p.reset(new_ax, new_ay, p1.getLeftFill(),
- p2.getRightFill(), p1.getLineStyle());
-
- // edges;
- const size_t len = p1.size();
- p.m_edges.resize(len);
-
- for (size_t j=0; j < p.size(); j++)
- {
- edge& e = p[j];
- const edge& e1 = j < p1.size() ? p1[j] : empty_edge;
- const edge& e2 = k < p2.size() ? p2[k] : empty_edge;
-
- e.cp.x = static_cast<int>(flerp(e1.cp.x, e2.cp.x, ratio));
- e.cp.y = static_cast<int>(flerp(e1.cp.y, e2.cp.y, ratio));
- e.ap.x = static_cast<int>(flerp(e1.ap.x, e2.ap.x, ratio));
- e.ap.y = static_cast<int>(flerp(e1.ap.y, e2.ap.y, ratio));
- ++k;
-
- if (p2.size() <= k) {
- k = 0;
- ++n;
- }
- }
- }
-
- // display
- render::drawShape(this, inst);
-
-}
-
-
-void morph2_character_def::read(SWFStream& in, SWF::TagType tag,
- movie_definition& md)
-{
- assert(tag == SWF::DEFINEMORPHSHAPE
- || tag == SWF::DEFINEMORPHSHAPE2
- || tag == SWF::DEFINEMORPHSHAPE2_);
-
- rect bound1, bound2;
- bound1.read(in);
- bound2.read(in);
-
- if (tag == SWF::DEFINEMORPHSHAPE2 || tag == SWF::DEFINEMORPHSHAPE2_) {
+namespace SWF {
+
+void
+DefineMorphShapeTag::loader(SWFStream& in, TagType tag, movie_definition& md,
+ const RunInfo& /*r*/)
+{
+ in.ensureBytes(2);
+ boost::uint16_t id = in.read_u16();
+
+ IF_VERBOSE_PARSE(
+ log_parse("DefineMorphShapeTag: id = %d", id);
+ );
+
+ DefineMorphShapeTag* morph = new DefineMorphShapeTag(in, tag, md);
+ md.addDisplayObject(id, morph);
+}
+
+DefineMorphShapeTag::DefineMorphShapeTag(SWFStream& in, TagType tag,
+ movie_definition& md)
+{
+ read(in, tag, md);
+}
+
+DisplayObject*
+DefineMorphShapeTag::createDisplayObject(DisplayObject* parent, int id)
+{
+ return new MorphShape(this, parent, id);
+}
+
+void
+DefineMorphShapeTag::display(const MorphShape& inst) const
+{
+ render::drawShape(inst.shape(), inst.get_world_cxform(),
+ inst.getWorldMatrix());
+}
+
+
+void
+DefineMorphShapeTag::read(SWFStream& in, TagType tag,
+ movie_definition& md)
+{
+ assert(tag == DEFINEMORPHSHAPE
+ || tag == DEFINEMORPHSHAPE2
+ || tag == DEFINEMORPHSHAPE2_);
+
+ rect bounds1, bounds2;
+ bounds1.read(in);
+ bounds2.read(in);
+
+ if (tag == DEFINEMORPHSHAPE2 || tag == DEFINEMORPHSHAPE2_) {
// TODO: Use these values.
- rect inner_bound1, inner_bound2;
- inner_bound1.read(in);
- inner_bound2.read(in);
+ rect innerBound1, innerBound2;
+ innerBound1.read(in);
+ innerBound2.read(in);
+
// This should be used -- first 6 bits reserved, then
// 'non-scaling' stroke, then 'scaling' stroke -- these can be
// used to optimize morphing.
-
in.ensureBytes(1);
static_cast<void>(in.read_u8());
}
@@ -248,56 +103,45 @@
fill_style fs1, fs2;
for (size_t i = 0; i < fillCount; ++i) {
fs1.read(in, tag, md, &fs2);
- m_shape1->addFillStyle(fs1);
- m_shape2->addFillStyle(fs2);
+ _shape1.addFillStyle(fs1);
+ _shape2.addFillStyle(fs2);
}
const boost::uint16_t lineCount = in.read_variable_count();
line_style ls1, ls2;
for (size_t i = 0; i < lineCount; ++i) {
ls1.read_morph(in, tag, md, &ls2);
- m_shape1->addLineStyle(ls1);
- m_shape2->addLineStyle(ls2);
+ _shape1.addLineStyle(ls1);
+ _shape2.addLineStyle(ls2);
}
- m_shape1->read(in, tag, false, md);
+ _shape1.read(in, tag, md);
in.align();
- m_shape2->read(in, tag, false, md);
+ _shape2.read(in, tag, md);
// Set bounds as read in *this* tags rather then
- // the one computed from shape_character_def parser
+ // the one computed from ShapeRecord parser
// (does it make sense ?)
- m_shape1->set_bound(bound1);
- m_shape2->set_bound(bound2);
-
- const shape_character_def::FillStyles& s1Fills = m_shape1->fillStyles();
-
- const shape_character_def::LineStyles& s1Lines = m_shape1->lineStyles();
-
- assert(s1Fills.size() == m_shape2->fillStyles().size());
- assert(s1Lines.size() == m_shape2->lineStyles().size());
-
- // setup array size
- _fill_styles.resize(s1Fills.size());
- FillStyles::const_iterator s1 = s1Fills.begin();
- for (FillStyles::iterator i = _fill_styles.begin(), e = _fill_styles.end();
- i != e; ++i, ++s1) {
-
- i->m_gradients.resize(s1->m_gradients.size());
- }
-
- _line_styles.resize(s1Lines.size());
- _paths.resize(m_shape1->paths().size());
-
- const unsigned edges1 = PathList::computeNumberOfEdges(m_shape1->paths());
- const unsigned edges2 = PathList::computeNumberOfEdges(m_shape2->paths());
+ _shape1.setBounds(bounds1);
+ _shape2.setBounds(bounds2);
+
+ // Starting bounds are the same as shape1
+ _bounds = bounds1;
+
+ assert(_shape1.fillStyles().size() == _shape2.fillStyles().size());
+ assert(_shape1.lineStyles().size() == _shape2.lineStyles().size());
+
+#if 0
+
+ const unsigned edges1 = PathList::computeNumberOfEdges(_shape1.paths());
+ const unsigned edges2 = PathList::computeNumberOfEdges(_shape2.paths());
IF_VERBOSE_PARSE(
log_parse("morph: "
"startShape(paths:%d, edges:%u), "
"endShape(paths:%d, edges:%u)",
- m_shape1->paths().size(), edges1,
- m_shape2->paths().size(), edges2);
+ _shape1.paths().size(), edges1,
+ _shape2.paths().size(), edges2);
);
IF_VERBOSE_MALFORMED_SWF(
@@ -310,9 +154,11 @@
}
);
+#endif
}
+} // namespace SWF
} // namespace gnash
// Local Variables:
=== renamed file 'libcore/parser/morph2_character_def.h' =>
'libcore/swf/DefineMorphShapeTag.h'
--- a/libcore/parser/morph2_character_def.h 2009-04-03 09:18:40 +0000
+++ b/libcore/swf/DefineMorphShapeTag.h 2009-04-07 12:34:43 +0000
@@ -1,27 +1,73 @@
-// morph2.h -- Mike Shaver <address@hidden> 2003, , Vitalij Alexeev
<address@hidden> 2004.
-
-// This source code has been donated to the Public Domain. Do
-// whatever you want with it.
-
-#ifndef GNASH_MORPH2_H
-#define GNASH_MORPH2_H
+// DefineMorphShapeTag.h: Load and parse morphing shapes, for Gnash.
+//
+// Copyright (C) 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
+//
+// Based on the public domain work of Mike Shaver <address@hidden> 2003,
+// Vitalij Alexeev <address@hidden> 2004.
+
+#ifndef GNASH_SWF_MORPH_SHAPE_H
+#define GNASH_SWF_MORPH_SHAPE_H
#include "smart_ptr.h" // GNASH_USE_GC
-#include "shape_character_def.h" // for inheritance of morph2_character_def
#include "swf.h"
-
-namespace gnash {
-
-class SWFStream;
+#include "ShapeRecord.h"
+#include "DefinitionTag.h"
+
+// Forward declarations.
+namespace gnash {
+ class movie_definition;
+ class SWFStream;
+ class MorphShape;
+}
+
+namespace gnash {
+namespace SWF {
/// DefineMorphShape tag
//
-class morph2_character_def : public shape_character_def
+class DefineMorphShapeTag : public DefinitionTag
{
public:
- morph2_character_def();
- virtual ~morph2_character_def();
-
+
+ static void loader(SWFStream& in, TagType tag, movie_definition& m,
+ const RunInfo& r);
+
+ virtual ~DefineMorphShapeTag() {}
+
+ virtual DisplayObject* createDisplayObject(DisplayObject* parent, int
id);
+
+ virtual void display(const MorphShape& inst) const;
+
+ const ShapeRecord& shape1() const {
+ return _shape1;
+ }
+
+ const ShapeRecord& shape2() const {
+ return _shape2;
+ }
+
+ virtual const rect& get_bound() const {
+ return _bounds;
+ }
+
+private:
+
+ DefineMorphShapeTag(SWFStream& in, SWF::TagType tag, movie_definition& md);
+
/// Read a DefineMorphShape tag from stream
//
/// Throw ParserException if the tag is malformed
@@ -41,41 +87,18 @@
///
void read(SWFStream& in, SWF::TagType tag, movie_definition& m);
- virtual void display(DisplayObject* inst);
-
- // Question: What is the bound of a morph? Is this conceptually correct?
- /// TODO: optimize this by take ratio into consideration, to decrease some
- /// invalidated area when rendering morphs
- virtual const rect& get_bound() const
- {
- _bound.expand_to_rect(m_shape1->get_bound());
- _bound.expand_to_rect(m_shape2->get_bound());
- return _bound;
- }
-
-protected:
-
-#ifdef GNASH_USE_GC
- /// Reachable resources are:
- /// - The start and end shapes (m_shape1, m_shape2)
- virtual void markReachableResources() const
- {
- if (m_shape1) m_shape1->setReachable();
- if (m_shape2) m_shape2->setReachable();
- }
-#endif
-
-private:
- boost::intrusive_ptr<shape_character_def> m_shape1;
- boost::intrusive_ptr<shape_character_def> m_shape2;
-
- mutable rect _bound;
-
+ ShapeRecord _shape1;
+ ShapeRecord _shape2;
+
+ rect _bounds;
+
};
+
+} // namespace SWF
} // namespace gnash
-#endif // GNASH_MORPH2_H
+#endif
// Local Variables:
// mode: C++
=== renamed file 'libcore/parser/shape_character_def.cpp' =>
'libcore/swf/DefineShapeTag.cpp'
--- a/libcore/parser/shape_character_def.cpp 2009-04-03 09:48:13 +0000
+++ b/libcore/swf/DefineShapeTag.cpp 2009-04-07 13:07:42 +0000
@@ -1,4 +1,4 @@
-// shape_character_def.cpp: Quadratic bezier outline shapes, for Gnash.
+// DefineShapeTag.cpp: Quadratic bezier outline shapes, for Gnash.
//
// Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
//
@@ -23,7 +23,7 @@
// Quadratic bezier outline shapes are the basis for most SWF rendering.
-#include "shape_character_def.h"
+#include "DefineShapeTag.h"
#include "smart_ptr.h" // GNASH_USE_GC
#include "impl.h"
#include "log.h"
@@ -31,6 +31,7 @@
#include "Shape.h"
#include "SWFStream.h"
#include "MovieClip.h"
+#include "swf.h"
#include <algorithm>
@@ -38,844 +39,64 @@
// and compare them with the bounds encoded in the SWF
//#define GNASH_DEBUG_SHAPE_BOUNDS 1
-namespace gnash
+namespace gnash {
+namespace SWF {
+
+void
+DefineShapeTag::loader(SWFStream& in, TagType tag, movie_definition& m,
+ const RunInfo& /*r*/)
{
+ assert(tag == DEFINESHAPE ||
+ tag == DEFINESHAPE2 ||
+ tag == DEFINESHAPE3 ||
+ tag == DEFINESHAPE4 ||
+ tag == DEFINESHAPE4_);
+
+ in.ensureBytes(2);
+ boost::uint16_t id = in.read_u16();
+ IF_VERBOSE_PARSE(
+ log_parse(_("DefineShapeTag(%s): id = %d"), tag, id);
+ );
+
+ DefineShapeTag* ch = new DefineShapeTag(in, tag, m);
+ m.addDisplayObject(id, ch);
+
+}
DisplayObject*
-shape_character_def::createDisplayObject(DisplayObject* parent, int id)
+DefineShapeTag::createDisplayObject(DisplayObject* 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,
- SWF::TagType tag, movie_definition& m)
-{
- in.ensureBytes(1);
- boost::uint16_t fill_style_count = in.read_u8();
- if (tag > 2)
- {
- if (fill_style_count == 0xFF)
- {
- in.ensureBytes(2);
- fill_style_count = in.read_u16();
- }
- }
-
- IF_VERBOSE_PARSE (
- log_parse(_(" read_fill_styles: count = %u"), fill_style_count);
- );
-
- // Read the styles.
- styles.reserve(styles.size()+fill_style_count);
- for (boost::uint16_t i = 0; i < fill_style_count; ++i)
- {
- // TODO: add a fill_style constructor directly reading from stream
- fill_style fs;
- fs.read(in, tag, m);
- styles.push_back(fs);
- }
-}
-
-// Read line styles and push them onto the back of the given array.
-static void
-read_line_styles(std::vector<line_style>& styles, SWFStream& in, SWF::TagType
tag,
- movie_definition& md)
-{
- in.ensureBytes(1);
- int line_style_count = in.read_u8();
-
- IF_VERBOSE_PARSE(
- log_parse(_(" read_line_styles: count = %d"), line_style_count);
- );
-
- if (line_style_count == 0xFF)
- {
- in.ensureBytes(2);
- line_style_count = in.read_u16();
- IF_VERBOSE_PARSE(
- log_parse(_(" read_line_styles: count2 = %d"), line_style_count);
- );
- }
-
- // Read the styles.
- for (int i = 0; i < line_style_count; i++)
- {
- styles.resize(styles.size() + 1);
- styles.back().read(in, tag, md);
- }
-}
-
-shape_character_def::shape_character_def()
- :
- character_def(),
- _fill_styles(),
- _line_styles(),
- _paths(),
- _bound()
-{ }
-
-shape_character_def::shape_character_def(const shape_character_def& o)
- :
- character_def(o),
- _fill_styles(o._fill_styles),
- _line_styles(o._line_styles),
- _paths(o._paths),
- _bound(o._bound)
- {
- }
-
-shape_character_def::~shape_character_def()
-{
-}
-
-void
-shape_character_def::read(SWFStream& in, SWF::TagType tag, bool with_style,
- movie_definition& m)
-{
- if (with_style)
- {
- _bound.read(in);
-
- IF_VERBOSE_PARSE(
- std::string b = _bound.toString();
- log_parse(_(" bound rect: %s"), b.c_str());
- );
-
- // TODO: Store and use these. Unfinished.
- if (tag == SWF::DEFINESHAPE4 || tag == SWF::DEFINESHAPE4_)
- {
- rect tbound;
- tbound.read(in);
- in.ensureBytes(1);
- static_cast<void>(in.read_u8());
- LOG_ONCE(log_unimpl("DEFINESHAPE4 edge boundaries and scales"));
- }
-
- read_fill_styles(_fill_styles, in, tag, m);
- read_line_styles(_line_styles, in, tag, m);
- }
-
- /// Adding a dummy fill style is just needed to make the
- /// parser somewhat more robust. This fill style is not
- /// really used, as text rendering will use style information
- /// from TEXTRECORD tag instead.
- ///
- if (tag == SWF::DEFINEFONT || tag == SWF::DEFINEFONT2 )
- {
- assert(!with_style);
- }
-
- // Use read_u8 to force alignment.
- in.ensureBytes(1);
- boost::uint8_t num_bits = in.read_u8();
- int num_fill_bits = (num_bits & 0xF0) >> 4;
- int num_line_bits = (num_bits & 0x0F);
-
- IF_VERBOSE_PARSE(
- log_parse(_(" shape_character_def read: nfillbits = %d, "
- "nlinebits = %d"), num_fill_bits, num_line_bits);
- );
-
- if ( !num_fill_bits && !num_line_bits )
- {
- /// When reading font glyphs it happens to read 1 byte
- /// past end boundary of a glyph due to fill/line bits being
- /// zero.
- ///
- /// Generally returning here seems to break morphs:
- /// http://savannah.gnu.org/bugs/?21747
- /// And other normal shapes:
- /// http://savannah.gnu.org/bugs/?21923
- /// http://savannah.gnu.org/bugs/?22000
- ///
- /// So for now we only return if NOT reading a morph shape.
- /// Pretty ugly... till next bug report.
- ///
- ///
- if (tag == SWF::DEFINEFONT || tag == SWF::DEFINEFONT2 ||
- tag == SWF::DEFINEFONT3)
- {
- log_debug("Skipping glyph read, being fill and line bits zero. "
- "SWF tag is %d.", tag);
- return;
- }
- }
-
- // These are state variables that keep the
- // current position & style of the shape
- // outline, and vary as we read the edge data.
- //
- // At the moment we just store each edge with
- // the full necessary info to render it, which
- // is simple but not optimally efficient.
- int fill_base = 0;
- int line_base = 0;
- int x = 0, y = 0;
- path current_path;
-
-#define SHAPE_LOG 0
-
- // SHAPERECORDS
- for (;;)
- {
- in.ensureBits(1);
- bool isEdgeRecord = in.read_bit();
- if (!isEdgeRecord)
- {
- // Parse the record.
- in.ensureBits(5);
- int flags = in.read_uint(5);
- if (flags == flagEnd)
- {
- // Store the current path if any.
- if (! current_path.is_empty())
- {
- _paths.push_back(current_path);
- current_path.m_edges.resize(0);
- }
- break;
- }
- if (flags & flagMove)
- {
- // Store the current path if any, and prepare a fresh one.
- if (! current_path.is_empty())
- {
- _paths.push_back(current_path);
- current_path.m_edges.resize(0);
- }
- in.ensureBits(5);
- int num_move_bits = in.read_uint(5);
- in.ensureBits(2 * num_move_bits);
- int move_x = in.read_sint(num_move_bits);
- int move_y = in.read_sint(num_move_bits);
-
- x = move_x;
- y = move_y;
-
- // Set the beginning of the path.
- current_path.ap.x = x;
- current_path.ap.y = y;
-
-#if SHAPE_LOG
- IF_VERBOSE_PARSE(
- log_parse(_(" Shape read: moveto %d %d"), x, y);
- );
-#endif
- }
- if ((flags & flagFillStyle0Change) && num_fill_bits > 0)
- {
- // fill_style_0_change = 1;
- if (! current_path.is_empty())
- {
- _paths.push_back(current_path);
- current_path.m_edges.resize(0);
- current_path.ap.x = x;
- current_path.ap.y = y;
- }
- in.ensureBits(num_fill_bits);
- unsigned style = in.read_uint(num_fill_bits);
- if (style > 0)
- {
- style += fill_base;
- }
-
- if (tag == SWF::DEFINEFONT || tag == SWF::DEFINEFONT2)
- {
- if ( style > 1 ) // 0:hide 1:renderer
- {
- IF_VERBOSE_MALFORMED_SWF(
- log_swferror(_("Invalid fill style %d in "
- "fillStyle0Change record for font tag "
- "(0 or 1 valid). Set to 0."), style);
- );
- style = 0;
- }
- }
- else
- {
- // 1-based index
- if ( style > _fill_styles.size() )
- {
- IF_VERBOSE_MALFORMED_SWF(
- log_swferror(_("Invalid fill style %d in "
- "fillStyle0Change record - %d defined. "
- "Set to 0."), style, _fill_styles.size());
- );
- style = 0;
- }
- }
-
- current_path.setLeftFill(style);
-#if SHAPE_LOG
- IF_VERBOSE_PARSE(
- log_parse(_(" Shape read: fill0 (left) = %d"),
- current_path.getLeftFill());
- );
-#endif
- }
- if ((flags & flagFillStyle1Change) && num_fill_bits > 0)
- {
- // fill_style_1_change = 1;
- if (! current_path.is_empty())
- {
- _paths.push_back(current_path);
- current_path.m_edges.resize(0);
- current_path.ap.x = x;
- current_path.ap.y = y;
- }
- in.ensureBits(num_fill_bits);
- unsigned style = in.read_uint(num_fill_bits);
- if (style > 0)
- {
- style += fill_base;
- }
-
- if (tag == SWF::DEFINEFONT || tag == SWF::DEFINEFONT2)
- {
- if ( style > 1 ) // 0:hide 1:renderer
- {
- IF_VERBOSE_MALFORMED_SWF(
- log_swferror(_("Invalid fill style %d in "
- "fillStyle1Change record for font tag "
- "(0 or 1 valid). Set to 0."), style);
- );
- style = 0;
- }
- }
- else
- {
- // 1-based index
- if ( style > _fill_styles.size() )
- {
- IF_VERBOSE_MALFORMED_SWF(
- log_swferror(_("Invalid fill style %d in "
- "fillStyle1Change record - %d defined. "
- "Set to 0."), style, _fill_styles.size());
- );
- style = 0;
- }
- }
- current_path.setRightFill(style);
-#if SHAPE_LOG
- IF_VERBOSE_PARSE (
- log_parse(_(" Shape read: fill1 (right) = %d"),
- current_path.getRightFill());
- );
-#endif
- }
- if ((flags & flagLineStyleChange) && num_line_bits > 0)
- {
- // line_style_change = 1;
- if (! current_path.is_empty())
- {
- _paths.push_back(current_path);
- current_path.m_edges.resize(0);
- current_path.ap.x = x;
- current_path.ap.y = y;
- }
- in.ensureBits(num_line_bits);
- unsigned style = in.read_uint(num_line_bits);
- if (style > 0)
- {
- style += line_base;
- }
- if (tag == SWF::DEFINEFONT || tag == SWF::DEFINEFONT2)
- {
- if ( style > 1 ) // 0:hide 1:renderer
- {
- IF_VERBOSE_MALFORMED_SWF(
- log_swferror(_("Invalid line style %d in "
- "lineStyleChange record for font tag "
- "(0 or 1 valid). Set to 0."), style);
- );
- style = 0;
- }
- }
- else {
- // 1-based index
- if (style > _line_styles.size()) {
- IF_VERBOSE_MALFORMED_SWF(
- log_swferror(_("Invalid fill style %d in "
- "lineStyleChange record - %d defined. "
- "Set to 0."), style, _line_styles.size());
- );
- style = 0;
- }
- }
- current_path.setLineStyle(style);
-#if SHAPE_LOG
- IF_VERBOSE_PARSE(
- log_parse(_(" Shape_read: line = %d"),
- current_path.getLineStyle());
- )
-#endif
- }
- if (flags & flagHasNewStyles)
- {
- if (!with_style)
- {
- IF_VERBOSE_MALFORMED_SWF(
- log_swferror("Unexpected HasNewStyle flag in tag "
- "%d shape record", tag);
- );
- continue;
- }
- IF_VERBOSE_PARSE (
- log_parse(_(" Shape read: more fill styles"));
- );
-
- // Store the current path if any.
- if (! current_path.is_empty())
- {
- _paths.push_back(current_path);
- current_path.clear();
- }
-
- // Tack on an empty path signalling a new shape.
- // @@ need better understanding of whether this is
correct??!?!!
- // @@ i.e., we should just start a whole new shape here, right?
- _paths.push_back(path());
- _paths.back().m_new_shape = true;
-
- fill_base = _fill_styles.size();
- line_base = _line_styles.size();
- read_fill_styles(_fill_styles, in, tag, m);
- read_line_styles(_line_styles, in, tag, m);
-
- in.ensureBits(8);
- num_fill_bits = in.read_uint(4);
- num_line_bits = in.read_uint(4);
- }
- }
- else
- {
- // EDGERECORD
- in.ensureBits(1);
- bool edge_flag = in.read_bit();
- if (edge_flag == 0)
- {
- in.ensureBits(4);
- int num_bits = 2 + in.read_uint(4);
- // curved edge
- in.ensureBits(4 * num_bits);
- int cx = x + in.read_sint(num_bits);
- int cy = y + in.read_sint(num_bits);
- int ax = cx + in.read_sint(num_bits);
- int ay = cy + in.read_sint(num_bits);
-
-#if SHAPE_LOG
- IF_VERBOSE_PARSE (
- log_parse(_(" Shape read: curved edge = "
- "%d %d - %d %d - %d %d"), x, y, cx, cy, ax, ay);
- );
-#endif
- current_path.m_edges.push_back(edge(cx, cy, ax, ay));
- x = ax;
- y = ay;
- }
- else
- {
- // straight edge
- in.ensureBits(5);
- int num_bits = 2 + in.read_uint(4);
- bool line_flag = in.read_bit();
- int dx = 0, dy = 0;
- if (line_flag)
- {
- // General line.
- in.ensureBits(2 * num_bits);
- dx = in.read_sint(num_bits);
- dy = in.read_sint(num_bits);
- }
- else
- {
- in.ensureBits(1);
- bool vert_flag = in.read_bit();
- if (vert_flag == 0)
- {
- // Horizontal line.
- in.ensureBits(num_bits);
- dx = in.read_sint(num_bits);
- }
- else
- {
- // Vertical line.
- in.ensureBits(num_bits);
- dy = in.read_sint(num_bits);
- }
- }
-
-#if SHAPE_LOG
- IF_VERBOSE_PARSE (
- log_parse(_(" Shape_read: straight edge = "
- "%d %d - %d %d"), x, y, x + dx, y + dy);
- );
-#endif
- current_path.m_edges.push_back(edge(x + dx, y + dy,
- x + dx, y + dy));
- x += dx;
- y += dy;
- }
- }
- }
-
- if ( ! with_style )
- {
- // TODO: performance would be improved by computing
- // the bounds as edges are parsed.
- compute_bound(_bound, m.get_version());
- }
-#ifdef GNASH_DEBUG_SHAPE_BOUNDS
- else
- {
- rect computedBounds;
- compute_bound(computedBounds, m->get_version());
- if ( computedBounds != m_bounds )
- {
- log_debug("Shape DisplayObject read for tag %d contained embedded "
- "bounds %s, while we computed bounds %s",
- tag, m_bound, computedBounds);
- }
- }
-#endif
-}
-
-void
-shape_character_def::display(DisplayObject* inst)
-{
- // Draw the shape using our own inherent styles.
- render::drawShape(this, inst);
-}
-
-
-// TODO: this should be moved to libgeometry or something
-// Finds the quadratic bezier curve crossings with the line Y.
-// The function can have zero, one or two solutions (cross1, cross2). The
-// return value of the function is the number of solutions.
-// x0, y0 = start point of the curve
-// x1, y1 = end point of the curve (anchor, aka ax|ay)
-// cx, cy = control point of the curve
-// If there are two crossings, cross1 is the nearest to x0|y0 on the curve.
-int curve_x_crossings(float x0, float y0, float x1, float y1,
- float cx, float cy, float y, float &cross1, float &cross2)
-{
- int count=0;
-
- // check if any crossings possible
- if ( ((y0 < y) && (y1 < y) && (cy < y))
- || ((y0 > y) && (y1 > y) && (cy > y)) )
- {
- // all above or below -- no possibility of crossing
- return 0;
- }
-
- // Quadratic bezier is:
- //
- // p = (1-t)^2 * a0 + 2t(1-t) * c + t^2 * a1
- //
- // We need to solve for x at y.
-
- // Use the quadratic formula.
-
- // Numerical Recipes suggests this variation:
- // q = -0.5 [b +sgn(b) sqrt(b^2 - 4ac)]
- // x1 = q/a; x2 = c/q;
-
- float A = y1 + y0 - 2 * cy;
- float B = 2 * (cy - y0);
- float C = y0 - y;
-
- float rad = B * B - 4 * A * C;
-
- if (rad < 0)
- {
- return 0;
- }
- else
- {
- float q;
- float sqrt_rad = sqrtf(rad);
- if (B < 0)
- {
- q = -0.5f * (B - sqrt_rad);
- }
- else
- {
- q = -0.5f * (B + sqrt_rad);
- }
-
- // The old-school way.
- // float t0 = (-B + sqrt_rad) / (2 * A);
- // float t1 = (-B - sqrt_rad) / (2 * A);
-
- if (q != 0)
- {
- float t1 = C / q;
- if (t1 >= 0 && t1 < 1)
- {
- float x_at_t1 =
- x0 + 2 * (cx - x0) * t1 + (x1 + x0 - 2 * cx) * t1 * t1;
-
- count++;
- assert(count==1);
- cross1 = x_at_t1; // order is important!
- }
- }
-
- if (A != 0)
- {
- float t0 = q / A;
- if (t0 >= 0 && t0 < 1)
- {
- float x_at_t0 =
- x0 + 2 * (cx - x0) * t0 + (x1 + x0 - 2 * cx) * t0 * t0;
-
- count++;
- // order is important!
- if (count == 2) cross2 = x_at_t0;
- else cross1 = x_at_t0;
- }
- }
-
- }
-
- return count;
-}
-
-bool shape_character_def::point_test_local(boost::int32_t x,
- boost::int32_t y, const SWFMatrix& wm)
-{
- /*
- Principle:
- For the fill of the shape, we project a ray from the test point to the left
- side of the shape counting all crossings. When a line or curve segment is
- crossed we add 1 if the left fill style is set. Regardless of the left fill
- style we subtract 1 from the counter then the right fill style is set.
- This is true when the line goes in downward direction. If it goes upward,
- the fill styles are reversed.
-
- The final counter value reveals if the point is inside the shape (and
- depends on filling rule, see below).
- This method should not depend on subshapes and work for some malformed
- shapes situations:
- - wrong fill side (eg. left side set for a clockwise drawen rectangle)
- - intersecting paths
- */
- point pt(x, y);
-
- // later we will need non-zero for glyphs... (TODO)
- bool even_odd = true;
-
- // FIXME: if the shape contains non-scaled strokes
- // we can't rely on boundary itself for a quick
- // way out. Bounds supposedly already include
- // thickness, so we might keep a flag telling us
- // whether *non_scaled* strokes are present
- // and if not still use the boundary check.
- // NOTE: just skipping this test breaks a corner-case
- // in DrawingApiTest (kind of a fill-leakage making
- // the collision detection find you inside a self-crossing
- // shape).
- //
- if (_bound.point_test(x, y) == false)
- {
- return false;
- }
-
- unsigned npaths = _paths.size();
- int counter = 0;
-
- // browse all paths
- for (unsigned pno=0; pno<npaths; pno++)
- {
- const path& pth = _paths[pno];
- unsigned nedges = pth.m_edges.size();
-
- float next_pen_x = pth.ap.x;
- float next_pen_y = pth.ap.y;
- float pen_x, pen_y;
-
- if (pth.m_new_shape)
- {
- if ( ( even_odd && (counter % 2) != 0) ||
- (!even_odd && (counter != 0)) )
- {
- // the point is inside the previous subshape, so exit now
- return true;
- }
-
- counter=0;
- }
- if (pth.empty()) continue;
-
- // If the path has a line style, check for strokes there
- if (pth.m_line != 0 )
- {
- assert(_line_styles.size() >= pth.m_line);
- line_style& ls = _line_styles[pth.m_line-1];
- double thickness = ls.getThickness();
- if (! thickness )
- {
- thickness = 20; // at least ONE PIXEL thick.
- }
- else if ((!ls.scaleThicknessVertically()) &&
- (!ls.scaleThicknessHorizontally()) )
- {
- // TODO: pass the SWFMatrix to withinSquareDistance instead ?
- double xScale = wm.get_x_scale();
- double yScale = wm.get_y_scale();
- //log_debug("thickness:%d, xScale:%g, yScale:%g", thickness, xScale,
yScale);
- thickness *= std::max(xScale, yScale);
- //log_debug("after scaling, thickness:%d", thickness);
- }
- else if (ls.scaleThicknessVertically() !=
- ls.scaleThicknessHorizontally())
- {
- LOG_ONCE( log_unimpl("Collision detection for "
- "unidirectionally scaled strokes") );
- }
-
- double dist = thickness / 2.0;
- double sqdist = dist * dist;
- if (pth.withinSquareDistance(pt, sqdist))
- return true;
- }
-
- // browse all edges of the path
- for (unsigned eno=0; eno<nedges; eno++)
- {
- const edge& edg = pth.m_edges[eno];
- pen_x = next_pen_x;
- pen_y = next_pen_y;
- next_pen_x = edg.ap.x;
- next_pen_y = edg.ap.y;
-
- float cross1, cross2;
- int dir1, dir2 = 0; // +1 = downward, -1 = upward
- int crosscount = 0;
-
- if (edg.is_straight())
- {
- // ignore horizontal lines
- // TODO: better check for small difference?
- if (edg.ap.y == pen_y)
- {
- continue;
- }
- // does this line cross the Y coordinate?
- if ( ((pen_y <= y) && (edg.ap.y >= y))
- || ((pen_y >= y) && (edg.ap.y <= y)) )
- {
-
- // calculate X crossing
- cross1 = pen_x + (edg.ap.x - pen_x) *
- (y - pen_y) / (edg.ap.y - pen_y);
-
- if (pen_y > edg.ap.y)
- dir1 = -1; // upward
- else
- dir1 = +1; // downward
-
- crosscount = 1;
- }
- else
- {
- // no crossing found
- crosscount = 0;
- }
- }
- else
- {
- // ==> curve case
- crosscount = curve_x_crossings(pen_x, pen_y, edg.ap.x,
edg.ap.y,
- edg.cp.x, edg.cp.y, y, cross1, cross2);
- dir1 = pen_y > y ? -1 : +1;
- dir2 = dir1 * (-1); // second crossing always in opposite dir.
- } // curve
-
- // ==> we have now:
- // - one (cross1) or two (cross1, cross2) ray crossings (X
- // coordinate)
- // - dir1/dir2 tells the direction of the crossing
- // (+1 = downward, -1 = upward)
- // - crosscount tells the number of crossings
-
- // need at least one crossing
- if (crosscount == 0)
- {
- continue;
- }
-
- bool touched = false;
-
- // check first crossing
- if (cross1 <= x)
- {
- if (pth.m_fill0 > 0) counter += dir1;
- if (pth.m_fill1 > 0) counter -= dir1;
-
- touched = true;
- }
-
- // check optional second crossing (only possible with curves)
- if ( (crosscount > 1) && (cross2 <= x) )
- {
- if (pth.m_fill0 > 0) counter += dir2;
- if (pth.m_fill1 > 0) counter -= dir2;
-
- touched = true;
- }
-
- }// for edge
- } // for path
-
- return ( (even_odd && (counter % 2) != 0) ||
- (!even_odd && (counter != 0)) );
-}
-
-// Find the bounds of this shape, and store them in the given rectangle.
-void
-shape_character_def::compute_bound(rect& r, int swfVersion) const
-{
- r.set_null();
-
- for (unsigned int i = 0; i < _paths.size(); i++)
- {
- const path& p = _paths[i];
-
- unsigned thickness = 0;
- if ( p.m_line )
- {
- // For glyph shapes m_line is allowed to be 1
- // while no defined line styles are allowed.
- if ( _line_styles.empty() )
- {
- // This is either a Glyph, for which m_line==1 is valid
- // or a bug in the parser, which we have no way to
- // check at this time
- assert(p.m_line == 1);
- }
- else
- {
- thickness = _line_styles[p.m_line-1].getThickness();
- }
- }
- p.expandBounds(r, thickness, swfVersion);
- }
-}
-
-#ifdef GNASH_USE_GC
-void shape_character_def::markReachableResources() const
-{
- assert(isReachable());
- std::for_each(_fill_styles.begin(), _fill_styles.end(),
- std::mem_fun_ref(&fill_style::markReachableResources));
-}
-#endif
-
-} // end namespace gnash
+
+bool
+DefineShapeTag::pointTestLocal(boost::int32_t x, boost::int32_t y,
+ const SWFMatrix& wm) const
+{
+ return geometry::pointTest(_shape.paths(), _shape.lineStyles(), x, y, wm);
+}
+
+
+DefineShapeTag::DefineShapeTag(SWFStream& in, TagType tag,
+ movie_definition& m)
+ :
+ DefinitionTag(),
+ _shape(in, tag, m)
+{
+}
+
+void
+DefineShapeTag::display(const DisplayObject& inst) const
+{
+ render::drawShape(_shape, inst.get_world_cxform(), inst.getWorldMatrix());
+}
+
+void
+DefineShapeTag::markReachableResources() const
+{}
+
+} // namespace SWF
+} // namespace gnash
// Local Variables:
// mode: C++
=== renamed file 'libcore/parser/shape_character_def.h' =>
'libcore/swf/DefineShapeTag.h'
--- a/libcore/parser/shape_character_def.h 2009-04-03 09:18:40 +0000
+++ b/libcore/swf/DefineShapeTag.h 2009-04-07 12:45:25 +0000
@@ -9,100 +9,44 @@
#ifndef GNASH_SHAPE_CHARACTER_DEF_H
#define GNASH_SHAPE_CHARACTER_DEF_H
-#include "character_def.h" // for inheritance of shape_character_def
+#include "DefinitionTag.h" // for inheritance of DefineShapeTag
#include "smart_ptr.h" // GNASH_USE_GC
-#include "Geometry.h" // for path
-#include "rect.h" // for composition
-#include "fill_style.h" // for fill style
-#include "styles.h" // for line style
#include "swf.h"
-
-#include <vector> // for composition
-
+#include "ShapeRecord.h"
namespace gnash {
class SWFStream;
class cxform;
+ class Shape;
class SWFMatrix;
}
namespace gnash {
+namespace SWF {
/// \brief
/// Represents the outline of one or more shapes, along with
/// information on fill and line styles.
-//
-class shape_character_def : public character_def
+class DefineShapeTag : public DefinitionTag
{
public:
- typedef std::vector<fill_style> FillStyles;
- typedef std::vector<line_style> LineStyles;
- typedef std::vector<path> Paths;
-
- shape_character_def();
- virtual ~shape_character_def();
-
- virtual void display(DisplayObject* inst);
-
- /// Return true if the specified point is on the interior of our shape.
- //
- /// Incoming coords are local coords (twips).
- /// The SWFMatrix will be used for lines with non-scalable strokes.
- ///
- virtual bool point_test_local(boost::int32_t x, boost::int32_t y,
- const SWFMatrix& wm);
-
+ static void loader(SWFStream& in, TagType tag, movie_definition& m,
+ const RunInfo& r);
+
+ virtual ~DefineShapeTag() {};
+
+ // Display a Shape character.
+ virtual void display(const DisplayObject& inst) const;
+
+ // Create a Shape DisplayObject.
virtual DisplayObject* createDisplayObject(DisplayObject* parent, int
id);
- /// \brief
- /// Read a shape definition as included in DEFINEFONT*,
- /// DEFINESHAPE* or DEFINEMORPH* tag
- //
- /// @param in
- /// The stream to read the shape from
- ///
- /// @param TagType
- /// The SWF::TagType this shape definition is read for.
- /// TODO: change to an actual SWF::TagType type
- ///
- /// @param with_style
- /// If true, this definition includes bounds, fill styles and line
styles.
- /// Tipically, this is only false for DEFINEFONT* tags.
- /// NOTE: if with_style is false, bounds of the shape will be
computed
- /// rather then read.
- /// TODO: drop this function, set based on TagType ?
- ///
- /// @param m
- /// The movie definition corresponding to the SWF we/re parsing.
- /// This is used to resolve bitmap DisplayObjects for fill styles,
never
- /// used if with_style is false.
- void read(SWFStream& in, SWF::TagType tag, bool with_style,
- movie_definition& m);
-
/// Get cached bounds of this shape.
- const rect& get_bound() const { return _bound; }
-
- /// Compute bounds by looking at the component paths
- void compute_bound(rect& r, int swfVersion) const;
-
- const FillStyles& fillStyles() const { return _fill_styles; }
- const LineStyles& lineStyles() const { return _line_styles; }
-
- const Paths& paths() const { return _paths; }
-
- // morph uses this
- // Should this be verified?
- void set_bound(const rect& r) { _bound = r; }
-
- // Morph uses this.
- void addFillStyle(const fill_style& fs) {
- _fill_styles.push_back(fs);
- }
-
- void addLineStyle(const line_style& fs) {
- _line_styles.push_back(fs);
- }
+ const rect& get_bound() const { return _shape.getBounds(); }
+
+ virtual bool pointTestLocal(boost::int32_t x, boost::int32_t y,
+ const SWFMatrix& wm) const;
protected:
@@ -114,38 +58,22 @@
/// These are not actual resources, but may contain some.
///
virtual void markReachableResources() const;
-#endif // GNASH_USE_GC
-
- // derived morph classes changes these
- FillStyles _fill_styles;
- LineStyles _line_styles;
- Paths _paths;
- rect _bound;
-
- /// Copy a shape DisplayObject definition
- shape_character_def(const shape_character_def& o);
+#endif
private:
- /// Shape record flags
- enum ShapeRecordFlags {
- flagEnd = 0x00,
- flagMove = 0x01,
- flagFillStyle0Change = 0x02,
- flagFillStyle1Change = 0x04,
- flagLineStyleChange = 0x08,
- flagHasNewStyles = 0x10
- };
-
- // Don't assign to a shape DisplayObject definition
- shape_character_def& operator= (const shape_character_def&);
+ DefineShapeTag(SWFStream& in, TagType tag, movie_definition& m);
+
+ /// The actual shape data is stored in this record.
+ const ShapeRecord _shape;
};
-} // end namespace gnash
-
-
-#endif // GNASH_SHAPE_CHARACTER_DEF_H
+} // namespace SWF
+} // namespace gnash
+
+
+#endif
// Local Variables:
=== modified file 'libcore/swf/DefineTextTag.cpp'
--- a/libcore/swf/DefineTextTag.cpp 2009-04-03 09:48:13 +0000
+++ b/libcore/swf/DefineTextTag.cpp 2009-04-07 11:14:10 +0000
@@ -1,4 +1,4 @@
-// DefineTextTag.cpp: Read text DisplayObject definitions, for Gnash.
+// DefineTextTag.cpp: Read StaticText definitions, for Gnash.
// Derived from text.cpp -- Thatcher Ulrich <address@hidden> 2003
@@ -33,7 +33,7 @@
std::auto_ptr<DefineTextTag> t(new DefineTextTag(in, m, tag));
IF_VERBOSE_PARSE(
- log_parse(_("Text DisplayObject, id = %d"), id);
+ log_parse(_("DefineTextTag, id = %d"), id);
);
m.addDisplayObject(id, t.release());
@@ -45,10 +45,9 @@
return new StaticText(this, parent, id);
}
-
bool
DefineTextTag::extractStaticText(std::vector<const TextRecord*>& to,
- size_t& numChars)
+ size_t& numChars) const
{
if (_textRecords.empty()) return false;
@@ -107,7 +106,7 @@
}
void
-DefineTextTag::display(DisplayObject* inst)
+DefineTextTag::display(const StaticText& inst) const
{
const bool useEmbeddedGlyphs = true;
=== modified file 'libcore/swf/DefineTextTag.h'
--- a/libcore/swf/DefineTextTag.h 2009-04-03 09:18:40 +0000
+++ b/libcore/swf/DefineTextTag.h 2009-04-07 12:34:43 +0000
@@ -18,7 +18,7 @@
#ifndef GNASH_SWF_DEFINETEXTTAG_H
#define GNASH_SWF_DEFINETEXTTAG_H
-#include "character_def.h" // for inheritance
+#include "DefinitionTag.h" // for inheritance
#include "styles.h"
#include "rect.h" // for composition
#include "swf.h"
@@ -30,18 +30,19 @@
class movie_definition;
class SWFStream;
class RunInfo;
+ class StaticText;
}
namespace gnash {
namespace SWF {
-/// Text DisplayObject
+/// StaticText DisplayObject
//
/// This is either read from SWF stream
/// or (hopefully) created with scripting
///
-class DefineTextTag : public character_def
+class DefineTextTag : public DefinitionTag
{
public:
@@ -49,7 +50,7 @@
const RunInfo& r);
/// Draw the string.
- void display(DisplayObject* inst);
+ void display(const StaticText& inst) const;
const rect& get_bound() const {
// TODO: There is a _matrix field in the definition(!) that's
@@ -63,7 +64,8 @@
/// if any are present
/// @param size Will contain the number of DisplayObjects in this
/// StaticText definition.
- bool extractStaticText(std::vector<const TextRecord*>& to, size_t& size);
+ bool extractStaticText(std::vector<const TextRecord*>& to, size_t& size)
+ const;
virtual DisplayObject* createDisplayObject(DisplayObject* parent, int id);
=== modified file 'libcore/swf/DefineVideoStreamTag.h'
--- a/libcore/swf/DefineVideoStreamTag.h 2009-04-03 09:18:40 +0000
+++ b/libcore/swf/DefineVideoStreamTag.h 2009-04-07 12:34:43 +0000
@@ -24,7 +24,7 @@
#include "gnashconfig.h"
#endif
-#include "character_def.h"
+#include "DefinitionTag.h"
#include "swf.h"
#include "rect.h" // for composition
#include "MediaParser.h" // for videoFrameType and videoCodecType enums
@@ -69,7 +69,7 @@
namespace SWF {
-class DefineVideoStreamTag : public character_def
+class DefineVideoStreamTag : public DefinitionTag
{
public:
@@ -146,7 +146,7 @@
/// Construct a video stream definition with given ID
//
/// NOTE: for dynamically created definitions (ActionScript Video class
- /// instances) you can use an id of -1. See character_def
+ /// instances) you can use an id of -1. See DefinitionTag
/// constructor, as that's the one which will eventually get passed
/// the id.
/// NOTE: What dynamically created definitions?
=== renamed file 'libcore/parser/character_def.h' =>
'libcore/swf/DefinitionTag.h'
--- a/libcore/parser/character_def.h 2009-04-03 09:18:40 +0000
+++ b/libcore/swf/DefinitionTag.h 2009-04-07 12:45:25 +0000
@@ -15,13 +15,14 @@
// 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_CHARACTER_DEF_H
-#define GNASH_CHARACTER_DEF_H
+#ifndef GNASH_DEFINITION_TAG_H
+#define GNASH_DEFINITION_TAG_H
#include "ExportableResource.h"
#include <boost/cstdint.hpp>
#include <vector>
+#include <boost/noncopyable.hpp>
// Forward declarations
@@ -35,10 +36,7 @@
}
namespace gnash {
-
-
-class render_cache_manager;
-
+namespace SWF {
/// Immutable data representing the template of a movie element.
//
@@ -46,97 +44,26 @@
/// can be mixed into movie_definition and sprite_definition,
/// without using multiple inheritance.
///
-class character_def : public ExportableResource
+class DefinitionTag : public ExportableResource, boost::noncopyable
{
public:
- character_def()
- :
- m_render_cache(0),
- _id(-1)
- {
- }
-
-
- virtual ~character_def();
-
- virtual void display(DisplayObject* /*instance_info*/)
- {
- }
-
- /// Return true if the specified point is on the interior of our shape.
- //
- /// Point coordinates are local coords (TWIPS)
- ///
- /// @param wm
- /// Current world SWFMatrix of the instance we want to check.
- /// This is needed to properly scale non-scalable strokes.
- ///
- virtual bool point_test_local(boost::int32_t /*x*/, boost::int32_t
/*y*/,
- const SWFMatrix& /*wm*/)
- {
- return false;
- }
-
+ virtual ~DefinitionTag() {};
+
/// Should stick the result in a boost::intrusive_ptr immediately.
//
/// default is to make a DisplayObject
///
- virtual DisplayObject* createDisplayObject(DisplayObject* parent, int
id) = 0;
+ virtual DisplayObject* createDisplayObject(DisplayObject* parent,
+ int id) = 0;
// 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)
- /// 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:
-
- /// Copy a DisplayObject definition
- //
- /// The copy will have a NULL render cache object.
- /// The only known use of copy constructor is from
- /// duplicateMovieClip, in particular during copy
- /// of the drawable object, which is a subclass
- /// of a shape_character_def
- ///
- /// The choice of NOT copying the cache manager
- /// is a choice of simplicity. We can't copy the
- /// pointer as the character_def destructor will
- /// destroy it, and we don't want to destroy it twice.
- /// We don't want to make a copy of the whole cache
- /// as it might be a waste of resource, we don't want
- /// to share ownership as some character_def ended up
- /// NOT being immutable any more !! :(
- ///
- /// By setting the cache to NULL we'll leave reconstruction
- /// of a cache to the renderers.
- ///
- /// TODO: improve by implementing copy on write for the cache ?
- ///
- character_def(const character_def& o)
- :
- ExportableResource(),
- m_render_cache(0),
- _id(o._id)
- {}
-
-private:
-
- int _id;
-
- // don't assign-to
- character_def& operator= (const character_def&);
-
};
-
-} // namespace gnash
+} // namespace SWF
+} // namespace gnash
#endif
=== added file 'libcore/swf/ShapeRecord.cpp'
--- a/libcore/swf/ShapeRecord.cpp 1970-01-01 00:00:00 +0000
+++ b/libcore/swf/ShapeRecord.cpp 2009-04-07 14:32:06 +0000
@@ -0,0 +1,723 @@
+// 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 "ShapeRecord.h"
+#include "swf.h"
+#include "SWFStream.h"
+#include "movie_definition.h"
+#include "Geometry.h"
+#include "GnashNumeric.h"
+
+#include <vector>
+
+namespace gnash {
+namespace SWF {
+
+// Forward declarations
+namespace {
+ void readFillStyles(ShapeRecord::FillStyles& styles, SWFStream& in,
+ SWF::TagType tag, movie_definition& md);
+ void readLineStyles(ShapeRecord::LineStyles& styles, SWFStream& in,
+ SWF::TagType tag, movie_definition& md);
+ void computeBounds(rect& bounds, const ShapeRecord::Paths& paths,
+ const ShapeRecord::LineStyles& lineStyles, int swfVersion);
+}
+
+// Functors for path and style manipulation.
+namespace {
+
+template<typename T>
+class Lerp
+{
+public:
+ Lerp(typename T::const_iterator style1, typename T::const_iterator style2,
+ const double ratio)
+ :
+ _style1(style1),
+ _style2(style2),
+ _ratio(ratio)
+ {}
+
+ void operator()(typename T::value_type& st)
+ {
+ st.set_lerp(*_style1, *_style2, _ratio);
+ ++_style1, ++_style2;
+ }
+
+private:
+ typename T::const_iterator _style1;
+ typename T::const_iterator _style2;
+ const double _ratio;
+};
+
+// Facilities for working with list of paths.
+class PathList
+{
+ typedef SWF::ShapeRecord::Paths Paths;
+public:
+
+ PathList(const Paths& paths)
+ :
+ _paths(paths),
+ _currpath(0),
+ _curredge(0),
+ _nedges(computeNumberOfEdges(_paths))
+ {}
+
+ /// Return number of edges in the path list
+ size_t size() const
+ {
+ return _nedges;
+ }
+
+ /// Get next edge in the path list.
+ //
+ /// After last edge in the list has been fetched,
+ /// next call to this function will return first
+ /// edge again.
+ ///
+ const Edge& getNextEdge()
+ {
+ const Edge& ret = _paths[_currpath][_curredge];
+ if ( ++_curredge >= _paths[_currpath].size() )
+ {
+ if ( ++_currpath >= _paths.size() )
+ {
+ // this is not really needed,
+ // but it's simpler to do so that
+ // to make next call fail or abort..
+ _currpath = 0;
+ _curredge = 0;
+ }
+ }
+ return ret;
+ }
+
+ /// Compute total number of edges
+ static size_t computeNumberOfEdges(const Paths& paths)
+ {
+ size_t count=0;
+ for (Paths::const_iterator i = paths.begin(), e = paths.end();
+ i != e; ++i) {
+
+ count += i->size();
+ }
+ return count;
+ }
+
+private:
+
+ const Paths& _paths;
+
+ size_t _currpath;
+
+ size_t _curredge;
+
+ size_t _nedges;
+
+};
+
+} // anonymous namespace
+
+
+ShapeRecord::ShapeRecord(SWFStream& in, SWF::TagType tag, movie_definition& m)
+{
+ read(in, tag, m);
+}
+
+void
+ShapeRecord::setLerp(const ShapeRecord& a, const ShapeRecord& b,
+ const double ratio)
+{
+
+ // Update current bounds.
+ _bounds.set_lerp(a.getBounds(), b.getBounds(), ratio);
+
+ // fill styles
+ const FillStyles::const_iterator fs1 = a.fillStyles().begin();
+ const FillStyles::const_iterator fs2 = b.fillStyles().begin();
+
+ std::for_each(_fillStyles.begin(), _fillStyles.end(),
+ Lerp<FillStyles>(fs1, fs2, ratio));
+
+ // line styles
+ const LineStyles::const_iterator ls1 = a.lineStyles().begin();
+ const LineStyles::const_iterator ls2 = b.lineStyles().begin();
+
+ std::for_each(_lineStyles.begin(), _lineStyles.end(),
+ Lerp<LineStyles>(ls1, ls2, ratio));
+
+ // This is used for cases in which number
+ // of paths in start shape and end shape are not
+ // the same.
+ const Path empty_path;
+ const Edge empty_edge;
+
+ // shape
+ const Paths& paths1 = a.paths();
+ const Paths& paths2 = b.paths();
+ for (size_t i = 0, k = 0, n = 0; i < _paths.size(); i++)
+ {
+ Path& p = _paths[i];
+ const Path& p1 = i < paths1.size() ? paths1[i] : empty_path;
+ const Path& p2 = n < paths2.size() ? paths2[n] : empty_path;
+
+ const float new_ax = flerp(p1.ap.x, p2.ap.x, ratio);
+ const float new_ay = flerp(p1.ap.y, p2.ap.y, ratio);
+
+ p.reset(new_ax, new_ay, p1.getLeftFill(),
+ p2.getRightFill(), p1.getLineStyle());
+
+ // edges;
+ const size_t len = p1.size();
+ p.m_edges.resize(len);
+
+ for (size_t j=0; j < p.size(); j++)
+ {
+ Edge& e = p[j];
+ const Edge& e1 = j < p1.size() ? p1[j] : empty_edge;
+
+ const Edge& e2 = k < p2.size() ? p2[k] : empty_edge;
+
+ e.cp.x = static_cast<int>(flerp(e1.cp.x, e2.cp.x, ratio));
+ e.cp.y = static_cast<int>(flerp(e1.cp.y, e2.cp.y, ratio));
+ e.ap.x = static_cast<int>(flerp(e1.ap.x, e2.ap.x, ratio));
+ e.ap.y = static_cast<int>(flerp(e1.ap.y, e2.ap.y, ratio));
+ ++k;
+
+ if (p2.size() <= k) {
+ k = 0;
+ ++n;
+ }
+ }
+ }
+
+}
+
+void
+ShapeRecord::read(SWFStream& in, SWF::TagType tag, movie_definition& m)
+{
+
+ /// TODO: is this correct?
+ const bool styleInfo = (tag == SWF::DEFINESHAPE ||
+ tag == SWF::DEFINESHAPE2 ||
+ tag == SWF::DEFINESHAPE3 ||
+ tag == SWF::DEFINESHAPE4 ||
+ tag == SWF::DEFINESHAPE4_);
+
+ if (styleInfo)
+ {
+ _bounds.read(in);
+
+ IF_VERBOSE_PARSE(
+ std::string b = _bounds.toString();
+ log_parse(_(" bound rect: %s"), b);
+ );
+
+ // TODO: Store and use these. Unfinished.
+ if (tag == SWF::DEFINESHAPE4 || tag == SWF::DEFINESHAPE4_)
+ {
+ rect tbound;
+ tbound.read(in);
+ in.ensureBytes(1);
+ static_cast<void>(in.read_u8());
+ LOG_ONCE(log_unimpl("DEFINESHAPE4 edge boundaries and scales"));
+ }
+
+ readFillStyles(_fillStyles, in, tag, m);
+ readLineStyles(_lineStyles, in, tag, m);
+ }
+
+ if (tag == SWF::DEFINEFONT || tag == SWF::DEFINEFONT2 )
+ {
+ assert(!styleInfo);
+ }
+
+ // Use read_u8 to force alignment.
+ in.ensureBytes(1);
+ boost::uint8_t num_bits = in.read_u8();
+ int num_fill_bits = (num_bits & 0xF0) >> 4;
+ int num_line_bits = (num_bits & 0x0F);
+
+ IF_VERBOSE_PARSE(
+ log_parse(_(" ShapeRecord(%s): fillbits = %d, nlinebits = %d"),
+ tag, num_fill_bits, num_line_bits);
+ );
+
+ if ( !num_fill_bits && !num_line_bits )
+ {
+ /// When reading font glyphs it happens to read 1 byte
+ /// past end boundary of a glyph due to fill/line bits being
+ /// zero.
+ ///
+ /// Generally returning here seems to break morphs:
+ /// http://savannah.gnu.org/bugs/?21747
+ /// And other normal shapes:
+ /// http://savannah.gnu.org/bugs/?21923
+ /// http://savannah.gnu.org/bugs/?22000
+ ///
+ /// So for now we only return if NOT reading a morph shape.
+ /// Pretty ugly... till next bug report.
+ ///
+ ///
+ if (tag == SWF::DEFINEFONT || tag == SWF::DEFINEFONT2 ||
+ tag == SWF::DEFINEFONT3)
+ {
+ log_debug("Skipping glyph read, being fill and line bits zero. "
+ "SWF tag is %d.", tag);
+ return;
+ }
+ }
+
+ // These are state variables that keep the
+ // current position & style of the shape
+ // outline, and vary as we read the edge data.
+ //
+ // At the moment we just store each edge with
+ // the full necessary info to render it, which
+ // is simple but not optimally efficient.
+ int fill_base = 0;
+ int line_base = 0;
+ int x = 0, y = 0;
+ Path current_path;
+
+#define SHAPE_LOG 0
+
+ // SHAPERECORDS
+ for (;;)
+ {
+ in.ensureBits(1);
+ bool isEdgeRecord = in.read_bit();
+ if (!isEdgeRecord)
+ {
+ // Parse the record.
+ in.ensureBits(5);
+ int flags = in.read_uint(5);
+ if (flags == SHAPE_END)
+ {
+ // Store the current path if any.
+ if (! current_path.empty())
+ {
+ _paths.push_back(current_path);
+ current_path.m_edges.resize(0);
+ }
+ break;
+ }
+ if (flags & SHAPE_MOVE)
+ {
+ // Store the current path if any, and prepare a fresh one.
+ if (! current_path.empty())
+ {
+ _paths.push_back(current_path);
+ current_path.m_edges.resize(0);
+ }
+ in.ensureBits(5);
+ int num_move_bits = in.read_uint(5);
+ in.ensureBits(2 * num_move_bits);
+ int move_x = in.read_sint(num_move_bits);
+ int move_y = in.read_sint(num_move_bits);
+
+ x = move_x;
+ y = move_y;
+
+ // Set the beginning of the path.
+ current_path.ap.x = x;
+ current_path.ap.y = y;
+
+#if SHAPE_LOG
+ IF_VERBOSE_PARSE(
+ log_parse(_(" Shape read: moveto %d %d"), x, y);
+ );
+#endif
+ }
+ if ((flags & SHAPE_FILLSTYLE0_CHANGE) && num_fill_bits > 0)
+ {
+ // fill_style_0_change = 1;
+ if (! current_path.empty())
+ {
+ _paths.push_back(current_path);
+ current_path.m_edges.resize(0);
+ current_path.ap.x = x;
+ current_path.ap.y = y;
+ }
+ in.ensureBits(num_fill_bits);
+ unsigned style = in.read_uint(num_fill_bits);
+ if (style > 0)
+ {
+ style += fill_base;
+ }
+
+ if (tag == SWF::DEFINEFONT || tag == SWF::DEFINEFONT2)
+ {
+ if ( style > 1 ) // 0:hide 1:renderer
+ {
+ IF_VERBOSE_MALFORMED_SWF(
+ log_swferror(_("Invalid fill style %d in "
+ "fillStyle0Change record for font tag "
+ "(0 or 1 valid). Set to 0."), style);
+ );
+ style = 0;
+ }
+ }
+ else
+ {
+ // 1-based index
+ if ( style > _fillStyles.size() )
+ {
+ IF_VERBOSE_MALFORMED_SWF(
+ log_swferror(_("Invalid fill style %d in "
+ "fillStyle0Change record - %d defined. "
+ "Set to 0."), style, _fillStyles.size());
+ );
+ style = 0;
+ }
+ }
+
+ current_path.setLeftFill(style);
+#if SHAPE_LOG
+ IF_VERBOSE_PARSE(
+ log_parse(_(" Shape read: fill0 (left) = %d"),
+ current_path.getLeftFill());
+ );
+#endif
+ }
+ if ((flags & SHAPE_FILLSTYLE1_CHANGE) && num_fill_bits > 0)
+ {
+ // fill_style_1_change = 1;
+ if (! current_path.empty())
+ {
+ _paths.push_back(current_path);
+ current_path.m_edges.resize(0);
+ current_path.ap.x = x;
+ current_path.ap.y = y;
+ }
+ in.ensureBits(num_fill_bits);
+ unsigned style = in.read_uint(num_fill_bits);
+ if (style > 0)
+ {
+ style += fill_base;
+ }
+
+ if (tag == SWF::DEFINEFONT || tag == SWF::DEFINEFONT2)
+ {
+ if ( style > 1 ) // 0:hide 1:renderer
+ {
+ IF_VERBOSE_MALFORMED_SWF(
+ log_swferror(_("Invalid fill style %d in "
+ "fillStyle1Change record for font tag "
+ "(0 or 1 valid). Set to 0."), style);
+ );
+ style = 0;
+ }
+ }
+ else
+ {
+ // 1-based index
+ if ( style > _fillStyles.size() )
+ {
+ IF_VERBOSE_MALFORMED_SWF(
+ log_swferror(_("Invalid fill style %d in "
+ "fillStyle1Change record - %d defined. "
+ "Set to 0."), style, _fillStyles.size());
+ );
+ style = 0;
+ }
+ }
+ current_path.setRightFill(style);
+#if SHAPE_LOG
+ IF_VERBOSE_PARSE (
+ log_parse(_(" Shape read: fill1 (right) = %d"),
+ current_path.getRightFill());
+ );
+#endif
+ }
+ if ((flags & SHAPE_LINESTYLE_CHANGE) && num_line_bits > 0)
+ {
+ // line_style_change = 1;
+ if (! current_path.empty())
+ {
+ _paths.push_back(current_path);
+ current_path.m_edges.resize(0);
+ current_path.ap.x = x;
+ current_path.ap.y = y;
+ }
+ in.ensureBits(num_line_bits);
+ unsigned style = in.read_uint(num_line_bits);
+ if (style > 0)
+ {
+ style += line_base;
+ }
+ if (tag == SWF::DEFINEFONT || tag == SWF::DEFINEFONT2)
+ {
+ if ( style > 1 ) // 0:hide 1:renderer
+ {
+ IF_VERBOSE_MALFORMED_SWF(
+ log_swferror(_("Invalid line style %d in "
+ "lineStyleChange record for font tag "
+ "(0 or 1 valid). Set to 0."), style);
+ );
+ style = 0;
+ }
+ }
+ else {
+ // 1-based index
+ if (style > _lineStyles.size()) {
+ IF_VERBOSE_MALFORMED_SWF(
+ log_swferror(_("Invalid fill style %d in "
+ "lineStyleChange record - %d defined. "
+ "Set to 0."), style, _lineStyles.size());
+ );
+ style = 0;
+ }
+ }
+ current_path.setLineStyle(style);
+#if SHAPE_LOG
+ IF_VERBOSE_PARSE(
+ log_parse(_(" Shape_read: line = %d"),
+ current_path.getLineStyle());
+ )
+#endif
+ }
+ if (flags & SHAPE_HAS_NEW_STYLES)
+ {
+ if (!styleInfo)
+ {
+ IF_VERBOSE_MALFORMED_SWF(
+ log_swferror("Unexpected HasNewStyle flag in tag "
+ "%d shape record", tag);
+ );
+ continue;
+ }
+ IF_VERBOSE_PARSE (
+ log_parse(_(" Shape read: more fill styles"));
+ );
+
+ // Store the current path if any.
+ if (! current_path.empty())
+ {
+ _paths.push_back(current_path);
+ current_path.clear();
+ }
+
+ // Tack on an empty path signalling a new shape.
+ // @@ need better understanding of whether this is
correct??!?!!
+ // @@ i.e., we should just start a whole new shape here, right?
+ _paths.push_back(Path());
+ _paths.back().m_new_shape = true;
+
+ fill_base = _fillStyles.size();
+ line_base = _lineStyles.size();
+ readFillStyles(_fillStyles, in, tag, m);
+ readLineStyles(_lineStyles, in, tag, m);
+
+ in.ensureBits(8);
+ num_fill_bits = in.read_uint(4);
+ num_line_bits = in.read_uint(4);
+ }
+ }
+ else
+ {
+ // EDGERECORD
+ in.ensureBits(1);
+ bool edge_flag = in.read_bit();
+ if (edge_flag == 0)
+ {
+ in.ensureBits(4);
+ int num_bits = 2 + in.read_uint(4);
+ // curved edge
+ in.ensureBits(4 * num_bits);
+ int cx = x + in.read_sint(num_bits);
+ int cy = y + in.read_sint(num_bits);
+ int ax = cx + in.read_sint(num_bits);
+ int ay = cy + in.read_sint(num_bits);
+
+#if SHAPE_LOG
+ IF_VERBOSE_PARSE (
+ log_parse(_(" Shape read: curved edge = "
+ "%d %d - %d %d - %d %d"), x, y, cx, cy, ax, ay);
+ );
+#endif
+ current_path.m_edges.push_back(Edge(cx, cy, ax, ay));
+ x = ax;
+ y = ay;
+ }
+ else
+ {
+ // straight edge
+ in.ensureBits(5);
+ int num_bits = 2 + in.read_uint(4);
+ bool line_flag = in.read_bit();
+ int dx = 0, dy = 0;
+ if (line_flag)
+ {
+ // General line.
+ in.ensureBits(2 * num_bits);
+ dx = in.read_sint(num_bits);
+ dy = in.read_sint(num_bits);
+ }
+ else
+ {
+ in.ensureBits(1);
+ bool vert_flag = in.read_bit();
+ if (vert_flag == 0)
+ {
+ // Horizontal line.
+ in.ensureBits(num_bits);
+ dx = in.read_sint(num_bits);
+ }
+ else
+ {
+ // Vertical line.
+ in.ensureBits(num_bits);
+ dy = in.read_sint(num_bits);
+ }
+ }
+
+#if SHAPE_LOG
+ IF_VERBOSE_PARSE (
+ log_parse(_(" Shape_read: straight edge = "
+ "%d %d - %d %d"), x, y, x + dx, y + dy);
+ );
+#endif
+ current_path.m_edges.push_back(Edge(x + dx, y + dy,
+ x + dx, y + dy));
+ x += dx;
+ y += dy;
+ }
+ }
+ }
+
+ if (!styleInfo)
+ {
+ // TODO: performance would be improved by computing
+ // the bounds as edges are parsed.
+ computeBounds(_bounds, _paths, _lineStyles, m.get_version());
+ }
+#ifdef GNASH_DEBUG_SHAPE_BOUNDS
+ else
+ {
+ rect computedBounds;
+ computeBounds(computedBounds, _paths, _lineStyles, m->get_version());
+ if ( computedBounds != m_bounds )
+ {
+ log_debug("Shape DisplayObject read for tag %d contained embedded "
+ "bounds %s, while we computed bounds %s",
+ tag, m_bound, computedBounds);
+ }
+ }
+#endif
+}
+
+namespace {
+
+// Read fill styles, and push them onto the given style array.
+void
+readFillStyles(ShapeRecord::FillStyles& styles, SWFStream& in,
+ SWF::TagType tag, movie_definition& m)
+{
+ in.ensureBytes(1);
+ boost::uint16_t fill_style_count = in.read_u8();
+ if (tag != SWF::DEFINESHAPE)
+ {
+ if (fill_style_count == 0xFF)
+ {
+ in.ensureBytes(2);
+ fill_style_count = in.read_u16();
+ }
+ }
+
+ IF_VERBOSE_PARSE (
+ log_parse(_(" readFillStyles: count = %u"), fill_style_count);
+ );
+
+ // Read the styles.
+ styles.reserve(styles.size()+fill_style_count);
+ for (boost::uint16_t i = 0; i < fill_style_count; ++i)
+ {
+ // TODO: add a fill_style constructor directly reading from stream
+ fill_style fs;
+ fs.read(in, tag, m);
+ styles.push_back(fs);
+ }
+}
+
+// Read line styles and push them onto the back of the given array.
+void
+readLineStyles(ShapeRecord::LineStyles& styles, SWFStream& in,
+ SWF::TagType tag, movie_definition& md)
+{
+ in.ensureBytes(1);
+ int line_style_count = in.read_u8();
+
+ IF_VERBOSE_PARSE(
+ log_parse(_(" readLineStyles: count = %d"), line_style_count);
+ );
+
+ if (line_style_count == 0xFF)
+ {
+ in.ensureBytes(2);
+ line_style_count = in.read_u16();
+ IF_VERBOSE_PARSE(
+ log_parse(_(" readLineStyles: count2 = %d"), line_style_count);
+ );
+ }
+
+ // Read the styles.
+ for (int i = 0; i < line_style_count; i++)
+ {
+ styles.resize(styles.size() + 1);
+ styles.back().read(in, tag, md);
+ }
+}
+
+// Find the bounds of this shape, and store them in the given rectangle.
+void
+computeBounds(rect& bounds, const ShapeRecord::Paths& paths,
+ const ShapeRecord::LineStyles& lineStyles, int swfVersion)
+{
+ bounds.set_null();
+
+ for (unsigned int i = 0; i < paths.size(); i++)
+ {
+ const Path& p = paths[i];
+
+ unsigned thickness = 0;
+ if ( p.m_line )
+ {
+ // For glyph shapes m_line is allowed to be 1
+ // while no defined line styles are allowed.
+ if (lineStyles.empty()) {
+ // This is either a Glyph, for which m_line==1 is valid
+ // or a bug in the parser, which we have no way to
+ // check at this time
+ assert(p.m_line == 1);
+ }
+ else
+ {
+ thickness = lineStyles[p.m_line-1].getThickness();
+ }
+ }
+ p.expandBounds(bounds, thickness, swfVersion);
+ }
+}
+
+
+} // anonymous namespace
+
+} // namespace SWF
+} // namespace gnash
+
=== added file 'libcore/swf/ShapeRecord.h'
--- a/libcore/swf/ShapeRecord.h 1970-01-01 00:00:00 +0000
+++ b/libcore/swf/ShapeRecord.h 2009-04-07 14:32:06 +0000
@@ -0,0 +1,158 @@
+// 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_SWF_SHAPERECORD_H
+#define GNASH_SWF_SHAPERECORD_H
+
+#include "Geometry.h"
+#include "fill_style.h"
+#include "styles.h"
+#include "rect.h"
+
+#include <vector>
+
+
+namespace gnash {
+ class movie_definition;
+}
+
+namespace gnash {
+namespace SWF {
+
+/// Holds information needed to draw a shape.
+//
+/// This does not correspond exactly to parsed record in a SWF file, but
+/// is used to create both mutable and immutable shapes.
+//
+/// A ShapeRecord should have enough methods to implement the AS3 Graphics
+/// object (the drawing API of Shape and Sprite). This is restricted to
+/// adding fills, paths and line styles (which must be constructed outside
+/// this ShapeRecord before being added) and clearing everything. There
+/// is no support for removing single elements.
+//
+/// ShapeRecord objects are not ref-counted, so they may be stack-allocated
+/// or used in smart pointers.
+class ShapeRecord
+{
+public:
+
+ typedef std::vector<fill_style> FillStyles;
+ typedef std::vector<line_style> LineStyles;
+ typedef std::vector<Path> Paths;
+
+ /// Construct a ShapeRecord.
+ //
+ /// Ideally all immutable ShapeRecords should be constructed with the
+ /// ctor taking an SWFStream, but some tag formats do not allow this.
+ ShapeRecord() {}
+
+ /// Construct a ShapeRecord from a SWFStream.
+ //
+ /// This is useful for constructing immutable tags.
+ ShapeRecord(SWFStream& in, SWF::TagType tag, movie_definition& m);
+
+ ShapeRecord(const ShapeRecord& other)
+ :
+ _fillStyles(other._fillStyles),
+ _lineStyles(other._lineStyles),
+ _paths(other._paths),
+ _bounds(other._bounds)
+ {}
+
+ /// Parse path data from a SWFStream.
+ //
+ /// This is used by DefineMorphShapeTag as part of parsing its
+ /// more complex ShapeRecords.
+ void read(SWFStream& in, SWF::TagType tag, movie_definition& m);
+
+ const FillStyles& fillStyles() const {
+ return _fillStyles;
+ }
+
+ const LineStyles& lineStyles() const {
+ return _lineStyles;
+ }
+
+ const Paths& paths() const {
+ return _paths;
+ }
+
+ const rect& getBounds() const {
+ return _bounds;
+ }
+
+ /// For DynamicShape
+ //
+ /// TODO: rewrite DynamicShape to push paths when they're
+ /// finished and drop this.
+ Path& currentPath() {
+ return _paths.back();
+ }
+
+ /// Set to the lerp of two ShapeRecords.
+ //
+ /// Used in shape morphing.
+ void setLerp(const ShapeRecord& a, const ShapeRecord& b,
+ const double ratio);
+
+ /// Reset all shape data.
+ void clear() {
+ _fillStyles.clear();
+ _lineStyles.clear();
+ _paths.clear();
+ _bounds.set_null();
+ }
+
+ void addFillStyle(const fill_style& fs) {
+ _fillStyles.push_back(fs);
+ }
+
+ void addPath(const Path& path) {
+ _paths.push_back(path);
+ }
+
+ void addLineStyle(const line_style& ls) {
+ _lineStyles.push_back(ls);
+ }
+
+ void setBounds(const rect& bounds) {
+ _bounds = bounds;
+ }
+
+private:
+
+ /// Shape record flags for use in parsing.
+ enum ShapeRecordFlags {
+ SHAPE_END = 0x00,
+ SHAPE_MOVE = 0x01,
+ SHAPE_FILLSTYLE0_CHANGE = 0x02,
+ SHAPE_FILLSTYLE1_CHANGE = 0x04,
+ SHAPE_LINESTYLE_CHANGE = 0x08,
+ SHAPE_HAS_NEW_STYLES = 0x10
+ };
+
+ FillStyles _fillStyles;
+ LineStyles _lineStyles;
+ Paths _paths;
+ rect _bounds;
+
+};
+
+} // namespace SWF
+} // namespace gnash
+
+#endif
=== modified file 'libcore/swf/TextRecord.cpp'
--- a/libcore/swf/TextRecord.cpp 2009-04-03 09:18:40 +0000
+++ b/libcore/swf/TextRecord.cpp 2009-04-07 11:14:10 +0000
@@ -144,14 +144,15 @@
// Render the given glyph records.
void
-TextRecord::displayRecords(const SWFMatrix& this_mat, DisplayObject* inst,
- const std::vector<SWF::TextRecord>& records, bool embedded)
+TextRecord::displayRecords(const SWFMatrix& this_mat,
+ const DisplayObject& inst, const std::vector<SWF::TextRecord>& records,
+ bool embedded)
{
- SWFMatrix mat = inst->getWorldMatrix();
+ SWFMatrix mat = inst.getWorldMatrix();
mat.concatenate(this_mat);
- cxform cx = inst->get_world_cxform();
+ cxform cx = inst.get_world_cxform();
const SWFMatrix base_matrix = mat;
// Starting positions.
@@ -230,12 +231,12 @@
}
else
{
- shape_character_def* glyph = fnt->get_glyph(index, embedded);
+ ShapeRecord* glyph = fnt->get_glyph(index, embedded);
// Draw the DisplayObject using the filled outline.
if (glyph)
{
- render::draw_glyph(glyph, mat, textColor);
+ render::drawGlyph(*glyph, textColor, mat);
}
}
x += ge.advance;
=== modified file 'libcore/swf/TextRecord.h'
--- a/libcore/swf/TextRecord.h 2009-04-03 09:18:40 +0000
+++ b/libcore/swf/TextRecord.h 2009-04-07 11:14:10 +0000
@@ -86,8 +86,10 @@
bool read(SWFStream& in, movie_definition& m, int glyphBits,
int advanceBits, TagType tag);
- static void displayRecords(const SWFMatrix& this_mat, DisplayObject* inst,
- const std::vector<SWF::TextRecord>& records, bool useEmbeddedGlyphs);
+ static void displayRecords(const SWFMatrix& this_mat,
+ const DisplayObject& inst,
+ const std::vector<SWF::TextRecord>& records,
+ bool useEmbeddedGlyphs);
const Glyphs& glyphs() const {
return _glyphs;
=== modified file 'libcore/swf/VideoFrameTag.cpp'
--- a/libcore/swf/VideoFrameTag.cpp 2009-04-03 09:18:40 +0000
+++ b/libcore/swf/VideoFrameTag.cpp 2009-04-07 12:46:29 +0000
@@ -36,14 +36,14 @@
assert(tag == SWF::VIDEOFRAME);
in.ensureBytes(2);
- boost::uint16_t DisplayObject_id = in.read_u16();
- character_def* chdef = m.get_character_def(DisplayObject_id);
+ boost::uint16_t id = in.read_u16();
+ DefinitionTag* chdef = m.getDefinitionTag(id);
if (!chdef)
{
IF_VERBOSE_MALFORMED_SWF(
log_swferror(_("VideoFrame tag refers to unknown video "
- "stream id %d"), DisplayObject_id);
+ "stream id %d"), id);
);
return;
}
@@ -53,7 +53,7 @@
{
IF_VERBOSE_MALFORMED_SWF(
log_swferror(_("VideoFrame tag refers to a non-video DisplayObject "
- "%d (%s)"), DisplayObject_id, typeName(*chdef));
+ "%d (%s)"), id, typeName(*chdef));
);
return;
}
=== modified file 'libcore/swf/VideoFrameTag.h'
--- a/libcore/swf/VideoFrameTag.h 2009-04-03 09:18:40 +0000
+++ b/libcore/swf/VideoFrameTag.h 2009-04-07 12:34:43 +0000
@@ -24,7 +24,7 @@
#include "gnashconfig.h"
#endif
-#include "character_def.h"
+#include "DefinitionTag.h"
#include "movie_definition.h"
#include "swf.h"
#include "rect.h" // for composition
=== modified file 'libcore/swf/tag_loaders.cpp'
--- a/libcore/swf/tag_loaders.cpp 2009-04-03 09:48:13 +0000
+++ b/libcore/swf/tag_loaders.cpp 2009-04-07 12:46:29 +0000
@@ -29,7 +29,6 @@
#include "Font.h"
#include "fontlib.h"
#include "log.h"
-#include "morph2_character_def.h"
#include "Geometry.h"
#include "SWFStream.h"
#include "styles.h"
@@ -285,13 +284,13 @@
assert(tag == SWF::DEFINEBITS); // 6
in.ensureBytes(2);
- boost::uint16_t DisplayObject_id = in.read_u16();
+ boost::uint16_t id = in.read_u16();
- if (m.getBitmap(DisplayObject_id))
+ if (m.getBitmap(id))
{
IF_VERBOSE_MALFORMED_SWF(
log_swferror(_("DEFINEBITS: Duplicate id (%d) for bitmap DisplayObject
"
- "- discarding it"), DisplayObject_id);
+ "- discarding it"), id);
);
return;
}
@@ -302,7 +301,7 @@
{
IF_VERBOSE_MALFORMED_SWF(
log_swferror(_("DEFINEBITS: No jpeg loader registered in movie "
- "definition - discarding bitmap DisplayObject %d"),
DisplayObject_id);
+ "definition - discarding bitmap DisplayObject %d"), id);
);
return;
}
@@ -318,7 +317,7 @@
{
IF_VERBOSE_MALFORMED_SWF(
log_swferror("Error reading jpeg2 with headers for DisplayObject "
- "id %d: %s", DisplayObject_id, e.what());
+ "id %d: %s", id, e.what());
);
return;
}
@@ -326,7 +325,7 @@
boost::intrusive_ptr<BitmapInfo> bi = render::createBitmapInfo(im);
// add bitmap to movie under DisplayObject id.
- m.addBitmap(DisplayObject_id, bi);
+ m.addBitmap(id, bi);
}
@@ -337,20 +336,20 @@
assert(tag == SWF::DEFINEBITSJPEG2); // 21
in.ensureBytes(2);
- boost::uint16_t DisplayObject_id = in.read_u16();
+ boost::uint16_t id = in.read_u16();
IF_VERBOSE_PARSE
(
log_parse(_(" define_bits_jpeg2_loader: charid = %d pos = %ld"),
- DisplayObject_id, in.tell());
+ id, in.tell());
);
- if ( m.getBitmap(DisplayObject_id) )
+ if ( m.getBitmap(id) )
{
IF_VERBOSE_MALFORMED_SWF(
log_swferror(_("DEFINEBITSJPEG2: Duplicate id (%d) for bitmap "
- "DisplayObject - discarding it"), DisplayObject_id);
+ "DisplayObject - discarding it"), id);
);
return;
}
@@ -366,7 +365,7 @@
boost::intrusive_ptr<BitmapInfo> bi = render::createBitmapInfo(im);
// add bitmap to movie under DisplayObject id.
- m.addBitmap(DisplayObject_id, bi);
+ m.addBitmap(id, bi);
}
@@ -468,12 +467,12 @@
assert(tag == SWF::DEFINEBITSJPEG3); // 35
in.ensureBytes(2);
- boost::uint16_t DisplayObject_id = in.read_u16();
+ boost::uint16_t id = in.read_u16();
IF_VERBOSE_PARSE
(
log_parse(_(" define_bits_jpeg3_loader: charid = %d pos = %lx"),
- DisplayObject_id, in.tell());
+ id, in.tell());
);
in.ensureBytes(4);
@@ -516,7 +515,7 @@
render::createBitmapInfo(static_cast<std::auto_ptr<GnashImage> >(im));
// add bitmap to movie under DisplayObject id.
- m.addBitmap(DisplayObject_id, bi);
+ m.addBitmap(id, bi);
#endif
}
@@ -530,7 +529,7 @@
in.ensureBytes(2+2+2+1); // the initial header
- boost::uint16_t DisplayObject_id = in.read_u16();
+ boost::uint16_t id = in.read_u16();
// 3 == 8 bit, 4 == 16 bit, 5 == 32 bit
boost::uint8_t bitmap_format = in.read_u8();
@@ -540,25 +539,25 @@
IF_VERBOSE_PARSE(
log_parse(_(" defbitslossless2: tag = %d, id = %d, "
"fmt = %d, w = %d, h = %d"),
- tag, DisplayObject_id, bitmap_format, width, height);
+ tag, id, bitmap_format, width, height);
);
if (!width || !height) {
IF_VERBOSE_MALFORMED_SWF(
log_swferror(_("Bitmap DisplayObject %d has a height or width of
0"),
- DisplayObject_id);
+ id);
);
return;
}
// No need to parse any further if it already exists, as we aren't going
// to add it.
- if (m.getBitmap(DisplayObject_id))
+ if (m.getBitmap(id))
{
IF_VERBOSE_MALFORMED_SWF(
log_swferror(_("DEFINEBITSLOSSLESS: Duplicate id (%d) "
"for bitmap DisplayObject - discarding it"),
- DisplayObject_id);
+ id);
);
}
@@ -703,7 +702,7 @@
boost::intrusive_ptr<BitmapInfo> bi = render::createBitmapInfo(image);
// add bitmap to movie under DisplayObject id.
- m.addBitmap(DisplayObject_id, bi);
+ m.addBitmap(id, bi);
#endif // HAVE_ZLIB_H
}
@@ -719,45 +718,6 @@
}
}
-void define_shape_loader(SWFStream& in, TagType tag, movie_definition& m,
- const RunInfo& /*r*/)
-{
- assert(tag == SWF::DEFINESHAPE
- || tag == SWF::DEFINESHAPE2
- || tag == SWF::DEFINESHAPE3
- || tag == SWF::DEFINESHAPE4 || tag == SWF::DEFINESHAPE4_);
-
- in.ensureBytes(2);
- boost::uint16_t DisplayObject_id = in.read_u16();
- IF_VERBOSE_PARSE(
- log_parse(_(" shape_loader: id = %d"), DisplayObject_id);
- );
-
- shape_character_def* ch = new shape_character_def;
- ch->read(in, tag, true, m);
-
- m.addDisplayObject(DisplayObject_id, ch);
-}
-
-void define_shape_morph_loader(SWFStream& in, TagType tag, movie_definition& m,
- const RunInfo& /*r*/)
-{
- assert(tag == SWF::DEFINEMORPHSHAPE
- || tag == SWF::DEFINEMORPHSHAPE2
- || tag == SWF::DEFINEMORPHSHAPE2_);
-
- in.ensureBytes(2);
- boost::uint16_t DisplayObject_id = in.read_u16();
-
- IF_VERBOSE_PARSE(
- log_parse(_(" shape_morph_loader: id = %d"), DisplayObject_id);
- );
-
- morph2_character_def* morph = new morph2_character_def;
- morph->read(in, tag, m);
- m.addDisplayObject(DisplayObject_id, morph);
-}
-
// Create and initialize a sprite, and add it to the movie.
void
sprite_loader(SWFStream& in, TagType tag, movie_definition& m,
@@ -766,11 +726,11 @@
assert(tag == SWF::DEFINESPRITE); // 39 - DefineSprite
in.ensureBytes(2);
- int DisplayObject_id = in.read_u16();
+ int id = in.read_u16();
IF_VERBOSE_PARSE
(
- log_parse(_(" sprite: char id = %d"), DisplayObject_id);
+ log_parse(_(" sprite: char id = %d"), id);
);
// A DEFINESPRITE tag as part of a DEFINESPRITE
@@ -791,12 +751,12 @@
IF_VERBOSE_MALFORMED_SWF(
if (!ch->get_frame_count()) {
- log_swferror(_("Sprite %d advertise no frames"), DisplayObject_id);
+ log_swferror(_("Sprite %d advertise no frames"), id);
}
);
- m.addDisplayObject(DisplayObject_id, ch);
+ m.addDisplayObject(id, ch);
}
@@ -847,7 +807,7 @@
// Fonts, DisplayObjects and sounds can be exported.
ExportableResource* f;
if ((f = m.get_font(id)) ||
- (f = m.get_character_def(id)) ||
+ (f = m.getDefinitionTag(id)) ||
(f = m.get_sound_sample(id))) {
m.export_resource(symbolName, f);
@@ -976,7 +936,7 @@
in.ensureBytes(2+4+1+4); // DisplayObject id + flags + sample count
- boost::uint16_t DisplayObject_id = in.read_u16();
+ boost::uint16_t id = in.read_u16();
media::audioCodecType format = static_cast<media::audioCodecType>(
in.read_uint(4));
@@ -1024,7 +984,7 @@
(
log_parse(_("define sound: ch=%d, format=%s, "
"rate=%d, 16=%d, stereo=%d, ct=%d"),
- DisplayObject_id, format, sample_rate,
+ id, format, sample_rate,
int(sample_16bit), int(stereo), sample_count);
);
@@ -1067,7 +1027,7 @@
if (handler_id >= 0)
{
sound_sample* sam = new sound_sample(handler_id, r);
- m.add_sound_sample(DisplayObject_id, sam);
+ m.add_sound_sample(id, sam);
}
}
@@ -1077,7 +1037,7 @@
log_error(_("There is no sound handler currently active, "
"so DisplayObject with id %d will NOT be added to "
"the dictionary"),
- DisplayObject_id);
+ id);
}
}
=== modified file 'libcore/swf/tag_loaders.h'
--- a/libcore/swf/tag_loaders.h 2009-01-22 20:10:39 +0000
+++ b/libcore/swf/tag_loaders.h 2009-04-07 12:45:25 +0000
@@ -63,20 +63,11 @@
void define_bits_jpeg3_loader(SWFStream&, TagType, movie_definition&,
const RunInfo&);
-void define_shape_loader(SWFStream&, TagType, movie_definition&,
- const RunInfo&);
-
-void define_shape_morph_loader(SWFStream&, TagType, movie_definition&,
- const RunInfo&);
-
/// SWF Tags Reflex (777)
//
void reflex_loader(SWFStream&, TagType, movie_definition&,
const RunInfo&);
-void place_object_2_loader(SWFStream&, TagType, movie_definition&,
- const RunInfo&);
-
void define_bits_lossless_2_loader(SWFStream&, TagType, movie_definition&,
const RunInfo&);
=== modified file 'testsuite/Makefile.am'
--- a/testsuite/Makefile.am 2009-03-24 10:21:30 +0000
+++ b/testsuite/Makefile.am 2009-04-07 09:19:54 +0000
@@ -111,6 +111,7 @@
-I$(top_srcdir)/libsound \
-I$(top_srcdir)/backend \
-I$(top_srcdir)/libcore \
+ -I$(top_srcdir)/libcore/swf \
-I$(top_srcdir)/libcore/parser \
-I$(top_srcdir)/libcore/vm \
$(BOOST_CFLAGS) \
=== modified file 'testsuite/libcore.all/ClassSizes.cpp'
--- a/testsuite/libcore.all/ClassSizes.cpp 2009-04-03 09:29:19 +0000
+++ b/testsuite/libcore.all/ClassSizes.cpp 2009-04-07 16:32:11 +0000
@@ -27,6 +27,11 @@
#include "DisplayObject.h"
#include "RGBA.h"
#include "movie_root.h"
+#include "swf/ShapeRecord.h"
+#include "StaticText.h"
+#include "Button.h"
+#include "MorphShape.h"
+#include "Shape.h"
#include <iostream>
#include <sstream>
@@ -69,5 +74,11 @@
std::cout << "sizeof(fill_style): " << (sizeof(fill_style)) <<
std::endl;
std::cout << "sizeof(SWFMatrix): " << (sizeof(SWFMatrix)) << std::endl;
std::cout << "sizeof(movie_root): " << (sizeof(movie_root)) <<
std::endl;
+
+ std::cout << "sizeof(ShapeRecord): " << (sizeof(SWF::ShapeRecord)) <<
std::endl;
+ std::cout << "sizeof(StaticText): " << (sizeof(StaticText)) <<
std::endl;
+ std::cout << "sizeof(MorphShape): " << (sizeof(MorphShape)) <<
std::endl;
+ std::cout << "sizeof(Shape): " << (sizeof(Shape)) << std::endl;
+ std::cout << "sizeof(Button): " << (sizeof(Button)) << std::endl;
}
=== modified file 'testsuite/libcore.all/EdgeTest.cpp'
--- a/testsuite/libcore.all/EdgeTest.cpp 2009-03-10 20:43:50 +0000
+++ b/testsuite/libcore.all/EdgeTest.cpp 2009-04-06 11:31:51 +0000
@@ -64,13 +64,13 @@
// Test distance
//
- check_equals(edge::distancePtSeg(point(0,0), point(9, 0), point(9, 0)),
9);
- check_equals(edge::distancePtSeg(point(0,0), point(0, 0), point(3, 0)),
0);
- check_equals(edge::distancePtSeg(point(-5,0), point(0, 0), point(3,
0)), 5);
- check_equals(edge::distancePtSeg(point(5,0), point(0, 0), point(3, 0)),
2);
- check_equals(D(edge::distancePtSeg(point(0,0), point(-10, 0), point(3,
0))), 0);
- check_equals(edge::distancePtSeg(point(0,0), point(-10, 0), point(-10,
30)), 10);
- check_equals(edge::distancePtSeg(point(5,5), point(-10, 0), point(10,
0)), 5);
+ check_equals(Edge::distancePtSeg(point(0,0), point(9, 0), point(9, 0)),
9);
+ check_equals(Edge::distancePtSeg(point(0,0), point(0, 0), point(3, 0)),
0);
+ check_equals(Edge::distancePtSeg(point(-5,0), point(0, 0), point(3,
0)), 5);
+ check_equals(Edge::distancePtSeg(point(5,0), point(0, 0), point(3, 0)),
2);
+ check_equals(D(Edge::distancePtSeg(point(0,0), point(-10, 0), point(3,
0))), 0);
+ check_equals(Edge::distancePtSeg(point(0,0), point(-10, 0), point(-10,
30)), 10);
+ check_equals(Edge::distancePtSeg(point(5,5), point(-10, 0), point(10,
0)), 5);
//
// Test pointOnCurve
@@ -84,11 +84,11 @@
point A(10, 10);
point C(20, 10);
point B(20, 20);
- check_equals(edge::pointOnCurve(A, C, B, 0), A);
- check_equals(edge::pointOnCurve(A, C, B, 1), B);
- check_equals(edge::pointOnCurve(A, C, B, 0.5), point(17.5, 12.5));
- check_equals(sqrt((float)edge::squareDistancePtCurve(A, C, B, B, 1)),
0);
- check_equals(sqrt((float)edge::squareDistancePtCurve(A, C, B, A, 0)),
0);
+ check_equals(Edge::pointOnCurve(A, C, B, 0), A);
+ check_equals(Edge::pointOnCurve(A, C, B, 1), B);
+ check_equals(Edge::pointOnCurve(A, C, B, 0.5), point(17.5, 12.5));
+ check_equals(sqrt((float)Edge::squareDistancePtCurve(A, C, B, B, 1)),
0);
+ check_equals(sqrt((float)Edge::squareDistancePtCurve(A, C, B, A, 0)),
0);
//
// A----B---C
@@ -96,10 +96,10 @@
A.setTo(10, 10);
C.setTo(40, 10);
B.setTo(20, 10);
- check_equals(edge::pointOnCurve(A, C, B, 0), A);
- check_equals(edge::pointOnCurve(A, C, B, 1), B);
- check_equals(edge::pointOnCurve(A, C, B, 0.5), point(27.5, 10));
- check_equals(sqrt((float)edge::squareDistancePtCurve(A, C, B, B, 1)),
0);
- check_equals(sqrt((float)edge::squareDistancePtCurve(A, C, B, A, 0)),
0);
+ check_equals(Edge::pointOnCurve(A, C, B, 0), A);
+ check_equals(Edge::pointOnCurve(A, C, B, 1), B);
+ check_equals(Edge::pointOnCurve(A, C, B, 0.5), point(27.5, 10));
+ check_equals(sqrt((float)Edge::squareDistancePtCurve(A, C, B, B, 1)),
0);
+ check_equals(sqrt((float)Edge::squareDistancePtCurve(A, C, B, A, 0)),
0);
}
=== modified file 'testsuite/libcore.all/Makefile.am'
--- a/testsuite/libcore.all/Makefile.am 2009-03-19 22:18:46 +0000
+++ b/testsuite/libcore.all/Makefile.am 2009-04-07 16:32:11 +0000
@@ -25,6 +25,7 @@
-I$(top_srcdir)/libnet \
-I$(top_srcdir)/libbase \
-I$(top_srcdir)/libcore \
+ -I$(top_srcdir)/libcore/swf \
-I$(top_srcdir)/libcore/parser \
-I$(top_srcdir)/libcore/vm \
$(FFMPEG_CFLAGS) \
=== modified file 'testsuite/misc-ming.all/Makefile.am'
--- a/testsuite/misc-ming.all/Makefile.am 2009-03-18 17:47:08 +0000
+++ b/testsuite/misc-ming.all/Makefile.am 2009-04-07 09:19:54 +0000
@@ -55,6 +55,7 @@
-I$(top_srcdir)/libsound \
-I$(top_srcdir)/backend \
-I$(top_srcdir)/libcore \
+ -I$(top_srcdir)/libcore/swf \
-I$(top_srcdir)/libcore/parser \
-I$(top_srcdir)/libcore/vm \
-I$(top_srcdir)/libcore/asobj \
=== modified file 'testsuite/misc-swfc.all/Makefile.am'
--- a/testsuite/misc-swfc.all/Makefile.am 2009-02-25 22:33:03 +0000
+++ b/testsuite/misc-swfc.all/Makefile.am 2009-04-07 11:14:10 +0000
@@ -58,6 +58,7 @@
-I$(top_srcdir)/libsound \
-I$(top_srcdir)/backend \
-I$(top_srcdir)/libcore \
+ -I$(top_srcdir)/libcore/swf \
-I$(top_srcdir)/libcore/vm \
-I$(top_srcdir)/libcore/parser \
-I$(top_srcdir)/testsuite \
=== modified file 'testsuite/misc-swfmill.all/Makefile.am'
--- a/testsuite/misc-swfmill.all/Makefile.am 2009-02-25 22:33:03 +0000
+++ b/testsuite/misc-swfmill.all/Makefile.am 2009-04-07 11:14:10 +0000
@@ -42,6 +42,7 @@
-I$(top_srcdir)/libsound \
-I$(top_srcdir)/backend \
-I$(top_srcdir)/libcore \
+ -I$(top_srcdir)/libcore/swf \
-I$(top_srcdir)/libcore/parser \
-I$(top_srcdir)/libcore/vm \
-I$(top_srcdir)/libcore/asobj \
=== modified file 'testsuite/movies.all/Makefile.am'
--- a/testsuite/movies.all/Makefile.am 2009-02-25 22:33:03 +0000
+++ b/testsuite/movies.all/Makefile.am 2009-04-07 09:49:53 +0000
@@ -39,6 +39,7 @@
-I$(top_srcdir)/libsound \
-I$(top_srcdir)/backend \
-I$(top_srcdir)/libcore \
+ -I$(top_srcdir)/libcore/swf \
-I$(top_srcdir)/libcore/parser \
-I$(top_srcdir)/libcore/vm \
-I$(top_srcdir)/libcore/asobj \
=== modified file 'testsuite/samples/Makefile.am'
--- a/testsuite/samples/Makefile.am 2009-02-25 22:33:03 +0000
+++ b/testsuite/samples/Makefile.am 2009-04-07 09:49:53 +0000
@@ -32,6 +32,7 @@
-I$(top_srcdir)/libsound \
-I$(top_srcdir)/backend \
-I$(top_srcdir)/libcore \
+ -I$(top_srcdir)/libcore/swf \
-I$(top_srcdir)/libcore/parser \
-I$(top_srcdir)/libcore/vm \
-I$(top_srcdir)/testsuite \
=== modified file 'utilities/Makefile.am'
--- a/utilities/Makefile.am 2009-02-02 02:07:06 +0000
+++ b/utilities/Makefile.am 2009-04-06 20:29:42 +0000
@@ -54,6 +54,7 @@
-I$(top_srcdir)/backend \
-I$(top_srcdir)/libcore \
-I$(top_srcdir)/libcore/asobj \
+ -I$(top_srcdir)/libcore/swf \
-I$(top_srcdir)/libcore/parser \
-I$(top_srcdir)/libcore/vm \
-I$(top_srcdir)/libmedia \
- [Gnash-commit] /srv/bzr/gnash/trunk r10779: Major reorganization of the messy half of Gnash to match the neater half,
Benjamin Wolsey <=