Program: 61481
Project: 61481
Buggy source:
public void createAndShowTempSwf(TreeItem tagObj){
  SWF swf=null;
  try {
    if (tempFile != null) {
      tempFile.delete();
    }
    tempFile=File.createTempFile("String_Node_Str","String_Node_Str");
    tempFile.deleteOnExit();
    Color backgroundColor=View.getSwfBackgroundColor();
    if (tagObj instanceof Tag) {
      Tag tag=(Tag)tagObj;
      swf=tag.getSwf();
      if (tag instanceof FontTag) {
        backgroundColor=View.getDefaultBackgroundColor();
      }
    }
 else     if (tagObj instanceof Frame) {
      Frame fn=(Frame)tagObj;
      swf=fn.getSwf();
      if (fn.timeline.timelined == swf) {
        for (        Tag t : swf.tags) {
          if (t instanceof SetBackgroundColorTag) {
            backgroundColor=((SetBackgroundColorTag)t).backgroundColor.toColor();
            break;
          }
        }
      }
    }
    int frameCount=1;
    float frameRate=swf.frameRate;
    HashMap<Integer,VideoFrameTag> videoFrames=new HashMap<>();
    if (tagObj instanceof DefineVideoStreamTag) {
      DefineVideoStreamTag vs=(DefineVideoStreamTag)tagObj;
      SWF.populateVideoFrames(vs.getCharacterId(),swf.tags,videoFrames);
      frameCount=videoFrames.size();
    }
    List<SoundStreamBlockTag> soundFrames=new ArrayList<>();
    if (tagObj instanceof SoundStreamHeadTypeTag) {
      soundFrames=((SoundStreamHeadTypeTag)tagObj).getBlocks();
      frameCount=soundFrames.size();
    }
    if ((tagObj instanceof DefineMorphShapeTag) || (tagObj instanceof DefineMorphShape2Tag)) {
      frameRate=MainPanel.MORPH_SHAPE_ANIMATION_FRAME_RATE;
      frameCount=(int)(MainPanel.MORPH_SHAPE_ANIMATION_LENGTH * frameRate);
    }
    if (tagObj instanceof DefineSoundTag) {
      frameCount=1;
    }
    if (tagObj instanceof DefineSpriteTag) {
      frameCount=((DefineSpriteTag)tagObj).frameCount;
    }
    byte[] data;
    try (ByteArrayOutputStream baos=new ByteArrayOutputStream()){
      SWFOutputStream sos2=new SWFOutputStream(baos,SWF.DEFAULT_VERSION);
      RECT outrect=new RECT(swf.displayRect);
      if (tagObj instanceof FontTag) {
        outrect.Xmin=0;
        outrect.Ymin=0;
        outrect.Xmax=FontTag.PREVIEWSIZE * 20;
        outrect.Ymax=FontTag.PREVIEWSIZE * 20;
      }
      int width=outrect.getWidth();
      int height=outrect.getHeight();
      sos2.writeRECT(outrect);
      sos2.writeFIXED8(frameRate);
      sos2.writeUI16(frameCount);
      new SetBackgroundColorTag(swf,new RGB(backgroundColor)).writeTag(sos2);
      if (tagObj instanceof Frame) {
        Frame fn=(Frame)tagObj;
        Timelined parent=fn.timeline.timelined;
        List<Tag> subs=fn.timeline.tags;
        List<Integer> doneCharacters=new ArrayList<>();
        int frameCnt=0;
        for (        Tag t : subs) {
          if (t instanceof ShowFrameTag) {
            frameCnt++;
            continue;
          }
          if (frameCnt > fn.frame) {
            break;
          }
          if (t instanceof DoActionTag || t instanceof DoInitActionTag) {
            continue;
          }
          Set<Integer> needed=new HashSet<>();
          t.getNeededCharactersDeep(needed);
          for (          int n : needed) {
            if (!doneCharacters.contains(n)) {
              classicTag(swf.getCharacter(n)).writeTag(sos2);
              doneCharacters.add(n);
            }
          }
          if (t instanceof CharacterTag) {
            int characterId=((CharacterTag)t).getCharacterId();
            if (!doneCharacters.contains(characterId)) {
              doneCharacters.add(((CharacterTag)t).getCharacterId());
            }
          }
          classicTag(t).writeTag(sos2);
          if (parent != null) {
            if (t instanceof PlaceObjectTypeTag) {
              PlaceObjectTypeTag pot=(PlaceObjectTypeTag)t;
              int chid=pot.getCharacterId();
              int depth=pot.getDepth();
              MATRIX mat=pot.getMatrix();
              if (mat == null) {
                mat=new MATRIX();
              }
              mat=Helper.deepCopy(mat);
              RECT r=parent.getRect();
              mat.translateX+=width / 2 - r.getWidth() / 2;
              mat.translateY+=height / 2 - r.getHeight() / 2;
              new PlaceObject2Tag(swf,false,false,false,false,false,true,false,true,depth,chid,mat,null,0,null,0,null).writeTag(sos2);
            }
          }
        }
        new ShowFrameTag(swf).writeTag(sos2);
      }
 else {
        boolean isSprite=false;
        if (tagObj instanceof DefineSpriteTag) {
          isSprite=true;
        }
        int chtId=0;
        if (tagObj instanceof CharacterTag) {
          chtId=((CharacterTag)tagObj).getCharacterId();
        }
        if (tagObj instanceof DefineBitsTag) {
          JPEGTablesTag jtt=swf.getJtt();
          if (jtt != null) {
            jtt.writeTag(sos2);
          }
        }
 else         if (tagObj instanceof AloneTag) {
        }
 else {
          Set<Integer> needed=new HashSet<>();
          ((Tag)tagObj).getNeededCharactersDeep(needed);
          for (          int n : needed) {
            if (isSprite && chtId == n) {
              continue;
            }
            CharacterTag characterTag=swf.getCharacter(n);
            if (characterTag instanceof DefineBitsTag) {
              JPEGTablesTag jtt=swf.getJtt();
              if (jtt != null) {
                jtt.writeTag(sos2);
              }
            }
            classicTag(characterTag).writeTag(sos2);
          }
        }
        classicTag((Tag)tagObj).writeTag(sos2);
        MATRIX mat=new MATRIX();
        mat.hasRotate=false;
        mat.hasScale=false;
        mat.translateX=0;
        mat.translateY=0;
        if (tagObj instanceof BoundedTag) {
          RECT r=((BoundedTag)tagObj).getRect();
          mat.translateX=-r.Xmin;
          mat.translateY=-r.Ymin;
          mat.translateX=mat.translateX + width / 2 - r.getWidth() / 2;
          mat.translateY=mat.translateY + height / 2 - r.getHeight() / 2;
        }
 else {
          mat.translateX=width / 4;
          mat.translateY=height / 4;
        }
        if (tagObj instanceof FontTag) {
          FontTag ft=(FontTag)classicTag((Tag)tagObj);
          int countGlyphsTotal=ft.getGlyphShapeTable().size();
          int countGlyphs=Math.min(SHAPERECORD.MAX_CHARACTERS_IN_FONT_PREVIEW,countGlyphsTotal);
          int fontId=ft.getFontId();
          int cols=(int)Math.ceil(Math.sqrt(countGlyphs));
          int rows=(int)Math.ceil(((float)countGlyphs) / ((float)cols));
          if (rows == 0) {
            rows=1;
            cols=1;
          }
          int x=0;
          int y=0;
          int firstGlyphIndex=fontPageNum * SHAPERECORD.MAX_CHARACTERS_IN_FONT_PREVIEW;
          countGlyphs=Math.min(SHAPERECORD.MAX_CHARACTERS_IN_FONT_PREVIEW,countGlyphsTotal - firstGlyphIndex);
          List<SHAPE> shapes=ft.getGlyphShapeTable();
          int maxw=0;
          for (int f=firstGlyphIndex; f < firstGlyphIndex + countGlyphs; f++) {
            RECT b=shapes.get(f).getBounds();
            if (b.Xmin == Integer.MAX_VALUE) {
              continue;
            }
            if (b.Ymin == Integer.MAX_VALUE) {
              continue;
            }
            int w=(int)(b.getWidth() / ft.getDivider());
            if (w > maxw) {
              maxw=w;
            }
            x++;
          }
          x=0;
          int BORDER=3 * 20;
          int textHeight=height / rows;
          while (maxw * textHeight / 1024.0 > width / cols - 2 * BORDER) {
            textHeight--;
          }
          MATRIX tmat=new MATRIX();
          for (int f=firstGlyphIndex; f < firstGlyphIndex + countGlyphs; f++) {
            if (x >= cols) {
              x=0;
              y++;
            }
            List<TEXTRECORD> rec=new ArrayList<>();
            TEXTRECORD tr=new TEXTRECORD();
            RECT b=shapes.get(f).getBounds();
            int xmin=b.Xmin == Integer.MAX_VALUE ? 0 : (int)(b.Xmin / ft.getDivider());
            xmin*=textHeight / 1024.0;
            int ymin=b.Ymin == Integer.MAX_VALUE ? 0 : (int)(b.Ymin / ft.getDivider());
            ymin*=textHeight / 1024.0;
            int w=(int)(b.getWidth() / ft.getDivider());
            w*=textHeight / 1024.0;
            int h=(int)(b.getHeight() / ft.getDivider());
            h*=textHeight / 1024.0;
            tr.fontId=fontId;
            tr.styleFlagsHasFont=true;
            tr.textHeight=textHeight;
            tr.xOffset=-xmin;
            tr.yOffset=0;
            tr.styleFlagsHasXOffset=true;
            tr.styleFlagsHasYOffset=true;
            tr.glyphEntries=new ArrayList<>(1);
            tr.styleFlagsHasColor=true;
            tr.textColor=new RGB(0,0,0);
            GLYPHENTRY ge=new GLYPHENTRY();
            double ga=ft.getGlyphAdvance(f);
            int cw=ga == -1 ? w : (int)(ga / ft.getDivider() * textHeight / 1024.0);
            ge.glyphAdvance=0;
            ge.glyphIndex=f;
            tr.glyphEntries.add(ge);
            rec.add(tr);
            tmat.translateX=x * width / cols + width / cols / 2 - w / 2;
            tmat.translateY=y * height / rows + height / rows / 2;
            new DefineTextTag(swf,999 + f,new RECT(0,cw,ymin,ymin + h),new MATRIX(),rec).writeTag(sos2);
            new PlaceObject2Tag(swf,false,false,false,true,false,true,true,false,1 + f,999 + f,tmat,null,0,null,0,null).writeTag(sos2);
            x++;
          }
          new ShowFrameTag(swf).writeTag(sos2);
        }
 else         if ((tagObj instanceof DefineMorphShapeTag) || (tagObj instanceof DefineMorphShape2Tag)) {
          new PlaceObject2Tag(swf,false,false,false,true,false,true,true,false,1,chtId,mat,null,0,null,0,null).writeTag(sos2);
          new ShowFrameTag(swf).writeTag(sos2);
          for (int ratio=0; ratio < 65536; ratio+=65536 / frameCount) {
            new PlaceObject2Tag(swf,false,false,false,true,false,true,false,true,1,chtId,mat,null,ratio,null,0,null).writeTag(sos2);
            new ShowFrameTag(swf).writeTag(sos2);
          }
        }
 else         if (tagObj instanceof SoundStreamHeadTypeTag) {
          for (          SoundStreamBlockTag blk : soundFrames) {
            blk.writeTag(sos2);
            new ShowFrameTag(swf).writeTag(sos2);
          }
        }
 else         if (tagObj instanceof DefineSoundTag) {
          ExportAssetsTag ea=new ExportAssetsTag(swf);
          DefineSoundTag ds=(DefineSoundTag)tagObj;
          ea.tags.add(ds.soundId);
          ea.names.add("String_Node_Str");
          ea.writeTag(sos2);
          List<Action> actions;
          DoActionTag doa;
          doa=new DoActionTag(swf,null);
          actions=ASMParser.parse(0,false,"String_Node_Str" + "String_Node_Str" + "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str",swf.version,false);
          doa.setActions(actions);
          doa.writeTag(sos2);
          new ShowFrameTag(swf).writeTag(sos2);
          actions=ASMParser.parse(0,false,"String_Node_Str" + "String_Node_Str" + "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str",swf.version,false);
          doa.setActions(actions);
          doa.writeTag(sos2);
          new ShowFrameTag(swf).writeTag(sos2);
          actions=ASMParser.parse(0,false,"String_Node_Str" + "String_Node_Str" + "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str",swf.version,false);
          doa.setActions(actions);
          doa.writeTag(sos2);
          new ShowFrameTag(swf).writeTag(sos2);
          actions=ASMParser.parse(0,false,"String_Node_Str" + "String_Node_Str",swf.version,false);
          doa.setActions(actions);
          doa.writeTag(sos2);
          new ShowFrameTag(swf).writeTag(sos2);
          new ShowFrameTag(swf).writeTag(sos2);
        }
 else         if (tagObj instanceof DefineVideoStreamTag) {
          new PlaceObject2Tag(swf,false,false,false,false,false,true,true,false,1,chtId,mat,null,0,null,0,null).writeTag(sos2);
          List<VideoFrameTag> frs=new ArrayList<>(videoFrames.values());
          Collections.sort(frs,new Comparator<VideoFrameTag>(){
            @Override public int compare(            VideoFrameTag o1,            VideoFrameTag o2){
              return o1.frameNum - o2.frameNum;
            }
          }
);
          boolean first=true;
          int ratio=0;
          for (          VideoFrameTag f : frs) {
            if (!first) {
              ratio++;
              new PlaceObject2Tag(swf,false,false,false,true,false,false,false,true,1,0,null,null,ratio,null,0,null).writeTag(sos2);
            }
            f.writeTag(sos2);
            new ShowFrameTag(swf).writeTag(sos2);
            first=false;
          }
        }
 else         if (tagObj instanceof DefineSpriteTag) {
          DefineSpriteTag s=(DefineSpriteTag)tagObj;
          Tag lastTag=null;
          for (          Tag t : s.subTags) {
            if (t instanceof EndTag) {
              break;
            }
 else             if (t instanceof PlaceObjectTypeTag) {
              PlaceObjectTypeTag pt=(PlaceObjectTypeTag)t;
              MATRIX m=pt.getMatrix();
              MATRIX m2=new Matrix(m).preConcatenate(new Matrix(mat)).toMATRIX();
              pt.writeTagWithMatrix(sos2,m2);
              lastTag=t;
            }
 else {
              t.writeTag(sos2);
              lastTag=t;
            }
          }
          if (!s.subTags.isEmpty() && (lastTag != null) && (!(lastTag instanceof ShowFrameTag))) {
            new ShowFrameTag(swf).writeTag(sos2);
          }
        }
 else {
          new PlaceObject2Tag(swf,false,false,false,true,false,true,true,false,1,chtId,mat,null,0,null,0,null).writeTag(sos2);
          new ShowFrameTag(swf).writeTag(sos2);
        }
      }
      new EndTag(swf).writeTag(sos2);
      data=baos.toByteArray();
    }
     try (OutputStream fos=new BufferedOutputStream(new FileOutputStream(tempFile))){
      SWFOutputStream sos=new SWFOutputStream(fos,Math.max(10,swf.version));
      sos.write("String_Node_Str".getBytes());
      sos.write(swf.version);
      sos.writeUI32(sos.getPos() + data.length + 4);
      sos.write(data);
      fos.flush();
    }
     if (flashPanel != null) {
      flashPanel.displaySWF(tempFile.getAbsolutePath(),backgroundColor,frameRate);
    }
    showFlashViewerPanel();
  }
 catch (  IOException|ActionParseException ex) {
    Logger.getLogger(PreviewPanel.class.getName()).log(Level.SEVERE,null,ex);
  }
}

Fixed version (ground truth):
public void createAndShowTempSwf(TreeItem tagObj){
  SWF swf=null;
  try {
    if (tempFile != null) {
      tempFile.delete();
    }
    tempFile=File.createTempFile("String_Node_Str","String_Node_Str");
    tempFile.deleteOnExit();
    Color backgroundColor=View.getSwfBackgroundColor();
    if (tagObj instanceof Tag) {
      Tag tag=(Tag)tagObj;
      swf=tag.getSwf();
      if (tag instanceof FontTag) {
        backgroundColor=View.getDefaultBackgroundColor();
      }
    }
 else     if (tagObj instanceof Frame) {
      Frame fn=(Frame)tagObj;
      swf=fn.getSwf();
      if (fn.timeline.timelined == swf) {
        SetBackgroundColorTag setBgColorTag=swf.getBackgroundColor();
        if (setBgColorTag != null) {
          backgroundColor=setBgColorTag.backgroundColor.toColor();
        }
      }
    }
    int frameCount=1;
    float frameRate=swf.frameRate;
    HashMap<Integer,VideoFrameTag> videoFrames=new HashMap<>();
    if (tagObj instanceof DefineVideoStreamTag) {
      DefineVideoStreamTag vs=(DefineVideoStreamTag)tagObj;
      SWF.populateVideoFrames(vs.getCharacterId(),swf.tags,videoFrames);
      frameCount=videoFrames.size();
    }
    List<SoundStreamBlockTag> soundFrames=new ArrayList<>();
    if (tagObj instanceof SoundStreamHeadTypeTag) {
      soundFrames=((SoundStreamHeadTypeTag)tagObj).getBlocks();
      frameCount=soundFrames.size();
    }
    if ((tagObj instanceof DefineMorphShapeTag) || (tagObj instanceof DefineMorphShape2Tag)) {
      frameRate=MainPanel.MORPH_SHAPE_ANIMATION_FRAME_RATE;
      frameCount=(int)(MainPanel.MORPH_SHAPE_ANIMATION_LENGTH * frameRate);
    }
    if (tagObj instanceof DefineSoundTag) {
      frameCount=1;
    }
    if (tagObj instanceof DefineSpriteTag) {
      frameCount=((DefineSpriteTag)tagObj).frameCount;
    }
    byte[] data;
    try (ByteArrayOutputStream baos=new ByteArrayOutputStream()){
      SWFOutputStream sos2=new SWFOutputStream(baos,SWF.DEFAULT_VERSION);
      RECT outrect=new RECT(swf.displayRect);
      if (tagObj instanceof FontTag) {
        outrect.Xmin=0;
        outrect.Ymin=0;
        outrect.Xmax=FontTag.PREVIEWSIZE * 20;
        outrect.Ymax=FontTag.PREVIEWSIZE * 20;
      }
      int width=outrect.getWidth();
      int height=outrect.getHeight();
      sos2.writeRECT(outrect);
      sos2.writeFIXED8(frameRate);
      sos2.writeUI16(frameCount);
      FileAttributesTag fa=swf.getFileAttributes();
      if (fa != null) {
        fa.writeTag(sos2);
      }
      SetBackgroundColorTag setBgColorTag=swf.getBackgroundColor();
      if (setBgColorTag == null) {
        setBgColorTag=new SetBackgroundColorTag(swf,new RGB(backgroundColor));
      }
      setBgColorTag.writeTag(sos2);
      if (tagObj instanceof Frame) {
        Frame fn=(Frame)tagObj;
        Timelined parent=fn.timeline.timelined;
        List<Tag> subs=fn.timeline.tags;
        List<Integer> doneCharacters=new ArrayList<>();
        int frameCnt=0;
        for (        Tag t : subs) {
          if (t instanceof FileAttributesTag || t instanceof SetBackgroundColorTag) {
            continue;
          }
          if (t instanceof ShowFrameTag) {
            frameCnt++;
            continue;
          }
          if (frameCnt > fn.frame) {
            break;
          }
          if (t instanceof DoActionTag || t instanceof DoInitActionTag) {
            continue;
          }
          Set<Integer> needed=new HashSet<>();
          t.getNeededCharactersDeep(needed);
          for (          int n : needed) {
            if (!doneCharacters.contains(n)) {
              classicTag(swf.getCharacter(n)).writeTag(sos2);
              doneCharacters.add(n);
            }
          }
          if (t instanceof CharacterTag) {
            int characterId=((CharacterTag)t).getCharacterId();
            if (!doneCharacters.contains(characterId)) {
              doneCharacters.add(((CharacterTag)t).getCharacterId());
            }
          }
          classicTag(t).writeTag(sos2);
          if (parent != null) {
            if (t instanceof PlaceObjectTypeTag) {
              PlaceObjectTypeTag pot=(PlaceObjectTypeTag)t;
              int chid=pot.getCharacterId();
              int depth=pot.getDepth();
              MATRIX mat=pot.getMatrix();
              if (mat == null) {
                mat=new MATRIX();
              }
              mat=Helper.deepCopy(mat);
              RECT r=parent.getRect();
              mat.translateX+=width / 2 - r.getWidth() / 2;
              mat.translateY+=height / 2 - r.getHeight() / 2;
              new PlaceObject2Tag(swf,false,false,false,false,false,true,false,true,depth,chid,mat,null,0,null,0,null).writeTag(sos2);
            }
          }
        }
        new ShowFrameTag(swf).writeTag(sos2);
      }
 else {
        boolean isSprite=false;
        if (tagObj instanceof DefineSpriteTag) {
          isSprite=true;
        }
        int chtId=0;
        if (tagObj instanceof CharacterTag) {
          chtId=((CharacterTag)tagObj).getCharacterId();
        }
        if (tagObj instanceof DefineBitsTag) {
          JPEGTablesTag jtt=swf.getJtt();
          if (jtt != null) {
            jtt.writeTag(sos2);
          }
        }
 else         if (tagObj instanceof AloneTag) {
        }
 else {
          Set<Integer> needed=new HashSet<>();
          ((Tag)tagObj).getNeededCharactersDeep(needed);
          for (          int n : needed) {
            if (isSprite && chtId == n) {
              continue;
            }
            CharacterTag characterTag=swf.getCharacter(n);
            if (characterTag instanceof DefineBitsTag) {
              JPEGTablesTag jtt=swf.getJtt();
              if (jtt != null) {
                jtt.writeTag(sos2);
              }
            }
            classicTag(characterTag).writeTag(sos2);
          }
        }
        classicTag((Tag)tagObj).writeTag(sos2);
        MATRIX mat=new MATRIX();
        mat.hasRotate=false;
        mat.hasScale=false;
        mat.translateX=0;
        mat.translateY=0;
        if (tagObj instanceof BoundedTag) {
          RECT r=((BoundedTag)tagObj).getRect();
          mat.translateX=-r.Xmin;
          mat.translateY=-r.Ymin;
          mat.translateX=mat.translateX + width / 2 - r.getWidth() / 2;
          mat.translateY=mat.translateY + height / 2 - r.getHeight() / 2;
        }
 else {
          mat.translateX=width / 4;
          mat.translateY=height / 4;
        }
        if (tagObj instanceof FontTag) {
          FontTag ft=(FontTag)classicTag((Tag)tagObj);
          int countGlyphsTotal=ft.getGlyphShapeTable().size();
          int countGlyphs=Math.min(SHAPERECORD.MAX_CHARACTERS_IN_FONT_PREVIEW,countGlyphsTotal);
          int fontId=ft.getFontId();
          int cols=(int)Math.ceil(Math.sqrt(countGlyphs));
          int rows=(int)Math.ceil(((float)countGlyphs) / ((float)cols));
          if (rows == 0) {
            rows=1;
            cols=1;
          }
          int x=0;
          int y=0;
          int firstGlyphIndex=fontPageNum * SHAPERECORD.MAX_CHARACTERS_IN_FONT_PREVIEW;
          countGlyphs=Math.min(SHAPERECORD.MAX_CHARACTERS_IN_FONT_PREVIEW,countGlyphsTotal - firstGlyphIndex);
          List<SHAPE> shapes=ft.getGlyphShapeTable();
          int maxw=0;
          for (int f=firstGlyphIndex; f < firstGlyphIndex + countGlyphs; f++) {
            RECT b=shapes.get(f).getBounds();
            if (b.Xmin == Integer.MAX_VALUE) {
              continue;
            }
            if (b.Ymin == Integer.MAX_VALUE) {
              continue;
            }
            int w=(int)(b.getWidth() / ft.getDivider());
            if (w > maxw) {
              maxw=w;
            }
            x++;
          }
          x=0;
          int BORDER=3 * 20;
          int textHeight=height / rows;
          while (maxw * textHeight / 1024.0 > width / cols - 2 * BORDER) {
            textHeight--;
          }
          MATRIX tmat=new MATRIX();
          for (int f=firstGlyphIndex; f < firstGlyphIndex + countGlyphs; f++) {
            if (x >= cols) {
              x=0;
              y++;
            }
            List<TEXTRECORD> rec=new ArrayList<>();
            TEXTRECORD tr=new TEXTRECORD();
            RECT b=shapes.get(f).getBounds();
            int xmin=b.Xmin == Integer.MAX_VALUE ? 0 : (int)(b.Xmin / ft.getDivider());
            xmin*=textHeight / 1024.0;
            int ymin=b.Ymin == Integer.MAX_VALUE ? 0 : (int)(b.Ymin / ft.getDivider());
            ymin*=textHeight / 1024.0;
            int w=(int)(b.getWidth() / ft.getDivider());
            w*=textHeight / 1024.0;
            int h=(int)(b.getHeight() / ft.getDivider());
            h*=textHeight / 1024.0;
            tr.fontId=fontId;
            tr.styleFlagsHasFont=true;
            tr.textHeight=textHeight;
            tr.xOffset=-xmin;
            tr.yOffset=0;
            tr.styleFlagsHasXOffset=true;
            tr.styleFlagsHasYOffset=true;
            tr.glyphEntries=new ArrayList<>(1);
            tr.styleFlagsHasColor=true;
            tr.textColor=new RGB(0,0,0);
            GLYPHENTRY ge=new GLYPHENTRY();
            double ga=ft.getGlyphAdvance(f);
            int cw=ga == -1 ? w : (int)(ga / ft.getDivider() * textHeight / 1024.0);
            ge.glyphAdvance=0;
            ge.glyphIndex=f;
            tr.glyphEntries.add(ge);
            rec.add(tr);
            tmat.translateX=x * width / cols + width / cols / 2 - w / 2;
            tmat.translateY=y * height / rows + height / rows / 2;
            new DefineTextTag(swf,999 + f,new RECT(0,cw,ymin,ymin + h),new MATRIX(),rec).writeTag(sos2);
            new PlaceObject2Tag(swf,false,false,false,true,false,true,true,false,1 + f,999 + f,tmat,null,0,null,0,null).writeTag(sos2);
            x++;
          }
          new ShowFrameTag(swf).writeTag(sos2);
        }
 else         if ((tagObj instanceof DefineMorphShapeTag) || (tagObj instanceof DefineMorphShape2Tag)) {
          new PlaceObject2Tag(swf,false,false,false,true,false,true,true,false,1,chtId,mat,null,0,null,0,null).writeTag(sos2);
          new ShowFrameTag(swf).writeTag(sos2);
          for (int ratio=0; ratio < 65536; ratio+=65536 / frameCount) {
            new PlaceObject2Tag(swf,false,false,false,true,false,true,false,true,1,chtId,mat,null,ratio,null,0,null).writeTag(sos2);
            new ShowFrameTag(swf).writeTag(sos2);
          }
        }
 else         if (tagObj instanceof SoundStreamHeadTypeTag) {
          for (          SoundStreamBlockTag blk : soundFrames) {
            blk.writeTag(sos2);
            new ShowFrameTag(swf).writeTag(sos2);
          }
        }
 else         if (tagObj instanceof DefineSoundTag) {
          ExportAssetsTag ea=new ExportAssetsTag(swf);
          DefineSoundTag ds=(DefineSoundTag)tagObj;
          ea.tags.add(ds.soundId);
          ea.names.add("String_Node_Str");
          ea.writeTag(sos2);
          List<Action> actions;
          DoActionTag doa;
          doa=new DoActionTag(swf,null);
          actions=ASMParser.parse(0,false,"String_Node_Str" + "String_Node_Str" + "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str",swf.version,false);
          doa.setActions(actions);
          doa.writeTag(sos2);
          new ShowFrameTag(swf).writeTag(sos2);
          actions=ASMParser.parse(0,false,"String_Node_Str" + "String_Node_Str" + "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str",swf.version,false);
          doa.setActions(actions);
          doa.writeTag(sos2);
          new ShowFrameTag(swf).writeTag(sos2);
          actions=ASMParser.parse(0,false,"String_Node_Str" + "String_Node_Str" + "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str",swf.version,false);
          doa.setActions(actions);
          doa.writeTag(sos2);
          new ShowFrameTag(swf).writeTag(sos2);
          actions=ASMParser.parse(0,false,"String_Node_Str" + "String_Node_Str",swf.version,false);
          doa.setActions(actions);
          doa.writeTag(sos2);
          new ShowFrameTag(swf).writeTag(sos2);
          new ShowFrameTag(swf).writeTag(sos2);
        }
 else         if (tagObj instanceof DefineVideoStreamTag) {
          new PlaceObject2Tag(swf,false,false,false,false,false,true,true,false,1,chtId,mat,null,0,null,0,null).writeTag(sos2);
          List<VideoFrameTag> frs=new ArrayList<>(videoFrames.values());
          Collections.sort(frs,new Comparator<VideoFrameTag>(){
            @Override public int compare(            VideoFrameTag o1,            VideoFrameTag o2){
              return o1.frameNum - o2.frameNum;
            }
          }
);
          boolean first=true;
          int ratio=0;
          for (          VideoFrameTag f : frs) {
            if (!first) {
              ratio++;
              new PlaceObject2Tag(swf,false,false,false,true,false,false,false,true,1,0,null,null,ratio,null,0,null).writeTag(sos2);
            }
            f.writeTag(sos2);
            new ShowFrameTag(swf).writeTag(sos2);
            first=false;
          }
        }
 else         if (tagObj instanceof DefineSpriteTag) {
          DefineSpriteTag s=(DefineSpriteTag)tagObj;
          Tag lastTag=null;
          for (          Tag t : s.subTags) {
            if (t instanceof EndTag) {
              break;
            }
 else             if (t instanceof PlaceObjectTypeTag) {
              PlaceObjectTypeTag pt=(PlaceObjectTypeTag)t;
              MATRIX m=pt.getMatrix();
              MATRIX m2=new Matrix(m).preConcatenate(new Matrix(mat)).toMATRIX();
              pt.writeTagWithMatrix(sos2,m2);
              lastTag=t;
            }
 else {
              t.writeTag(sos2);
              lastTag=t;
            }
          }
          if (!s.subTags.isEmpty() && (lastTag != null) && (!(lastTag instanceof ShowFrameTag))) {
            new ShowFrameTag(swf).writeTag(sos2);
          }
        }
 else {
          new PlaceObject2Tag(swf,false,false,false,true,false,true,true,false,1,chtId,mat,null,0,null,0,null).writeTag(sos2);
          new ShowFrameTag(swf).writeTag(sos2);
        }
      }
      new EndTag(swf).writeTag(sos2);
      data=baos.toByteArray();
    }
     try (OutputStream fos=new BufferedOutputStream(new FileOutputStream(tempFile))){
      SWFOutputStream sos=new SWFOutputStream(fos,Math.max(10,swf.version));
      sos.write("String_Node_Str".getBytes());
      sos.write(swf.version);
      sos.writeUI32(sos.getPos() + data.length + 4);
      sos.write(data);
      fos.flush();
    }
     if (flashPanel != null) {
      flashPanel.displaySWF(tempFile.getAbsolutePath(),backgroundColor,frameRate);
    }
    showFlashViewerPanel();
  }
 catch (  IOException|ActionParseException ex) {
    Logger.getLogger(PreviewPanel.class.getName()).log(Level.SEVERE,null,ex);
  }
}