SWF_Text.cpp (9794B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. 23 24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. 25 26 =========================================================================== 27 */ 28 #pragma hdrstop 29 #include "../idlib/precompiled.h" 30 31 #pragma warning( disable: 4189 ) // local variable is initialized but not referenced 32 33 /* 34 ======================== 35 idSWF::DefineFont2 36 ======================== 37 */ 38 void idSWF::DefineFont2( idSWFBitStream & bitstream ) { 39 uint16 characterID = bitstream.ReadU16(); 40 idSWFDictionaryEntry * entry = AddDictionaryEntry( characterID, SWF_DICT_FONT ); 41 if ( entry == NULL ) { 42 return; 43 } 44 uint8 flags = bitstream.ReadU8(); 45 uint8 language = bitstream.ReadU8(); 46 47 char fontName[257]; 48 uint8 fontNameLength = bitstream.ReadU8(); 49 memcpy( fontName, bitstream.ReadData( fontNameLength ), fontNameLength ); 50 fontName[ fontNameLength ] = 0; 51 52 entry->font->fontID = renderSystem->RegisterFont( fontName ); 53 54 uint16 numGlyphs = bitstream.ReadU16(); 55 entry->font->glyphs.SetNum( numGlyphs ); 56 57 if ( flags & BIT( 3 ) ) { 58 // 32 bit offsets 59 uint32 offsetTableSize = ( numGlyphs + 1 ) * 4; 60 idSWFBitStream offsetStream( bitstream.ReadData( offsetTableSize ), offsetTableSize, false ); 61 if ( offsetStream.ReadU32() != offsetTableSize ) { 62 idLib::Warning( "idSWF::DefineFont2: first glyph offset != offsetTableSize" ); 63 return; 64 } 65 uint32 previousOffset = offsetTableSize; 66 for ( int i = 0; i < numGlyphs; i++ ) { 67 uint32 nextOffset = offsetStream.ReadU32(); 68 uint32 shapeSize = nextOffset - previousOffset; 69 previousOffset = nextOffset; 70 idSWFBitStream shapeStream( bitstream.ReadData( shapeSize ), shapeSize, false ); 71 idSWFShapeParser swfShapeParser; 72 swfShapeParser.ParseFont( shapeStream, entry->font->glyphs[i] ); 73 } 74 } else { 75 // 16 bit offsets 76 uint16 offsetTableSize = ( numGlyphs + 1 ) * 2; 77 idSWFBitStream offsetStream( bitstream.ReadData( offsetTableSize ), offsetTableSize, false ); 78 if ( offsetStream.ReadU16() != offsetTableSize ) { 79 idLib::Warning( "idSWF::DefineFont2: first glyph offset != offsetTableSize" ); 80 return; 81 } 82 uint16 previousOffset = offsetTableSize; 83 for ( int i = 0; i < numGlyphs; i++ ) { 84 uint16 nextOffset = offsetStream.ReadU16(); 85 uint16 shapeSize = nextOffset - previousOffset; 86 previousOffset = nextOffset; 87 idSWFBitStream shapeStream( bitstream.ReadData( shapeSize ), shapeSize, false ); 88 idSWFShapeParser swfShapeParser; 89 swfShapeParser.ParseFont( shapeStream, entry->font->glyphs[i] ); 90 } 91 } 92 if ( flags & BIT( 2 ) ) { 93 // 16 bit codes 94 for ( int i = 0; i < numGlyphs; i++ ) { 95 entry->font->glyphs[i].code = bitstream.ReadU16(); 96 } 97 } else { 98 // 8 bit codes 99 for ( int i = 0; i < numGlyphs; i++ ) { 100 entry->font->glyphs[i].code = bitstream.ReadU8(); 101 } 102 } 103 if ( flags & BIT( 7 ) ) { 104 entry->font->ascent = bitstream.ReadS16(); 105 entry->font->descent = bitstream.ReadS16(); 106 entry->font->leading = bitstream.ReadS16(); 107 for ( int i = 0; i < numGlyphs; i++ ) { 108 entry->font->glyphs[i].advance = bitstream.ReadS16(); 109 } 110 for ( int i = 0; i < numGlyphs; i++ ) { 111 swfRect_t ignored; 112 bitstream.ReadRect( ignored ); 113 } 114 uint16 kearningCount = bitstream.ReadU16(); 115 if ( flags & BIT( 2 ) ) { 116 for ( int i = 0; i < kearningCount; i++ ) { 117 uint16 code1 = bitstream.ReadU16(); 118 uint16 code2 = bitstream.ReadU16(); 119 int16 adjustment = bitstream.ReadS16(); 120 } 121 } else { 122 for ( int i = 0; i < kearningCount; i++ ) { 123 uint16 code1 = bitstream.ReadU8(); 124 uint16 code2 = bitstream.ReadU8(); 125 int16 adjustment = bitstream.ReadS16(); 126 } 127 } 128 } 129 } 130 131 /* 132 ======================== 133 idSWF::DefineFont3 134 ======================== 135 */ 136 void idSWF::DefineFont3( idSWFBitStream & bitstream ) { 137 DefineFont2( bitstream ); 138 } 139 140 /* 141 ======================== 142 idSWF::DefineTextX 143 ======================== 144 */ 145 void idSWF::DefineTextX( idSWFBitStream & bitstream, bool rgba ) { 146 uint16 characterID = bitstream.ReadU16(); 147 idSWFDictionaryEntry * entry = AddDictionaryEntry( characterID, SWF_DICT_TEXT ); 148 if ( entry == NULL ) { 149 return; 150 } 151 idSWFText * text = entry->text; 152 153 bitstream.ReadRect( text->bounds ); 154 bitstream.ReadMatrix( text->matrix ); 155 156 uint8 glyphBits = bitstream.ReadU8(); 157 uint8 advanceBits = bitstream.ReadU8(); 158 159 while ( true ) { 160 uint8 flags = bitstream.ReadU8(); 161 if ( flags == 0 ) { 162 break; 163 } 164 idSWFTextRecord & textRecord = text->textRecords.Alloc(); 165 166 if ( flags & BIT( 3 ) ) { 167 textRecord.fontID = bitstream.ReadU16(); 168 } 169 if ( flags & BIT( 2 ) ) { 170 if ( rgba ) { 171 bitstream.ReadColorRGBA( textRecord.color ); 172 } else { 173 bitstream.ReadColorRGB( textRecord.color ); 174 } 175 } 176 if ( flags & BIT( 0 ) ) { 177 textRecord.xOffset = bitstream.ReadS16(); 178 } 179 if ( flags & BIT( 1 ) ) { 180 textRecord.yOffset = bitstream.ReadS16(); 181 } 182 if ( flags & BIT( 3 ) ) { 183 textRecord.textHeight = bitstream.ReadU16(); 184 } 185 textRecord.firstGlyph = text->glyphs.Num(); 186 textRecord.numGlyphs = bitstream.ReadU8(); 187 for ( int i = 0; i < textRecord.numGlyphs; i++ ) { 188 swfGlyphEntry_t & glyph = text->glyphs.Alloc(); 189 glyph.index = bitstream.ReadU( glyphBits ); 190 glyph.advance = bitstream.ReadS( advanceBits ); 191 } 192 }; 193 } 194 195 /* 196 ======================== 197 idSWF::DefineText 198 ======================== 199 */ 200 void idSWF::DefineText( idSWFBitStream & bitstream ) { 201 DefineTextX( bitstream, false ); 202 } 203 204 /* 205 ======================== 206 idSWF::DefineText2 207 ======================== 208 */ 209 void idSWF::DefineText2( idSWFBitStream & bitstream ) { 210 DefineTextX( bitstream, true ); 211 } 212 213 /* 214 ======================== 215 idSWF::DefineEditText 216 ======================== 217 */ 218 void idSWF::DefineEditText( idSWFBitStream & bitstream ) { 219 uint16 characterID = bitstream.ReadU16(); 220 idSWFDictionaryEntry * entry = AddDictionaryEntry( characterID, SWF_DICT_EDITTEXT ); 221 if ( entry == NULL ) { 222 return; 223 } 224 idSWFEditText * edittext = entry->edittext; 225 bitstream.ReadRect( edittext->bounds ); 226 bitstream.ResetBits(); 227 bool hasText = bitstream.ReadBool(); 228 bool wordWrap = bitstream.ReadBool(); 229 bool multiline = bitstream.ReadBool(); 230 bool password = bitstream.ReadBool(); 231 bool readonly = bitstream.ReadBool(); 232 bool hasTextColor = bitstream.ReadBool(); 233 bool hasMaxLength = bitstream.ReadBool(); 234 bool hasFont = bitstream.ReadBool(); 235 bool hasFontClass = bitstream.ReadBool(); 236 bool autoSize = bitstream.ReadBool(); 237 bool hasLayout = bitstream.ReadBool(); 238 bool noSelect = bitstream.ReadBool(); 239 bool border = bitstream.ReadBool(); 240 bool wasStatic = bitstream.ReadBool(); 241 bool html = bitstream.ReadBool(); 242 bool useOutlines = bitstream.ReadBool(); 243 if ( hasFont ) { 244 edittext->fontID = bitstream.ReadU16(); 245 edittext->fontHeight = bitstream.ReadU16(); 246 } 247 if ( hasFontClass ) { 248 idStr fontClass = bitstream.ReadString(); 249 } 250 if ( hasTextColor ) { 251 bitstream.ReadColorRGBA( edittext->color ); 252 } 253 if ( hasMaxLength ) { 254 edittext->maxLength = bitstream.ReadU16(); 255 } 256 if ( hasLayout ) { 257 edittext->align = (swfEditTextAlign_t)bitstream.ReadU8(); 258 edittext->leftMargin = bitstream.ReadU16(); 259 edittext->rightMargin = bitstream.ReadU16(); 260 edittext->indent = bitstream.ReadU16(); 261 edittext->leading = bitstream.ReadS16(); 262 } 263 edittext->variable = bitstream.ReadString(); 264 if ( hasText ) { 265 const char * text = bitstream.ReadString(); 266 idStr initialText; 267 268 // convert html tags if necessary 269 for ( int i = 0; text[i] != 0; i++ ) { 270 if ( text[i] == '<' ) { 271 if ( i != 0 && text[i+1] == 'p' ) { 272 initialText.Append( '\n' ); 273 } 274 for ( ; text[i] != 0 && text[i] != '>'; i++ ) { 275 } 276 continue; 277 } 278 byte tc = (byte)text[i]; 279 if ( tc == '&' ) { 280 idStr special; 281 for ( i++; text[i] != 0 && text[i] != ';'; i++ ) { 282 special.Append( text[i] ); 283 } 284 if ( special.Icmp( "amp" ) == 0 ) { 285 tc = '&'; 286 } else if ( special.Icmp( "apos" ) == 0 ) { 287 tc = '\''; 288 } else if ( special.Icmp( "lt" ) == 0 ) { 289 tc = '<'; 290 } else if ( special.Icmp( "gt" ) == 0 ) { 291 tc = '>'; 292 } else if ( special.Icmp( "quot" ) == 0 ) { 293 tc = '\"'; 294 } 295 } 296 initialText.Append( tc ); 297 } 298 edittext->initialText = initialText; 299 } 300 edittext->flags |= wordWrap ? SWF_ET_WORDWRAP : 0; 301 edittext->flags |= multiline ? SWF_ET_MULTILINE : 0; 302 edittext->flags |= password ? SWF_ET_PASSWORD : 0; 303 edittext->flags |= readonly ? SWF_ET_READONLY : 0; 304 edittext->flags |= autoSize ? SWF_ET_AUTOSIZE : 0; 305 edittext->flags |= border ? SWF_ET_BORDER : 0; 306 }