diff --git a/CHANGELOG.md b/CHANGELOG.md index c81c8643e..b5146aac3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ All notable changes to this project will be documented in this file. - [#1858] PDF export - Applying same color multiple times - [#1907] Crashing on memory search - [#1906] Memory search - byte align opens wrong SWFs +- [#1914] DropShadow filter ### Changed - Warning before switching deobfuscation is now optional @@ -2650,7 +2651,8 @@ All notable changes to this project will be documented in this file. ### Added - Initial public release -[Unreleased]: https://github.com/jindrapetrik/jpexs-decompiler/compare/version18.0.0...dev +[Unreleased]: https://github.com/jindrapetrik/jpexs-decompiler/compare/version18.1.0...dev +[18.1.0]: https://github.com/jindrapetrik/jpexs-decompiler/compare/version18.0.0...version18.1.0 [18.0.0]: https://github.com/jindrapetrik/jpexs-decompiler/compare/version17.0.4...version18.0.0 [17.0.4]: https://github.com/jindrapetrik/jpexs-decompiler/compare/version17.0.3...version17.0.4 [17.0.3]: https://github.com/jindrapetrik/jpexs-decompiler/compare/version17.0.2...version17.0.3 @@ -2800,6 +2802,7 @@ All notable changes to this project will be documented in this file. [#1908]: https://www.free-decompiler.com/flash/issues/1908 [#1907]: https://www.free-decompiler.com/flash/issues/1907 [#1906]: https://www.free-decompiler.com/flash/issues/1906 +[#1914]: https://www.free-decompiler.com/flash/issues/1914 [#1898]: https://www.free-decompiler.com/flash/issues/1898 [#1511]: https://www.free-decompiler.com/flash/issues/1511 [#1765]: https://www.free-decompiler.com/flash/issues/1765 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/Filtering.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/Filtering.java index 9737cd840..e746f5f87 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/Filtering.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/Filtering.java @@ -399,6 +399,14 @@ public class Filtering { return val; } + private static Color over(Color a, Color b) { + int resultA = a.getAlpha() + b.getAlpha() * (255 - a.getAlpha()) / 255; + int resultR = cut((a.getRed() * (a.getAlpha() / 255.0) + b.getRed() * (b.getAlpha() / 255.0) * (1 - (a.getAlpha() / 255.0))) / (resultA / 255.0)); + int resultG = cut((a.getGreen() * (a.getAlpha() / 255.0) + b.getGreen() * (b.getAlpha() / 255.0) * (1 - (a.getAlpha() / 255.0))) / (resultA / 255.0)); + int resultB = cut((a.getBlue() * (a.getAlpha() / 255.0) + b.getBlue() * (b.getAlpha() / 255.0) * (1 - (a.getAlpha() / 255.0))) / (resultA / 255.0)); + return new Color(resultR, resultG, resultB, resultA); + } + private static BufferedImage dropShadow(BufferedImage src, int blurX, int blurY, float angle, double distance, Color color, boolean inner, int iterations, float strength, boolean knockout, boolean compositeSource) { int width = src.getWidth(); int height = src.getHeight(); @@ -408,38 +416,48 @@ public class Filtering { int alpha = (srcPixels[i] >> 24) & 0xff; if (inner) { alpha = 255 - alpha; - } - - shadow[i] = RGBA.toInt(color.getRed(), color.getGreen(), color.getBlue(), cut(color.getAlpha() * alpha / 255 * strength)); + } + Color shadowColor; + shadowColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), cut(color.getAlpha() * alpha / 255 * strength)); + shadow[i] = shadowColor.getRGB(); } - Color colorFirst = Color.BLACK; Color colorAlpha = ALPHA; double angleRad = angle / 180 * Math.PI; double moveX = (distance * Math.cos(angleRad)); double moveY = (distance * Math.sin(angleRad)); - shadow = moveRGB(width, height, shadow, moveX, moveY, inner ? colorFirst : colorAlpha); + shadow = moveRGB(width, height, shadow, moveX, moveY, inner ? color : colorAlpha); if (blurX > 0 || blurY > 0) { blur(shadow, width, height, blurX, blurY, iterations, null); } - if (compositeSource) { + if (knockout || inner) { for (int i = 0; i < shadow.length; i++) { int mask = (srcPixels[i] >> 24) & 0xff; if (!inner) { mask = 255 - mask; } - shadow[i] = shadow[i] & 0xffffff + ((mask * ((shadow[i] >> 24) & 0xff) / 255) << 24); + + if (inner && compositeSource && !knockout) { + Color shadowColor = new Color(shadow[i], true); + Color srcColor = new Color(srcPixels[i], true); + srcColor = new Color(srcColor.getRed(), srcColor.getGreen(), srcColor.getBlue(), 255); + + Color resultColor = over(shadowColor, srcColor); + + shadow[i] = resultColor.getRGB(); + } + shadow[i] = (shadow[i] & 0xffffff) + ((mask * ((shadow[i] >> 24) & 0xff) / 255) << 24); } } BufferedImage retCanvas = new BufferedImage(width, height, src.getType()); setRGB(retCanvas, width, height, shadow); - if (!knockout && compositeSource) { + if (!knockout && compositeSource && !inner) { Graphics2D g = retCanvas.createGraphics(); - g.setComposite(AlphaComposite.DstOver); + g.setComposite(AlphaComposite.SrcOver); g.drawImage(src, 0, 0, null); } @@ -587,7 +605,7 @@ public class Filtering { } private static int cut(double val) { - int i = (int) val; + int i = (int) Math.round(val); if (i < 0) { i = 0; }