SWF_Text.cpp 9.6 KB

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