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