From 74bb5ea5a25f2fde8bf2f16398ea723c440c00d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Wed, 3 Mar 2021 19:55:47 +0100 Subject: [PATCH] Fixed: #1570 Bad shapes rendering and export --- .../flash/exporters/shape/BitmapExporter.java | 3 +- .../flash/exporters/shape/CurvedEdge.java | 9 +- .../exporters/shape/ShapeExporterBase.java | 98 ++++++++++++++++++- .../flash/exporters/shape/StraightEdge.java | 9 +- 4 files changed, 111 insertions(+), 8 deletions(-) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/BitmapExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/BitmapExporter.java index 167b19a14..7726cf561 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/BitmapExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/BitmapExporter.java @@ -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; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/CurvedEdge.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/CurvedEdge.java index 4540d4253..1e93fd352 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/CurvedEdge.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/CurvedEdge.java @@ -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 + "]"; + } + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/ShapeExporterBase.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/ShapeExporterBase.java index 995355f1e..7f003d015 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/ShapeExporterBase.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/ShapeExporterBase.java @@ -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>> fillEdgeMaps = new ArrayList<>(); List>> lineEdgeMaps = new ArrayList<>(); - createEdgeMaps(shape, fillStyles, lineStyles, fillEdgeMaps, lineEdgeMaps); + try { + createEdgeMaps(shape, fillStyles, lineStyles, fillEdgeMaps, lineEdgeMaps); + } catch (Throwable t) { + t.printStackTrace(); + } int count = lineEdgeMaps.size(); List> fillPaths = new ArrayList<>(count); List> 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--) { - path.add(subPath.get(j).reverseWithNewFillStyle(fillStyleIdx0)); + 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 tmpPath = new ArrayList<>(); Map> coordMap = createCoordMap(subPath); + Map> 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 { - idx = 0; - prevEdge = null; + + 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> createReverseCoordMap(List path) { + Map> 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 coordMapArray = coordMap.get(toLong); + if (coordMapArray == null) { + List list = new ArrayList<>(); + list.add(path.get(i)); + coordMap.put(toLong, list); + } else { + coordMapArray.add(path.get(i)); + } + } + return coordMap; + } + private void removeEdgeFromCoordMap(Map> coordMap, IEdge edge) { long fromLong = (((long) edge.getFromX()) << 32) | (edge.getFromY() & 0xffffffffL); List coordMapArray = coordMap.get(fromLong); @@ -496,6 +540,21 @@ public abstract class ShapeExporterBase implements IShapeExporter { } } + private void removeEdgeFromReverseCoordMap(Map> coordMap, IEdge edge) { + long toLong = (((long) edge.getToX()) << 32) | (edge.getToY() & 0xffffffffL); + List 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> coordMap, IEdge edge) { long toLong = (((long) edge.getToX()) << 32) | (edge.getToY() & 0xffffffffL); List coordMapArray = coordMap.get(toLong); @@ -505,6 +564,34 @@ public abstract class ShapeExporterBase implements IShapeExporter { return null; } + private IEdge updateEdgeInCoordMap(Map> 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> 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 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 v1, List v2) { for (int i = 0; i < v2.size(); i++) { + //System.err.println("appending " + v2.get(i)); v1.add(v2.get(i)); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/StraightEdge.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/StraightEdge.java index b9f8416ec..9892dff04 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/StraightEdge.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/StraightEdge.java @@ -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 + "]"; + } + }