1 //
2 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 //   Free Software Foundation, Inc
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 
19 #ifndef GNASH_SWF_TEXTRECORD_H
20 #define GNASH_SWF_TEXTRECORD_H
21 
22 #include <string>
23 #include <vector>
24 #include <boost/intrusive_ptr.hpp>
25 
26 #include "RGBA.h"
27 #include "SWF.h"
28 #include "Font.h"
29 
30 namespace gnash {
31     class movie_definition;
32     class SWFStream;
33     class Font;
34     class Renderer;
35     class Transform;
36 }
37 
38 namespace gnash {
39 namespace SWF {
40 
41 /// Store a TextRecord.
42 //
43 /// This consists of style information and a number of glyphs.
44 /// This may be parsed from a SWFStream, or it can be constructed
45 /// dynamically by TextField. A static TextField has fewer possible
46 /// properties than a dynamic one.
47 class TextRecord
48 {
49 public:
50 
51     typedef std::vector<TextRecord> TextRecords;
52 
53     struct GlyphEntry
54     {
55         int index;
56         float advance;
57     };
58 
TextRecord()59     TextRecord()
60         :
61         _color(0, 0, 0, 0),
62         _textHeight(0),
63         _hasXOffset(false),
64         _hasYOffset(false),
65         _xOffset(0.0f),
66         _yOffset(0.0f),
67         _font(nullptr),
68         _underline(false)
69     {}
70 
71     typedef std::vector<GlyphEntry> Glyphs;
72 
73     /// Accumulate the number of glyphs in a TextRecord.
74     struct RecordCounter
75     {
operatorRecordCounter76         size_t operator()(size_t c, const TextRecord& t) {
77             const Glyphs& glyphs = t.glyphs();
78             size_t ret = c + glyphs.size();
79             return ret;
80         }
81     };
82 
83     /// Read a TextRecord from the stream
84     //
85     /// @param in           The SWFStream to read from.
86     /// @param m            The movie_definition containing this TextRecord.
87     /// @param glyphBits    The number of bits per glyph
88     /// @param advanceBits  The number of bits per advance
89     /// @param tag          The tag type of this TextRecord. This must be
90     ///                     DefineText or DefineText2
91     /// @return             False if we have reached the end of the
92     ///                     TextRecords, true if there are more to parse.
93     bool read(SWFStream& in, movie_definition& m, int glyphBits,
94             int advanceBits, TagType tag);
95 
96     static void displayRecords(Renderer& renderer, const Transform& xform,
97             const TextRecords& records, bool embedded = true);
98 
glyphs()99     const Glyphs& glyphs() const {
100         return _glyphs;
101     }
102 
103     void addGlyph(const GlyphEntry& ge, Glyphs::size_type num = 1) {
104         _glyphs.insert(_glyphs.end(), num, ge);
105     }
106 
107     void clearGlyphs(Glyphs::size_type num = 0) {
108         if (!num) _glyphs.clear();
109         else _glyphs.resize(_glyphs.size() - num);
110     }
111 
112     // TODO: check font properly.
setFont(boost::intrusive_ptr<const Font> f)113     void setFont(boost::intrusive_ptr<const Font> f) {
114         _font = f;
115     }
116 
setURL(std::string url)117 	void setURL(std::string url) {
118 		_htmlURL = url;
119 	}
120 
getURL()121 	const std::string& getURL() const {
122 		return _htmlURL;
123 	}
124 
setTarget(std::string target)125 	void setTarget(std::string target) {
126 		_htmlTarget = target;
127 	}
128 
getTarget()129 	const std::string& getTarget() const {
130 		return _htmlTarget;
131 	}
132 
getFont()133     const Font* getFont() const {
134         return _font.get();
135     }
136 
setTextHeight(std::uint16_t height)137     void setTextHeight(std::uint16_t height) {
138         _textHeight = height;
139     }
140 
recordWidth()141 	float recordWidth() const {
142 		float width = 0.0f;
143 		for (const auto& glyph : glyphs())
144 		{
145 			width += glyph.advance;
146 		}
147         return width;
148 	}
149 
textHeight()150     std::uint16_t textHeight() const {
151         return _textHeight;
152     }
153 
hasXOffset()154     bool hasXOffset() const {
155         return _hasXOffset;
156     }
157 
setXOffset(float x)158     void setXOffset(float x) {
159         _hasXOffset = true;
160         _xOffset = x;
161     }
162 
xOffset()163     float xOffset() const {
164         return _xOffset;
165     }
166 
hasYOffset()167     bool hasYOffset() const {
168         return _hasYOffset;
169     }
170 
setYOffset(float y)171     void setYOffset(float y) {
172         _hasYOffset = true;
173         _yOffset = y;
174     }
175 
yOffset()176     float yOffset() const {
177         return _yOffset;
178     }
179 
setColor(const rgba & color)180     void setColor(const rgba& color) {
181         _color = color;
182     }
183 
color()184     const rgba& color() const {
185         return _color;
186     }
187 
underline()188     bool underline() const {
189         return _underline;
190     }
191 
setUnderline(bool b)192     void setUnderline(bool b) {
193         _underline = b;
194     }
195 
196 private:
197 
198     Glyphs _glyphs;
199 
200     /// The text color.
201     rgba _color;
202 
203     /// The height of the text in TWIPS.
204     std::uint16_t _textHeight;
205 
206     /// Whether the TextRecord has an x offset.
207     bool _hasXOffset;
208 
209     /// Whether the TextRecord has a y offset.
210     bool _hasYOffset;
211 
212     /// The x offset of the text, by default 0.0
213     float _xOffset;
214 
215     /// The y offset of the text, by default 0.0
216     float _yOffset;
217 
218     /// The font associated with the TextRecord. Can be NULL.
219     boost::intrusive_ptr<const Font> _font;
220 
221 	std::string _htmlURL;
222 	std::string _htmlTarget;
223     /// Whether the text should be underlined.
224     bool _underline;
225 };
226 
227 } // namespace SWF
228 } // namespace gnash
229 
230 
231 #endif
232