Added SVG Export - stroke-bitmapId, fill-bitmapId attribute

Fixed Generic tag editor - morphshape fill - show bitmapId for repeating bitmap fill, gradient matrix for focal gradient

Changed SVG export - attributes like data-characterId and data-characterName moved under `ffdec:` namespace
This commit is contained in:
Jindra Petřík
2023-11-05 21:11:10 +01:00
parent d523b1ba54
commit 87d0bfc761
6 changed files with 81 additions and 15 deletions
@@ -61,6 +61,8 @@ public class SVGExporter {
protected static final String sNamespace = "http://www.w3.org/2000/svg";
protected static final String xlinkNamespace = "http://www.w3.org/1999/xlink";
protected static final String ffdecNamespace = "https://www.free-decompiler.com/flash";
protected Document _svg;
@@ -97,6 +99,7 @@ public class SVGExporter {
_svg = impl.createDocument(sNamespace, "svg", svgDocType);
Element svgRoot = _svg.getDocumentElement();
svgRoot.setAttribute("xmlns:xlink", xlinkNamespace);
svgRoot.setAttribute("xmlns:ffdec", ffdecNamespace);
if (bounds != null) {
if (Configuration.svgRetainBounds.get()) {
svgRoot.setAttribute("width", (bounds.xMax / SWF.unitDivisor) + "px");
@@ -416,10 +419,10 @@ public class SVGExporter {
image.setAttribute("id", instanceName);
}
if (characterId != null) {
image.setAttribute("data-characterId", characterId);
image.setAttribute("ffdec:characterId", characterId);
}
if (characterName != null) {
image.setAttribute("data-characterName", characterName);
if (characterName != null && !characterName.isEmpty()) {
image.setAttribute("ffdec:characterName", characterName);
}
setBlendMode(image, blendMode);
handleFilters(image, filters);
@@ -469,10 +472,10 @@ public class SVGExporter {
image.setAttribute("id", instanceName);
}
if (characterId != null) {
image.setAttribute("data-characterId", characterId);
image.setAttribute("ffdec:characterId", characterId);
}
if (characterName != null) {
image.setAttribute("data-characterName", characterName);
if (characterName != null && !characterName.isEmpty()) {
image.setAttribute("ffdec:characterName", characterName);
}
setBlendMode(image, blendMode);
@@ -158,6 +158,7 @@ public class SVGShapeExporter extends DefaultSVGShapeExporter {
return;
}
path.setAttribute("fill", "#ff0000");
path.setAttribute("ffdec:fill-bitmapId", "" + bitmapId);
}
@Override
@@ -229,7 +230,7 @@ public class SVGShapeExporter extends DefaultSVGShapeExporter {
String patternId = getPattern(bitmapId, matrix, colorTransform);
if (patternId != null) {
path.setAttribute("stroke", "url(#" + patternId + ")");
return;
path.setAttribute("ffdec:stroke-bitmapId", "" + bitmapId);
}
}
@@ -27,4 +27,54 @@ public class FOCALGRADIENT extends GRADIENT implements Serializable {
@SWFType(BasicType.FIXED8)
public float focalPoint;
@Override
public boolean isCompatibleGradient(GRADIENT otherGradient) {
if (interpolationMode != otherGradient.interpolationMode) {
return false;
}
if (spreadMode != otherGradient.spreadMode) {
return false;
}
if (gradientRecords.length != otherGradient.gradientRecords.length) {
return false;
}
return true;
}
@Override
public MORPHGRADIENT toMorphGradient() {
MORPHFOCALGRADIENT morphGradient = new MORPHFOCALGRADIENT();
morphGradient.interPolationMode = interpolationMode;
morphGradient.spreadMode = spreadMode;
morphGradient.gradientRecords = new MORPHGRADRECORD[gradientRecords.length];
for (int i = 0; i < gradientRecords.length; i++) {
morphGradient.gradientRecords[i] = gradientRecords[i].toMorphGradRecord();
}
morphGradient.startFocalPoint = focalPoint;
morphGradient.startFocalPoint = focalPoint;
return morphGradient;
}
@Override
public MORPHGRADIENT toMorphGradient(GRADIENT endGradient) {
if (!isCompatibleGradient(endGradient)) {
return null;
}
MORPHFOCALGRADIENT morphGradient = new MORPHFOCALGRADIENT();
morphGradient.interPolationMode = interpolationMode;
morphGradient.spreadMode = spreadMode;
morphGradient.gradientRecords = new MORPHGRADRECORD[gradientRecords.length];
for (int i = 0; i < gradientRecords.length; i++) {
morphGradient.gradientRecords[i] = gradientRecords[i].toMorphGradRecord();
}
morphGradient.startFocalPoint = focalPoint;
if (endGradient instanceof FOCALGRADIENT) {
morphGradient.endFocalPoint = ((FOCALGRADIENT)endGradient).focalPoint;
} else {
morphGradient.endFocalPoint = 0;
}
return morphGradient;
}
}
@@ -63,7 +63,7 @@ public class GRADIENT implements Serializable {
@SWFArray(value = "record")
public GRADRECORD[] gradientRecords = new GRADRECORD[0];
public boolean isCompatibleGradient(GRADIENT otherGradient) {
public boolean isCompatibleGradient(GRADIENT otherGradient) {
if (interpolationMode != otherGradient.interpolationMode) {
return false;
}
@@ -91,13 +91,22 @@ public class GRADIENT implements Serializable {
if (!isCompatibleGradient(endGradient)) {
return null;
}
MORPHGRADIENT morphGradient = new MORPHGRADIENT();
MORPHGRADIENT morphGradient;
if (endGradient instanceof FOCALGRADIENT) {
morphGradient = new MORPHFOCALGRADIENT();
} else {
morphGradient = new MORPHGRADIENT();
}
morphGradient.interPolationMode = interpolationMode;
morphGradient.spreadMode = spreadMode;
morphGradient.gradientRecords = new MORPHGRADRECORD[gradientRecords.length];
for (int i = 0; i < gradientRecords.length; i++) {
morphGradient.gradientRecords[i] = gradientRecords[i].toMorphGradRecord();
}
if (endGradient instanceof FOCALGRADIENT) {
((MORPHFOCALGRADIENT)morphGradient).startFocalPoint = 0;
((MORPHFOCALGRADIENT)morphGradient).endFocalPoint = ((FOCALGRADIENT)endGradient).focalPoint;
}
return morphGradient;
}
}
@@ -65,22 +65,22 @@ public class MORPHFILLSTYLE implements NeedsCharacters, Serializable {
@Conditional(value = "fillStyleType", options = {SOLID})
public RGBA endColor;
@Conditional(value = "fillStyleType", options = {LINEAR_GRADIENT, RADIAL_GRADIENT})
@Conditional(value = "fillStyleType", options = {LINEAR_GRADIENT, RADIAL_GRADIENT, FOCAL_RADIAL_GRADIENT})
public MATRIX startGradientMatrix;
@Conditional(value = "fillStyleType", options = {LINEAR_GRADIENT, RADIAL_GRADIENT})
@Conditional(value = "fillStyleType", options = {LINEAR_GRADIENT, RADIAL_GRADIENT, FOCAL_RADIAL_GRADIENT})
public MATRIX endGradientMatrix;
@Conditional(value = "fillStyleType", options = {LINEAR_GRADIENT, RADIAL_GRADIENT})
@Conditional(value = "fillStyleType", options = {LINEAR_GRADIENT, RADIAL_GRADIENT, FOCAL_RADIAL_GRADIENT})
public MORPHGRADIENT gradient;
@Conditional(value = "fillStyleType", options = {CLIPPED_BITMAP, NON_SMOOTHED_REPEATING_BITMAP, NON_SMOOTHED_CLIPPED_BITMAP})
@Conditional(value = "fillStyleType", options = {REPEATING_BITMAP, CLIPPED_BITMAP, NON_SMOOTHED_REPEATING_BITMAP, NON_SMOOTHED_CLIPPED_BITMAP})
public int bitmapId;
@Conditional(value = "fillStyleType", options = {CLIPPED_BITMAP, NON_SMOOTHED_REPEATING_BITMAP, NON_SMOOTHED_CLIPPED_BITMAP})
@Conditional(value = "fillStyleType", options = {REPEATING_BITMAP, CLIPPED_BITMAP, NON_SMOOTHED_REPEATING_BITMAP, NON_SMOOTHED_CLIPPED_BITMAP})
public MATRIX startBitmapMatrix;
@Conditional(value = "fillStyleType", options = {CLIPPED_BITMAP, NON_SMOOTHED_REPEATING_BITMAP, NON_SMOOTHED_CLIPPED_BITMAP})
@Conditional(value = "fillStyleType", options = {REPEATING_BITMAP, CLIPPED_BITMAP, NON_SMOOTHED_REPEATING_BITMAP, NON_SMOOTHED_CLIPPED_BITMAP})
public MATRIX endBitmapMatrix;
@Override