Added: #2592, #2154, #2591 - Better handling of antialias conflation artifacts (by scaling), can be enabled in Advanced Settings / Display and Export.

This commit is contained in:
Jindra Petřík
2025-12-22 17:41:37 +01:00
parent 8fc7541f21
commit a43da6ed0a
32 changed files with 338 additions and 132 deletions

View File

@@ -186,9 +186,11 @@ import com.jpexs.helpers.utf8.Utf8Helper;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -4948,17 +4950,19 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
* @param backGroundColor Background color
* @param zoom Zoom
* @param canUseSmoothing Can use smoothing
* @param aaScale Antialias conflation reducing scale coefficient
* @return Image
*/
public static SerializableImage frameToImageGet(Timeline timeline, int frame, int time, Point cursorPosition, int mouseButton, RECT displayRect, Matrix transformation, ColorTransform colorTransform, Color backGroundColor, double zoom, boolean canUseSmoothing) {
public static SerializableImage frameToImageGet(Timeline timeline, int frame, int time, Point cursorPosition, int mouseButton, RECT displayRect, Matrix transformation, ColorTransform colorTransform, Color backGroundColor, double zoom, boolean canUseSmoothing, int aaScale) {
if (timeline.getFrameCount() == 0) {
return new SerializableImage(1, 1, SerializableImage.TYPE_INT_ARGB_PRE);
}
RECT rect = displayRect;
RECT rect = displayRect;
SerializableImage image = new SerializableImage(
rect.getWidth() == 0 ? 1 /*FIXME: is this necessary?*/ : (int) (rect.getWidth() * zoom / SWF.unitDivisor),
rect.getHeight() == 0 ? 1 : (int) (rect.getHeight() * zoom / SWF.unitDivisor), SerializableImage.TYPE_INT_ARGB_PRE);
rect.getWidth() == 0 ? 1 /*FIXME: is this necessary?*/ : (int) (rect.getWidth() * zoom * aaScale / SWF.unitDivisor),
rect.getHeight() == 0 ? 1 : (int) (rect.getHeight() * zoom * aaScale / SWF.unitDivisor), SerializableImage.TYPE_INT_ARGB_PRE);
if (backGroundColor == null) {
image.fillTransparent();
} else {
@@ -4969,14 +4973,27 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
}
Matrix m = transformation.clone();
m.translate(-rect.Xmin * zoom, -rect.Ymin * zoom);
m.scale(zoom);
m.translate(-rect.Xmin * zoom * aaScale, -rect.Ymin * zoom * aaScale);
m.scale(zoom * aaScale);
RenderContext renderContext = new RenderContext();
renderContext.cursorPosition = cursorPosition;
renderContext.mouseButton = mouseButton;
ExportRectangle viewRect = new ExportRectangle(rect);
timeline.toImage(frame, time, renderContext, image, image, false, m, new Matrix(), m, colorTransform, zoom, true, viewRect, viewRect, m, true, Timeline.DRAW_MODE_ALL, 0, canUseSmoothing, new ArrayList<>());
viewRect.xMin *= aaScale;
viewRect.yMin *= aaScale;
viewRect.xMax *= aaScale;
viewRect.yMax *= aaScale;
timeline.toImage(frame, time, renderContext, image, image, false, m, new Matrix(), m, colorTransform, zoom * aaScale, true, viewRect, viewRect, m, true, Timeline.DRAW_MODE_ALL, 0, canUseSmoothing, new ArrayList<>(), aaScale);
SerializableImage img2 = new SerializableImage(image.getWidth() / aaScale, image.getHeight() / aaScale, BufferedImage.TYPE_INT_ARGB_PRE);
img2.fillTransparent();
Graphics2D g2 = (Graphics2D) img2.getGraphics();
g2.drawImage(image.getBufferedImage().getScaledInstance(image.getWidth() / aaScale, image.getHeight() / aaScale, Image.SCALE_SMOOTH), 0, 0, null);
image = img2;
return image;
}

View File

@@ -841,7 +841,23 @@ public final class Configuration {
@ConfigurationCategory("display")
@ConfigurationRemoved
public static ConfigurationItem<Boolean> fixAntialiasConflation = null;
@ConfigurationDefaultBoolean(false)
@ConfigurationCategory("display")
public static ConfigurationItem<Boolean> reduceAntialiasConflationByScalingForDisplay = null;
@ConfigurationDefaultInt(4)
@ConfigurationCategory("display")
public static ConfigurationItem<Integer> reduceAntialiasConflationByScalingValueForDisplay = null;
@ConfigurationDefaultBoolean(false)
@ConfigurationCategory("export")
public static ConfigurationItem<Boolean> reduceAntialiasConflationByScalingForExport = null;
@ConfigurationDefaultInt(10)
@ConfigurationCategory("export")
public static ConfigurationItem<Integer> reduceAntialiasConflationByScalingValueForExport = null;
@ConfigurationDefaultBoolean(true)
@ConfigurationCategory("display")
public static ConfigurationItem<Boolean> autoPlaySounds = null;
@@ -1822,4 +1838,19 @@ public final class Configuration {
return null;
}
public static int calculateRealAaScale(int imageWidth, int imageHeight, double zoom, int initialAaScale) {
final int MAX_IMAGE_DIMENSION = 10000;
int aaScale = initialAaScale;
while (
aaScale > 1
&& (((long) imageWidth * zoom * aaScale / SWF.unitDivisor) > MAX_IMAGE_DIMENSION
|| ((long) imageHeight * zoom * aaScale / SWF.unitDivisor) > MAX_IMAGE_DIMENSION)
) {
aaScale--;
}
return aaScale;
}
}

View File

@@ -140,7 +140,7 @@ public class FrameExporter {
frames.add(0); // todo: export all frames
}
FrameExportSettings fes = new FrameExportSettings(fem, settings.zoom, true);
FrameExportSettings fes = new FrameExportSettings(fem, settings.zoom, true, settings.aaScale);
return exportFrames(handler, outdir, swf, containerId, frames, 1, fes, evl);
}
@@ -178,7 +178,7 @@ public class FrameExporter {
throw new Error("Unsupported sprite export mode");
}
FrameExportSettings fes = new FrameExportSettings(fem, settings.zoom, true);
FrameExportSettings fes = new FrameExportSettings(fem, settings.zoom, true, settings.aaScale);
return exportFrames(handler, outdir, swf, containerId, frames, subframesLength, fes, evl);
}
@@ -248,7 +248,8 @@ public class FrameExporter {
int max = subFrameMode ? subframeLength : fframes.size();
int fframe = subFrameMode ? fframes.get(0) : fframes.get(pos++);
BufferedImage result = SWF.frameToImageGet(tim, fframe, subFrameMode ? pos++ : 0, null, 0, tim.displayRect, new Matrix(), null, backgroundColor == null && !usesTransparency ? Color.white : backgroundColor, settings.zoom, true).getBufferedImage();
int realAaScale = Configuration.calculateRealAaScale(tim.displayRect.getWidth(), tim.displayRect.getHeight(), settings.zoom, settings.aaScale);
BufferedImage result = SWF.frameToImageGet(tim, fframe, subFrameMode ? pos++ : 0, null, 0, tim.displayRect, new Matrix(), null, backgroundColor == null && !usesTransparency ? Color.white : backgroundColor, settings.zoom, true, realAaScale).getBufferedImage();
if (CancellableWorker.isInterrupted()) {
return null;
}
@@ -687,7 +688,7 @@ public class FrameExporter {
renderContext.stateUnderCursor = new ArrayList<>();
try {
tim.toImage(fframe, subFramesLength > 1 ? pos : 0, renderContext, image, image, false, m, new Matrix(), m, null, zoom, true, new ExportRectangle(rect), new ExportRectangle(rect), m, true, Timeline.DRAW_MODE_ALL, 0, true, new ArrayList<>());
tim.toImage(fframe, subFramesLength > 1 ? pos : 0, renderContext, image, image, false, m, new Matrix(), m, null, zoom, true, new ExportRectangle(rect), new ExportRectangle(rect), m, true, Timeline.DRAW_MODE_ALL, 0, true, new ArrayList<>(), 1);
} catch (Exception ex) {
ex.printStackTrace();
}

View File

@@ -49,7 +49,10 @@ import com.jpexs.helpers.Path;
import com.jpexs.helpers.SerializableImage;
import com.jpexs.helpers.utf8.Utf8Helper;
import dev.matrixlab.webp4j.WebPCodec;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -121,7 +124,7 @@ public class MorphShapeExporter {
RECT rect = st.getRect();
m = Matrix.getScaleInstance(settings.zoom);
m.translate(-rect.Xmin, -rect.Ymin);
switch (settings.mode) {
case SVG_START_END:
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(fileStart))) {
@@ -163,8 +166,11 @@ public class MorphShapeExporter {
double unzoom = settings.zoom;
st = mst.getStartShapeTag();
rect = st.getRect();
int newWidth = (int) (rect.getWidth() * settings.zoom / SWF.unitDivisor) + 1;
int newHeight = (int) (rect.getHeight() * settings.zoom / SWF.unitDivisor) + 1;
int realAaScale = Configuration.calculateRealAaScale(rect.getWidth(), rect.getHeight(), settings.zoom, settings.aaScale);
int newWidth = (int) (rect.getWidth() * settings.zoom * realAaScale / SWF.unitDivisor) + 1;
int newHeight = (int) (rect.getHeight() * settings.zoom * realAaScale / SWF.unitDivisor) + 1;
SerializableImage img = new SerializableImage(newWidth, newHeight, SerializableImage.TYPE_INT_ARGB_PRE);
img.fillTransparent();
if (settings.mode == MorphShapeExportMode.BMP_START_END) {
@@ -175,23 +181,37 @@ public class MorphShapeExporter {
g.fillRect(0, 0, img.getWidth(), img.getHeight());
}
}
m = Matrix.getScaleInstance(settings.zoom);
m = Matrix.getScaleInstance(settings.zoom * realAaScale);
m.translate(-rect.Xmin, -rect.Ymin);
st.toImage(0, 0, 0, new RenderContext(), img, img, false, m, m, m, m, new CXFORMWITHALPHA(), unzoom, false, new ExportRectangle(rect), new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, true);
st.toImage(0, 0, 0, new RenderContext(), img, img, false, m, m, m, m, new CXFORMWITHALPHA(), unzoom * realAaScale, false, new ExportRectangle(rect), new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, true, realAaScale);
BufferedImage bim = img.getBufferedImage();
if (realAaScale > 1) {
SerializableImage img2 = new SerializableImage(((newWidth - 1) / realAaScale) + 1,
((newHeight - 1) / realAaScale) + 1, SerializableImage.TYPE_INT_ARGB_PRE);
img2.fillTransparent();
Graphics g2 = img2.getGraphics();
g2.drawImage(img.getBufferedImage().getScaledInstance(img2.getWidth(), img2.getHeight(), Image.SCALE_SMOOTH), 0, 0, null);
bim = img2.getBufferedImage();
}
if (settings.mode == MorphShapeExportMode.PNG_START_END) {
ImageHelper.write(img.getBufferedImage(), ImageFormat.PNG, fileStart);
ImageHelper.write(bim, ImageFormat.PNG, fileStart);
} else if (settings.mode == MorphShapeExportMode.WEBP_START_END) {
try (FileOutputStream fos = new FileOutputStream(fileStart)) {
fos.write(WebPCodec.encodeImage(img.getBufferedImage(), 100f));
fos.write(WebPCodec.encodeImage(bim, 100f));
}
} else {
BMPFile.saveBitmap(img.getBufferedImage(), fileStart);
BMPFile.saveBitmap(bim, fileStart);
}
st = mst.getEndShapeTag();
rect = st.getRect();
newWidth = (int) (rect.getWidth() * settings.zoom / SWF.unitDivisor) + 1;
newHeight = (int) (rect.getHeight() * settings.zoom / SWF.unitDivisor) + 1;
realAaScale = Configuration.calculateRealAaScale(rect.getWidth(), rect.getHeight(), settings.zoom, settings.aaScale);
newWidth = (int) (rect.getWidth() * settings.zoom * realAaScale / SWF.unitDivisor) + 1;
newHeight = (int) (rect.getHeight() * settings.zoom * realAaScale / SWF.unitDivisor) + 1;
img = new SerializableImage(newWidth, newHeight, SerializableImage.TYPE_INT_ARGB_PRE);
img.fillTransparent();
if (settings.mode == MorphShapeExportMode.BMP_START_END) {
@@ -202,17 +222,29 @@ public class MorphShapeExporter {
g.fillRect(0, 0, img.getWidth(), img.getHeight());
}
}
m = Matrix.getScaleInstance(settings.zoom);
m = Matrix.getScaleInstance(settings.zoom * realAaScale);
m.translate(-rect.Xmin, -rect.Ymin);
st.toImage(0, 0, 0, new RenderContext(), img, img, false, m, m, m, m, new CXFORMWITHALPHA(), unzoom, false, new ExportRectangle(rect), new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, true);
st.toImage(0, 0, 0, new RenderContext(), img, img, false, m, m, m, m, new CXFORMWITHALPHA(), unzoom, false, new ExportRectangle(rect), new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, true, settings.aaScale);
bim = img.getBufferedImage();
if (realAaScale > 1) {
SerializableImage img2 = new SerializableImage(((newWidth - 1) / realAaScale) + 1,
((newHeight - 1) / realAaScale) + 1, SerializableImage.TYPE_INT_ARGB_PRE);
img2.fillTransparent();
Graphics g2 = img2.getGraphics();
g2.drawImage(img.getBufferedImage().getScaledInstance(img2.getWidth(), img2.getHeight(), Image.SCALE_SMOOTH), 0, 0, null);
bim = img2.getBufferedImage();
}
if (settings.mode == MorphShapeExportMode.PNG_START_END) {
ImageHelper.write(img.getBufferedImage(), ImageFormat.PNG, fileEnd);
ImageHelper.write(bim, ImageFormat.PNG, fileEnd);
} else if (settings.mode == MorphShapeExportMode.WEBP_START_END) {
try (FileOutputStream fos = new FileOutputStream(fileEnd)) {
fos.write(WebPCodec.encodeLosslessImage(img.getBufferedImage()));
fos.write(WebPCodec.encodeLosslessImage(bim));
}
} else {
BMPFile.saveBitmap(img.getBufferedImage(), fileEnd);
BMPFile.saveBitmap(bim, fileEnd);
}
break;
case CANVAS:

View File

@@ -47,7 +47,10 @@ import com.jpexs.helpers.Path;
import com.jpexs.helpers.SerializableImage;
import com.jpexs.helpers.utf8.Utf8Helper;
import dev.matrixlab.webp4j.WebPCodec;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -71,7 +74,7 @@ import java.util.logging.Logger;
*/
public class ShapeExporter {
public List<File> exportShapes(AbortRetryIgnoreHandler handler, final String outdir, final SWF swf, ReadOnlyTagList tags, final ShapeExportSettings settings, EventListener evl, double unzoom) throws IOException, InterruptedException {
public List<File> exportShapes(AbortRetryIgnoreHandler handler, final String outdir, final SWF swf, ReadOnlyTagList tags, final ShapeExportSettings settings, EventListener evl, double unzoom, int aaScale) throws IOException, InterruptedException {
List<File> ret = new ArrayList<>();
if (CancellableWorker.isInterrupted()) {
return ret;
@@ -124,8 +127,9 @@ public class ShapeExporter {
case PNG:
case BMP:
case WEBP:
int newWidth = (int) (rect.getWidth() * settings.zoom / SWF.unitDivisor) + 1;
int newHeight = (int) (rect.getHeight() * settings.zoom / SWF.unitDivisor) + 1;
int realAaScale = Configuration.calculateRealAaScale(rect.getWidth(), rect.getHeight(), settings.zoom, aaScale);
int newWidth = (int) (rect.getWidth() * settings.zoom * realAaScale / SWF.unitDivisor) + 1;
int newHeight = (int) (rect.getHeight() * settings.zoom * realAaScale / SWF.unitDivisor) + 1;
SerializableImage img = new SerializableImage(newWidth, newHeight, SerializableImage.TYPE_INT_ARGB_PRE);
img.fillTransparent();
if (settings.mode == ShapeExportMode.BMP) {
@@ -135,16 +139,30 @@ public class ShapeExporter {
g.setColor(backColor.toColor());
g.fillRect(0, 0, img.getWidth(), img.getHeight());
}
}
st.toImage(0, 0, 0, new RenderContext(), img, img, false, m, m, m, m, new CXFORMWITHALPHA(), unzoom, false, new ExportRectangle(rect), new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, true);
}
Matrix m2 = Matrix.getScaleInstance(settings.zoom * realAaScale);
m2.translate(-rect.Xmin, -rect.Ymin);
st.toImage(0, 0, 0, new RenderContext(), img, img, false, m2, m2, m2, m2, new CXFORMWITHALPHA(), unzoom * realAaScale, false, new ExportRectangle(rect), new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL, 0, true, realAaScale);
BufferedImage bim = img.getBufferedImage();
if (realAaScale > 1) {
SerializableImage img2 = new SerializableImage(((newWidth - 1) / realAaScale) + 1,
((newHeight - 1) / realAaScale) + 1, SerializableImage.TYPE_INT_ARGB_PRE);
img2.fillTransparent();
Graphics g2 = img2.getGraphics();
g2.drawImage(img.getBufferedImage().getScaledInstance(img2.getWidth(), img2.getHeight(), Image.SCALE_SMOOTH), 0, 0, null);
bim = img2.getBufferedImage();
}
if (settings.mode == ShapeExportMode.PNG) {
ImageHelper.write(img.getBufferedImage(), ImageFormat.PNG, file);
ImageHelper.write(bim, ImageFormat.PNG, file);
} else if (settings.mode == ShapeExportMode.WEBP) {
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(WebPCodec.encodeLosslessImage(img.getBufferedImage()));
fos.write(WebPCodec.encodeLosslessImage(bim));
}
} else {
BMPFile.saveBitmap(img.getBufferedImage(), file);
BMPFile.saveBitmap(bim, file);
}
break;
case CANVAS:

View File

@@ -39,14 +39,21 @@ public class ButtonExportSettings {
* Zoom
*/
public double zoom;
/**
* Antialias conflation reducing scale coefficient
*/
public int aaScale;
/**
* Constructor.
* @param mode Mode
* @param zoom Zoom
* @param aaScale Antialias conflation reducing scale coefficient
*/
public ButtonExportSettings(ButtonExportMode mode, double zoom) {
public ButtonExportSettings(ButtonExportMode mode, double zoom, int aaScale) {
this.mode = mode;
this.zoom = zoom;
this.aaScale = aaScale;
}
}

View File

@@ -44,16 +44,23 @@ public class FrameExportSettings {
* Transparent background
*/
public boolean transparentBackground;
/**
* Antialias conflation reducing scale coefficient
*/
public int aaScale;
/**
* Constructor.
* @param mode Mode
* @param zoom Zoom
* @param transparentBackground Transparent background
* @param aaScale Antialias conflation reducing scale coefficient
*/
public FrameExportSettings(FrameExportMode mode, double zoom, boolean transparentBackground) {
public FrameExportSettings(FrameExportMode mode, double zoom, boolean transparentBackground, int aaScale) {
this.mode = mode;
this.zoom = zoom;
this.transparentBackground = transparentBackground;
this.aaScale = aaScale;
}
}

View File

@@ -39,15 +39,22 @@ public class MorphShapeExportSettings {
* Zoom
*/
public double zoom;
/**
* Antialias conflation reducing scale coefficient
*/
public int aaScale;
/**
* Constructor.
* @param mode Mode
* @param zoom Zoom
* @param aaScale Antialias conflation reducing scale coefficient
*/
public MorphShapeExportSettings(MorphShapeExportMode mode, double zoom) {
public MorphShapeExportSettings(MorphShapeExportMode mode, double zoom, int aaScale) {
this.mode = mode;
this.zoom = zoom;
this.aaScale = aaScale;
}
/**

View File

@@ -39,14 +39,21 @@ public class SpriteExportSettings {
* Zoom
*/
public double zoom;
/**
* Antialias conflation reducing scale coefficient
*/
public int aaScale;
/**
* Constructor.
* @param mode Mode
* @param zoom Zoom
* @param aaScale Antialias conflation reducing scale coefficient
*/
public SpriteExportSettings(SpriteExportMode mode, double zoom) {
public SpriteExportSettings(SpriteExportMode mode, double zoom, int aaScale) {
this.mode = mode;
this.zoom = zoom;
this.aaScale = aaScale;
}
}

View File

@@ -101,6 +101,8 @@ public class BitmapExporter extends ShapeExporterBase {
private double thicknessScaleY;
private double unzoom;
private int aaScale;
private static boolean linearGradientColorWarningShown = false;
@@ -171,11 +173,12 @@ public class BitmapExporter extends ShapeExporterBase {
* @param colorTransform Color transform
* @param scaleStrokes Scale strokes
* @param canUseSmoothing Can use smoothing
* @param aaScale Antialias conflation reducing scale coefficient
*/
public static void export(int windingRule, int shapeNum, SWF swf, SHAPE shape, Color defaultColor, SerializableImage image, double unzoom, Matrix transformation, Matrix strokeTransformation, ColorTransform colorTransform, boolean scaleStrokes, boolean canUseSmoothing) {
public static void export(int windingRule, int shapeNum, SWF swf, SHAPE shape, Color defaultColor, SerializableImage image, double unzoom, Matrix transformation, Matrix strokeTransformation, ColorTransform colorTransform, boolean scaleStrokes, boolean canUseSmoothing, int aaScale) {
BitmapExporter exporter = new BitmapExporter(windingRule, shapeNum, swf, shape, defaultColor, colorTransform);
exporter.setCanUseSmoothing(canUseSmoothing);
exporter.exportTo(shapeNum, image, unzoom, transformation, strokeTransformation, scaleStrokes);
exporter.exportTo(shapeNum, image, unzoom, transformation, strokeTransformation, scaleStrokes, aaScale);
}
private BitmapExporter(int windingRule, int shapeNum, SWF swf, SHAPE shape, Color defaultColor, ColorTransform colorTransform) {
@@ -185,7 +188,7 @@ public class BitmapExporter extends ShapeExporterBase {
path = new GeneralPath(windingRule == ShapeTag.WIND_NONZERO ? GeneralPath.WIND_NON_ZERO : GeneralPath.WIND_EVEN_ODD);
}
private void exportTo(int shapeNum, 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, int aaScale) {
this.image = image;
this.scaleStrokes = scaleStrokes;
ExportRectangle bounds = new ExportRectangle(shape.getBounds(shapeNum));
@@ -198,6 +201,7 @@ public class BitmapExporter extends ShapeExporterBase {
graphics.setTransform(at);
defaultStroke = graphics.getStroke();
this.unzoom = unzoom;
this.aaScale = aaScale;
super.export();
}
@@ -411,8 +415,8 @@ public class BitmapExporter extends ShapeExporterBase {
}
//always display minimum stroke of 1 pixel, no matter how zoomed it is
if (thickness * unzoom < 1 * SWF.unitDivisor) {
thickness = 1 * SWF.unitDivisor / unzoom;
if (thickness * unzoom / aaScale < 1 * SWF.unitDivisor) {
thickness = 1 * SWF.unitDivisor / (unzoom / aaScale);
}
/*

View File

@@ -1480,7 +1480,7 @@ public class SvgImporter {
st = (DefineShape4Tag) (new SvgImporter().importSvg(st, svgDataS, false));
swf.addTag(st);
SerializableImage si = new SerializableImage(480, 360, BufferedImage.TYPE_4BYTE_ABGR);
BitmapExporter.export(st.getWindingRule(), st.getShapeNum(), swf, st.shapes, Color.yellow, si, 1, new Matrix(), new Matrix(), null, true, true);
BitmapExporter.export(st.getWindingRule(), st.getShapeNum(), swf, st.shapes, Color.yellow, si, 1, new Matrix(), new Matrix(), null, true, true, 1);
List<Tag> li = new ArrayList<>();
li.add(st);
ImageIO.write(si.getBufferedImage(), "PNG", new File(name + ".imported.png"));
@@ -1491,7 +1491,7 @@ public class SvgImporter {
swf.assignExportNamesToSymbols();
st.shapeBounds.Xmax = (int) (si.getWidth() * SWF.unitDivisor);
st.shapeBounds.Ymax = (int) (si.getHeight() * SWF.unitDivisor);
new ShapeExporter().exportShapes(null, "./outex/", swf, new ReadOnlyTagList(li), new ShapeExportSettings(ShapeExportMode.SVG, 1), null, 1);
new ShapeExporter().exportShapes(null, "./outex/", swf, new ReadOnlyTagList(li), new ShapeExportSettings(ShapeExportMode.SVG, 1), null, 1, 1);
}
/**

View File

@@ -1278,8 +1278,8 @@ public class DefineEditTextTag extends TextTag {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) {
render(TextRenderMode.BITMAP, image, null, null, transformation, colorTransform, 1, renderContext.selectionText == this ? renderContext.selectionStart : 0, renderContext.selectionText == this ? renderContext.selectionEnd : 0);
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing, int aaScale) {
render(TextRenderMode.BITMAP, image, null, null, transformation, colorTransform, 1, renderContext.selectionText == this ? renderContext.selectionStart : 0, renderContext.selectionText == this ? renderContext.selectionEnd : 0, aaScale);
}
@Override
@@ -1287,25 +1287,25 @@ public class DefineEditTextTag extends TextTag {
int realTextId = getSwf().getCharacterId(this);
if (exporter.getNormalizedTexts().containsKey(realTextId) && exporter.getNormalizedTexts().get(realTextId) instanceof DefineEditTextTag) {
DefineEditTextTag normalizedText = (DefineEditTextTag) exporter.getNormalizedTexts().get(realTextId);
normalizedText.render(TextRenderMode.SVG, null, exporter, null, new Matrix(), colorTransform, 1, 0, 0);
normalizedText.render(TextRenderMode.SVG, null, exporter, null, new Matrix(), colorTransform, 1, 0, 0, 1);
return;
}
render(TextRenderMode.SVG, null, exporter, null, new Matrix(), colorTransform, 1, 0, 0);
render(TextRenderMode.SVG, null, exporter, null, new Matrix(), colorTransform, 1, 0, 0, 1);
}
@Override
public void toHtmlCanvas(StringBuilder result, double unitDivisor) {
render(TextRenderMode.HTML5_CANVAS, null, null, result, new Matrix(), null, unitDivisor, 0, 0);
render(TextRenderMode.HTML5_CANVAS, null, null, result, new Matrix(), null, unitDivisor, 0, 0, 1);
}
private void render(TextRenderMode renderMode, SerializableImage image, SVGExporter svgExporter, StringBuilder htmlCanvasBuilder, Matrix transformation, ColorTransform colorTransform, double zoom, int selectionStart, int selectionEnd) {
private void render(TextRenderMode renderMode, SerializableImage image, SVGExporter svgExporter, StringBuilder htmlCanvasBuilder, Matrix transformation, ColorTransform colorTransform, double zoom, int selectionStart, int selectionEnd, int aaScale) {
if (image != null && image.getGraphics() instanceof RequiresNormalizedFonts) {
RequiresNormalizedFonts g = (RequiresNormalizedFonts) image.getGraphics();
Map<Integer, TextTag> normalizedTexts = g.getNormalizedTexts();
int realTextId = getSwf().getCharacterId(this);
if (normalizedTexts.containsKey(realTextId) && normalizedTexts.get(realTextId) instanceof DefineEditTextTag && normalizedTexts.get(realTextId) != this) {
DefineEditTextTag normalizedText = (DefineEditTextTag) normalizedTexts.get(realTextId);
normalizedText.render(renderMode, image, svgExporter, htmlCanvasBuilder, transformation, colorTransform, zoom, selectionStart, selectionEnd);
normalizedText.render(renderMode, image, svgExporter, htmlCanvasBuilder, transformation, colorTransform, zoom, selectionStart, selectionEnd, aaScale);
return;
}
}
@@ -1315,7 +1315,7 @@ public class DefineEditTextTag extends TextTag {
RGB fillColor = new RGBA(Color.white);
switch (renderMode) {
case BITMAP:
drawBorder(swf, image, borderColor, fillColor, getRect(), getTextMatrix(), transformation, colorTransform);
drawBorder(swf, image, borderColor, fillColor, getRect(), getTextMatrix(), transformation, colorTransform, aaScale);
break;
case HTML5_CANVAS:
drawBorderHtmlCanvas(swf, htmlCanvasBuilder, borderColor, fillColor, getRect(), getTextMatrix(), colorTransform, zoom);
@@ -1329,7 +1329,7 @@ public class DefineEditTextTag extends TextTag {
List<TEXTRECORD> allTextRecords = getTextRecords(swf);
switch (renderMode) {
case BITMAP:
staticTextToImage(swf, allTextRecords, 2, image, getTextMatrix(), transformation, colorTransform, selectionStart, selectionEnd);
staticTextToImage(swf, allTextRecords, 2, image, getTextMatrix(), transformation, colorTransform, selectionStart, selectionEnd, aaScale);
break;
case HTML5_CANVAS:
staticTextToHtmlCanvas(zoom, swf, allTextRecords, 2, htmlCanvasBuilder, getBounds(), getTextMatrix(), colorTransform);

View File

@@ -461,8 +461,8 @@ public class DefineSpriteTag extends DrawableTag implements Timelined {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) {
getTimeline().toImage(frame, time, renderContext, image, fullImage, isClip, transformation, strokeTransformation, absoluteTransformation, colorTransform, unzoom, sameImage, viewRect, viewRectRaw, fullTransformation, scaleStrokes, drawMode, blendMode, canUseSmoothing, new ArrayList<>());
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing, int aaScale) {
getTimeline().toImage(frame, time, renderContext, image, fullImage, isClip, transformation, strokeTransformation, absoluteTransformation, colorTransform, unzoom, sameImage, viewRect, viewRectRaw, fullTransformation, scaleStrokes, drawMode, blendMode, canUseSmoothing, new ArrayList<>(), aaScale);
}
@Override

View File

@@ -338,7 +338,7 @@ public class DefineVideoStreamTag extends DrawableTag implements BoundedTag, Tim
}
@Override
public synchronized 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, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) {
public synchronized 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, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing, int aaScale) {
if (renderingPaused || !SimpleMediaPlayer.isAvailable()) {
Graphics2D g = (Graphics2D) image.getBufferedImage().getGraphics();

View File

@@ -126,8 +126,8 @@ public abstract class ButtonTag extends DrawableTag implements Timelined {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) {
getTimeline().toImage(frame, time, renderContext, image, fullImage, isClip, transformation, strokeTransformation, absoluteTransformation, colorTransform, unzoom, sameImage, viewRect, viewRectRaw, fullTransformation, scaleStrokes, drawMode, blendMode, canUseSmoothing, new ArrayList<>());
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing, int aaScale) {
getTimeline().toImage(frame, time, renderContext, image, fullImage, isClip, transformation, strokeTransformation, absoluteTransformation, colorTransform, unzoom, sameImage, viewRect, viewRectRaw, fullTransformation, scaleStrokes, drawMode, blendMode, canUseSmoothing, new ArrayList<>(), aaScale);
}
@Override

View File

@@ -104,8 +104,9 @@ public abstract class DrawableTag extends CharacterTag implements BoundedTag {
* @param drawMode Draw mode
* @param blendMode Blend mode
* @param canUseSmoothing Can use smoothing
* @param aaScale Antialias conflation reducing scale coefficient
*/
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, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing);
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, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing, int aaScale);
/**
* Converts the drawable to SVG.

View File

@@ -719,7 +719,7 @@ public abstract class FontTag extends DrawableTag implements AloneTag {
}
@Override
public synchronized void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) {
public synchronized void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing, int aaScale) {
SHAPERECORD.shapeListToImage(ShapeTag.WIND_EVEN_ODD, 1, swf, getGlyphShapeTable(), image, frame, Color.black, colorTransform);
}

View File

@@ -341,8 +341,8 @@ public abstract class ImageTag extends DrawableTag {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) {
BitmapExporter.export(ShapeTag.WIND_EVEN_ODD, 1, swf, getShape(1), null, image, unzoom, transformation, strokeTransformation, colorTransform, true, canUseSmoothing);
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing, int aaScale) {
BitmapExporter.export(ShapeTag.WIND_EVEN_ODD, 1, swf, getShape(1), null, image, unzoom, transformation, strokeTransformation, colorTransform, true, canUseSmoothing, aaScale);
}
@Override

View File

@@ -410,13 +410,13 @@ public abstract class MorphShapeTag extends DrawableTag {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing, int aaScale) {
SHAPEWITHSTYLE shape = getShapeAtRatio(ratio);
// morphShape using shapeNum=3, morphShape2 using shapeNum=4
// todo: Currently the generated image is not cached, because the cache
// key contains the hashCode of the finalRecord object, and it is always
// recreated
BitmapExporter.export(ShapeTag.WIND_EVEN_ODD /*??? FIXME*/, getShapeNum() == 2 ? 4 : 1, swf, shape, null, image, unzoom, transformation, strokeTransformation, colorTransform, scaleStrokes, canUseSmoothing);
BitmapExporter.export(ShapeTag.WIND_EVEN_ODD /*??? FIXME*/, getShapeNum() == 2 ? 4 : 1, swf, shape, null, image, unzoom, transformation, strokeTransformation, colorTransform, scaleStrokes, canUseSmoothing, aaScale);
}
@Override

View File

@@ -233,8 +233,8 @@ public abstract class ShapeTag extends DrawableTag implements LazyObject {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) {
BitmapExporter.export(getWindingRule(), getShapeNum(), getSwf(), getShapes(), null, image, unzoom, transformation, strokeTransformation, colorTransform, scaleStrokes, canUseSmoothing);
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing, int aaScale) {
BitmapExporter.export(getWindingRule(), getShapeNum(), getSwf(), getShapes(), null, image, unzoom, transformation, strokeTransformation, colorTransform, scaleStrokes, canUseSmoothing, aaScale);
if (Configuration._debugMode.get()) { // show control points
List<GeneralPath> paths = PathExporter.export(getWindingRule(), getShapeNum(), swf, getShapes());
double[] coords = new double[6];

View File

@@ -1027,18 +1027,18 @@ public abstract class StaticTextTag extends TextTag {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing, int aaScale) {
if (image.getGraphics() instanceof RequiresNormalizedFonts) {
RequiresNormalizedFonts g = (RequiresNormalizedFonts) image.getGraphics();
Map<Integer, TextTag> normalizedTexts = g.getNormalizedTexts();
int realTextId = getSwf().getCharacterId(this);
if (normalizedTexts.containsKey(realTextId) && normalizedTexts.get(realTextId) instanceof StaticTextTag) {
StaticTextTag normalizedText = (StaticTextTag) normalizedTexts.get(realTextId);
staticTextToImage(swf, normalizedText.textRecords, getTextNum(), image, normalizedText.textMatrix, transformation, colorTransform, renderContext.selectionText == this ? renderContext.selectionStart : 0, renderContext.selectionText == this ? renderContext.selectionEnd : 0);
staticTextToImage(swf, normalizedText.textRecords, getTextNum(), image, normalizedText.textMatrix, transformation, colorTransform, renderContext.selectionText == this ? renderContext.selectionStart : 0, renderContext.selectionText == this ? renderContext.selectionEnd : 0, aaScale);
return;
}
}
staticTextToImage(swf, textRecords, getTextNum(), image, textMatrix, transformation, colorTransform, renderContext.selectionText == this ? renderContext.selectionStart : 0, renderContext.selectionText == this ? renderContext.selectionEnd : 0);
staticTextToImage(swf, textRecords, getTextNum(), image, textMatrix, transformation, colorTransform, renderContext.selectionText == this ? renderContext.selectionStart : 0, renderContext.selectionText == this ? renderContext.selectionEnd : 0, aaScale);
/*try {
TextTag originalTag = (TextTag) getOriginalTag();
if (isModified()) {

View File

@@ -610,11 +610,11 @@ public abstract class TextTag extends DrawableTag {
* @param transformation Transformation
* @param colorTransform Color transform
*/
public static void drawBorder(SWF swf, SerializableImage image, RGB borderColor, RGB fillColor, RECT rect, MATRIX textMatrix, Matrix transformation, ColorTransform colorTransform) {
public static void drawBorder(SWF swf, SerializableImage image, RGB borderColor, RGB fillColor, RECT rect, MATRIX textMatrix, Matrix transformation, ColorTransform colorTransform, int aaScale) {
Graphics2D g = (Graphics2D) image.getGraphics();
Matrix mat = transformation.clone();
mat = mat.concatenate(new Matrix(textMatrix));
BitmapExporter.export(ShapeTag.WIND_EVEN_ODD, 1, swf, getBorderShape(borderColor, fillColor, rect), null, image, 1 /*FIXME??*/, mat, mat, colorTransform, true, false);
BitmapExporter.export(ShapeTag.WIND_EVEN_ODD, 1, swf, getBorderShape(borderColor, fillColor, rect), null, image, 1 /*FIXME??*/, mat, mat, colorTransform, true, false, aaScale);
}
/**
@@ -674,7 +674,7 @@ public abstract class TextTag extends DrawableTag {
* @param selectionStart Selection start
* @param selectionEnd Selection end
*/
public static void staticTextToImage(SWF swf, List<TEXTRECORD> textRecords, int numText, SerializableImage image, MATRIX textMatrix, Matrix transformation, ColorTransform colorTransform, int selectionStart, int selectionEnd) {
public static void staticTextToImage(SWF swf, List<TEXTRECORD> textRecords, int numText, SerializableImage image, MATRIX textMatrix, Matrix transformation, ColorTransform colorTransform, int selectionStart, int selectionEnd, int aaScale) {
if (image.getGraphics() instanceof GraphicsTextDrawable) {
//custom drawing
((GraphicsTextDrawable) image.getGraphics()).drawTextRecords(swf, textRecords, numText, textMatrix, transformation, colorTransform);
@@ -789,17 +789,17 @@ public abstract class TextTag extends DrawableTag {
//bounds.Ymin = (int) Math.round(-ascent);
//bounds.Ymax = (int) Math.round(descent + leading);
Matrix mat2 = Matrix.getTranslateInstance(bounds.Xmin, bounds.Ymin).preConcatenate(mat);
TextTag.drawBorder(swf, image, borderColor, fillColor, bounds, new MATRIX(), mat2, colorTransform);
TextTag.drawBorder(swf, image, borderColor, fillColor, bounds, new MATRIX(), mat2, colorTransform, aaScale);
}
if (shape != null) {
BitmapExporter.export(ShapeTag.WIND_EVEN_ODD, 1, swf, shape, pos >= selectionStart && pos < selectionEnd ? Color.white : textColor3, image, 1 /*FIXME??*/, mat, mat, colorTransform, true, false);
BitmapExporter.export(ShapeTag.WIND_EVEN_ODD, 1, swf, shape, pos >= selectionStart && pos < selectionEnd ? Color.white : textColor3, image, 1 /*FIXME??*/, mat, mat, colorTransform, true, false, aaScale);
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(1);
mat = Matrix.getTranslateInstance(bounds.Xmin, bounds.Ymin).preConcatenate(mat);
TextTag.drawBorder(swf, image, borderColor, fillColor, bounds, new MATRIX(), mat, colorTransform);
TextTag.drawBorder(swf, image, borderColor, fillColor, bounds, new MATRIX(), mat, colorTransform, aaScale);
}
}

View File

@@ -1068,8 +1068,9 @@ public class Timeline {
* @param scaleStrokes Scale strokes
* @param drawMode Draw mode
* @param canUseSmoothing Can use smoothing
* @param aaScale Antialias conflation reducing scale coefficient
*/
private void drawDrawable(SWF swf, Matrix strokeTransform, DepthState layer, Matrix layerMatrix, Graphics2D g, ColorTransform colorTransForm, int blendMode, int parentBlendMode, List<Clip> clips, Matrix transformation, boolean isClip, int clipDepth, Matrix absMat, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, DrawableTag drawable, List<FILTER> filters, double unzoom, ColorTransform mergedColorTransform, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, Matrix fullTransformation, boolean scaleStrokes, int drawMode, boolean canUseSmoothing) {
private void drawDrawable(SWF swf, Matrix strokeTransform, DepthState layer, Matrix layerMatrix, Graphics2D g, ColorTransform colorTransForm, int blendMode, int parentBlendMode, List<Clip> clips, Matrix transformation, boolean isClip, int clipDepth, Matrix absMat, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, DrawableTag drawable, List<FILTER> filters, double unzoom, ColorTransform mergedColorTransform, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, Matrix fullTransformation, boolean scaleStrokes, int drawMode, boolean canUseSmoothing, int aaScale) {
Matrix drawMatrix = new Matrix();
int drawableFrameCount = drawable.getNumFrames();
if (drawableFrameCount == 0) {
@@ -1412,7 +1413,7 @@ public class Timeline {
}
if (!(drawable instanceof ImageTag) || (swf.isAS3() && layer.hasImage)) {
drawable.toImage(dframe, dtime, ratio, renderContext, img, fullImage, isClip || clipDepth > -1, m, strokeTransform, absMat, mfull, mergedColorTransform2, unzoom, sameImage, viewRect2, viewRectRaw, scaleStrokes, drawMode, layer.blendMode, canUseSmoothing);
drawable.toImage(dframe, dtime, ratio, renderContext, img, fullImage, isClip || clipDepth > -1, m, strokeTransform, absMat, mfull, mergedColorTransform2, unzoom, sameImage, viewRect2, viewRectRaw, scaleStrokes, drawMode, layer.blendMode, canUseSmoothing, aaScale);
} else {
// todo: show one time warning
}
@@ -1596,8 +1597,9 @@ public class Timeline {
* @param blendMode Blend mode
* @param canUseSmoothing Can use smoothing
* @param ignoreDepths Ignore these depths when drawing
* @param aaScale Antialias conflation reducing scale coefficient
*/
public void toImage(int frame, int time, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, Matrix fullTransformation, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing, List<Integer> ignoreDepths) {
public void toImage(int frame, int time, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, ExportRectangle viewRectRaw, Matrix fullTransformation, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing, List<Integer> ignoreDepths, int aaScale) {
if (getFrameCount() <= frame) {
return;
}
@@ -1732,7 +1734,7 @@ public class Timeline {
Rectangle2D r = new Rectangle2D.Double(p1.xMin, p1.yMin, p1.getWidth(), p1.getHeight());
g.setClip(r);
drawDrawable(swf, strokeTransformation, layer, transforms[s], g, colorTransform, layer.blendMode, blendMode, clips, transformation, isClip, layer.clipDepth, absMat, layer.time + time, layer.ratio, renderContext, image, fullImage, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, viewRectRaw, fullTransformation, false, DRAW_MODE_SHAPES, canUseSmoothing);
drawDrawable(swf, strokeTransformation, layer, transforms[s], g, colorTransform, layer.blendMode, blendMode, clips, transformation, isClip, layer.clipDepth, absMat, layer.time + time, layer.ratio, renderContext, image, fullImage, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, viewRectRaw, fullTransformation, false, DRAW_MODE_SHAPES, canUseSmoothing, aaScale);
s++;
}
}
@@ -1741,13 +1743,13 @@ public class Timeline {
g.setTransform(origTransform);
//draw all nonshapes (normally scaled) next
drawDrawable(swf, strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, blendMode, clips, transformation, isClip, layer.clipDepth, absMat, layer.time + time, layer.ratio, renderContext, image, fullImage, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, viewRectRaw, fullTransformation, scaleStrokes, DRAW_MODE_SPRITES, canUseSmoothing);
drawDrawable(swf, strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, blendMode, clips, transformation, isClip, layer.clipDepth, absMat, layer.time + time, layer.ratio, renderContext, image, fullImage, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, viewRectRaw, fullTransformation, scaleStrokes, DRAW_MODE_SPRITES, canUseSmoothing, aaScale);
} else {
boolean subScaleStrokes = scaleStrokes;
if (character instanceof DefineSpriteTag) {
subScaleStrokes = true;
}
drawDrawable(swf, strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, blendMode, clips, transformation, isClip, layer.clipDepth, absMat, layer.time + time, layer.ratio, renderContext, image, fullImage, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, viewRectRaw, fullTransformation, subScaleStrokes, DRAW_MODE_ALL, canUseSmoothing);
drawDrawable(swf, strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, blendMode, clips, transformation, isClip, layer.clipDepth, absMat, layer.time + time, layer.ratio, renderContext, image, fullImage, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, viewRectRaw, fullTransformation, subScaleStrokes, DRAW_MODE_ALL, canUseSmoothing, aaScale);
}
} else if (character instanceof BoundedTag) {
showPlaceholder = true;

View File

@@ -283,14 +283,14 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali
Matrix transformation = Matrix.getTranslateInstance(px, py);
transformation.scale(ratio);
BitmapExporter.export(windingRule, shapeNum, swf, shape, color, image, 1 /*FIXME??*/, transformation, transformation, colorTransform, true, true);
BitmapExporter.export(windingRule, shapeNum, swf, shape, color, image, 1 /*FIXME??*/, transformation, transformation, colorTransform, true, true, 1 /*??*/);
// draw bounding boxes
if (DRAW_BOUNDING_BOX) {
RGB borderColor = new RGBA(Color.black);
RGB fillColor = new RGBA(new Color(255, 255, 255, 0));
transformation = Matrix.getTranslateInstance(bounds.Xmin, bounds.Ymin).preConcatenate(transformation);
TextTag.drawBorder(swf, image, borderColor, fillColor, bounds, new MATRIX(), transformation, colorTransform);
TextTag.drawBorder(swf, image, borderColor, fillColor, bounds, new MATRIX(), transformation, colorTransform, 1 /*??*/);
}
pos++;
}

View File

@@ -126,7 +126,7 @@ public class SerializableImage implements Serializable {
Graphics2D g = (Graphics2D) image.getGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
return graphics = g;
}