Fixed #1678 Miter clip join - can be enabled in Settings

This commit is contained in:
Jindra Petřík
2022-11-14 06:41:23 +01:00
parent bde3353855
commit 48096290da
6 changed files with 39 additions and 34 deletions

View File

@@ -775,6 +775,10 @@ public final class Configuration {
@ConfigurationDefaultBoolean(true)
@ConfigurationCategory("ui")
public static ConfigurationItem<Boolean> allowDragAndDropInTagListTree = null;
@ConfigurationDefaultBoolean(false)
@ConfigurationCategory("display")
public static ConfigurationItem<Boolean> allowMiterClipLinestyle = null;
private enum OSId {
WINDOWS, OSX, UNIX

View File

@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.exporters.shape;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.ImageTagBufferedImage;
import com.jpexs.decompiler.flash.exporters.commonshape.ExportRectangle;
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
@@ -440,8 +441,9 @@ public class BitmapExporter extends ShapeExporterBase {
if (joinStyle == BasicStroke.JOIN_MITER) {
lineStroke = new BasicStroke((float) thickness, capStyle, joinStyle, miterLimit);
//This seems to be correct, but ridiculously slow :-(
//lineStroke = new MiterClipBasicStroke((BasicStroke) lineStroke);
if (Configuration.allowMiterClipLinestyle.get()) {
lineStroke = new MiterClipBasicStroke((BasicStroke) lineStroke);
}
} else {
lineStroke = new BasicStroke((float) thickness, capStyle, joinStyle);
}

View File

@@ -45,12 +45,15 @@ public class MiterClipBasicStroke implements Stroke {
public float y1;
public float x2;
public float y2;
public int kind;
public Vector(float x1, float y1, float x2, float y2) {
public Vector(float x1, float y1, float x2, float y2, int kind) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.kind = kind;
}
public float getLength() {
@@ -71,7 +74,7 @@ public class MiterClipBasicStroke implements Stroke {
}
public Vector reverse() {
return new Vector(x2, y2, x1, y1);
return new Vector(x2, y2, x1, y1, kind);
}
public Vector transform(AffineTransform t) {
@@ -81,7 +84,7 @@ public class MiterClipBasicStroke implements Stroke {
Point2D toDest = new Point2D.Float();
t.transform(fromSrc, fromDest);
t.transform(toSrc, toDest);
return new Vector((float) fromDest.getX(), (float) fromDest.getY(), (float) toDest.getX(), (float) toDest.getY());
return new Vector((float) fromDest.getX(), (float) fromDest.getY(), (float) toDest.getX(), (float) toDest.getY(), kind);
}
public Vector parallel(float w) {
@@ -92,7 +95,7 @@ public class MiterClipBasicStroke implements Stroke {
float y3 = y1 + yd;
float x4 = x2 + xd;
float y4 = y2 + yd;
return new Vector(x3, y3, x4, y4);
return new Vector(x3, y3, x4, y4, kind);
}
}
@@ -107,63 +110,52 @@ public class MiterClipBasicStroke implements Stroke {
float points[] = new float[6];
Area area = new Area(stroke.createStrokedShape(p));
AffineTransform t = new AffineTransform();
List<Vector> vectors = new ArrayList<>();
List<Boolean> offPath = new ArrayList<>();
List<Boolean> moveTo = new ArrayList<>();
float x = 0;
float y = 0;
final int KIND_MOVETO = 2;
final int KIND_OFFPATH = 1;
final int KIND_NORMAL = 0;
while (!pi.isDone()) {
type = pi.currentSegment(points);
switch (type) {
case PathIterator.SEG_MOVETO:
vectors.add(new Vector(x, y, points[0], points[1]));
offPath.add(true);
moveTo.add(true);
vectors.add(new Vector(x, y, points[0], points[1], KIND_MOVETO));
x = points[0];
y = points[1];
break;
case PathIterator.SEG_LINETO:
vectors.add(new Vector(x, y, points[0], points[1]));
offPath.add(false);
moveTo.add(false);
vectors.add(new Vector(x, y, points[0], points[1], KIND_NORMAL));
x = points[0];
y = points[1];
break;
case PathIterator.SEG_CUBICTO:
vectors.add(new Vector(x, y, points[0], points[1]));
offPath.add(true);
moveTo.add(false);
vectors.add(new Vector(points[0], points[1], points[2], points[3]));
offPath.add(true);
moveTo.add(false);
vectors.add(new Vector(points[2], points[3], points[4], points[5]));
offPath.add(false);
moveTo.add(false);
vectors.add(new Vector(x, y, points[0], points[1], KIND_OFFPATH));
vectors.add(new Vector(points[0], points[1], points[2], points[3], KIND_OFFPATH));
vectors.add(new Vector(points[2], points[3], points[4], points[5], KIND_NORMAL));
x = points[4];
y = points[5];
break;
case PathIterator.SEG_QUADTO:
vectors.add(new Vector(x, y, points[0], points[1]));
offPath.add(true);
moveTo.add(false);
vectors.add(new Vector(points[0], points[1], points[2], points[3]));
offPath.add(false);
moveTo.add(false);
vectors.add(new Vector(x, y, points[0], points[1], KIND_OFFPATH));
vectors.add(new Vector(points[0], points[1], points[2], points[3], KIND_NORMAL));
x = points[2];
y = points[3];
break;
}
pi.next();
}
//FIXME - make this faster!!!
for (int i = 0; i < vectors.size() - 1; i++) {
if (offPath.get(i) || moveTo.get(i + 1)) {
Vector u = vectors.get(i);
Vector v = vectors.get(i + 1);
if (u.kind == KIND_OFFPATH || v.kind == KIND_MOVETO) {
continue;
}
Vector u = vectors.get(i).transform(t);
Vector v = vectors.get(i + 1).transform(t);
float parallelSign = 1;
float dx = u.x2 - u.x1;