Bitmap rendering improved

This commit is contained in:
Honfika
2014-02-23 13:29:01 +01:00
parent 1643910051
commit ccc6099687
36 changed files with 583 additions and 323 deletions
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2010-2014 PEXS
*
* 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;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import java.awt.Color;
import java.util.Map;
/**
*
* @author JPEXS
*/
public class FrameInfo {
public int maxDepth;
public Map<Integer, Layer> layers;
public Color backgroundColor;
public Map<Integer, CharacterTag> characters;
public int frame;
}
+196 -169
View File
@@ -52,6 +52,7 @@ import com.jpexs.decompiler.flash.action.swf5.ActionSetMember;
import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.ecma.Null;
import com.jpexs.decompiler.flash.exporters.ExportRectangle;
import com.jpexs.decompiler.flash.exporters.Matrix;
import com.jpexs.decompiler.flash.flv.AUDIODATA;
import com.jpexs.decompiler.flash.flv.FLVOutputStream;
@@ -125,7 +126,6 @@ import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -175,7 +175,7 @@ public final class SWF implements TreeItem {
*/
public List<Tag> tags = new ArrayList<>();
/**
* Rectangle for the display
* ExportRectangle for the display
*/
public RECT displayRect;
/**
@@ -2129,180 +2129,37 @@ public final class SWF implements TreeItem {
return ret;
}
public static SerializableImage frameToImage(int containerId, int maxDepth, HashMap<Integer, Layer> layers, Color backgroundColor, HashMap<Integer, CharacterTag> characters, int frame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect, Stack<Integer> visited, Matrix transformation) {
public static SerializableImage frameToImage(int containerId, int frame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect, int totalFrameCount, Stack<Integer> visited, Matrix transformation) {
String key = "frame_" + frame + "_" + containerId;
if (frameCache.contains(key)) {
SerializableImage ciret = ((SerializableImage) frameCache.get(key));
return ciret;
}
float unzoom = (float) SWF.unitDivisor;
int fixX = -displayRect.Xmin;
int fixY = -displayRect.Ymin;
displayRect = fixRect(displayRect);
int width = displayRect.getWidth();
int height = displayRect.getHeight();
SerializableImage ret = new SerializableImage((int) (width / unzoom), (int) (height / unzoom), SerializableImage.TYPE_INT_ARGB);
ret.bounds = new Rectangle2D.Double(-fixX / unzoom, -fixY / unzoom, width / unzoom, height / unzoom);
Graphics2D g = (Graphics2D) ret.getGraphics();
g.setPaint(backgroundColor);
g.fill(new Rectangle(ret.getWidth(), ret.getHeight()));
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (int i = 1; i <= maxDepth; i++) {
if (!layers.containsKey(i)) {
continue;
}
Layer layer = layers.get(i);
if (!characters.containsKey(layer.characterId)) {
continue;
}
if (!layer.visible) {
continue;
}
CharacterTag character = characters.get(layer.characterId);
Matrix mat = new Matrix(layer.matrix);
/*if (firstLevel) {
mat.scale(unzoom);
}*/
mat.translate(fixX, fixY);
if (character instanceof DrawableTag) {
DrawableTag drawable = (DrawableTag) character;
SerializableImage img = drawable.toImage(layer.ratio < 0 ? 0 : layer.ratio/*layer.duration*/, allTags, characters, visited, transformation);
mat.translate(img.bounds.getMinX() * unzoom, img.bounds.getMinY() * unzoom);
/*if (character instanceof BoundedTag) {
BoundedTag bounded = (BoundedTag) character;
RECT rect = bounded.getRect(characters, visited);
}*/
if (layer.filters != null) {
for (FILTER filter : layer.filters) {
img = filter.apply(img);
}
}
if (layer.colorTransForm != null) {
img = layer.colorTransForm.apply(img);
}
if (layer.colorTransFormAlpha != null) {
img = layer.colorTransFormAlpha.apply(img);
}
switch (layer.blendMode) {
case 0:
case 1:
g.setComposite(AlphaComposite.SrcOver);
break;
case 2: //TODO:Layer
g.setComposite(AlphaComposite.SrcOver);
break;
case 3:
g.setComposite(BlendComposite.Multiply);
break;
case 4:
g.setComposite(BlendComposite.Screen);
break;
case 5:
g.setComposite(BlendComposite.Lighten);
break;
case 6:
g.setComposite(BlendComposite.Darken);
break;
case 7:
g.setComposite(BlendComposite.Difference);
break;
case 8:
g.setComposite(BlendComposite.Add);
break;
case 9:
g.setComposite(BlendComposite.Subtract);
break;
case 10:
g.setComposite(BlendComposite.Invert);
break;
case 11:
g.setComposite(BlendComposite.Alpha);
break;
case 12:
g.setComposite(BlendComposite.Erase);
break;
case 13:
g.setComposite(BlendComposite.Overlay);
break;
case 14:
g.setComposite(BlendComposite.HardLight);
break;
default: //Not implemented
g.setComposite(AlphaComposite.SrcOver);
break;
}
mat.translateX /= unzoom;
mat.translateY /= unzoom;
AffineTransform trans = mat.toTransform();
g.setTransform(trans);
g.drawImage(img.getBufferedImage(), 0, 0, null);
} else if (character instanceof BoundedTag) {
mat.translateX /= unzoom;
mat.translateY /= unzoom;
AffineTransform trans = mat.toTransform();
g.setTransform(trans);
BoundedTag b = (BoundedTag) character;
g.setPaint(new Color(255, 255, 255, 128));
g.setComposite(BlendComposite.Invert);
RECT r = b.getRect(characters, visited);
int div = (int) unzoom;
g.drawString(character.toString(), r.Xmin / div + 3, r.Ymin / div + 15);
g.draw(new Rectangle(r.Xmin / div, r.Ymin / div, r.getWidth() / div, r.getHeight() / div));
g.drawLine(r.Xmin / div, r.Ymin / div, r.Xmax / div, r.Ymax / div);
g.drawLine(r.Xmax / div, r.Ymin / div, r.Xmin / div, r.Ymax / div);
g.setComposite(AlphaComposite.Dst);
}
}
g.setTransform(AffineTransform.getScaleInstance(1, 1));
/*g.setPaint(Color.yellow);
g.draw(new Rectangle(ret.getWidth()-1,ret.getHeight()-1));*/
frameCache.put(key, ret);
/*try {
ImageIO.write(ret, "png", new File("tst_id_" + containerId + "_time_" + System.currentTimeMillis() + ".png"));
} catch (IOException ex) {
Logger.getLogger(SWF.class.getName()).log(Level.SEVERE, null, ex);
}*/
return ret;
}
public static SerializableImage frameToImage(int containerId, int frame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect, int totalFrameCount, Stack<Integer> visited, Matrix transformation) {
List<SerializableImage> ret = new ArrayList<>();
framesToImage(containerId, ret, frame, frame, allTags, controlTags, displayRect, totalFrameCount, visited, transformation);
if (ret.isEmpty()) {
List<FrameInfo> frameInfos = getFrameInfo(frame, frame, allTags, controlTags, totalFrameCount);
if (frameInfos.isEmpty()) {
return new SerializableImage(1, 1, SerializableImage.TYPE_INT_ARGB);
}
return ret.get(0);
FrameInfo fi = frameInfos.get(0);
RECT rect = displayRect;
SerializableImage image = new SerializableImage((int) (rect.getWidth() / SWF.unitDivisor) + 1,
(int) (rect.getHeight() / SWF.unitDivisor) + 1, SerializableImage.TYPE_INT_ARGB);
Matrix m = new Matrix();
m.translate(-rect.Xmin, -rect.Ymin);
frameToImage(containerId, fi.maxDepth, fi.layers, fi.backgroundColor, fi.characters, fi.frame, allTags, controlTags, displayRect, visited, image, m);
frameCache.put(key, image);
return image;
}
public static void framesToImage(int containerId, List<SerializableImage> ret, int startFrame, int stopFrame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect, int totalFrameCount, Stack<Integer> visited, Matrix transformation) {
for (int i = startFrame; i <= stopFrame; i++) {
String key = "frame_" + i + "_" + containerId;
if (frameCache.contains(key)) {
SerializableImage g = (SerializableImage) frameCache.get(key);
if (g == null) {
break;
}
ret.add(g);
startFrame++;
} else {
break;
}
}
private static List<FrameInfo> getFrameInfo(int startFrame, int stopFrame, List<Tag> allTags, List<Tag> controlTags, int totalFrameCount) {
List<FrameInfo> ret = new ArrayList<>();
if (startFrame > stopFrame) {
return;
return ret;
}
if (totalFrameCount == 0) {
return;
return ret;
}
while (startFrame >= totalFrameCount) {
@@ -2313,7 +2170,7 @@ public final class SWF implements TreeItem {
stopFrame -= totalFrameCount;
}
HashMap<Integer, CharacterTag> characters = new HashMap<>();
Map<Integer, CharacterTag> characters = new HashMap<>();
for (Tag t : allTags) {
if (t instanceof CharacterTag) {
CharacterTag ch = (CharacterTag) t;
@@ -2321,7 +2178,7 @@ public final class SWF implements TreeItem {
}
}
HashMap<Integer, Layer> layers = new HashMap<>();
Map<Integer, Layer> layers = new HashMap<>();
int maxDepth = 0;
int f = 0;
@@ -2401,15 +2258,185 @@ public final class SWF implements TreeItem {
l.duration++;
}
if (t instanceof ShowFrameTag) {
if ((f >= startFrame) && (f <= stopFrame)) {
FrameInfo fi = new FrameInfo();
fi.maxDepth = maxDepth;
fi.layers = layers;
fi.backgroundColor = backgroundColor;
fi.characters = characters;
fi.frame = f;
ret.add(fi);
}
f++;
if (f > stopFrame) {
break;
}
if ((f >= startFrame) && (f <= stopFrame)) {
ret.add(frameToImage(containerId, maxDepth, layers, backgroundColor, characters, f, allTags, controlTags, displayRect, visited, transformation));
}
f++;
}
}
return ret;
}
public static void framesToImage(int containerId, List<SerializableImage> ret, int startFrame, int stopFrame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect, int totalFrameCount, Stack<Integer> visited, Matrix transformation) {
List<FrameInfo> frameInfos = getFrameInfo(startFrame, stopFrame, allTags, controlTags, totalFrameCount);
RECT rect = displayRect;
for (FrameInfo fi : frameInfos) {
SerializableImage image = new SerializableImage((int) (rect.getWidth() / SWF.unitDivisor) + 1,
(int) (rect.getHeight() / SWF.unitDivisor) + 1, SerializableImage.TYPE_INT_ARGB);
Matrix m = new Matrix();
m.translate(-rect.Xmin, -rect.Ymin);
frameToImage(containerId, fi.maxDepth, fi.layers, fi.backgroundColor, fi.characters, fi.frame, allTags, controlTags, displayRect, visited, image, m);
ret.add(image);
}
}
public static void frameToImage(int containerId, int maxDepth, Map<Integer, Layer> layers, Color backgroundColor, Map<Integer, CharacterTag> characters, int frame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect, Stack<Integer> visited, SerializableImage image, Matrix transformation) {
float unzoom = (float) SWF.unitDivisor;
Graphics2D g = (Graphics2D) image.getGraphics();
g.setPaint(backgroundColor);
g.fill(new Rectangle(image.getWidth(), image.getHeight()));
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setTransform(transformation.toTransform());
for (int i = 1; i <= maxDepth; i++) {
if (!layers.containsKey(i)) {
continue;
}
Layer layer = layers.get(i);
if (!characters.containsKey(layer.characterId)) {
continue;
}
if (!layer.visible) {
continue;
}
CharacterTag character = characters.get(layer.characterId);
Matrix mat = new Matrix(layer.matrix);
mat = mat.preConcatenate(transformation);
if (character instanceof DrawableTag) {
DrawableTag drawable = (DrawableTag) character;
SerializableImage img;
Matrix drawMatrix = new Matrix();
if (drawable instanceof BoundedTag) {
BoundedTag bounded = (BoundedTag) drawable;
RECT boundRect = bounded.getRect(characters, new Stack<Integer>());
ExportRectangle rect = new ExportRectangle(boundRect);
rect = mat.transform(rect);
img = new SerializableImage((int) (rect.getWidth() / SWF.unitDivisor) + 1,
(int) (rect.getHeight() / SWF.unitDivisor) + 1, SerializableImage.TYPE_INT_ARGB);
Matrix m = mat.clone();
m.translate(-rect.xMin, -rect.yMin);
drawMatrix.translate(rect.xMin, rect.yMin);
drawable.toImage(layer.ratio < 0 ? 0 : layer.ratio/*layer.duration*/, allTags, characters, visited, img, m);
} else {
img = drawable.toImage(layer.ratio < 0 ? 0 : layer.ratio/*layer.duration*/, allTags, characters, visited, transformation);
}
/*if (character instanceof BoundedTag) {
BoundedTag bounded = (BoundedTag) character;
RECT rect = bounded.getRect(characters, visited);
}*/
if (layer.filters != null) {
for (FILTER filter : layer.filters) {
img = filter.apply(img);
}
}
if (layer.colorTransForm != null) {
img = layer.colorTransForm.apply(img);
}
if (layer.colorTransFormAlpha != null) {
img = layer.colorTransFormAlpha.apply(img);
}
switch (layer.blendMode) {
case 0:
case 1:
g.setComposite(AlphaComposite.SrcOver);
break;
case 2: //TODO:Layer
g.setComposite(AlphaComposite.SrcOver);
break;
case 3:
g.setComposite(BlendComposite.Multiply);
break;
case 4:
g.setComposite(BlendComposite.Screen);
break;
case 5:
g.setComposite(BlendComposite.Lighten);
break;
case 6:
g.setComposite(BlendComposite.Darken);
break;
case 7:
g.setComposite(BlendComposite.Difference);
break;
case 8:
g.setComposite(BlendComposite.Add);
break;
case 9:
g.setComposite(BlendComposite.Subtract);
break;
case 10:
g.setComposite(BlendComposite.Invert);
break;
case 11:
g.setComposite(BlendComposite.Alpha);
break;
case 12:
g.setComposite(BlendComposite.Erase);
break;
case 13:
g.setComposite(BlendComposite.Overlay);
break;
case 14:
g.setComposite(BlendComposite.HardLight);
break;
default: //Not implemented
g.setComposite(AlphaComposite.SrcOver);
break;
}
drawMatrix.translateX /= unzoom;
drawMatrix.translateY /= unzoom;
g.setTransform(drawMatrix.toTransform());
g.drawImage(img.getBufferedImage(), 0, 0, null);
} else if (character instanceof BoundedTag) {
mat.translateX /= unzoom;
mat.translateY /= unzoom;
AffineTransform trans = mat.toTransform();
g.setTransform(trans);
BoundedTag b = (BoundedTag) character;
g.setPaint(new Color(255, 255, 255, 128));
g.setComposite(BlendComposite.Invert);
RECT r = b.getRect(characters, visited);
int div = (int) unzoom;
g.drawString(character.toString(), r.Xmin / div + 3, r.Ymin / div + 15);
g.draw(new Rectangle(r.Xmin / div, r.Ymin / div, r.getWidth() / div, r.getHeight() / div));
g.drawLine(r.Xmin / div, r.Ymin / div, r.Xmax / div, r.Ymax / div);
g.drawLine(r.Xmax / div, r.Ymin / div, r.Xmin / div, r.Ymax / div);
g.setComposite(AlphaComposite.Dst);
}
}
g.setTransform(AffineTransform.getScaleInstance(1, 1));
/*g.setPaint(Color.yellow);
g.draw(new ExportRectangle(ret.getWidth()-1,ret.getHeight()-1));*/
/*try {
ImageIO.write(ret, "png", new File("tst_id_" + containerId + "_time_" + System.currentTimeMillis() + ".png"));
} catch (IOException ex) {
Logger.getLogger(SWF.class.getName()).log(Level.SEVERE, null, ex);
}*/
}
public static void frameToImage(int containerId, int frame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect, int totalFrameCount, Stack<Integer> visited, SerializableImage image, Matrix transformation) {
List<FrameInfo> frameInfos = getFrameInfo(frame, frame, allTags, controlTags, totalFrameCount);
if (!frameInfos.isEmpty()) {
FrameInfo fi = frameInfos.get(0);
frameToImage(containerId, fi.maxDepth, fi.layers, fi.backgroundColor, fi.characters, fi.frame, allTags, controlTags, displayRect, visited, image, transformation);
}
}
public void removeTagFromTimeline(Tag toRemove, List<Tag> timeline) {
@@ -65,6 +65,8 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter
private Color lineColor;
private Stroke lineStroke;
private Stroke defaultStroke;
private Matrix transform;
private double unitDivisor;
public static SerializableImage export(SWF swf, SHAPE shape) {
BitmapExporter exporter = new BitmapExporter(swf, shape, null);
@@ -72,12 +74,17 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter
return exporter.getImage();
}
public static SerializableImage export(SWF swf, SHAPE shape, Color defaultColor, boolean putToCache) {
public static SerializableImage export(SWF swf, SHAPE shape, Color defaultColor) {
BitmapExporter exporter = new BitmapExporter(swf, shape, defaultColor);
exporter.export();
return exporter.getImage();
}
public static void exportTo(SWF swf, SHAPE shape, Color defaultColor, SerializableImage image, Matrix transformation) {
BitmapExporter exporter = new BitmapExporter(swf, shape, defaultColor);
exporter.exportTo(image, transformation);
}
private BitmapExporter(SWF swf, SHAPE shape, Color defaultColor) {
super(shape);
this.swf = swf;
@@ -97,11 +104,12 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter
}
}
}
double maxLineWidth = maxLineWidthTwips / SWF.unitDivisor / 2;
deltaX = bounds.Xmin / SWF.unitDivisor - maxLineWidth;
deltaY = bounds.Ymin / SWF.unitDivisor - maxLineWidth;
double width = bounds.getWidth() / SWF.unitDivisor + 2 * (maxLineWidth + 1);
double height = bounds.getHeight() / SWF.unitDivisor + 2 * (maxLineWidth + 1);
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);
graphics = (Graphics2D) image.getGraphics();
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
@@ -112,6 +120,21 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter
image.bounds = new Rectangle2D.Double(deltaX, deltaY, width, height);
}
private void exportTo(SerializableImage image, Matrix transformation) {
this.image = image;
this.transform = transformation;
graphics = (Graphics2D) image.getGraphics();
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
AffineTransform at = transformation.toTransform();
at.preConcatenate(AffineTransform.getScaleInstance(1 / SWF.unitDivisor, 1 / SWF.unitDivisor));
unitDivisor = 1;
graphics.setTransform(at);
defaultStroke = graphics.getStroke();
super.export();
}
public SerializableImage getImage() {
return image;
}
@@ -150,12 +173,12 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter
@Override
public void beginGradientFill(int type, GRADRECORD[] gradientRecords, Matrix matrix, int spreadMethod, int interpolationMethod, float focalPointRatio) {
finalizePath();
matrix.translateX /= SWF.unitDivisor;
matrix.translateY /= SWF.unitDivisor;
matrix.scaleX /= SWF.unitDivisor;
matrix.scaleY /= SWF.unitDivisor;
matrix.rotateSkew0 /= SWF.unitDivisor;
matrix.rotateSkew1 /= SWF.unitDivisor;
matrix.translateX /= unitDivisor;
matrix.translateY /= unitDivisor;
matrix.scaleX /= unitDivisor;
matrix.scaleY /= unitDivisor;
matrix.rotateSkew0 /= unitDivisor;
matrix.rotateSkew1 /= unitDivisor;
switch (type) {
case FILLSTYLE.LINEAR_GRADIENT: {
List<Color> colors = new ArrayList<>();
@@ -264,12 +287,12 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter
@Override
public void beginBitmapFill(int bitmapId, Matrix matrix, boolean repeat, boolean smooth) {
finalizePath();
matrix.translateX /= SWF.unitDivisor;
matrix.translateY /= SWF.unitDivisor;
matrix.scaleX /= SWF.unitDivisor;
matrix.scaleY /= SWF.unitDivisor;
matrix.rotateSkew0 /= SWF.unitDivisor;
matrix.rotateSkew1 /= SWF.unitDivisor;
matrix.translateX /= unitDivisor;
matrix.translateY /= unitDivisor;
matrix.scaleX /= unitDivisor;
matrix.scaleY /= unitDivisor;
matrix.rotateSkew0 /= unitDivisor;
matrix.rotateSkew1 /= unitDivisor;
ImageTag image = null;
for (Tag t : swf.tags) {
if (t instanceof ImageTag) {
@@ -300,7 +323,7 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter
@Override
public void lineStyle(double thickness, RGB color, boolean pixelHinting, String scaleMode, int startCaps, int endCaps, int joints, int miterLimit) {
finalizePath();
thickness /= SWF.unitDivisor;
thickness /= unitDivisor;
lineColor = color.toColor();
int capStyle = BasicStroke.CAP_ROUND;
switch (startCaps) {
@@ -339,18 +362,18 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter
@Override
public void moveTo(double x, double y) {
path.moveTo(x / SWF.unitDivisor - deltaX, y / SWF.unitDivisor - deltaY);
path.moveTo(x / unitDivisor - deltaX, y / unitDivisor - deltaY);
}
@Override
public void lineTo(double x, double y) {
path.lineTo(x / SWF.unitDivisor - deltaX, y / SWF.unitDivisor - deltaY);
path.lineTo(x / unitDivisor - deltaX, y / unitDivisor - deltaY);
}
@Override
public void curveTo(double controlX, double controlY, double anchorX, double anchorY) {
path.quadTo(controlX / SWF.unitDivisor - deltaX, controlY / SWF.unitDivisor - deltaY,
anchorX / SWF.unitDivisor - deltaX, anchorY / SWF.unitDivisor - deltaY);
path.quadTo(controlX / unitDivisor - deltaX, controlY / unitDivisor - deltaY,
anchorX / unitDivisor - deltaX, anchorY / unitDivisor - deltaY);
}
protected void finalizePath() {
@@ -364,6 +387,7 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter
}
graphics.fill(path);
graphics.setClip(path);
fillTransform.preConcatenate(oldAf);
graphics.setTransform(fillTransform);
graphics.setPaint(fillPaint);
@@ -373,6 +397,7 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter
} else if (fillPaint instanceof TexturePaint) {
AffineTransform oldAf = graphics.getTransform();
graphics.setClip(path);
fillTransform.preConcatenate(oldAf);
graphics.setTransform(fillTransform);
graphics.setPaint(fillPaint);
@@ -16,24 +16,41 @@
*/
package com.jpexs.decompiler.flash.exporters;
import com.jpexs.decompiler.flash.types.RECT;
/**
*
* @author JPEXS
*/
public class Rectangle {
public class ExportRectangle {
public double xMin;
public double yMin;
public double xMax;
public double yMax;
Rectangle(double xMin, double yMin, double xMax, double yMax) {
public ExportRectangle(double xMin, double yMin, double xMax, double yMax) {
this.xMin = xMin;
this.yMin = yMin;
this.xMax = xMax;
this.yMax = yMax;
}
public ExportRectangle(RECT rect) {
this.xMin = rect.Xmin;
this.yMin = rect.Ymin;
this.xMax = rect.Xmax;
this.yMax = rect.Ymax;
}
public double getWidth() {
return xMax - xMin;
}
public double getHeight() {
return yMax - yMin;
}
@Override
public int hashCode() {
long bits = Double.doubleToLongBits(xMin);
@@ -45,8 +62,8 @@ public class Rectangle {
@Override
public boolean equals(Object obj) {
if (obj instanceof Rectangle) {
Rectangle r = (Rectangle) obj;
if (obj instanceof ExportRectangle) {
ExportRectangle r = (ExportRectangle) obj;
return (xMin == r.xMin) && (yMin == r.yMin) && (xMax == r.xMax) && (yMax == r.yMax);
}
return super.equals(obj);
@@ -71,6 +71,46 @@ public class Matrix {
return mat;
}
public Point transform(double x, double y) {
Point result = new Point(
scaleX * x + rotateSkew1 * y + translateX,
rotateSkew0 * x + scaleY * y + translateY);
return result;
}
public Point transform(Point point) {
return transform(point.x, point.y);
}
public ExportRectangle transform(ExportRectangle rect) {
double minX = Double.MAX_VALUE;
double minY = Double.MAX_VALUE;
double maxX = Double.MIN_VALUE;
double maxY = Double.MIN_VALUE;
Point point;
point = transform(rect.xMin, rect.yMin);
if (point.x < minX) minX = point.x;
if (point.x > maxX) maxX = point.x;
if (point.y < minY) minY = point.y;
if (point.y > maxY) maxY = point.y;
point = transform(rect.xMax, rect.yMin);
if (point.x < minX) minX = point.x;
if (point.x > maxX) maxX = point.x;
if (point.y < minY) minY = point.y;
if (point.y > maxY) maxY = point.y;
point = transform(rect.xMin, rect.yMax);
if (point.x < minX) minX = point.x;
if (point.x > maxX) maxX = point.x;
if (point.y < minY) minY = point.y;
if (point.y > maxY) maxY = point.y;
point = transform(rect.xMax, rect.yMax);
if (point.x < minX) minX = point.x;
if (point.x > maxX) maxX = point.x;
if (point.y < minY) minY = point.y;
if (point.y > maxY) maxY = point.y;
return new ExportRectangle(minX, minY, maxX, maxY);
}
public void translate(double x, double y) {
translateX += x;
translateY += y;
@@ -83,6 +123,28 @@ public class Matrix {
rotateSkew1 *= factor;
}
public Matrix concatenate(Matrix m) {
Matrix result = new Matrix();
result.scaleX = scaleX * m.scaleX + rotateSkew1 * m.rotateSkew0;
result.rotateSkew0 = rotateSkew0 * m.scaleX + scaleY * m.rotateSkew0;
result.rotateSkew1 = scaleX * m.rotateSkew1 + rotateSkew1 * m.scaleY;
result.scaleY = rotateSkew0 * m.rotateSkew1 + scaleY * m.scaleY;
result.translateX = scaleX * m.translateX + rotateSkew1 * m.translateY + translateX;
result.translateY = rotateSkew0 * m.translateX + scaleY * m.translateY + translateY;
return result;
}
public Matrix preConcatenate(Matrix m) {
Matrix result = new Matrix();
result.scaleX = m.scaleX * scaleX + m.rotateSkew1 * rotateSkew0;
result.rotateSkew0 = m.rotateSkew0 * scaleX + m.scaleY * rotateSkew0;
result.rotateSkew1 = m.scaleX * rotateSkew1 + m.rotateSkew1 * scaleY;
result.scaleY = m.rotateSkew0 * rotateSkew1 + m.scaleY * scaleY;
result.translateX = m.scaleX * translateX + m.rotateSkew1 * translateY + m.translateX;
result.translateY = m.rotateSkew0 * translateX + m.scaleY * translateY + m.translateY;
return result;
}
public AffineTransform toTransform() {
AffineTransform transform = new AffineTransform(scaleX, rotateSkew0,
rotateSkew1, scaleY,
@@ -53,7 +53,7 @@ public abstract class ShapeExporterBase implements IShapeExporter {
protected Map<Integer, List<IEdge>> currentLineEdgeMap;
private int numGroups;
protected Map<String, List<IEdge>> coordMap;
private final Rectangle bounds = new Rectangle(Double.MAX_VALUE, Double.MAX_VALUE, Double.MIN_VALUE, Double.MIN_VALUE);
private final ExportRectangle bounds = new ExportRectangle(Double.MAX_VALUE, Double.MAX_VALUE, Double.MIN_VALUE, Double.MIN_VALUE);
private boolean edgeMapsCreated;
@@ -101,7 +101,7 @@ public class GenericTagTreePanel extends GenericTagPanel {
private class MyTreeCellEditor extends AbstractCellEditor implements TreeCellEditor {
private GenericTagEditor editor = null;
private JTree tree;
private final JTree tree;
public MyTreeCellEditor(JTree tree) {
this.tree = tree;
@@ -321,6 +321,7 @@ public class GenericTagTreePanel extends GenericTagPanel {
}
@Override
public void clear() {
}
@@ -445,8 +446,8 @@ public class GenericTagTreePanel extends GenericTagPanel {
private static class MyTreeModel extends DefaultTreeModel {
private Object root;
private List<TreeModelListener> listeners = new ArrayList<>();
private final Object root;
private final List<TreeModelListener> listeners = new ArrayList<>();
private DefaultMutableTreeNode rootNode;
public MyTreeModel(Tag root) {
@@ -526,6 +527,7 @@ public class GenericTagTreePanel extends GenericTagPanel {
return new MyTreeModel(editedTag);
}
@Override
public void setEditMode(boolean edit, Tag tag) {
if (tag == null) {
tag = this.tag;
@@ -536,6 +538,7 @@ public class GenericTagTreePanel extends GenericTagPanel {
tree.setEditable(edit);
}
@Override
public void save() {
tree.stopEditing();
SWF swf = tag.getSwf();
@@ -557,6 +560,7 @@ public class GenericTagTreePanel extends GenericTagPanel {
}
}
@Override
public Tag getTag() {
return tag;
}
@@ -20,8 +20,10 @@ import com.jpexs.decompiler.flash.AppStrings;
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.types.RECT;
import com.jpexs.helpers.SerializableImage;
import java.awt.BorderLayout;
import java.awt.Color;
@@ -127,7 +129,19 @@ public final class ImagePanel extends JPanel implements ActionListener, FlashDis
String key = "drawable_0_" + drawable.hashCode();
SerializableImage img = SWF.getFromCache(key);
if (img == null) {
img = drawable.toImage(0, swf.tags, characters, new Stack<Integer>(), Matrix.getScaleInstance(1 / SWF.unitDivisor));
if (drawable instanceof BoundedTag) {
BoundedTag bounded = (BoundedTag) drawable;
RECT rect = bounded.getRect(characters, new Stack<Integer>());
SerializableImage image = new SerializableImage((int) (rect.getWidth() / SWF.unitDivisor) + 1,
(int) (rect.getHeight() / SWF.unitDivisor) + 1, SerializableImage.TYPE_INT_ARGB);
Matrix m = new Matrix();
m.translate(-rect.Xmin, -rect.Ymin);
drawable.toImage(0, swf.tags, characters, new Stack<Integer>(), image, m);
img = image;
} else {
img = drawable.toImage(0, swf.tags, characters, new Stack<Integer>(), Matrix.getScaleInstance(1 / SWF.unitDivisor));
}
SWF.putToCache(key, img);
}
if (img != null && img.bounds != null && mat != null) {
@@ -189,7 +203,19 @@ public final class ImagePanel extends JPanel implements ActionListener, FlashDis
String key = "drawable_" + nframe + "_" + drawable.hashCode();
SerializableImage img = SWF.getFromCache(key);
if (img == null) {
img = drawable.toImage(nframe, swf.tags, characters, new Stack<Integer>(), Matrix.getScaleInstance(1 / SWF.unitDivisor));
if (drawable instanceof BoundedTag) {
BoundedTag bounded = (BoundedTag) drawable;
RECT rect = bounded.getRect(characters, new Stack<Integer>());
SerializableImage image = new SerializableImage((int) (rect.getWidth() / SWF.unitDivisor) + 1,
(int) (rect.getHeight() / SWF.unitDivisor) + 1, SerializableImage.TYPE_INT_ARGB);
Matrix m = new Matrix();
m.translate(-rect.Xmin, -rect.Ymin);
drawable.toImage(nframe, swf.tags, characters, new Stack<Integer>(), image, m);
img = image;
} else {
img = drawable.toImage(nframe, swf.tags, characters, new Stack<Integer>(), Matrix.getScaleInstance(1 / SWF.unitDivisor));
}
SWF.putToCache(key, img);
}
mat.translate(img.bounds.getMinX(), img.bounds.getMinY());
@@ -31,7 +31,7 @@ public class BooleanEditor extends JCheckBox implements GenericTagEditor {
private final Field field;
private final int index;
private final Class<?> type;
private String fieldName;
private final String fieldName;
public BooleanEditor(String fieldName,Object obj, Field field, int index, Class<?> type) {
super();
@@ -73,10 +73,12 @@ public class BooleanEditor extends JCheckBox implements GenericTagEditor {
return isSelected();
}
@Override
public String getFieldName() {
return fieldName;
}
@Override
public Field getField() {
return field;
}
@@ -46,7 +46,7 @@ public class ColorEditor extends JPanel implements GenericTagEditor, ActionListe
private final Field field;
private final int index;
private final Class<?> type;
private String fieldName;
private final String fieldName;
private Color color;
public static final int COLOR_TYPE_RGB = 0;
public static final int COLOR_TYPE_RGBA = 1;
@@ -203,10 +203,12 @@ public class NumberEditor extends JSpinner implements GenericTagEditor {
return value;
}
@Override
public String getFieldName() {
return fieldName;
}
@Override
public Field getField() {
return field;
}
@@ -113,6 +113,7 @@ public class StringEditor extends JTextArea implements GenericTagEditor {
return fieldName;
}
@Override
public Field getField() {
return field;
}
@@ -47,6 +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;
import java.util.logging.Level;
@@ -216,7 +217,7 @@ public class DefineButton2Tag extends CharacterTag implements Container, Bounded
private static final Cache<RECT> rectCache = Cache.getInstance(true);
@Override
public RECT getRect(HashMap<Integer, CharacterTag> allCharacters, Stack<Integer> visited) {
public RECT getRect(Map<Integer, CharacterTag> allCharacters, Stack<Integer> visited) {
if (rectCache.contains(this)) {
return (RECT) rectCache.get(this);
}
@@ -253,9 +254,14 @@ public class DefineButton2Tag extends CharacterTag implements Container, Bounded
}
@Override
public SerializableImage toImage(int frame, List<Tag> tags, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
public SerializableImage toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
throw new Error("this overload of toImage call is not supported on BoundedTag");
}
@Override
public void toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, SerializableImage image, Matrix transformation) {
if (visited.contains(buttonId)) {
return new SerializableImage(1, 1, SerializableImage.TYPE_4BYTE_ABGR);
return;
}
visited.push(buttonId);
HashMap<Integer, Layer> layers = new HashMap<>();
@@ -277,13 +283,11 @@ public class DefineButton2Tag extends CharacterTag implements Container, Bounded
visited.pop();
RECT displayRect = getRect(characters, visited);
visited.push(buttonId);
SerializableImage ret = SWF.frameToImage(buttonId, maxDepth, layers, new Color(0, 0, 0, 0), characters, 1, tags, tags, displayRect, visited, transformation);
return ret;
SWF.frameToImage(buttonId, maxDepth, layers, new Color(0, 0, 0, 0), characters, 1, tags, tags, displayRect, visited, image, transformation);
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public Point getImagePos(int frame, Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
RECT r = getRect(characters, visited);
return new Point(r.Xmin / SWF.unitDivisor, r.Ymin / SWF.unitDivisor);
}
@@ -52,6 +52,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;
import java.util.logging.Level;
@@ -228,7 +229,7 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT
private static final Cache<RECT> rectCache = Cache.getInstance(true);
@Override
public RECT getRect(HashMap<Integer, CharacterTag> allCharacters, Stack<Integer> visited) {
public RECT getRect(Map<Integer, CharacterTag> allCharacters, Stack<Integer> visited) {
if (rectCache.contains(this)) {
return (RECT) rectCache.get(this);
}
@@ -276,9 +277,14 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT
}
@Override
public SerializableImage toImage(int frame, List<Tag> tags, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
public SerializableImage toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
throw new Error("this overload of toImage call is not supported on BoundedTag");
}
@Override
public void toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, SerializableImage image, Matrix transformation) {
if (visited.contains(buttonId)) {
return new SerializableImage(1, 1, SerializableImage.TYPE_4BYTE_ABGR);
return;
}
visited.push(buttonId);
HashMap<Integer, Layer> layers = new HashMap<>();
@@ -300,13 +306,12 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT
visited.pop();
RECT displayRect = getRect(characters, visited);
visited.push(buttonId);
SerializableImage ret = SWF.frameToImage(buttonId, maxDepth, layers, new Color(0, 0, 0, 0), characters, 1, tags, tags, displayRect, visited, transformation);
SWF.frameToImage(buttonId, maxDepth, layers, new Color(0, 0, 0, 0), characters, 1, tags, tags, displayRect, visited, image, transformation);
visited.pop();
return ret;
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public Point getImagePos(int frame, Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
RECT r = getRect(characters, visited);
return new Point(r.Xmin / SWF.unitDivisor, r.Ymin / SWF.unitDivisor);
}
@@ -38,9 +38,9 @@ import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;
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;
import java.util.logging.Level;
@@ -470,7 +470,7 @@ public class DefineEditTextTag extends TextTag {
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> allCharacters, Stack<Integer> visited) {
public RECT getRect(Map<Integer, CharacterTag> allCharacters, Stack<Integer> visited) {
return bounds;
}
@@ -47,9 +47,9 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
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;
@@ -87,7 +87,7 @@ public class DefineMorphShape2Tag extends CharacterTag implements BoundedTag, Mo
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public RECT getRect(Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
RECT rect = new RECT();
rect.Xmin = Math.min(startBounds.Xmin, endBounds.Xmin);
rect.Ymin = Math.min(startBounds.Ymin, endBounds.Ymin);
@@ -197,8 +197,7 @@ public class DefineMorphShape2Tag extends CharacterTag implements BoundedTag, Mo
return 2;
}
@Override
public SerializableImage toImage(int frame, List<Tag> tags, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
private SHAPEWITHSTYLE getFrame(int frame) {
List<SHAPERECORD> finalRecords = new ArrayList<>();
FILLSTYLEARRAY fillStyles = morphFillStyles.getFillStylesAt(frame);
LINESTYLEARRAY lineStyles = morphLineStyles.getLineStylesAt(getShapeNum(), frame);
@@ -313,15 +312,26 @@ public class DefineMorphShape2Tag extends CharacterTag implements BoundedTag, Mo
shape.fillStyles = fillStyles;
shape.lineStyles = lineStyles;
shape.shapeRecords = finalRecords;
return shape;
}
@Override
public SerializableImage toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
throw new Error("this overload of toImage call is not supported on BoundedTag");
}
@Override
public void toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, SerializableImage image, Matrix transformation) {
SHAPEWITHSTYLE shape = getFrame(frame);
// shapeNum: 4
// todo: Currently the generated image is not cached, because the cache
// key contains the hashCode of the finalRecord object, and it is always
// recreated
return BitmapExporter.export(swf, shape, null, false);
BitmapExporter.exportTo(swf, shape, null, image, transformation);
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public Point getImagePos(int frame, Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(
(startBounds.Xmin + (endBounds.Xmin - startBounds.Xmin) * frame / 65535) / SWF.unitDivisor,
(startBounds.Ymin + (endBounds.Ymin - startBounds.Ymin) * frame / 65535) / SWF.unitDivisor);
@@ -46,9 +46,9 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
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;
@@ -136,7 +136,7 @@ public class DefineMorphShapeTag extends CharacterTag implements BoundedTag, Mor
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public RECT getRect(Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
RECT rect = new RECT();
rect.Xmin = Math.min(startBounds.Xmin, endBounds.Xmin);
rect.Ymin = Math.min(startBounds.Ymin, endBounds.Ymin);
@@ -180,8 +180,7 @@ public class DefineMorphShapeTag extends CharacterTag implements BoundedTag, Mor
return 1;
}
@Override
public SerializableImage toImage(int frame, List<Tag> tags, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
private SHAPEWITHSTYLE getFrame(int frame) {
List<SHAPERECORD> finalRecords = new ArrayList<>();
FILLSTYLEARRAY fillStyles = morphFillStyles.getFillStylesAt(frame);
LINESTYLEARRAY lineStyles = morphLineStyles.getLineStylesAt(getShapeNum(), frame);
@@ -296,15 +295,26 @@ public class DefineMorphShapeTag extends CharacterTag implements BoundedTag, Mor
shape.fillStyles = fillStyles;
shape.lineStyles = lineStyles;
shape.shapeRecords = finalRecords;
return shape;
}
@Override
public SerializableImage toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
throw new Error("this overload of toImage call is not supported on BoundedTag");
}
@Override
public void toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, SerializableImage image, Matrix transformation) {
SHAPEWITHSTYLE shape = getFrame(frame);
// shapeNum: 3
// todo: Currently the generated image is not cached, because the cache
// key contains the hashCode of the finalRecord object, and it is always
// recreated
return BitmapExporter.export(swf, shape, null, false);
BitmapExporter.exportTo(swf, shape, null, image, transformation);
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public Point getImagePos(int frame, Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(
(startBounds.Xmin + (endBounds.Xmin - startBounds.Xmin) * frame / 65535) / SWF.unitDivisor,
(startBounds.Ymin + (endBounds.Ymin - startBounds.Ymin) * frame / 65535) / SWF.unitDivisor);
@@ -22,7 +22,6 @@ 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.exporters.SVGShapeExporter;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
import com.jpexs.decompiler.flash.types.BasicType;
@@ -32,12 +31,12 @@ import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.SerializableImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
public class DefineShape2Tag extends CharacterTag implements BoundedTag, ShapeTag {
public class DefineShape2Tag extends CharacterTag implements ShapeTag {
@SWFType(BasicType.UI16)
public int shapeId;
@@ -46,7 +45,7 @@ public class DefineShape2Tag extends CharacterTag implements BoundedTag, ShapeTa
public static final int ID = 22;
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public Point getImagePos(int frame, Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(shapeBounds.Xmin / SWF.unitDivisor, shapeBounds.Ymin / SWF.unitDivisor);
}
@@ -73,17 +72,22 @@ public class DefineShape2Tag extends CharacterTag implements BoundedTag, ShapeTa
}
@Override
public SerializableImage toImage(int frame, List<Tag> tags, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
return BitmapExporter.export(swf, getShapes());
public SerializableImage toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
throw new Error("this overload of toImage call is not supported on BoundedTag");
}
@Override
public void toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, SerializableImage image, Matrix transformation) {
BitmapExporter.exportTo(swf, getShapes(), null, image, transformation);
}
@Override
public int getCharacterId() {
return shapeId;
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public RECT getRect(Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
return shapeBounds;
}
@@ -22,7 +22,6 @@ 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.exporters.SVGShapeExporter;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
import com.jpexs.decompiler.flash.types.BasicType;
@@ -32,12 +31,12 @@ import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.SerializableImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
public class DefineShape3Tag extends CharacterTag implements BoundedTag, ShapeTag {
public class DefineShape3Tag extends CharacterTag implements ShapeTag {
@SWFType(BasicType.UI16)
public int shapeId;
@@ -46,7 +45,7 @@ public class DefineShape3Tag extends CharacterTag implements BoundedTag, ShapeTa
public static final int ID = 32;
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public Point getImagePos(int frame, Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(shapeBounds.Xmin / SWF.unitDivisor, shapeBounds.Ymin / SWF.unitDivisor);
}
@@ -66,7 +65,7 @@ public class DefineShape3Tag extends CharacterTag implements BoundedTag, ShapeTa
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public RECT getRect(Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
return shapeBounds;
}
@@ -78,10 +77,15 @@ public class DefineShape3Tag extends CharacterTag implements BoundedTag, ShapeTa
}
@Override
public SerializableImage toImage(int frame, List<Tag> tags, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
return BitmapExporter.export(swf, getShapes());
public SerializableImage toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
throw new Error("this overload of toImage call is not supported on BoundedTag");
}
@Override
public void toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, SerializableImage image, Matrix transformation) {
BitmapExporter.exportTo(swf, getShapes(), null, image, transformation);
}
@Override
public int getCharacterId() {
return shapeId;
@@ -22,7 +22,6 @@ 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.exporters.SVGShapeExporter;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
import com.jpexs.decompiler.flash.types.BasicType;
@@ -33,12 +32,12 @@ import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.SerializableImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
public class DefineShape4Tag extends CharacterTag implements BoundedTag, ShapeTag {
public class DefineShape4Tag extends CharacterTag implements ShapeTag {
@SWFType(BasicType.UI16)
public int shapeId;
@@ -54,7 +53,7 @@ public class DefineShape4Tag extends CharacterTag implements BoundedTag, ShapeTa
public static final int ID = 83;
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public Point getImagePos(int frame, Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(shapeBounds.Xmin / SWF.unitDivisor, shapeBounds.Ymin / SWF.unitDivisor);
}
@@ -81,17 +80,22 @@ public class DefineShape4Tag extends CharacterTag implements BoundedTag, ShapeTa
}
@Override
public SerializableImage toImage(int frame, List<Tag> tags, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
return BitmapExporter.export(swf, getShapes());
public SerializableImage toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
throw new Error("this overload of toImage call is not supported on BoundedTag");
}
@Override
public void toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, SerializableImage image, Matrix transformation) {
BitmapExporter.exportTo(swf, getShapes(), null, image, transformation);
}
@Override
public int getCharacterId() {
return shapeId;
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public RECT getRect(Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
return shapeBounds;
}
@@ -23,7 +23,6 @@ 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.exporters.SVGShapeExporter;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
import com.jpexs.decompiler.flash.types.BasicType;
@@ -34,12 +33,12 @@ import com.jpexs.helpers.SerializableImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
public class DefineShapeTag extends CharacterTag implements BoundedTag, ShapeTag {
public class DefineShapeTag extends CharacterTag implements ShapeTag {
@SWFType(BasicType.UI16)
public int shapeId;
@@ -63,7 +62,7 @@ public class DefineShapeTag extends CharacterTag implements BoundedTag, ShapeTag
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public RECT getRect(Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
return shapeBounds;
}
@@ -107,12 +106,17 @@ public class DefineShapeTag extends CharacterTag implements BoundedTag, ShapeTag
}
@Override
public SerializableImage toImage(int frame, List<Tag> tags, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
return BitmapExporter.export(swf, getShapes());
public SerializableImage toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
throw new Error("this overload of toImage call is not supported on BoundedTag");
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public void toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, SerializableImage image, Matrix transformation) {
BitmapExporter.exportTo(swf, getShapes(), null, image, transformation);
}
@Override
public Point getImagePos(int frame, Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(shapeBounds.Xmin / SWF.unitDivisor, shapeBounds.Ymin / SWF.unitDivisor);
}
@@ -44,6 +44,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;
@@ -74,7 +75,7 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
return spriteId;
}
private RECT getCharacterBounds(HashMap<Integer, CharacterTag> allCharacters, Set<Integer> characters, Stack<Integer> visited) {
private RECT getCharacterBounds(Map<Integer, CharacterTag> allCharacters, Set<Integer> characters, Stack<Integer> visited) {
if (visited.contains(spriteId)) {
return new RECT();
}
@@ -109,7 +110,7 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
private static final Cache<RECT> rectCache = Cache.getInstance(true);
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public RECT getRect(Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
if (rectCache.contains(this)) {
return (RECT) rectCache.get(this);
}
@@ -277,9 +278,14 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
}
@Override
public SerializableImage toImage(int frame, List<Tag> tags, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
public SerializableImage toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
throw new Error("this overload of toImage call is not supported on BoundedTag");
}
@Override
public void toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, SerializableImage image, Matrix transformation) {
if (visited.contains(spriteId)) {
return new SerializableImage(1, 1, SerializableImage.TYPE_4BYTE_ABGR);
return;
}
/*
rect.Xmax=displayRect.Xmin+rect.getWidth();
@@ -290,13 +296,12 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
SWF.fixRect(rect);*/
RECT rect = getRect(characters, visited);
visited.push(spriteId);
SerializableImage ret = SWF.frameToImage(spriteId, frame, tags, subTags, rect, frameCount, visited, transformation);
SWF.frameToImage(spriteId, frame, tags, subTags, rect, frameCount, visited, image, transformation);
visited.pop();
return ret;
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public Point getImagePos(int frame, Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
//RECT displayRect = getRect(characters, visited); //use visited
return new Point(0, 0); //displayRect.Xmin,displayRect.Ymin);
}
@@ -44,9 +44,9 @@ import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;
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;
import java.util.regex.Matcher;
@@ -412,7 +412,7 @@ public class DefineText2Tag extends TextTag implements DrawableTag {
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public RECT getRect(Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
return textBounds;
}
@@ -492,12 +492,17 @@ public class DefineText2Tag extends TextTag implements DrawableTag {
}
@Override
public SerializableImage toImage(int frame, List<Tag> tags, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
return staticTextToImage(swf, characters, textRecords, textBounds, 2, transformation);
public SerializableImage toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
throw new Error("this overload of toImage call is not supported on BoundedTag");
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public void toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, SerializableImage image, Matrix transformation) {
staticTextToImage(swf, characters, textRecords, textBounds, 2, image, transformation);
}
@Override
public Point getImagePos(int frame, Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(textBounds.Xmin / 20, textBounds.Ymin / 20);
}
@@ -45,9 +45,9 @@ import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;
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;
import java.util.regex.Matcher;
@@ -492,7 +492,7 @@ public class DefineTextTag extends TextTag implements DrawableTag {
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public RECT getRect(Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
return textBounds;
}
@@ -508,12 +508,17 @@ public class DefineTextTag extends TextTag implements DrawableTag {
}
@Override
public SerializableImage toImage(int frame, List<Tag> tags, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
return staticTextToImage(swf, characters, textRecords, textBounds, 1, transformation);
public SerializableImage toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
throw new Error("this overload of toImage call is not supported on BoundedTag");
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public void toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, SerializableImage image, Matrix transformation) {
staticTextToImage(swf, characters, textRecords, textBounds, 1, image, transformation);
}
@Override
public Point getImagePos(int frame, Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(textBounds.Xmin / SWF.unitDivisor, textBounds.Ymin / SWF.unitDivisor);
}
@@ -29,7 +29,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
/**
@@ -122,7 +122,7 @@ public class DefineVideoStreamTag extends CharacterTag implements BoundedTag {
}
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public RECT getRect(Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new RECT(0, (int) (SWF.unitDivisor * width), 0, (int) (SWF.unitDivisor * height));
}
}
@@ -17,7 +17,7 @@
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.types.RECT;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
/**
@@ -26,6 +26,6 @@ import java.util.Stack;
*/
public interface BoundedTag {
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited);
public RECT getRect(Map<Integer, CharacterTag> characters, Stack<Integer> visited);
//public List<GeneralPath> getPaths(List<Tag> tags);
}
@@ -20,8 +20,8 @@ import com.jpexs.decompiler.flash.exporters.Matrix;
import com.jpexs.decompiler.flash.exporters.Point;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.helpers.SerializableImage;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
/**
@@ -30,9 +30,11 @@ import java.util.Stack;
*/
public interface DrawableTag {
public SerializableImage toImage(int frame, List<Tag> tags, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation);
public SerializableImage toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation);
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited);
public void toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, SerializableImage image, Matrix transformation);
public Point getImagePos(int frame, Map<Integer, CharacterTag> characters, Stack<Integer> visited);
public int getNumFrames();
}
@@ -36,7 +36,6 @@ import java.awt.font.GlyphMetrics;
import java.awt.font.GlyphVector;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
@@ -247,12 +246,17 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
}
@Override
public SerializableImage toImage(int frame, List<Tag> tags, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
public SerializableImage toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
return SHAPERECORD.shapeListToImage(swf, getGlyphShapeTable(), 500, 500, Color.black);
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public void toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, SerializableImage image, Matrix transformation) {
}
@Override
public Point getImagePos(int frame, Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(0, 0);
}
@@ -22,7 +22,7 @@ import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
*
* @author JPEXS
*/
public interface ShapeTag extends DrawableTag {
public interface ShapeTag extends BoundedTag, DrawableTag {
public SHAPEWITHSTYLE getShapes();
@@ -34,8 +34,6 @@ import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.LineMetrics;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -194,21 +192,13 @@ public abstract class TextTag extends CharacterTag implements BoundedTag {
return att;
}
public static SerializableImage staticTextToImage(SWF swf, HashMap<Integer, CharacterTag> characters, List<TEXTRECORD> textRecords, RECT textBounds, int numText, Matrix transformation) {
double unzoom = SWF.unitDivisor;
double fixX = -textBounds.Xmin / unzoom;
double fixY = -textBounds.Ymin / unzoom;
double width = textBounds.getWidth() / unzoom;
double height = textBounds.getHeight() / unzoom;
SerializableImage ret = new SerializableImage((int) width, (int) height, SerializableImage.TYPE_INT_ARGB);
ret.bounds = new Rectangle2D.Double(-fixX, -fixY, width, height);
public static void staticTextToImage(SWF swf, Map<Integer, CharacterTag> characters, List<TEXTRECORD> textRecords, RECT textBounds, int numText, SerializableImage image, Matrix transformation) {
Color textColor = new Color(0, 0, 0);
FontTag font = null;
int textHeight = 12;
int x = textBounds.Xmin;
int x = 0;
int y = 0;
Graphics2D g = (Graphics2D) ret.getGraphics();
Graphics2D g = (Graphics2D) image.getGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
@@ -233,19 +223,16 @@ public abstract class TextTag extends CharacterTag implements BoundedTag {
y = rec.yOffset;
}
Matrix mat = transformation.clone();
double rat = textHeight / 1024.0 / font.getDivider();
mat = mat.preConcatenate(Matrix.getScaleInstance(rat));
mat.translate(x - textBounds.Xmin, y - textBounds.Ymin);
for (GLYPHENTRY entry : rec.glyphEntries) {
// shapeNum: 1
SHAPE shape = glyphs.get(entry.glyphIndex);
SerializableImage img = BitmapExporter.export(swf, shape, textColor, true);
AffineTransform tr = new AffineTransform();
double rat = textHeight / 1024.0;
tr.translate(x / unzoom + img.bounds.getMinX() * rat + fixX, y / unzoom + img.bounds.getMinY() * rat + fixY);
tr.scale(1.0 / font.getDivider(), 1.0 / font.getDivider());
tr.scale(rat, rat);
g.drawImage(img.getBufferedImage(), tr, null);
x += (int) entry.glyphAdvance;
BitmapExporter.exportTo(swf, shape, textColor, image, mat);
mat.translate(entry.glyphAdvance, 0);
}
}
return ret;
}
}
@@ -49,8 +49,8 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -116,7 +116,7 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag {
}
@Override
public SerializableImage toImage(int frame, List<Tag> tags, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
public SerializableImage toImage(int frame, List<Tag> tags, Map<Integer, CharacterTag> characters, Stack<Integer> visited, Matrix transformation) {
List<SHAPE> shapes = new ArrayList<>();
for (int i = 0; i < shapeCache.size(); i++) {
shapes.add(SHAPERECORD.resizeSHAPE(shapeCache.get(i), SWF.unitDivisor));
@@ -131,7 +131,7 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag {
}
@Override
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public Point getImagePos(int frame, Map<Integer, CharacterTag> characters, Stack<Integer> visited) {
return new Point(0, 0);
}
@@ -31,7 +31,7 @@ import java.util.Stack;
*/
public class ConditionEvaluator {
private Conditional cond;
private final Conditional cond;
public ConditionEvaluator(Conditional cond) {
this.cond = cond;
@@ -254,7 +254,7 @@ public final class ConditionLexer {
return yyline+1;
}
private Stack<ConditionToken> pushedBack=new Stack<ConditionToken>();
private final Stack<ConditionToken> pushedBack=new Stack<>();
public void pushback(ConditionToken symb) {
pushedBack.push(symb);
@@ -368,6 +368,7 @@ public final class ConditionLexer {
/**
* Closes the input stream.
* @throws java.io.IOException
*/
public final void yyclose() throws java.io.IOException {
zzAtEOF = true; /* indicate end of file */
@@ -406,6 +407,7 @@ public final class ConditionLexer {
/**
* Returns the current lexical state.
* @return
*/
public final int yystate() {
return zzLexicalState;
@@ -424,6 +426,7 @@ public final class ConditionLexer {
/**
* Returns the text matched by the current regular expression.
* @return
*/
public final String yytext() {
return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead );
@@ -448,6 +451,7 @@ public final class ConditionLexer {
/**
* Returns the length of the matched text region.
* @return
*/
public final int yylength() {
return zzMarkedPos-zzStartRead;
@@ -503,6 +507,7 @@ public final class ConditionLexer {
*
* @return the next token
* @exception java.io.IOException if any I/O-Error occurs
* @throws com.jpexs.decompiler.flash.types.annotations.parser.ParseException
*/
public ConditionToken yylex() throws java.io.IOException, ParseException {
int zzInput;
@@ -168,7 +168,7 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali
}
// shapeNum: 1
SerializableImage img = BitmapExporter.export(swf, shapes.get(pos), color, false);
SerializableImage img = BitmapExporter.export(swf, shapes.get(pos), color);
int w1 = img.getWidth();
int h1 = img.getHeight();
@@ -74,8 +74,6 @@ 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.decompiler.flash.types.SHAPEWITHSTYLE;
import com.jpexs.decompiler.flash.types.SOUNDENVELOPE;
import com.jpexs.decompiler.flash.types.TEXTRECORD;
import com.jpexs.decompiler.flash.types.filters.BEVELFILTER;
@@ -63,11 +63,15 @@ public class SerializableImage implements Serializable {
image = new BufferedImage(i, i1, i2, icm);
}
public void setBufferedImage(BufferedImage image, Rectangle2D bounds) {
this.image = image;
this.bounds = bounds;
}
public BufferedImage getBufferedImage() {
/*try {
ImageIO.write(image, "png", new File("c:\\10\\x\\imageid" + String.format("%03d", imageid++) + ".png"));
} catch (IOException ex) {
Logger.getLogger(BitmapExporter.class.getName()).log(Level.SEVERE, null, ex);
}*/
return image;
}