Fixed: #1570 Bad shapes rendering and export

This commit is contained in:
Jindra Petřík
2021-03-03 19:55:47 +01:00
parent ec0d890fd2
commit 74bb5ea5a2
4 changed files with 111 additions and 8 deletions

View File

@@ -12,7 +12,8 @@
* 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.SWF;

View File

@@ -12,7 +12,8 @@
* 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;
/**
@@ -43,4 +44,10 @@ public class CurvedEdge extends StraightEdge implements IEdge {
public IEdge reverseWithNewFillStyle(int newFillStyleIdx) {
return new CurvedEdge(toX, toY, controlX, controlY, fromX, fromY, lineStyleIdx, newFillStyleIdx);
}
@Override
public String toString() {
return "curved[" + fromX / 20f + "," + fromY / 20f + " -> " + toX / 20f + "," + toY / 20f + " control:" + controlX / 20f + "," + controlY / 20f + "]";
}
}

View File

@@ -12,7 +12,8 @@
* 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.SWF;
@@ -80,7 +81,11 @@ public abstract class ShapeExporterBase implements IShapeExporter {
// Create edge maps
List<Map<Integer, List<IEdge>>> fillEdgeMaps = new ArrayList<>();
List<Map<Integer, List<IEdge>>> lineEdgeMaps = new ArrayList<>();
List<Map<Integer, List<IEdge>>> lineEdgeMaps = new ArrayList<>();
try {
createEdgeMaps(shape, fillStyles, lineStyles, fillEdgeMaps, lineEdgeMaps);
} catch (Throwable t) {
t.printStackTrace();
}
int count = lineEdgeMaps.size();
List<List<IEdge>> fillPaths = new ArrayList<>(count);
List<List<IEdge>> linePaths = new ArrayList<>(count);
@@ -225,7 +230,9 @@ public abstract class ShapeExporterBase implements IShapeExporter {
currentFillEdgeMap.put(fillStyleIdx0, path);
}
for (int j = subPath.size() - 1; j >= 0; j--) {
for (int j = subPath.size() - 1; j >= 0; j--) {
IEdge rev = subPath.get(j).reverseWithNewFillStyle(fillStyleIdx0);
//System.err.println("appending reversed " + rev);
path.add(rev);
}
}
if (fillStyleIdx1 != 0) {
@@ -436,6 +443,7 @@ public abstract class ShapeExporterBase implements IShapeExporter {
IEdge prevEdge = null;
List<IEdge> tmpPath = new ArrayList<>();
Map<Long, List<IEdge>> coordMap = createCoordMap(subPath);
Map<Long, List<IEdge>> reverseCoordMap = createReverseCoordMap(subPath);
while (subPath.size() > 0) {
idx = 0;
while (idx < subPath.size()) {
@@ -446,8 +454,26 @@ public abstract class ShapeExporterBase implements IShapeExporter {
if (edge != null) {
idx = subPath.indexOf(edge);
} else {
} else {
idx = 0;
boolean useNew = false;
IEdge revEdge = findNextEdgeInCoordMap(reverseCoordMap, prevEdge);
if (revEdge != null) {
if (useNew) {
idx = subPath.indexOf(revEdge);
IEdge r = revEdge.reverseWithNewFillStyle(revEdge.getFillStyleIdx());
updateEdgeInCoordMap(coordMap, revEdge, r);
updateEdgeInReverseCoordMap(reverseCoordMap, revEdge, r);
subPath.set(idx, r);
} else {
idx = 0;
prevEdge = null;
}
} else {
idx = 0;
prevEdge = null;
}
}
continue;
}
@@ -456,6 +482,7 @@ public abstract class ShapeExporterBase implements IShapeExporter {
IEdge edge = subPath.remove(idx);
tmpPath.add(edge);
removeEdgeFromCoordMap(coordMap, edge);
removeEdgeFromReverseCoordMap(reverseCoordMap, edge);
prevEdge = edge;
}
}
@@ -481,6 +508,23 @@ public abstract class ShapeExporterBase implements IShapeExporter {
return coordMap;
}
private Map<Long, List<IEdge>> createReverseCoordMap(List<IEdge> path) {
Map<Long, List<IEdge>> coordMap = new HashMap<>();
for (int i = 0; i < path.size(); i++) {
IEdge edge = path.get(i);
long toLong = (((long) edge.getToX()) << 32) | (edge.getToY() & 0xffffffffL);
List<IEdge> coordMapArray = coordMap.get(toLong);
if (coordMapArray == null) {
List<IEdge> list = new ArrayList<>();
list.add(path.get(i));
coordMap.put(toLong, list);
} else {
coordMapArray.add(path.get(i));
}
}
return coordMap;
}
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);
@@ -496,6 +540,21 @@ public abstract class ShapeExporterBase implements IShapeExporter {
}
}
private void removeEdgeFromReverseCoordMap(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) {
if (coordMapArray.size() == 1) {
coordMap.remove(toLong);
} else {
int i = coordMapArray.indexOf(edge);
if (i > -1) {
coordMapArray.remove(i);
}
}
}
}
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);
@@ -505,6 +564,34 @@ public abstract class ShapeExporterBase implements IShapeExporter {
return null;
}
private IEdge updateEdgeInCoordMap(Map<Long, List<IEdge>> coordMap, IEdge edge, IEdge newEdge) {
long fromLong = (((long) edge.getFromX()) << 32) | (edge.getFromY() & 0xffffffffL);
coordMap.get(fromLong).remove(edge);
long fromLong2 = (((long) newEdge.getFromX()) << 32) | (newEdge.getFromY() & 0xffffffffL);
if (!coordMap.containsKey(fromLong2)) {
coordMap.put(fromLong2, new ArrayList<>());
}
coordMap.get(fromLong2).add(newEdge);
return null;
}
private IEdge updateEdgeInReverseCoordMap(Map<Long, List<IEdge>> coordMap, IEdge edge, IEdge newEdge) {
long toLong = (((long) edge.getToX()) << 32) | (edge.getToY() & 0xffffffffL);
coordMap.get(toLong).remove(edge);
long toLong2 = (((long) newEdge.getToX()) << 32) | (newEdge.getToY() & 0xffffffffL);
if (!coordMap.containsKey(toLong2)) {
coordMap.put(toLong2, new ArrayList<>());
}
coordMap.get(toLong2).add(newEdge);
return null;
}
private void appendFillStyles(List<FillStyle> v1, FILLSTYLE[] v2) {
for (FILLSTYLE s : v2) {
v1.add(new FillStyle(s));
@@ -519,6 +606,7 @@ public abstract class ShapeExporterBase implements IShapeExporter {
private void appendEdges(List<IEdge> v1, List<IEdge> v2) {
for (int i = 0; i < v2.size(); i++) {
//System.err.println("appending " + v2.get(i));
v1.add(v2.get(i));
}
}

View File

@@ -12,7 +12,8 @@
* 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;
/**
@@ -76,4 +77,10 @@ public class StraightEdge implements IEdge {
public IEdge reverseWithNewFillStyle(int newFillStyleIdx) {
return new StraightEdge(toX, toY, fromX, fromY, lineStyleIdx, newFillStyleIdx);
}
@Override
public String toString() {
return "straight[" + fromX / 20f + "," + fromY / 20f + " -> " + toX / 20f + "," + toY / 20f + "]";
}
}