Fixed: #2460 SVG export - incorrect caching colorTransform and ratio for the same tag

This commit is contained in:
Jindra Petřík
2025-05-27 00:05:42 +02:00
parent c8ad42cf9b
commit 9cd6a203fe
4 changed files with 135 additions and 10 deletions

View File

@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.FontExportMode;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.types.BlendMode;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.RGBA;
import com.jpexs.decompiler.flash.types.filters.FILTER;
@@ -32,6 +33,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -78,7 +80,7 @@ public class SVGExporter {
protected int lastClipId;
public Map<Tag, String> exportedTags = new HashMap<>();
public Map<ExportKey, String> exportedTags = new HashMap<>();
public Map<Tag, Map<Integer, String>> exportedChars = new HashMap<>();
@@ -88,6 +90,49 @@ public class SVGExporter {
public boolean useTextTag = Configuration.textExportExportFontFace.get();
public static class ExportKey {
private final Tag tag;
public final ColorTransform colorTransform;
public final int ratio;
public ExportKey(Tag tag, ColorTransform colorTransform, int ratio) {
this.tag = tag;
this.colorTransform = colorTransform;
this.ratio = ratio;
}
@Override
public int hashCode() {
int hash = 7;
hash = 43 * hash + Objects.hashCode(this.tag);
hash = 43 * hash + Objects.hashCode(this.colorTransform);
hash = 43 * hash + this.ratio;
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ExportKey other = (ExportKey) obj;
if (this.ratio != other.ratio) {
return false;
}
if (!Objects.equals(this.tag, other.tag)) {
return false;
}
return Objects.equals(this.colorTransform, other.colorTransform);
}
}
public SVGExporter(ExportRectangle bounds, double zoom, String objectType) {
this(bounds, zoom, objectType, null);
}

View File

@@ -145,7 +145,7 @@ public class Timeline {
* Map of depth to maximum frame.
*/
private final Map<Integer, Integer> depthMaxFrame = new HashMap<>();
/**
* Map of depth to maximum frame including buttons
*/
@@ -289,7 +289,7 @@ public class Timeline {
ensureInitialized();
return depthMaxFrame;
}
/**
* Gets map of depth to max frame including buttons
*
@@ -746,23 +746,23 @@ public class Timeline {
for (int d = 0; d <= maxDepth; d++) {
for (int f = frames.size() - 1; f >= 0; f--) {
if (frames.get(f).layers.get(d) != null) {
depthMaxFrame.put(d, f);
depthMaxFrame.put(d, f);
break;
}
}
}
if (timelined instanceof ButtonTag) {
ButtonTag button = (ButtonTag) timelined;
Set<Integer> emptyFrames = button.getEmptyFrames();
for (int d = 0; d <= maxDepth; d++) {
for (int f = frames.size() - 1; f >= 0; f--) {
if (frames.get(f).layers.get(d) != null) {
if (!emptyFrames.contains(f)) {
depthMaxFrameButtons.put(d, f);
break;
}
}
}
}
}
@@ -1657,11 +1657,13 @@ public class Timeline {
Tag drawableTag = (Tag) drawable;
RECT boundRect = drawable.getRect();
boolean createNew = false;
if (exporter.exportedTags.containsKey(drawableTag)) {
assetName = exporter.exportedTags.get(drawableTag);
SVGExporter.ExportKey exportKey = new SVGExporter.ExportKey(drawableTag, clrTrans, layer.ratio);
if (exporter.exportedTags.containsKey(exportKey)) {
assetName = exporter.exportedTags.get(exportKey);
} else {
assetName = getTagIdPrefix(drawableTag, exporter);
exporter.exportedTags.put(drawableTag, assetName);
exporter.exportedTags.put(exportKey, assetName);
createNew = true;
}
ExportRectangle rect = new ExportRectangle(boundRect);

View File

@@ -28,6 +28,15 @@ import java.awt.image.RescaleOp;
*/
public class ColorTransform implements Cloneable {
private int redAdd;
private int greenAdd;
private int blueAdd;
private int alphaAdd;
private int redMulti;
private int greenMulti;
private int blueMulti;
private int alphaMulti;
/**
* Constructor.
*/
@@ -37,6 +46,7 @@ public class ColorTransform implements Cloneable {
/**
* Converts this color transform to RescaleOp.
*
* @return RescaleOp
*/
public RescaleOp toRescaleOp() {
@@ -46,6 +56,7 @@ public class ColorTransform implements Cloneable {
/**
* Applies this color transform to the given image.
*
* @param src Source image
* @return Transformed image
*/
@@ -55,6 +66,7 @@ public class ColorTransform implements Cloneable {
/**
* Applies this color transform to the given color.
*
* @param color Color
* @return Transformed color
*/
@@ -64,6 +76,7 @@ public class ColorTransform implements Cloneable {
/**
* Applies this color transform to the given color.
*
* @param color Color
* @return Transformed color
*/
@@ -76,6 +89,7 @@ public class ColorTransform implements Cloneable {
/**
* Applies this color transform to the given color.
*
* @param color Color
* @return Transformed color
*/
@@ -88,6 +102,7 @@ public class ColorTransform implements Cloneable {
/**
* Applies this color transform to the given color.
*
* @param color Color
* @return Transformed color
*/
@@ -100,6 +115,7 @@ public class ColorTransform implements Cloneable {
/**
* Applies this color transform to gradient records.
*
* @param gradRecords Gradient records
* @return Transformed gradient records
*/
@@ -118,6 +134,7 @@ public class ColorTransform implements Cloneable {
/**
* Gets red addition.
*
* @return Red addition
*/
public int getRedAdd() {
@@ -126,6 +143,7 @@ public class ColorTransform implements Cloneable {
/**
* Gets green addition.
*
* @return Green addition
*/
public int getGreenAdd() {
@@ -134,6 +152,7 @@ public class ColorTransform implements Cloneable {
/**
* Gets blue addition.
*
* @return Blue addition
*/
public int getBlueAdd() {
@@ -142,6 +161,7 @@ public class ColorTransform implements Cloneable {
/**
* Gets alpha addition.
*
* @return Alpha addition
*/
public int getAlphaAdd() {
@@ -150,6 +170,7 @@ public class ColorTransform implements Cloneable {
/**
* Gets red multiplier.
*
* @return Red multiplier
*/
public int getRedMulti() {
@@ -158,6 +179,7 @@ public class ColorTransform implements Cloneable {
/**
* Gets green multiplier.
*
* @return Green multiplier
*/
public int getGreenMulti() {
@@ -166,6 +188,7 @@ public class ColorTransform implements Cloneable {
/**
* Gets blue multiplier.
*
* @return Blue multiplier
*/
public int getBlueMulti() {
@@ -174,6 +197,7 @@ public class ColorTransform implements Cloneable {
/**
* Gets alpha multiplier.
*
* @return Alpha multiplier
*/
public int getAlphaMulti() {
@@ -182,6 +206,7 @@ public class ColorTransform implements Cloneable {
/**
* Merges this color transform with another one.
*
* @param c Another color transform
* @return Merged color transform
*/
@@ -245,4 +270,55 @@ public class ColorTransform implements Cloneable {
throw new RuntimeException();
}
}
@Override
public int hashCode() {
int hash = 3;
hash = 97 * hash + this.getRedAdd();
hash = 97 * hash + this.getGreenAdd();
hash = 97 * hash + this.getBlueAdd();
hash = 97 * hash + this.getAlphaAdd();
hash = 97 * hash + this.getRedMulti();
hash = 97 * hash + this.getGreenMulti();
hash = 97 * hash + this.getBlueMulti();
hash = 97 * hash + this.getAlphaMulti();
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof ColorTransform)) {
return false;
}
final ColorTransform other = (ColorTransform) obj;
if (this.getRedAdd() != other.getRedAdd()) {
return false;
}
if (this.getGreenAdd() != other.getGreenAdd()) {
return false;
}
if (this.getBlueAdd() != other.getBlueAdd()) {
return false;
}
if (this.getAlphaAdd() != other.getAlphaAdd()) {
return false;
}
if (this.getRedMulti() != other.getRedMulti()) {
return false;
}
if (this.getGreenMulti() != other.getGreenMulti()) {
return false;
}
if (this.getBlueMulti() != other.getBlueMulti()) {
return false;
}
return this.getAlphaMulti() == other.getAlphaMulti();
}
}