00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <vector>
00021 #include <list>
00022 #include <algorithm>
00023 #include "scripting/abc.h"
00024 #include "tags.h"
00025 #include "scripting/actions.h"
00026 #include "backends/geometry.h"
00027 #include "backends/rendering.h"
00028 #include "swftypes.h"
00029 #include "swf.h"
00030 #include "logger.h"
00031 #include "frame.h"
00032 #include <GL/glew.h>
00033 #include "compat.h"
00034
00035 #undef RGB
00036
00037 using namespace std;
00038 using namespace lightspark;
00039
00040 extern TLSDATA SystemState* sys;
00041 extern TLSDATA RenderThread* rt;
00042 extern TLSDATA ParseThread* pt;
00043
00044 Tag* TagFactory::readTag()
00045 {
00046 RECORDHEADER h;
00047 f >> h;
00048
00049 unsigned int expectedLen=h.getLength();
00050 unsigned int start=f.tellg();
00051 Tag* ret=NULL;
00052 LOG(LOG_TRACE,_("Reading tag type: ") << h.getTagType() << _(" at byte ") << start << _(" with length ") << expectedLen << _(" bytes"));
00053 switch(h.getTagType())
00054 {
00055 case 0:
00056 LOG(LOG_TRACE, _("EndTag at position ") << f.tellg());
00057 ret=new EndTag(h,f);
00058 break;
00059 case 1:
00060 ret=new ShowFrameTag(h,f);
00061 break;
00062 case 2:
00063 ret=new DefineShapeTag(h,f);
00064 break;
00065
00066
00067 case 9:
00068 ret=new SetBackgroundColorTag(h,f);
00069 break;
00070 case 10:
00071 ret=new DefineFontTag(h,f);
00072 break;
00073 case 11:
00074 ret=new DefineTextTag(h,f);
00075 break;
00076 case 12:
00077 ret=new DoActionTag(h,f);
00078 break;
00079 case 13:
00080 ret=new DefineFontInfoTag(h,f);
00081 break;
00082 case 14:
00083 ret=new DefineSoundTag(h,f);
00084 break;
00085 case 15:
00086 ret=new StartSoundTag(h,f);
00087 break;
00088 case 18:
00089 ret=new SoundStreamHeadTag(h,f);
00090 break;
00091 case 19:
00092 ret=new SoundStreamBlockTag(h,f);
00093 break;
00094 case 20:
00095 ret=new DefineBitsLosslessTag(h,f);
00096 break;
00097 case 21:
00098 ret=new DefineBitsJPEG2Tag(h,f);
00099 break;
00100 case 22:
00101 ret=new DefineShape2Tag(h,f);
00102 break;
00103 case 24:
00104 ret=new ProtectTag(h,f);
00105 break;
00106 case 26:
00107 ret=new PlaceObject2Tag(h,f);
00108 break;
00109 case 28:
00110 ret=new RemoveObject2Tag(h,f);
00111 break;
00112 case 32:
00113 ret=new DefineShape3Tag(h,f);
00114 break;
00115 case 34:
00116 ret=new DefineButton2Tag(h,f);
00117 break;
00118 case 36:
00119 ret=new DefineBitsLossless2Tag(h,f);
00120 break;
00121 case 37:
00122 ret=new DefineEditTextTag(h,f);
00123 break;
00124 case 39:
00125 ret=new DefineSpriteTag(h,f);
00126 break;
00127 case 41:
00128 ret=new ProductInfoTag(h,f);
00129 break;
00130 case 43:
00131 ret=new FrameLabelTag(h,f);
00132 break;
00133 case 45:
00134 ret=new SoundStreamHead2Tag(h,f);
00135 break;
00136 case 46:
00137 ret=new DefineMorphShapeTag(h,f);
00138 break;
00139 case 48:
00140 ret=new DefineFont2Tag(h,f);
00141 break;
00142 case 56:
00143 ret=new ExportAssetsTag(h,f);
00144 break;
00145 case 58:
00146 ret=new EnableDebuggerTag(h,f);
00147 break;
00148 case 59:
00149 ret=new DoInitActionTag(h,f);
00150 break;
00151 case 60:
00152 ret=new DefineVideoStreamTag(h,f);
00153 break;
00154 case 63:
00155 ret=new DebugIDTag(h,f);
00156 break;
00157 case 64:
00158 ret=new EnableDebugger2Tag(h,f);
00159 break;
00160 case 65:
00161 ret=new ScriptLimitsTag(h,f);
00162 break;
00163 case 69:
00164
00165 if(pt->version>=8)
00166 {
00167 if(!firstTag)
00168 LOG(LOG_ERROR,_("FileAttributes tag not in the beginning"));
00169 }
00170 ret=new FileAttributesTag(h,f);
00171 break;
00172 case 70:
00173 ret=new PlaceObject3Tag(h,f);
00174 break;
00175 case 73:
00176 ret=new DefineFontAlignZonesTag(h,f);
00177 break;
00178 case 74:
00179 ret=new CSMTextSettingsTag(h,f);
00180 break;
00181 case 75:
00182 ret=new DefineFont3Tag(h,f);
00183 break;
00184 case 76:
00185 ret=new SymbolClassTag(h,f);
00186 break;
00187 case 77:
00188 ret=new MetadataTag(h,f);
00189 break;
00190 case 78:
00191 ret=new DefineScalingGridTag(h,f);
00192 break;
00193 case 82:
00194 ret=new DoABCTag(h,f);
00195 break;
00196 case 83:
00197 ret=new DefineShape4Tag(h,f);
00198 break;
00199 case 86:
00200 ret=new DefineSceneAndFrameLabelDataTag(h,f);
00201 break;
00202 case 87:
00203 ret=new DefineBinaryDataTag(h,f);
00204 break;
00205 case 88:
00206 ret=new DefineFontNameTag(h,f);
00207 break;
00208 default:
00209 LOG(LOG_NOT_IMPLEMENTED,_("Unsupported tag type ") << h.getTagType());
00210 ret=new UnimplementedTag(h,f);
00211 }
00212
00213
00214 if(topLevel && firstTag && pt->root==sys)
00215 sys->needsAVM2(pt->useAVM2);
00216 firstTag=false;
00217
00218 unsigned int end=f.tellg();
00219
00220 unsigned int actualLen=end-start;
00221
00222 if(actualLen<expectedLen)
00223 {
00224 LOG(LOG_ERROR,_("Error while reading tag ") << h.getTagType() << _(". Size=") << actualLen << _(" expected: ") << expectedLen);
00225 ignore(f,expectedLen-actualLen);
00226 }
00227 else if(actualLen>expectedLen)
00228 {
00229 LOG(LOG_ERROR,_("Error while reading tag ") << h.getTagType() << _(". Size=") << actualLen << _(" expected: ") << expectedLen);
00230 throw ParseException("Malformed SWF file");
00231 }
00232
00233 return ret;
00234 }
00235
00236 RemoveObject2Tag::RemoveObject2Tag(RECORDHEADER h, std::istream& in):DisplayListTag(h)
00237 {
00238 in >> Depth;
00239 LOG(LOG_TRACE,_("RemoveObject2 Depth: ") << Depth);
00240 }
00241
00242 void RemoveObject2Tag::execute(MovieClip* parent, list <pair<PlaceInfo, DisplayObject*> >& ls)
00243 {
00244 list <pair<PlaceInfo, DisplayObject*> >::iterator it=ls.begin();
00245
00246 for(;it!=ls.end();it++)
00247 {
00248 if(it->second->Depth==Depth)
00249 {
00250 it->second->decRef();
00251 ls.erase(it);
00252 break;
00253 }
00254 }
00255 }
00256
00257 SetBackgroundColorTag::SetBackgroundColorTag(RECORDHEADER h, std::istream& in):ControlTag(h)
00258 {
00259 in >> BackgroundColor;
00260 }
00261
00262 DefineEditTextTag::DefineEditTextTag(RECORDHEADER h, std::istream& in):DictionaryTag(h)
00263 {
00264
00265 in >> CharacterID >> Bounds;
00266 LOG(LOG_TRACE,_("DefineEditTextTag ID ") << CharacterID);
00267 BitStream bs(in);
00268 HasText=UB(1,bs);
00269 WordWrap=UB(1,bs);
00270 Multiline=UB(1,bs);
00271 Password=UB(1,bs);
00272 ReadOnly=UB(1,bs);
00273 HasTextColor=UB(1,bs);
00274 HasMaxLength=UB(1,bs);
00275 HasFont=UB(1,bs);
00276 HasFontClass=UB(1,bs);
00277 AutoSize=UB(1,bs);
00278 HasLayout=UB(1,bs);
00279 NoSelect=UB(1,bs);
00280 Border=UB(1,bs);
00281 WasStatic=UB(1,bs);
00282 HTML=UB(1,bs);
00283 UseOutlines=UB(1,bs);
00284 if(HasFont)
00285 {
00286 in >> FontID;
00287 if(HasFontClass)
00288 in >> FontClass;
00289 in >> FontHeight;
00290 }
00291 if(HasTextColor)
00292 in >> TextColor;
00293 if(HasMaxLength)
00294 in >> MaxLength;
00295 if(HasLayout)
00296 {
00297 in >> Align >> LeftMargin >> RightMargin >> Indent >> Leading;
00298 }
00299 in >> VariableName;
00300 LOG(LOG_NOT_IMPLEMENTED,_("Sync to variable name ") << VariableName);
00301 if(HasText)
00302 in >> InitialText;
00303 }
00304
00305 void DefineEditTextTag::Render()
00306 {
00307 LOG(LOG_NOT_IMPLEMENTED,_("DefineEditTextTag: Render"));
00308 }
00309
00310 Vector2 DefineEditTextTag::debugRender(FTFont* font, bool deep)
00311 {
00312 assert(!deep);
00313 glColor3f(0,0.8,0);
00314 char buf[20];
00315 snprintf(buf,20,"EditText id=%u",(int)CharacterID);
00316 font->Render(buf,-1,FTPoint(0,50));
00317
00318 glBegin(GL_LINE_LOOP);
00319 glVertex2i(0,0);
00320 glVertex2i(100,0);
00321 glVertex2i(100,100);
00322 glVertex2i(0,100);
00323 glEnd();
00324 return Vector2(100,100);
00325 }
00326
00327 ASObject* DefineEditTextTag::instance() const
00328 {
00329 DefineEditTextTag* ret=new DefineEditTextTag(*this);
00330
00331 assert_and_throw(bindedTo==NULL);
00332 ret->setPrototype(Class<TextField>::getClass());
00333 return ret;
00334 }
00335
00336 DefineSpriteTag::DefineSpriteTag(RECORDHEADER h, std::istream& in):DictionaryTag(h)
00337 {
00338 in >> SpriteID >> FrameCount;
00339 setTotalFrames(FrameCount);
00340 framesLoaded=FrameCount;
00341 state.max_FP=FrameCount;
00342
00343 LOG(LOG_TRACE,_("DefineSprite ID: ") << SpriteID);
00344
00345 TagFactory factory(in, false);
00346 Tag* tag;
00347 bool done=false;
00348 bool empty=true;
00349 do
00350 {
00351 tag=factory.readTag();
00352 sys->tagsStorage.push_back(tag);
00353 switch(tag->getType())
00354 {
00355 case DICT_TAG:
00356 throw ParseException("Dictionary tag inside a sprite. Should not happen.");
00357 case DISPLAY_LIST_TAG:
00358 addToFrame(static_cast<DisplayListTag*>(tag));
00359 empty=false;
00360 break;
00361 case SHOW_TAG:
00362 {
00363 frames.push_back(Frame());
00364 cur_frame=&frames.back();
00365 empty=true;
00366 break;
00367 }
00368 case CONTROL_TAG:
00369 throw ParseException("Control tag inside a sprite. Should not happen.");
00370 case FRAMELABEL_TAG:
00371 frames.back().Label=(const char*)static_cast<FrameLabelTag*>(tag)->Name;
00372 empty=false;
00373 break;
00374 case TAG:
00375 LOG(LOG_NOT_IMPLEMENTED,_("Unclassified tag inside Sprite?"));
00376 break;
00377 case END_TAG:
00378 done=true;
00379 if(empty && frames.size()!=FrameCount)
00380 frames.pop_back();
00381 break;
00382 }
00383 }
00384 while(!done);
00385
00386 if(frames.size()!=FrameCount)
00387 {
00388 LOG(LOG_ERROR,_("Inconsistent frame count ") << FrameCount);
00389 throw ParseException("Invalid frame count in Sprite");
00390 }
00391
00392 LOG(LOG_TRACE,_("EndDefineSprite ID: ") << SpriteID);
00393 }
00394
00395 ASObject* DefineSpriteTag::instance() const
00396 {
00397 DefineSpriteTag* ret=new DefineSpriteTag(*this);
00398
00399 if(bindedTo)
00400 {
00401
00402 ret->setPrototype(bindedTo);
00403 }
00404 else
00405 ret->setPrototype(Class<MovieClip>::getClass());
00406 ret->bootstrap();
00407 return ret;
00408 }
00409
00410 Vector2 DefineSpriteTag::debugRender(FTFont* font, bool deep)
00411 {
00412 if(deep)
00413 return MovieClip::debugRender(font,deep);
00414
00415 glColor3f(0.5,0,0);
00416 char buf[20];
00417 snprintf(buf,20,"Sprite id=%u",(int)SpriteID);
00418 font->Render(buf,-1,FTPoint(0,50));
00419 FTBBox tagBox=font->BBox(buf,-1);
00420 glBegin(GL_LINE_LOOP);
00421 glVertex2i(0,0);
00422 glVertex2i(tagBox.Upper().X(),0);
00423 glVertex2i(tagBox.Upper().X(),100);
00424 glVertex2i(0,100);
00425 glEnd();
00426 return Vector2(tagBox.Upper().X(),100);
00427 }
00428
00429 void lightspark::ignore(istream& i, int count)
00430 {
00431 char* buf=new char[count];
00432
00433 i.read(buf,count);
00434
00435 delete[] buf;
00436 }
00437
00438 DefineFontTag::DefineFontTag(RECORDHEADER h, std::istream& in):FontTag(h)
00439 {
00440 LOG(LOG_TRACE,_("DefineFont"));
00441 in >> FontID;
00442
00443 UI16 t;
00444 int NumGlyphs=0;
00445 in >> t;
00446 OffsetTable.push_back(t);
00447 NumGlyphs=t/2;
00448
00449 for(int i=1;i<NumGlyphs;i++)
00450 {
00451 in >> t;
00452 OffsetTable.push_back(t);
00453 }
00454
00455 for(int i=0;i<NumGlyphs;i++)
00456 {
00457 SHAPE t;
00458 in >> t;
00459 GlyphShapeTable.push_back(t);
00460 }
00461 }
00462
00463 DefineFont2Tag::DefineFont2Tag(RECORDHEADER h, std::istream& in):FontTag(h)
00464 {
00465 LOG(LOG_TRACE,_("DefineFont2"));
00466 in >> FontID;
00467 BitStream bs(in);
00468 FontFlagsHasLayout = UB(1,bs);
00469 FontFlagsShiftJIS = UB(1,bs);
00470 FontFlagsSmallText = UB(1,bs);
00471 FontFlagsANSI = UB(1,bs);
00472 FontFlagsWideOffsets = UB(1,bs);
00473 FontFlagsWideCodes = UB(1,bs);
00474 FontFlagsItalic = UB(1,bs);
00475 FontFlagsBold = UB(1,bs);
00476 in >> LanguageCode >> FontNameLen;
00477 for(int i=0;i<FontNameLen;i++)
00478 {
00479 UI8 t;
00480 in >> t;
00481 FontName.push_back(t);
00482 }
00483 in >> NumGlyphs;
00484 if(FontFlagsWideOffsets)
00485 {
00486 UI32 t;
00487 for(int i=0;i<NumGlyphs;i++)
00488 {
00489 in >> t;
00490 OffsetTable.push_back(t);
00491 }
00492 in >> t;
00493 CodeTableOffset=t;
00494 }
00495 else
00496 {
00497 UI16 t;
00498 for(int i=0;i<NumGlyphs;i++)
00499 {
00500 in >> t;
00501 OffsetTable.push_back(t);
00502 }
00503 in >> t;
00504 CodeTableOffset=t;
00505 }
00506 for(int i=0;i<NumGlyphs;i++)
00507 {
00508 SHAPE t;
00509 in >> t;
00510 GlyphShapeTable.push_back(t);
00511 }
00512 if(FontFlagsWideCodes)
00513 {
00514 for(int i=0;i<NumGlyphs;i++)
00515 {
00516 UI16 t;
00517 in >> t;
00518 CodeTable.push_back(t);
00519 }
00520 }
00521 else
00522 {
00523 for(int i=0;i<NumGlyphs;i++)
00524 {
00525 UI8 t;
00526 in >> t;
00527 CodeTable.push_back(t);
00528 }
00529 }
00530 if(FontFlagsHasLayout)
00531 {
00532 in >> FontAscent >> FontDescent >> FontLeading;
00533
00534 for(int i=0;i<NumGlyphs;i++)
00535 {
00536 SI16 t;
00537 in >> t;
00538 FontAdvanceTable.push_back(t);
00539 }
00540 for(int i=0;i<NumGlyphs;i++)
00541 {
00542 RECT t;
00543 in >> t;
00544 FontBoundsTable.push_back(t);
00545 }
00546 in >> KerningCount;
00547 }
00548
00549 ignore(in,KerningCount*4);
00550 }
00551
00552 DefineFont3Tag::DefineFont3Tag(RECORDHEADER h, std::istream& in):FontTag(h)
00553 {
00554 LOG(LOG_TRACE,_("DefineFont3"));
00555 in >> FontID;
00556 BitStream bs(in);
00557 FontFlagsHasLayout = UB(1,bs);
00558 FontFlagsShiftJIS = UB(1,bs);
00559 FontFlagsSmallText = UB(1,bs);
00560 FontFlagsANSI = UB(1,bs);
00561 FontFlagsWideOffsets = UB(1,bs);
00562 FontFlagsWideCodes = UB(1,bs);
00563 FontFlagsItalic = UB(1,bs);
00564 FontFlagsBold = UB(1,bs);
00565 in >> LanguageCode >> FontNameLen;
00566 for(int i=0;i<FontNameLen;i++)
00567 {
00568 UI8 t;
00569 in >> t;
00570 FontName.push_back(t);
00571 }
00572 in >> NumGlyphs;
00573 if(FontFlagsWideOffsets)
00574 {
00575 UI32 t;
00576 for(int i=0;i<NumGlyphs;i++)
00577 {
00578 in >> t;
00579 OffsetTable.push_back(t);
00580 }
00581 in >> t;
00582 CodeTableOffset=t;
00583 }
00584 else
00585 {
00586 UI16 t;
00587 for(int i=0;i<NumGlyphs;i++)
00588 {
00589 in >> t;
00590 OffsetTable.push_back(t);
00591 }
00592 in >> t;
00593 CodeTableOffset=t;
00594 }
00595 GlyphShapeTable.resize(NumGlyphs);
00596 for(int i=0;i<NumGlyphs;i++)
00597 {
00598 in >> GlyphShapeTable[i];
00599 }
00600 for(int i=0;i<NumGlyphs;i++)
00601 {
00602 UI16 t;
00603 in >> t;
00604 CodeTable.push_back(t);
00605 }
00606 if(FontFlagsHasLayout)
00607 {
00608 in >> FontAscent >> FontDescent >> FontLeading;
00609
00610 for(int i=0;i<NumGlyphs;i++)
00611 {
00612 SI16 t;
00613 in >> t;
00614 FontAdvanceTable.push_back(t);
00615 }
00616 for(int i=0;i<NumGlyphs;i++)
00617 {
00618 RECT t;
00619 in >> t;
00620 FontBoundsTable.push_back(t);
00621 }
00622 in >> KerningCount;
00623 }
00624
00625 ignore(in,KerningCount*4);
00626 }
00627
00628 DefineBitsLosslessTag::DefineBitsLosslessTag(RECORDHEADER h, istream& in):DictionaryTag(h)
00629 {
00630 int dest=in.tellg();
00631 dest+=h.getLength();
00632 in >> CharacterId >> BitmapFormat >> BitmapWidth >> BitmapHeight;
00633
00634 if(BitmapFormat==3)
00635 in >> BitmapColorTableSize;
00636
00637
00638 ignore(in,dest-in.tellg());
00639 }
00640
00641 DefineBitsLossless2Tag::DefineBitsLossless2Tag(RECORDHEADER h, istream& in):DictionaryTag(h)
00642 {
00643 int dest=in.tellg();
00644 dest+=h.getLength();
00645 in >> CharacterId >> BitmapFormat >> BitmapWidth >> BitmapHeight;
00646
00647 if(BitmapFormat==3)
00648 in >> BitmapColorTableSize;
00649
00650
00651 ignore(in,dest-in.tellg());
00652 }
00653
00654 ASObject* DefineBitsLossless2Tag::instance() const
00655 {
00656 DefineBitsLossless2Tag* ret=new DefineBitsLossless2Tag(*this);
00657
00658 if(bindedTo)
00659 {
00660
00661 ret->setPrototype(bindedTo);
00662 }
00663 else
00664 ret->setPrototype(Class<Bitmap>::getClass());
00665 return ret;
00666 }
00667
00668 void DefineBitsLossless2Tag::Render()
00669 {
00670 LOG(LOG_NOT_IMPLEMENTED,_("DefineBitsLossless2Tag::Render"));
00671 }
00672
00673 DefineTextTag::DefineTextTag(RECORDHEADER h, istream& in):DictionaryTag(h)
00674 {
00675 in >> CharacterId >> TextBounds >> TextMatrix >> GlyphBits >> AdvanceBits;
00676 LOG(LOG_TRACE,_("DefineText ID ") << CharacterId);
00677
00678 TEXTRECORD t(this);
00679 while(1)
00680 {
00681 in >> t;
00682 if(t.TextRecordType+t.StyleFlagsHasFont+t.StyleFlagsHasColor+t.StyleFlagsHasYOffset+t.StyleFlagsHasXOffset==0)
00683 break;
00684 TextRecords.push_back(t);
00685 }
00686 }
00687
00688 void DefineTextTag::inputRender()
00689 {
00690 if(alpha==0)
00691 return;
00692 if(!visible)
00693 return;
00694 std::vector < TEXTRECORD >::iterator it=TextRecords.begin();
00695 if(it==TextRecords.end())
00696 return;
00697 std::vector < GLYPHENTRY >::iterator it2;
00698 int x=0,y=0;
00699
00700
00701 FILLSTYLE f;
00702 f.FillStyleType=0x00;
00703 f.Color=it->TextColor;
00704 MatrixApplier ma(getMatrix());
00705 ma.concat(TextMatrix);
00706
00707 glScalef(0.05,0.05,1);
00708
00709
00710 glScalef(0.05,0.05,1);
00711 float scale_cur=1;
00712 int count=0;
00713 unsigned int shapes_done=0;
00714 it= TextRecords.begin();
00715 for(;it!=TextRecords.end();it++)
00716 {
00717 if(it->StyleFlagsHasFont)
00718 {
00719 float scale=it->TextHeight;
00720 scale/=1024;
00721 glScalef(scale/scale_cur,scale/scale_cur,1);
00722 scale_cur=scale;
00723 }
00724 it2 = it->GlyphEntries.begin();
00725 int x2=x,y2=y;
00726 x2+=(*it).XOffset;
00727 y2+=(*it).YOffset;
00728
00729 for(;it2!=(it->GlyphEntries.end());it2++)
00730 {
00731 while(shapes_done<cached.size() && cached[shapes_done].id==count)
00732 {
00733 assert_and_throw(cached[shapes_done].color==1)
00734 cached[shapes_done].style=&f;
00735
00736 cached[shapes_done].Render(x2/scale_cur*20,y2/scale_cur*20);
00737 shapes_done++;
00738 if(shapes_done==cached.size())
00739 break;
00740 }
00741 x2+=it2->GlyphAdvance;
00742 count++;
00743 }
00744 }
00745 ma.unapply();
00746 }
00747
00748 void DefineTextTag::Render()
00749 {
00750 LOG(LOG_TRACE,_("DefineText Render"));
00751 if(alpha==0)
00752 return;
00753 if(!visible)
00754 return;
00755 if(cached.size()==0)
00756 {
00757 FontTag* font=NULL;
00758 int count=0;
00759 std::vector < TEXTRECORD >::iterator it= TextRecords.begin();
00760 std::vector < GLYPHENTRY >::iterator it2;
00761 for(;it!=TextRecords.end();it++)
00762 {
00763 if(it->StyleFlagsHasFont)
00764 {
00765 DictionaryTag* it3=loadedFrom->dictionaryLookup(it->FontID);
00766 font=dynamic_cast<FontTag*>(it3);
00767 if(font==NULL)
00768 LOG(LOG_ERROR,_("Should be a FontTag"));
00769 }
00770 it2 = it->GlyphEntries.begin();
00771 for(;it2!=(it->GlyphEntries.end());it2++)
00772 {
00773
00774 vector<GeomShape> new_shapes;
00775 font->genGlyphShape(new_shapes,it2->GlyphIndex);
00776 for(unsigned int i=0;i<new_shapes.size();i++)
00777 cached.push_back(GlyphShape(new_shapes[i],count));
00778
00779 count++;
00780 }
00781 }
00782 }
00783 std::vector < TEXTRECORD >::iterator it=TextRecords.begin();
00784 if(it==TextRecords.end())
00785 return;
00786 std::vector < GLYPHENTRY >::iterator it2;
00787 int x=0,y=0;
00788
00789
00790 FILLSTYLE f;
00791 f.FillStyleType=0x00;
00792 f.Color=it->TextColor;
00793 MatrixApplier ma(getMatrix());
00794 ma.concat(TextMatrix);
00795
00796 glScalef(0.05,0.05,1);
00797
00798 if(!isSimple())
00799 rt->glAcquireTempBuffer(TextBounds.Xmin,TextBounds.Xmax, TextBounds.Ymin,TextBounds.Ymax);
00800
00801
00802 glScalef(0.05,0.05,1);
00803 float scale_cur=1;
00804 int count=0;
00805 unsigned int shapes_done=0;
00806 for(;it!=TextRecords.end();it++)
00807 {
00808 if(it->StyleFlagsHasFont)
00809 {
00810 float scale=it->TextHeight;
00811 scale/=1024;
00812 glScalef(scale/scale_cur,scale/scale_cur,1);
00813 scale_cur=scale;
00814 }
00815 it2 = it->GlyphEntries.begin();
00816 int x2=x,y2=y;
00817 x2+=(*it).XOffset;
00818 y2+=(*it).YOffset;
00819
00820 for(;it2!=(it->GlyphEntries.end());it2++)
00821 {
00822 while(shapes_done<cached.size() && cached[shapes_done].id==count)
00823 {
00824 assert_and_throw(cached[shapes_done].color==1)
00825 cached[shapes_done].style=&f;
00826
00827 cached[shapes_done].Render(x2/scale_cur*20,y2/scale_cur*20);
00828 shapes_done++;
00829 if(shapes_done==cached.size())
00830 break;
00831 }
00832 x2+=it2->GlyphAdvance;
00833 count++;
00834 }
00835 }
00836
00837 if(!isSimple())
00838 rt->glBlitTempBuffer(TextBounds.Xmin,TextBounds.Xmax,TextBounds.Ymin,TextBounds.Ymax);
00839 ma.unapply();
00840 }
00841
00842 Vector2 DefineTextTag::debugRender(FTFont* font, bool deep)
00843 {
00844 assert(!deep);
00845 glColor3f(0,0.4,0.4);
00846 char buf[20];
00847 snprintf(buf,20,"Text id=%u",(int)CharacterId);
00848 font->Render(buf,-1,FTPoint(0,50));
00849 glBegin(GL_LINE_LOOP);
00850 glVertex2i(0,0);
00851 glVertex2i(100,0);
00852 glVertex2i(100,100);
00853 glVertex2i(0,100);
00854 glEnd();
00855 return Vector2(100,100);
00856 }
00857
00858 DefineShapeTag::DefineShapeTag(RECORDHEADER h, std::istream& in):DictionaryTag(h)
00859 {
00860 LOG(LOG_TRACE,_("DefineShapeTag"));
00861 Shapes.version=1;
00862 in >> ShapeId >> ShapeBounds >> Shapes;
00863 }
00864
00865 DefineShape2Tag::DefineShape2Tag(RECORDHEADER h, std::istream& in):DefineShapeTag(h)
00866 {
00867 LOG(LOG_TRACE,_("DefineShape2Tag"));
00868 Shapes.version=2;
00869 in >> ShapeId >> ShapeBounds >> Shapes;
00870 }
00871
00872 DefineShape3Tag::DefineShape3Tag(RECORDHEADER h, std::istream& in):DefineShape2Tag(h)
00873 {
00874 LOG(LOG_TRACE,_("DefineShape3Tag"));
00875 Shapes.version=3;
00876 in >> ShapeId >> ShapeBounds >> Shapes;
00877 }
00878
00879 DefineShape4Tag::DefineShape4Tag(RECORDHEADER h, std::istream& in):DefineShape3Tag(h)
00880 {
00881 LOG(LOG_TRACE,_("DefineShape4Tag"));
00882 Shapes.version=4;
00883 in >> ShapeId >> ShapeBounds >> EdgeBounds;
00884 BitStream bs(in);
00885 UB(5,bs);
00886 UsesFillWindingRule=UB(1,bs);
00887 UsesNonScalingStrokes=UB(1,bs);
00888 UsesScalingStrokes=UB(1,bs);
00889 in >> Shapes;
00890 }
00891
00892 DefineMorphShapeTag::DefineMorphShapeTag(RECORDHEADER h, std::istream& in):DictionaryTag(h)
00893 {
00894 int dest=in.tellg();
00895 dest+=h.getLength();
00896 in >> CharacterId >> StartBounds >> EndBounds >> Offset >> MorphFillStyles >> MorphLineStyles >> StartEdges >> EndEdges;
00897 if(in.tellg()<dest)
00898 ignore(in,dest-in.tellg());
00899 }
00900
00901 std::ostream& operator<<(std::ostream& s, const Vector2& p)
00902 {
00903 s << "{ "<< p.x << ',' << p.y << " }" << std::endl;
00904 return s;
00905 }
00906
00907 ASObject* DefineMorphShapeTag::instance() const
00908 {
00909 DefineMorphShapeTag* ret=new DefineMorphShapeTag(*this);
00910 assert_and_throw(bindedTo==NULL);
00911 ret->setPrototype(Class<MorphShape>::getClass());
00912 return ret;
00913 }
00914
00915 void DefineMorphShapeTag::Render()
00916 {
00917 if(alpha==0)
00918 return;
00919 if(!visible)
00920 return;
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950 }
00951
00952 void DefineShapeTag::inputRender()
00953 {
00954 if(alpha==0)
00955 return;
00956 if(!visible)
00957 return;
00958
00959 MatrixApplier ma(getMatrix());
00960 glScalef(0.05,0.05,1);
00961
00962 std::vector < GeomShape >::iterator it=cached.begin();
00963 for(;it!=cached.end();it++)
00964 {
00965 assert_and_throw(it->color <= Shapes.FillStyles.FillStyleCount);
00966 it->Render();
00967 }
00968 ma.unapply();
00969 }
00970
00971 void DefineShapeTag::Render()
00972 {
00973 if(alpha==0)
00974 return;
00975 if(!visible)
00976 return;
00977
00978 if(cached.size()==0)
00979 {
00980 FromShaperecordListToShapeVector(Shapes.ShapeRecords,cached);
00981
00982 for(unsigned int i=0;i<cached.size();i++)
00983 cached[i].BuildFromEdges(&Shapes.FillStyles.FillStyles);
00984 }
00985
00986 MatrixApplier ma(getMatrix());
00987 glScalef(0.05,0.05,1);
00988
00989 if(!isSimple())
00990 rt->glAcquireTempBuffer(ShapeBounds.Xmin,ShapeBounds.Xmax,ShapeBounds.Ymin,ShapeBounds.Ymax);
00991
00992 std::vector < GeomShape >::iterator it=cached.begin();
00993 for(;it!=cached.end();it++)
00994 {
00995 assert_and_throw(it->color <= Shapes.FillStyles.FillStyleCount);
00996 it->Render();
00997 }
00998
00999 if(!isSimple())
01000 rt->glBlitTempBuffer(ShapeBounds.Xmin,ShapeBounds.Xmax,ShapeBounds.Ymin,ShapeBounds.Ymax);
01001
01002 ma.unapply();
01003 }
01004
01005 Vector2 DefineShapeTag::debugRender(FTFont* font, bool deep)
01006 {
01007 assert(!deep);
01008 glColor3f(0,0,0.8);
01009 char buf[20];
01010 snprintf(buf,20,"Shape id=%u",(int)ShapeId);
01011 font->Render(buf,-1,FTPoint(0,50));
01012 glBegin(GL_LINE_LOOP);
01013 glVertex2i(0,0);
01014 glVertex2i(100,0);
01015 glVertex2i(100,100);
01016 glVertex2i(0,100);
01017 glEnd();
01018 return Vector2(100,100);
01019 }
01020
01021 Vector2 DefineShape2Tag::debugRender(FTFont* font, bool deep)
01022 {
01023 assert(!deep);
01024 glColor3f(0,0.8,0.8);
01025 char buf[20];
01026 snprintf(buf,20,"Shape2 id=%u",(int)ShapeId);
01027 font->Render(buf,-1,FTPoint(0,50));
01028 glBegin(GL_LINE_LOOP);
01029 glVertex2i(0,0);
01030 glVertex2i(100,0);
01031 glVertex2i(100,100);
01032 glVertex2i(0,100);
01033 glEnd();
01034 return Vector2(100,100);
01035 }
01036
01037 Vector2 DefineShape3Tag::debugRender(FTFont* font, bool deep)
01038 {
01039 assert(!deep);
01040 glColor3f(0.8,0,0.8);
01041 char buf[20];
01042 snprintf(buf,20,"Shape3 id=%u",(int)ShapeId);
01043 font->Render(buf,-1,FTPoint(0,50));
01044 glBegin(GL_LINE_LOOP);
01045 glVertex2i(0,0);
01046 glVertex2i(100,0);
01047 glVertex2i(100,100);
01048 glVertex2i(0,100);
01049 glEnd();
01050 return Vector2(100,100);
01051 }
01052
01057 void lightspark::FromShaperecordListToShapeVector(const vector<SHAPERECORD>& shapeRecords, vector<GeomShape>& shapes)
01058 {
01059 int startX=0;
01060 int startY=0;
01061 unsigned int color0=0;
01062 unsigned int color1=0;
01063
01064 ShapesBuilder shapesBuilder;
01065
01066 for(unsigned int i=0;i<shapeRecords.size();i++)
01067 {
01068 const SHAPERECORD* cur=&shapeRecords[i];
01069 if(cur->TypeFlag)
01070 {
01071 if(cur->StraightFlag)
01072 {
01073 Vector2 p1(startX,startY);
01074 startX+=cur->DeltaX;
01075 startY+=cur->DeltaY;
01076 Vector2 p2(startX,startY);
01077
01078 if(color0)
01079 shapesBuilder.extendOutlineForColor(color0,p1,p2);
01080 if(color1)
01081 shapesBuilder.extendOutlineForColor(color1,p1,p2);
01082 }
01083 else
01084 {
01085 Vector2 p1(startX,startY);
01086 startX+=cur->ControlDeltaX;
01087 startY+=cur->ControlDeltaY;
01088 Vector2 p2(startX,startY);
01089 startX+=cur->AnchorDeltaX;
01090 startY+=cur->AnchorDeltaY;
01091 Vector2 p3(startX,startY);
01092
01093 if(color0)
01094 {
01095 shapesBuilder.extendOutlineForColor(color0,p1,p2);
01096 shapesBuilder.extendOutlineForColor(color0,p2,p3);
01097 }
01098 if(color1)
01099 {
01100 shapesBuilder.extendOutlineForColor(color1,p1,p2);
01101 shapesBuilder.extendOutlineForColor(color1,p2,p3);
01102 }
01103 }
01104 }
01105 else
01106 {
01107 if(cur->StateMoveTo)
01108 {
01109 startX=cur->MoveDeltaX;
01110 startY=cur->MoveDeltaY;
01111 }
01112
01113
01114
01115
01116
01117 if(cur->StateFillStyle1)
01118 {
01119 color1=cur->FillStyle1;
01120 }
01121 if(cur->StateFillStyle0)
01122 {
01123 color0=cur->FillStyle0;
01124 }
01125 }
01126 }
01127
01128 shapesBuilder.outputShapes(shapes);
01129 }
01130
01131 void DefineFont3Tag::genGlyphShape(vector<GeomShape>& s, int glyph)
01132 {
01133 SHAPE& shape=GlyphShapeTable[glyph];
01134 FromShaperecordListToShapeVector(shape.ShapeRecords,s);
01135
01136 for(unsigned int i=0;i<s.size();i++)
01137 s[i].BuildFromEdges(NULL);
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169 }
01170
01171 void DefineFont2Tag::genGlyphShape(vector<GeomShape>& s, int glyph)
01172 {
01173 SHAPE& shape=GlyphShapeTable[glyph];
01174 FromShaperecordListToShapeVector(shape.ShapeRecords,s);
01175
01176 for(unsigned int i=0;i<s.size();i++)
01177 s[i].BuildFromEdges(NULL);
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209 }
01210
01211 void DefineFontTag::genGlyphShape(vector<GeomShape>& s,int glyph)
01212 {
01213 SHAPE& shape=GlyphShapeTable[glyph];
01214 FromShaperecordListToShapeVector(shape.ShapeRecords,s);
01215
01216 for(unsigned int i=0;i<s.size();i++)
01217 s[i].BuildFromEdges(NULL);
01218
01219
01220 }
01221
01222 ShowFrameTag::ShowFrameTag(RECORDHEADER h, std::istream& in):Tag(h)
01223 {
01224 LOG(LOG_TRACE,_("ShowFrame"));
01225 }
01226
01227 bool PlaceObject2Tag::list_orderer::operator ()(const pair<PlaceInfo, DisplayObject*>& a, int d)
01228 {
01229 return a.second->Depth<d;
01230 }
01231
01232 bool PlaceObject2Tag::list_orderer::operator ()(int d, const pair<PlaceInfo, DisplayObject*>& a)
01233 {
01234 return d<a.second->Depth;
01235 }
01236
01237 bool PlaceObject2Tag::list_orderer::operator ()(const std::pair<PlaceInfo, DisplayObject*>& a, const std::pair<PlaceInfo, DisplayObject*>& b)
01238 {
01239 return a.second->Depth < b.second->Depth;
01240 }
01241
01242 void PlaceObject2Tag::execute(MovieClip* parent, list < pair< PlaceInfo, DisplayObject*> >& ls)
01243 {
01244
01245 if(ClipDepth!=0)
01246 return;
01247
01248 PlaceInfo infos;
01249
01250 list < pair<PlaceInfo, DisplayObject*> >::iterator it=ls.begin();
01251 for(;it!=ls.end();it++)
01252 {
01253 if(it->second->Depth==Depth)
01254 {
01255 infos=it->first;
01256 if(!PlaceFlagMove)
01257 throw ParseException("Depth already used already on displaylist");
01258 break;
01259 }
01260 }
01261
01262 if(PlaceFlagHasMatrix)
01263 infos.Matrix=Matrix;
01264
01265 DisplayObject* toAdd=NULL;
01266 if(PlaceFlagHasCharacter)
01267 {
01268
01269
01270
01271 LOG(LOG_TRACE,_("Placing ID ") << CharacterId);
01272 RootMovieClip* localRoot=NULL;
01273 DictionaryTag* parentDict=dynamic_cast<DictionaryTag*>(parent);
01274 if(parentDict)
01275 localRoot=parentDict->loadedFrom;
01276 else
01277 localRoot=parent->getRoot();
01278 DictionaryTag* dict=localRoot->dictionaryLookup(CharacterId);
01279 toAdd=dynamic_cast<DisplayObject*>(dict->instance());
01280 assert_and_throw(toAdd);
01281
01282
01283 if(toAdd->getPrototype() && sys->currentVm)
01284 {
01285
01286 if(PlaceFlagHasMatrix)
01287 toAdd->setMatrix(Matrix);
01288
01289 ConstructObjectEvent* e=new ConstructObjectEvent(toAdd,toAdd->getPrototype());
01290 bool added=sys->currentVm->addEvent(NULL,e);
01291 if(!added)
01292 {
01293 e->decRef();
01294 throw RunTimeException("Could not add event");
01295 }
01296 e->wait();
01297 e->decRef();
01298 }
01299
01300 if(PlaceFlagHasColorTransform)
01301 toAdd->ColorTransform=ColorTransform;
01302
01303 if(PlaceFlagHasRatio)
01304 toAdd->Ratio=Ratio;
01305
01306 if(PlaceFlagHasClipDepth)
01307 toAdd->ClipDepth=ClipDepth;
01308
01309 toAdd->setRoot(parent->getRoot());
01310 toAdd->Depth=Depth;
01311 if(!PlaceFlagMove)
01312 {
01313 list<pair<PlaceInfo, DisplayObject*> >::iterator it=
01314 lower_bound< list<pair<PlaceInfo, DisplayObject*> >::iterator, int, list_orderer>
01315 (ls.begin(),ls.end(),Depth,list_orderer());
01316
01317 toAdd->incRef();
01318 ls.insert(it,make_pair(infos,toAdd));
01319 }
01320 }
01321
01322 if(PlaceFlagHasName)
01323 {
01324
01325 LOG(LOG_NO_INFO,_("Registering ID ") << CharacterId << _(" with name ") << Name);
01326 if(!PlaceFlagMove)
01327 {
01328 assert_and_throw(toAdd);
01329 toAdd->incRef();
01330 parent->setVariableByQName((const char*)Name,"",toAdd);
01331 }
01332 else
01333 LOG(LOG_ERROR, _("Moving of registered objects not really supported"));
01334 }
01335
01336
01337 if(PlaceFlagMove)
01338 {
01339 if(it!=ls.end())
01340 {
01341 if(!PlaceFlagHasCharacter)
01342 {
01343
01344 if(PlaceFlagHasColorTransform)
01345 it->second->ColorTransform=ColorTransform;
01346
01347 if(PlaceFlagHasRatio)
01348 it->second->Ratio=Ratio;
01349
01350 if(PlaceFlagHasClipDepth)
01351 it->second->ClipDepth=ClipDepth;
01352 it->first=infos;
01353 }
01354 else
01355 {
01356 it->second->decRef();
01357 ls.erase(it);
01358 list<pair<PlaceInfo, DisplayObject*> >::iterator it=lower_bound(ls.begin(),ls.end(),Depth,list_orderer());
01359 toAdd->incRef();
01360 ls.insert(it,make_pair(infos,toAdd));
01361 }
01362 }
01363 else
01364 LOG(LOG_ERROR,_("no char to move at depth ") << Depth << _(" name ") << Name);
01365 }
01366
01367 if(toAdd)
01368 toAdd->decRef();
01369 }
01370
01371 PlaceObject2Tag::PlaceObject2Tag(RECORDHEADER h, std::istream& in):DisplayListTag(h)
01372 {
01373 LOG(LOG_TRACE,_("PlaceObject2"));
01374
01375 BitStream bs(in);
01376 PlaceFlagHasClipAction=UB(1,bs);
01377 PlaceFlagHasClipDepth=UB(1,bs);
01378 PlaceFlagHasName=UB(1,bs);
01379 PlaceFlagHasRatio=UB(1,bs);
01380 PlaceFlagHasColorTransform=UB(1,bs);
01381 PlaceFlagHasMatrix=UB(1,bs);
01382 PlaceFlagHasCharacter=UB(1,bs);
01383 PlaceFlagMove=UB(1,bs);
01384 in >> Depth;
01385 if(PlaceFlagHasCharacter)
01386 in >> CharacterId;
01387
01388 if(PlaceFlagHasMatrix)
01389 in >> Matrix;
01390
01391 if(PlaceFlagHasColorTransform)
01392 in >> ColorTransform;
01393
01394 if(PlaceFlagHasRatio)
01395 in >> Ratio;
01396
01397 if(PlaceFlagHasName)
01398 in >> Name;
01399
01400 if(PlaceFlagHasClipDepth)
01401 in >> ClipDepth;
01402
01403 if(PlaceFlagHasClipAction)
01404 in >> ClipActions;
01405
01406 assert_and_throw(!(PlaceFlagHasCharacter && CharacterId==0))
01407 }
01408
01409 void PlaceObject3Tag::execute(MovieClip* parent, list < pair< PlaceInfo, DisplayObject*> >& ls)
01410 {
01411
01412 if(ClipDepth!=0)
01413 return;
01414
01415 PlaceInfo infos;
01416
01417 list < pair<PlaceInfo, DisplayObject*> >::iterator it=ls.begin();
01418 for(;it!=ls.end();it++)
01419 {
01420 if(it->second->Depth==Depth)
01421 {
01422 infos=it->first;
01423 if(!PlaceFlagMove)
01424 throw ParseException("Depth already used already on displaylist");
01425 break;
01426 }
01427 }
01428
01429 if(PlaceFlagHasMatrix)
01430 infos.Matrix=Matrix;
01431
01432 DisplayObject* toAdd=NULL;
01433 if(PlaceFlagHasCharacter)
01434 {
01435
01436
01437
01438 LOG(LOG_TRACE,_("Placing ID ") << CharacterId);
01439 RootMovieClip* localRoot=NULL;
01440 DictionaryTag* parentDict=dynamic_cast<DictionaryTag*>(parent);
01441 if(parentDict)
01442 localRoot=parentDict->loadedFrom;
01443 else
01444 localRoot=parent->getRoot();
01445 DictionaryTag* dict=localRoot->dictionaryLookup(CharacterId);
01446 toAdd=dynamic_cast<DisplayObject*>(dict->instance());
01447 assert_and_throw(toAdd);
01448
01449
01450 if(toAdd->getPrototype() && sys->currentVm)
01451 {
01452
01453 if(PlaceFlagHasMatrix)
01454 toAdd->setMatrix(Matrix);
01455
01456 ConstructObjectEvent* e=new ConstructObjectEvent(toAdd,toAdd->getPrototype());
01457 bool added=sys->currentVm->addEvent(NULL,e);
01458 if(!added)
01459 {
01460 e->decRef();
01461 throw RunTimeException("Could not add event");
01462 }
01463 e->wait();
01464 e->decRef();
01465 }
01466
01467 if(PlaceFlagHasColorTransform)
01468 toAdd->ColorTransform=ColorTransform;
01469
01470 if(PlaceFlagHasRatio)
01471 toAdd->Ratio=Ratio;
01472
01473 if(PlaceFlagHasClipDepth)
01474 toAdd->ClipDepth=ClipDepth;
01475
01476 toAdd->setRoot(parent->getRoot());
01477 toAdd->Depth=Depth;
01478 if(!PlaceFlagMove)
01479 {
01480 list<pair<PlaceInfo, DisplayObject*> >::iterator it=
01481 lower_bound< list<pair<PlaceInfo, DisplayObject*> >::iterator, int, list_orderer>
01482 (ls.begin(),ls.end(),Depth,list_orderer());
01483
01484 toAdd->incRef();
01485 ls.insert(it,make_pair(infos,toAdd));
01486 }
01487 }
01488
01489 if(PlaceFlagHasName)
01490 {
01491
01492 LOG(LOG_NO_INFO,_("Registering ID ") << CharacterId << _(" with name ") << Name);
01493 if(!PlaceFlagMove)
01494 {
01495 assert_and_throw(toAdd);
01496 toAdd->incRef();
01497 parent->setVariableByQName((const char*)Name,"",toAdd);
01498 }
01499 else
01500 LOG(LOG_ERROR, _("Moving of registered objects not really supported"));
01501 }
01502
01503
01504 if(PlaceFlagMove)
01505 {
01506 if(it!=ls.end())
01507 {
01508 if(!PlaceFlagHasCharacter)
01509 {
01510
01511 if(PlaceFlagHasColorTransform)
01512 it->second->ColorTransform=ColorTransform;
01513
01514 if(PlaceFlagHasRatio)
01515 it->second->Ratio=Ratio;
01516
01517 if(PlaceFlagHasClipDepth)
01518 it->second->ClipDepth=ClipDepth;
01519 it->first=infos;
01520 }
01521 else
01522 {
01523 it->second->decRef();
01524 ls.erase(it);
01525 list<pair<PlaceInfo, DisplayObject*> >::iterator it=lower_bound(ls.begin(),ls.end(),Depth,list_orderer());
01526 toAdd->incRef();
01527 ls.insert(it,make_pair(infos,toAdd));
01528 }
01529 }
01530 else
01531 LOG(LOG_ERROR,_("no char to move at depth ") << Depth << _(" name ") << Name);
01532 }
01533
01534 if(toAdd)
01535 toAdd->decRef();
01536 }
01537
01538 PlaceObject3Tag::PlaceObject3Tag(RECORDHEADER h, std::istream& in):PlaceObject2Tag(h)
01539 {
01540 LOG(LOG_TRACE,_("PlaceObject3"));
01541
01542 BitStream bs(in);
01543 PlaceFlagHasClipAction=UB(1,bs);
01544 PlaceFlagHasClipDepth=UB(1,bs);
01545 PlaceFlagHasName=UB(1,bs);
01546 PlaceFlagHasRatio=UB(1,bs);
01547 PlaceFlagHasColorTransform=UB(1,bs);
01548 PlaceFlagHasMatrix=UB(1,bs);
01549 PlaceFlagHasCharacter=UB(1,bs);
01550 PlaceFlagMove=UB(1,bs);
01551 UB(3,bs);
01552 PlaceFlagHasImage=UB(1,bs);
01553 PlaceFlagHasClassName=UB(1,bs);
01554 PlaceFlagHasCacheAsBitmap=UB(1,bs);
01555 PlaceFlagHasBlendMode=UB(1,bs);
01556 PlaceFlagHasFilterList=UB(1,bs);
01557
01558 in >> Depth;
01559 if(PlaceFlagHasClassName || (PlaceFlagHasImage && PlaceFlagHasCharacter))
01560 throw ParseException("ClassName in PlaceObject3 not yet supported");
01561
01562 if(PlaceFlagHasCharacter)
01563 in >> CharacterId;
01564
01565 if(PlaceFlagHasMatrix)
01566 in >> Matrix;
01567
01568 if(PlaceFlagHasColorTransform)
01569 in >> ColorTransform;
01570
01571 if(PlaceFlagHasRatio)
01572 in >> Ratio;
01573
01574 if(PlaceFlagHasName)
01575 in >> Name;
01576
01577 if(PlaceFlagHasClipDepth)
01578 in >> ClipDepth;
01579
01580 if(PlaceFlagHasFilterList)
01581 in >> SurfaceFilterList;
01582
01583 if(PlaceFlagHasBlendMode)
01584 in >> BlendMode;
01585
01586 if(PlaceFlagHasCacheAsBitmap)
01587 in >> BitmapCache;
01588
01589 if(PlaceFlagHasClipAction)
01590 in >> ClipActions;
01591
01592 assert_and_throw(!(PlaceFlagHasCharacter && CharacterId==0))
01593 }
01594
01595 void SetBackgroundColorTag::execute(RootMovieClip* root)
01596 {
01597 root->setBackground(BackgroundColor);
01598 }
01599
01600 ProductInfoTag::ProductInfoTag(RECORDHEADER h, std::istream& in):Tag(h)
01601 {
01602 LOG(LOG_TRACE,_("ProductInfoTag Tag"));
01603
01604 in >> ProductId >> Edition >> MajorVersion >> MinorVersion >>
01605 MinorBuild >> MajorBuild >> CompileTimeLo >> CompileTimeHi;
01606
01607 uint64_t longlongTime = CompileTimeHi;
01608 longlongTime<<=32;
01609 longlongTime|=CompileTimeLo;
01610
01611 LOG(LOG_NO_INFO,_("SWF Info:") <<
01612 endl << "\tProductId: " << ProductId <<
01613 endl << "\tEdition: " << Edition <<
01614 endl << "\tVersion: " << UI32(MajorVersion) << "." << UI32(MinorVersion) << "." << MajorBuild << "." << MinorBuild <<
01615 endl << "\tCompileTime: " << longlongTime);
01616 }
01617
01618 FrameLabelTag::FrameLabelTag(RECORDHEADER h, std::istream& in):Tag(h)
01619 {
01620 in >> Name;
01621 if(pt->version>=6)
01622 {
01623 UI8 NamedAnchor=in.peek();
01624 if(NamedAnchor==1)
01625 in >> NamedAnchor;
01626 }
01627 }
01628
01629 DefineButton2Tag::DefineButton2Tag(RECORDHEADER h, std::istream& in):DictionaryTag(h),IdleToOverUp(false)
01630 {
01631 state=BUTTON_UP;
01632 in >> ButtonId;
01633 BitStream bs(in);
01634 UB(7,bs);
01635 TrackAsMenu=UB(1,bs);
01636 in >> ActionOffset;
01637
01638 BUTTONRECORD br(2);
01639
01640 do
01641 {
01642 in >> br;
01643 Characters.push_back(br);
01644 }
01645 while(!br.isNull());
01646
01647 if(ActionOffset)
01648 {
01649 BUTTONCONDACTION bca;
01650 do
01651 {
01652 in >> bca;
01653 Actions.push_back(bca);
01654 }
01655 while(!bca.isLast());
01656 }
01657 }
01658
01659 ASObject* DefineButton2Tag::instance() const
01660 {
01661 return new DefineButton2Tag(*this);
01662 }
01663
01664 void DefineButton2Tag::handleEvent(Event* e)
01665 {
01666 state=BUTTON_OVER;
01667 IdleToOverUp=true;
01668 }
01669
01670 void DefineButton2Tag::Render()
01671 {
01672 LOG(LOG_NOT_IMPLEMENTED,_("DefineButton2Tag::Render"));
01673 if(alpha==0)
01674 return;
01675 if(!visible)
01676 return;
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710 }
01711
01712 Vector2 DefineButton2Tag::debugRender(FTFont* font, bool deep)
01713 {
01714 assert(!deep);
01715 glColor3f(0.8,0.8,0.8);
01716 char buf[20];
01717 snprintf(buf,20,"Button2 id=%u",(int)CharacterId);
01718 font->Render(buf,-1,FTPoint(0,50));
01719 glBegin(GL_LINE_LOOP);
01720 glVertex2i(0,0);
01721 glVertex2i(100,0);
01722 glVertex2i(100,100);
01723 glVertex2i(0,100);
01724 glEnd();
01725 return Vector2(100,100);
01726 }
01727
01728 DefineVideoStreamTag::DefineVideoStreamTag(RECORDHEADER h, std::istream& in):DictionaryTag(h)
01729 {
01730 LOG(LOG_NO_INFO,_("DefineVideoStreamTag"));
01731 in >> CharacterID >> NumFrames >> Width >> Height;
01732 BitStream bs(in);
01733 UB(4,bs);
01734 VideoFlagsDeblocking=UB(3,bs);
01735 VideoFlagsSmoothing=UB(1,bs);
01736 in >> CodecID;
01737 }
01738
01739 void DefineVideoStreamTag::Render()
01740 {
01741 LOG(LOG_NO_INFO,_("DefineVideoStreamTag Render"));
01742
01743
01744
01745
01746 glColor4f(1,0,0,0);
01747 glBegin(GL_QUADS);
01748 glVertex2i(0,0);
01749 glVertex2i(Width,0);
01750 glVertex2i(Width,Height);
01751 glVertex2i(0,Height);
01752 glEnd();
01753 }
01754
01755 DefineBinaryDataTag::DefineBinaryDataTag(RECORDHEADER h,std::istream& s):DictionaryTag(h)
01756 {
01757 LOG(LOG_TRACE,_("DefineBinaryDataTag"));
01758 int size=h.getLength();
01759 s >> Tag >> Reserved;
01760 size -= sizeof(Tag)+sizeof(Reserved);
01761 bytes=new uint8_t[size];
01762 len=size;
01763 s.read((char*)bytes,size);
01764 }
01765
01766 FileAttributesTag::FileAttributesTag(RECORDHEADER h, std::istream& in):Tag(h)
01767 {
01768 LOG(LOG_TRACE,_("FileAttributesTag Tag"));
01769 BitStream bs(in);
01770 UB(1,bs);
01771 UseDirectBlit=UB(1,bs);
01772 UseGPU=UB(1,bs);
01773 HasMetadata=UB(1,bs);
01774 ActionScript3=UB(1,bs);
01775 UB(2,bs);
01776 UseNetwork=UB(1,bs);
01777 UB(24,bs);
01778
01779 if(ActionScript3)
01780 pt->useAVM2=true;
01781 }
01782
01783 DefineSoundTag::DefineSoundTag(RECORDHEADER h, std::istream& in):DictionaryTag(h)
01784 {
01785 LOG(LOG_TRACE,_("DefineSound Tag"));
01786 in >> SoundId;
01787 BitStream bs(in);
01788 SoundFormat=UB(4,bs);
01789 SoundRate=UB(2,bs);
01790 SoundSize=UB(1,bs);
01791 SoundType=UB(1,bs);
01792 in >> SoundSampleCount;
01793
01794 ignore(in,h.getLength()-7);
01795 }
01796
01797 ASObject* DefineSoundTag::instance() const
01798 {
01799 DefineSoundTag* ret=new DefineSoundTag(*this);
01800
01801 if(bindedTo)
01802 {
01803
01804 ret->setPrototype(bindedTo);
01805 }
01806 else
01807 ret->setPrototype(Class<Sound>::getClass());
01808 return ret;
01809 }
01810
01811 ScriptLimitsTag::ScriptLimitsTag(RECORDHEADER h, std::istream& in):Tag(h)
01812 {
01813 LOG(LOG_TRACE,_("ScriptLimitsTag Tag"));
01814 in >> MaxRecursionDepth >> ScriptTimeoutSeconds;
01815 LOG(LOG_NO_INFO,_("MaxRecusionDepth: ") << MaxRecursionDepth << _(", ScriptTimeoutSeconds: ") << ScriptTimeoutSeconds);
01816 }
01817
01818 DebugIDTag::DebugIDTag(RECORDHEADER h, std::istream& in):Tag(h)
01819 {
01820 LOG(LOG_TRACE,_("DebugIDTag Tag"));
01821 for(int i = 0; i < 16; i++)
01822 in >> DebugId[i];
01823
01824
01825 LOG(LOG_NO_INFO,_("DebugId ") << hex <<
01826 UI32(DebugId[0]) << UI32(DebugId[1]) << UI32(DebugId[2]) << UI32(DebugId[3]) << "-" <<
01827 UI32(DebugId[4]) << UI32(DebugId[5]) << "-" <<
01828 UI32(DebugId[6]) << UI32(DebugId[7]) << "-" <<
01829 UI32(DebugId[8]) << UI32(DebugId[9]) << "-" <<
01830 UI32(DebugId[10]) << UI32(DebugId[11]) << UI32(DebugId[12]) << UI32(DebugId[13]) << UI32(DebugId[14]) << UI32(DebugId[15]) <<
01831 dec);
01832 }
01833
01834 EnableDebuggerTag::EnableDebuggerTag(RECORDHEADER h, std::istream& in):Tag(h)
01835 {
01836 LOG(LOG_TRACE,_("EnableDebuggerTag Tag"));
01837 DebugPassword = "";
01838 if(h.getLength() > 0)
01839 in >> DebugPassword;
01840 LOG(LOG_NO_INFO,_("Debugger enabled, password: ") << DebugPassword);
01841 }
01842
01843 EnableDebugger2Tag::EnableDebugger2Tag(RECORDHEADER h, std::istream& in):Tag(h)
01844 {
01845 LOG(LOG_TRACE,_("EnableDebugger2Tag Tag"));
01846 in >> ReservedWord;
01847
01848 DebugPassword = "";
01849 if(h.getLength() > sizeof(ReservedWord))
01850 in >> DebugPassword;
01851 LOG(LOG_NO_INFO,_("Debugger enabled, reserved: ") << ReservedWord << _(", password: ") << DebugPassword);
01852 }
01853
01854 MetadataTag::MetadataTag(RECORDHEADER h, std::istream& in):Tag(h)
01855 {
01856 LOG(LOG_TRACE,_("MetadataTag Tag"));
01857 in >> XmlString;
01858 LOG(LOG_NO_INFO,_("MetaData: ") << XmlString);
01859 }