Fixed #1828 Incorrect stroke scaling (normal/none/vertical/horizontal)

This commit is contained in:
Jindra Petřík
2022-10-24 12:26:11 +02:00
parent 499e5645cd
commit b896688d5d
15 changed files with 415 additions and 222 deletions
@@ -123,4 +123,20 @@ public class ExportRectangle {
public ExportRectangle toPx() {
return new ExportRectangle(Math.round(xMin / 20), Math.round(yMin / 20), Math.round(xMax / 20), Math.round(yMax / 20));
}
public Point getUpperLeftPoint() {
return new Point(xMin, yMin);
}
public Point getUpperRightPoint() {
return new Point(xMax, yMin);
}
public Point getLowerLeftPoint() {
return new Point(xMin, yMax);
}
public Point getLowerRightPoint() {
return new Point(xMax, yMax);
}
}
@@ -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.commonshape;
/**
@@ -45,4 +46,15 @@ public class Point {
}
return false;
}
public double distanceTo(Point p) {
double dx = x - p.x;
double dy = y - p.y;
return Math.sqrt(dx * dx + dy * dy);
}
@Override
public String toString() {
return "[" + x + "," + y + "]";
}
}
@@ -45,6 +45,7 @@ import java.awt.TexturePaint;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
@@ -92,6 +93,12 @@ public class BitmapExporter extends ShapeExporterBase {
private Matrix strokeTransformation;
private double thicknessScale;
private double thicknessScaleX;
private double thicknessScaleY;
private double realZoom;
private static boolean linearGradientColorWarnignShown = false;
private boolean scaleStrokes;
@@ -162,12 +169,8 @@ public class BitmapExporter extends ShapeExporterBase {
this.image = image;
this.scaleStrokes = scaleStrokes;
ExportRectangle bounds = new ExportRectangle(shape.getBounds());
ExportRectangle transformedBounds = strokeTransformation.transform(bounds);
this.strokeTransformation = Matrix.getScaleInstance(
Double.compare(bounds.getWidth(), 0.0d) == 0 /*horizontal line or single point */ ? 1 : transformedBounds.getWidth() / bounds.getWidth(),
Double.compare(bounds.getHeight(), 0.0d) == 0 /*vertical line or single point */ ? 1 : transformedBounds.getHeight() / bounds.getHeight()
);
this.strokeTransformation = strokeTransformation;
calculateThicknessScale(bounds, transformation);
graphics = (Graphics2D) image.getGraphics();
AffineTransform at = transformation.toTransform();
@@ -177,6 +180,19 @@ public class BitmapExporter extends ShapeExporterBase {
super.export();
}
private void calculateThicknessScale(ExportRectangle bounds, Matrix transformation) {
com.jpexs.decompiler.flash.exporters.commonshape.Point p00 = strokeTransformation.transform(0, 0);
com.jpexs.decompiler.flash.exporters.commonshape.Point p11 = strokeTransformation.transform(1, 1);
thicknessScale = p00.distanceTo(p11) / Math.sqrt(2);
thicknessScaleX = Math.abs(p11.x - p00.x);
thicknessScaleY = Math.abs(p11.y - p00.y);
Matrix transPre = transformation.preConcatenate(Matrix.getScaleInstance(1 / SWF.unitDivisor, 1 / SWF.unitDivisor));
p00 = transPre.transform(0, 0);
p11 = transPre.transform(1, 1);
realZoom = p00.distanceTo(p11);
}
public SerializableImage getImage() {
return image;
}
@@ -398,21 +414,22 @@ public class BitmapExporter extends ShapeExporterBase {
if (scaleStrokes) {
switch (scaleMode) {
case "VERTICAL":
thickness *= strokeTransformation.scaleY;
thickness *= thicknessScaleY;
break;
case "HORIZONTAL":
thickness *= strokeTransformation.scaleX;
thickness *= thicknessScaleX;
break;
case "NORMAL":
thickness *= Math.max(strokeTransformation.scaleX, strokeTransformation.scaleY);
thickness *= thicknessScale;
break;
case "NONE":
break;
}
}
if (thickness < 0) {
thickness = -thickness;
//always display minimum strokem of 1 pixel, no matter how zoomed it is
if (thickness * realZoom < 1) {
thickness = 1 / realZoom;
}
if (joinStyle == BasicStroke.JOIN_MITER) {
@@ -78,6 +78,9 @@ public abstract class CharacterTag extends Tag implements CharacterIdTag {
}
public DefineScalingGridTag getScalingGridTag() {
if (swf == null) { //???
return null;
}
return (DefineScalingGridTag) swf.getCharacterIdTag(getCharacterId(), DefineScalingGridTag.ID);
}
}
@@ -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.types.filters;
import com.jpexs.decompiler.flash.types.RGBA;
@@ -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.helpers;
import com.jpexs.decompiler.flash.helpers.ImageHelper;