DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

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 }