mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-12 00:44:35 +00:00
Fixed #1982 Slow calculation of large shape outlines - now use only rectangles for large shapes
This commit is contained in:
@@ -116,7 +116,7 @@ public class DefineScalingGridTag extends Tag implements CharacterIdTag {
|
||||
}
|
||||
|
||||
public RECT getRect() {
|
||||
Shape s = getOutline(0, 0, 0, new RenderContext(), new Matrix(), new Matrix(), true, new ExportRectangle(0, 0, 1, 1)/*?*/, 1);
|
||||
Shape s = getOutline(true, 0, 0, 0, new RenderContext(), new Matrix(), new Matrix(), true, new ExportRectangle(0, 0, 1, 1)/*?*/, 1);
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -124,7 +124,7 @@ public class DefineScalingGridTag extends Tag implements CharacterIdTag {
|
||||
return new RECT(r.x, r.x + r.width, r.y, r.y + r.height);
|
||||
}
|
||||
|
||||
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, Matrix prevTransform, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
public Shape getOutline(boolean fast, int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, Matrix prevTransform, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
CharacterTag ct = swf.getCharacter(characterId);
|
||||
if (ct == null) {
|
||||
return null;
|
||||
@@ -135,7 +135,7 @@ public class DefineScalingGridTag extends Tag implements CharacterIdTag {
|
||||
double[] coords = new double[6];
|
||||
|
||||
DrawableTag dt = (DrawableTag) ct;
|
||||
Shape path = dt.getOutline(frame, time, ratio, renderContext, transformation, stroked, viewRect, unzoom);
|
||||
Shape path = dt.getOutline(fast, frame, time, ratio, renderContext, transformation, stroked, viewRect, unzoom);
|
||||
PathIterator iterator = path.getPathIterator(new AffineTransform());
|
||||
GeneralPath gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
|
||||
ExportRectangle boundsRect = new ExportRectangle(dt.getRect());
|
||||
|
||||
@@ -400,8 +400,8 @@ public class DefineSpriteTag extends DrawableTag implements Timelined {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
return getTimeline().getOutline(frame, time, renderContext, transformation, stroked, viewRect, unzoom);
|
||||
public Shape getOutline(boolean fast, int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
return getTimeline().getOutline(fast, frame, time, renderContext, transformation, stroked, viewRect, unzoom);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -325,7 +325,7 @@ public class DefineVideoStreamTag extends DrawableTag implements BoundedTag, Tim
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
public Shape getOutline(boolean fast, int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
return transformation.toTransform().createTransformedShape(new Rectangle2D.Double(0, 0, width * SWF.unitDivisor, height * SWF.unitDivisor));
|
||||
}
|
||||
|
||||
|
||||
@@ -88,8 +88,8 @@ public abstract class ButtonTag extends DrawableTag implements Timelined {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
return getTimeline().getOutline(frame, time, renderContext, transformation, stroked, viewRect, unzoom);
|
||||
public Shape getOutline(boolean fast, int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
return getTimeline().getOutline(fast, frame, time, renderContext, transformation, stroked, viewRect, unzoom);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -44,8 +44,21 @@ public abstract class DrawableTag extends CharacterTag implements BoundedTag {
|
||||
|
||||
public abstract int getUsedParameters();
|
||||
|
||||
public abstract Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom);
|
||||
|
||||
/**
|
||||
* Calculates drawable outline.
|
||||
* @param fast When the structure is large, can approximate to rectangles instead of being slow.
|
||||
* @param frame
|
||||
* @param time
|
||||
* @param ratio
|
||||
* @param renderContext
|
||||
* @param transformation
|
||||
* @param stroked
|
||||
* @param viewRect
|
||||
* @param unzoom
|
||||
* @return
|
||||
*/
|
||||
public abstract Shape getOutline(boolean fast, int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom);
|
||||
|
||||
public abstract void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix prevTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing);
|
||||
|
||||
public abstract void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException;
|
||||
|
||||
@@ -427,7 +427,7 @@ public abstract class FontTag extends DrawableTag implements AloneTag {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
public Shape getOutline(boolean fast, int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
RECT r = getRect();
|
||||
return new Area(new Rectangle(r.Xmin, r.Ymin, r.getWidth(), r.getHeight()));
|
||||
}
|
||||
|
||||
@@ -249,8 +249,8 @@ public abstract class ImageTag extends DrawableTag {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
return transformation.toTransform().createTransformedShape(getShape(1).getOutline(1, swf, stroked));
|
||||
public Shape getOutline(boolean fast, int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
return transformation.toTransform().createTransformedShape(getShape(1).getOutline(fast, 1, swf, stroked));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -349,8 +349,8 @@ public abstract class MorphShapeTag extends DrawableTag {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
return transformation.toTransform().createTransformedShape(getShapeAtRatio(ratio).getOutline(getShapeNum() == 2 ? 4 : 1, swf, stroked));
|
||||
public Shape getOutline(boolean fast, int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
return transformation.toTransform().createTransformedShape(getShapeAtRatio(ratio).getOutline(fast, getShapeNum() == 2 ? 4 : 1, swf, stroked));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -183,8 +183,8 @@ public abstract class ShapeTag extends DrawableTag implements LazyObject {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
return transformation.toTransform().createTransformedShape(getShapes().getOutline(getShapeNum(), swf, stroked));
|
||||
public Shape getOutline(boolean fast, int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
return transformation.toTransform().createTransformedShape(getShapes().getOutline(fast, getShapeNum(), swf, stroked));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -787,7 +787,7 @@ public abstract class TextTag extends DrawableTag {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
public Shape getOutline(boolean fast, int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
RECT r = getBounds();
|
||||
Shape shp = new Rectangle.Double(r.Xmin, r.Ymin, r.getWidth(), r.getHeight());
|
||||
return transformation.toTransform().createTransformedShape(shp); //TODO: match character shapes (?)
|
||||
|
||||
@@ -813,7 +813,7 @@ public class Timeline {
|
||||
int dy = (int) (viewRect.yMin * unzoom);
|
||||
Point cursorPositionInView = new Point((int) Math.round(renderContext.cursorPosition.x * unzoom) - dx, (int) Math.round(renderContext.cursorPosition.y * unzoom) - dy);
|
||||
|
||||
Shape buttonShape = drawable.getOutline(ButtonTag.FRAME_HITTEST, dtime, ratio, renderContext, absMat, true, viewRect, unzoom);
|
||||
Shape buttonShape = ((ButtonTag) drawable).getOutline(true, ButtonTag.FRAME_HITTEST, dtime, ratio, renderContext, absMat, true, viewRect, unzoom);
|
||||
if (buttonShape.contains(cursorPositionInView)) {
|
||||
renderContext.mouseOverButton = (ButtonTag) drawable;
|
||||
if (renderContext.mouseButton > 0) {
|
||||
@@ -980,7 +980,7 @@ public class Timeline {
|
||||
renderContext.stateUnderCursor.add(layer);
|
||||
}
|
||||
} else if (absMat.transform(new ExportRectangle(boundRect)).contains(cursorPositionInView)) {
|
||||
Shape shape = drawable.getOutline(dframe, dtime, layer.ratio, renderContext, absMat, true, viewRect, unzoom);
|
||||
Shape shape = drawable.getOutline(true, dframe, dtime, layer.ratio, renderContext, absMat, true, viewRect, unzoom);
|
||||
if (shape.contains(cursorPositionInView)) {
|
||||
renderContext.stateUnderCursor.add(layer);
|
||||
}
|
||||
@@ -991,7 +991,7 @@ public class Timeline {
|
||||
Graphics2D g2 = (Graphics2D) renderContext.borderImage.getGraphics();
|
||||
g2.setPaint(Color.red);
|
||||
g2.setStroke(new BasicStroke(2));
|
||||
Shape shape = drawable.getOutline(dframe, dtime, layer.ratio, renderContext, absMat.preConcatenate(Matrix.getScaleInstance(1 / SWF.unitDivisor)), true, viewRect, unzoom);
|
||||
Shape shape = drawable.getOutline(true, dframe, dtime, layer.ratio, renderContext, absMat.preConcatenate(Matrix.getScaleInstance(1 / SWF.unitDivisor)), true, viewRect, unzoom);
|
||||
g2.draw(shape);
|
||||
}
|
||||
if (!(sameImage && canUseSameImage)) {
|
||||
@@ -1341,7 +1341,7 @@ public class Timeline {
|
||||
}
|
||||
}
|
||||
|
||||
public Shape getOutline(int frame, int time, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
public Shape getOutline(boolean fast, int frame, int time, RenderContext renderContext, Matrix transformation, boolean stroked, ExportRectangle viewRect, double unzoom) {
|
||||
Frame fr = getFrame(frame);
|
||||
Area area = new Area();
|
||||
Stack<Clip> clips = new Stack<>();
|
||||
@@ -1378,7 +1378,7 @@ public class Timeline {
|
||||
dframe = ButtonTag.FRAME_UP;
|
||||
if (renderContext.cursorPosition != null) {
|
||||
ButtonTag buttonTag = (ButtonTag) character;
|
||||
Shape buttonShape = buttonTag.getOutline(ButtonTag.FRAME_HITTEST, time, layer.ratio, renderContext, m, stroked, viewRect, unzoom);
|
||||
Shape buttonShape = buttonTag.getOutline(fast, ButtonTag.FRAME_HITTEST, time, layer.ratio, renderContext, m, stroked, viewRect, unzoom);
|
||||
int dx = (int) Math.round(viewRect.xMin * unzoom);
|
||||
int dy = (int) Math.round(viewRect.yMin * unzoom);
|
||||
Point cursorPositionInView = new Point((int) Math.round(renderContext.cursorPosition.x * unzoom) - dx, (int) Math.round(renderContext.cursorPosition.y * unzoom) - dy);
|
||||
@@ -1392,7 +1392,7 @@ public class Timeline {
|
||||
}
|
||||
}
|
||||
|
||||
Shape cshape = ((DrawableTag) character).getOutline(dframe, time, layer.ratio, renderContext, m, stroked, viewRect, unzoom);
|
||||
Shape cshape = ((DrawableTag) character).getOutline(fast, dframe, time, layer.ratio, renderContext, m, stroked, viewRect, unzoom);
|
||||
Area addArea = new Area(cshape);
|
||||
if (currentClip != null) {
|
||||
Area a = new Area(new Rectangle(displayRect.Xmin, displayRect.Ymin, displayRect.getWidth(), displayRect.getHeight()));
|
||||
|
||||
@@ -47,6 +47,7 @@ public class SHAPE implements NeedsCharacters, Serializable {
|
||||
public List<SHAPERECORD> shapeRecords;
|
||||
|
||||
private Shape cachedOutline;
|
||||
private Shape fastCachedOutline;
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
@@ -86,27 +87,50 @@ public class SHAPE implements NeedsCharacters, Serializable {
|
||||
|
||||
public void clearCachedOutline() {
|
||||
cachedOutline = null;
|
||||
fastCachedOutline = null;
|
||||
}
|
||||
|
||||
public Shape getOutline(int shapeNum, SWF swf, boolean stroked) {
|
||||
/**
|
||||
*
|
||||
* @param fast When the shape is large, can approximate to rectangles instead of being slow.
|
||||
* @param shapeNum Version of DefineShape, 2 for DefineShape2 etc.
|
||||
* @param swf
|
||||
* @param stroked
|
||||
* @return
|
||||
*/
|
||||
public Shape getOutline(boolean fast, int shapeNum, SWF swf, boolean stroked) {
|
||||
if (cachedOutline != null) {
|
||||
return cachedOutline;
|
||||
}
|
||||
if (fast && fastCachedOutline != null) {
|
||||
return fastCachedOutline;
|
||||
}
|
||||
|
||||
List<GeneralPath> strokes = new ArrayList<>();
|
||||
List<GeneralPath> paths = PathExporter.export(shapeNum, swf, this, strokes);
|
||||
|
||||
Area area = new Area();
|
||||
boolean large = shapeRecords.size() > 500;
|
||||
|
||||
if (!large) {
|
||||
fast = false;
|
||||
}
|
||||
|
||||
Area area = new Area();
|
||||
for (GeneralPath path : paths) {
|
||||
area.add(new Area(path));
|
||||
area.add(new Area(fast ? path.getBounds2D() : path));
|
||||
}
|
||||
if (stroked) {
|
||||
for (GeneralPath path : strokes) {
|
||||
area.add(new Area(path));
|
||||
area.add(new Area(fast ? path.getBounds2D() : path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cachedOutline = area;
|
||||
if (fast) {
|
||||
fastCachedOutline = area;
|
||||
} else {
|
||||
fastCachedOutline = null;
|
||||
cachedOutline = area;
|
||||
}
|
||||
return area;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user