outlines fixed

This commit is contained in:
honfika@gmail.com
2015-02-01 13:02:45 +01:00
parent 0f54e89379
commit 7d4a8dc8cc
21 changed files with 236 additions and 162 deletions

View File

@@ -102,6 +102,7 @@ import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.base.MorphShapeTag;
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
import com.jpexs.decompiler.flash.tags.base.RemoveTag;
import com.jpexs.decompiler.flash.tags.base.RenderContext;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
import com.jpexs.decompiler.flash.tags.base.TextTag;
import com.jpexs.decompiler.flash.timeline.Clip;
@@ -2784,12 +2785,17 @@ public final class SWF implements SWFContainerItem, Timelined {
Matrix m = transformation.clone();
m.translate(-rect.Xmin, -rect.Ymin);
m.scale(zoom);
frameToImage(timeline, frame, time, stateUnderCursor, mouseButton, image, m, colorTransform);
putToCache(key, image);
RenderContext renderContext = new RenderContext();
renderContext.stateUnderCursor = stateUnderCursor;
renderContext.mouseButton = mouseButton;
frameToImage(timeline, frame, time, renderContext, image, m, colorTransform);
if (useCache) {
putToCache(key, image);
}
return image;
}
public static void framesToImage(Timeline timeline, List<SerializableImage> ret, int startFrame, int stopFrame, DepthState stateUnderCursor, int mouseButton, RECT displayRect, int totalFrameCount, Stack<Integer> visited, Matrix transformation, ColorTransform colorTransform, double zoom) {
public static void framesToImage(Timeline timeline, List<SerializableImage> ret, int startFrame, int stopFrame, RenderContext renderContext, RECT displayRect, int totalFrameCount, Stack<Integer> visited, Matrix transformation, ColorTransform colorTransform, double zoom) {
RECT rect = displayRect;
for (int f = 0; f < timeline.getFrames().size(); f++) {
SerializableImage image = new SerializableImage((int) (rect.getWidth() / SWF.unitDivisor) + 1,
@@ -2797,12 +2803,12 @@ public final class SWF implements SWFContainerItem, Timelined {
image.fillTransparent();
Matrix m = new Matrix();
m.translate(-rect.Xmin, -rect.Ymin);
frameToImage(timeline, f, 0, stateUnderCursor, mouseButton, image, m, colorTransform);
frameToImage(timeline, f, 0, renderContext, image, m, colorTransform);
ret.add(image);
}
}
public static void frameToImage(Timeline timeline, int frame, int time, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
public static void frameToImage(Timeline timeline, int frame, int time, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
double unzoom = SWF.unitDivisor;
if (timeline.getFrames().size() <= frame) {
return;
@@ -2850,7 +2856,6 @@ public final class SWF implements SWFContainerItem, Timelined {
boolean showPlaceholder = false;
if (character instanceof DrawableTag) {
DrawableTag drawable = (DrawableTag) character;
SerializableImage img;
Matrix drawMatrix = new Matrix();
int drawableFrameCount = drawable.getNumFrames();
if (drawableFrameCount == 0) {
@@ -2858,10 +2863,9 @@ public final class SWF implements SWFContainerItem, Timelined {
}
int dframe = (time + layer.time) % drawableFrameCount;
if (character instanceof ButtonTag) {
ButtonTag bt = (ButtonTag) character;
dframe = ButtonTag.FRAME_UP;
if (stateUnderCursor == layer) {
if (mouseButton > 0) {
if (renderContext.stateUnderCursor == layer) {
if (renderContext.mouseButton > 0) {
dframe = ButtonTag.FRAME_DOWN;
} else {
dframe = ButtonTag.FRAME_OVER;
@@ -2905,22 +2909,40 @@ public final class SWF implements SWFContainerItem, Timelined {
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();
SerializableImage img = null;
String cacheKey = null;
if (drawable instanceof ShapeTag) {
cacheKey = m.toString() + clrTrans.toString();
img = renderContext.shapeCache.get(cacheKey);
}
if (img == null) {
img = new SerializableImage(newWidth, newHeight, SerializableImage.TYPE_INT_ARGB);
img.fillTransparent();
drawable.toImage(dframe, layer.time + time, layer.ratio, renderContext, img, m, clrTrans);
if (cacheKey != null) {
renderContext.shapeCache.put(cacheKey, img);
}
}
/*//if (renderContext.stateUnderCursor == layer) {
if (true) {
BufferedImage bi = img.getBufferedImage();
ColorModel cm = bi.getColorModel();
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
WritableRaster raster = bi.copyData(null);
img = new SerializableImage(new BufferedImage(cm, raster, isAlphaPremultiplied, null));
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)));
gg.draw(SHAPERECORD.twipToPixelShape(drawable.getOutline(dframe, layer.time + time, layer.ratio, renderContext, m)));
}*/
if (layer.filters != null) {
for (FILTER filter : layer.filters) {
img = filter.apply(img);

View File

@@ -30,6 +30,7 @@ import com.jpexs.decompiler.flash.helpers.BMPFile;
import com.jpexs.decompiler.flash.helpers.ImageHelper;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.RenderContext;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA;
import com.jpexs.decompiler.flash.types.RECT;
@@ -111,7 +112,7 @@ public class ShapeExporter {
Matrix m = new Matrix();
m.translate(-rect.Xmin, -rect.Ymin);
m.scale(settings.zoom);
st.toImage(0, 0, 0, null, 0, img, m, new CXFORMWITHALPHA());
st.toImage(0, 0, 0, new RenderContext(), img, m, new CXFORMWITHALPHA());
if (settings.mode == ShapeExportMode.PNG) {
ImageHelper.write(img.getBufferedImage(), "PNG", new FileOutputStream(file));
} else {

View File

@@ -52,15 +52,15 @@ public abstract class ShapeExporterBase implements IShapeExporter {
private final List<LINESTYLE> _lineStyles;
private final List<Map<Integer, List<IEdge>>> _fillEdgeMaps;
private final List<List<IEdge>> _fillPaths;
private final List<Map<Integer, List<IEdge>>> _lineEdgeMaps;
private final List<List<IEdge>> _linePaths;
private final ColorTransform colorTransform;
private static final Cache<SHAPE, List<Map<Integer, List<IEdge>>>> fillEdgeMapCache = Cache.getInstance(true, true, "fillEdgeMap");
private static final Cache<SHAPE, List<List<IEdge>>> fillEdgeMapCache = Cache.getInstance(true, true, "fillEdgeMap");
private static final Cache<SHAPE, List<Map<Integer, List<IEdge>>>> lineEdgeMapCache = Cache.getInstance(true, true, "lineEdgeMap");
private static final Cache<SHAPE, List<List<IEdge>>> lineEdgeMapCache = Cache.getInstance(true, true, "lineEdgeMap");
public ShapeExporterBase(SHAPE shape, ColorTransform colorTransform) {
this.shape = shape;
@@ -73,30 +73,38 @@ public abstract class ShapeExporterBase implements IShapeExporter {
_lineStyles.addAll(Arrays.asList(shapeWithStyle.lineStyles.lineStyles));
}
List<Map<Integer, List<IEdge>>> fillEdgeMaps = fillEdgeMapCache.get(shape);
List<Map<Integer, List<IEdge>>> lineEdgeMaps = lineEdgeMapCache.get(shape);
if (fillEdgeMaps == null || lineEdgeMaps == null) {
List<List<IEdge>> fillPaths = fillEdgeMapCache.get(shape);
List<List<IEdge>> linePaths = lineEdgeMapCache.get(shape);
if (fillPaths == null || linePaths == null) {
// Create edge maps
fillEdgeMaps = new ArrayList<>();
lineEdgeMaps = new ArrayList<>();
List<Map<Integer, List<IEdge>>> fillEdgeMaps = new ArrayList<>();
List<Map<Integer, List<IEdge>>> lineEdgeMaps = new ArrayList<>();
createEdgeMaps(shape, _fillStyles, _lineStyles, fillEdgeMaps, lineEdgeMaps);
fillEdgeMapCache.put(shape, fillEdgeMaps);
lineEdgeMapCache.put(shape, lineEdgeMaps);
int count = lineEdgeMaps.size();
fillPaths = new ArrayList<>(count);
linePaths = new ArrayList<>(count);
for (int i = 0; i < count; i++) {
fillPaths.add(createPathFromEdgeMap(fillEdgeMaps.get(i)));
linePaths.add(createPathFromEdgeMap(lineEdgeMaps.get(i)));
}
fillEdgeMapCache.put(shape, fillPaths);
lineEdgeMapCache.put(shape, linePaths);
}
_fillEdgeMaps = fillEdgeMaps;
_lineEdgeMaps = lineEdgeMaps;
_fillPaths = fillPaths;
_linePaths = linePaths;
}
public void export() {
// Let the doc handler know that a shape export starts
beginShape();
// Export fills and strokes for each group separately
for (int i = 0; i < _lineEdgeMaps.size(); i++) {
for (int i = 0; i < _linePaths.size(); i++) {
// Export fills first
exportFillPath(i);
exportFillPath(_fillPaths.get(i));
// Export strokes last
exportLinePath(i);
exportLinePath(_linePaths.get(i));
}
// Let the doc handler know that we're done exporting a shape
endShape();
@@ -203,7 +211,7 @@ public abstract class ShapeExporterBase implements IShapeExporter {
}
}
protected void processSubPath(List<IEdge> subPath, int lineStyleIdx, int fillStyleIdx0, int fillStyleIdx1,
private void processSubPath(List<IEdge> subPath, int lineStyleIdx, int fillStyleIdx0, int fillStyleIdx1,
Map<Integer, List<IEdge>> currentFillEdgeMap, Map<Integer, List<IEdge>> currentLineEdgeMap) {
List<IEdge> path;
if (fillStyleIdx0 != 0) {
@@ -234,8 +242,7 @@ public abstract class ShapeExporterBase implements IShapeExporter {
}
}
protected void exportFillPath(int groupIndex) {
List<IEdge> path = createPathFromEdgeMap(_fillEdgeMaps.get(groupIndex));
private void exportFillPath(List<IEdge> path) {
PointInt pos = PointInt.MAX;
int fillStyleIdx = Integer.MAX_VALUE;
if (path.size() > 0) {
@@ -309,8 +316,7 @@ public abstract class ShapeExporterBase implements IShapeExporter {
}
}
protected void exportLinePath(int groupIndex) {
List<IEdge> path = createPathFromEdgeMap(_lineEdgeMaps.get(groupIndex));
private void exportLinePath(List<IEdge> path) {
PointInt pos = PointInt.MAX;
int lineStyleIdx = Integer.MAX_VALUE;
if (path.size() > 0) {
@@ -399,7 +405,7 @@ public abstract class ShapeExporterBase implements IShapeExporter {
}
}
protected List<IEdge> createPathFromEdgeMap(Map<Integer, List<IEdge>> edgeMap) {
private List<IEdge> createPathFromEdgeMap(Map<Integer, List<IEdge>> edgeMap) {
List<IEdge> newPath = new ArrayList<>();
List<Integer> styleIdxArray = new ArrayList<>();
for (Integer styleIdx : edgeMap.keySet()) {
@@ -412,7 +418,7 @@ public abstract class ShapeExporterBase implements IShapeExporter {
return newPath;
}
protected void cleanEdgeMap(Map<Integer, List<IEdge>> edgeMap) {
private void cleanEdgeMap(Map<Integer, List<IEdge>> edgeMap) {
for (Integer styleIdx : edgeMap.keySet()) {
List<IEdge> subPath = edgeMap.get(styleIdx);
if (subPath != null && subPath.size() > 0) {
@@ -444,7 +450,7 @@ public abstract class ShapeExporterBase implements IShapeExporter {
}
}
protected Map<String, List<IEdge>> createCoordMap(List<IEdge> path) {
private Map<String, List<IEdge>> createCoordMap(List<IEdge> path) {
Map<String, List<IEdge>> coordMap = new HashMap<>();
for (int i = 0; i < path.size(); i++) {
PointInt from = path.get(i).getFrom();
@@ -461,7 +467,7 @@ public abstract class ShapeExporterBase implements IShapeExporter {
return coordMap;
}
protected void removeEdgeFromCoordMap(Map<String, List<IEdge>> coordMap, IEdge edge) {
private void removeEdgeFromCoordMap(Map<String, List<IEdge>> coordMap, IEdge edge) {
String key = edge.getFrom().getX() + "_" + edge.getFrom().getY();
List<IEdge> coordMapArray = coordMap.get(key);
if (coordMapArray != null) {
@@ -476,7 +482,7 @@ public abstract class ShapeExporterBase implements IShapeExporter {
}
}
protected IEdge findNextEdgeInCoordMap(Map<String, List<IEdge>> coordMap, IEdge edge) {
private IEdge findNextEdgeInCoordMap(Map<String, List<IEdge>> coordMap, IEdge edge) {
String key = edge.getTo().getX() + "_" + edge.getTo().getY();
List<IEdge> coordMapArray = coordMap.get(key);
if (coordMapArray != null && coordMapArray.size() > 0) {
@@ -485,15 +491,15 @@ public abstract class ShapeExporterBase implements IShapeExporter {
return null;
}
protected void appendFillStyles(List<FILLSTYLE> v1, FILLSTYLE[] v2) {
private void appendFillStyles(List<FILLSTYLE> v1, FILLSTYLE[] v2) {
v1.addAll(Arrays.asList(v2));
}
protected void appendLineStyles(List<LINESTYLE> v1, LINESTYLE[] v2) {
private void appendLineStyles(List<LINESTYLE> v1, LINESTYLE[] v2) {
v1.addAll(Arrays.asList(v2));
}
protected void appendEdges(List<IEdge> v1, List<IEdge> v2) {
private void appendEdges(List<IEdge> v1, List<IEdge> v2) {
for (int i = 0; i < v2.size(); i++) {
v1.add(v2.get(i));
}

View File

@@ -386,19 +386,21 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
}
}
timeline.getFrames().add(frameUp);
List<Frame> frames = timeline.getFrames();
frames.add(frameUp);
if (frameOver.layers.isEmpty()) {
frameOver = frameUp;
}
timeline.getFrames().add(frameOver);
frames.add(frameOver);
if (frameDown.layers.isEmpty()) {
frameDown = frameOver;
}
timeline.getFrames().add(frameDown);
frames.add(frameDown);
if (frameHit.layers.isEmpty()) {
frameHit = frameUp;
}
timeline.getFrames().add(frameHit);
frames.add(frameHit);
return timeline;
}

View File

@@ -25,6 +25,7 @@ import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.tags.base.MissingCharacterHandler;
import com.jpexs.decompiler.flash.tags.base.RenderContext;
import com.jpexs.decompiler.flash.tags.base.TextTag;
import com.jpexs.decompiler.flash.tags.dynamictext.CharacterWithStyle;
import com.jpexs.decompiler.flash.tags.dynamictext.DynamicTextModel;
@@ -35,7 +36,6 @@ import com.jpexs.decompiler.flash.tags.dynamictext.Word;
import com.jpexs.decompiler.flash.tags.text.ParsedSymbol;
import com.jpexs.decompiler.flash.tags.text.TextLexer;
import com.jpexs.decompiler.flash.tags.text.TextParseException;
import com.jpexs.decompiler.flash.timeline.DepthState;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.GLYPHENTRY;
@@ -810,7 +810,7 @@ public class DefineEditTextTag extends TextTag {
}
@Override
public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
render(false, image, transformation, colorTransform);
}

View File

@@ -27,7 +27,7 @@ import com.jpexs.decompiler.flash.exporters.shape.BitmapExporter;
import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.MorphShapeTag;
import com.jpexs.decompiler.flash.timeline.DepthState;
import com.jpexs.decompiler.flash.tags.base.RenderContext;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
@@ -361,7 +361,7 @@ public class DefineMorphShape2Tag extends MorphShapeTag {
}
@Override
public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
SHAPEWITHSTYLE shape = getShapeAtRatio(ratio);
// shapeNum: 4
// todo: Currently the generated image is not cached, because the cache
@@ -396,7 +396,7 @@ public class DefineMorphShape2Tag extends MorphShapeTag {
}
@Override
public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) {
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) {
return transformation.toTransform().createTransformedShape(getShapeAtRatio(ratio).getOutline());
}

View File

@@ -27,7 +27,7 @@ import com.jpexs.decompiler.flash.exporters.shape.BitmapExporter;
import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.MorphShapeTag;
import com.jpexs.decompiler.flash.timeline.DepthState;
import com.jpexs.decompiler.flash.tags.base.RenderContext;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
@@ -337,7 +337,7 @@ public class DefineMorphShapeTag extends MorphShapeTag {
}
@Override
public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
SHAPEWITHSTYLE shape = getShapeAtRatio(ratio);
// shapeNum: 3
// todo: Currently the generated image is not cached, because the cache
@@ -372,7 +372,7 @@ public class DefineMorphShapeTag extends MorphShapeTag {
}
@Override
public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) {
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) {
return transformation.toTransform().createTransformedShape(getShapeAtRatio(ratio).getOutline());
}

View File

@@ -28,7 +28,7 @@ import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
import com.jpexs.decompiler.flash.timeline.DepthState;
import com.jpexs.decompiler.flash.tags.base.RenderContext;
import com.jpexs.decompiler.flash.timeline.Frame;
import com.jpexs.decompiler.flash.timeline.Timeline;
import com.jpexs.decompiler.flash.timeline.Timelined;
@@ -289,8 +289,8 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
}
@Override
public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
SWF.frameToImage(getTimeline(), frame, time, stateUnderCursor, mouseButton, image, transformation, colorTransform);
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
SWF.frameToImage(getTimeline(), frame, time, renderContext, image, transformation, colorTransform);
}
@Override
@@ -337,8 +337,8 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
}
@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);
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) {
return getTimeline().getOutline(frame, time, ratio, renderContext, transformation);
}
@Override

View File

@@ -26,11 +26,11 @@ import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.tags.base.MissingCharacterHandler;
import com.jpexs.decompiler.flash.tags.base.RenderContext;
import com.jpexs.decompiler.flash.tags.base.TextTag;
import com.jpexs.decompiler.flash.tags.text.ParsedSymbol;
import com.jpexs.decompiler.flash.tags.text.TextLexer;
import com.jpexs.decompiler.flash.tags.text.TextParseException;
import com.jpexs.decompiler.flash.timeline.DepthState;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.GLYPHENTRY;
@@ -549,7 +549,7 @@ public class DefineText2Tag extends TextTag {
}
@Override
public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
staticTextToImage(swf, textRecords, 2, image, getTextMatrix(), transformation, colorTransform);
/*try {
DefineText2Tag originalTag = (DefineText2Tag) getOriginalTag();

View File

@@ -27,11 +27,11 @@ import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.tags.base.MissingCharacterHandler;
import com.jpexs.decompiler.flash.tags.base.RenderContext;
import com.jpexs.decompiler.flash.tags.base.TextTag;
import com.jpexs.decompiler.flash.tags.text.ParsedSymbol;
import com.jpexs.decompiler.flash.tags.text.TextLexer;
import com.jpexs.decompiler.flash.tags.text.TextParseException;
import com.jpexs.decompiler.flash.timeline.DepthState;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.GLYPHENTRY;
@@ -568,7 +568,7 @@ public class DefineTextTag extends TextTag {
}
@Override
public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
staticTextToImage(swf, textRecords, 1, image, getTextMatrix(), transformation, colorTransform);
/*try {
DefineTextTag originalTag = (DefineTextTag) getOriginalTag();

View File

@@ -21,7 +21,6 @@ import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
import com.jpexs.decompiler.flash.tags.DefineButtonSoundTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.timeline.DepthState;
import com.jpexs.decompiler.flash.timeline.Timelined;
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
import com.jpexs.decompiler.flash.types.ColorTransform;
@@ -62,13 +61,13 @@ public abstract class ButtonTag extends CharacterTag implements DrawableTag, Tim
}
@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);
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) {
return getTimeline().getOutline(frame, time, ratio, renderContext, transformation);
}
@Override
public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
SWF.frameToImage(getTimeline(), frame, time, stateUnderCursor, mouseButton, image, transformation, colorTransform);
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
SWF.frameToImage(getTimeline(), frame, time, renderContext, image, transformation, colorTransform);
}
@Override

View File

@@ -1,23 +1,23 @@
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
*
* This library 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
* Lesser General Public License for more details.
*
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.helpers.SerializableImage;
import java.awt.Shape;
@@ -29,7 +29,9 @@ import java.io.IOException;
*/
public interface DrawableTag extends BoundedTag {
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation);
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform);
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level, double zoom) throws IOException;
@@ -38,6 +40,4 @@ public interface DrawableTag extends BoundedTag {
public int getNumFrames();
public boolean isSingleFrame();
public boolean isSingleFrame();
}

View File

@@ -26,7 +26,6 @@ import com.jpexs.decompiler.flash.tags.DefineFontNameTag;
import com.jpexs.decompiler.flash.tags.DefineText2Tag;
import com.jpexs.decompiler.flash.tags.DefineTextTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.timeline.DepthState;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.GLYPHENTRY;
import com.jpexs.decompiler.flash.types.RECT;
@@ -290,7 +289,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
}
@Override
public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
SHAPERECORD.shapeListToImage(swf, getGlyphShapeTable(), image, frame, Color.black, colorTransform);
}
@@ -313,7 +312,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
}
@Override
public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) {
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) {
RECT r = getRect();
return new Area(new Rectangle(r.Xmin, r.Ymin, r.getWidth(), r.getHeight()));
}

View File

@@ -22,7 +22,6 @@ import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
import com.jpexs.decompiler.flash.exporters.shape.BitmapExporter;
import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter;
import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter;
import com.jpexs.decompiler.flash.timeline.DepthState;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.FILLSTYLE;
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
@@ -184,7 +183,7 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag {
}
@Override
public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
BitmapExporter.export(swf, getShape(), null, image, transformation, colorTransform);
}
@@ -212,7 +211,7 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag {
}
@Override
public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) {
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) {
return transformation.toTransform().createTransformedShape(getShape().getOutline());
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.timeline.DepthState;
import com.jpexs.helpers.SerializableImage;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author JPEXS
*/
public class RenderContext {
public DepthState stateUnderCursor;
public int mouseButton;
public Map<String, SerializableImage> shapeCache = new HashMap<>();
}

View File

@@ -25,7 +25,6 @@ import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter;
import com.jpexs.decompiler.flash.exporters.shape.PathExporter;
import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter;
import com.jpexs.decompiler.flash.helpers.LazyObject;
import com.jpexs.decompiler.flash.timeline.DepthState;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
@@ -68,12 +67,12 @@ public abstract class ShapeTag extends CharacterTag implements DrawableTag, Lazy
}
@Override
public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) {
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) {
return transformation.toTransform().createTransformedShape(getShapes().getOutline());
}
@Override
public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
BitmapExporter.export(swf, getShapes(), null, image, transformation, colorTransform);
if (Configuration.debugMode.get()) { // show control points
List<GeneralPath> paths = PathExporter.export(getShapes());

View File

@@ -29,7 +29,6 @@ import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter;
import com.jpexs.decompiler.flash.importers.TextImportResizeTextBoundsMode;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.text.TextParseException;
import com.jpexs.decompiler.flash.timeline.DepthState;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.FILLSTYLE;
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
@@ -579,7 +578,7 @@ public abstract class TextTag extends CharacterTag implements DrawableTag {
}
@Override
public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) {
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) {
RECT r = getBounds();
Shape shp = new Rectangle.Double(r.Xmin, r.Ymin, r.getWidth(), r.getHeight());
return transformation.toTransform().createTransformedShape(shp); //TODO: match character shapes (?)

View File

@@ -33,6 +33,7 @@ import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
import com.jpexs.decompiler.flash.tags.base.RemoveTag;
import com.jpexs.decompiler.flash.tags.base.RenderContext;
import com.jpexs.decompiler.flash.types.CLIPACTIONS;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.MATRIX;
@@ -67,6 +68,8 @@ public class Timeline {
public Tag parentTag;
public int maxDepth;
public List<Tag> tags;
private final List<Frame> frames = new ArrayList<>();
@@ -120,18 +123,19 @@ public class Timeline {
public final int getMaxDepth() {
ensureInitialized();
return getMaxDepthInternal();
return maxDepth;
}
public final int getMaxDepthInternal() {
private int getMaxDepthInternal() {
int max_depth = 0;
for (Frame f : frames) {
for (int depth : f.layers.keySet()) {
if (depth > max_depth) {
max_depth = depth;
}
if (f.layers.get(depth).clipDepth > max_depth) {
max_depth = f.layers.get(depth).clipDepth;
int clipDepth = f.layers.get(depth).clipDepth;
if (clipDepth > max_depth) {
max_depth = clipDepth;
}
}
}
@@ -285,9 +289,10 @@ public class Timeline {
frames.add(frame);
}
maxDepth = getMaxDepthInternal();
// todo: enable again after TweenDetector.detectRanges implemented
//detectTweens();
int maxDepth = getMaxDepthInternal();
for (int d = 1; d <= maxDepth; d++) {
for (int f = frames.size() - 1; f >= 0; f--) {
if (frames.get(f).layers.get(d) != null) {
@@ -307,7 +312,6 @@ public class Timeline {
}
private void detectTweens() {
int maxDepth = getMaxDepthInternal();
for (int d = 1; d <= maxDepth; d++) {
int characterId = -1;
int len = 0;
@@ -405,8 +409,8 @@ public class Timeline {
return modified;
}
public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
SWF.frameToImage(this, frame, time, stateUnderCursor, mouseButton, image, transformation, colorTransform);
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
SWF.frameToImage(this, frame, time, renderContext, image, transformation, colorTransform);
}
public String toHtmlCanvas(double unitDivisor, List<Integer> frames) {
@@ -417,7 +421,6 @@ public class Timeline {
Frame fr = getFrames().get(frame);
sounds.addAll(fr.sounds);
soundClasses.addAll(fr.soundClasses);
int maxDepth = getMaxDepthInternal();
for (int d = maxDepth; d >= 0; d--) {
DepthState ds = fr.layers.get(d);
if (ds != null) {
@@ -448,7 +451,6 @@ public class Timeline {
public void getObjectsOutlines(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation, List<DepthState> objs, List<Shape> outlines) {
Frame fr = getFrames().get(frame);
Stack<Clip> clips = new Stack<>();
int maxDepth = getMaxDepthInternal();
for (int d = maxDepth; d >= 0; d--) {
Clip currentClip = null;
for (int i = clips.size() - 1; i >= 0; i--) {
@@ -460,27 +462,27 @@ public class Timeline {
if (!clips.isEmpty()) {
currentClip = clips.peek();
}
DepthState ds = fr.layers.get(d);
if (ds == null) {
DepthState layer = fr.layers.get(d);
if (layer == null) {
continue;
}
if (!ds.isVisible) {
if (!layer.isVisible) {
continue;
}
CharacterTag c = swf.getCharacter(ds.characterId);
if (c instanceof DrawableTag) {
Matrix m = new Matrix(ds.matrix);
CharacterTag character = swf.getCharacter(layer.characterId);
if (character instanceof DrawableTag) {
DrawableTag drawable = (DrawableTag) character;
Matrix m = new Matrix(layer.matrix);
m = m.preConcatenate(transformation);
int dframe = 0;
if (c instanceof Timelined) {
int frameCount = ((Timelined) c).getTimeline().frames.size();
if (frameCount == 0) {
return;
}
dframe = ds.time % frameCount;
if (c instanceof ButtonTag) {
ButtonTag bt = (ButtonTag) c;
int drawableFrameCount = drawable.getNumFrames();
if (drawableFrameCount == 0) {
drawableFrameCount = 1;
}
int dframe = (time + layer.time) % drawableFrameCount;
if (character instanceof Timelined) {
if (character instanceof ButtonTag) {
ButtonTag bt = (ButtonTag) character;
dframe = ButtonTag.FRAME_HITTEST;
/*dframe = ButtonTag.FRAME_UP;
if (stateUnderCursor == ds) {
@@ -492,7 +494,11 @@ public class Timeline {
}*/
}
}
Shape cshape = ((DrawableTag) c).getOutline(dframe, ds.time + time, ds.ratio, stateUnderCursor, mouseButton, m);
RenderContext renderContext = new RenderContext();
renderContext.stateUnderCursor = stateUnderCursor;
renderContext.mouseButton = mouseButton;
Shape cshape = ((DrawableTag) character).getOutline(dframe, layer.time + time, layer.ratio, renderContext, m);
Area addArea = new Area(cshape);
if (currentClip != null) {
@@ -500,25 +506,24 @@ public class Timeline {
a.subtract(new Area(currentClip.shape));
addArea.subtract(a);
}
if (ds.clipDepth > -1) {
Clip clip = new Clip(addArea, ds.clipDepth);
if (layer.clipDepth > -1) {
Clip clip = new Clip(addArea, layer.clipDepth);
clips.push(clip);
} else {
objs.add(ds);
objs.add(layer);
outlines.add(addArea);
}
if (c instanceof Timelined) {
((Timelined) c).getTimeline().getObjectsOutlines(dframe, time + ds.time, ds.ratio, stateUnderCursor, mouseButton, m, objs, outlines);
if (character instanceof Timelined) {
((Timelined) character).getTimeline().getObjectsOutlines(dframe, time + layer.time, layer.ratio, stateUnderCursor, mouseButton, m, objs, outlines);
}
}
}
}
public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) {
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) {
Frame fr = getFrames().get(frame);
Area area = new Area();
Stack<Clip> clips = new Stack<>();
int maxDepth = getMaxDepthInternal();
for (int d = maxDepth; d >= 0; d--) {
Clip currentClip = null;
for (int i = clips.size() - 1; i >= 0; i--) {
@@ -530,30 +535,30 @@ public class Timeline {
if (!clips.isEmpty()) {
currentClip = clips.peek();
}
DepthState ds = fr.layers.get(d);
if (ds == null) {
DepthState layer = fr.layers.get(d);
if (layer == null) {
continue;
}
if (!ds.isVisible) {
if (!layer.isVisible) {
continue;
}
CharacterTag c = swf.getCharacter(ds.characterId);
if (c instanceof DrawableTag) {
Matrix m = new Matrix(ds.matrix);
CharacterTag character = swf.getCharacter(layer.characterId);
if (character instanceof DrawableTag) {
DrawableTag drawable = (DrawableTag) character;
Matrix m = new Matrix(layer.matrix);
m = m.preConcatenate(transformation);
int dframe = 0;
if (c instanceof Timelined) {
int frameCount = ((Timelined) c).getTimeline().frames.size();
if (frameCount < 1) {
frameCount = 1;
}
dframe = (time + ds.time) % frameCount;
if (c instanceof ButtonTag) {
ButtonTag bt = (ButtonTag) c;
int drawableFrameCount = drawable.getNumFrames();
if (drawableFrameCount == 0) {
drawableFrameCount = 1;
}
int dframe = (time + layer.time) % drawableFrameCount;
if (character instanceof Timelined) {
if (character instanceof ButtonTag) {
ButtonTag bt = (ButtonTag) character;
dframe = ButtonTag.FRAME_UP;
if (stateUnderCursor == ds) {
if (mouseButton > 0) {
if (renderContext.stateUnderCursor == layer) {
if (renderContext.mouseButton > 0) {
dframe = ButtonTag.FRAME_DOWN;
} else {
dframe = ButtonTag.FRAME_OVER;
@@ -561,7 +566,8 @@ public class Timeline {
}
}
}
Shape cshape = ((DrawableTag) c).getOutline(dframe, time + ds.time, ds.ratio, stateUnderCursor, mouseButton, m);
Shape cshape = ((DrawableTag) character).getOutline(dframe, time + layer.time, layer.ratio, renderContext, m);
Area addArea = new Area(cshape);
if (currentClip != null) {
@@ -569,8 +575,8 @@ public class Timeline {
a.subtract(new Area(currentClip.shape));
addArea.subtract(a);
}
if (ds.clipDepth > -1) {
Clip clip = new Clip(addArea, ds.clipDepth);
if (layer.clipDepth > -1) {
Clip clip = new Clip(addArea, layer.clipDepth);
clips.push(clip);
} else {
area.add(addArea);
@@ -590,8 +596,7 @@ public class Timeline {
}
public boolean isSingleFrame(int frame) {
Frame frameObj = frames.get(frame);
int maxDepth = getMaxDepthInternal();
Frame frameObj = getFrames().get(frame);
for (int i = 1; i <= maxDepth; i++) {
if (!frameObj.layers.containsKey(i)) {
continue;

View File

@@ -57,16 +57,16 @@ public class SerializableImage implements Serializable {
this.image = image;
}
public SerializableImage(int i, int i1, int i2) {
image = new BufferedImage(i, i1, i2);
public SerializableImage(int width, int height, int imageType) {
image = new BufferedImage(width, height, imageType);
}
public SerializableImage(ColorModel cm, WritableRaster wr, boolean bln, Hashtable<?, ?> hshtbl) {
image = new BufferedImage(cm, wr, bln, hshtbl);
public SerializableImage(ColorModel cm, WritableRaster raster, boolean isRasterPremultiplied, Hashtable<?, ?> properties) {
image = new BufferedImage(cm, raster, isRasterPremultiplied, properties);
}
public SerializableImage(int i, int i1, int i2, IndexColorModel icm) {
image = new BufferedImage(i, i1, i2, icm);
public SerializableImage(int width, int height, int imageType, IndexColorModel cm) {
image = new BufferedImage(width, height, imageType, cm);
}
public BufferedImage getBufferedImage() {