faster shape export

This commit is contained in:
honfika@gmail.com
2015-06-17 14:46:49 +02:00
parent 324f5f52e2
commit ad9497cb46
9 changed files with 269 additions and 237 deletions

View File

@@ -1,59 +0,0 @@
/*
* 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.exporters.commonshape;
/**
*
* @author JPEXS
*/
public class PointInt {
public static final PointInt MAX = new PointInt(Integer.MAX_VALUE, Integer.MAX_VALUE);
private final int x;
private final int y;
public PointInt(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
public int hashCode() {
long bits = Double.doubleToLongBits(x);
bits ^= Double.doubleToLongBits(y) * 31;
return (((int) bits) ^ ((int) (bits >> 32)));
}
@Override
public boolean equals(Object obj) {
if (obj instanceof PointInt) {
PointInt pt = (PointInt) obj;
return (x == pt.x) && (y == pt.y);
}
return super.equals(obj);
}
}

View File

@@ -16,35 +16,47 @@
*/
package com.jpexs.decompiler.flash.exporters.morphshape;
import com.jpexs.decompiler.flash.exporters.commonshape.PointInt;
/**
*
* @author JPEXS
*/
public class CurvedMorphEdge extends StraightMorphEdge implements IMorphEdge {
private final PointInt control;
private final int controlX;
private final PointInt controlEnd;
private final int controlY;
CurvedMorphEdge(PointInt from, PointInt control, PointInt to,
PointInt fromEnd, PointInt controlEnd, PointInt toEnd, int lineStyleIdx, int fillStyleIdx) {
super(from, to, fromEnd, toEnd, lineStyleIdx, fillStyleIdx);
this.control = control;
this.controlEnd = controlEnd;
private final int controlEndX;
private final int controlEndY;
CurvedMorphEdge(int fromX, int fromY, int controlX, int controlY, int toX, int toY,
int fromEndX, int fromEndY, int controlEndX, int controlEndY, int toEndX, int toEndY, int lineStyleIdx, int fillStyleIdx) {
super(fromX, fromY, toX, toY, fromEndX, fromEndY, toEndX, toEndY, lineStyleIdx, fillStyleIdx);
this.controlX = controlX;
this.controlY = controlY;
this.controlEndX = controlEndX;
this.controlEndY = controlEndY;
}
public PointInt getControl() {
return control;
public int getControlX() {
return controlX;
}
public PointInt getControlEnd() {
return controlEnd;
public int getControlY() {
return controlY;
}
public int getControlEndX() {
return controlEndX;
}
public int getControlEndY() {
return controlEndY;
}
@Override
public IMorphEdge reverseWithNewFillStyle(int newFillStyleIdx) {
return new CurvedMorphEdge(to, control, from, toEnd, controlEnd, fromEnd, lineStyleIdx, newFillStyleIdx);
return new CurvedMorphEdge(toX, toY, controlX, controlY, fromX, fromY, toEndX, toEndY, controlEndX, controlEndY, fromEndX, fromEndY, lineStyleIdx, newFillStyleIdx);
}
}

View File

@@ -1,35 +1,42 @@
/*
* 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.exporters.morphshape;
import com.jpexs.decompiler.flash.exporters.commonshape.PointInt;
/**
*
* @author JPEXS
*/
public interface IMorphEdge {
public int getFromX();
public int getFromY();
public int getToX();
public int getToY();
public int getFromEndX();
public int getFromEndY();
public int getToEndX();
public int getToEndY();
public int getLineStyleIdx();

View File

@@ -17,7 +17,6 @@
package com.jpexs.decompiler.flash.exporters.morphshape;
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
import com.jpexs.decompiler.flash.exporters.commonshape.PointInt;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.FILLSTYLE;
import com.jpexs.decompiler.flash.types.FOCALGRADIENT;
@@ -195,7 +194,8 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
}
} else if (shapeRecord instanceof StraightEdgeRecord) {
StraightEdgeRecord straightEdgeRecord = (StraightEdgeRecord) shapeRecord;
PointInt from = new PointInt(xPos, yPos);
int xPosFrom = xPos;
int yPosFrom = yPos;
if (straightEdgeRecord.generalLineFlag) {
xPos += straightEdgeRecord.deltaX;
yPos += straightEdgeRecord.deltaY;
@@ -206,10 +206,10 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
xPos += straightEdgeRecord.deltaX;
}
}
PointInt to = new PointInt(xPos, yPos);
StraightEdgeRecord straightEdgeRecordEnd = (StraightEdgeRecord) shapeRecordEnd;
PointInt fromEnd = new PointInt(xPosEnd, yPosEnd);
int xPosEndFrom = xPosEnd;
int yPosEndFrom = yPosEnd;
if (straightEdgeRecordEnd.generalLineFlag) {
xPosEnd += straightEdgeRecordEnd.deltaX;
yPosEnd += straightEdgeRecordEnd.deltaY;
@@ -220,29 +220,26 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
xPosEnd += straightEdgeRecordEnd.deltaX;
}
}
PointInt toEnd = new PointInt(xPosEnd, yPosEnd);
subPath.add(new StraightMorphEdge(from, to, fromEnd, toEnd, currentLineStyleIdx, currentFillStyleIdx1));
subPath.add(new StraightMorphEdge(xPosFrom, yPosFrom, xPos, yPos, xPosEndFrom, yPosEndFrom, xPosEnd, yPosEnd, currentLineStyleIdx, currentFillStyleIdx1));
} else if (shapeRecord instanceof CurvedEdgeRecord) {
CurvedEdgeRecord curvedEdgeRecord = (CurvedEdgeRecord) shapeRecord;
PointInt from = new PointInt(xPos, yPos);
int xPosFrom = xPos;
int yPosFrom = yPos;
int xPosControl = xPos + curvedEdgeRecord.controlDeltaX;
int yPosControl = yPos + curvedEdgeRecord.controlDeltaY;
xPos = xPosControl + curvedEdgeRecord.anchorDeltaX;
yPos = yPosControl + curvedEdgeRecord.anchorDeltaY;
PointInt control = new PointInt(xPosControl, yPosControl);
PointInt to = new PointInt(xPos, yPos);
CurvedEdgeRecord curvedEdgeRecordEnd = (CurvedEdgeRecord) shapeRecordEnd;
PointInt fromEnd = new PointInt(xPosEnd, yPosEnd);
int xPosControlEnd = xPosEnd + curvedEdgeRecordEnd.controlDeltaX;
int yPosControlEnd = yPosEnd + curvedEdgeRecordEnd.controlDeltaY;
xPosEnd = xPosControlEnd + curvedEdgeRecordEnd.anchorDeltaX;
yPosEnd = yPosControlEnd + curvedEdgeRecordEnd.anchorDeltaY;
PointInt controlEnd = new PointInt(xPosControlEnd, yPosControlEnd);
PointInt toEnd = new PointInt(xPosEnd, yPosEnd);
int xPosEndFrom = xPosEnd;
int yPosEndFrom = yPosEnd;
int xPosEndControl = xPosEnd + curvedEdgeRecordEnd.controlDeltaX;
int yPosEndControl = yPosEnd + curvedEdgeRecordEnd.controlDeltaY;
xPosEnd = xPosEndControl + curvedEdgeRecordEnd.anchorDeltaX;
yPosEnd = yPosEndControl + curvedEdgeRecordEnd.anchorDeltaY;
subPath.add(new CurvedMorphEdge(from, control, to, fromEnd, controlEnd, toEnd, currentLineStyleIdx, currentFillStyleIdx1));
subPath.add(new CurvedMorphEdge(xPosFrom, yPosFrom, xPosControl, yPosControl, xPos, yPos, xPosEndFrom, yPosEndFrom, xPosEndControl, yPosEndControl, xPosEnd, yPosEnd, currentLineStyleIdx, currentFillStyleIdx1));
} else if (shapeRecord instanceof EndShapeRecord) {
// We're done. Process the last subpath, if any
processSubPath(subPath, currentLineStyleIdx, currentFillStyleIdx0, currentFillStyleIdx1, currentFillEdgeMap, currentLineEdgeMap);
@@ -290,7 +287,8 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
protected void exportFillPath(int groupIndex) {
List<IMorphEdge> path = createPathFromEdgeMap(_fillEdgeMaps.get(groupIndex));
PointInt pos = PointInt.MAX;
int posX = Integer.MAX_VALUE;
int posY = Integer.MAX_VALUE;
int fillStyleIdx = Integer.MAX_VALUE;
if (path.size() > 0) {
beginFills();
@@ -301,7 +299,8 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
endFill();
}
fillStyleIdx = e.getFillStyleIdx();
pos = PointInt.MAX;
posX = Integer.MAX_VALUE;
posY = Integer.MAX_VALUE;
if (fillStyleIdx - 1 < _fillStyles.size()) {
Matrix matrix;
Matrix matrixEnd;
@@ -353,16 +352,17 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
beginFill(null, null);
}
}
if (!pos.equals(e.getFrom())) {
moveTo(e.getFrom().getX(), e.getFrom().getY(), e.getFromEnd().getX(), e.getFromEnd().getY());
if (posX != e.getFromX() || posY != e.getFromY()) {
moveTo(e.getFromX(), e.getFromY(), e.getFromEndX(), e.getFromEndY());
}
if (e instanceof CurvedMorphEdge) {
CurvedMorphEdge c = (CurvedMorphEdge) e;
curveTo(c.getControl().getX(), c.getControl().getY(), c.to.getX(), c.to.getY(), c.getControlEnd().getX(), c.getControlEnd().getY(), c.toEnd.getX(), c.toEnd.getY());
curveTo(c.getControlX(), c.getControlY(), c.toX, c.toY, c.getControlEndX(), c.getControlEndY(), c.toEndX, c.toEndY);
} else {
lineTo(e.getTo().getX(), e.getTo().getY(), e.getToEnd().getX(), e.getToEnd().getY());
lineTo(e.getToX(), e.getToY(), e.getToEndX(), e.getToEndY());
}
pos = e.getTo();
posX = e.getToX();
posY = e.getToY();
}
if (fillStyleIdx != Integer.MAX_VALUE) {
endFill();
@@ -373,7 +373,8 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
protected void exportLinePath(int groupIndex) {
List<IMorphEdge> path = createPathFromEdgeMap(_lineEdgeMaps.get(groupIndex));
PointInt pos = PointInt.MAX;
int posX = Integer.MAX_VALUE;
int posY = Integer.MAX_VALUE;
int lineStyleIdx = Integer.MAX_VALUE;
if (path.size() > 0) {
beginLines();
@@ -381,7 +382,8 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
IMorphEdge e = path.get(i);
if (lineStyleIdx != e.getLineStyleIdx()) {
lineStyleIdx = e.getLineStyleIdx();
pos = PointInt.MAX;
posX = Integer.MAX_VALUE;
posY = Integer.MAX_VALUE;
LINESTYLE lineStyle = null;
LINESTYLE lineStyleEnd = null;
try {
@@ -456,16 +458,17 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
lineStyle(1, 1, new RGB(Color.black), new RGB(Color.BLACK), false, "NORMAL", 0, 0, 0, 3);
}
}
if (!e.getFrom().equals(pos)) {
moveTo(e.getFrom().getX(), e.getFrom().getY(), e.getFromEnd().getX(), e.getFromEnd().getY());
if (posX != e.getFromX() || posY != e.getFromY()) {
moveTo(e.getFromX(), e.getFromY(), e.getFromEndX(), e.getFromEndY());
}
if (e instanceof CurvedMorphEdge) {
CurvedMorphEdge c = (CurvedMorphEdge) e;
curveTo(c.getControl().getX(), c.getControl().getY(), c.to.getX(), c.to.getY(), c.getControlEnd().getX(), c.getControlEnd().getY(), c.toEnd.getX(), c.toEnd.getY());
curveTo(c.getControlX(), c.getControlY(), c.toX, c.toY, c.getControlEndX(), c.getControlEndY(), c.toEndX, c.toEndY);
} else {
lineTo(e.getTo().getX(), e.getTo().getY(), e.getToEnd().getX(), e.getToEnd().getY());
lineTo(e.getToX(), e.getToY(), e.getToEndX(), e.getToEndY());
}
pos = e.getTo();
posX = e.getToX();
posY = e.getToY();
}
endLines();
}
@@ -491,24 +494,28 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
int idx;
IMorphEdge prevEdge = null;
List<IMorphEdge> tmpPath = new ArrayList<>();
Map<PointInt, List<IMorphEdge>> coordMap = createCoordMap(subPath);
Map<Long, List<IMorphEdge>> coordMap = createCoordMap(subPath);
while (subPath.size() > 0) {
idx = 0;
while (idx < subPath.size()) {
if (prevEdge == null || prevEdge.getTo().equals(subPath.get(idx).getFrom())) {
IMorphEdge edge = subPath.remove(idx);
tmpPath.add(edge);
removeEdgeFromCoordMap(coordMap, edge);
prevEdge = edge;
} else {
IMorphEdge edge = findNextEdgeInCoordMap(coordMap, prevEdge);
if (edge != null) {
idx = subPath.indexOf(edge);
} else {
idx = 0;
prevEdge = null;
if (prevEdge != null) {
IMorphEdge subPathEdge = subPath.get(idx);
if (prevEdge.getToX() != subPathEdge.getFromX() || prevEdge.getToY() != subPathEdge.getFromY()) {
IMorphEdge edge = findNextEdgeInCoordMap(coordMap, prevEdge);
if (edge != null) {
idx = subPath.indexOf(edge);
} else {
idx = 0;
prevEdge = null;
}
continue;
}
}
IMorphEdge edge = subPath.remove(idx);
tmpPath.add(edge);
removeEdgeFromCoordMap(coordMap, edge);
prevEdge = edge;
}
}
edgeMap.put(styleIdx, tmpPath);
@@ -516,15 +523,16 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
}
}
protected Map<PointInt, List<IMorphEdge>> createCoordMap(List<IMorphEdge> path) {
Map<PointInt, List<IMorphEdge>> coordMap = new HashMap<>();
protected Map<Long, List<IMorphEdge>> createCoordMap(List<IMorphEdge> path) {
Map<Long, List<IMorphEdge>> coordMap = new HashMap<>();
for (int i = 0; i < path.size(); i++) {
PointInt from = path.get(i).getFrom();
List<IMorphEdge> coordMapArray = coordMap.get(from);
IMorphEdge edge = path.get(i);
long fromLong = (((long) edge.getFromX()) << 32) | (edge.getFromY() & 0xffffffffL);
List<IMorphEdge> coordMapArray = coordMap.get(fromLong);
if (coordMapArray == null) {
List<IMorphEdge> list = new ArrayList<>();
list.add(path.get(i));
coordMap.put(from, list);
coordMap.put(fromLong, list);
} else {
coordMapArray.add(path.get(i));
}
@@ -532,12 +540,12 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
return coordMap;
}
protected void removeEdgeFromCoordMap(Map<PointInt, List<IMorphEdge>> coordMap, IMorphEdge edge) {
PointInt from = edge.getFrom();
List<IMorphEdge> coordMapArray = coordMap.get(from);
protected void removeEdgeFromCoordMap(Map<Long, List<IMorphEdge>> coordMap, IMorphEdge edge) {
long fromLong = (((long) edge.getFromX()) << 32) | (edge.getFromY() & 0xffffffffL);
List<IMorphEdge> coordMapArray = coordMap.get(fromLong);
if (coordMapArray != null) {
if (coordMapArray.size() == 1) {
coordMap.remove(from);
coordMap.remove(fromLong);
} else {
int i = coordMapArray.indexOf(edge);
if (i > -1) {
@@ -547,8 +555,9 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
}
}
protected IMorphEdge findNextEdgeInCoordMap(Map<PointInt, List<IMorphEdge>> coordMap, IMorphEdge edge) {
List<IMorphEdge> coordMapArray = coordMap.get(edge.getTo());
protected IMorphEdge findNextEdgeInCoordMap(Map<Long, List<IMorphEdge>> coordMap, IMorphEdge edge) {
long toLong = (((long) edge.getToX()) << 32) | (edge.getToY() & 0xffffffffL);
List<IMorphEdge> coordMapArray = coordMap.get(toLong);
if (coordMapArray != null && coordMapArray.size() > 0) {
return coordMapArray.get(0);
}

View File

@@ -16,53 +16,83 @@
*/
package com.jpexs.decompiler.flash.exporters.morphshape;
import com.jpexs.decompiler.flash.exporters.commonshape.PointInt;
/**
*
* @author JPEXS
*/
public class StraightMorphEdge implements IMorphEdge {
protected final PointInt from;
protected final int fromX;
protected final PointInt to;
protected final int fromY;
protected final PointInt fromEnd;
protected final int toX;
protected final PointInt toEnd;
protected final int toY;
protected final int fromEndX;
protected final int fromEndY;
protected final int toEndX;
protected final int toEndY;
protected final int lineStyleIdx;
private final int fillStyleIdx;
StraightMorphEdge(PointInt from, PointInt to, PointInt fromEnd, PointInt toEnd, int lineStyleIdx, int fillStyleIdx) {
this.from = from;
this.to = to;
this.fromEnd = fromEnd;
this.toEnd = toEnd;
StraightMorphEdge(int fromX, int fromY, int toX, int toY, int fromEndX, int fromEndY, int toEndX, int toEndY, int lineStyleIdx, int fillStyleIdx) {
this.fromX = fromX;
this.fromY = fromY;
this.toX = toX;
this.toY = toY;
this.fromEndX = fromEndX;
this.fromEndY = fromEndY;
this.toEndX = toEndX;
this.toEndY = toEndY;
this.lineStyleIdx = lineStyleIdx;
this.fillStyleIdx = fillStyleIdx;
}
@Override
public PointInt getFrom() {
return from;
public int getFromX() {
return fromX;
}
@Override
public PointInt getTo() {
return to;
public int getFromY() {
return fromY;
}
@Override
public PointInt getFromEnd() {
return fromEnd;
public int getToX() {
return toX;
}
@Override
public PointInt getToEnd() {
return toEnd;
public int getToY() {
return toY;
}
@Override
public int getFromEndX() {
return fromEndX;
}
@Override
public int getFromEndY() {
return fromEndY;
}
@Override
public int getToEndX() {
return toEndX;
}
@Override
public int getToEndY() {
return toEndY;
}
@Override
@@ -77,6 +107,6 @@ public class StraightMorphEdge implements IMorphEdge {
@Override
public IMorphEdge reverseWithNewFillStyle(int newFillStyleIdx) {
return new StraightMorphEdge(to, from, toEnd, fromEnd, lineStyleIdx, newFillStyleIdx);
return new StraightMorphEdge(toX, toY, fromX, fromY, toEndX, toEndY, fromEndX, fromEndY, lineStyleIdx, newFillStyleIdx);
}
}

View File

@@ -1,41 +1,47 @@
/*
* 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.exporters.shape;
import com.jpexs.decompiler.flash.exporters.commonshape.PointInt;
/**
*
* @author JPEXS
*/
public class CurvedEdge extends StraightEdge implements IEdge {
private final int controlX;
CurvedEdge(PointInt from, PointInt control, PointInt to, int lineStyleIdx, int fillStyleIdx) {
super(from, to, lineStyleIdx, fillStyleIdx);
private final int controlY;
CurvedEdge(int fromX, int fromY, int controlX, int controlY, int toX, int toY, int lineStyleIdx, int fillStyleIdx) {
super(fromX, fromY, toX, toY, lineStyleIdx, fillStyleIdx);
this.controlX = controlX;
this.controlY = controlY;
}
public PointInt getControl() {
public int getControlX() {
return controlX;
}
public int getControlY() {
return controlY;
}
@Override
public IEdge reverseWithNewFillStyle(int newFillStyleIdx) {
public IEdge reverseWithNewFillStyle(int newFillStyleIdx) {
return new CurvedEdge(toX, toY, controlX, controlY, fromX, fromY, lineStyleIdx, newFillStyleIdx);
}
}

View File

@@ -1,31 +1,34 @@
/*
* 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.exporters.shape;
import com.jpexs.decompiler.flash.exporters.commonshape.PointInt;
/**
*
* @author JPEXS
*/
public interface IEdge {
public int getFromX();
public int getFromY();
public int getToX();
public int getToY();
public int getLineStyleIdx();

View File

@@ -18,7 +18,6 @@ package com.jpexs.decompiler.flash.exporters.shape;
import com.jpexs.decompiler.flash.exporters.commonshape.FillStyle;
import com.jpexs.decompiler.flash.exporters.commonshape.LineStyle;
import com.jpexs.decompiler.flash.exporters.commonshape.PointInt;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.FILLSTYLE;
import com.jpexs.decompiler.flash.types.FOCALGRADIENT;
@@ -186,7 +185,8 @@ public abstract class ShapeExporterBase implements IShapeExporter {
}
} else if (shapeRecord instanceof StraightEdgeRecord) {
StraightEdgeRecord straightEdgeRecord = (StraightEdgeRecord) shapeRecord;
PointInt from = new PointInt(xPos, yPos);
int xPosFrom = xPos;
int yPosFrom = yPos;
if (straightEdgeRecord.generalLineFlag) {
xPos += straightEdgeRecord.deltaX;
yPos += straightEdgeRecord.deltaY;
@@ -197,18 +197,16 @@ public abstract class ShapeExporterBase implements IShapeExporter {
xPos += straightEdgeRecord.deltaX;
}
}
PointInt to = new PointInt(xPos, yPos);
subPath.add(new StraightEdge(from, to, currentLineStyleIdx, currentFillStyleIdx1));
subPath.add(new StraightEdge(xPosFrom, yPosFrom, xPos, yPos, currentLineStyleIdx, currentFillStyleIdx1));
} else if (shapeRecord instanceof CurvedEdgeRecord) {
CurvedEdgeRecord curvedEdgeRecord = (CurvedEdgeRecord) shapeRecord;
PointInt from = new PointInt(xPos, yPos);
int xPosFrom = xPos;
int yPosFrom = yPos;
int xPosControl = xPos + curvedEdgeRecord.controlDeltaX;
int yPosControl = yPos + curvedEdgeRecord.controlDeltaY;
xPos = xPosControl + curvedEdgeRecord.anchorDeltaX;
yPos = yPosControl + curvedEdgeRecord.anchorDeltaY;
PointInt control = new PointInt(xPosControl, yPosControl);
PointInt to = new PointInt(xPos, yPos);
subPath.add(new CurvedEdge(from, control, to, currentLineStyleIdx, currentFillStyleIdx1));
subPath.add(new CurvedEdge(xPosFrom, yPosFrom, xPosControl, yPosControl, xPos, yPos, currentLineStyleIdx, currentFillStyleIdx1));
} else if (shapeRecord instanceof EndShapeRecord) {
// We're done. Process the last subpath, if any
processSubPath(subPath, currentLineStyleIdx, currentFillStyleIdx0, currentFillStyleIdx1, currentFillEdgeMap, currentLineEdgeMap);
@@ -252,7 +250,8 @@ public abstract class ShapeExporterBase implements IShapeExporter {
}
private void exportFillPath(List<IEdge> path) {
PointInt pos = PointInt.MAX;
int posX = Integer.MAX_VALUE;
int posY = Integer.MAX_VALUE;
int fillStyleIdx = Integer.MAX_VALUE;
if (path.size() > 0) {
beginFills();
@@ -263,7 +262,8 @@ public abstract class ShapeExporterBase implements IShapeExporter {
endFill();
}
fillStyleIdx = e.getFillStyleIdx();
pos = PointInt.MAX;
posX = Integer.MAX_VALUE;
posY = Integer.MAX_VALUE;
if (fillStyleIdx - 1 < _fillStyles.size()) {
FillStyle fillStyle = _fillStyles.get(fillStyleIdx - 1);
switch (fillStyle.fillStyleType) {
@@ -304,16 +304,17 @@ public abstract class ShapeExporterBase implements IShapeExporter {
beginFill(null);
}
}
if (!pos.equals(e.getFrom())) {
moveTo(e.getFrom().getX(), e.getFrom().getY());
if (posX != e.getFromX() || posY != e.getFromY()) {
moveTo(e.getFromX(), e.getFromY());
}
if (e instanceof CurvedEdge) {
CurvedEdge c = (CurvedEdge) e;
curveTo(c.getControl().getX(), c.getControl().getY(), c.to.getX(), c.to.getY());
curveTo(c.getControlX(), c.getControlY(), c.toX, c.toY);
} else {
lineTo(e.getTo().getX(), e.getTo().getY());
lineTo(e.getToX(), e.getToY());
}
pos = e.getTo();
posX = e.getToX();
posY = e.getToY();
}
if (fillStyleIdx != Integer.MAX_VALUE) {
endFill();
@@ -323,7 +324,8 @@ public abstract class ShapeExporterBase implements IShapeExporter {
}
private void exportLinePath(List<IEdge> path) {
PointInt pos = PointInt.MAX;
int posX = Integer.MAX_VALUE;
int posY = Integer.MAX_VALUE;
int lineStyleIdx = Integer.MAX_VALUE;
if (path.size() > 0) {
beginLines();
@@ -331,7 +333,8 @@ public abstract class ShapeExporterBase implements IShapeExporter {
IEdge e = path.get(i);
if (lineStyleIdx != e.getLineStyleIdx()) {
lineStyleIdx = e.getLineStyleIdx();
pos = PointInt.MAX;
posX = Integer.MAX_VALUE;
posY = Integer.MAX_VALUE;
LineStyle lineStyle = null;
try {
lineStyle = _lineStyles.get(lineStyleIdx - 1);
@@ -393,16 +396,17 @@ public abstract class ShapeExporterBase implements IShapeExporter {
lineStyle(1, new RGB(Color.black), false, "NORMAL", 0, 0, 0, 3);
}
}
if (!e.getFrom().equals(pos)) {
moveTo(e.getFrom().getX(), e.getFrom().getY());
if (posX != e.getFromX() || posY != e.getFromY()) {
moveTo(e.getFromX(), e.getFromY());
}
if (e instanceof CurvedEdge) {
CurvedEdge c = (CurvedEdge) e;
curveTo(c.getControl().getX(), c.getControl().getY(), c.to.getX(), c.to.getY());
curveTo(c.getControlX(), c.getControlY(), c.toX, c.toY);
} else {
lineTo(e.getTo().getX(), e.getTo().getY());
lineTo(e.getToX(), e.getToY());
}
pos = e.getTo();
posX = e.getToX();
posY = e.getToY();
}
endLines();
}
@@ -428,24 +432,28 @@ public abstract class ShapeExporterBase implements IShapeExporter {
int idx;
IEdge prevEdge = null;
List<IEdge> tmpPath = new ArrayList<>();
Map<PointInt, List<IEdge>> coordMap = createCoordMap(subPath);
Map<Long, List<IEdge>> coordMap = createCoordMap(subPath);
while (subPath.size() > 0) {
idx = 0;
while (idx < subPath.size()) {
if (prevEdge == null || prevEdge.getTo().equals(subPath.get(idx).getFrom())) {
IEdge edge = subPath.remove(idx);
tmpPath.add(edge);
removeEdgeFromCoordMap(coordMap, edge);
prevEdge = edge;
} else {
IEdge edge = findNextEdgeInCoordMap(coordMap, prevEdge);
if (edge != null) {
idx = subPath.indexOf(edge);
} else {
idx = 0;
prevEdge = null;
if (prevEdge != null) {
IEdge subPathEdge = subPath.get(idx);
if (prevEdge.getToX() != subPathEdge.getFromX() || prevEdge.getToY() != subPathEdge.getFromY()) {
IEdge edge = findNextEdgeInCoordMap(coordMap, prevEdge);
if (edge != null) {
idx = subPath.indexOf(edge);
} else {
idx = 0;
prevEdge = null;
}
continue;
}
}
IEdge edge = subPath.remove(idx);
tmpPath.add(edge);
removeEdgeFromCoordMap(coordMap, edge);
prevEdge = edge;
}
}
edgeMap.put(styleIdx, tmpPath);
@@ -453,15 +461,16 @@ public abstract class ShapeExporterBase implements IShapeExporter {
}
}
private Map<PointInt, List<IEdge>> createCoordMap(List<IEdge> path) {
Map<PointInt, List<IEdge>> coordMap = new HashMap<>();
private Map<Long, List<IEdge>> createCoordMap(List<IEdge> path) {
Map<Long, List<IEdge>> coordMap = new HashMap<>();
for (int i = 0; i < path.size(); i++) {
PointInt from = path.get(i).getFrom();
List<IEdge> coordMapArray = coordMap.get(from);
IEdge edge = path.get(i);
long fromLong = (((long) edge.getFromX()) << 32) | (edge.getFromY() & 0xffffffffL);
List<IEdge> coordMapArray = coordMap.get(fromLong);
if (coordMapArray == null) {
List<IEdge> list = new ArrayList<>();
list.add(path.get(i));
coordMap.put(from, list);
coordMap.put(fromLong, list);
} else {
coordMapArray.add(path.get(i));
}
@@ -469,12 +478,12 @@ public abstract class ShapeExporterBase implements IShapeExporter {
return coordMap;
}
private void removeEdgeFromCoordMap(Map<PointInt, List<IEdge>> coordMap, IEdge edge) {
PointInt from = edge.getFrom();
List<IEdge> coordMapArray = coordMap.get(from);
private void removeEdgeFromCoordMap(Map<Long, List<IEdge>> coordMap, IEdge edge) {
long fromLong = (((long) edge.getFromX()) << 32) | (edge.getFromY() & 0xffffffffL);
List<IEdge> coordMapArray = coordMap.get(fromLong);
if (coordMapArray != null) {
if (coordMapArray.size() == 1) {
coordMap.remove(from);
coordMap.remove(fromLong);
} else {
int i = coordMapArray.indexOf(edge);
if (i > -1) {
@@ -484,8 +493,9 @@ public abstract class ShapeExporterBase implements IShapeExporter {
}
}
private IEdge findNextEdgeInCoordMap(Map<PointInt, List<IEdge>> coordMap, IEdge edge) {
List<IEdge> coordMapArray = coordMap.get(edge.getTo());
private IEdge findNextEdgeInCoordMap(Map<Long, List<IEdge>> coordMap, IEdge edge) {
long toLong = (((long) edge.getToX()) << 32) | (edge.getToY() & 0xffffffffL);
List<IEdge> coordMapArray = coordMap.get(toLong);
if (coordMapArray != null && coordMapArray.size() > 0) {
return coordMapArray.get(0);
}

View File

@@ -16,37 +16,51 @@
*/
package com.jpexs.decompiler.flash.exporters.shape;
import com.jpexs.decompiler.flash.exporters.commonshape.PointInt;
/**
*
* @author JPEXS
*/
public class StraightEdge implements IEdge {
protected final PointInt from;
protected final int fromX;
protected final PointInt to;
protected final int fromY;
protected final int toX;
protected final int toY;
protected final int lineStyleIdx;
private final int fillStyleIdx;
StraightEdge(PointInt from, PointInt to, int lineStyleIdx, int fillStyleIdx) {
this.from = from;
this.to = to;
StraightEdge(int fromX, int fromY, int toX, int toY, int lineStyleIdx, int fillStyleIdx) {
this.fromX = fromX;
this.fromY = fromY;
this.toX = toX;
this.toY = toY;
this.lineStyleIdx = lineStyleIdx;
this.fillStyleIdx = fillStyleIdx;
}
@Override
public PointInt getFrom() {
return from;
public int getFromX() {
return fromX;
}
@Override
public PointInt getTo() {
return to;
public int getFromY() {
return fromY;
}
@Override
public int getToX() {
return toX;
}
@Override
public int getToY() {
return toY;
}
@Override
@@ -61,6 +75,6 @@ public class StraightEdge implements IEdge {
@Override
public IEdge reverseWithNewFillStyle(int newFillStyleIdx) {
return new StraightEdge(to, from, lineStyleIdx, newFillStyleIdx);
return new StraightEdge(toX, toY, fromX, fromY, lineStyleIdx, newFillStyleIdx);
}
}