show previews for font tags and frames, double click on preview jumps to the item in the tree

This commit is contained in:
Honfika
2014-03-06 23:23:39 +01:00
parent edc9ed88b6
commit 91e92fd646
24 changed files with 124 additions and 124 deletions
@@ -31,7 +31,6 @@ import com.jpexs.decompiler.flash.types.SHAPE;
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
import com.jpexs.helpers.SerializableImage;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
@@ -21,23 +21,17 @@ import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.exporters.Matrix;
import com.jpexs.decompiler.flash.gui.player.FlashDisplay;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.tags.base.MorphShapeTag;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.helpers.SerializableImage;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.ImageIcon;
@@ -103,6 +103,7 @@ import com.jpexs.decompiler.flash.treeitems.FrameNodeItem;
import com.jpexs.decompiler.flash.treeitems.StringItem;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import com.jpexs.decompiler.flash.treenodes.ContainerNode;
import com.jpexs.decompiler.flash.treenodes.FrameNode;
import com.jpexs.decompiler.flash.treenodes.TagNode;
import com.jpexs.decompiler.flash.treenodes.TreeNode;
import com.jpexs.decompiler.flash.types.ColorTransform;
@@ -1630,15 +1631,19 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
@Override
public void updateSearchPos(TextTag item) {
TagTreeModel ttm = (TagTreeModel) tagTree.getModel();
TreePath tp = ttm.getTagPath(item);
tagTree.setSelectionPath(tp);
tagTree.scrollPathToVisible(tp);
setTreeItem(item);
textValue.setCaretPosition(0);
textSearchPanel.showQuickFindDialog(textValue);
}
public void setTreeItem(TreeItem treeItem) {
TagTreeModel ttm = (TagTreeModel) tagTree.getModel();
TreePath tp = ttm.getTagPath(treeItem);
tagTree.setSelectionPath(tp);
tagTree.scrollPathToVisible(tp);
}
public void autoDeobfuscateChanged() {
clearCache();
if (abcPanel != null) {
@@ -2177,9 +2182,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
case ACTION_SAVE_GENERIC_TAG: {
genericTagPanel.save();
refreshTree();
TagTreeModel ttm = (TagTreeModel) tagTree.getModel();
TreePath tp = ttm.getTagPath(genericTagPanel.getTag());
tagTree.setSelectionPath(tp);
setTreeItem(genericTagPanel.getTag());
genericEditButton.setVisible(true);
genericSaveButton.setVisible(false);
genericCancelButton.setVisible(false);
@@ -2398,10 +2401,8 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
}
if (treeNode instanceof StringNode) {
StringNode stringNode = (StringNode) treeNode;
StringItem item = stringNode.getItem();
showCard(CARDFOLDERPREVIEWPANEL);
showFolderPreview(item.getSwf(), item.getName());
showFolderPreview(treeNode);
} else if (treeNode instanceof SWFNode) {
SWFNode swfNode = (SWFNode) treeNode;
SWF swf = swfNode.getItem();
@@ -2912,15 +2913,18 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
textValue.setCaretPosition(0);
}
private void showFolderPreview(SWF swf, String folderName) {
private void showFolderPreview(TreeNode treeNode) {
folderPreviewPanel.removeAll();
StringNode stringNode = (StringNode) treeNode;
StringItem item = stringNode.getItem();
String folderName = item.getName();
SWF swf = item.swf;
JPanel panel = folderPreviewPanel;
//folderPreviewPanel.add(new JScrollPane(panel), BorderLayout.CENTER);
switch (folderName) {
case TagTreeModel.FOLDER_SHAPES:
for (Tag tag : swf.tags) {
if (tag instanceof ShapeTag) {
Component c = PreviewImage.createFolderPreviewImage(tag);
Component c = PreviewImage.createFolderPreviewImage(this, tag);
if (c != null) {
panel.add(c);
}
@@ -2930,7 +2934,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
case TagTreeModel.FOLDER_MORPHSHAPES:
for (Tag tag : swf.tags) {
if (tag instanceof MorphShapeTag) {
Component c = PreviewImage.createFolderPreviewImage(tag);
Component c = PreviewImage.createFolderPreviewImage(this, tag);
if (c != null) {
panel.add(c);
}
@@ -2940,7 +2944,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
case TagTreeModel.FOLDER_SPRITES:
for (Tag tag : swf.tags) {
if (tag instanceof DefineSpriteTag) {
Component c = PreviewImage.createFolderPreviewImage(tag);
Component c = PreviewImage.createFolderPreviewImage(this, tag);
if (c != null) {
panel.add(c);
}
@@ -2950,37 +2954,37 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
case TagTreeModel.FOLDER_BUTTONS:
for (Tag tag : swf.tags) {
if (tag instanceof ButtonTag) {
Component c = PreviewImage.createFolderPreviewImage(tag);
Component c = PreviewImage.createFolderPreviewImage(this, tag);
if (c != null) {
panel.add(c);
}
}
}
break;
/*case TagTreeModel.FOLDER_FONTS:
for (Tag tag : swf.tags) {
if (tag instanceof FontTag) {
Component c = PreviewImage.createFolderPreviewImage(tag);
if (c != null) {
panel.add(c);
}
}
}
break;*/
/*case TagTreeModel.FOLDER_FRAMES:
for (Tag tag : swf.tags) {
if (tag instanceof FrameTag) {
Component c = PreviewImage.createFolderPreviewImage(tag);
if (c != null) {
panel.add(c);
}
}
}
break;*/
case TagTreeModel.FOLDER_FONTS:
for (Tag tag : swf.tags) {
if (tag instanceof FontTag) {
Component c = PreviewImage.createFolderPreviewImage(this, tag);
if (c != null) {
panel.add(c);
}
}
}
break;
case TagTreeModel.FOLDER_FRAMES:
for (TreeNode subNode : treeNode.subNodes) {
FrameNode frameNode = (FrameNode) subNode;
FrameNodeItem fn = frameNode.getItem();
Component c = PreviewImage.createFolderPreviewImage(this, fn);
if (c != null) {
panel.add(c);
}
}
break;
case TagTreeModel.FOLDER_IMAGES:
for (Tag tag : swf.tags) {
if (tag instanceof ImageTag) {
Component c = PreviewImage.createFolderPreviewImage(tag);
Component c = PreviewImage.createFolderPreviewImage(this, tag);
if (c != null) {
panel.add(c);
}
@@ -2990,7 +2994,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
case TagTreeModel.FOLDER_TEXTS:
for (Tag tag : swf.tags) {
if (tag instanceof TextTag) {
Component c = PreviewImage.createFolderPreviewImage(tag);
Component c = PreviewImage.createFolderPreviewImage(this, tag);
if (c != null) {
panel.add(c);
}
@@ -22,7 +22,10 @@ import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.treeitems.FrameNodeItem;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.helpers.SerializableImage;
@@ -33,6 +36,8 @@ import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform;
import java.util.Stack;
import java.util.concurrent.Callable;
@@ -48,15 +53,22 @@ import javax.swing.JPanel;
*/
public class PreviewImage extends JPanel {
private static ExecutorService executor = Executors.newFixedThreadPool(1);
private static final ExecutorService executor = Executors.newFixedThreadPool(1);
private static final int PREVIEW_SIZE = 150;
private static final int BORDER_SIZE = 5;
private Image image;
private boolean rendering;
private Tag tag;
private final MainPanel mainPanel;
private final TreeItem treeItem;
public PreviewImage(Tag tag) {
this.tag = tag;
/**
*
* @param mainPanel
* @param treeItem
*/
public PreviewImage(final MainPanel mainPanel, final TreeItem treeItem) {
this.mainPanel = mainPanel;
this.treeItem = treeItem;
Dimension dim = new Dimension(PREVIEW_SIZE + 2 * BORDER_SIZE, PREVIEW_SIZE + 2 * BORDER_SIZE);
setMinimumSize(dim);
setMaximumSize(dim);
@@ -64,9 +76,36 @@ public class PreviewImage extends JPanel {
setSize(dim);
setLayout(null);
setBorder(BorderFactory.createLineBorder(Color.black));
this.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() >= 2) {
mainPanel.setTreeItem(treeItem);
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
});
}
private synchronized void renderImageTask(final Tag tag) {
private synchronized void renderImageTask(final TreeItem treeItem) {
if (rendering) {
return;
}
@@ -75,23 +114,13 @@ public class PreviewImage extends JPanel {
@Override
public Void call() throws Exception {
image = renderImage(tag.getSwf(), tag);
image = renderImage(treeItem.getSwf(), treeItem);
View.execInEventDispatch(new Runnable() {
@Override
public void run() {
// todo:
// call repaint on MainPanel.folderPreviewPanel
// this is a hack, but otherwise the preview panel looks crazy sometimes
// how to handle it in a better way?
// normally repaint() on this panel should be enough
Component parent = getParent();
if (parent != null) {
parent = parent.getParent();
if (parent != null) {
parent.repaint();
}
}
revalidate();
repaint();
}
});
return null;
@@ -101,19 +130,30 @@ public class PreviewImage extends JPanel {
}
private Image renderImage(SWF swf, Tag tag) {
private Image renderImage(SWF swf, TreeItem treeItem) {
double scale = 1;
int width = 0;
int height = 0;
SerializableImage imgSrc = null;
Matrix m = new Matrix();
if (tag instanceof ImageTag) {
imgSrc = ((ImageTag) tag).getImage();
if (treeItem instanceof FontTag) {
FontTag fontTag = (FontTag) treeItem;
imgSrc = fontTag.toImage(0, 0, Matrix.getScaleInstance(1 / SWF.unitDivisor), new ColorTransform());
width = (imgSrc.getWidth());
height = (imgSrc.getHeight());
} else if (tag instanceof BoundedTag) {
BoundedTag boundedTag = (BoundedTag) tag;
} else if (treeItem instanceof FrameNodeItem) {
FrameNodeItem fn = (FrameNodeItem) treeItem;
RECT rect = swf.displayRect;
imgSrc = SWF.frameToImageGet(swf.getTimeline(), fn.getFrame() - 1, rect, new Stack<Integer>(), Matrix.getScaleInstance(1 / SWF.unitDivisor), new ColorTransform());
width = (imgSrc.getWidth());
height = (imgSrc.getHeight());
} else if (treeItem instanceof ImageTag) {
imgSrc = ((ImageTag) treeItem).getImage();
width = (imgSrc.getWidth());
height = (imgSrc.getHeight());
} else if (treeItem instanceof BoundedTag) {
BoundedTag boundedTag = (BoundedTag) treeItem;
RECT rect = boundedTag.getRect();
width = (int) (rect.getWidth() / SWF.unitDivisor);
height = (int) (rect.getHeight() / SWF.unitDivisor);
@@ -155,7 +195,7 @@ public class PreviewImage extends JPanel {
SerializableImage image = new SerializableImage(width, height, SerializableImage.TYPE_INT_ARGB);
image.fillTransparent();
if (imgSrc == null) {
DrawableTag drawable = (DrawableTag) tag;
DrawableTag drawable = (DrawableTag) treeItem;
drawable.toImage(0, 0, image, m, new ColorTransform());
} else {
Graphics2D g = (Graphics2D) image.getGraphics();
@@ -165,13 +205,18 @@ public class PreviewImage extends JPanel {
return image.getBufferedImage();
}
public static Component createFolderPreviewImage(Tag tag) {
public static Component createFolderPreviewImage(MainPanel mainPanel, TreeItem treeItem) {
JPanel pan = new JPanel(new BorderLayout());
PreviewImage imagePanel = new PreviewImage(tag);
PreviewImage imagePanel = new PreviewImage(mainPanel, treeItem);
pan.add(imagePanel, BorderLayout.CENTER);
String s = tag.getTagName();
if (tag instanceof CharacterTag) {
s = s + " (" + ((CharacterTag) tag).getCharacterId() + ")";
String s;
if (treeItem instanceof Tag) {
s = ((Tag) treeItem).getTagName();
if (treeItem instanceof CharacterTag) {
s = s + " (" + ((CharacterTag) treeItem).getCharacterId() + ")";
}
} else {
s = treeItem.toString();
}
JLabel lab = new JLabel(s);
lab.setFont(lab.getFont().deriveFont(AffineTransform.getScaleInstance(0.8, 0.8)));
@@ -181,12 +226,13 @@ public class PreviewImage extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
int x = (getWidth() / 2) - (image.getWidth(this) / 2);
int y = (getHeight() / 2) - (image.getHeight(this) / 2);
g.drawImage(image, x, y, null);
} else {
renderImageTask(tag);
renderImageTask(treeItem);
}
}
}
@@ -107,7 +107,7 @@ public class WrapLayout extends FlowLayout {
*/
private Dimension layoutSize(Container target, boolean preferred) {
synchronized (target.getTreeLock()) {
// Each row must fit with the width allocated to the containter.
// Each row must fit with the width allocated to the containter.
// When the container width = 0, the preferred width of the container
// has not yet been calculated so lets ask for the maximum.
@@ -123,7 +123,7 @@ public class WrapLayout extends FlowLayout {
int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2);
int maxWidth = targetWidth - horizontalInsetsAndGap;
// Fit components into the allowed width
// Fit components into the allowed width
Dimension dim = new Dimension(0, 0);
int rowWidth = 0;
int rowHeight = 0;
@@ -136,14 +136,14 @@ public class WrapLayout extends FlowLayout {
if (m.isVisible()) {
Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize();
// Can't add the component to current row. Start a new row.
// Can't add the component to current row. Start a new row.
if (rowWidth + d.width > maxWidth) {
addRow(dim, rowWidth, rowHeight);
rowWidth = 0;
rowHeight = 0;
}
// Add a horizontal gap for all components after the first
// Add a horizontal gap for all components after the first
if (rowWidth != 0) {
rowWidth += hgap;
}
@@ -158,7 +158,7 @@ public class WrapLayout extends FlowLayout {
dim.width += horizontalInsetsAndGap;
dim.height += insets.top + insets.bottom + vgap * 2;
// When using a scroll pane or the DecoratedLookAndFeel we need to
// When using a scroll pane or the DecoratedLookAndFeel we need to
// make sure the preferred size is less than the size of the
// target containter so shrinking the container size works
// correctly. Removing the horizontal gap is an easy way to do this.
@@ -48,9 +48,7 @@ import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -53,9 +53,7 @@ import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -21,7 +21,6 @@ import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.exporters.Matrix;
import com.jpexs.decompiler.flash.exporters.Point;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.tags.base.MissingCharacterHandler;
import com.jpexs.decompiler.flash.tags.base.TextTag;
@@ -55,7 +54,6 @@ import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.logging.Level;
@@ -50,9 +50,7 @@ import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
/**
*
@@ -49,9 +49,7 @@ import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
/**
*
@@ -32,10 +32,7 @@ import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.SerializableImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
public class DefineShape2Tag extends CharacterTag implements ShapeTag {
@@ -32,10 +32,7 @@ import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.SerializableImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
public class DefineShape3Tag extends CharacterTag implements ShapeTag {
@@ -33,10 +33,7 @@ import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.SerializableImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
public class DefineShape4Tag extends CharacterTag implements ShapeTag {
@@ -47,9 +47,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
/**
* Defines a sprite character
@@ -21,7 +21,6 @@ import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.exporters.Matrix;
import com.jpexs.decompiler.flash.exporters.Point;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.tags.base.MissingCharacterHandler;
import com.jpexs.decompiler.flash.tags.base.TextTag;
@@ -46,9 +45,7 @@ import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -22,7 +22,6 @@ import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.exporters.Matrix;
import com.jpexs.decompiler.flash.exporters.Point;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.tags.base.MissingCharacterHandler;
import com.jpexs.decompiler.flash.tags.base.TextTag;
@@ -47,9 +46,7 @@ import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -29,8 +29,6 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
import java.util.Stack;
/**
*
@@ -34,7 +34,6 @@ import com.jpexs.decompiler.flash.tags.gfx.FontTextureInfo;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -72,7 +71,7 @@ public class Tag implements NeedsCharacters, Exportable, ContainerItem, Serializ
public String getTagName() {
return tagName;
}
public String getName() {
return tagName;
}
@@ -17,8 +17,6 @@
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.types.RECT;
import java.util.Map;
import java.util.Stack;
/**
*
@@ -18,12 +18,8 @@ package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.exporters.Matrix;
import com.jpexs.decompiler.flash.exporters.Point;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.helpers.SerializableImage;
import java.util.List;
import java.util.Map;
import java.util.Stack;
/**
*
@@ -39,7 +39,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Stack;
/**
*
@@ -23,7 +23,6 @@ import com.jpexs.decompiler.flash.exporters.Matrix;
import com.jpexs.decompiler.flash.exporters.Point;
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.types.ColorTransform;
@@ -51,8 +50,6 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JPanel;
@@ -26,11 +26,9 @@ import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.SHAPE;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.SerializableImage;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.font.GlyphVector;
import java.awt.geom.PathIterator;
@@ -25,7 +25,6 @@ import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;