From 29ead369bfbff0d42a92b918e83affaceb8d06fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Tue, 3 Mar 2026 22:18:37 +0100 Subject: [PATCH] SVG export - Gradient glow filter SVG filters refactoring --- CHANGELOG.md | 2 +- .../flash/types/filters/BEVELFILTER.java | 12 +- .../flash/types/filters/BLURFILTER.java | 5 +- .../flash/types/filters/BlendComposite.java | 1 + .../types/filters/COLORMATRIXFILTER.java | 1 - .../types/filters/CONVOLUTIONFILTER.java | 3 +- .../flash/types/filters/DROPSHADOWFILTER.java | 5 +- .../flash/types/filters/FILTER.java | 516 --------------- .../flash/types/filters/GLOWFILTER.java | 99 +-- .../types/filters/GRADIENTBEVELFILTER.java | 8 +- .../types/filters/GRADIENTGLOWFILTER.java | 13 +- .../flash/types/filters/SvgFiltering.java | 615 ++++++++++++++++++ .../src/com/jpexs/helpers/GradientUtil.java | 42 +- .../ffdec_lib/testdata/graphics/graphics.swf | Bin 1433377 -> 1433341 bytes .../graphics/graphics/DOMDocument.xml | 22 +- .../graphics/graphics/META-INF/metadata.xml | 12 +- .../graphics/graphics/bin/SymDepend.cache | Bin 490 -> 490 bytes 17 files changed, 689 insertions(+), 667 deletions(-) create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/SvgFiltering.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 2abde7ef6..d0b520f4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. - AS3 Direct editation - Error when accessing inaccessible namespace - AS3 ambiguous namespace detection (back again) - [#2648] Dockerfile -- SVG export - Gradient bevel filter +- SVG export - Gradient bevel filter, Gradient glow filter ### Fixed - [#2643] APNG export - images containing multiple IDAT chunks diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/BEVELFILTER.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/BEVELFILTER.java index 982562928..93831231d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/BEVELFILTER.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/BEVELFILTER.java @@ -129,11 +129,13 @@ public class BEVELFILTER extends FILTER { @Override public String toSvg(Document document, Element filtersElement, SVGExporter exporter, String in) { - RGBA shadowColorTransparent = new RGBA(shadowColor); - shadowColorTransparent.alpha = 0; - RGBA highlightColorTransparent = new RGBA(highlightColor); - highlightColorTransparent.alpha = 0; - return bevelSvg(distance, angle, new RGBA[]{shadowColor, shadowColorTransparent, highlightColorTransparent, highlightColor}, new int[]{0, 127, 128, 255}, knockout, onTop, innerShadow, blurX, blurY, strength, passes, document, filtersElement, exporter, in); + int type = Filtering.INNER; + if (onTop && !innerShadow) { + type = Filtering.FULL; + } else if (!innerShadow) { + type = Filtering.OUTER; + } + return SvgFiltering.bevel(distance, angle, highlightColor, shadowColor, knockout, compositeSource, type, blurX, blurY, strength, passes, document, filtersElement, exporter, in); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/BLURFILTER.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/BLURFILTER.java index 9283a3c7a..b453f4e93 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/BLURFILTER.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/BLURFILTER.java @@ -80,7 +80,7 @@ public class BLURFILTER extends FILTER { @Override public String toSvg(Document document, Element filtersElement, SVGExporter exporter, String in) { - return blurSvg(blurX, blurY, passes, document, filtersElement, exporter, in); + return SvgFiltering.blur(blurX, blurY, passes, document, filtersElement, exporter, in); } @Override @@ -116,6 +116,5 @@ public class BLURFILTER extends FILTER { } return this.reserved == other.reserved; } - - + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/BlendComposite.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/BlendComposite.java index e27ed72f2..ea6123e45 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/BlendComposite.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/BlendComposite.java @@ -172,6 +172,7 @@ public final class BlendComposite implements Composite { /** * Gets alpha. + * * @return Alpha */ public float getAlpha() { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/COLORMATRIXFILTER.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/COLORMATRIXFILTER.java index 4485d5c2a..d12c28544 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/COLORMATRIXFILTER.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/COLORMATRIXFILTER.java @@ -119,5 +119,4 @@ public class COLORMATRIXFILTER extends FILTER { return Arrays.equals(this.matrix, other.matrix); } - } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/CONVOLUTIONFILTER.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/CONVOLUTIONFILTER.java index 3b69c6f73..231fdef57 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/CONVOLUTIONFILTER.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/CONVOLUTIONFILTER.java @@ -194,6 +194,5 @@ public class CONVOLUTIONFILTER extends FILTER { } return Objects.equals(this.defaultColor, other.defaultColor); } - - + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/DROPSHADOWFILTER.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/DROPSHADOWFILTER.java index 994f3a2f1..34c51d64d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/DROPSHADOWFILTER.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/DROPSHADOWFILTER.java @@ -113,7 +113,7 @@ public class DROPSHADOWFILTER extends FILTER { @Override public String toSvg(Document document, Element filtersElement, SVGExporter exporter, String in) { - return dropShadowSvg(distance, angle, dropShadowColor, innerShadow, knockout, compositeSource, blurX, blurY, strength, passes, document, filtersElement, exporter, in); + return SvgFiltering.dropShadow(distance, angle, dropShadowColor, innerShadow, knockout, compositeSource, blurX, blurY, strength, passes, document, filtersElement, exporter, in); } @Override @@ -173,6 +173,5 @@ public class DROPSHADOWFILTER extends FILTER { } return Objects.equals(this.dropShadowColor, other.dropShadowColor); } - - + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/FILTER.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/FILTER.java index e2b64b052..742420c06 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/FILTER.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/FILTER.java @@ -16,20 +16,13 @@ */ package com.jpexs.decompiler.flash.types.filters; -import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; import com.jpexs.decompiler.flash.types.BasicType; -import com.jpexs.decompiler.flash.types.RGBA; import com.jpexs.decompiler.flash.types.annotations.Internal; import com.jpexs.decompiler.flash.types.annotations.SWFType; import com.jpexs.helpers.ConcreteClasses; -import com.jpexs.helpers.GradientUtil; import com.jpexs.helpers.SerializableImage; -import java.awt.Color; import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -101,293 +94,6 @@ public abstract class FILTER implements Serializable { */ public abstract String toSvg(Document document, Element filtersElement, SVGExporter exporter, String in); - /** - * Converts drop shadow to SVG. - * - * @param distance Distance - * @param angle Angle - * @param dropShadowColor Drop shadow color - * @param innerShadow Inner shadow - * @param knockout Knockout - * @param compositeSource Composite source - * @param blurX Blur X - * @param blurY Blur Y - * @param strength Strength - * @param iterations Iterations - * @param document Document - * @param filtersElement Filters element - * @param exporter SVG exporter - * @param in Input - * @return SVG id of the drop shadow - */ - protected String dropShadowSvg( - double distance, - double angle, - RGBA dropShadowColor, - boolean innerShadow, - boolean knockout, - boolean compositeSource, - double blurX, - double blurY, - double strength, - int iterations, - Document document, - Element filtersElement, - SVGExporter exporter, - String in - ) { - return dropShadowSvg( - distance, - angle, - new RGBA[]{dropShadowColor}, - new int[0], - innerShadow, - knockout, - compositeSource, - blurX, - blurY, - strength, - iterations, - document, - filtersElement, - exporter, - in - ); - } - - /** - * Converts drop shadow to SVG. - * - * @param distance Distance - * @param angle Angle - * @param dropShadowColor Drop shadow color - * @param innerShadow Inner shadow - * @param knockout Knockout - * @param compositeSource Composite source - * @param blurX Blur X - * @param blurY Blur Y - * @param strength Strength - * @param iterations Iterations - * @param document Document - * @param filtersElement Filters element - * @param exporter SVG exporter - * @param in Input - * @return SVG id of the drop shadow - */ - protected String dropShadowSvg( - double distance, - double angle, - RGBA[] gradientColors, - int[] gradientRatio, - boolean innerShadow, - boolean knockout, - boolean compositeSource, - double blurX, - double blurY, - double strength, - int iterations, - Document document, - Element filtersElement, - SVGExporter exporter, - String in - ) { - double dx = distance * Math.cos(angle); - double dy = distance * Math.sin(angle); - - RGBA dropShadowColor = gradientColors.length == 1 ? gradientColors[0] : new RGBA(0, 0, 0, 255); - - if (innerShadow) { - - Element feFlood = document.createElement("feFlood"); - feFlood.setAttribute("flood-color", dropShadowColor.toHexRGB()); - feFlood.setAttribute("flood-opacity", "" + dropShadowColor.getAlphaFloat()); - filtersElement.appendChild(feFlood); - String feFloodResult = exporter.getUniqueId("filterResult"); - feFlood.setAttribute("result", feFloodResult); - - Element feOffset = document.createElement("feOffset"); - feOffset.setAttribute("dx", "" + dx); - feOffset.setAttribute("dy", "" + dy); - feOffset.setAttribute("in", in); - String feOffsetResult = exporter.getUniqueId("filterResult"); - feOffset.setAttribute("result", feOffsetResult); - filtersElement.appendChild(feOffset); - - Element feComposite1 = document.createElement("feComposite"); - feComposite1.setAttribute("in", feFloodResult); - feComposite1.setAttribute("in2", feOffsetResult); - feComposite1.setAttribute("operator", "out"); - String feComposite1Result = exporter.getUniqueId("filterResult"); - feComposite1.setAttribute("result", feComposite1Result); - filtersElement.appendChild(feComposite1); - - String blurResult = blurSvg(blurX, blurY, iterations, document, filtersElement, exporter, feComposite1Result); - - Element feComposite2 = document.createElement("feComposite"); - feComposite2.setAttribute("in", blurResult); - feComposite2.setAttribute("in2", in); - feComposite2.setAttribute("operator", "in"); - - String result = exporter.getUniqueId("filterResult"); - feComposite2.setAttribute("result", result); - filtersElement.appendChild(feComposite2); - - if (Double.compare(strength, 1.0) != 0) { - Element feColorMatrix2 = document.createElement("feColorMatrix"); - feColorMatrix2.setAttribute("type", "matrix"); - feColorMatrix2.setAttribute("in", result); - feColorMatrix2.setAttribute("values", - "1 0 0 0 0," - + "0 1 0 0 0," - + "0 0 1 0 0," - + "0 0 0 " + strength + " 0" - ); - result = exporter.getUniqueId("filterResult"); - feColorMatrix2.setAttribute("result", result); - filtersElement.appendChild(feColorMatrix2); - } - - if (knockout || !compositeSource) { - return result; - } - Element feComposite3 = document.createElement("feComposite"); - feComposite3.setAttribute("in", result); - feComposite3.setAttribute("in2", in); - feComposite3.setAttribute("operator", "over"); - - result = exporter.getUniqueId("filterResult"); - feComposite3.setAttribute("result", result); - filtersElement.appendChild(feComposite3); - return result; - } else { - Element feOffset = document.createElement("feOffset"); - feOffset.setAttribute("dx", "" + dx); - feOffset.setAttribute("dy", "" + dy); - feOffset.setAttribute("in", in); - String feOffsetResult = exporter.getUniqueId("filterResult"); - feOffset.setAttribute("result", feOffsetResult); - filtersElement.appendChild(feOffset); - - Element feColorMatrix = document.createElement("feColorMatrix"); - feColorMatrix.setAttribute("type", "matrix"); - feColorMatrix.setAttribute("in", feOffsetResult); - feColorMatrix.setAttribute("values", - "0 0 0 0 " + (dropShadowColor.red / 255f) + "," - + "0 0 0 0 " + (dropShadowColor.green / 255f) + "," - + "0 0 0 0 " + (dropShadowColor.blue / 255f) + "," - + "0 0 0 1 0" - ); - String feColorMatrixResult = exporter.getUniqueId("filterResult"); - feColorMatrix.setAttribute("result", feColorMatrixResult); - filtersElement.appendChild(feColorMatrix); - - String result = blurSvg(blurX, blurY, iterations, document, filtersElement, exporter, feColorMatrixResult); - - if (Double.compare(strength, 1.0) != 0) { - Element feColorMatrix2 = document.createElement("feColorMatrix"); - feColorMatrix2.setAttribute("type", "matrix"); - feColorMatrix2.setAttribute("in", result); - feColorMatrix2.setAttribute("values", - "1 0 0 0 0," - + "0 1 0 0 0," - + "0 0 1 0 0," - + "0 0 0 " + strength + " 0" - ); - result = exporter.getUniqueId("filterResult"); - feColorMatrix2.setAttribute("result", result); - filtersElement.appendChild(feColorMatrix2); - } - - if (!knockout && !compositeSource) { - return result; - } - - Element feComposite = document.createElement("feComposite"); - if (knockout) { - feComposite.setAttribute("in", result); - feComposite.setAttribute("in2", in); - feComposite.setAttribute("operator", "out"); - } else { - feComposite.setAttribute("in", in); - feComposite.setAttribute("in2", result); - feComposite.setAttribute("operator", "over"); - } - - result = exporter.getUniqueId("filterResult"); - feComposite.setAttribute("result", result); - filtersElement.appendChild(feComposite); - return result; - } - } - - /** - * Converts blur to SVG. - * - * @param blurX Blur X - * @param blurY Blur Y - * @param iterations Iterations - * @param document Document - * @param filtersElement Filters element - * @param exporter SVG exporter - * @param in Input - * @return SVG id of the blur - */ - protected String blurSvg(double blurX, double blurY, int iterations, Document document, Element filtersElement, SVGExporter exporter, String in) { - if (iterations == 0) { - return in; - } - if (Double.compare(blurX, 0.0) == 0 && Double.compare(blurY, 0.0) == 0) { - return in; - } - Element element; - if (Configuration.svgExportGaussianBlur.get()) { - double blurXScaled = blurX * exporter.getZoom(); - double blurYScaled = blurY * exporter.getZoom(); - - double deviationX = Math.sqrt((blurXScaled * blurXScaled - 1) / 12); - double deviationY = Math.sqrt((blurYScaled * blurYScaled - 1) / 12); - - element = document.createElement("feGaussianBlur"); - - element.setAttribute("stdDeviation", "" + deviationX + " " + deviationY); - } else { - element = document.createElement("feConvolveMatrix"); - - List parts = new ArrayList<>(); - - int orderX = (int) Math.ceil(blurX * exporter.getZoom()); - int orderY = (int) Math.ceil(blurY * exporter.getZoom()); - - if (orderX % 2 == 0) { - orderX++; - } - - if (orderY % 2 == 0) { - orderY++; - } - - double divisor = orderX * orderY; - element.setAttribute("order", "" + orderX + " " + orderY); - - for (int i = 0; i < divisor; i++) { - parts.add("1"); - } - - element.setAttribute("divisor", "" + divisor); - - element.setAttribute("kernelMatrix", String.join(" ", parts)); - element.setAttribute("kernelUnitLength", "1"); - } - element.setAttribute("in", in); - - String result = exporter.getUniqueId("filterResult"); - element.setAttribute("result", result); - - filtersElement.appendChild(element); - - return blurSvg(blurX, blurY, iterations - 1, document, filtersElement, exporter, result); - } - /** * Converts gradient ratios to Java format float ratios. * @@ -431,226 +137,4 @@ public abstract class FILTER implements Serializable { return output; } - - protected String bevelSvg(double distance, double angle, RGBA[] gradientColors, int[] gradientRatio, boolean knockout, boolean onTop, boolean innerShadow, double blurX, double blurY, double strength, int passes, Document document, Element filtersElement, SVGExporter exporter, String in) { - RGBA highlightColor = new RGBA(255, 0, 0, 255); - RGBA shadowColor = new RGBA(0, 0, 255, 255); - - int type = Filtering.INNER; - if (onTop && !innerShadow) { - type = Filtering.FULL; - } else if (!innerShadow) { - type = Filtering.OUTER; - } - - String shadowInner = null; - String hilightInner = null; - if (type != Filtering.OUTER) { - String hilight = dropShadowSvg(distance, angle, highlightColor, true, true, true, 0, 0, strength, passes, document, filtersElement, exporter, in); - String shadow = dropShadowSvg(distance, angle + Math.PI, shadowColor, true, true, true, 0, 0, strength, passes, document, filtersElement, exporter, in); - - Element feComposite1 = document.createElement("feComposite"); - feComposite1.setAttribute("in", hilight); - feComposite1.setAttribute("in2", shadow); - feComposite1.setAttribute("operator", "out"); - hilightInner = exporter.getUniqueId("filterResult"); - feComposite1.setAttribute("result", hilightInner); - filtersElement.appendChild(feComposite1); - - Element feComposite2 = document.createElement("feComposite"); - feComposite2.setAttribute("in", shadow); - feComposite2.setAttribute("in2", hilight); - feComposite2.setAttribute("operator", "out"); - shadowInner = exporter.getUniqueId("filterResult"); - feComposite2.setAttribute("result", shadowInner); - filtersElement.appendChild(feComposite2); - } - - String shadowOuter = null; - String hilightOuter = null; - - if (type != Filtering.INNER) { - String hilight = dropShadowSvg(distance, angle + Math.PI, highlightColor, false, true, true, 0, 0, strength, passes, document, filtersElement, exporter, in); - String shadow = dropShadowSvg(distance, angle, shadowColor, false, true, true, 0, 0, strength, passes, document, filtersElement, exporter, in); - - Element feComposite1 = document.createElement("feComposite"); - feComposite1.setAttribute("in", hilight); - feComposite1.setAttribute("in2", shadow); - feComposite1.setAttribute("operator", "out"); - hilightOuter = exporter.getUniqueId("filterResult"); - feComposite1.setAttribute("result", hilightOuter); - filtersElement.appendChild(feComposite1); - - Element feComposite2 = document.createElement("feComposite"); - feComposite2.setAttribute("in", shadow); - feComposite2.setAttribute("in2", hilight); - feComposite2.setAttribute("operator", "out"); - shadowOuter = exporter.getUniqueId("filterResult"); - feComposite2.setAttribute("result", shadowOuter); - filtersElement.appendChild(feComposite2); - } - - String hilight = null; - String shadow = null; - - switch (type) { - case Filtering.OUTER: - hilight = hilightOuter; - shadow = shadowOuter; - break; - case Filtering.INNER: - hilight = hilightInner; - shadow = shadowInner; - break; - case Filtering.FULL: - Element feComposite1 = document.createElement("feComposite"); - feComposite1.setAttribute("in", hilightInner); - feComposite1.setAttribute("in2", hilightOuter); - feComposite1.setAttribute("operator", "over"); - hilight = exporter.getUniqueId("filterResult"); - feComposite1.setAttribute("result", hilight); - filtersElement.appendChild(feComposite1); - - Element feComposite2 = document.createElement("feComposite"); - feComposite2.setAttribute("in", shadowInner); - feComposite2.setAttribute("in2", shadowOuter); - feComposite2.setAttribute("operator", "over"); - shadow = exporter.getUniqueId("filterResult"); - feComposite2.setAttribute("result", shadow); - filtersElement.appendChild(feComposite2); - break; - } - - Element feFlood = document.createElement("feFlood"); - feFlood.setAttribute("flood-color", "black"); - feFlood.setAttribute("flood-opacity", "1"); - String black = exporter.getUniqueId("filterResult"); - feFlood.setAttribute("result", black); - filtersElement.appendChild(feFlood); - - String result; - - Element feComposite4 = document.createElement("feComposite"); - feComposite4.setAttribute("in", shadow); - feComposite4.setAttribute("in2", black); - feComposite4.setAttribute("operator", "over"); - result = exporter.getUniqueId("filterResult"); - feComposite4.setAttribute("result", result); - filtersElement.appendChild(feComposite4); - - Element feComposite5 = document.createElement("feComposite"); - feComposite5.setAttribute("in", hilight); - feComposite5.setAttribute("in2", result); - feComposite5.setAttribute("operator", "over"); - result = exporter.getUniqueId("filterResult"); - feComposite5.setAttribute("result", result); - filtersElement.appendChild(feComposite5); - - result = blurSvg(blurX, blurY, passes, document, filtersElement, exporter, result); - - Element feColorMatrix = document.createElement("feColorMatrix"); - feColorMatrix.setAttribute("type", "matrix"); - feColorMatrix.setAttribute("in", result); - double halfStrength = strength / 2; - String matrixRow = "" + halfStrength + " 0 " + (-halfStrength) + " 0 0.5"; - feColorMatrix.setAttribute("values", - matrixRow + " " - + matrixRow + " " - + matrixRow + " " - + matrixRow - ); - result = exporter.getUniqueId("filterResult"); - feColorMatrix.setAttribute("result", result); - filtersElement.appendChild(feColorMatrix); - - result = prepareFeComponentTransfer(gradientColors, gradientRatio, document, filtersElement, exporter, result); - - if (type == Filtering.INNER) { - Element feComposite6 = document.createElement("feComposite"); - feComposite6.setAttribute("in", result); - feComposite6.setAttribute("in2", in); - feComposite6.setAttribute("operator", "in"); - result = exporter.getUniqueId("filterResult"); - feComposite6.setAttribute("result", result); - filtersElement.appendChild(feComposite6); - } - if (type == Filtering.OUTER) { - Element feComposite6 = document.createElement("feComposite"); - feComposite6.setAttribute("in", result); - feComposite6.setAttribute("in2", in); - feComposite6.setAttribute("operator", "out"); - result = exporter.getUniqueId("filterResult"); - feComposite6.setAttribute("result", result); - filtersElement.appendChild(feComposite6); - } - - if (!knockout) { - Element feComposite7 = document.createElement("feComposite"); - feComposite7.setAttribute("in", result); - feComposite7.setAttribute("in2", in); - feComposite7.setAttribute("operator", "over"); - result = exporter.getUniqueId("filterResult"); - feComposite7.setAttribute("result", result); - filtersElement.appendChild(feComposite7); - } - return result; - } - - private String prepareFeComponentTransfer(RGBA[] gradientColors, int[] gradientRatio, Document document, Element filtersElement, SVGExporter exporter, String in) { - Element feComponentTransfer = document.createElement("feComponentTransfer"); - feComponentTransfer.setAttribute("in", in); - - List redValues = new ArrayList<>(); - List greenValues = new ArrayList<>(); - List blueValues = new ArrayList<>(); - List alphaValues = new ArrayList<>(); - - for (int i = 0; i < 256; i++) { - RGBA color = GradientUtil.colorAt(gradientColors, gradientRatio, i, GradientUtil.ColorInterpolation.SRGB); - redValues.add("" + (color.red / 255f)); - greenValues.add("" + (color.green / 255f)); - blueValues.add("" + (color.blue / 255f)); - alphaValues.add("" + color.getAlphaFloat()); - } - - /* - //In case we want to map 128 to center - - for (int i = 0; i < 126; i++) { //126 colors - RGBA color = GradientUtil.colorAt(gradientColors, gradientRatio, i * 127f / 125f, GradientUtil.ColorInterpolation.SRGB); - redValues.add("" + (color.red / 255f)); - greenValues.add("" + (color.green / 255f)); - blueValues.add("" + (color.blue / 255f)); - alphaValues.add("" + color.getAlphaFloat()); - } - for (int i = 128; i < 256; i++) { //1 center + 126 colors - RGBA color = GradientUtil.colorAt(gradientColors, gradientRatio, i, GradientUtil.ColorInterpolation.SRGB); - redValues.add("" + (color.red / 255f)); - greenValues.add("" + (color.green / 255f)); - blueValues.add("" + (color.blue / 255f)); - alphaValues.add("" + color.getAlphaFloat()); - } - */ - Element feFuncR = document.createElement("feFuncR"); - feFuncR.setAttribute("type", "table"); - feFuncR.setAttribute("tableValues", String.join(" ", redValues)); - Element feFuncG = document.createElement("feFuncG"); - feFuncG.setAttribute("type", "table"); - feFuncG.setAttribute("tableValues", String.join(" ", greenValues)); - Element feFuncB = document.createElement("feFuncB"); - feFuncB.setAttribute("type", "table"); - feFuncB.setAttribute("tableValues", String.join(" ", blueValues)); - Element feFuncA = document.createElement("feFuncA"); - feFuncA.setAttribute("type", "table"); - feFuncA.setAttribute("tableValues", String.join(" ", alphaValues)); - feComponentTransfer.appendChild(feFuncR); - feComponentTransfer.appendChild(feFuncG); - feComponentTransfer.appendChild(feFuncB); - feComponentTransfer.appendChild(feFuncA); - - String result = exporter.getUniqueId("filterResult"); - feComponentTransfer.setAttribute("result", result); - filtersElement.appendChild(feComponentTransfer); - return result; - } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/GLOWFILTER.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/GLOWFILTER.java index e9ca0b22b..c173df271 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/GLOWFILTER.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/GLOWFILTER.java @@ -101,101 +101,7 @@ public class GLOWFILTER extends FILTER { @Override public String toSvg(Document document, Element filtersElement, SVGExporter exporter, String in) { - /*Element element = document.createElement("feDropShadow"); - element.setAttribute("dx", "0"); - element.setAttribute("dy", "0"); - - double blur = ((blurX + blurY) / 2); - element.setAttribute("stdDeviation", "" + blur); - - element.setAttribute("flood-color", glowColor.toHexRGB()); - element.setAttribute("flood-opacity", "" + glowColor.getAlphaFloat()); - - element.setAttribute("in", in); - - String result = exporter.getUniqueId("filterResult"); - element.setAttribute("result", result); - - filtersElement.appendChild(element); - - return result;*/ - - if (innerGlow) { - Element feFlood = document.createElement("feFlood"); - feFlood.setAttribute("flood-color", glowColor.toHexRGB()); - feFlood.setAttribute("flood-opacity", "" + glowColor.getAlphaFloat()); - filtersElement.appendChild(feFlood); - String feFloodResult = exporter.getUniqueId("filterResult"); - feFlood.setAttribute("result", feFloodResult); - - Element feComposite1 = document.createElement("feComposite"); - feComposite1.setAttribute("in", feFloodResult); - feComposite1.setAttribute("in2", in); - feComposite1.setAttribute("operator", "out"); - String feComposite1Result = exporter.getUniqueId("filterResult"); - feComposite1.setAttribute("result", feComposite1Result); - filtersElement.appendChild(feComposite1); - - String blurResult = blurSvg(blurX, blurY, passes, document, filtersElement, exporter, feComposite1Result); - - Element feComposite2 = document.createElement("feComposite"); - feComposite2.setAttribute("in", blurResult); - feComposite2.setAttribute("in2", in); - feComposite2.setAttribute("operator", "in"); - - String feComposite2Result = exporter.getUniqueId("filterResult"); - feComposite2.setAttribute("result", feComposite2Result); - filtersElement.appendChild(feComposite2); - - if (knockout || !compositeSource) { - return feComposite2Result; - } - Element feComposite3 = document.createElement("feComposite"); - feComposite3.setAttribute("in", feComposite2Result); - feComposite3.setAttribute("in2", in); - feComposite3.setAttribute("operator", "over"); - - String feComposite3Result = exporter.getUniqueId("filterResult"); - feComposite3.setAttribute("result", feComposite3Result); - filtersElement.appendChild(feComposite3); - return feComposite3Result; - } else { - - Element feColorMatrix = document.createElement("feColorMatrix"); - feColorMatrix.setAttribute("type", "matrix"); - feColorMatrix.setAttribute("in", in); - feColorMatrix.setAttribute("values", - "0 0 0 0 " + (glowColor.red / 255f) + "," - + "0 0 0 0 " + (glowColor.green / 255f) + "," - + "0 0 0 0 " + (glowColor.blue / 255f) + "," - + "0 0 0 1 0" - ); - String feColorMatrixResult = exporter.getUniqueId("filterResult"); - feColorMatrix.setAttribute("result", feColorMatrixResult); - filtersElement.appendChild(feColorMatrix); - - String blurResult = blurSvg(blurX, blurY, passes, document, filtersElement, exporter, feColorMatrixResult); - - if (!knockout && !compositeSource) { - return blurResult; - } - - Element feComposite = document.createElement("feComposite"); - if (knockout) { - feComposite.setAttribute("in", blurResult); - feComposite.setAttribute("in2", in); - feComposite.setAttribute("operator", "out"); - } else { - feComposite.setAttribute("in", in); - feComposite.setAttribute("in2", blurResult); - feComposite.setAttribute("operator", "over"); - } - - String feCompositeResult = exporter.getUniqueId("filterResult"); - feComposite.setAttribute("result", feCompositeResult); - filtersElement.appendChild(feComposite); - return feCompositeResult; - } + return SvgFiltering.glow(glowColor, knockout, innerGlow, compositeSource, blurX, blurY, strength, passes, document, filtersElement, exporter, in); } @Override @@ -247,6 +153,5 @@ public class GLOWFILTER extends FILTER { } return Objects.equals(this.glowColor, other.glowColor); } - - + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/GRADIENTBEVELFILTER.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/GRADIENTBEVELFILTER.java index c63afe857..c445b8e9c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/GRADIENTBEVELFILTER.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/GRADIENTBEVELFILTER.java @@ -143,7 +143,13 @@ public class GRADIENTBEVELFILTER extends FILTER { @Override public String toSvg(Document document, Element filtersElement, SVGExporter exporter, String in) { - return bevelSvg(distance, angle, gradientColors, gradientRatio, knockout, onTop, innerShadow, blurX, blurY, strength, passes, document, filtersElement, exporter, in); + int type = Filtering.INNER; + if (onTop && !innerShadow) { + type = Filtering.FULL; + } else if (!innerShadow) { + type = Filtering.OUTER; + } + return SvgFiltering.gradientBevel(distance, angle, gradientColors, gradientRatio, knockout, compositeSource, type, blurX, blurY, strength, passes, document, filtersElement, exporter, in); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/GRADIENTGLOWFILTER.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/GRADIENTGLOWFILTER.java index 75e274d94..686f8ad6c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/GRADIENTGLOWFILTER.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/GRADIENTGLOWFILTER.java @@ -122,7 +122,7 @@ public class GRADIENTGLOWFILTER extends FILTER { colorsArr[i] = gradientColors[i].toColor(); } float[] ratiosArr = convertRatiosToJavaGradient(gradientRatio); - + int type = Filtering.INNER; if (onTop && !innerShadow) { type = Filtering.FULL; @@ -145,7 +145,13 @@ public class GRADIENTGLOWFILTER extends FILTER { @Override public String toSvg(Document document, Element filtersElement, SVGExporter exporter, String in) { - return null; //NOT SUPPORTED + int type = Filtering.INNER; + if (onTop && !innerShadow) { + type = Filtering.FULL; + } else if (!innerShadow) { + type = Filtering.OUTER; + } + return SvgFiltering.gradientGlow(distance, angle, gradientColors, gradientRatio, knockout, type, compositeSource, innerShadow, blurX, blurY, strength, passes, document, filtersElement, exporter, in); } @Override @@ -213,6 +219,5 @@ public class GRADIENTGLOWFILTER extends FILTER { } return Arrays.equals(this.gradientRatio, other.gradientRatio); } - - + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/SvgFiltering.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/SvgFiltering.java new file mode 100644 index 000000000..9765d3ae9 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/SvgFiltering.java @@ -0,0 +1,615 @@ +/* + * Copyright (C) 2010-2026 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.types.filters; + +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; +import com.jpexs.decompiler.flash.types.RGBA; +import com.jpexs.helpers.GradientUtil; +import java.util.ArrayList; +import java.util.List; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * SVG filtering + * + * @author JPEXS + */ +public class SvgFiltering { + + /** + * Blur filter + * + * @param blurX Blur X + * @param blurY Blur Y + * @param iterations Iterations + * @param document Document + * @param filtersElement Filters element + * @param exporter SVG exporter + * @param in Input + * @return SVG id of the blur + */ + public static String blur(double blurX, double blurY, int iterations, Document document, Element filtersElement, SVGExporter exporter, String in) { + if (iterations == 0) { + return in; + } + if (Double.compare(blurX, 0.0) == 0 && Double.compare(blurY, 0.0) == 0) { + return in; + } + Element element; + if (Configuration.svgExportGaussianBlur.get()) { + double blurXScaled = blurX * exporter.getZoom(); + double blurYScaled = blurY * exporter.getZoom(); + + double deviationX = Math.sqrt((blurXScaled * blurXScaled - 1) / 12); + double deviationY = Math.sqrt((blurYScaled * blurYScaled - 1) / 12); + + element = document.createElement("feGaussianBlur"); + + element.setAttribute("stdDeviation", "" + deviationX + " " + deviationY); + } else { + element = document.createElement("feConvolveMatrix"); + + List parts = new ArrayList<>(); + + int orderX = (int) Math.ceil(blurX * exporter.getZoom()); + int orderY = (int) Math.ceil(blurY * exporter.getZoom()); + + if (orderX % 2 == 0) { + orderX++; + } + + if (orderY % 2 == 0) { + orderY++; + } + + double divisor = orderX * orderY; + element.setAttribute("order", "" + orderX + " " + orderY); + + for (int i = 0; i < divisor; i++) { + parts.add("1"); + } + + element.setAttribute("divisor", "" + divisor); + + element.setAttribute("kernelMatrix", String.join(" ", parts)); + element.setAttribute("kernelUnitLength", "1"); + } + element.setAttribute("in", in); + + String result = exporter.getUniqueId("filterResult"); + element.setAttribute("result", result); + + filtersElement.appendChild(element); + + return blur(blurX, blurY, iterations - 1, document, filtersElement, exporter, result); + } + + /** + * Compose result according to INNER/OUTER/FULL + * + * @param src Source + * @param result Result + * @param type Type + * @param knockout Knockout + * @param compositeSource Composite source + * @param document Document + * @param filtersElement Filters element + * @param exporter Exporter + * @return Result + */ + private static String compose( + String src, + String result, + int type, + boolean knockout, + boolean compositeSource, + Document document, + Element filtersElement, + SVGExporter exporter + ) { + String in = ""; + String in2 = ""; + String operator = ""; + String dst = result; + + if (type == Filtering.FULL && !knockout && compositeSource) { + operator = "over"; + in = dst; + in2 = src; + //dstover + } else if (type == Filtering.INNER) { + if (knockout || !compositeSource) { + operator = "in"; + //dstin + } else { + operator = "atop"; + //dstatop + } + in = dst; + in2 = src; + } else if (type == Filtering.OUTER) { + if (knockout) { + in = dst; + in2 = src; + operator = "out"; + //dstout + } else if (compositeSource) { + in = src; + in2 = dst; + operator = "over"; + //srcover + } + } else { + return result; + } + + Element feComposite = document.createElement("feComposite"); + feComposite.setAttribute("in", in); + feComposite.setAttribute("in2", in2); + feComposite.setAttribute("operator", operator); + result = exporter.getUniqueId("filterResult"); + feComposite.setAttribute("result", result); + filtersElement.appendChild(feComposite); + return result; + } + + /** + * Glow filter + * + * @param glowColor Glow color + * @param knockout Knockout + * @param innerGlow Inner glow + * @param compositeSource Composite source + * @param blurX Blur X + * @param blurY Blur Y + * @param strength Strength + * @param iterations Iterations + * @param document Document + * @param filtersElement Filters element + * @param exporter Exporter + * @param in In + * @return Result + */ + public static String glow(RGBA glowColor, boolean knockout, boolean innerGlow, boolean compositeSource, double blurX, double blurY, double strength, int iterations, Document document, Element filtersElement, SVGExporter exporter, String in) { + return dropShadow(0, 45, glowColor, innerGlow, knockout, true, blurX, blurY, strength, iterations, document, filtersElement, exporter, in); + } + + /** + * Gradient glow + * + * @param distance Distance + * @param angle Angle + * @param gradientColors Gradient colors + * @param gradientRatio Gradient ratio + * @param knockout Knockout + * @param type Type + * @param compositeSource Composite source + * @param innerGlow Inner glow + * @param blurX Blur X + * @param blurY Blur Y + * @param strength Strength + * @param iterations Iterations + * @param document Document + * @param filtersElement Filters element + * @param exporter Exporter + * @param in In + * @return Result + */ + public static String gradientGlow(double distance, double angle, RGBA[] gradientColors, int[] gradientRatio, boolean knockout, int type, boolean compositeSource, boolean innerGlow, double blurX, double blurY, double strength, int iterations, Document document, Element filtersElement, SVGExporter exporter, String in) { + RGBA glowColor = new RGBA(255, 0, 0, 255); + + double dx = distance * exporter.getZoom() * Math.cos(angle); + double dy = distance * exporter.getZoom() * Math.sin(angle); + + Element feFloodBlack = document.createElement("feFlood"); + feFloodBlack.setAttribute("flood-color", "black"); + feFloodBlack.setAttribute("flood-opacity", "1"); + String black = exporter.getUniqueId("filterResult"); + feFloodBlack.setAttribute("result", black); + filtersElement.appendChild(feFloodBlack); + + Element feOffset = document.createElement("feOffset"); + feOffset.setAttribute("dx", "" + dx); + feOffset.setAttribute("dy", "" + dy); + feOffset.setAttribute("in", in); + String feOffsetResult = exporter.getUniqueId("filterResult"); + feOffset.setAttribute("result", feOffsetResult); + filtersElement.appendChild(feOffset); + + String result; + + Element feColorMatrix = document.createElement("feColorMatrix"); + feColorMatrix.setAttribute("type", "matrix"); + feColorMatrix.setAttribute("in", feOffsetResult); + feColorMatrix.setAttribute("values", + "0 0 0 0 " + (glowColor.red / 255f) + "," + + "0 0 0 0 " + (glowColor.green / 255f) + "," + + "0 0 0 0 " + (glowColor.blue / 255f) + "," + + "0 0 0 " + (glowColor.alpha / 255f) + " 0" //Note: it is not last one here + ); + result = exporter.getUniqueId("filterResult"); + feColorMatrix.setAttribute("result", result); + filtersElement.appendChild(feColorMatrix); + + Element feComposite = document.createElement("feComposite"); + feComposite.setAttribute("in", result); + feComposite.setAttribute("in2", black); + feComposite.setAttribute("operator", "over"); + result = exporter.getUniqueId("filterResult"); + feComposite.setAttribute("result", result); + filtersElement.appendChild(feComposite); + + if (Double.compare(blurX, 0.0) != 0 || Double.compare(blurY, 0.0) != 0) { + result = blur(blurX, blurY, iterations, document, filtersElement, exporter, result); + } + + Element feColorMatrix2 = document.createElement("feColorMatrix"); + feColorMatrix2.setAttribute("type", "matrix"); + feColorMatrix2.setAttribute("in", result); + String matrixRow = "" + strength + " 0 0 0 0"; + feColorMatrix2.setAttribute("values", + matrixRow + " " + + matrixRow + " " + + matrixRow + " " + + matrixRow + ); + result = exporter.getUniqueId("filterResult"); + feColorMatrix2.setAttribute("result", result); + filtersElement.appendChild(feColorMatrix2); + + result = prepareFeComponentTransfer(gradientColors, gradientRatio, document, filtersElement, exporter, result); + + return compose(in, result, type, knockout, compositeSource, document, filtersElement, exporter); + } + + /** + * Bevel filter + * + * @param distance Distance + * @param angle Angle + * @param highlightColor Highlight color + * @param shadowColor Shadow color + * @param knockout Knockout + * @param compositeSource Composite source + * @param type Type + * @param blurX Blur X + * @param blurY Blur Y + * @param strength Strength + * @param iterations Iterations + * @param document Document + * @param filtersElement Filters element + * @param exporter Exporter + * @param in In + * @return Result + */ + public static String bevel(double distance, double angle, RGBA highlightColor, RGBA shadowColor, boolean knockout, boolean compositeSource, int type, double blurX, double blurY, double strength, int iterations, Document document, Element filtersElement, SVGExporter exporter, String in) { + RGBA shadowColorTransparent = new RGBA(shadowColor); + shadowColorTransparent.alpha = 0; + RGBA highlightColorTransparent = new RGBA(highlightColor); + highlightColorTransparent.alpha = 0; + + return SvgFiltering.gradientBevel(distance, angle, new RGBA[]{shadowColor, shadowColorTransparent, highlightColorTransparent, highlightColor}, new int[]{0, 127, 128, 255}, knockout, compositeSource, type, blurX, blurY, strength, iterations, document, filtersElement, exporter, in); + + } + + /** + * Gradient bevel + * + * @param distance Distance + * @param angle Angle + * @param gradientColors Gradient colors + * @param gradientRatio Gradient ratio + * @param knockout Knockout + * @param compositeSource Composite source + * @param type Type + * @param blurX Blur X + * @param blurY Blur Y + * @param strength Strength + * @param iterations Iterations + * @param document Document + * @param filtersElement Filters element + * @param exporter Exporter + * @param in In + * @return Result + */ + public static String gradientBevel(double distance, double angle, RGBA[] gradientColors, int[] gradientRatio, boolean knockout, boolean compositeSource, int type, double blurX, double blurY, double strength, int iterations, Document document, Element filtersElement, SVGExporter exporter, String in) { + RGBA highlightColor = new RGBA(255, 0, 0, 255); + RGBA shadowColor = new RGBA(0, 0, 255, 255); + + String shadowInner = null; + String hilightInner = null; + if (type != Filtering.OUTER) { + String hilight = dropShadow(distance, angle, highlightColor, true, true, true, 0, 0, strength, iterations, document, filtersElement, exporter, in); + String shadow = dropShadow(distance, angle + Math.PI, shadowColor, true, true, true, 0, 0, strength, iterations, document, filtersElement, exporter, in); + + Element feComposite1 = document.createElement("feComposite"); + feComposite1.setAttribute("in", hilight); + feComposite1.setAttribute("in2", shadow); + feComposite1.setAttribute("operator", "out"); + hilightInner = exporter.getUniqueId("filterResult"); + feComposite1.setAttribute("result", hilightInner); + filtersElement.appendChild(feComposite1); + + Element feComposite2 = document.createElement("feComposite"); + feComposite2.setAttribute("in", shadow); + feComposite2.setAttribute("in2", hilight); + feComposite2.setAttribute("operator", "out"); + shadowInner = exporter.getUniqueId("filterResult"); + feComposite2.setAttribute("result", shadowInner); + filtersElement.appendChild(feComposite2); + } + + String shadowOuter = null; + String hilightOuter = null; + + if (type != Filtering.INNER) { + String hilight = dropShadow(distance, angle + Math.PI, highlightColor, false, true, true, 0, 0, strength, iterations, document, filtersElement, exporter, in); + String shadow = dropShadow(distance, angle, shadowColor, false, true, true, 0, 0, strength, iterations, document, filtersElement, exporter, in); + + Element feComposite1 = document.createElement("feComposite"); + feComposite1.setAttribute("in", hilight); + feComposite1.setAttribute("in2", shadow); + feComposite1.setAttribute("operator", "out"); + hilightOuter = exporter.getUniqueId("filterResult"); + feComposite1.setAttribute("result", hilightOuter); + filtersElement.appendChild(feComposite1); + + Element feComposite2 = document.createElement("feComposite"); + feComposite2.setAttribute("in", shadow); + feComposite2.setAttribute("in2", hilight); + feComposite2.setAttribute("operator", "out"); + shadowOuter = exporter.getUniqueId("filterResult"); + feComposite2.setAttribute("result", shadowOuter); + filtersElement.appendChild(feComposite2); + } + + String hilight = null; + String shadow = null; + + switch (type) { + case Filtering.OUTER: + hilight = hilightOuter; + shadow = shadowOuter; + break; + case Filtering.INNER: + hilight = hilightInner; + shadow = shadowInner; + break; + case Filtering.FULL: + Element feComposite1 = document.createElement("feComposite"); + feComposite1.setAttribute("in", hilightInner); + feComposite1.setAttribute("in2", hilightOuter); + feComposite1.setAttribute("operator", "over"); + hilight = exporter.getUniqueId("filterResult"); + feComposite1.setAttribute("result", hilight); + filtersElement.appendChild(feComposite1); + + Element feComposite2 = document.createElement("feComposite"); + feComposite2.setAttribute("in", shadowInner); + feComposite2.setAttribute("in2", shadowOuter); + feComposite2.setAttribute("operator", "over"); + shadow = exporter.getUniqueId("filterResult"); + feComposite2.setAttribute("result", shadow); + filtersElement.appendChild(feComposite2); + break; + } + + Element feFlood = document.createElement("feFlood"); + feFlood.setAttribute("flood-color", "black"); + feFlood.setAttribute("flood-opacity", "1"); + String black = exporter.getUniqueId("filterResult"); + feFlood.setAttribute("result", black); + filtersElement.appendChild(feFlood); + + String result; + + Element feComposite4 = document.createElement("feComposite"); + feComposite4.setAttribute("in", shadow); + feComposite4.setAttribute("in2", black); + feComposite4.setAttribute("operator", "over"); + result = exporter.getUniqueId("filterResult"); + feComposite4.setAttribute("result", result); + filtersElement.appendChild(feComposite4); + + Element feComposite5 = document.createElement("feComposite"); + feComposite5.setAttribute("in", hilight); + feComposite5.setAttribute("in2", result); + feComposite5.setAttribute("operator", "over"); + result = exporter.getUniqueId("filterResult"); + feComposite5.setAttribute("result", result); + filtersElement.appendChild(feComposite5); + + result = blur(blurX, blurY, iterations, document, filtersElement, exporter, result); + + Element feColorMatrix = document.createElement("feColorMatrix"); + feColorMatrix.setAttribute("type", "matrix"); + feColorMatrix.setAttribute("in", result); + double halfStrength = strength / 2; + String matrixRow = "" + halfStrength + " 0 " + (-halfStrength) + " 0 0.5"; + feColorMatrix.setAttribute("values", + matrixRow + " " + + matrixRow + " " + + matrixRow + " " + + matrixRow + ); + result = exporter.getUniqueId("filterResult"); + feColorMatrix.setAttribute("result", result); + filtersElement.appendChild(feColorMatrix); + + result = prepareFeComponentTransfer(gradientColors, gradientRatio, document, filtersElement, exporter, result); + + return compose(in, result, type, knockout, compositeSource, document, filtersElement, exporter); + } + + private static String prepareFeComponentTransfer(RGBA[] gradientColors, int[] gradientRatio, Document document, Element filtersElement, SVGExporter exporter, String in) { + Element feComponentTransfer = document.createElement("feComponentTransfer"); + feComponentTransfer.setAttribute("in", in); + + List redValues = new ArrayList<>(); + List greenValues = new ArrayList<>(); + List blueValues = new ArrayList<>(); + List alphaValues = new ArrayList<>(); + + for (int i = 0; i < 256; i++) { + RGBA color = GradientUtil.colorAt(gradientColors, gradientRatio, i, GradientUtil.ColorInterpolation.SRGB); + redValues.add("" + (color.red / 255f)); + greenValues.add("" + (color.green / 255f)); + blueValues.add("" + (color.blue / 255f)); + alphaValues.add("" + color.getAlphaFloat()); + } + + /* + //In case we want to map 128 to center + + for (int i = 0; i < 126; i++) { //126 colors + RGBA color = GradientUtil.colorAt(gradientColors, gradientRatio, i * 127f / 125f, GradientUtil.ColorInterpolation.SRGB); + redValues.add("" + (color.red / 255f)); + greenValues.add("" + (color.green / 255f)); + blueValues.add("" + (color.blue / 255f)); + alphaValues.add("" + color.getAlphaFloat()); + } + for (int i = 128; i < 256; i++) { //1 center + 126 colors + RGBA color = GradientUtil.colorAt(gradientColors, gradientRatio, i, GradientUtil.ColorInterpolation.SRGB); + redValues.add("" + (color.red / 255f)); + greenValues.add("" + (color.green / 255f)); + blueValues.add("" + (color.blue / 255f)); + alphaValues.add("" + color.getAlphaFloat()); + } + */ + Element feFuncR = document.createElement("feFuncR"); + feFuncR.setAttribute("type", "table"); + feFuncR.setAttribute("tableValues", String.join(" ", redValues)); + Element feFuncG = document.createElement("feFuncG"); + feFuncG.setAttribute("type", "table"); + feFuncG.setAttribute("tableValues", String.join(" ", greenValues)); + Element feFuncB = document.createElement("feFuncB"); + feFuncB.setAttribute("type", "table"); + feFuncB.setAttribute("tableValues", String.join(" ", blueValues)); + Element feFuncA = document.createElement("feFuncA"); + feFuncA.setAttribute("type", "table"); + feFuncA.setAttribute("tableValues", String.join(" ", alphaValues)); + feComponentTransfer.appendChild(feFuncR); + feComponentTransfer.appendChild(feFuncG); + feComponentTransfer.appendChild(feFuncB); + feComponentTransfer.appendChild(feFuncA); + + String result = exporter.getUniqueId("filterResult"); + feComponentTransfer.setAttribute("result", result); + filtersElement.appendChild(feComponentTransfer); + return result; + } + + /** + * Drop shadow + * + * @param distance Distance + * @param angle Angle + * @param dropShadowColor Drop shadow color + * @param innerShadow Inner shadow + * @param knockout Knockout + * @param compositeSource Composite source + * @param blurX Blur X + * @param blurY Blur Y + * @param strength Strength + * @param iterations Iterations + * @param document Document + * @param filtersElement Filters element + * @param exporter SVG exporter + * @param in Input + * @return SVG id of the drop shadow + */ + public static String dropShadow( + double distance, + double angle, + RGBA dropShadowColor, + boolean innerShadow, + boolean knockout, + boolean compositeSource, + double blurX, + double blurY, + double strength, + int iterations, + Document document, + Element filtersElement, + SVGExporter exporter, + String in + ) { + double dx = distance * exporter.getZoom() * Math.cos(angle); + double dy = distance * exporter.getZoom() * Math.sin(angle); + + Element feOffset = document.createElement("feOffset"); + feOffset.setAttribute("dx", "" + dx); + feOffset.setAttribute("dy", "" + dy); + feOffset.setAttribute("in", in); + String feOffsetResult = exporter.getUniqueId("filterResult"); + feOffset.setAttribute("result", feOffsetResult); + filtersElement.appendChild(feOffset); + + String result; + if (innerShadow) { + Element feFlood = document.createElement("feFlood"); + feFlood.setAttribute("flood-color", dropShadowColor.toHexRGB()); + feFlood.setAttribute("flood-opacity", "" + dropShadowColor.getAlphaFloat()); + filtersElement.appendChild(feFlood); + String feFloodResult = exporter.getUniqueId("filterResult"); + feFlood.setAttribute("result", feFloodResult); + + Element feComposite1 = document.createElement("feComposite"); + feComposite1.setAttribute("in", feFloodResult); + feComposite1.setAttribute("in2", feOffsetResult); + feComposite1.setAttribute("operator", "out"); + result = exporter.getUniqueId("filterResult"); + feComposite1.setAttribute("result", result); + filtersElement.appendChild(feComposite1); + } else { + Element feColorMatrix = document.createElement("feColorMatrix"); + feColorMatrix.setAttribute("type", "matrix"); + feColorMatrix.setAttribute("in", feOffsetResult); + feColorMatrix.setAttribute("values", + "0 0 0 0 " + (dropShadowColor.red / 255f) + "," + + "0 0 0 0 " + (dropShadowColor.green / 255f) + "," + + "0 0 0 0 " + (dropShadowColor.blue / 255f) + "," + + "0 0 0 " + (dropShadowColor.alpha / 255f) + " 0" //Note: it is not last one here + ); + result = exporter.getUniqueId("filterResult"); + feColorMatrix.setAttribute("result", result); + filtersElement.appendChild(feColorMatrix); + } + + if (Double.compare(blurX, 0.0) != 0 || Double.compare(blurY, 0.0) != 0) { + result = blur(blurX, blurY, iterations, document, filtersElement, exporter, result); + } + + if (Double.compare(strength, 1.0) != 0) { + Element feColorMatrix2 = document.createElement("feColorMatrix"); + feColorMatrix2.setAttribute("type", "matrix"); + feColorMatrix2.setAttribute("in", result); + feColorMatrix2.setAttribute("values", + "1 0 0 0 0," + + "0 1 0 0 0," + + "0 0 1 0 0," + + "0 0 0 " + strength + " 0" + ); + result = exporter.getUniqueId("filterResult"); + feColorMatrix2.setAttribute("result", result); + filtersElement.appendChild(feColorMatrix2); + } + return compose(in, result, innerShadow ? Filtering.INNER : Filtering.OUTER, knockout, compositeSource, document, filtersElement, exporter); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/helpers/GradientUtil.java b/libsrc/ffdec_lib/src/com/jpexs/helpers/GradientUtil.java index a219379a8..d3b16b483 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/helpers/GradientUtil.java +++ b/libsrc/ffdec_lib/src/com/jpexs/helpers/GradientUtil.java @@ -16,7 +16,6 @@ */ package com.jpexs.helpers; - import com.jpexs.decompiler.flash.types.RGBA; import java.util.ArrayList; import java.util.List; @@ -107,8 +106,9 @@ public final class GradientUtil { ); } } - + public static final class SplitResult { + public final RGBA[] colorsA; public final int[] ratioA; public final RGBA[] colorsB; @@ -123,14 +123,12 @@ public final class GradientUtil { } /** - * Splits a gradient into two halves: - * - A: original positions 0..127 mapped to 0..255 - * - B: original positions 128..255 mapped to 0..255 + * Splits a gradient into two halves: - A: original positions 0..127 mapped + * to 0..255 - B: original positions 128..255 mapped to 0..255 * - * Notes: - * - Stop lookup is based on original ratio[]. - * - Boundary stops at 127 (A) and 128 (B) are ensured (interpolated if missing). - * - ratio[] is assumed sorted ascending. + * Notes: - Stop lookup is based on original ratio[]. - Boundary stops at + * 127 (A) and 128 (B) are ensured (interpolated if missing). - ratio[] is + * assumed sorted ascending. */ public static SplitResult splitIntoHalves( RGBA[] colors, int[] ratio, ColorInterpolation mode @@ -152,18 +150,19 @@ public final class GradientUtil { } // ----- Internal representation of stops ----- - private static final class Stops { + final List colors = new ArrayList<>(); final List ratio = new ArrayList<>(); } /** - * Extracts all stops within [from..to] (inclusive), and ensures stops at both ends exist. - * If an endpoint stop is missing, it is computed via SvgGradient.colorAt(...). + * Extracts all stops within [from..to] (inclusive), and ensures stops at + * both ends exist. If an endpoint stop is missing, it is computed via + * SvgGradient.colorAt(...). */ private static Stops extractRange(RGBA[] colors, int[] ratio, int from, int to, - ColorInterpolation mode) { + ColorInterpolation mode) { Stops out = new Stops(); // Ensure start stop @@ -184,19 +183,22 @@ public final class GradientUtil { } /** - * If there is an existing stop exactly at pos, returns its color; - * otherwise computes the color by interpolation at that position. + * If there is an existing stop exactly at pos, returns its color; otherwise + * computes the color by interpolation at that position. */ private static RGBA stopColorAtOrExisting(RGBA[] colors, int[] ratio, int pos, - ColorInterpolation mode) { + ColorInterpolation mode) { for (int i = 0; i < ratio.length; i++) { - if (ratio[i] == pos) return colors[i]; + if (ratio[i] == pos) { + return colors[i]; + } } return colorAt(colors, ratio, pos, mode); } /** - * Adds a stop keeping order; if the same position already exists, it overwrites the color. + * Adds a stop keeping order; if the same position already exists, it + * overwrites the color. */ private static void addStop(Stops stops, int pos, RGBA color) { // Insert in ascending order (ratio is small, linear insert is fine) @@ -217,8 +219,8 @@ public final class GradientUtil { } /** - * Remaps original integer positions in [from..to] to [0..255]. - * Uses rounding and clamps, guaranteeing endpoints map to 0 and 255. + * Remaps original integer positions in [from..to] to [0..255]. Uses + * rounding and clamps, guaranteeing endpoints map to 0 and 255. */ private static int[] remap(List original, int from, int to) { int span = to - from; // for 0..127 and 128..255 span is 127 diff --git a/libsrc/ffdec_lib/testdata/graphics/graphics.swf b/libsrc/ffdec_lib/testdata/graphics/graphics.swf index 95c1e79bf85381bd3edbb957b5d2d31b49eff4be..97e2bceb3257ae7faa273eb7b5733b3223f11e44 100644 GIT binary patch delta 1417644 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%0DTUo>9N>-rRpL@Z)Jc+EmOOI2;l` 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