mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-19 06:08:31 +00:00
faster imagepanel
This commit is contained in:
@@ -94,7 +94,6 @@ import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.Container;
|
||||
import com.jpexs.decompiler.flash.tags.base.ContainerItem;
|
||||
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.tags.base.PlaceObjectTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.RemoveTag;
|
||||
@@ -102,6 +101,7 @@ import com.jpexs.decompiler.flash.tags.base.ShapeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.TextTag;
|
||||
import com.jpexs.decompiler.flash.timeline.Clip;
|
||||
import com.jpexs.decompiler.flash.timeline.DepthState;
|
||||
import com.jpexs.decompiler.flash.timeline.Frame;
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
@@ -177,7 +177,6 @@ import java.util.zip.InflaterInputStream;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.stream.FileImageOutputStream;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import javax.imageio.stream.MemoryCacheImageOutputStream;
|
||||
import net.kroo.elliot.GifSequenceWriter;
|
||||
import org.monte.media.VideoFormatKeys;
|
||||
import org.monte.media.avi.AVIWriter;
|
||||
@@ -2389,18 +2388,6 @@ public final class SWF implements TreeItem, Timelined {
|
||||
}
|
||||
}
|
||||
|
||||
private static class Clip {
|
||||
|
||||
public Shape shape;
|
||||
public int clipDepth;
|
||||
|
||||
public Clip(Shape clip, int clipDepth) {
|
||||
this.shape = clip;
|
||||
this.clipDepth = clipDepth;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void frameToImage(Timeline timeline, int frame, int time, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
|
||||
float unzoom = (float) SWF.unitDivisor;
|
||||
if (timeline.frames.size() <= frame) {
|
||||
@@ -2416,7 +2403,7 @@ public final class SWF implements TreeItem, Timelined {
|
||||
|
||||
for (int i = 1; i <= timeline.getMaxDepth(); i++) {
|
||||
for (int c = 0; c < clips.size(); c++) {
|
||||
if (clips.get(c).clipDepth == i) {
|
||||
if (clips.get(c).depth == i) {
|
||||
g.setClip(prevClips.get(c));
|
||||
prevClips.remove(c);
|
||||
clips.remove(c);
|
||||
@@ -2450,7 +2437,7 @@ public final class SWF implements TreeItem, Timelined {
|
||||
DrawableTag drawable = (DrawableTag) character;
|
||||
SerializableImage img;
|
||||
Matrix drawMatrix = new Matrix();
|
||||
int dframe = 0 + (time + layer.time) % drawable.getNumFrames();
|
||||
int dframe = (time + layer.time) % drawable.getNumFrames();
|
||||
if (character instanceof ButtonTag) {
|
||||
ButtonTag bt = (ButtonTag) character;
|
||||
dframe = ButtonTag.FRAME_UP;
|
||||
@@ -2463,64 +2450,56 @@ public final class SWF implements TreeItem, Timelined {
|
||||
}
|
||||
}
|
||||
|
||||
if (drawable instanceof BoundedTag) {
|
||||
BoundedTag bounded = (BoundedTag) drawable;
|
||||
RECT boundRect = bounded.getRect();
|
||||
ExportRectangle rect = new ExportRectangle(boundRect);
|
||||
rect = mat.transform(rect);
|
||||
Matrix m = mat.clone();
|
||||
if (layer.filters != null) {
|
||||
// calculate size after applying the filters
|
||||
double deltaXMax = 0;
|
||||
double deltaYMax = 0;
|
||||
for (FILTER filter : layer.filters) {
|
||||
double x = filter.getDeltaX();
|
||||
double y = filter.getDeltaY();
|
||||
deltaXMax = Math.max(x, deltaXMax);
|
||||
deltaYMax = Math.max(y, deltaYMax);
|
||||
}
|
||||
rect.xMin -= deltaXMax * SWF.unitDivisor;
|
||||
rect.xMax += deltaXMax * SWF.unitDivisor;
|
||||
rect.yMin -= deltaYMax * SWF.unitDivisor;
|
||||
rect.yMax += deltaYMax * SWF.unitDivisor;
|
||||
RECT boundRect = drawable.getRect();
|
||||
ExportRectangle rect = new ExportRectangle(boundRect);
|
||||
rect = mat.transform(rect);
|
||||
Matrix m = mat.clone();
|
||||
if (layer.filters != null) {
|
||||
// calculate size after applying the filters
|
||||
double deltaXMax = 0;
|
||||
double deltaYMax = 0;
|
||||
for (FILTER filter : layer.filters) {
|
||||
double x = filter.getDeltaX();
|
||||
double y = filter.getDeltaY();
|
||||
deltaXMax = Math.max(x, deltaXMax);
|
||||
deltaYMax = Math.max(y, deltaYMax);
|
||||
}
|
||||
|
||||
rect.xMin = Math.max(0, rect.xMin);
|
||||
rect.yMin = Math.max(0, rect.yMin);
|
||||
|
||||
int newWidth = (int) (rect.getWidth() / SWF.unitDivisor);
|
||||
int newHeight = (int) (rect.getHeight() / SWF.unitDivisor);
|
||||
int deltaX = (int) (rect.xMin / SWF.unitDivisor);
|
||||
int deltaY = (int) (rect.yMin / SWF.unitDivisor);
|
||||
newWidth = Math.min(image.getWidth() - deltaX, newWidth) + 1;
|
||||
newHeight = Math.min(image.getHeight() - deltaY, newHeight) + 1;
|
||||
|
||||
if (newWidth <= 0 || newHeight <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
img = new SerializableImage(newWidth, newHeight, SerializableImage.TYPE_INT_ARGB);
|
||||
img.fillTransparent();
|
||||
|
||||
m.translate(-rect.xMin, -rect.yMin);
|
||||
drawMatrix.translate(rect.xMin, rect.yMin);
|
||||
|
||||
drawable.toImage(dframe, layer.time + time, layer.ratio, stateUnderCursor, mouseButton, img, m, clrTrans);
|
||||
//if(stateUnderCursor == layer){
|
||||
/* if(true){
|
||||
Graphics2D gg = (Graphics2D)img.getGraphics();
|
||||
gg.setStroke(new BasicStroke(3));
|
||||
gg.setPaint(Color.red);
|
||||
gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
|
||||
gg.draw(SHAPERECORD.twipToPixelShape(drawable.getOutline(frame, layer.ratio, stateUnderCursor, mouseButton, m)));
|
||||
}*/
|
||||
} else if (drawable instanceof FontTag) {
|
||||
// only DefineFont tags
|
||||
FontTag fontTag = (FontTag) drawable;
|
||||
img = fontTag.toImage(dframe, layer.ratio, transformation, clrTrans);
|
||||
} else {
|
||||
throw new Error("Unsupported drawable.");
|
||||
rect.xMin -= deltaXMax * SWF.unitDivisor;
|
||||
rect.xMax += deltaXMax * SWF.unitDivisor;
|
||||
rect.yMin -= deltaYMax * SWF.unitDivisor;
|
||||
rect.yMax += deltaYMax * SWF.unitDivisor;
|
||||
}
|
||||
|
||||
rect.xMin = Math.max(0, rect.xMin);
|
||||
rect.yMin = Math.max(0, rect.yMin);
|
||||
|
||||
int newWidth = (int) (rect.getWidth() / SWF.unitDivisor);
|
||||
int newHeight = (int) (rect.getHeight() / SWF.unitDivisor);
|
||||
int deltaX = (int) (rect.xMin / SWF.unitDivisor);
|
||||
int deltaY = (int) (rect.yMin / SWF.unitDivisor);
|
||||
newWidth = Math.min(image.getWidth() - deltaX, newWidth) + 1;
|
||||
newHeight = Math.min(image.getHeight() - deltaY, newHeight) + 1;
|
||||
|
||||
if (newWidth <= 0 || newHeight <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
img = new SerializableImage(newWidth, newHeight, SerializableImage.TYPE_INT_ARGB);
|
||||
img.fillTransparent();
|
||||
|
||||
m.translate(-rect.xMin, -rect.yMin);
|
||||
drawMatrix.translate(rect.xMin, rect.yMin);
|
||||
|
||||
drawable.toImage(dframe, layer.time + time, layer.ratio, stateUnderCursor, mouseButton, img, m, clrTrans);
|
||||
//if(stateUnderCursor == layer){
|
||||
/* if(true){
|
||||
Graphics2D gg = (Graphics2D)img.getGraphics();
|
||||
gg.setStroke(new BasicStroke(3));
|
||||
gg.setPaint(Color.red);
|
||||
gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
|
||||
gg.draw(SHAPERECORD.twipToPixelShape(drawable.getOutline(frame, layer.ratio, stateUnderCursor, mouseButton, m)));
|
||||
}*/
|
||||
|
||||
if (layer.filters != null) {
|
||||
for (FILTER filter : layer.filters) {
|
||||
img = filter.apply(img);
|
||||
|
||||
@@ -23,13 +23,9 @@ import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.FILLSTYLE;
|
||||
import com.jpexs.decompiler.flash.types.GRADIENT;
|
||||
import com.jpexs.decompiler.flash.types.GRADRECORD;
|
||||
import com.jpexs.decompiler.flash.types.LINESTYLE;
|
||||
import com.jpexs.decompiler.flash.types.LINESTYLE2;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.RGB;
|
||||
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.BasicStroke;
|
||||
import java.awt.Color;
|
||||
@@ -67,13 +63,7 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter
|
||||
private Stroke defaultStroke;
|
||||
private double unitDivisor;
|
||||
|
||||
public static SerializableImage export(SWF swf, SHAPE shape, Color defaultColor, ColorTransform colorTransform) {
|
||||
BitmapExporter exporter = new BitmapExporter(swf, shape, defaultColor, colorTransform);
|
||||
exporter.export();
|
||||
return exporter.getImage();
|
||||
}
|
||||
|
||||
public static void exportTo(SWF swf, SHAPE shape, Color defaultColor, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
|
||||
public static void export(SWF swf, SHAPE shape, Color defaultColor, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
|
||||
BitmapExporter exporter = new BitmapExporter(swf, shape, defaultColor, colorTransform);
|
||||
exporter.exportTo(image, transformation);
|
||||
}
|
||||
@@ -84,34 +74,6 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter
|
||||
this.defaultColor = defaultColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void export() {
|
||||
List<SHAPERECORD> records = shape.shapeRecords;
|
||||
RECT bounds = SHAPERECORD.getBounds(records);
|
||||
int maxLineWidthTwips = 0;
|
||||
if (shape instanceof SHAPEWITHSTYLE) {
|
||||
SHAPEWITHSTYLE shapeWithStyle = (SHAPEWITHSTYLE) shape;
|
||||
for (LINESTYLE lineStyle : shapeWithStyle.lineStyles.lineStyles) {
|
||||
if (lineStyle.width > maxLineWidthTwips) {
|
||||
maxLineWidthTwips = lineStyle.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
unitDivisor = SWF.unitDivisor;
|
||||
double maxLineWidth = maxLineWidthTwips / unitDivisor / 2;
|
||||
deltaX = bounds.Xmin / unitDivisor - maxLineWidth;
|
||||
deltaY = bounds.Ymin / unitDivisor - maxLineWidth;
|
||||
double width = bounds.getWidth() / unitDivisor + 2 * (maxLineWidth + 1);
|
||||
double height = bounds.getHeight() / unitDivisor + 2 * (maxLineWidth + 1);
|
||||
image = new SerializableImage((int) width, (int) height, SerializableImage.TYPE_INT_ARGB);
|
||||
image.fillTransparent();
|
||||
|
||||
graphics = (Graphics2D) image.getGraphics();
|
||||
|
||||
defaultStroke = graphics.getStroke();
|
||||
super.export();
|
||||
}
|
||||
|
||||
private void exportTo(SerializableImage image, Matrix transformation) {
|
||||
this.image = image;
|
||||
graphics = (Graphics2D) image.getGraphics();
|
||||
|
||||
134
trunk/src/com/jpexs/decompiler/flash/exporters/PathExporter.java
Normal file
134
trunk/src/com/jpexs/decompiler/flash/exporters/PathExporter.java
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.GRADRECORD;
|
||||
import com.jpexs.decompiler.flash.types.RGB;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class PathExporter extends ShapeExporterBase {
|
||||
|
||||
private final List<GeneralPath> paths = new ArrayList<>();
|
||||
private GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
|
||||
|
||||
private final double unitDivisor = 1;
|
||||
|
||||
public static List<GeneralPath> export(SHAPE shape) {
|
||||
PathExporter exporter = new PathExporter(shape, new ColorTransform());
|
||||
exporter.export();
|
||||
return exporter.paths;
|
||||
}
|
||||
|
||||
private PathExporter(SHAPE shape, ColorTransform colorTransform) {
|
||||
super(shape, colorTransform);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void export() {
|
||||
super.export();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginShape() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endShape(double xMin, double yMin, double xMax, double yMax) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginFills() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endFills() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginLines() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endLines() {
|
||||
finalizePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginFill(RGB color) {
|
||||
finalizePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginGradientFill(int type, GRADRECORD[] gradientRecords, Matrix matrix, int spreadMethod, int interpolationMethod, float focalPointRatio) {
|
||||
finalizePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginBitmapFill(int bitmapId, Matrix matrix, boolean repeat, boolean smooth, ColorTransform colorTransform) {
|
||||
finalizePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endFill() {
|
||||
finalizePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lineStyle(double thickness, RGB color, boolean pixelHinting, String scaleMode, int startCaps, int endCaps, int joints, int miterLimit) {
|
||||
finalizePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lineGradientStyle(int type, GRADRECORD[] gradientRecords, Matrix matrix, int spreadMethod, int interpolationMethod, float focalPointRatio) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveTo(double x, double y) {
|
||||
path.moveTo(x / unitDivisor, y / unitDivisor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lineTo(double x, double y) {
|
||||
path.lineTo(x / unitDivisor, y / unitDivisor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void curveTo(double controlX, double controlY, double anchorX, double anchorY) {
|
||||
path.quadTo(controlX / unitDivisor, controlY / unitDivisor,
|
||||
anchorX / unitDivisor, anchorY / unitDivisor);
|
||||
}
|
||||
|
||||
protected void finalizePath() {
|
||||
paths.add(path);
|
||||
path = new GeneralPath(GeneralPath.WIND_EVEN_ODD); //For correct intersections display
|
||||
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,6 @@
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-97,0,0,1,-39"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.jpexs.decompiler.flash.tags.DefineButtonSoundTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.decompiler.flash.timeline.DepthState;
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
@@ -52,7 +51,6 @@ import java.awt.event.MouseListener;
|
||||
import java.awt.event.MouseMotionAdapter;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -122,6 +120,9 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
}
|
||||
|
||||
public Point toImagePoint(Point p) {
|
||||
if (img == null) {
|
||||
return null;
|
||||
}
|
||||
return new Point((p.x - rect.x) * img.getWidth() / rect.width, (p.y - rect.y) * img.getHeight() / rect.height);
|
||||
}
|
||||
|
||||
@@ -150,6 +151,8 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
}
|
||||
|
||||
rect = new Rectangle(getWidth() / 2 - w / 2, getHeight() / 2 - h / 2, w, h);
|
||||
} else {
|
||||
rect = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,13 +224,15 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
m.scale(scale);
|
||||
Point p = e.getPoint();
|
||||
p = iconPanel.toImagePoint(p);
|
||||
int x = p.x;
|
||||
int y = p.y;
|
||||
List<DepthState> objs = new ArrayList<>();
|
||||
objs = iconPanel.getObjectsUnderPoint(p);
|
||||
String ret = "";
|
||||
if (p != null) {
|
||||
int x = p.x;
|
||||
int y = p.y;
|
||||
objs = iconPanel.getObjectsUnderPoint(p);
|
||||
|
||||
ret += " [" + x + "," + y + "] : ";
|
||||
ret += " [" + x + "," + y + "] : ";
|
||||
}
|
||||
|
||||
boolean first = true;
|
||||
for (int i = 0; i < objs.size(); i++) {
|
||||
@@ -468,7 +473,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
soundPlayers.clear();
|
||||
}
|
||||
|
||||
private void nextFrame() {
|
||||
private void nextFrame(boolean first) {
|
||||
int newframe = frame == timelined.getTimeline().frames.size() - 1 ? 0 : frame + 1;
|
||||
if (stillFrame) {
|
||||
newframe = frame;
|
||||
@@ -480,13 +485,16 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
frame = newframe;
|
||||
time = 0;
|
||||
} else {
|
||||
if (!first && timelined.getTimeline().isSingleFrame()) {
|
||||
return;
|
||||
}
|
||||
time++;
|
||||
}
|
||||
drawFrame();
|
||||
}
|
||||
|
||||
private static SerializableImage getFrame(SWF swf, int frame, int time, Timelined drawable, DepthState stateUnderCursor, int mouseButton) {
|
||||
String key = "drawable_" + frame + "_" + drawable.hashCode() + "_" + mouseButton + "_" + (stateUnderCursor == null ? "out" : stateUnderCursor.hashCode()) + "_" + time;
|
||||
String key = "drawable_" + frame + "_" + drawable.hashCode() + "_" + mouseButton + "_" + (stateUnderCursor == null ? "out" : stateUnderCursor.hashCode());
|
||||
SerializableImage img = SWF.getFromCache(key);
|
||||
if (img == null) {
|
||||
if (drawable instanceof BoundedTag) {
|
||||
@@ -497,7 +505,6 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
}
|
||||
int width = rect.getWidth();
|
||||
int height = rect.getHeight();
|
||||
double scale = 1.0;
|
||||
SerializableImage image = new SerializableImage((int) (width / SWF.unitDivisor) + 1,
|
||||
(int) (height / SWF.unitDivisor) + 1, SerializableImage.TYPE_INT_ARGB);
|
||||
image.fillTransparent();
|
||||
@@ -519,18 +526,16 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
}*/
|
||||
|
||||
img = image;
|
||||
} else if (drawable instanceof FontTag) {
|
||||
// only DefineFont tags
|
||||
FontTag fontTag = (FontTag) drawable;
|
||||
img = fontTag.toImage(frame, frame, Matrix.getScaleInstance(1 / SWF.unitDivisor), new ColorTransform());
|
||||
}
|
||||
SWF.putToCache(key, img);
|
||||
if (drawable.getTimeline().isSingleFrame()) {
|
||||
SWF.putToCache(key, img);
|
||||
}
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
private void drawFrame() {
|
||||
if (timelined == null) {
|
||||
if (timelined == null || timelined.getTimeline().getFrameCount() <= frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -539,7 +544,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
mat.translateX = swf.displayRect.Xmin;
|
||||
mat.translateY = swf.displayRect.Ymin;
|
||||
updatePos(lastMouseEvent, false);
|
||||
BufferedImage img = getFrame(swf, frame, time, timelined, stateUnderCursor, mouseButton).getBufferedImage();
|
||||
SerializableImage img = getFrame(swf, frame, time, timelined, stateUnderCursor, mouseButton);
|
||||
List<Integer> sounds = new ArrayList<>();
|
||||
List<String> soundClasses = new ArrayList<>();
|
||||
timelined.getTimeline().getSounds(frame, time, stateUnderCursor, mouseButton, sounds, soundClasses);
|
||||
@@ -559,7 +564,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
}
|
||||
}
|
||||
|
||||
iconPanel.setImg(new SerializableImage(img));
|
||||
iconPanel.setImg(img);
|
||||
}
|
||||
|
||||
private void playSound(SoundTag st) {
|
||||
@@ -613,9 +618,12 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
if (timelined != null) {
|
||||
timer = new Timer();
|
||||
timer.schedule(new TimerTask() {
|
||||
boolean first = true;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
nextFrame();
|
||||
nextFrame(first);
|
||||
first = false;
|
||||
}
|
||||
}, 0, 1000 / timelined.getTimeline().frameRate);
|
||||
} else {
|
||||
|
||||
@@ -22,7 +22,6 @@ 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;
|
||||
@@ -157,12 +156,7 @@ public class PreviewImage extends JPanel {
|
||||
int height = 0;
|
||||
SerializableImage imgSrc = null;
|
||||
Matrix m = new Matrix();
|
||||
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 (treeItem instanceof FrameNodeItem) {
|
||||
if (treeItem instanceof FrameNodeItem) {
|
||||
FrameNodeItem fn = (FrameNodeItem) treeItem;
|
||||
RECT rect = swf.displayRect;
|
||||
imgSrc = SWF.frameToImageGet(swf.getTimeline(), fn.getFrame() - 1, 0, null, 0, rect, Matrix.getScaleInstance(1 / SWF.unitDivisor), new ColorTransform(), null);
|
||||
|
||||
@@ -83,6 +83,9 @@ public class DefineButton2Tag extends ButtonTag implements Container {
|
||||
|
||||
private Timeline timeline;
|
||||
|
||||
private boolean isSingleFrameInitialized;
|
||||
private boolean isSingleFrame;
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return buttonId;
|
||||
@@ -252,6 +255,21 @@ public class DefineButton2Tag extends ButtonTag implements Container {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
initialiteIsSingleFrame();
|
||||
}
|
||||
return isSingleFrame;
|
||||
}
|
||||
|
||||
private synchronized void initialiteIsSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
isSingleFrame = getTimeline().isSingleFrame();
|
||||
isSingleFrameInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timeline getTimeline() {
|
||||
if (timeline != null) {
|
||||
|
||||
@@ -87,6 +87,9 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
|
||||
|
||||
private Timeline timeline;
|
||||
|
||||
private boolean isSingleFrameInitialized;
|
||||
private boolean isSingleFrame;
|
||||
|
||||
@Override
|
||||
public List<BUTTONRECORD> getRecords() {
|
||||
return characters;
|
||||
@@ -275,6 +278,21 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
initialiteIsSingleFrame();
|
||||
}
|
||||
return isSingleFrame;
|
||||
}
|
||||
|
||||
private synchronized void initialiteIsSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
isSingleFrame = getTimeline().isSingleFrame();
|
||||
isSingleFrameInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourcePrefix(GraphTextWriter writer) {
|
||||
return writer;
|
||||
|
||||
@@ -957,4 +957,9 @@ public class DefineEditTextTag extends TextTag {
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.exporters.BitmapExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.Matrix;
|
||||
import com.jpexs.decompiler.flash.exporters.Point;
|
||||
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.MorphShapeTag;
|
||||
@@ -59,7 +58,7 @@ import java.util.Set;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineMorphShape2Tag extends CharacterTag implements BoundedTag, MorphShapeTag, DrawableTag {
|
||||
public class DefineMorphShape2Tag extends CharacterTag implements MorphShapeTag, DrawableTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterId;
|
||||
@@ -322,7 +321,7 @@ public class DefineMorphShape2Tag extends CharacterTag implements BoundedTag, Mo
|
||||
// todo: Currently the generated image is not cached, because the cache
|
||||
// key contains the hashCode of the finalRecord object, and it is always
|
||||
// recreated
|
||||
BitmapExporter.exportTo(swf, shape, null, image, transformation, colorTransform);
|
||||
BitmapExporter.export(swf, shape, null, image, transformation, colorTransform);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -337,6 +336,12 @@ public class DefineMorphShape2Tag extends CharacterTag implements BoundedTag, Mo
|
||||
return 65536;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
// Morpshape is a single frame specified with the ratio
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) {
|
||||
return transformation.toTransform().createTransformedShape(getShapeAtRatio(ratio).getOutline());
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.exporters.BitmapExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.Matrix;
|
||||
import com.jpexs.decompiler.flash.exporters.Point;
|
||||
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.MorphShapeTag;
|
||||
@@ -58,7 +57,7 @@ import java.util.Set;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineMorphShapeTag extends CharacterTag implements BoundedTag, MorphShapeTag, DrawableTag {
|
||||
public class DefineMorphShapeTag extends CharacterTag implements MorphShapeTag, DrawableTag {
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterId;
|
||||
@@ -305,7 +304,7 @@ public class DefineMorphShapeTag extends CharacterTag implements BoundedTag, Mor
|
||||
// todo: Currently the generated image is not cached, because the cache
|
||||
// key contains the hashCode of the finalRecord object, and it is always
|
||||
// recreated
|
||||
BitmapExporter.exportTo(swf, shape, null, image, transformation, colorTransform);
|
||||
BitmapExporter.export(swf, shape, null, image, transformation, colorTransform);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -320,6 +319,12 @@ public class DefineMorphShapeTag extends CharacterTag implements BoundedTag, Mor
|
||||
return 65536;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
// Morpshape is a single frame specified with the ratio
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) {
|
||||
return transformation.toTransform().createTransformedShape(getShapeAtRatio(ratio).getOutline());
|
||||
|
||||
@@ -87,4 +87,9 @@ public class DefineShape2Tag extends ShapeTag {
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,4 +91,9 @@ public class DefineShape3Tag extends ShapeTag {
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,4 +100,9 @@ public class DefineShape4Tag extends ShapeTag {
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,4 +111,9 @@ public class DefineShapeTag extends ShapeTag {
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ import java.util.Set;
|
||||
/**
|
||||
* Defines a sprite character
|
||||
*/
|
||||
public class DefineSpriteTag extends CharacterTag implements Container, BoundedTag, DrawableTag, Timelined {
|
||||
public class DefineSpriteTag extends CharacterTag implements Container, DrawableTag, Timelined {
|
||||
|
||||
/**
|
||||
* Character ID of sprite
|
||||
@@ -75,6 +75,9 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
|
||||
|
||||
private Timeline timeline;
|
||||
|
||||
private boolean isSingleFrameInitialized;
|
||||
private boolean isSingleFrame;
|
||||
|
||||
@Override
|
||||
public Timeline getTimeline() {
|
||||
if (timeline == null) {
|
||||
@@ -282,6 +285,26 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
|
||||
return frameCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
initialiteIsSingleFrame();
|
||||
}
|
||||
return isSingleFrame;
|
||||
}
|
||||
|
||||
private synchronized void initialiteIsSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
if (frameCount > 1) {
|
||||
isSingleFrameInitialized = true;
|
||||
return;
|
||||
}
|
||||
|
||||
isSingleFrame = getTimeline().isSingleFrame();
|
||||
isSingleFrameInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) {
|
||||
return getTimeline().getOutline(frame, time, ratio, stateUnderCursor, mouseButton, transformation);
|
||||
|
||||
@@ -501,4 +501,9 @@ public class DefineText2Tag extends TextTag {
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,4 +517,9 @@ public class DefineTextTag extends TextTag {
|
||||
public int getNumFrames() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import java.util.List;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public abstract class ButtonTag extends CharacterTag implements BoundedTag, DrawableTag, Timelined {
|
||||
public abstract class ButtonTag extends CharacterTag implements DrawableTag, Timelined {
|
||||
|
||||
public static int FRAME_UP = 0;
|
||||
public static int FRAME_OVER = 1;
|
||||
|
||||
@@ -27,7 +27,7 @@ import java.awt.Shape;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface DrawableTag {
|
||||
public interface DrawableTag extends BoundedTag {
|
||||
|
||||
public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform);
|
||||
|
||||
@@ -35,5 +35,7 @@ public interface DrawableTag {
|
||||
|
||||
public int getNumFrames();
|
||||
|
||||
public boolean isSingleFrame();
|
||||
|
||||
public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation);
|
||||
}
|
||||
|
||||
@@ -32,10 +32,8 @@ import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import com.jpexs.decompiler.flash.types.TEXTRECORD;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.font.FontRenderContext;
|
||||
@@ -51,7 +49,9 @@ import java.util.Map;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public abstract class FontTag extends CharacterTag implements AloneTag, BoundedTag, DrawableTag {
|
||||
public abstract class FontTag extends CharacterTag implements AloneTag, DrawableTag {
|
||||
|
||||
protected final int previewSize = 500;
|
||||
|
||||
public FontTag(SWF swf, int id, String name, byte[] data, long pos) {
|
||||
super(swf, id, name, data, pos);
|
||||
@@ -252,15 +252,9 @@ public abstract class FontTag extends CharacterTag implements AloneTag, BoundedT
|
||||
return defaultFontName;
|
||||
}
|
||||
|
||||
public SerializableImage toImage(int frame, int ratio, Matrix transformation, ColorTransform colorTransform) {
|
||||
return SHAPERECORD.shapeListToImage(swf, getGlyphShapeTable(), 500, 500, Color.black, colorTransform);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
g.setComposite(AlphaComposite.SrcOver);
|
||||
g.drawImage(toImage(0, 0, new Matrix(), colorTransform).getBufferedImage(), transformation.toTransform(), null);
|
||||
SHAPERECORD.shapeListToImage(swf, getGlyphShapeTable(), image, Color.black, colorTransform);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -273,6 +267,11 @@ public abstract class FontTag extends CharacterTag implements AloneTag, BoundedT
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) {
|
||||
RECT r = getRect();
|
||||
@@ -281,7 +280,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, BoundedT
|
||||
|
||||
@Override
|
||||
public RECT getRect() {
|
||||
return new RECT(0, (int) (500 * SWF.unitDivisor), 0, (int) (500 * SWF.unitDivisor));
|
||||
return new RECT(0, (int) (previewSize * SWF.unitDivisor), 0, (int) (previewSize * SWF.unitDivisor));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,6 +48,6 @@ public abstract class ShapeTag extends CharacterTag implements BoundedTag, Drawa
|
||||
|
||||
@Override
|
||||
public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
|
||||
BitmapExporter.exportTo(swf, getShapes(), null, image, transformation, colorTransform);
|
||||
BitmapExporter.export(swf, getShapes(), null, image, transformation, colorTransform);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ public abstract class TextTag extends CharacterTag implements BoundedTag, Drawab
|
||||
shape.shapeRecords.add(bottom);
|
||||
shape.shapeRecords.add(left);
|
||||
shape.shapeRecords.add(new EndShapeRecord());
|
||||
BitmapExporter.exportTo(swf, shape, null, image, mat, colorTransform);
|
||||
BitmapExporter.export(swf, shape, null, image, mat, colorTransform);
|
||||
}
|
||||
|
||||
public static void staticTextToImage(SWF swf, List<TEXTRECORD> textRecords, int numText, SerializableImage image, MATRIX textMatrix, Matrix transformation, ColorTransform colorTransform) {
|
||||
@@ -294,7 +294,7 @@ public abstract class TextTag extends CharacterTag implements BoundedTag, Drawab
|
||||
if (entry.glyphIndex != -1) {
|
||||
// shapeNum: 1
|
||||
SHAPE shape = glyphs.get(entry.glyphIndex);
|
||||
BitmapExporter.exportTo(swf, shape, textColor, image, mat, colorTransform);
|
||||
BitmapExporter.export(swf, shape, textColor, image, mat, colorTransform);
|
||||
x += entry.glyphAdvance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,13 +19,11 @@ package com.jpexs.decompiler.flash.tags.gfx;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
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.DefineFont2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.KERNINGRECORD;
|
||||
import com.jpexs.decompiler.flash.types.LANGCODE;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
@@ -41,8 +39,6 @@ import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -111,21 +107,6 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag {
|
||||
shapeCache = fonts.get(0).getGlyphShapes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerializableImage toImage(int frame, int ratio, Matrix transformation, ColorTransform colorTransform) {
|
||||
List<SHAPE> shapes = new ArrayList<>();
|
||||
for (int i = 0; i < shapeCache.size(); i++) {
|
||||
shapes.add(SHAPERECORD.resizeSHAPE(shapeCache.get(i), SWF.unitDivisor));
|
||||
}
|
||||
int cols = (int) Math.ceil(Math.sqrt(shapes.size()));
|
||||
int size = 500;
|
||||
if (size / cols < 30) {
|
||||
size = cols * 30;
|
||||
}
|
||||
SerializableImage ret = SHAPERECORD.shapeListToImage(swf, shapes, size, size, Color.black, colorTransform);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getImagePos(int frame) {
|
||||
return new Point(0, 0);
|
||||
|
||||
34
trunk/src/com/jpexs/decompiler/flash/timeline/Clip.java
Normal file
34
trunk/src/com/jpexs/decompiler/flash/timeline/Clip.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.timeline;
|
||||
|
||||
import java.awt.Shape;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class Clip {
|
||||
|
||||
public Shape shape;
|
||||
public int depth;
|
||||
|
||||
public Clip(Shape shape, int depth) {
|
||||
this.shape = shape;
|
||||
this.depth = depth;
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,6 @@ public class DepthState {
|
||||
public DepthState(DepthState obj, Frame frame, boolean sameInstance) {
|
||||
this.frame = frame;
|
||||
swf = obj.swf;
|
||||
frame = obj.frame;
|
||||
characterId = obj.characterId;
|
||||
matrix = obj.matrix;
|
||||
instanceName = obj.instanceName;
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.jpexs.decompiler.flash.timeline;
|
||||
import com.jpexs.decompiler.flash.tags.DoActionTag;
|
||||
import com.jpexs.decompiler.flash.types.RGB;
|
||||
import com.jpexs.decompiler.flash.types.RGBA;
|
||||
import java.awt.Shape;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TreeMap;
|
||||
@@ -50,16 +49,4 @@ public class Frame {
|
||||
}
|
||||
//Do not copy sounds
|
||||
}
|
||||
|
||||
private class Clip {
|
||||
|
||||
public Shape shape;
|
||||
public int depth;
|
||||
|
||||
public Clip(Shape shape, int depth) {
|
||||
this.shape = shape;
|
||||
this.depth = depth;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.jpexs.decompiler.flash.tags.ShowFrameTag;
|
||||
import com.jpexs.decompiler.flash.tags.StartSound2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.StartSoundTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
|
||||
@@ -171,18 +170,6 @@ public class Timeline {
|
||||
SWF.frameToImage(this, frame, time, stateUnderCursor, mouseButton, image, transformation, colorTransform);
|
||||
}
|
||||
|
||||
private class Clip {
|
||||
|
||||
public Shape shape;
|
||||
public int depth;
|
||||
|
||||
public Clip(Shape shape, int depth) {
|
||||
this.shape = shape;
|
||||
this.depth = depth;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void getSounds(int frame, int time, DepthState stateUnderCursor, int mouseButton, List<Integer> sounds, List<String> soundClasses) {
|
||||
Frame fr = this.frames.get(frame);
|
||||
sounds.addAll(fr.sounds);
|
||||
@@ -232,7 +219,7 @@ public class Timeline {
|
||||
continue;
|
||||
}
|
||||
CharacterTag c = swf.characters.get(ds.characterId);
|
||||
if ((c instanceof DrawableTag) && (c instanceof BoundedTag)) {
|
||||
if (c instanceof DrawableTag) {
|
||||
Matrix m = new Matrix(ds.matrix);
|
||||
m = m.preConcatenate(transformation);
|
||||
|
||||
@@ -297,7 +284,7 @@ public class Timeline {
|
||||
continue;
|
||||
}
|
||||
CharacterTag c = swf.characters.get(ds.characterId);
|
||||
if ((c instanceof DrawableTag) && (c instanceof BoundedTag)) {
|
||||
if (c instanceof DrawableTag) {
|
||||
Matrix m = new Matrix(ds.matrix);
|
||||
m = m.preConcatenate(transformation);
|
||||
|
||||
@@ -334,4 +321,29 @@ public class Timeline {
|
||||
}
|
||||
return area;
|
||||
}
|
||||
|
||||
public boolean isSingleFrame() {
|
||||
Frame frameObj = frames.get(0);
|
||||
for (int i = 1; i <= getMaxDepth(); i++) {
|
||||
if (!frameObj.layers.containsKey(i)) {
|
||||
continue;
|
||||
}
|
||||
DepthState layer = frameObj.layers.get(i);
|
||||
if (!swf.characters.containsKey(layer.characterId)) {
|
||||
continue;
|
||||
}
|
||||
if (!layer.isVisible) {
|
||||
continue;
|
||||
}
|
||||
CharacterTag character = swf.characters.get(layer.characterId);
|
||||
if (character instanceof DrawableTag) {
|
||||
DrawableTag drawable = (DrawableTag) character;
|
||||
if (!drawable.isSingleFrame()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.types;
|
||||
|
||||
import com.jpexs.decompiler.flash.exporters.Matrix;
|
||||
import com.jpexs.decompiler.flash.exporters.ShapeExporterBase;
|
||||
import com.jpexs.decompiler.flash.exporters.PathExporter;
|
||||
import com.jpexs.decompiler.flash.tags.base.NeedsCharacters;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
@@ -25,7 +24,6 @@ import java.awt.Shape;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -56,101 +54,7 @@ public class SHAPE implements NeedsCharacters, Serializable {
|
||||
}
|
||||
|
||||
public Shape getOutline() {
|
||||
final List<GeneralPath> paths = new ArrayList<>();
|
||||
ShapeExporterBase se = new ShapeExporterBase(this, new ColorTransform()) {
|
||||
private GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
|
||||
|
||||
private double unitDivisor;
|
||||
|
||||
@Override
|
||||
public void export() {
|
||||
unitDivisor = 1;
|
||||
super.export();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginShape() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endShape(double xMin, double yMin, double xMax, double yMax) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginFills() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endFills() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginLines() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endLines() {
|
||||
finalizePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginFill(RGB color) {
|
||||
finalizePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginGradientFill(int type, GRADRECORD[] gradientRecords, Matrix matrix, int spreadMethod, int interpolationMethod, float focalPointRatio) {
|
||||
finalizePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginBitmapFill(int bitmapId, Matrix matrix, boolean repeat, boolean smooth, ColorTransform colorTransform) {
|
||||
finalizePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endFill() {
|
||||
finalizePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lineStyle(double thickness, RGB color, boolean pixelHinting, String scaleMode, int startCaps, int endCaps, int joints, int miterLimit) {
|
||||
finalizePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lineGradientStyle(int type, GRADRECORD[] gradientRecords, Matrix matrix, int spreadMethod, int interpolationMethod, float focalPointRatio) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveTo(double x, double y) {
|
||||
path.moveTo(x / unitDivisor, y / unitDivisor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lineTo(double x, double y) {
|
||||
path.lineTo(x / unitDivisor, y / unitDivisor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void curveTo(double controlX, double controlY, double anchorX, double anchorY) {
|
||||
path.quadTo(controlX / unitDivisor, controlY / unitDivisor,
|
||||
anchorX / unitDivisor, anchorY / unitDivisor);
|
||||
}
|
||||
|
||||
protected void finalizePath() {
|
||||
paths.add(path);
|
||||
path = new GeneralPath(GeneralPath.WIND_EVEN_ODD); //For correct intersections display
|
||||
|
||||
}
|
||||
};
|
||||
se.export();
|
||||
List<GeneralPath> paths = PathExporter.export(this);
|
||||
Area area = new Area();
|
||||
for (GeneralPath path : paths) {
|
||||
area.add(new Area(path));
|
||||
|
||||
@@ -19,23 +19,26 @@ package com.jpexs.decompiler.flash.types.shaperecords;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.exporters.BitmapExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.Matrix;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.NeedsCharacters;
|
||||
import com.jpexs.decompiler.flash.tags.base.TextTag;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.RGB;
|
||||
import com.jpexs.decompiler.flash.types.RGBA;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.PathIterator;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
@@ -50,6 +53,7 @@ import javax.swing.JPanel;
|
||||
public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Serializable {
|
||||
|
||||
public static final int MAX_CHARACTERS_IN_FONT_PREVIEW = 400;
|
||||
private static final boolean DRAW_BOUNDING_BOX = false;
|
||||
|
||||
public abstract void calculateBits();
|
||||
|
||||
@@ -125,34 +129,42 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static SerializableImage shapeListToImage(SWF swf, List<SHAPE> shapes, int prevWidth, int prevHeight, Color color, ColorTransform colorTransform) {
|
||||
public static void shapeListToImage(SWF swf, List<SHAPE> shapes, SerializableImage image, Color color, ColorTransform colorTransform) {
|
||||
if (shapes.isEmpty()) {
|
||||
SerializableImage image = new SerializableImage(1, 1, BufferedImage.TYPE_INT_RGB);
|
||||
image.fillTransparent();
|
||||
return image;
|
||||
return;
|
||||
}
|
||||
SerializableImage ret = new SerializableImage(prevWidth, prevHeight, SerializableImage.TYPE_INT_ARGB);
|
||||
Graphics g = ret.getGraphics();
|
||||
|
||||
int prevWidth = image.getWidth();
|
||||
int prevHeight = image.getHeight();
|
||||
|
||||
int maxw = 0;
|
||||
int maxh = 0;
|
||||
int minXMin = 0;
|
||||
int minYMin = 0;
|
||||
for (SHAPE s : shapes) {
|
||||
RECT r = SHAPERECORD.getBounds(s.shapeRecords);
|
||||
if (r.Xmax < r.Xmin || r.Ymax < r.Ymin) {
|
||||
continue;
|
||||
}
|
||||
if (r.getWidth() > maxw) {
|
||||
maxw = r.getWidth();
|
||||
}
|
||||
if (r.getHeight() > maxh) {
|
||||
maxh = r.getHeight();
|
||||
}
|
||||
if (r.Xmin < minXMin) {
|
||||
minXMin = r.Xmin;
|
||||
}
|
||||
if (r.Ymin < minYMin) {
|
||||
minYMin = r.Ymin;
|
||||
}
|
||||
}
|
||||
maxw /= SWF.unitDivisor;
|
||||
maxh /= SWF.unitDivisor;
|
||||
|
||||
int shapeCount = Math.min(MAX_CHARACTERS_IN_FONT_PREVIEW, shapes.size());
|
||||
int cols = (int) Math.ceil(Math.sqrt(shapeCount));
|
||||
int pos = 0;
|
||||
int w2 = prevWidth / cols;
|
||||
int h2 = prevHeight / cols;
|
||||
int w2 = (int) (prevWidth * SWF.unitDivisor / cols);
|
||||
int h2 = (int) (prevHeight * SWF.unitDivisor / cols);
|
||||
|
||||
int mh = maxh * w2 / maxw;
|
||||
int mw;
|
||||
@@ -173,21 +185,33 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali
|
||||
}
|
||||
|
||||
// shapeNum: 1
|
||||
SerializableImage img = BitmapExporter.export(swf, shapes.get(pos), color, colorTransform);
|
||||
SHAPE shape = shapes.get(pos);
|
||||
List<SHAPERECORD> records = shape.shapeRecords;
|
||||
RECT bounds = SHAPERECORD.getBounds(records);
|
||||
|
||||
int w1 = img.getWidth();
|
||||
int h1 = img.getHeight();
|
||||
int w1 = bounds.getWidth();
|
||||
int h1 = bounds.getHeight();
|
||||
|
||||
int w = Math.round(ratio * w1);
|
||||
int h = Math.round(ratio * h1);
|
||||
int px = x * w2 + w2 / 2 - w / 2;
|
||||
int py = y * h2 + w2 - h;
|
||||
g.drawImage(img.getBufferedImage(), px, py, px + w, py + h, 0, 0, w1, h1, null);
|
||||
double w = ratio * w1;
|
||||
double h = ratio * h1;
|
||||
double px = x * w2 + w2 / 2 - w / 2 - minXMin * ratio;
|
||||
double py = y * h2 - minYMin * ratio;
|
||||
|
||||
Matrix transformation = new Matrix();
|
||||
transformation.translate(px, py);
|
||||
transformation = transformation.concatenate(Matrix.getScaleInstance(ratio));
|
||||
BitmapExporter.export(swf, shape, color, image, transformation, colorTransform);
|
||||
|
||||
// draw bounding boxes
|
||||
if (DRAW_BOUNDING_BOX) {
|
||||
RGB borderColor = new RGBA(Color.black);
|
||||
RGB fillColor = new RGBA(new Color(255, 255, 255, 0));
|
||||
transformation = Matrix.getTranslateInstance(bounds.Xmin, bounds.Ymin).preConcatenate(transformation);
|
||||
TextTag.drawBorder(swf, image, borderColor, fillColor, bounds, new MATRIX(), transformation, colorTransform);
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public abstract boolean isMove();
|
||||
|
||||
Reference in New Issue
Block a user