From 8bd23069a31d6165ab11824696155b53c260606c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sat, 27 Sep 2014 16:00:31 +0200 Subject: [PATCH] interval viewer / shape image export - non scaling strokes --- .../flash/exporters/shape/BitmapExporter.java | 69 ++++++++++++++++++- .../exporters/shape/ShapeExporterBase.java | 7 +- 2 files changed, 72 insertions(+), 4 deletions(-) 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 aec7fca61..a5a87e291 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 @@ -44,6 +44,7 @@ import java.awt.geom.GeneralPath; import java.awt.geom.NoninvertibleTransformException; import java.util.ArrayList; import java.util.List; +import java.awt.Shape; /** * @@ -66,6 +67,55 @@ public class BitmapExporter extends ShapeExporterBase { private Stroke defaultStroke; private double unitDivisor; + private class TransformedStroke implements Stroke { + + /** + * To make this serializable without problems. + */ + private static final long serialVersionUID = 1; + + /** + * the AffineTransform used to transform the shape before stroking. + */ + private AffineTransform transform; + /** + * The inverse of {@link #transform}, used to transform back after + * stroking. + */ + private AffineTransform inverse; + + /** + * Our base stroke. + */ + private Stroke stroke; + + /** + * Creates a TransformedStroke based on another Stroke and an + * AffineTransform. + */ + public TransformedStroke(Stroke base, AffineTransform at) + throws NoninvertibleTransformException { + this.transform = new AffineTransform(at); + this.inverse = transform.createInverse(); + this.stroke = base; + } + + /** + * Strokes the given Shape with this stroke, creating an outline. + * + * This outline is distorted by our AffineTransform relative to the + * outline which would be given by the base stroke, but only in terms of + * scaling (i.e. thickness of the lines), as translation and rotation + * are undone after the stroking. + */ + public Shape createStrokedShape(Shape s) { + Shape sTrans = transform.createTransformedShape(s); + Shape sTransStroked = stroke.createStrokedShape(sTrans); + Shape sStroked = inverse.createTransformedShape(sTransStroked); + return sStroked; + } + } + public static void export(SWF swf, SHAPE shape, Color defaultColor, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { BitmapExporter exporter = new BitmapExporter(swf, shape, defaultColor, colorTransform); exporter.exportTo(image, transformation); @@ -79,7 +129,7 @@ public class BitmapExporter extends ShapeExporterBase { private void exportTo(SerializableImage image, Matrix transformation) { this.image = image; - graphics = (Graphics2D) image.getGraphics(); + graphics = (Graphics2D) image.getGraphics(); AffineTransform at = transformation.toTransform(); at.preConcatenate(AffineTransform.getScaleInstance(1 / SWF.unitDivisor, 1 / SWF.unitDivisor)); unitDivisor = 1; @@ -311,11 +361,28 @@ public class BitmapExporter extends ShapeExporterBase { joinStyle = BasicStroke.JOIN_ROUND; break; } + switch(scaleMode){ + case "VERTICAL": + thickness *= graphics.getTransform().getScaleY(); + break; + case "HORIZONTAL": + thickness *= graphics.getTransform().getScaleX(); + break; + case "NORMAL": + thickness *= Math.max(graphics.getTransform().getScaleX(), graphics.getTransform().getScaleY()); + break; + } if (joinStyle == BasicStroke.JOIN_MITER) { lineStroke = new BasicStroke((float) thickness, capStyle, joinStyle, miterLimit); } else { lineStroke = new BasicStroke((float) thickness, capStyle, joinStyle); } + //Do not scale strokes automatically: + try{ + lineStroke = new TransformedStroke(lineStroke,graphics.getTransform()); + }catch(NoninvertibleTransformException net){ + //ignore + } } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/ShapeExporterBase.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/ShapeExporterBase.java index e7d5b9fc2..a61445b86 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/ShapeExporterBase.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/ShapeExporterBase.java @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.exporters.shape; import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; @@ -325,9 +326,9 @@ public abstract class ShapeExporterBase implements IShapeExporter { if (lineStyle2.noHScaleFlag && lineStyle2.noVScaleFlag) { scaleMode = "NONE"; } else if (lineStyle2.noHScaleFlag) { - scaleMode = "HORIZONTAL"; - } else if (lineStyle2.noVScaleFlag) { scaleMode = "VERTICAL"; + } else if (lineStyle2.noVScaleFlag) { + scaleMode = "HORIZONTAL"; } pixelHintingFlag = lineStyle2.pixelHintingFlag; startCapStyle = lineStyle2.startCapStyle;