[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r10244: Move DefineText parsing from
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r10244: Move DefineText parsing from all over the place to libcore/swf and use |
Date: |
Sat, 08 Nov 2008 11:24:58 +0100 |
User-agent: |
Bazaar (1.5) |
------------------------------------------------------------
revno: 10244
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Sat 2008-11-08 11:24:58 +0100
message:
Move DefineText parsing from all over the place to libcore/swf and use
the new system for tag loading. Make TextRecord parsing more sensible
and clean up rendering.
removed:
libcore/text.cpp
libcore/text.h
added:
libcore/swf/TextRecord.cpp
libcore/swf/TextRecord.h
renamed:
libcore/parser/text_character_def.cpp => libcore/swf/DefineTextTag.cpp
libcore/parser/text_character_def.h => libcore/swf/DefineTextTag.h
modified:
libcore/Makefile.am
libcore/TextField.cpp
libcore/TextField.h
libcore/font.h
libcore/impl.cpp
libcore/parser/Makefile.am
libcore/swf/DefineButtonSoundTag.h
libcore/swf/DefineButtonTag.h
libcore/swf/DefineEditTextTag.h
libcore/swf/DefineFontAlignZonesTag.cpp
libcore/swf/DefineFontAlignZonesTag.h
libcore/swf/DefineVideoStreamTag.h
libcore/swf/StartSoundTag.cpp
libcore/swf/StreamSoundBlockTag.cpp
libcore/swf/StreamSoundBlockTag.h
libcore/swf/tag_loaders.cpp
libcore/swf/tag_loaders.h
libcore/swf/DefineTextTag.cpp
libcore/swf/DefineTextTag.h
------------------------------------------------------------
revno: 10239.1.6
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Fri 2008-11-07 19:07:45 +0100
message:
Transfer DefineText and DefineText2 parsing to swf.
renamed:
libcore/parser/text_character_def.cpp => libcore/swf/DefineTextTag.cpp
libcore/parser/text_character_def.h => libcore/swf/DefineTextTag.h
modified:
libcore/Makefile.am
libcore/font.h
libcore/impl.cpp
libcore/parser/Makefile.am
libcore/swf/DefineEditTextTag.h
libcore/swf/tag_loaders.cpp
libcore/swf/tag_loaders.h
libcore/text.h
libcore/swf/DefineTextTag.cpp
libcore/swf/DefineTextTag.h
------------------------------------------------------------
revno: 10239.1.7
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Fri 2008-11-07 19:13:26 +0100
message:
Rename text class to Text.
renamed:
libcore/text.cpp => libcore/Text.cpp
libcore/text.h => libcore/Text.h
modified:
libcore/Makefile.am
libcore/TextField.cpp
libcore/TextField.h
libcore/swf/DefineTextTag.h
libcore/Text.cpp
------------------------------------------------------------
revno: 10239.1.8
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Fri 2008-11-07 23:19:58 +0100
message:
Introduce TextRecord class for parsing and storing TextRecords (DefineText
and DefineText2), and also for dynamic creation from TextField.
Text.h and Text.cpp are almost useless now.
added:
libcore/swf/TextRecord.cpp
libcore/swf/TextRecord.h
modified:
libcore/Makefile.am
libcore/Text.cpp
libcore/Text.h
libcore/TextField.cpp
libcore/TextField.h
libcore/swf/DefineTextTag.cpp
libcore/swf/DefineTextTag.h
------------------------------------------------------------
revno: 10239.1.9
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Sat 2008-11-08 00:26:10 +0100
message:
Correct some typos, restore has{X,Y}Offset(). Testsuite now passes again.
Everything seems in order.
modified:
libcore/Text.cpp
libcore/swf/TextRecord.cpp
libcore/swf/TextRecord.h
------------------------------------------------------------
revno: 10239.1.10
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Sat 2008-11-08 00:57:14 +0100
message:
Quiet logging.
modified:
libcore/Text.cpp
libcore/swf/TextRecord.cpp
------------------------------------------------------------
revno: 10239.1.11
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Sat 2008-11-08 11:04:43 +0100
message:
Remove Text, move display function to TextRecord.
Make more tag constructors private so that they can only be constructed
during parsing. Add some documentation.
removed:
libcore/Text.cpp
libcore/Text.h
modified:
libcore/Makefile.am
libcore/TextField.cpp
libcore/swf/DefineButtonSoundTag.h
libcore/swf/DefineButtonTag.h
libcore/swf/DefineEditTextTag.h
libcore/swf/DefineFontAlignZonesTag.cpp
libcore/swf/DefineFontAlignZonesTag.h
libcore/swf/DefineTextTag.cpp
libcore/swf/DefineTextTag.h
libcore/swf/DefineVideoStreamTag.h
libcore/swf/StartSoundTag.cpp
libcore/swf/StreamSoundBlockTag.cpp
libcore/swf/StreamSoundBlockTag.h
libcore/swf/TextRecord.cpp
libcore/swf/TextRecord.h
=== modified file 'libcore/Makefile.am'
--- a/libcore/Makefile.am 2008-11-07 16:05:23 +0000
+++ b/libcore/Makefile.am 2008-11-08 10:04:43 +0000
@@ -83,11 +83,13 @@
MovieClip.cpp \
swf/TagLoadersTable.cpp \
swf/DefineVideoStreamTag.cpp \
+ swf/DefineTextTag.cpp \
swf/DefineButtonSoundTag.cpp \
swf/DefineButtonCxformTag.cpp \
swf/DefineButtonTag.cpp \
swf/VideoFrameTag.cpp \
swf/SoundInfoRecord.cpp \
+ swf/TextRecord.cpp \
swf/tag_loaders.cpp \
swf/DefineFontAlignZonesTag.cpp \
swf/DefineEditTextTag.cpp \
@@ -111,7 +113,6 @@
shape.cpp \
SWFStream.cpp \
styles.cpp \
- text.cpp \
timers.cpp \
RGBA.cpp \
$(FREETYPE_SOURCES) \
@@ -187,7 +188,9 @@
swf/DefineFontAlignZonesTag.h \
swf/CSMTextSettingsTag.h \
swf/SoundInfoRecord.h \
+ swf/TextRecord.h \
swf/DefineButtonSoundTag.h \
+ swf/DefineTextTag.h \
swf/DefineButtonTag.h \
swf/DefineEditTextTag.h \
swf/DefineButtonCxformTag.h \
@@ -202,7 +205,6 @@
swf/ScriptLimitsTag.h \
swf_event.h \
swf_function.h \
- text.h \
timers.h \
RGBA.h \
Video.h \
=== modified file 'libcore/TextField.cpp'
--- a/libcore/TextField.cpp 2008-11-06 15:59:49 +0000
+++ b/libcore/TextField.cpp 2008-11-08 10:04:43 +0000
@@ -43,6 +43,7 @@
#include "StringPredicates.h"
#include "TextFormat.h" // for getTextFormat/setTextFormat
#include "GnashKey.h" // key::code
+#include "TextRecord.h"
#include <algorithm> // std::min
#include <string>
@@ -938,7 +939,7 @@
// Draw our actual text.
// Using a SWFMatrix to translate to def bounds seems an hack to me.
// A cleaner implementation is likely correctly setting the
- // m_x_offset and m_y_offset memebers in glyph records.
+ // _xOffset and _yOffset memebers in glyph records.
// Anyway, see bug #17954 for a testcase.
SWFMatrix m;
@@ -947,7 +948,7 @@
m.concatenate_translation(_bounds.get_x_min(), _bounds.get_y_min());
}
- display_glyph_records(m, this, m_text_glyph_records, _embedFonts);
+ SWF::TextRecord::displayRecords(m, this, _textRecords, _embedFonts);
if (m_has_focus) show_cursor(wmat);
@@ -1430,14 +1431,12 @@
}
// Shift the beginnings of the records on this line.
- for (unsigned int i = last_line_start_record; i <
m_text_glyph_records.size(); i++)
+ for (unsigned int i = last_line_start_record; i < _textRecords.size(); ++i)
{
- text_glyph_record& rec = m_text_glyph_records[i];
+ SWF::TextRecord& rec = _textRecords[i];
- if ( rec.m_style.hasXOffset() )
- {
- rec.m_style.shiftXOffset(shift_right);
- }
+ //if ( rec.hasXOffset() ) // why?
+ rec.setXOffset(rec.xOffset() + shift_right);
}
return shift_right;
}
@@ -1457,7 +1456,7 @@
void
TextField::format_text()
{
- m_text_glyph_records.clear();
+ _textRecords.clear();
// nothing more to do if text is empty
if ( _text.empty() )
@@ -1511,16 +1510,16 @@
//log_debug("%s: fontDescent:%g, fontLeading:%g, fontHeight:%g, scale:%g",
getTarget(), fontDescent, fontLeading, fontHeight, scale);
- text_glyph_record rec; // one to work on
- rec.m_style.setFont(_font.get());
- rec.m_style.setUnderlined(underlined);
- rec.m_style.m_color = getTextColor();
- rec.m_style.setXOffset( PADDING_TWIPS + std::max(0, leftMargin + indent +
blockIndent) );
- rec.m_style.setYOffset( PADDING_TWIPS + fontHeight + (fontLeading -
fontDescent) );
- rec.m_style.m_text_height = fontHeight;
+ SWF::TextRecord rec; // one to work on
+ rec.setFont(_font.get());
+ rec.setUnderline(underlined);
+ rec.setColor(getTextColor());
+ rec.setXOffset(PADDING_TWIPS + std::max(0, leftMargin + indent +
blockIndent));
+ rec.setYOffset(PADDING_TWIPS + fontHeight + (fontLeading - fontDescent));
+ rec.setTextHeight(fontHeight);
- boost::int32_t x =
static_cast<boost::int32_t>(rec.m_style.getXOffset());
- boost::int32_t y =
static_cast<boost::int32_t>(rec.m_style.getYOffset());
+ boost::int32_t x = static_cast<boost::int32_t>(rec.xOffset());
+ boost::int32_t y = static_cast<boost::int32_t>(rec.yOffset());
// Start the bbox at the upper-left corner of the first glyph.
reset_bounding_box(x, y - fontDescent + fontHeight);
@@ -1573,7 +1572,7 @@
// need to detect \r\n and treat it as one newline.
// Close out this stretch of glyphs.
- m_text_glyph_records.push_back(rec);
+ _textRecords.push_back(rec);
align_line(textAlignment, last_line_start_record, x);
// Expand bounding box to include last column of text ...
@@ -1584,16 +1583,16 @@
y += fontHeight + leading;
// Start a new record on the next line.
- rec.m_glyphs.resize(0);
- rec.m_style.setFont(_font.get());
- rec.m_style.setUnderlined(underlined);
- rec.m_style.m_color = getTextColor();
- rec.m_style.setXOffset(x);
- rec.m_style.setYOffset(y);
- rec.m_style.m_text_height = fontHeight;
+ rec.clearGlyphs();
+ rec.setFont(_font.get());
+ rec.setUnderline(underlined);
+ rec.setColor(getTextColor());
+ rec.setXOffset(x);
+ rec.setYOffset(y);
+ rec.setTextHeight(fontHeight);
last_space_glyph = -1;
- last_line_start_record = m_text_glyph_records.size();
+ last_line_start_record = _textRecords.size();
continue;
}
@@ -1613,13 +1612,14 @@
// ONLY WORKS FOR BACKSPACING OVER ONE CHARACTER, WON'T BS
// OVER NEWLINES, ETC.
- if (rec.m_glyphs.size() > 0)
+ if (!rec.glyphs().empty())
{
// Peek at the previous glyph, and zero out its advance
// value, so the next char overwrites it.
- float advance = rec.m_glyphs.back().m_glyph_advance;
+ float advance = rec.glyphs().back().advance;
x -= advance; // maintain formatting
- rec.m_glyphs.back().m_glyph_advance = 0; // do the BS effect
+ // Remove one glyph
+ rec.clearGlyphs(1);
}
continue;
}
@@ -1656,13 +1656,13 @@
}
else
{
- text_glyph_record::glyph_entry ge;
- ge.m_glyph_index = index;
- ge.m_glyph_advance = scale * _font->get_advance(index,
_embedFonts);
+ SWF::TextRecord::GlyphEntry ge;
+ ge.index = index;
+ ge.advance = scale * _font->get_advance(index, _embedFonts);
- const int tabstop=8;
- rec.m_glyphs.insert(rec.m_glyphs.end(), tabstop, ge);
- x += ge.m_glyph_advance*tabstop;
+ const int tabstop = 8;
+ rec.addGlyph(ge, tabstop);
+ x += ge.advance * tabstop;
}
goto after_x_advance;
}
@@ -1670,7 +1670,7 @@
// Remember where word breaks occur.
if (code == 32)
{
- last_space_glyph = rec.m_glyphs.size();
+ last_space_glyph = rec.glyphs().size();
}
{
@@ -1692,7 +1692,7 @@
// error -- missing glyph!
// Log an error, but don't log too many times.
- static int s_log_count = 0;
+ static int s_log_count = 0;
if (s_log_count < 10)
{
s_log_count++;
@@ -1721,13 +1721,13 @@
}
); // IF_VERBOSE_MALFORMED_SWF
- text_glyph_record::glyph_entry ge;
- ge.m_glyph_index = index;
- ge.m_glyph_advance = scale * _font->get_advance(index, _embedFonts);
-
- rec.m_glyphs.push_back(ge);
-
- x += ge.m_glyph_advance;
+ SWF::TextRecord::GlyphEntry ge;
+ ge.index = index;
+ ge.advance = scale * _font->get_advance(index, _embedFonts);
+
+ rec.addGlyph(ge);
+
+ x += ge.advance;
}
after_x_advance:
@@ -1783,55 +1783,56 @@
// Insert newline if there's space or autosize != none
// Close out this stretch of glyphs.
- m_text_glyph_records.push_back(rec);
+ _textRecords.push_back(rec);
- float previous_x = x;
+ float previous_x = x;
x = leftMargin + blockIndent + PADDING_TWIPS;
y += fontHeight + leading;
// Start a new record on the next line.
- rec.m_glyphs.resize(0);
- rec.m_style.setFont(_font.get());
- rec.m_style.setUnderlined(underlined);
- rec.m_style.m_color = getTextColor();
- rec.m_style.setXOffset(x);
- rec.m_style.setYOffset(y);
- rec.m_style.m_text_height = getFontHeight();
+ rec.clearGlyphs();
+ rec.setFont(_font.get());
+ rec.setUnderline(underlined);
+ rec.setColor(getTextColor());
+ rec.setXOffset(x);
+ rec.setYOffset(y);
+ rec.setTextHeight(getFontHeight());
// TODO : what if m_text_glyph_records is empty ? Is it
possible ?
- assert(!m_text_glyph_records.empty());
- text_glyph_record& last_line = m_text_glyph_records.back();
+ assert(!_textRecords.empty());
+ SWF::TextRecord& last_line = _textRecords.back();
if (last_space_glyph == -1)
{
// Pull the previous glyph down onto the
// new line.
- if (last_line.m_glyphs.size() > 0)
+ if (!last_line.glyphs().empty())
{
- rec.m_glyphs.push_back(last_line.m_glyphs.back());
- x += last_line.m_glyphs.back().m_glyph_advance;
- previous_x -=
last_line.m_glyphs.back().m_glyph_advance;
- last_line.m_glyphs.resize(last_line.m_glyphs.size() -
1);
+ rec.addGlyph(last_line.glyphs().back());
+ x += last_line.glyphs().back().advance;
+ previous_x -= last_line.glyphs().back().advance;
+ last_line.clearGlyphs(1);
}
}
else
{
// Move the previous word down onto the next line.
- previous_x -=
last_line.m_glyphs[last_space_glyph].m_glyph_advance;
+ previous_x -= last_line.glyphs()[last_space_glyph].advance;
- for (unsigned int i = last_space_glyph + 1; i <
last_line.m_glyphs.size(); i++)
+ const SWF::TextRecord::Glyphs::size_type lineSize =
last_line.glyphs().size();
+ for (unsigned int i = last_space_glyph + 1; i < lineSize;
++i)
{
- rec.m_glyphs.push_back(last_line.m_glyphs[i]);
- x += last_line.m_glyphs[i].m_glyph_advance;
- previous_x -= last_line.m_glyphs[i].m_glyph_advance;
+ rec.addGlyph(last_line.glyphs()[i]);
+ x += last_line.glyphs()[i].advance;
+ previous_x -= last_line.glyphs()[i].advance;
}
- last_line.m_glyphs.resize(last_space_glyph);
+ last_line.clearGlyphs(lineSize - last_space_glyph);
}
align_line(textAlignment, last_line_start_record, previous_x);
last_space_glyph = -1;
- last_line_start_record = m_text_glyph_records.size();
+ last_line_start_record = _textRecords.size();
}
else
@@ -1848,9 +1849,10 @@
#ifdef GNASH_DEBUG_TEXT_FORMATTING
log_debug("Text with wordWrap exceeds height of box");
#endif
- rec.m_glyphs.clear();
+ rec.clearGlyphs();
// TODO: should still compute m_text_bounds !
- LOG_ONCE(log_unimpl("Computing text bounds of a TextField
containing text that doesn't fit the box vertically"));
+ LOG_ONCE(log_unimpl("Computing text bounds of a TextField "
+ "containing text that doesn't fit the box
vertically"));
break;
}
@@ -1872,7 +1874,7 @@
}
// Add this line to our output.
- if ( ! rec.m_glyphs.empty() ) m_text_glyph_records.push_back(rec);
+ if (!rec.glyphs().empty()) _textRecords.push_back(rec);
float extra_space = align_line(textAlignment, last_line_start_record, x);
@@ -2214,11 +2216,11 @@
_textColor = col;
// Change color of all current glyph records
- for (TextGlyphRecords::iterator i=m_text_glyph_records.begin(),
- e=m_text_glyph_records.end(); i!=e; ++i)
+ for (TextRecords::iterator i=_textRecords.begin(),
+ e = _textRecords.end(); i!=e; ++i)
{
- text_glyph_record& rec=*i;
- rec.m_style.m_color = _textColor;
+ SWF::TextRecord& rec = *i;
+ rec.setColor(_textColor);
}
}
=== modified file 'libcore/TextField.h'
--- a/libcore/TextField.h 2008-11-06 13:56:00 +0000
+++ b/libcore/TextField.h 2008-11-07 22:19:58 +0000
@@ -20,16 +20,15 @@
#include "character.h" // for inheritance
#include "styles.h" // for fill_style and line_style
-#include "text.h" // for text_glyph_record
#include "Range2d.h"
#include "rect.h" // for inlines
#include "font.h" // for visibility of font add_ref/drop_ref
// Forward declarations
namespace gnash {
- class text_glyph_record;
namespace SWF {
class DefineEditTextTag;
+ class TextRecord;
}
}
@@ -505,8 +504,8 @@
m_text_bounding_box.set_to_point(x, y);
}
- typedef std::vector<text_glyph_record> TextGlyphRecords;
- TextGlyphRecords m_text_glyph_records;
+ typedef std::vector<SWF::TextRecord> TextRecords;
+ TextRecords _textRecords;
/// used to pass a color on to shape_character::display()
std::vector<fill_style> m_dummy_style;
=== modified file 'libcore/font.h'
--- a/libcore/font.h 2008-10-30 13:15:12 +0000
+++ b/libcore/font.h 2008-11-07 18:07:45 +0000
@@ -140,18 +140,6 @@
{
}
- /// Get number of embedded glyphs defined for this font
- //
- /// Callers of this function are:
- ///
- /// - fontlib, for writing cache data (known to be not working
anyway).
- /// - edit_text_character, for validating the font (obsoleted too).
- ///
- int getEmbedGlyphCount() const
- {
- return _embedGlyphTable.size();
- }
-
/// Get glyph by index.
//
/// @param glyph_index
=== modified file 'libcore/impl.cpp'
--- a/libcore/impl.cpp 2008-11-07 16:05:23 +0000
+++ b/libcore/impl.cpp 2008-11-07 18:07:45 +0000
@@ -40,6 +40,7 @@
#include "DefineButtonCxformTag.h"
#include "CSMTextSettingsTag.h"
#include "DefineButtonTag.h"
+#include "DefineTextTag.h"
#include "PlaceObject2Tag.h"
#include "RemoveObjectTag.h"
#include "DoActionTag.h"
@@ -105,7 +106,7 @@
register_tag_loader(SWF::JPEGTABLES, jpeg_tables_loader);
register_tag_loader(SWF::SETBACKGROUNDCOLOR,
SetBackgroundColorTag::loader);
register_tag_loader(SWF::DEFINEFONT, define_font_loader);
- register_tag_loader(SWF::DEFINETEXT, define_text_loader);
+ register_tag_loader(SWF::DEFINETEXT, DefineTextTag::loader);
register_tag_loader(SWF::DOACTION, DoActionTag::doActionLoader);
register_tag_loader(SWF::DEFINEFONTINFO, define_font_info_loader);
// 62
@@ -138,7 +139,7 @@
// 30 - _UNKNOWN_ unimplemented
register_tag_loader(SWF::FREEALL, fixme_loader); // 31
register_tag_loader(SWF::DEFINESHAPE3, define_shape_loader);
- register_tag_loader(SWF::DEFINETEXT2, define_text_loader);
+ register_tag_loader(SWF::DEFINETEXT2, DefineText2Tag::loader);
// 37
register_tag_loader(SWF::DEFINEBUTTON2, DefineButton2Tag::loader);
register_tag_loader(SWF::DEFINEBITSJPEG3, define_bits_jpeg3_loader);
=== modified file 'libcore/parser/Makefile.am'
--- a/libcore/parser/Makefile.am 2008-11-07 16:05:23 +0000
+++ b/libcore/parser/Makefile.am 2008-11-07 18:07:45 +0000
@@ -51,7 +51,6 @@
bitmap_character_def.cpp \
BitmapMovieDefinition.cpp \
character_def.cpp \
- text_character_def.cpp \
SWFMovieDefinition.cpp \
morph2_character_def.cpp \
shape_character_def.cpp \
@@ -64,7 +63,6 @@
character_def.h \
bitmap_character_def.h \
BitmapMovieDefinition.h \
- text_character_def.h \
morph2_character_def.h \
movie_definition.h \
SWFMovieDefinition.h \
=== modified file 'libcore/swf/DefineButtonSoundTag.h'
--- a/libcore/swf/DefineButtonSoundTag.h 2008-11-07 16:05:23 +0000
+++ b/libcore/swf/DefineButtonSoundTag.h 2008-11-08 10:04:43 +0000
@@ -68,8 +68,6 @@
typedef std::vector<ButtonSound> Sounds;
- DefineButtonSoundTag(SWFStream& in, movie_definition& m);
-
static void loader(SWFStream& in, tag_type tag, movie_definition& m,
const RunInfo& r);
@@ -97,6 +95,11 @@
private:
+ /// Construct a DefineButtonSoundTag.
+ //
+ /// This can only be used from the loader() function.
+ DefineButtonSoundTag(SWFStream& in, movie_definition& m);
+
void read(SWFStream& in, movie_definition& m);
Sounds _sounds;
=== modified file 'libcore/swf/DefineButtonTag.h'
--- a/libcore/swf/DefineButtonTag.h 2008-11-07 16:14:21 +0000
+++ b/libcore/swf/DefineButtonTag.h 2008-11-08 10:04:43 +0000
@@ -189,9 +189,6 @@
typedef std::vector<ButtonRecord> ButtonRecords;
typedef std::vector<ButtonAction*> ButtonActions;
- /// Construct a DefineButtonTag (DefinitionTag) (SWF)
- DefineButtonTag(SWFStream& in, movie_definition& m, tag_type tag);
-
virtual ~DefineButtonTag();
/// Create a mutable instance of our definition.
@@ -281,6 +278,14 @@
private:
+ /// DefineButton2Tag::loader also needs to create a DefineButtonTag.
+ friend class DefineButton2Tag;
+
+ /// Construct a DefineButtonTag (DefinitionTag)
+ //
+ /// This can only be constructed using a loader() function.
+ DefineButtonTag(SWFStream& in, movie_definition& m, tag_type tag);
+
/// Read a DEFINEBUTTON tag
void readDefineButtonTag(SWFStream& in, movie_definition& m);
=== modified file 'libcore/swf/DefineEditTextTag.h'
--- a/libcore/swf/DefineEditTextTag.h 2008-11-06 13:56:00 +0000
+++ b/libcore/swf/DefineEditTextTag.h 2008-11-08 10:04:43 +0000
@@ -61,12 +61,11 @@
public:
- DefineEditTextTag(SWFStream& in, movie_definition& m);
-
~DefineEditTextTag() {}
/// Load an SWF::DEFINEEDITTEXT (37) tag.
- static void loader(SWFStream& in, tag_type tag, movie_definition& m,
const RunInfo& r);
+ static void loader(SWFStream& in, tag_type tag, movie_definition& m,
+ const RunInfo& r);
const rect& get_bound() const { return _rect; }
@@ -226,9 +225,16 @@
private:
+ /// Construct a DefineEditTextTag.
+ //
+ /// This should only be used from the loader() function.
+ DefineEditTextTag(SWFStream& in, movie_definition& m);
+
+ /// Read a tag from the SWFStream.
void read(SWFStream& in, movie_definition& m);
rect _rect;
+
std::string _variableName;
// For an SWF-defined textfield we'll read
@@ -292,7 +298,7 @@
/// height of font text, in twips
// TODO: initialize to a meaningful value (see MovieClip::add_textfield)
// and make sure get_font_height is not called for rendering purposes
- // (instead call a method of edit_text_character_def)
+ // (instead call a method of TextField) (?)
boost::uint16_t _textHeight;
/// Text color
=== modified file 'libcore/swf/DefineFontAlignZonesTag.cpp'
--- a/libcore/swf/DefineFontAlignZonesTag.cpp 2008-10-29 09:45:23 +0000
+++ b/libcore/swf/DefineFontAlignZonesTag.cpp 2008-11-08 10:04:43 +0000
@@ -30,6 +30,8 @@
DefineFontAlignZonesTag::DefineFontAlignZonesTag(movie_definition& /* m */,
SWFStream& /* in */)
+ :
+ _csm_table_int(2)
{
}
@@ -38,7 +40,7 @@
DefineFontAlignZonesTag::loader(SWFStream& in, tag_type tag,
movie_definition& m, const RunInfo& /*r*/)
{
- assert(tag == SWF::DEFINEALIGNZONES); // 73
+ assert(tag == SWF::DEFINEALIGNZONES);
in.ensureBytes(1);
unsigned short ref = in.read_u8(); // must reference a valid
DEFINEFONT3 tag
@@ -46,7 +48,8 @@
if ( ! referencedFont )
{
IF_VERBOSE_MALFORMED_SWF(
- log_swferror(_("DefineFontAlignZones tag references an
undefined font %d"), ref);
+ log_swferror(_("DefineFontAlignZones tag references an
undefined "
+ "font %d"), ref);
);
in.skip_to_tag_end();
return;
=== modified file 'libcore/swf/DefineFontAlignZonesTag.h'
--- a/libcore/swf/DefineFontAlignZonesTag.h 2008-10-28 21:17:19 +0000
+++ b/libcore/swf/DefineFontAlignZonesTag.h 2008-11-08 10:04:43 +0000
@@ -41,15 +41,20 @@
THICK = 2
};
+
+ static void loader(SWFStream& in, tag_type tag, movie_definition& m,
+ const RunInfo& r);
+
+private:
+
+ /// Construct a DefineFoneAlignZonesTag
+ //
+ /// This should only be called from the loader() function.
DefineFontAlignZonesTag(movie_definition& m, SWFStream& in);
- static void loader(SWFStream& in, tag_type tag, movie_definition& m,
const RunInfo& r);
-
-private:
-
unsigned short _font2_id_ref;
- unsigned _csm_table_int:2;
+ unsigned _csm_table_int;
};
=== renamed file 'libcore/parser/text_character_def.cpp' =>
'libcore/swf/DefineTextTag.cpp'
--- a/libcore/parser/text_character_def.cpp 2008-10-19 19:36:12 +0000
+++ b/libcore/swf/DefineTextTag.cpp 2008-11-08 10:04:43 +0000
@@ -1,4 +1,4 @@
-// text_character_def.cpp: Read text character definitions, for Gnash.
+// DefineTextTag.cpp: Read text character definitions, for Gnash.
// Derived from text.cpp -- Thatcher Ulrich <address@hidden> 2003
@@ -7,168 +7,84 @@
// Code for the text tags.
+#include "DefineTextTag.h"
#include "SWFStream.h"
#include "log.h"
-#include "text_character_def.h"
#include "swf.h"
+#include "TextRecord.h"
namespace gnash {
-
-void text_character_def::read(SWFStream& in, int tag_type,
- movie_definition& m)
-{
- assert(tag_type == SWF::DEFINETEXT || tag_type == SWF::DEFINETEXT2);
-
- m_rect.read(in);
- m_matrix.read(in);
+namespace SWF {
+
+void
+DefineTextTag::loader(SWFStream& in, tag_type tag, movie_definition& m,
+ const RunInfo& /*r*/)
+{
+ assert(tag == DEFINETEXT);
+
+ in.ensureBytes(2);
+ boost::uint16_t id = in.read_u16();
+
+ std::auto_ptr<DefineTextTag> t(new DefineTextTag(in, m, tag));
+ IF_VERBOSE_PARSE(
+ log_parse(_("Text character, id = %d"), id);
+ );
+
+ m.add_character(id, t.release());
+}
+
+void
+DefineText2Tag::loader(SWFStream& in, tag_type tag, movie_definition& m,
+ const RunInfo& /*r*/)
+{
+ assert(tag == DEFINETEXT2);
+
+ in.ensureBytes(2);
+ boost::uint16_t id = in.read_u16();
+
+ std::auto_ptr<DefineTextTag> t(new DefineTextTag(in, m, tag));
+ IF_VERBOSE_PARSE(
+ log_parse(_("Text character, id = %d"), id);
+ );
+
+ m.add_character(id, t.release());
+}
+
+void
+DefineTextTag::read(SWFStream& in, movie_definition&m, tag_type tag)
+{
+ assert(tag == DEFINETEXT || tag == DEFINETEXT2);
+
+ _rect.read(in);
+ _matrix.read(in);
in.ensureBytes(2); // glyph_bits + advance_bits
- int glyph_bits = in.read_u8();
- int advance_bits = in.read_u8();
+ int glyphBits = in.read_u8();
+ int advanceBits = in.read_u8();
IF_VERBOSE_PARSE(
- log_parse(_("begin text records for text_character_def %p"),
(void*)this);
+ log_parse(_("begin text records for DefineTextTag %p"),
(void*)this);
);
- bool last_record_was_style_change = false;
-
- text_style style;
+ /// Parse until there are no more records.
for (;;)
{
- in.ensureBytes(1);
- unsigned int first_byte = in.read_u8();
-
- if (first_byte == 0)
- {
- // This is the end of the text records.
- IF_VERBOSE_PARSE(
- log_parse(_("end text records"));
- );
- break;
- }
-
- // Style changes and glyph records just alternate.
- // (Contrary to what most SWF references say!)
- if (last_record_was_style_change == false)
- {
- // This is a style change.
-
- last_record_was_style_change = true;
-
- bool has_font = (first_byte >> 3) & 1;
- bool has_color = (first_byte >> 2) & 1;
- bool has_y_offset = (first_byte >> 1) & 1;
- bool has_x_offset = (first_byte >> 0) & 1;
-
- IF_VERBOSE_PARSE(
- log_parse(_(" text style change"));
- );
-
- if (has_font)
- {
- in.ensureBytes(2);
- boost::uint16_t font_id = in.read_u16();
- if ( ! style.setFont(font_id, m) )
- {
- // setFont would have already printed
an swferror on failure
- }
-
- IF_VERBOSE_PARSE(
- log_parse(_(" has_font: font id = %d (%p)"),
font_id, (const void*)style.getFont());
- );
- } // else reuse previous record font
-
- if (has_color)
- {
- if (tag_type == SWF::DEFINETEXT)
- {
- style.m_color.read_rgb(in);
- }
- else
- {
- assert(tag_type == SWF::DEFINETEXT2);
- style.m_color.read_rgba(in);
- }
- IF_VERBOSE_PARSE(
- log_parse(_(" has_color"));
- );
- } // else reuse previous record color
-
- if (has_x_offset)
- {
- in.ensureBytes(2);
- style.setXOffset(in.read_s16());
- IF_VERBOSE_PARSE(
- log_parse(_(" has_x_offset = %g"),
style.getXOffset());
- );
- }
- else
- {
- // continue where previous record left
- style.dropXOffset();
- }
-
- if (has_y_offset)
- {
- in.ensureBytes(2);
- style.setYOffset(in.read_s16());
- IF_VERBOSE_PARSE(
- log_parse(_(" has_y_offset = %g"),
style.getYOffset());
- );
- }
- else
- {
- // continue where previous record left
- style.dropYOffset();
- }
- if (has_font)
- {
- in.ensureBytes(2);
- style.m_text_height = in.read_u16();
- IF_VERBOSE_PARSE(
- log_parse(_(" text_height = %g"),
style.m_text_height);
- );
- }
- }
- else
- {
- // Read the glyph record.
-
- last_record_was_style_change = false;
-
- unsigned int glyph_count = first_byte;
-
-// if (! last_record_was_style_change)
-// {
-// glyph_count &= 0x7F;
-// }
-// // else { Don't mask the top bit; the first record is
allowed to have > 127 glyphs. }
-
- m_text_glyph_records.resize(m_text_glyph_records.size()
+ 1);
- text_glyph_record& grecord =
m_text_glyph_records.back();
- grecord.m_style = style; // copy current style
- grecord.read(in, glyph_count, glyph_bits, advance_bits);
-
- IF_VERBOSE_PARSE(
- log_parse(_(" glyph_records: count = %d"),
glyph_count);
- for (unsigned int i = 0; i < glyph_count; i++)
- {
- text_glyph_record::glyph_entry& ge =
grecord.m_glyphs[i];
- log_parse(_(" glyph%d: index=%d,
advance=%g"), i, ge.m_glyph_index, ge.m_glyph_advance);
- }
- );
- }
+ TextRecord text;
+ if (!text.read(in, m, glyphBits, advanceBits, tag)) break;
+ _textRecords.push_back(text);
}
}
-void text_character_def::display(character* inst)
+void
+DefineTextTag::display(character* inst)
{
-// GNASH_REPORT_FUNCTION;
-
- bool useEmbeddedGlyphs = true;
-
- display_glyph_records(m_matrix, inst,
- m_text_glyph_records, useEmbeddedGlyphs);
-}
-
+
+ const bool useEmbeddedGlyphs = true;
+
+ TextRecord::displayRecords(_matrix, inst, _textRecords,
+ useEmbeddedGlyphs);
+}
+
+
+}
} // end namespace gnash
=== renamed file 'libcore/parser/text_character_def.h' =>
'libcore/swf/DefineTextTag.h'
--- a/libcore/parser/text_character_def.h 2008-10-19 19:36:12 +0000
+++ b/libcore/swf/DefineTextTag.h 2008-11-08 10:04:43 +0000
@@ -15,54 +15,81 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-//
-//
-//
-
-// Code for the text tags.
-
-
-#ifndef GNASH_PARSER_TEXT_CHARACTER_DEF_H
-#define GNASH_PARSER_TEXT_CHARACTER_DEF_H
+#ifndef GNASH_SWF_DEFINETEXTTAG_H
+#define GNASH_SWF_DEFINETEXTTAG_H
#include "character_def.h" // for inheritance
-#include "text.h" // for text_glyph_record
#include "styles.h"
#include "rect.h" // for composition
-
-namespace gnash {
-
-class movie_definition; // for read signature
-class SWFStream; // for read signature
+#include "swf.h"
+#include "movie_definition.h"
+#include "SWFMatrix.h"
+#include "TextRecord.h"
+
+namespace gnash {
+ class movie_definition;
+ class SWFStream;
+ class RunInfo;
+}
+
+namespace gnash {
+namespace SWF {
+
/// Text character
//
/// This is either read from SWF stream
/// or (hopefully) created with scripting
///
-class text_character_def : public character_def
+class DefineTextTag : public character_def
{
public:
- rect m_rect;
- SWFMatrix m_matrix;
- std::vector<text_glyph_record> m_text_glyph_records;
-
- text_character_def() {}
-
- void read(SWFStream& in, int tag_type, movie_definition& m);
+
+ static void loader(SWFStream& in, tag_type tag, movie_definition& m,
+ const RunInfo& r);
/// Draw the string.
void display(character* inst);
const rect& get_bound() const {
- // TODO: There is a m_matrix field in the definition(!) that's currently
- // ignored. Don't know if it needs to be transformed...
- return m_rect;
- }
+ // TODO: There is a _matrix field in the definition(!) that's
+ // currently ignored. Don't know if it needs to be transformed...
+ return _rect;
+ }
+
+private:
+
+ /// DefineText2Tag::loader also constructs a DefineTextTag.
+ friend class DefineText2Tag;
+
+ /// Construct a DefineTextTag.
+ //
+ /// This should only be constructed using the loader() functions.
+ DefineTextTag(SWFStream& in, movie_definition& m, tag_type tag)
+ {
+ read(in, m, tag);
+ }
+
+ rect _rect;
+
+ SWFMatrix _matrix;
+
+ void read(SWFStream& in, movie_definition& m, tag_type tag);
-};
-
-
+ std::vector<TextRecord> _textRecords;
+};
+
+/// Parse a DefineText2Tag.
+//
+/// This creates a DefineTextTag, as there are only minor differences.
+class DefineText2Tag
+{
+public:
+ static void loader(SWFStream& in, tag_type tag, movie_definition& m,
+ const RunInfo& r);
+};
+
+} // namespace SWF
} // namespace gnash
-#endif // GNASH_PARSER_TEXT_CHARACTER_DEF_H
+#endif
=== modified file 'libcore/swf/DefineVideoStreamTag.h'
--- a/libcore/swf/DefineVideoStreamTag.h 2008-11-07 09:53:14 +0000
+++ b/libcore/swf/DefineVideoStreamTag.h 2008-11-08 10:04:43 +0000
@@ -72,14 +72,6 @@
{
public:
- /// 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
- /// constructor, as that's the one which will eventually get passed
- /// the id.
- DefineVideoStreamTag(SWFStream& in, boost::uint16_t id);
-
~DefineVideoStreamTag();
character* create_character_instance(character* parent, int id);
@@ -142,6 +134,15 @@
private:
+ /// 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
+ /// constructor, as that's the one which will eventually get passed
+ /// the id.
+ /// NOTE: What dynamically created definitions?
+ DefineVideoStreamTag(SWFStream& in, boost::uint16_t id);
+
void read(SWFStream& in);
/// Id of this character definition, set by constructor.
=== modified file 'libcore/swf/StartSoundTag.cpp'
--- a/libcore/swf/StartSoundTag.cpp 2008-11-07 12:55:48 +0000
+++ b/libcore/swf/StartSoundTag.cpp 2008-11-08 10:04:43 +0000
@@ -109,6 +109,7 @@
IF_VERBOSE_PARSE(
log_parse("StartSound2 tag: SoundClassName %s", className);
);
+ in.skip_to_tag_end();
}
=== modified file 'libcore/swf/StreamSoundBlockTag.cpp'
--- a/libcore/swf/StreamSoundBlockTag.cpp 2008-10-30 21:35:10 +0000
+++ b/libcore/swf/StreamSoundBlockTag.cpp 2008-11-08 10:04:43 +0000
@@ -46,7 +46,8 @@
/* public static */
void
-StreamSoundBlockTag::loader(SWFStream& in, tag_type tag, movie_definition& m,
const RunInfo& r)
+StreamSoundBlockTag::loader(SWFStream& in, tag_type tag, movie_definition& m,
+ const RunInfo& r)
{
assert(tag == SWF::SOUNDSTREAMBLOCK); // 19
=== modified file 'libcore/swf/StreamSoundBlockTag.h'
--- a/libcore/swf/StreamSoundBlockTag.h 2008-10-28 21:43:42 +0000
+++ b/libcore/swf/StreamSoundBlockTag.h 2008-11-08 10:04:43 +0000
@@ -63,6 +63,18 @@
public:
+ /// Start the associated block of sound
+ void execute(MovieClip* m, DisplayList& dlist) const;
+
+ /// Load an SWF::SOUNDSTREAMBLOCK (19) tag.
+ static void loader(SWFStream& in, tag_type tag, movie_definition& m,
+ const RunInfo& r);
+
+ /// Not a "state" (DisplayList?) tag, do doesn't need to provide
+ /// execute_state
+
+private:
+
/// Create a ControlTag playing the given sample when executed.
//
/// @param handlerId
@@ -72,20 +84,12 @@
/// Offset to start playback from.
/// (Should be offset of the associated sound block).
///
+ /// This should only be constructed using the loader() function.
StreamSoundBlockTag(int handlerId, long start)
:
m_handler_id(handlerId),
m_start(start)
{}
-
- /// Start the associated block of sound
- void execute(MovieClip* m, DisplayList& /*dlist*/) const;
-
- /// Load an SWF::SOUNDSTREAMBLOCK (19) tag.
- static void loader(SWFStream& in, tag_type tag, movie_definition& m,
const RunInfo& r);
-
- /// Not a "state" (DisplayList?) tag, do doesn't need to provide
execute_state
- //void execute_state(MovieClip* m) const {}
};
=== added file 'libcore/swf/TextRecord.cpp'
--- a/libcore/swf/TextRecord.cpp 1970-01-01 00:00:00 +0000
+++ b/libcore/swf/TextRecord.cpp 2008-11-08 10:04:43 +0000
@@ -0,0 +1,286 @@
+//
+// Copyright (C) 2005, 2006, 2007, 2008 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 "TextRecord.h"
+#include "SWFStream.h"
+#include "SWFMatrix.h"
+#include "cxform.h"
+#include "movie_definition.h"
+#include "character.h"
+#include "swf.h"
+#include "log.h"
+#include "render.h"
+#include "font.h"
+
+#include <vector>
+
+namespace gnash {
+namespace SWF {
+
+bool
+TextRecord::read(SWFStream& in, movie_definition& m, int glyphBits,
+ int advanceBits, tag_type tag)
+{
+ in.ensureBytes(1);
+ boost::uint8_t flags = in.read_u8();
+
+ if (!flags)
+ {
+ // This is the end of the text records.
+ IF_VERBOSE_PARSE(
+ log_parse(_("end text records"));
+ );
+ return false;
+ }
+
+ bool hasFont = (flags >> 3) & 1;
+ bool hasColor = (flags >> 2) & 1;
+ _hasYOffset = (flags >> 1) & 1;
+ _hasXOffset = (flags >> 0) & 1;
+
+ if (hasFont)
+ {
+ in.ensureBytes(2);
+ boost::uint16_t fontID = in.read_u16();
+
+ _font = m.get_font(fontID);
+ if (!_font)
+ {
+ // What do we do now?
+ IF_VERBOSE_PARSE(
+ log_parse("Font not found.");
+ );
+ }
+ else
+ {
+ IF_VERBOSE_PARSE(
+ log_parse(_(" has_font: font id = %d (%p)"), fontID,
+ (void*)_font);
+ );
+ }
+ }
+
+ if (hasColor)
+ {
+ if (tag == DEFINETEXT) _color.read_rgb(in);
+ else _color.read_rgba(in);
+
+ IF_VERBOSE_PARSE(
+ log_parse(_(" hasColor"));
+ );
+ }
+
+ if (_hasXOffset)
+ {
+ in.ensureBytes(2);
+ _xOffset = in.read_s16();
+ IF_VERBOSE_PARSE(
+ log_parse(_(" xOffset = %g"), _xOffset);
+ );
+ }
+
+ if (_hasYOffset)
+ {
+ in.ensureBytes(2);
+ _yOffset = in.read_s16();
+ IF_VERBOSE_PARSE(
+ log_parse(_(" _yOffset = %g"), _yOffset);
+ );
+ }
+
+ if (hasFont)
+ {
+ in.ensureBytes(2);
+ _textHeight = in.read_u16();
+ IF_VERBOSE_PARSE(
+ log_parse(_(" textHeight = %g"), _textHeight);
+ );
+ }
+
+ in.ensureBytes(1);
+ boost::uint8_t glyphCount = in.read_u8();
+ if (!glyphCount) return false;
+
+ IF_VERBOSE_PARSE(
+ log_parse(_(" glyph_records: count = %d"), glyphCount);
+ );
+
+ in.ensureBits(glyphCount * (glyphBits + advanceBits));
+ for (unsigned int i = 0; i < glyphCount; ++i)
+ {
+ GlyphEntry ge;
+ ge.index = in.read_uint(glyphBits);
+ ge.advance = static_cast<float>(in.read_sint(advanceBits));
+ _glyphs.push_back(ge);
+ IF_VERBOSE_PARSE(
+ log_parse(_(" glyph%d: index=%d, advance=%g"), i,
+ ge.index, ge.advance);
+ );
+ }
+
+ // Continue parsing more records.
+ return true;
+}
+
+
+// Render the given glyph records.
+void
+TextRecord::displayRecords(const SWFMatrix& this_mat, character* inst,
+ const std::vector<SWF::TextRecord>& records, bool embedded)
+{
+
+ SWFMatrix mat = inst->getWorldMatrix();
+ mat.concatenate(this_mat);
+
+ cxform cx = inst->get_world_cxform();
+ SWFMatrix base_matrix = mat;
+
+ // Starting positions.
+ float x = 0.0f;
+ float y = 0.0f;
+
+ for (std::vector<TextRecord>::const_iterator i = records.begin(),
+ e = records.end(); i !=e; ++i)
+ {
+
+ // Draw the characters within the current record; i.e. consecutive
+ // chars that share a particular style.
+ const TextRecord& rec = *i;
+
+ // Used to pass a color on to shape_character::display()
+ // FIXME: this isn't very good, especially the line style.
+ static std::vector<fill_style> s_dummy_style(1, fill_style());
+ static std::vector<line_style> s_dummy_line_style;
+
+ const font* fnt = rec.getFont();
+ if (!fnt) {
+ IF_VERBOSE_MALFORMED_SWF(
+ log_swferror("No font in style of TextRecord");
+ );
+ return;
+ }
+
+ // unitsPerEM returns an int, we cast to float to get
+ // a float division
+ const float unitsPerEM = fnt->unitsPerEM(embedded);
+ const float scale = rec.textHeight() / unitsPerEM;
+
+#ifdef GNASH_DEBUG_TEXT_RENDERING
+ log_debug("font for TextRecord == %p" static_cast<void*>(fnt));
+#endif
+
+ if (rec.hasXOffset()) x = rec.xOffset();
+ if (rec.hasYOffset()) y = rec.yOffset();
+
+ boost::int16_t startX = x; // for the underline, if any
+
+ s_dummy_style[0].set_color(rec.color());
+
+ rgba textColor = cx.transform(rec.color());
+
+ typedef SWF::TextRecord::Glyphs Glyphs;
+ for (Glyphs::const_iterator j = rec.glyphs().begin(),
+ je = rec.glyphs().end(); j != je; ++j)
+ {
+ // the glyph entry
+ const SWF::TextRecord::GlyphEntry& ge = *j;
+
+ int index = ge.index;
+
+ mat = base_matrix;
+ mat.concatenate_translation(x, y);
+ mat.concatenate_scale(scale, scale);
+
+ if (index == -1)
+ {
+#ifdef GNASH_DEBUG_TEXT_RENDERING
+ log_error(_("invalid glyph (-1)"));
+#endif
+
+#ifdef DRAW_INVALID_GLYPHS_AS_EMPTY_BOXES
+ // The EM square is 1024x1024, but usually isn't filled up.
+ // We'll use about half the width, and around 3/4 the height.
+ // Values adjusted by eye.
+ // The Y baseline is at 0; negative Y is up.
+ //
+ // TODO: FIXME (if we'll ever enable it back): the EM
+ // square is not hard-coded anymore but can be
+ // queried from the font class
+ //
+ static const boost::int16_t s_empty_char_box[5 * 2] =
+ {
+ 32, 32,
+ 480, 32,
+ 480, -656,
+ 32, -656,
+ 32, 32
+ };
+ render::draw_line_strip(s_empty_char_box, 5,
+ textColor, mat);
+#endif
+
+ }
+ else
+ {
+ shape_character_def* glyph = fnt->get_glyph(index, embedded);
+
+ // Draw the character using the filled outline.
+ if (glyph)
+ {
+#ifdef GNASH_DEBUG_TEXT_RENDERING
+ log_debug(_("render shape glyph using filled outline
(render::draw_glyph)"));
+#endif
+
+ gnash::render::draw_glyph(glyph, mat,
+ textColor);
+ }
+ }
+ x += ge.advance;
+ }
+
+ if (rec.underline())
+ {
+ // Underline should end where last displayed glyphs
+ // does. 'x' here is where next glyph would be displayed
+ // which is normally after some space.
+ // For more precise metrics we should substract the advance
+ // of last glyph and add the actual size of it.
+ // This will only be known if a glyph was actually found,
+ // or would be the size of the empty box (arbitrary size)
+ //
+ boost::int16_t endX = (int)x; // -
rec.m_glyphs.back().m_glyph_advance + (480.0*scale);
+
+ // The underline is made to be some pixels below the baseline (0)
+ // and scaled so it's further as font size increases.
+ //
+ // 1/4 the EM square offset far from baseline
+ boost::int16_t posY = int(y+int((unitsPerEM/4)*scale));
+
+ boost::int16_t underline[2 * 2] =
+ {
+ startX, posY,
+ endX, posY,
+ };
+ render::draw_line_strip(underline, 2, textColor,
+ base_matrix);
+ }
+ }
+}
+
+
+} // namespace SWF
+} // namespace gnash
=== added file 'libcore/swf/TextRecord.h'
--- a/libcore/swf/TextRecord.h 1970-01-01 00:00:00 +0000
+++ b/libcore/swf/TextRecord.h 2008-11-08 10:04:43 +0000
@@ -0,0 +1,186 @@
+//
+// Copyright (C) 2005, 2006, 2007, 2008 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_TEXTRECORD_H
+#define GNASH_SWF_TEXTRECORD_H
+
+#include "RGBA.h"
+#include "swf.h"
+#include <vector>
+
+namespace gnash {
+ class character;
+ class movie_definition;
+ class SWFStream;
+ class SWFMatrix;
+ class font;
+}
+
+namespace gnash {
+namespace SWF {
+
+/// Store a TextRecord.
+//
+/// This consists of style information and a number of glyphs.
+/// This may be parsed from a SWFStream, or it can be constructed
+/// dynamically by TextField. A static TextField has fewer possible
+/// properties than a dynamic one.
+class TextRecord
+{
+public:
+
+ struct GlyphEntry
+ {
+ int index;
+ float advance;
+ };
+
+ TextRecord()
+ :
+ _color(0, 0, 0, 255),
+ _textHeight(1.0f),
+ _hasXOffset(false),
+ _hasYOffset(false),
+ _xOffset(0.0f),
+ _yOffset(0.0f),
+ _font(0),
+ _underline(false)
+ {}
+
+ typedef std::vector<GlyphEntry> Glyphs;
+ Glyphs _glyphs;
+
+ /// Read a TextRecord from the stream
+ //
+ /// @param in The SWFStream to read from.
+ /// @param m The movie_definition containing this TextRecord.
+ /// @param glyphBits The number of bits per glyph
+ /// @param advanceBits The number of bits per advance
+ /// @param tag The tag type of this TextRecord. This must be
+ /// DefineText or DefineText2
+ /// @return False if we have reached the end of the
+ /// TextRecords, true if there are more to parse.
+ bool read(SWFStream& in, movie_definition& m, int glyphBits,
+ int advanceBits, tag_type tag);
+
+ static void displayRecords(const SWFMatrix& this_mat, character* inst,
+ const std::vector<SWF::TextRecord>& records, bool useEmbeddedGlyphs);
+
+ const Glyphs& glyphs() const {
+ return _glyphs;
+ }
+
+ void addGlyph(const GlyphEntry& ge, Glyphs::size_type num = 1) {
+ _glyphs.insert(_glyphs.end(), num, ge);
+ }
+
+ void clearGlyphs(Glyphs::size_type num = 0) {
+ if (!num) _glyphs.clear();
+ else _glyphs.resize(_glyphs.size() - num);
+ }
+
+ // TODO: check font properly.
+ void setFont(const font* f) {
+ _font = f;
+ }
+
+ const font* getFont() const {
+ return _font;
+ }
+
+ void setTextHeight(float height) {
+ _textHeight = height;
+ }
+
+ float textHeight() const {
+ return _textHeight;
+ }
+
+ bool hasXOffset() const {
+ return _hasXOffset;
+ }
+
+ void setXOffset(float x) {
+ _hasXOffset = true;
+ _xOffset = x;
+ }
+
+ float xOffset() const {
+ return _xOffset;
+ }
+
+ bool hasYOffset() const {
+ return _hasYOffset;
+ }
+
+ void setYOffset(float y) {
+ _hasYOffset = true;
+ _yOffset = y;
+ }
+
+ float yOffset() const {
+ return _yOffset;
+ }
+
+ void setColor(const rgba& color) {
+ _color = color;
+ }
+
+ const rgba& color() const {
+ return _color;
+ }
+
+ bool underline() const {
+ return _underline;
+ }
+
+ void setUnderline(bool b) {
+ _underline = b;
+ }
+
+private:
+
+ /// The text color.
+ rgba _color;
+
+ /// The height of the text as a multiple of the font height.
+ float _textHeight;
+
+ /// Whether the TextRecord has an x offset.
+ bool _hasXOffset;
+
+ /// Whether the TextRecord has a y offset.
+ bool _hasYOffset;
+
+ /// The x offset of the text, by default 0.0
+ float _xOffset;
+
+ /// The y offset of the text, by default 0.0
+ float _yOffset;
+
+ /// The font associated with the TextRecord. Can be NULL.
+ const font* _font;
+
+ /// Whether the text should be underlined.
+ bool _underline;
+};
+
+} // namespace SWF
+} // namespace gnash
+
+
+#endif
=== modified file 'libcore/swf/tag_loaders.cpp'
--- a/libcore/swf/tag_loaders.cpp 2008-11-07 16:05:23 +0000
+++ b/libcore/swf/tag_loaders.cpp 2008-11-07 18:07:45 +0000
@@ -48,7 +48,6 @@
#include "SWFMovieDefinition.h"
#include "swf.h"
#include "swf/TagLoadersTable.h"
-#include "text_character_def.h"
#include "URL.h"
#include "GnashException.h"
#include "swf/DefineVideoStreamTag.h"
@@ -1097,25 +1096,6 @@
}
-// See description in header
-void
-define_text_loader(SWFStream& in, tag_type tag, movie_definition& m,
- const RunInfo& /*r*/)
-{
- assert(tag == SWF::DEFINETEXT || tag == SWF::DEFINETEXT2);
-
- in.ensureBytes(2);
- boost::uint16_t character_id = in.read_u16();
-
- text_character_def* ch = new text_character_def();
- IF_VERBOSE_PARSE(
- log_parse(_("text_character, id = %d"), character_id);
- );
- ch->read(in, tag, m);
-
- m.add_character(character_id, ch);
-}
-
//
// Sound
//
=== modified file 'libcore/swf/tag_loaders.h'
--- a/libcore/swf/tag_loaders.h 2008-11-07 16:05:23 +0000
+++ b/libcore/swf/tag_loaders.h 2008-11-07 18:07:45 +0000
@@ -95,10 +95,6 @@
void define_font_name_loader(SWFStream&, tag_type, movie_definition&,
const RunInfo&);
-/// Read SWF::DEFINETEXT and SWF::DEFINETEXT2 tags.
-void define_text_loader(SWFStream&, tag_type, movie_definition&,
- const RunInfo&);
-
void place_object_2_loader(SWFStream&, tag_type, movie_definition&,
const RunInfo&);
=== removed file 'libcore/text.cpp'
--- a/libcore/text.cpp 2008-10-19 19:36:12 +0000
+++ b/libcore/text.cpp 1970-01-01 00:00:00 +0000
@@ -1,234 +0,0 @@
-// text.cpp: Implementation of ActionScript text tags, for Gnash.
-//
-// Copyright (C) 2006, 2007, 2008 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 Thatcher Ulrich <address@hidden> 2003
-#ifdef HAVE_CONFIG_H
-#include "gnashconfig.h" // HAVE_ZLIB_H, USE_SWFTREE
-#endif
-
-#ifdef HAVE_PTHREADS
-#include <pthread.h>
-#endif
-
-#include "utf8.h"
-#include "utility.h"
-#include "impl.h"
-#include "shape_character_def.h"
-#include "SWFStream.h"
-#include "log.h"
-#include "font.h"
-#include "fontlib.h"
-#include "render.h"
-#include "text.h"
-#include "movie_definition.h"
-
-// Define the following macro to get debugging messages
-// for text rendering
-//#define GNASH_DEBUG_TEXT_RENDERING 1
-
-// Define the following macro to have invalid glyphs drawn as
-// empty boxes
-//#define DRAW_INVALID_GLYPHS_AS_EMPTY_BOXES 1
-
-
-namespace gnash {
-
- bool text_style::setFont(int id, movie_definition& root_def)
- {
- return resolve_font(id, root_def);
- }
-
- bool text_style::resolve_font(int id, const movie_definition& root_def)
- {
- assert(id >= 0);
-
- _font = root_def.get_font(id);
- if (_font == NULL)
- {
- IF_VERBOSE_MALFORMED_SWF(
- log_error(_("text style references unknown font (id = %d)"),
id);
- );
- return false;
- }
-
- return true;
- }
-
- void text_glyph_record::read(SWFStream& in, int glyph_count,
- int glyph_bits, int advance_bits)
- {
- // TODO: shouldn't we take unsigned for *_bits ?
- m_glyphs.resize(glyph_count);
- in.ensureBits(glyph_count * (glyph_bits+advance_bits));
- for (int i = 0; i < glyph_count; i++)
- {
- m_glyphs[i].m_glyph_index = in.read_uint(glyph_bits);
- m_glyphs[i].m_glyph_advance = (float)
in.read_sint(advance_bits);
- }
- }
-
- // Render the given glyph records.
- void display_glyph_records(
- const SWFMatrix& this_mat,
- character* inst,
- const std::vector<text_glyph_record>& records,
- bool useEmbeddedGlyphs)
- {
- //GNASH_REPORT_FUNCTION;
-
- static std::vector<fill_style> s_dummy_style; // used to pass
a color on to shape_character::display()
- static std::vector<line_style> s_dummy_line_style;
- s_dummy_style.resize(1);
-
- SWFMatrix mat = inst->getWorldMatrix();
- mat.concatenate(this_mat);
-
- cxform cx = inst->get_world_cxform();
- SWFMatrix base_matrix = mat;
-
- float x = 0.0f;
- float y = 0.0f;
-
- for (unsigned int i = 0; i < records.size(); i++)
- {
- // Draw the characters within the current record; i.e.
consecutive
- // chars that share a particular style.
- const text_glyph_record& rec = records[i];
-
- const font* fnt = rec.m_style.getFont();
- if (fnt == NULL)
- {
-#ifdef GNASH_DEBUG_TEXT_RENDERING
- log_debug("No font in style of record %u", i);
-#endif
- continue;
- }
-
- // unitsPerEM returns an int, we cast to float to get
- // a float division
- float unitsPerEM = fnt->unitsPerEM(useEmbeddedGlyphs);
- float scale = rec.m_style.m_text_height / unitsPerEM;
-
-#ifdef GNASH_DEBUG_TEXT_RENDERING
- log_debug("font for record %u == %p", i, (const
void*)fnt);
-#endif
-
- if ( rec.m_style.hasXOffset() ) x =
rec.m_style.getXOffset();
- if ( rec.m_style.hasYOffset() ) y =
rec.m_style.getYOffset();
-
- boost::int16_t startX = x; // for the underline, if any
-
- s_dummy_style[0].set_color(rec.m_style.m_color);
-
- rgba transformed_color =
cx.transform(rec.m_style.m_color);
-
- unsigned int nglyphs = rec.m_glyphs.size();
- for (unsigned int j = 0; j < nglyphs; ++j)
- {
- // the glyph entry
- const text_glyph_record::glyph_entry& ge =
rec.m_glyphs[j];
-
- int index = ge.m_glyph_index;
-
- mat = base_matrix;
- mat.concatenate_translation(x, y);
- mat.concatenate_scale(scale, scale);
-
- if (index == -1)
- {
-#ifdef GNASH_DEBUG_TEXT_RENDERING
-log_error(_("invalid glyph (-1)"));
-#endif
-
-#ifdef DRAW_INVALID_GLYPHS_AS_EMPTY_BOXES
- // The EM square is 1024x1024, but
usually isn't filled up.
- // We'll use about half the width, and
around 3/4 the height.
- // Values adjusted by eye.
- // The Y baseline is at 0; negative Y
is up.
- //
- // TODO: FIXME (if we'll ever enable it
back): the EM
- // square is not hard-coded
anymore but can be
- // queried from the font class
- //
- static const boost::int16_t
s_empty_char_box[5 * 2] =
- {
- 32, 32,
- 480, 32,
- 480, -656,
- 32, -656,
- 32, 32
- };
-
render::draw_line_strip(s_empty_char_box, 5, transformed_color, mat);
-#endif
-
- }
- else
- {
- shape_character_def* glyph =
fnt->get_glyph(index, useEmbeddedGlyphs);
-
- // Draw the character using the filled
outline.
- if (glyph)
- {
-#ifdef GNASH_DEBUG_TEXT_RENDERING
-log_debug(_("render shape glyph using filled outline (render::draw_glyph)"));
-#endif
-
-
gnash::render::draw_glyph(glyph, mat, transformed_color);
- }
- }
- x += ge.m_glyph_advance;
- }
-
- bool underline = rec.m_style.isUnderlined();
- if ( nglyphs && underline )
- {
- // Underline should end where last displayed
glyphs
- // does. 'x' here is where next glyph would be
displayed
- // which is normally after some space.
- // For more precise metrics we should substract
the advance
- // of last glyph and add the actual size of it.
- // This will only be known if a glyph was
actually found,
- // or would be the size of the empty box
(arbitrary size)
- //
- boost::int16_t endX = (int)x; // -
rec.m_glyphs.back().m_glyph_advance + (480.0*scale);
-
- // The underline is made to be some pixels
below the baseline (0)
- // and scaled so it's further as font size
increases.
- //
- // 1/4 the EM square offset far from baseline
- boost::int16_t posY =
int(y+int((unitsPerEM/4)*scale));
-
- boost::int16_t underline[2 * 2] =
- {
- startX, posY,
- endX, posY,
- };
- render::draw_line_strip(underline, 2,
transformed_color, base_matrix);
- }
- }
- }
-
-} // end namespace gnash
-
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:
=== removed file 'libcore/text.h'
--- a/libcore/text.h 2008-10-30 13:15:12 +0000
+++ b/libcore/text.h 1970-01-01 00:00:00 +0000
@@ -1,229 +0,0 @@
-//
-// Copyright (C) 2005, 2006, 2007, 2008 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
-
-// Code for the text tags.
-
-
-#ifndef GNASH_TEXT_H
-#define GNASH_TEXT_H
-
-#include "styles.h"
-#include "font.h"
-
-namespace gnash {
-
- // Forward declarations
- class text_character_def;
- class text_glyph_record;
- class text_style;
- class SWFStream;
-
- // Helper class.
- // @@ text_character_def friend ?
- class text_style
- {
- public:
- rgba m_color;
- float m_text_height;
-
- text_style()
- :
- m_text_height(1.0f),
- _hasXOffset(false),
- _hasYOffset(false),
- _underlined(false),
- _xOffset(0.0f),
- _yOffset(0.0f),
- _font(NULL)
- {
- }
-
- /// Should text be underlined ?
- bool isUnderlined() const
- {
- return _underlined;
- }
-
- /// Specify whether text should be underlined or not
- void setUnderlined(bool v) { _underlined=v; }
-
- /// Set an X offset
- void setXOffset(float o)
- {
- _hasXOffset=true;
- _xOffset=o;
- }
-
- /// Drop X offset
- void dropXOffset()
- {
- _hasXOffset=false;
- _xOffset=0; // we shouldn't need this..
- }
-
- /// Shift X offset by given amount
- void shiftXOffset(float xo)
- {
- //assert(_hasXOffset)
- _xOffset+=xo;
- }
-
- /// Return true if text has an X offset
- //
- // TODO: is this really needed ?
- //
- bool hasXOffset() const
- {
- return _hasXOffset;
- }
-
- /// Return the X offset
- float getXOffset() const
- {
- return _xOffset;
- }
-
- /// Set an Y offset
- void setYOffset(float o)
- {
- _hasYOffset = true;
- _yOffset=o;
- }
-
- /// Drop X offset
- void dropYOffset()
- {
- _hasYOffset = false;
- _yOffset=0; // we shouldn't need this..
- }
-
- /// Shift Y offset by given amount
- void shiftYOffset(float yo)
- {
- //assert(_hasYOffset)
- _yOffset+=yo;
- }
-
- /// Return true if text has an Y offset
- bool hasYOffset() const
- {
- return _hasYOffset;
- }
-
- /// Return the Y offset
- float getYOffset() const
- {
- return _yOffset;
- }
-
- /// Set font by id and movie_definition
- //
- /// This method will perform a lookup from the movie_definition
- /// and appropriately set the _font member.
- ///
- /// @param id
- /// The font id.
- ///
- /// @param root_def
- /// The movie_definition used for looking up font by id
- ///
- /// @return true on success, false on error (unknown font id)
- ///
- bool setFont(int id, movie_definition& def);
-
- /// Set font by font pointer.
- //
- /// @param fnt
- /// The font pointer.
- /// Must not be NULL or an assertion will fail.
- ///
- void setFont(const font* fnt)
- {
- assert(fnt);
- _font = fnt;
- }
-
- /// Return the associated font (possibly NULL).
- //
- /// @return
- /// The font associated with this style.
- /// NOTE: it may be NULL if a font set by
id/movie_definition
- /// could not be resolved.
- ///
- const font* getFont() const
- {
- return _font;
- }
-
- private:
-
- bool _hasXOffset;
- bool _hasYOffset;
- bool _underlined;
-
- float _xOffset;
- float _yOffset;
-
- const font* _font;
-
- /// Set font based on id
- //
- /// @param root_def
- /// The movie_definition used for looking up font by id
- ///
- /// @return true on success, false on error
- /// (unknown font id, would print an swferror about it)
- ///
- bool resolve_font(int id, const movie_definition& root_def);
- };
-
-
- /// A vector of glyphs sharing the same text_style
- //
- /// For each glyph, this class stores index and advance values
- ///
- class text_glyph_record
- {
- public:
- struct glyph_entry
- {
- int m_glyph_index;
- float m_glyph_advance;
- };
- text_style m_style;
- std::vector<glyph_entry> m_glyphs;
-
- void read(SWFStream& in, int glyph_count,
- int glyph_bits, int advance_bits);
-
- };
-
- /// Render the given glyph records.
- //
- /// @param useEmbeddedGlyphs
- /// If true, the font will be queried for embedded glyphs.
- /// Otherwise, the font will be queried for device fonts.
- ///
- void display_glyph_records(
- const SWFMatrix& this_mat,
- character* inst,
- const std::vector<text_glyph_record>& records,
- bool useEmbeddedGlyphs);
-
-} // namespace gnash
-
-#endif // GNASH_TEXT_H
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r10244: Move DefineText parsing from all over the place to libcore/swf and use,
Benjamin Wolsey <=