diff --git a/CHANGELOG.md b/CHANGELOG.md index 6821ffafd..36021a4aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ All notable changes to this project will be documented in this file. - [#1915] SVG import - gradient when it has two final stops - Native sound export format for ADPCM compression is FLV +### Changed +- [#1913] SVG export/import of shapes - shape exact position (bounds) is retained + ## [18.2.1] - 2022-12-28 ### Fixed - Copy/Move/Cut with dependencies did not handle original tag when not charactertag @@ -2813,6 +2816,7 @@ All notable changes to this project will be documented in this file. [alpha 8]: https://github.com/jindrapetrik/jpexs-decompiler/compare/alpha7...alpha8 [alpha 7]: https://github.com/jindrapetrik/jpexs-decompiler/releases/tag/alpha7 [#1915]: https://www.free-decompiler.com/flash/issues/1915 +[#1913]: https://www.free-decompiler.com/flash/issues/1913 [#1922]: https://www.free-decompiler.com/flash/issues/1922 [#1921]: https://www.free-decompiler.com/flash/issues/1921 [#1917]: https://www.free-decompiler.com/flash/issues/1917 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FrameExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FrameExporter.java index 99dcffa74..4157f6c55 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FrameExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FrameExporter.java @@ -223,7 +223,7 @@ public class FrameExporter { rect.xMax *= settings.zoom; rect.yMax *= settings.zoom; rect.xMin *= settings.zoom; - rect.yMin *= settings.zoom; + rect.yMin *= settings.zoom; SVGExporter exporter = new SVGExporter(rect, settings.zoom); if (fbackgroundColor != null) { exporter.setBackGroundColor(fbackgroundColor); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/PreviewExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/PreviewExporter.java index 0048c6474..6bfcea7be 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/PreviewExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/PreviewExporter.java @@ -461,7 +461,7 @@ public class PreviewExporter { List shapes = ft.getGlyphShapeTable(); int maxw = 0; for (int f = firstGlyphIndex; f < firstGlyphIndex + countGlyphs; f++) { - RECT b = shapes.get(f).getBounds(); + RECT b = shapes.get(f).getBounds(1); if (b.Xmin == Integer.MAX_VALUE) { continue; } @@ -494,7 +494,7 @@ public class PreviewExporter { List rec = new ArrayList<>(); TEXTRECORD tr = new TEXTRECORD(); - RECT b = shapes.get(f).getBounds(); + RECT b = shapes.get(f).getBounds(1); int xmin = b.Xmin == Integer.MAX_VALUE ? 0 : (int) (b.Xmin / ft.getDivider()); xmin *= textHeight / 1024.0; int ymin = b.Ymin == Integer.MAX_VALUE ? 0 : (int) (b.Ymin / ft.getDivider()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/ShapeExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/ShapeExporter.java index 1e6bc3b53..be51a85fe 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/ShapeExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/ShapeExporter.java @@ -137,8 +137,8 @@ public class ShapeExporter { case CANVAS: try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(file))) { SHAPE shp = st.getShapes(); - int deltaX = -shp.getBounds().Xmin; - int deltaY = -shp.getBounds().Ymin; + int deltaX = -shp.getBounds(1).Xmin; + int deltaY = -shp.getBounds(1).Ymin; CanvasShapeExporter cse = new CanvasShapeExporter(st.getShapeNum(), null, SWF.unitDivisor / settings.zoom, ((Tag) st).getSwf(), shp, new CXFORMWITHALPHA(), deltaX, deltaY); cse.export(); Set needed = new HashSet<>(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/commonshape/SVGExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/commonshape/SVGExporter.java index c689e7c03..d629baa99 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/commonshape/SVGExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/commonshape/SVGExporter.java @@ -96,8 +96,8 @@ public class SVGExporter { Element svgRoot = _svg.getDocumentElement(); svgRoot.setAttribute("xmlns:xlink", xlinkNamespace); if (bounds != null) { - svgRoot.setAttribute("width", (bounds.getWidth() / SWF.unitDivisor) + "px"); - svgRoot.setAttribute("height", (bounds.getHeight() / SWF.unitDivisor) + "px"); + svgRoot.setAttribute("width", (bounds.xMax / SWF.unitDivisor) + "px"); + svgRoot.setAttribute("height", (bounds.yMax / SWF.unitDivisor) + "px"); createDefGroup(bounds, null, zoom); } } catch (ParserConfigurationException ex) { @@ -131,7 +131,7 @@ public class SVGExporter { public final void createDefGroup(ExportRectangle bounds, String id, double zoom) { Element g = _svg.createElement("g"); if (bounds != null) { - Matrix mat = Matrix.getTranslateInstance(-bounds.xMin, -bounds.yMin); + Matrix mat = new Matrix(); //Matrix.getTranslateInstance(-bounds.xMin, -bounds.yMin); mat.scale(zoom); g.setAttribute("transform", mat.getSvgTransformationString(SWF.unitDivisor, 1)); } 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 679677b95..641af2b48 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 @@ -168,7 +168,7 @@ public class BitmapExporter extends ShapeExporterBase { public static void export(int shapeNum, SWF swf, SHAPE shape, Color defaultColor, SerializableImage image, double unzoom, Matrix transformation, Matrix strokeTransformation, ColorTransform colorTransform, boolean scaleStrokes) { BitmapExporter exporter = new BitmapExporter(shapeNum, swf, shape, defaultColor, colorTransform); - exporter.exportTo(image, unzoom, transformation, strokeTransformation, scaleStrokes); + exporter.exportTo(shapeNum, image, unzoom, transformation, strokeTransformation, scaleStrokes); } private BitmapExporter(int shapeNum, SWF swf, SHAPE shape, Color defaultColor, ColorTransform colorTransform) { @@ -177,10 +177,10 @@ public class BitmapExporter extends ShapeExporterBase { this.defaultColor = defaultColor; } - private void exportTo(SerializableImage image, double unzoom, Matrix transformation, Matrix strokeTransformation, boolean scaleStrokes) { + private void exportTo(int shapeNum, SerializableImage image, double unzoom, Matrix transformation, Matrix strokeTransformation, boolean scaleStrokes) { this.image = image; this.scaleStrokes = scaleStrokes; - ExportRectangle bounds = new ExportRectangle(shape.getBounds()); + ExportRectangle bounds = new ExportRectangle(shape.getBounds(shapeNum)); this.strokeTransformation = strokeTransformation; calculateThicknessScale(bounds, transformation); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyToSwfConvertor.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyToSwfConvertor.java index c5e58dbcd..a222d73ff 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyToSwfConvertor.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyToSwfConvertor.java @@ -154,7 +154,7 @@ public class IggyToSwfConvertor { SHAPE shp; if (glyph != null) { shp = IggyShapeToSwfConvertor.convertCharToShape(glyph); - fontTag.fontBoundsTable.add(shp.getBounds()); + fontTag.fontBoundsTable.add(shp.getBounds(1)); } else { shp = new SHAPE(); shp.shapeRecords = new ArrayList<>(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfShapeToIggyConvertor.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfShapeToIggyConvertor.java index d8917d8b1..e5df7a906 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfShapeToIggyConvertor.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfShapeToIggyConvertor.java @@ -37,12 +37,12 @@ public class SwfShapeToIggyConvertor { return (val / 1024f); } - public static IggyShape convertShape(SHAPE swfShape) { + public static IggyShape convertShape(int shapeNum, SHAPE swfShape) { /*if (swfShape.shapeRecords.size() == 1) { //no glyphs, maybe space return null; }*/ List nodes = new ArrayList<>(); - RECT bounds = swfShape.getBounds(); + RECT bounds = swfShape.getBounds(shapeNum); boolean first = true; float curX = 0f; float curY = 0f; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfToIggyConvertor.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfToIggyConvertor.java index 6654d25ef..a788e6908 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfToIggyConvertor.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfToIggyConvertor.java @@ -126,7 +126,7 @@ public class SwfToIggyConvertor { List glyphs = new ArrayList<>(); for (SHAPE s : fontTag.glyphShapeTable) { - glyphs.add(SwfShapeToIggyConvertor.convertShape(s)); + glyphs.add(SwfShapeToIggyConvertor.convertShape(1, s)); } List chars = new ArrayList<>(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/SvgImporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/SvgImporter.java index 9a48d51b3..4d0e7b4b5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/SvgImporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/svg/SvgImporter.java @@ -179,16 +179,7 @@ public class SvgImporter { SvgStyle style = new SvgStyle(this, idMap, rootElement); Matrix transform = new Matrix(); - if (!fill) { - rect.Xmin -= origXmin; - rect.Xmax -= origXmin; - rect.Ymin -= origYmin; - rect.Ymax -= origYmin; - rect.Xmin = (int) Math.round(viewBox.x * SWF.unitDivisor); - rect.Ymin = (int) Math.round(viewBox.y * SWF.unitDivisor); - rect.Xmax = (int) Math.round((viewBox.x + viewBox.width) * SWF.unitDivisor); - rect.Ymax = (int) Math.round((viewBox.y + viewBox.height) * SWF.unitDivisor); - } else { + if (fill) { double ratioX = rect.getWidth() / width / SWF.unitDivisor; double ratioY = rect.getHeight() / height / SWF.unitDivisor; transform = Matrix.getScaleInstance(ratioX, ratioY); @@ -202,7 +193,10 @@ public class SvgImporter { shapes.shapeRecords.add(new EndShapeRecord()); - st.shapes = shapes; + st.shapes = shapes; + if (!fill) { + st.shapeBounds = shapes.getBounds(st.getShapeNum()); + } st.setModified(true); return (Tag) st; @@ -522,7 +516,7 @@ public class SvgImporter { x0 = x; y0 = y; } - applyStyleGradients(SHAPERECORD.getBounds(newRecords), scrStyle, transform2, shapeNum, style); + applyStyleGradients(SHAPERECORD.getBounds(newRecords, shapes.lineStyles, shapeNum), scrStyle, transform2, shapeNum, style); shapes.shapeRecords.addAll(newRecords); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java index 511ba8a97..b7961e1b5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java @@ -320,7 +320,7 @@ public class DefineFont2Tag extends FontTag { @Override public int getGlyphWidth(int glyphIndex) { - return glyphShapeTable.get(glyphIndex).getBounds().getWidth(); + return glyphShapeTable.get(glyphIndex).getBounds(1).getWidth(); } @Override @@ -481,10 +481,10 @@ public class DefineFont2Tag extends FontTag { if (fontFlagsHasLayout) { Font advanceFont = font.deriveFont(fontStyle, 1024); // Not multiplied with divider as it causes problems to create font with height around 20k if (!exists) { - fontBoundsTable.add(pos, shp.getBounds()); + fontBoundsTable.add(pos, shp.getBounds(1)); fontAdvanceTable.add(pos, (int) getDivider() * Math.round(FontHelper.getFontAdvance(advanceFont, character))); } else { - fontBoundsTable.set(pos, shp.getBounds()); + fontBoundsTable.set(pos, shp.getBounds(1)); fontAdvanceTable.set(pos, (int) getDivider() * Math.round(FontHelper.getFontAdvance(advanceFont, character))); } @@ -577,7 +577,7 @@ public class DefineFont2Tag extends FontTag { continue; } SHAPE shp = SHAPERECORD.fontCharacterToSHAPE(font, (int) Math.round(getDivider() * 1024), ch); - newFontBoundsTable.add(shp.getBounds()); + newFontBoundsTable.add(shp.getBounds(1)); int fontStyle = getFontStyle(); Font advanceFont = font.deriveFont(fontStyle, 1024); // Not multiplied with divider as it causes problems to create font with height around 20k newFontAdvanceTable.add((int) getDivider() * Math.round(FontHelper.getFontAdvance(advanceFont, ch))); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java index 189f2eb00..66f592edd 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java @@ -308,7 +308,7 @@ public class DefineFont3Tag extends FontTag { @Override public int getGlyphWidth(int glyphIndex) { - return glyphShapeTable.get(glyphIndex).getBounds().getWidth(); + return glyphShapeTable.get(glyphIndex).getBounds(1).getWidth(); } @Override @@ -470,10 +470,10 @@ public class DefineFont3Tag extends FontTag { Font advanceFont = font.deriveFont(fontStyle, 1024); // Not multiplied with divider as it causes problems to create font with height around 20k if (!exists) { - fontBoundsTable.add(pos, shp.getBounds()); + fontBoundsTable.add(pos, shp.getBounds(1)); fontAdvanceTable.add(pos, (int) getDivider() * Math.round(FontHelper.getFontAdvance(advanceFont, character))); } else { - fontBoundsTable.set(pos, shp.getBounds()); + fontBoundsTable.set(pos, shp.getBounds(1)); fontAdvanceTable.set(pos, (int) getDivider() * Math.round(FontHelper.getFontAdvance(advanceFont, character))); } @@ -578,7 +578,7 @@ public class DefineFont3Tag extends FontTag { continue; } SHAPE shp = SHAPERECORD.fontCharacterToSHAPE(font, (int) Math.round(getDivider() * 1024), ch); - newFontBoundsTable.add(shp.getBounds()); + newFontBoundsTable.add(shp.getBounds(1)); int fontStyle = getFontStyle(); Font advanceFont = font.deriveFont(fontStyle, 1024); // Not multiplied with divider as it causes problems to create font with height around 20k newFontAdvanceTable.add((int) getDivider() * Math.round(FontHelper.getFontAdvance(advanceFont, ch))); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFontTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFontTag.java index 8199f7a17..540e836ad 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFontTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFontTag.java @@ -134,7 +134,7 @@ public class DefineFontTag extends FontTag { @Override public int getGlyphWidth(int glyphIndex) { - return glyphShapeTable.get(glyphIndex).getBounds().getWidth(); + return glyphShapeTable.get(glyphIndex).getBounds(1).getWidth(); } private void ensureFontInfo() { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java index b7bb48b45..8ba2ac9e1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java @@ -517,7 +517,7 @@ public abstract class FontTag extends DrawableTag implements AloneTag { } public RECT getGlyphBounds(int glyphIndex) { - return getGlyphShapeTable().get(glyphIndex).getBounds(); + return getGlyphShapeTable().get(glyphIndex).getBounds(1); } public FontTag toClassicFont() { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/TextTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/TextTag.java index 2d3de8866..73adc79b2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/TextTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/TextTag.java @@ -38,6 +38,7 @@ import com.jpexs.decompiler.flash.types.FILLSTYLE; import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY; import com.jpexs.decompiler.flash.types.GLYPHENTRY; import com.jpexs.decompiler.flash.types.LINESTYLE; +import com.jpexs.decompiler.flash.types.LINESTYLE2; import com.jpexs.decompiler.flash.types.LINESTYLEARRAY; import com.jpexs.decompiler.flash.types.MATRIX; import com.jpexs.decompiler.flash.types.RECT; @@ -330,7 +331,10 @@ public abstract class TextTag extends DrawableTag { if (e < rec.glyphEntries.size() - 1) { nextEntry = rec.glyphEntries.get(e + 1); } - RECT rect = SHAPERECORD.getBounds(glyphs.get(entry.glyphIndex).shapeRecords); + LINESTYLEARRAY lsa = new LINESTYLEARRAY(); + lsa.lineStyles = new LINESTYLE[0]; + lsa.lineStyles2 = new LINESTYLE2[0]; + RECT rect = SHAPERECORD.getBounds(glyphs.get(entry.glyphIndex).shapeRecords, lsa, 1); rect.Xmax = (int) Math.round(((double) rect.Xmax * textHeight) / (font.getDivider() * 1024)); rect.Xmin = (int) Math.round(((double) rect.Xmin * textHeight) / (font.getDivider() * 1024)); rect.Ymax = (int) Math.round(((double) rect.Ymax * textHeight) / (font.getDivider() * 1024)); @@ -516,7 +520,7 @@ public abstract class TextTag extends DrawableTag { if (SHAPERECORD.DRAW_BOUNDING_BOX) { RGB borderColor = new RGBA(Color.black); RGB fillColor = new RGBA(new Color(255, 255, 255, 0)); - RECT bounds = shape.getBounds(); + RECT bounds = shape.getBounds(1); mat = Matrix.getTranslateInstance(bounds.Xmin, bounds.Ymin).preConcatenate(mat); TextTag.drawBorder(swf, image, borderColor, fillColor, bounds, new MATRIX(), mat, colorTransform); } @@ -558,7 +562,7 @@ public abstract class TextTag extends DrawableTag { if (entry.glyphIndex != -1 && glyphs != null) { // shapeNum: 1 SHAPE shape = glyphs.get(entry.glyphIndex); - RECT glyphBounds = shape.getBounds(); + RECT glyphBounds = shape.getBounds(1); int glyphWidth = glyphBounds.getWidth(); int glyphHeight = glyphBounds.getHeight(); glyphBounds.Xmin -= glyphWidth / 2; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java index 541103f6f..8e3c50b8f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java @@ -303,7 +303,7 @@ public final class DefineCompactedFont extends FontTag { @Override public int getGlyphWidth(int glyphIndex) { - return resize(getGlyphShapeTable().get(glyphIndex).getBounds().getWidth()); + return resize(getGlyphShapeTable().get(glyphIndex).getBounds(1).getWidth()); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/SHAPE.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/SHAPE.java index c1d870a13..610d288d1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/SHAPE.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/SHAPE.java @@ -73,8 +73,11 @@ public class SHAPE implements NeedsCharacters, Serializable { return modified; } - public RECT getBounds() { - return SHAPERECORD.getBounds(shapeRecords); + public RECT getBounds(int shapeNum) { + LINESTYLEARRAY lsa = new LINESTYLEARRAY(); + lsa.lineStyles = new LINESTYLE[0]; + lsa.lineStyles2 = new LINESTYLE2[0]; + return SHAPERECORD.getBounds(shapeRecords, lsa, shapeNum); } public Shape getOutline(int shapeNum, SWF swf, boolean stroked) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/SHAPEWITHSTYLE.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/SHAPEWITHSTYLE.java index b5cfc40bd..3e40cc9fe 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/SHAPEWITHSTYLE.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/SHAPEWITHSTYLE.java @@ -97,4 +97,11 @@ public class SHAPEWITHSTYLE extends SHAPE implements NeedsCharacters, Serializab return ret; } + + @Override + public RECT getBounds(int shapeNum) { + return SHAPERECORD.getBounds(shapeRecords, lineStyles, shapeNum); + } + + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/gfx/GlyphType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/gfx/GlyphType.java index 5de3215f8..a7f79cf33 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/gfx/GlyphType.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/gfx/GlyphType.java @@ -16,6 +16,9 @@ */ package com.jpexs.decompiler.flash.types.gfx; +import com.jpexs.decompiler.flash.types.LINESTYLE; +import com.jpexs.decompiler.flash.types.LINESTYLE2; +import com.jpexs.decompiler.flash.types.LINESTYLEARRAY; import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.SHAPE; import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord; @@ -46,7 +49,10 @@ public class GlyphType implements Serializable { public GlyphType(List records) { - RECT bounds = SHAPERECORD.getBounds(records); + LINESTYLEARRAY lsa = new LINESTYLEARRAY(); + lsa.lineStyles = new LINESTYLE[0]; + lsa.lineStyles2 = new LINESTYLE2[0]; + RECT bounds = SHAPERECORD.getBounds(records, lsa, 1); boundingBox = new int[4]; boundingBox[0] = bounds.Xmin; boundingBox[1] = bounds.Ymin; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/shaperecords/SHAPERECORD.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/shaperecords/SHAPERECORD.java index c3afc1106..f0c096ccf 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/shaperecords/SHAPERECORD.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/shaperecords/SHAPERECORD.java @@ -24,6 +24,9 @@ import com.jpexs.decompiler.flash.helpers.FontHelper; import com.jpexs.decompiler.flash.tags.base.NeedsCharacters; import com.jpexs.decompiler.flash.tags.base.TextTag; import com.jpexs.decompiler.flash.types.ColorTransform; +import com.jpexs.decompiler.flash.types.LINESTYLE; +import com.jpexs.decompiler.flash.types.LINESTYLE2; +import com.jpexs.decompiler.flash.types.LINESTYLEARRAY; import com.jpexs.decompiler.flash.types.MATRIX; import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.RGB; @@ -77,7 +80,7 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali public abstract void flip(); - public static RECT getBounds(List records) { + public static RECT getBounds(List records, LINESTYLEARRAY lineStyles, int shapeNum) { int x = 0; int y = 0; int max_x = 0; @@ -85,7 +88,29 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali int min_x = Integer.MAX_VALUE; int min_y = Integer.MAX_VALUE; boolean started = false; + int lineStyle = 0; + int lineWidth = 0; + int lineWidthHalf = 0; for (SHAPERECORD r : records) { + if (r instanceof StyleChangeRecord) { + StyleChangeRecord style = (StyleChangeRecord) r; + if (style.stateNewStyles) { + lineStyles = style.lineStyles; + } + if (style.stateLineStyle) { + lineStyle = style.lineStyle; + if (lineStyle == 0) { + lineWidth = 0; + } else { + if (shapeNum <= 3) { + lineWidth = lineStyles.lineStyles[lineStyle - 1].width; + } else { + lineWidth = lineStyles.lineStyles2[lineStyle - 1].width; + } + } + lineWidthHalf = lineWidth / 2; + } + } if (r instanceof CurvedEdgeRecord) { CurvedEdgeRecord curverEdge = (CurvedEdgeRecord) r; int x2 = x + curverEdge.controlDeltaX; @@ -96,6 +121,12 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali if (y2 > max_y) { max_y = y2; } + if (x2 + lineWidthHalf > max_x) { + max_x = x2 + lineWidthHalf; + } + if (y2 + lineWidthHalf > max_y) { + max_y = y2 + lineWidthHalf; + } if (started) { if (y2 < min_y) { min_y = y2; @@ -103,6 +134,14 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali if (x2 < min_x) { min_x = x2; } + + if (y2 - lineWidthHalf < min_y) { + min_y = y2 - lineWidthHalf; + } + + if (x2 - lineWidthHalf < min_x) { + min_x = x2 - lineWidthHalf; + } } } @@ -114,6 +153,12 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali if (y > max_y) { max_y = y; } + if (x + lineWidthHalf > max_x) { + max_x = x + lineWidthHalf; + } + if (y + lineWidthHalf > max_y) { + max_y = y + lineWidthHalf; + } if (r.isMove()) { started = true; } @@ -124,6 +169,13 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali if (x < min_x) { min_x = x; } + + if (y - lineWidthHalf < min_y) { + min_y = y - lineWidthHalf; + } + if (x - lineWidthHalf < min_x) { + min_x = x - lineWidthHalf; + } } } return new RECT(min_x, max_x, min_y, max_y); @@ -150,8 +202,11 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali int maxh = 0; int minXMin = 0; int minYMin = 0; + LINESTYLEARRAY lsa = new LINESTYLEARRAY(); + lsa.lineStyles = new LINESTYLE[0]; + lsa.lineStyles2 = new LINESTYLE2[0]; for (SHAPE s : shapes) { - RECT r = SHAPERECORD.getBounds(s.shapeRecords); + RECT r = SHAPERECORD.getBounds(s.shapeRecords, lsa, shapeNum); if (r.Xmax < r.Xmin || r.Ymax < r.Ymin) { continue; } @@ -207,7 +262,7 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali // shapeNum: 1 SHAPE shape = shapes.get(pos); List records = shape.shapeRecords; - RECT bounds = SHAPERECORD.getBounds(records); + RECT bounds = SHAPERECORD.getBounds(records, lsa, shapeNum); int w1 = bounds.getWidth(); int h1 = bounds.getHeight();