xoreos  0.0.5
gfxfile.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include "src/common/filepath.h"
26 #include "src/common/deflate.h"
27 #include "src/common/ustring.h"
28 #include "src/common/readstream.h"
29 #include "src/common/encoding.h"
30 #include "src/common/util.h"
31 
32 #include "src/aurora/gfxfile.h"
33 #include "src/aurora/resman.h"
34 
35 namespace Aurora {
36 
37 static const uint32 kCFXID = MKTAG('C', 'F', 'X', 0x08);
38 
39 enum TagType {
68 
69  // Scaleform GFx specific tags
73 };
74 
76  GFXCharacter character(id, kSprite);
77 
78  character._value = sprite;
79 
80  return character;
81 }
82 
84  GFXCharacter character(id, kShape);
85 
86  character._value = shape;
87 
88  return character;
89 }
90 
92  GFXCharacter character(id, kFont);
93 
94  character._value = font;
95 
96  return character;
97 }
98 
100  GFXCharacter character(id, kEditText);
101 
102  character._value = editText;
103 
104  return character;
105 }
106 
108  GFXCharacter character(id, kExternalImage);
109 
110  character._value = externalImage;
111 
112  return character;
113 }
114 
115 GFXCharacter::GFXCharacter(uint16 id, CharacterType type) : _id(id), _type(type) {
116 }
117 
119  return _type;
120 }
121 
123  return _id;
124 }
125 
126 void GFXCharacter::getSprite(Sprite &sprite) const {
127  if (_type != kSprite)
128  throw Common::Exception("Character is not a sprite");
129 
130  sprite = boost::get<Sprite>(_value);
131 }
132 
133 void GFXCharacter::getShape(Shape &shape) const {
134  if (_type != kShape)
135  throw Common::Exception("Character is not a shape");
136 
137  shape = boost::get<Shape>(_value);
138 }
139 
140 void GFXCharacter::getFont(Font &font) const {
141  if (_type != kFont)
142  throw Common::Exception("Character is not a font");
143 
144  font = boost::get<Font>(_value);
145 }
146 
147 void GFXCharacter::getEditText(EditText &editText) const {
148  if (_type != kEditText)
149  throw Common::Exception("Character is not an edit text");
150 
151  editText = boost::get<EditText>(_value);
152 }
153 
154 void GFXCharacter::getExternalImage(ExternalImage &externalImage) const {
155  if (_type != kExternalImage)
156  throw Common::Exception("Character is not an external image");
157 
158  externalImage = boost::get<ExternalImage>(_value);
159 }
160 
162  GFXControl control(kPlaceObject);
163 
164  control._value = placeObject;
165 
166  return control;
167 }
168 
170  GFXControl control(kDoAction);
171 
172  control._value = doAction;
173 
174  return control;
175 }
176 
178  return GFXControl(kShowFrame);
179 }
180 
181 void GFXControl::getPlaceObject(PlaceObject &placeObject) const {
182  if (_type != kPlaceObject)
183  throw Common::Exception("Control is not a PlaceObject");
184 
185  placeObject = boost::get<PlaceObject>(_value);
186 }
187 
188 void GFXControl::getDoAction(DoAction &doAction) const {
189  if (_type != kDoAction)
190  throw Common::Exception("Control is not a DoAction");
191 
192  doAction = boost::get<DoAction>(_value);
193 }
194 
195 GFXControl::GFXControl(ControlType type) : _type(type) {
196 }
197 
199  Common::SeekableReadStream *gfx = ResMan.getResource(resref, kFileTypeGFX);
200  if (!gfx)
201  throw Common::Exception("Error creating gfx stream");
202 
203  load(gfx, avm);
204 }
205 
207  std::map<Common::UString, uint16>::iterator iter = _exportTable.find(id);
208  if (iter == _exportTable.end())
209  throw Common::Exception("Export entry %s not found", id.c_str());
210 
211  return iter->second;
212 }
213 
215  std::map<uint16, GFXCharacter>::iterator iter = _characters.find(id);
216  if (iter == _characters.end())
217  throw Common::Exception("Character entry %i not found", id);
218 
219  return iter->second;
220 }
221 
223  /* Read the magic id, which corresponds to CFX, where the C marks a zlib compression, and an appended 0x08,
224  * which corresponds to the SWF version 8.
225  */
226  const uint32 magicId = gfx->readUint32BE();
227  if (magicId != kCFXID)
228  throw Common::Exception("Invalid gfx magic id");
229 
230  /* The next uint32 should determine the total size of the compressed data, but since this value is not reliable
231  * we skip it and decompress the file without knowing the output size.
232  */
233  gfx->skip(4);
234 
235  // Decompress the gfx file except for the first 8 bytes with zlib.
236  Common::SeekableSubReadStream gfxSub(gfx, 8, gfx->size());
238 
239  // Read the compressed part of the header.
240  readHeader();
241 
242  // Read all following tags.
243  RecordHeader header;
244  do {
245  header = readRecordHeader();
246  size_t oldSize = _gfx->pos();
247 
248  switch (header.tagType) {
249  case kTagTypeEnd:
250  break;
251 
252  case kTagTypeShowFrame:
254  break;
255  case kTagTypeDefineShape:
256  readDefineShape(0);
257  break;
260  break;
261  case kTagTypeDoAction: {
262  GFXControl::DoAction doAction;
263  doAction.asBuffer = readAction();
264  _controlTags.push_back(GFXControl::createDoAction(doAction));
265  break;
266  }
268  readDefineShape(1);
269  break;
271  _controlTags.push_back(readPlaceObject());
272  break;
274  readDefineShape(2);
275  break;
278  break;
281  break;
282  case kTagTypeFrameLabel:
283  readNullTerminatedString(); // TODO
284  break;
287  break;
289  readInitAction(avm);
290  break;
293  break;
295  readImportAssets(avm);
296  break;
297  case kTagTypeDefineFont3:
298  readDefineFont();
299  break;
300 
302  readGFXExporterInfo(header);
303  break;
306  break;
308  readGFXDefineExternalImage(header, 1);
309  break;
310 
311  default:
312  warning("Unknown Tag type %i", header.tagType);
313  _gfx->skip(header.tagLength);
314  break;
315  }
316 
317  if (_gfx->pos() - oldSize != header.tagLength)
318  throw Common::Exception("Invalid read of tag");
319  } while (header.tagType != kTagTypeEnd);
320 }
321 
324 
325  const byte denominator = _gfx->readByte();
326  const byte numerator = _gfx->readByte();
327  _frameRate = numerator + (denominator ? (1/denominator) : 0);
328  _frameCount = _gfx->readUint16LE();
329 }
330 
332  const uint16 shapeId = _gfx->readUint16LE();
333  GFXCharacter::Shape shape;
334 
335  shape.bounds = readRectangle();
336  shape.shapeRecords = readShape(version, true);
337 
338  _characters.insert(std::make_pair(shapeId, GFXCharacter::createShape(shapeId, shape)));
339 }
340 
342  readRGB();
343 }
344 
346  const uint16 count = _gfx->readUint16LE();
347  for (unsigned int i = 0; i < count; ++i) {
348  uint16 id = _gfx->readUint16LE();
350 
351  _exportTable[name] = id;
352  }
353 }
354 
357  GFXFile import(url, avm);
358 
359  byte reserved = _gfx->readByte();
360  assert(reserved == 1);
361  reserved = _gfx->readByte();
362  assert(reserved == 0);
363 
364  const uint16 count = _gfx->readUint16LE();
365  for (unsigned int i = 0; i < count; ++i) {
366  uint16 tag = _gfx->readUint16LE();
368 
369  uint16 exportId = import.getExportedAssetId(name);
370 
371  _characters.insert(std::make_pair(tag, import.getCharacter(exportId)));
372  }
373 }
374 
376  Common::BitStream8MSB bitStream(_gfx.get());
377 
378  bitStream.skip(1); // Reserved bit
379  const bool useDirectBlit = bitStream.getBit() == 1;
380  const bool useGPU = bitStream.getBit() == 1;
381  const bool hasMetadata = bitStream.getBit() == 1;
382  const bool actionScript3 = bitStream.getBit() == 1;
383  bitStream.skip(2); // Reserved bits
384  const bool useNetwork = bitStream.getBit() == 1;
385 
386  const uint32 zeros = bitStream.getBits(24);
387  assert(zeros == 0);
388 
389  if (useDirectBlit)
390  warning("Direct Blit is not supported");
391  if (useGPU)
392  warning("useGPU flag is ignored");
393  if (hasMetadata)
394  warning("Metadata loading is not supported");
395  if (actionScript3)
396  warning("ActionScript3 is not supported");
397  if (useNetwork)
398  warning("Network usage is not supported");
399 }
400 
402  uint16 spriteId = _gfx->readUint16LE();
403 
404  GFXCharacter::Sprite sprite;
405  sprite.frameCount = _gfx->readUint16LE();
406 
407  std::vector<GFXControl> control;
408 
409  RecordHeader header;
410  do {
411  header = readRecordHeader();
412  const size_t oldSize = _gfx->pos();
413 
414  switch (header.tagType) {
415  case kTagTypeShowFrame:
416  control.push_back(GFXControl::createShowFrame());
417  break;
419  control.push_back(readPlaceObject());
420  break;
421  case kTagTypeDoAction: {
422  GFXControl::DoAction doAction;
423  doAction.asBuffer = readAction();
424  control.push_back(GFXControl::createDoAction(doAction));
425  break;
426  }
428  control.push_back(readPlaceObject(2));
429  break;
430  case kTagTypePlaceObject:
434  case kTagTypeFrameLabel:
435  case kTagTypeStartSound:
439  warning("Unknown allowed Tag type %i", header.tagType);
440  _gfx->skip(header.tagLength);
441  break;
442  case kTagTypeEnd:
443  break;
444  default:
445  throw Common::Exception("Forbidden Tag type %i in sprite", header.tagType);
446  }
447 
448  if (_gfx->pos() - oldSize != header.tagLength)
449  throw Common::Exception("Invalid read of tag");
450  } while (header.tagType != kTagTypeEnd);
451 
452  sprite.controls = control;
453 
454  _characters.insert(std::make_pair(spriteId, GFXCharacter::createSprite(spriteId, sprite)));
455 }
456 
458  Common::BitStream8MSB bitStream(_gfx.get());
459 
460  const bool placeFlagHasClipActions = bitStream.getBit() == 1;
461  const bool placeFlagHasClipDepth = bitStream.getBit() == 1;
462  const bool placeFlagHasName = bitStream.getBit() == 1;
463  const bool placeFlagHasRatio = bitStream.getBit() == 1;
464  const bool placeFlagHasColorTransform = bitStream.getBit() == 1;
465  const bool placeFlagHasMatrix = bitStream.getBit() == 1;
466  const bool placeFlagHasCharacter = bitStream.getBit() == 1;
467  const bool placeFlagMove = bitStream.getBit() == 1;
468 
469  bool placeFlagOpaqueBackground = false;
470  bool placeFlagHasVisible = false;
471  bool placeFlagHasImage = false;
472  bool placeFlagHasClassName = false;
473  bool placeFlagHasCacheAsBitmap = false;
474  bool placeFlagHasBlendMode = false;
475  bool placeFlagHasFilter = false;
476  if (version == 2) {
477  bitStream.skip(1); // Reserved
478  placeFlagOpaqueBackground = bitStream.getBit() == 1;
479  placeFlagHasVisible = bitStream.getBit() == 1;
480  placeFlagHasImage = bitStream.getBit() == 1;
481  placeFlagHasClassName = bitStream.getBit() == 1;
482  placeFlagHasCacheAsBitmap = bitStream.getBit() == 1;
483  placeFlagHasBlendMode = bitStream.getBit() == 1;
484  placeFlagHasFilter = bitStream.getBit() == 1;
485  }
486 
487  if (placeFlagOpaqueBackground)
488  throw Common::Exception("GFXFile::readPlaceObject() Opaque background not supported");
489  if (placeFlagHasVisible)
490  throw Common::Exception("GFXFile::readPlaceObject() Visible flag not supported");
491 
492  GFXControl::PlaceObject placeObject;
493 
494  placeObject.hasMove = placeFlagMove;
495  placeObject.depth = _gfx->readUint16LE();
496 
497  if (placeFlagHasClassName || (placeFlagHasImage && placeFlagHasCharacter))
498  readNullTerminatedString(); // TODO
499  if (placeFlagHasCharacter)
500  placeObject.characterId = _gfx->readUint16LE();
501  if (placeFlagHasMatrix)
502  placeObject.matrix = readMatrix();
503  if (placeFlagHasColorTransform)
504  placeObject.colorTransform = readColorTransform();
505  if (placeFlagHasRatio)
506  _gfx->skip(2); // TODO
507  if (placeFlagHasName)
508  placeObject.name = readNullTerminatedString();
509  if (placeFlagHasClipDepth)
510  _gfx->skip(2); // TODO
511  if (placeFlagHasFilter)
512  throw Common::Exception("TODO: Implement Filter List");
513  if (placeFlagHasBlendMode)
514  placeObject.blendMode = _gfx->readByte();
515  if (placeFlagHasCacheAsBitmap)
516  _gfx->skip(1); // TODO
517  if (placeFlagHasClipActions)
518  throw Common::Exception("TODO: Implement ClipActions");
519 
520  return GFXControl::createPlaceObject(placeObject);
521 }
522 
524  const uint16 fontId = _gfx->readUint16LE();
525  GFXCharacter::Font font;
526 
527  Common::BitStream8MSB bitStream(_gfx.get());
528 
529  const bool fontFlagHasLayout = bitStream.getBit() == 1;
530  const bool fontFlagShiftJIS = bitStream.getBit() == 1;
531  const bool fontFlagHasSmallText = bitStream.getBit() == 1;
532  const bool fontFlagANSI = bitStream.getBit() == 1;
533  const bool fontFlagWideOffsets = bitStream.getBit() == 1;
534  const bool fontFlagWideCodes = bitStream.getBit() == 1;
535  const bool fontFlagItalic = bitStream.getBit() == 1;
536  const bool fontFlagBold = bitStream.getBit() == 1;
537 
538  if (fontFlagShiftJIS)
539  warning("GFXFile::readDefineFont() ShiftJIS Encoding not supported");
540  if (fontFlagHasSmallText)
541  warning("GFXFile::readDefineFont() Small Text not supported");
542  if (fontFlagANSI)
543  warning("GFXFile::readDefineFont() ANSI Encoding not supported");
544 
545  if (fontFlagItalic)
546  warning("GFXFile::readDefineFont() Italic fonts are not supported");
547  if (fontFlagBold)
548  warning("GFXFile::readDefineFont() Bold Fonts are not supported");
549 
550  const byte languageCode = _gfx->readByte();
551  if (languageCode < 1 || languageCode > 5)
552  warning("GFXFile::readDefineFont() Invalid language code");
553 
555 
556  const uint16 numGlyphs = _gfx->readUint16LE();
557 
558  const size_t startOffsetTable = _gfx->pos();
559 
560  std::vector<uint32> offsetTable;
561  for (unsigned int i = 0; i < numGlyphs; ++i) {
562  if (fontFlagWideOffsets) {
563  offsetTable.push_back(_gfx->readUint32LE());
564  } else {
565  offsetTable.push_back(_gfx->readUint16LE());
566  }
567  }
568 
569  uint32 codeTableOffset;
570  if (fontFlagWideOffsets)
571  codeTableOffset = _gfx->readUint32LE();
572  else
573  codeTableOffset = _gfx->readUint16LE();
574 
575  std::vector<std::vector<GFXCharacter::ShapeRecord> > glyphRecords;
576  for (unsigned int i = 0; i < numGlyphs; ++i) {
577  std::vector<GFXCharacter::ShapeRecord> records = readShape(0, false);
578  glyphRecords.push_back(records);
579  }
580 
581  assert(codeTableOffset == _gfx->pos() - startOffsetTable);
582 
583  std::vector<uint16> codeTable;
584  for (unsigned int i = 0; i < numGlyphs; ++i) {
585  codeTable.push_back(_gfx->readUint16LE());
586  }
587 
588  std::vector<Common::Rect> bounds;
589  std::vector<int16> advance;
590  std::vector<GFXCharacter::KerningCode> kerningCodes;
591  if (fontFlagHasLayout) {
592  font.fontAscent = _gfx->readUint16LE();
593  font.fontDescent = _gfx->readUint16LE();
594  font.fontLeading = _gfx->readSint16LE();
595 
596  for (unsigned int i = 0; i < numGlyphs; ++i) {
597  advance.push_back(_gfx->readSint16LE());
598  }
599 
600  for (unsigned int i = 0; i < numGlyphs; ++i) {
601  bounds.push_back(readRectangle());
602  }
603 
604  const uint16 kerningCount = _gfx->readUint16LE();
605  kerningCodes.resize(kerningCount);
606  for (unsigned int i = 0; i < kerningCount; ++i) {
607  if (fontFlagWideCodes) {
608  kerningCodes[i].code1 = _gfx->readUint16LE();
609  kerningCodes[i].code2 = _gfx->readUint16LE();
610  } else {
611  kerningCodes[i].code1 = _gfx->readByte();
612  kerningCodes[i].code2 = _gfx->readByte();
613  }
614 
615  kerningCodes[i].adjustment = _gfx->readSint16LE();
616  }
617  }
618 
619  font.kerningCodes = kerningCodes;
620 
621  std::vector<GFXCharacter::Glyph> glyphs;
622 
623  for (unsigned int i = 0; i < numGlyphs; ++i) {
624  GFXCharacter::Glyph glyph;
625 
626  glyph.code = codeTable[i];
627  glyph.shapeRecords = glyphRecords[i];
628 
629  if (!bounds.empty())
630  glyph.bounds = bounds[i];
631 
632  glyphs.push_back(glyph);
633  }
634 
635  font.glyphs = glyphs;
636 
637  _characters.insert(std::make_pair(fontId, GFXCharacter::createFont(fontId, GFXCharacter::Font())));
638 }
639 
641  const uint16 characterId = _gfx->readUint16LE();
642  GFXCharacter::EditText editText;
643 
644  editText.bounds = readRectangle();
645 
646  Common::BitStream8MSB bitStream(_gfx.get());
647 
648  const bool hasText = bitStream.getBit() == 1;
649  const bool wordWrap = bitStream.getBit() == 1;
650  const bool multiLine = bitStream.getBit() == 1;
651  const bool password = bitStream.getBit() == 1;
652  const bool readOnly = bitStream.getBit() == 1;
653  const bool hasTextColor = bitStream.getBit() == 1;
654  const bool hasMaxLength = bitStream.getBit() == 1;
655  const bool hasFont = bitStream.getBit() == 1;
656  const bool hasFontClass = bitStream.getBit() == 1;
657  const bool autoSize = bitStream.getBit() == 1;
658  const bool hasLayout = bitStream.getBit() == 1;
659  const bool noSelect = bitStream.getBit() == 1;
660  const bool border = bitStream.getBit() == 1;
661  const bool wasStatic = bitStream.getBit() == 1;
662  const bool html = bitStream.getBit() == 1;
663  const bool useOutlines = bitStream.getBit() == 1;
664 
665  if (wasStatic)
666  warning("GFXFile::readDefineEditText() static text is not supported");
667 
668  if (border)
669  warning("GFXFile::readDefineEditText() border drawing is not supported");
670 
671  if (!useOutlines)
672  warning("GFXFile::readDefineEditText() device fonts are nto supported");
673 
674  editText.wordWrap = wordWrap;
675  editText.multiLine = multiLine;
676  editText.password = password;
677  editText.readOnly = readOnly;
678  editText.autosize = autoSize;
679  editText.noSelect = noSelect;
680  editText.html = html;
681 
682  if (hasFont)
683  editText.fontId = _gfx->readUint16LE();
684 
685  Common::UString fontClass;
686  if (hasFontClass)
687  fontClass = readNullTerminatedString();
688 
689  if (hasFont)
690  editText.fontHeight = _gfx->readUint16LE();
691 
692  if (hasTextColor)
693  editText.textColor = readRGBA();
694 
695  if (hasMaxLength)
696  editText.maxLength = _gfx->readUint16LE();
697 
698  if (hasLayout) {
700  layout.alignment = GFXCharacter::TextAlignment(_gfx->readByte());
701  layout.leftMargin = _gfx->readUint16LE();
702  layout.rightMargin = _gfx->readUint16LE();
703  layout.indent = _gfx->readUint16LE();
704  layout.leading = _gfx->readSint16LE();
705  editText.layout = layout;
706  }
707 
708  const Common::UString variableName = readNullTerminatedString();
709 
710  if (hasText)
712 
713  _characters.insert(std::make_pair(characterId, GFXCharacter::createEditText(characterId, editText)));
714 }
715 
717  _gfx->skip(2); // Sprite Id
718 
720  try {
721  buffer->run(avm);
722  } catch (Common::Exception &e) {
723  warning("Failed executing actionscript: %s", e.what());
724  }
725 }
726 
728  const size_t start = _gfx->pos();
729 
730  byte actionCode = 0;
731  do {
732  actionCode = _gfx->readByte();
733  if (actionCode >= 0x80)
734  _gfx->seek(_gfx->readUint16LE(), Common::SeekableReadStream::kOriginCurrent);
735  } while (actionCode != 0);
736 
737  const size_t stop = _gfx->pos();
738 
739  _gfx->seek(start);
740  Common::MemoryReadStream *subReadStream = _gfx->readStream(stop - start);
741  ActionScript::ASBuffer *buffer = new ActionScript::ASBuffer(subReadStream);
742 
743  _gfx->seek(stop);
744 
745  return buffer;
746 }
747 
749  const size_t oldPos = _gfx->pos();
750 
751  const uint16 version = _gfx->readUint16LE();
752  if (version > 0x010A)
753  _gfx->skip(4);
754 
755  const uint16 bitmapFormat = _gfx->readUint16LE();
756  assert(bitmapFormat == 14);
757 
758  const byte prefixLen = _gfx->readByte();
759  assert(prefixLen == 0);
760 
761  const Common::UString swfName = readLengthPrefixedString();
762 
763  if (_gfx->pos() - oldPos < header.tagLength) {
764  uint16 numCodeOffsets = _gfx->readUint16LE();
765  for (unsigned int i = 0; i < numCodeOffsets; ++i) {
766  _gfx->skip(4);
767  }
768  }
769 }
770 
772  const size_t oldPos = _gfx->pos();
773 
774  uint16 id;
775  if (version == 0)
776  id = _gfx->readUint16LE();
777  else
778  id = _gfx->readUint32LE();
779 
780  GFXCharacter::ExternalImage externalImage;
781 
782  externalImage.bitmapFormat = _gfx->readUint16LE();
783  externalImage.width = _gfx->readUint16LE();
784  externalImage.height = _gfx->readUint16LE();
785 
786  if (version == 1)
788 
789  externalImage.name = readLengthPrefixedString();
790 
791  if (_gfx->pos() - oldPos < header.tagLength)
792  externalImage.name = readLengthPrefixedString();
793 
794  _characters.insert(
795  std::make_pair(id, GFXCharacter::createExternalImage(id, externalImage))
796  );
797 }
798 
800  RecordHeader recordHeader;
801 
802  Common::BitStream16LEMSB bitStream(_gfx.get());
803  recordHeader.tagType = bitStream.getBits(10);
804  recordHeader.tagLength = bitStream.getBits(6);
805 
806  // if the length is 0x3f, we have a long record header and read an the next uint32 as length
807  if (recordHeader.tagLength == 63)
808  recordHeader.tagLength = _gfx->readUint32LE();
809 
810  return recordHeader;
811 }
812 
814  Common::BitStream8MSB bitStream(_gfx.get());
815 
816  const unsigned int nBits = bitStream.getBits(5);
817 
818  Common::Rect r;
819  // SWF uses the twips unit, which is basically a twentieth pixel.
820  r.x = read2ComplementValue(bitStream, nBits) / 20;
821  r.w = read2ComplementValue(bitStream, nBits) / 20;
822  r.y = read2ComplementValue(bitStream, nBits) / 20;
823  r.h = read2ComplementValue(bitStream, nBits) / 20;
824 
825  return r;
826 }
827 
828 glm::mat3x2 GFXFile::readMatrix() {
829  glm::mat3x2 matrix;
830  matrix[0][0] = 1.0f;
831  matrix[1][1] = 1.0f;
832 
833  Common::BitStream8MSB bitStream(_gfx.get());
834 
835  const bool hasScale = bitStream.getBit() == 1;
836  if (hasScale) {
837  uint32 numScaleBits = bitStream.getBits(5);
838  matrix[0][0] = readNintendoFixedPoint(bitStream.getBits(numScaleBits), numScaleBits > 16, MAX<int32>(0, numScaleBits % 16 - 1), MIN<uint32>(numScaleBits, 16));
839  matrix[1][1] = readNintendoFixedPoint(bitStream.getBits(numScaleBits), numScaleBits > 16, MAX<int32>(0, numScaleBits % 16 - 1), MIN<uint32>(numScaleBits, 16));
840  }
841 
842  const bool hasRotate = bitStream.getBit() == 1;
843  if (hasRotate) {
844  uint32 numRotateBits = bitStream.getBits(5);
845  matrix[1][0] = bitStream.getBits(numRotateBits);
846  matrix[0][1] = bitStream.getBits(numRotateBits);
847  }
848 
849  const uint32 numTranslateBits = bitStream.getBits(5);
850  matrix[2][0] = read2ComplementValue(bitStream, numTranslateBits) / 20;
851  matrix[2][1] = read2ComplementValue(bitStream, numTranslateBits) / 20;
852 
853  return matrix;
854 }
855 
856 glm::u8vec3 GFXFile::readRGB() {
857  byte r, g, b;
858  r = _gfx->readByte();
859  g = _gfx->readByte();
860  b = _gfx->readByte();
861  return glm::u8vec3(r, g, b);
862 }
863 
864 glm::u8vec4 GFXFile::readRGBA() {
865  byte r, g, b, a;
866  r = _gfx->readByte();
867  g = _gfx->readByte();
868  b = _gfx->readByte();
869  a = _gfx->readByte();
870  return glm::u8vec4(r, g, b, a);
871 }
872 
873 std::vector<GFXCharacter::FillStyle> GFXFile::readFillStyleArray(byte version) {
874  std::vector<GFXCharacter::FillStyle> fillStyleArray;
875  uint16 fillStyleCount = _gfx->readByte();
876  if (fillStyleCount == 0xFF)
877  fillStyleCount = _gfx->readUint16LE();
878 
879  for (unsigned int i = 0; i < fillStyleCount; ++i) {
880  fillStyleArray.push_back(readFillStyle(version));
881  }
882 
883  return fillStyleArray;
884 }
885 
887  GFXCharacter::FillStyle fillStyle;
888  fillStyle.type = _gfx->readByte();
889 
890  switch (fillStyle.type) {
891  case 0x00: { // Solid fill.
892  GFXCharacter::Fill fill;
893 
894  if (version == 2)
895  fill.color = readRGBA();
896  else
897  fill.color = glm::u8vec4(readRGB(), 255);
898 
899  fillStyle.value = fill;
900  break;
901  }
902  case 0x10: // Linear gradient fill.
903  case 0x12: { // Radial gradient fill.
904  GFXCharacter::Gradient gradient;
905  gradient.matrix = readMatrix();
906 
907  Common::BitStream8MSB bitStream(_gfx.get());
908 
909  gradient.spreadMode = bitStream.getBits(2);
910  gradient.interpolationMode = bitStream.getBits(2);
911  uint32 numGradients = bitStream.getBits(4);
912 
913  for (uint32 i = 0; i < numGradients; ++i) {
914  gradient.records.push_back(readGradientRecord(version));
915  }
916 
917  fillStyle.value = gradient;
918  break;
919  }
920  case 0x41: // Clipped bitmap fill.
921  case 0x43: { // Non-smoothed bitmap fill.
922  GFXCharacter::Bitmap bitmap;
923 
924  bitmap.id = _gfx->readUint16LE();
925  bitmap.matrix = readMatrix();
926 
927  fillStyle.value = bitmap;
928  break;
929  }
930  default:
931  throw Common::Exception("Unknown or unimplemented fill style %i", fillStyle.type);
932  }
933 
934  return fillStyle;
935 }
936 
937 std::vector<GFXCharacter::LineStyle> GFXFile::readLineStyleArray(byte version) {
938  uint16 lineStyleCount = _gfx->readByte();
939  std::vector<GFXCharacter::LineStyle> lineStyleArray;
940  if (lineStyleCount == 0xFF)
941  lineStyleCount = _gfx->readUint16LE();
942 
943  for (unsigned int i = 0; i < lineStyleCount; ++i) {
944  lineStyleArray.push_back(readLineStyle(version));
945  }
946 
947  return lineStyleArray;
948 }
949 
951  GFXCharacter::LineStyle lineStyle;
952 
953  lineStyle.width = _gfx->readUint16LE();
954  if (version == 2)
955  lineStyle.color = readRGBA();
956  else
957  lineStyle.color = glm::u8vec4(readRGB(), 255);
958 
959  return lineStyle;
960 }
961 
963  GFXControl::ColorTransform colorTransform;
964 
965  Common::BitStream8MSB bitStream(_gfx.get());
966 
967  colorTransform.addTransform = bitStream.getBit() == 1;
968  colorTransform.mulTransform = bitStream.getBit() == 1;
969 
970  const unsigned int nbits = bitStream.getBits(4);
971 
972  if (colorTransform.mulTransform) {
973  colorTransform.mulR = bitStream.getBits(nbits);
974  colorTransform.mulG = bitStream.getBits(nbits);
975  colorTransform.mulB = bitStream.getBits(nbits);
976  colorTransform.mulA = bitStream.getBits(nbits);
977  }
978 
979  if (colorTransform.addTransform) {
980  colorTransform.addR = bitStream.getBits(nbits);
981  colorTransform.addG = bitStream.getBits(nbits);
982  colorTransform.addB = bitStream.getBits(nbits);
983  colorTransform.addA = bitStream.getBits(nbits);
984  }
985 
986  return colorTransform;
987 }
988 
990  // TODO
991 }
992 
995  record.ratio = _gfx->readByte();
996  if (version == 2)
997  record.color = readRGBA();
998  else
999  record.color = glm::u8vec4(readRGB(), 255);
1000 
1001  return record;
1002 }
1003 
1004 std::vector<GFXCharacter::ShapeRecord> GFXFile::readShape(byte version, bool withStyle) {
1005  std::vector<GFXCharacter::FillStyle> fillStyles;
1006  std::vector<GFXCharacter::LineStyle> lineStyles;
1007 
1008  if (withStyle) {
1009  fillStyles = readFillStyleArray(version);
1010  lineStyles = readLineStyleArray(version);
1011  }
1012 
1013  GFXCharacter::FillStyle fillStyle0, fillStyle1;
1014  GFXCharacter::LineStyle lineStyle;
1015 
1016  Common::BitStream8MSB bitStream(_gfx.get());
1017  byte numFillBits = bitStream.getBits(4);
1018  byte numLineBits = bitStream.getBits(4);
1019 
1020  std::vector<GFXCharacter::ShapeRecord> shapeRecords;
1021 
1022  while (true) {
1024  const bool type = bitStream.getBit() == 1;
1025  // Edge record.
1026  if (type) {
1027  const bool straightEdge = bitStream.getBit() == 1;
1028  uint32 numBits = bitStream.getBits(4);
1029 
1030  if (straightEdge) {
1031  const bool generalLine = bitStream.getBit() == 1;
1032  bool vertLine;
1033  if (generalLine)
1034  vertLine = false;
1035  else
1036  vertLine = bitStream.getBit() == 1;
1037 
1038  if (generalLine || !vertLine)
1039  record.straightEdge.deltaX = read2ComplementValue(bitStream, numBits + 2) / 20;
1040  else
1041  record.straightEdge.deltaX = 0;
1042  if (generalLine || vertLine)
1043  record.straightEdge.deltaY = read2ComplementValue(bitStream, numBits + 2) / 20;
1044  else
1045  record.straightEdge.deltaY = 0;
1046  } else {
1047  record.curvedEdge.controlDeltaX = read2ComplementValue(bitStream, numBits + 2);
1048  record.curvedEdge.controlDeltaY = read2ComplementValue(bitStream, numBits + 2);
1049  record.curvedEdge.anchorDeltaX = read2ComplementValue(bitStream, numBits + 2);
1050  record.curvedEdge.anchorDeltaY = read2ComplementValue(bitStream, numBits + 2);
1051  }
1052  } else {
1053  const bool stateNewStyles = bitStream.getBit() == 1;
1054  const bool stateLineStyle = bitStream.getBit() == 1;
1055  const bool stateFillStyle1 = bitStream.getBit() == 1;
1056  const bool stateFillStyle0 = bitStream.getBit() == 1;
1057  const bool stateMoveTo = bitStream.getBit() == 1;
1058 
1059  if (!stateNewStyles && !stateLineStyle && !stateFillStyle1 && !stateFillStyle0 && !stateMoveTo)
1060  break;
1061 
1062  if (stateMoveTo) {
1063  const size_t moveBits = bitStream.getBits(5);
1064  // Size in twips.
1065  record.move.deltaX = read2ComplementValue(bitStream, moveBits) / 20;
1066  record.move.deltaY = read2ComplementValue(bitStream, moveBits) / 20;
1067  }
1068 
1069  if (stateFillStyle0) {
1070  const uint32 index = bitStream.getBits(numFillBits);
1071  if (!fillStyles.empty()) {
1072  if (index)
1073  record.style.fillStyle0 = fillStyles[index - 1];
1074  else
1076  }
1077  }
1078 
1079  if (stateFillStyle1) {
1080  const uint32 index = bitStream.getBits(numFillBits);
1081  if (!fillStyles.empty()) {
1082  if (index)
1083  record.style.fillStyle1 = fillStyles[index - 1];
1084  else
1086  }
1087  }
1088 
1089  if (stateLineStyle) {
1090  const uint32 index = bitStream.getBits(numLineBits);
1091  if (!lineStyles.empty()) {
1092  if (!index)
1094  else
1095  record.style.lineStyle = lineStyles[index - 1];
1096  }
1097  }
1098 
1099  if (stateNewStyles) {
1100  if (version == 0)
1101  throw Common::Exception("New styles can only be defined by DefineShape2 and DefineShape3");
1102 
1103  fillStyles = readFillStyleArray(version);
1104  lineStyles = readLineStyleArray(version);
1105 
1106  if (bitStream.pos() % 8 != 0)
1107  bitStream.skip(8 - (bitStream.pos() % 8));
1108 
1109  numFillBits = bitStream.getBits(4);
1110  numLineBits = bitStream.getBits(4);
1111  }
1112  }
1113 
1114  shapeRecords.push_back(record);
1115  }
1116 
1117  return shapeRecords;
1118 }
1119 
1122 }
1123 
1125  const byte length = _gfx->readByte();
1127 }
1128 
1130  const uint32 v = bitStream.getBits(n);
1131  const uint32 sign = v >> (n - 1) << (n - 1);
1132  const int32 value = -sign + (v ^ sign);
1133  return value;
1134 }
1135 
1136 } // End of namespace Aurora
Class for parsing gfx files.
Definition: gfxfile.h:348
void readFileAttributes()
Read the file attributes tag.
Definition: gfxfile.cpp:375
#define ResMan
Shortcut for accessing the sound manager.
Definition: resman.h:557
A record for a shape.
Definition: gfxfile.h:112
Common::UString readNullTerminatedString()
Read a null terminated string.
Definition: gfxfile.cpp:1120
int32 read2ComplementValue(Common::BitStream &bitStream, size_t n)
Read a 2&#39;s complement value.
Definition: gfxfile.cpp:1129
#define MKTAG(a0, a1, a2, a3)
A wrapper macro used around four character constants, like &#39;DATA&#39;, to ensure portability.
Definition: endianness.h:140
double w
Definition: rect.h:37
std::vector< GradientRecord > records
Definition: gfxfile.h:78
std::vector< KerningCode > kerningCodes
Definition: gfxfile.h:216
static GFXCharacter createSprite(uint16 id, Sprite sprite)
Create a sprite character.
Definition: gfxfile.cpp:75
A simple one-color fill.
Definition: gfxfile.h:69
boost::optional< uint16 > fontHeight
Definition: gfxfile.h:203
void readFocalGradient(byte version)
Read a focal gradient record.
Definition: gfxfile.cpp:989
A class holding an UTF-8 string.
Definition: ustring.h:48
boost::optional< uint16 > characterId
Definition: gfxfile.h:308
GFXFile(const Common::UString &resref, Aurora::ActionScript::AVM &avm)
Open a gfx file specified by the reference and used with the specified avm.
Definition: gfxfile.cpp:198
void reset(PointerType o=0)
Resets the pointer with the new value.
Definition: scopedptr.h:87
boost::variant< Fill, Gradient, Bitmap > value
Definition: gfxfile.h:90
GFX files are used for the dragonage and dragonage2 guis.
GFXCharacter::FillStyle readFillStyle(byte version)
Read an FillStyle record.
Definition: gfxfile.cpp:886
double y
Definition: rect.h:36
std::vector< GFXControl > controls
Definition: gfxfile.h:169
ControlType
The possible control types.
Definition: gfxfile.h:283
TextAlignment
The alignment of text.
Definition: gfxfile.h:156
void load(Common::SeekableReadStream *gfx, Aurora::ActionScript::AVM &avm)
Definition: gfxfile.cpp:222
boost::variant< Sprite, Shape, EditText, Font, ExternalImage > _value
Definition: gfxfile.h:266
boost::optional< uint8 > blendMode
Definition: gfxfile.h:312
std::vector< ShapeRecord > shapeRecords
Definition: gfxfile.h:177
boost::optional< uint16 > maxLength
Definition: gfxfile.h:205
static GFXCharacter createExternalImage(uint16 id, ExternalImage externalImage)
Create an external image character.
Definition: gfxfile.cpp:107
void readImportAssets(ActionScript::AVM &avm)
Read an import assets tag.
Definition: gfxfile.cpp:355
boost::optional< uint16 > fontAscent
Definition: gfxfile.h:217
boost::optional< EditTextLayout > layout
Definition: gfxfile.h:207
An edit text character, mostly used as static, but sometimes also used as editable text...
Definition: gfxfile.h:193
GFXCharacter getCharacter(uint16 id)
Get a character by id.
Definition: gfxfile.cpp:214
uint32 getBit()
Read a bit from the bit stream.
Definition: bitstream.h:153
uint32 getBits(size_t n)
Read a multi-bit value from the bit stream.
Definition: bitstream.h:178
GFXControl readPlaceObject(byte version=1)
Read a place object tag.
Definition: gfxfile.cpp:457
double x
Definition: rect.h:36
GFXCharacter::LineStyle readLineStyle(byte version)
Read a line style.
Definition: gfxfile.cpp:950
boost::variant< PlaceObject, DoAction > _value
Definition: gfxfile.h:336
struct Aurora::GFXCharacter::ShapeRecord::@3 straightEdge
std::vector< GFXControl > _controlTags
All root control tags.
Definition: gfxfile.h:380
Common::UString name
Definition: gfxfile.h:214
Exception that provides a stack of explanations.
Definition: error.h:36
std::vector< GFXCharacter::FillStyle > readFillStyleArray(byte version)
Read an fillstyle array.
Definition: gfxfile.cpp:873
boost::optional< int16 > fontLeading
Definition: gfxfile.h:219
Common::ScopedPtr< Common::SeekableReadStream > _gfx
The read stream of this gfx file.
Definition: gfxfile.h:383
struct Aurora::GFXCharacter::ShapeRecord::@2 move
std::vector< ShapeRecord > shapeRecords
Definition: gfxfile.h:144
void getExternalImage(ExternalImage &externalImage) const
Get the external image character.
Definition: gfxfile.cpp:154
A control tag is used for controlling stuff in the scene, like placing or removing objects...
Definition: gfxfile.h:278
std::vector< Glyph > glyphs
Definition: gfxfile.h:215
boost::optional< Common::UString > name
Definition: gfxfile.h:309
void readInitAction(ActionScript::AVM &avm)
Read a DoInitAction tag.
Definition: gfxfile.cpp:716
static GFXCharacter createShape(uint16 id, Shape shape)
Create a shape character.
Definition: gfxfile.cpp:83
std::vector< GFXCharacter::ShapeRecord > readShape(byte version, bool withStyle)
Read a shape.
Definition: gfxfile.cpp:1004
The standard header of every tag.
Definition: gfxfile.h:370
void readDefineSprite()
Read a define sprite tag.
Definition: gfxfile.cpp:401
std::map< uint16, GFXCharacter > _characters
Every character associated with it&#39;s character id.
Definition: gfxfile.h:378
uint16_t uint16
Definition: types.h:202
#define UNUSED(x)
Definition: system.h:170
ControlType _type
Definition: gfxfile.h:338
An external image character, which loads an image resource from the guis texture atlas files...
Definition: gfxfile.h:226
Utility templates and functions.
A color tranformation of the specific object.
Definition: gfxfile.h:290
Aurora::ActionScript::ASBuffer * readAction()
Read a DoAction tag.
Definition: gfxfile.cpp:727
void readGFXDefineExternalImage(RecordHeader header, byte version=0)
Load an external image reference.
Definition: gfxfile.cpp:771
void getDoAction(DoAction &doAction) const
Get do action control.
Definition: gfxfile.cpp:188
virtual size_t skip(ptrdiff_t offset)
Skip the specified number of bytes, adding that offset to the current position in the stream...
Definition: readstream.h:317
void readExportAssets()
Read an export assets tag.
Definition: gfxfile.cpp:345
boost::optional< ColorTransform > colorTransform
Definition: gfxfile.h:311
GFXCharacter::GradientRecord readGradientRecord(byte version)
Read a gradient record.
Definition: gfxfile.cpp:993
Common::Rect _frameSize
The standard bounds of the ui in this file.
Definition: gfxfile.h:386
A do action control tag.
Definition: gfxfile.h:316
uint16 getExportedAssetId(const Common::UString &id)
Get the corresponding character id for an exported asset.
Definition: gfxfile.cpp:206
double readNintendoFixedPoint(uint32 value, bool sign, uint8 iBits, uint8 fBits)
Read a fixed-point value, in a format used by the Nintendo DS.
Definition: util.cpp:159
Simple memory based &#39;stream&#39;, which implements the ReadStream interface for a plain memory block...
Definition: memreadstream.h:66
void readDefineFont()
Read a font definition version 3.
Definition: gfxfile.cpp:523
Utility functions for working with differing string encodings.
static GFXControl createShowFrame()
Create a show frame control.
Definition: gfxfile.cpp:177
glm::mat3x2 readMatrix()
Read a matrix.
Definition: gfxfile.cpp:828
RecordHeader readRecordHeader()
Read a record header for the next tag.
Definition: gfxfile.cpp:799
StackException Exception
Definition: error.h:59
void readHeader()
Load all header information.
Definition: gfxfile.cpp:322
A scoped plain pointer, allowing pointer-y access and normal deletion.
Definition: scopedptr.h:120
glm::u8vec4 readRGBA()
Reag an RGBA color record.
Definition: gfxfile.cpp:864
A Scaleform GFx font, usable for rendering letters in the ui.
Definition: gfxfile.h:213
void readDefineShape(byte version)
Read a DefineShape tag.
Definition: gfxfile.cpp:331
Element placeable in the current scene.
Definition: gfxfile.h:49
void warning(const char *s,...)
Definition: util.cpp:33
virtual size_t size() const =0
Obtains the total size of the stream, measured in bytes.
CharacterType getType() const
Get the type of this character.
Definition: gfxfile.cpp:118
struct Aurora::GFXCharacter::ShapeRecord::@1 style
Basic reading stream interfaces.
void readGFXExporterInfo(RecordHeader header)
Load the information about the gfx exporter.
Definition: gfxfile.cpp:748
byte * decompressDeflateWithoutOutputSize(const byte *data, size_t inputSize, size_t &outputSize, int windowBits, unsigned int frameSize)
Decompress (inflate) using zlib&#39;s DEFLATE algorithm without knowing the output size.
Definition: deflate.cpp:96
uint32 readUint32BE()
Read an unsigned 32-bit word stored in big endian (MSB first) order from the stream and return it...
Definition: readstream.h:166
static GFXCharacter createEditText(uint16 id, EditText editText)
Create an edit text character.
Definition: gfxfile.cpp:99
Seek from the current position of the stream.
Definition: readstream.h:270
Unicode string handling.
void skip(size_t n)
Skip the specified amount of bits.
Definition: bitstream.h:221
void getPlaceObject(PlaceObject &placeObject) const
Get the place object control.
Definition: gfxfile.cpp:181
Plain, unextended ASCII (7bit clean).
Definition: encoding.h:40
void readBackgroundColor()
Read the background color tag.
Definition: gfxfile.cpp:341
GFXControl::ColorTransform readColorTransform()
Read a color transform.
Definition: gfxfile.cpp:962
static const int kWindowBitsMax
Definition: deflate.h:41
PointerType get() const
Returns the plain pointer value.
Definition: scopedptr.h:96
CharacterType _type
Definition: gfxfile.h:269
Aurora::ActionScript::ASBuffer * asBuffer
Definition: gfxfile.h:317
A shape character, which is a static image shape with bounds.
Definition: gfxfile.h:175
static UString getStem(const UString &p)
Return a file name&#39;s stem.
Definition: filepath.cpp:87
glm::u8vec3 readRGB()
Read an RGB color record.
Definition: gfxfile.cpp:856
Common::UString readLengthPrefixedString()
Read a byte length prefixed string.
Definition: gfxfile.cpp:1124
void getFont(Font &font) const
Get the font character.
Definition: gfxfile.cpp:140
Common::Rect readRectangle()
Read a basic rectangle type from the gfx file.
Definition: gfxfile.cpp:813
A style for the border.
Definition: gfxfile.h:98
boost::optional< uint16 > fontDescent
Definition: gfxfile.h:218
uint32_t uint32
Definition: types.h:204
double h
Definition: rect.h:37
static const uint32 kCFXID
Definition: gfxfile.cpp:37
Part of a gradient.
Definition: gfxfile.h:63
void readDefineEditText()
Read an edit text character.
Definition: gfxfile.cpp:640
Optional layout for edit texts.
Definition: gfxfile.h:181
void getSprite(Sprite &sprite) const
Get the sprite character.
Definition: gfxfile.cpp:126
void getEditText(EditText &editText) const
Get the edit text character.
Definition: gfxfile.cpp:147
virtual uint32 getBits(size_t n)=0
Read a multi-bit value from the bit stream.
UString readString(SeekableReadStream &stream, Encoding encoding)
Read a string with the given encoding of a stream.
Definition: encoding.cpp:287
boost::optional< glm::u8vec4 > textColor
Definition: gfxfile.h:204
CharacterType
The possible element types, used in the scene.
Definition: gfxfile.h:54
Vector graphics animation, Scaleform GFx.
Definition: types.h:292
std::map< Common::UString, uint16 > _exportTable
Every exported character id with the associated export name.
Definition: gfxfile.h:376
A place object control tag for placing objects.
Definition: gfxfile.h:304
A template implementing a bit stream for different data memory layouts.
Definition: bitstream.h:85
UString readStringFixed(SeekableReadStream &stream, Encoding encoding, size_t length)
Read length bytes as a string with the given encoding out of a stream.
Definition: encoding.cpp:297
A style for filling.
Definition: gfxfile.h:88
SeekableSubReadStream provides access to a SeekableReadStream restricted to the range [begin...
Definition: readstream.h:359
const char * what() const
Definition: error.cpp:73
std::vector< GFXCharacter::LineStyle > readLineStyleArray(byte version)
Read a line style array.
Definition: gfxfile.cpp:937
Compress (deflate) and decompress (inflate) using zlib&#39;s DEFLATE algorithm.
uint16 getId() const
Get the character id of this character.
Definition: gfxfile.cpp:122
unsigned short _frameCount
The count of frames in this gfx file.
Definition: gfxfile.h:390
boost::optional< uint16 > fontId
Definition: gfxfile.h:202
Interface for a seekable & readable data stream.
Definition: readstream.h:265
struct Aurora::GFXCharacter::ShapeRecord::@4 curvedEdge
A bit stream.
Definition: bitstream.h:40
void getShape(Shape &shape) const
Get the shape character.
Definition: gfxfile.cpp:133
The global resource manager for Aurora resources.
Utility class for manipulating file paths.
static GFXControl createDoAction(DoAction)
Create a do action control.
Definition: gfxfile.cpp:169
uint8 byte
Definition: types.h:209
boost::optional< Common::UString > initialText
Definition: gfxfile.h:206
float _frameRate
The frame rate, how fast this gui should be played.
Definition: gfxfile.h:388
A sprite character, which is basically a container with control statements and other characters...
Definition: gfxfile.h:167
boost::optional< glm::mat3x2 > matrix
Definition: gfxfile.h:310
static GFXCharacter createFont(uint16 id, Font font)
Create a font character.
Definition: gfxfile.cpp:91
int32_t int32
Definition: types.h:203
GFXCharacter(uint16 id, CharacterType type)
Definition: gfxfile.cpp:115
GFXControl(ControlType type)
Definition: gfxfile.cpp:195
static GFXControl createPlaceObject(PlaceObject)
Create a place object control.
Definition: gfxfile.cpp:161
The Action script virtual machine (AVM).
Definition: avm.h:46
A character glyph for a font.
Definition: gfxfile.h:141