PDF vector export stub

This commit is contained in:
Jindra Petřík
2021-03-16 22:07:13 +01:00
parent 50bea979b4
commit 2d0a96be46
16 changed files with 612 additions and 45 deletions

View File

@@ -2903,7 +2903,7 @@ public final class SWF implements SWFContainerItem, Timelined {
RenderContext renderContext = new RenderContext();
renderContext.cursorPosition = cursorPosition;
renderContext.mouseButton = mouseButton;
timeline.toImage(frame, time, renderContext, image, false, m, new Matrix(), m, colorTransform, zoom);
timeline.toImage(frame, time, renderContext, image, false, m, new Matrix(), m, colorTransform, zoom, false);
return image;
}

View File

@@ -0,0 +1,460 @@
package com.jpexs.decompiler.flash.exporters;
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ImageObserver;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderableImage;
import java.text.AttributedCharacterIterator;
import java.util.Map;
/**
*
* @author JPEXS
*/
public class DualGraphics2D extends Graphics2D {
private final Graphics2D first;
private final Graphics2D second;
public DualGraphics2D(Graphics2D first, Graphics2D second) {
this.first = first;
this.second = second;
}
@Override
public void draw(Shape s) {
first.draw(s);
second.draw(s);
}
@Override
public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) {
boolean ok1 = first.drawImage(img, xform, obs);
boolean ok2 = second.drawImage(img, xform, obs);
return ok1 && ok2; //?
}
@Override
public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) {
first.drawImage(img, op, x, y);
second.drawImage(img, op, x, y);
}
@Override
public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
first.drawRenderedImage(img, xform);
second.drawRenderedImage(img, xform);
}
@Override
public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
first.drawRenderableImage(img, xform);
second.drawRenderableImage(img, xform);
}
@Override
public void drawString(String str, int x, int y) {
first.drawString(str, x, y);
second.drawString(str, x, y);
}
@Override
public void drawString(String str, float x, float y) {
first.drawString(str, x, y);
second.drawString(str, x, y);
}
@Override
public void drawString(AttributedCharacterIterator iterator, int x, int y) {
first.drawString(iterator, x, y);
second.drawString(iterator, x, y);
}
@Override
public void drawString(AttributedCharacterIterator iterator, float x, float y) {
first.drawString(iterator, x, y);
second.drawString(iterator, x, y);
}
@Override
public void drawGlyphVector(GlyphVector g, float x, float y) {
first.drawGlyphVector(g, x, y);
second.drawGlyphVector(g, x, y);
}
@Override
public void fill(Shape s) {
first.fill(s);
second.fill(s);
}
@Override
public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
boolean ok1 = first.hit(rect, s, onStroke);
boolean ok2 = second.hit(rect, s, onStroke);
return ok1 && ok2; //?
}
@Override
public GraphicsConfiguration getDeviceConfiguration() {
return first.getDeviceConfiguration(); //?
}
@Override
public void setComposite(Composite comp) {
first.setComposite(comp);
second.setComposite(comp);
}
@Override
public void setPaint(Paint paint) {
first.setPaint(paint);
second.setPaint(paint);
}
@Override
public void setStroke(Stroke s) {
first.setStroke(s);
second.setStroke(s);
}
@Override
public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) {
first.setRenderingHint(hintKey, hintValue);
second.setRenderingHint(hintKey, hintValue);
}
@Override
public Object getRenderingHint(RenderingHints.Key hintKey) {
return first.getRenderingHint(hintKey); //?
}
@Override
public void setRenderingHints(Map<?, ?> hints) {
first.setRenderingHints(hints);
second.setRenderingHints(hints);
}
@Override
public void addRenderingHints(Map<?, ?> hints) {
first.addRenderingHints(hints);
second.addRenderingHints(hints);
}
@Override
public RenderingHints getRenderingHints() {
return first.getRenderingHints();
}
@Override
public void translate(int x, int y) {
first.translate(x, y);
second.translate(x, y);
}
@Override
public void translate(double tx, double ty) {
first.translate(tx, ty);
second.translate(tx, ty);
}
@Override
public void rotate(double theta) {
first.rotate(theta);
second.rotate(theta);
}
@Override
public void rotate(double theta, double x, double y) {
first.rotate(theta, x, y);
second.rotate(theta, x, y);
}
@Override
public void scale(double sx, double sy) {
first.scale(sx, sy);
second.scale(sx, sy);
}
@Override
public void shear(double shx, double shy) {
first.shear(shx, shy);
second.shear(shx, shy);
}
@Override
public void transform(AffineTransform Tx) {
first.transform(Tx);
second.transform(Tx);
}
@Override
public void setTransform(AffineTransform Tx) {
first.setTransform(Tx);
second.setTransform(Tx);
}
@Override
public AffineTransform getTransform() {
return first.getTransform();
}
@Override
public Paint getPaint() {
return first.getPaint();
}
@Override
public Composite getComposite() {
return first.getComposite();
}
@Override
public void setBackground(Color color) {
first.setBackground(color);
second.setBackground(color);
}
@Override
public Color getBackground() {
return first.getBackground();
}
@Override
public Stroke getStroke() {
return first.getStroke();
}
@Override
public void clip(Shape s) {
first.clip(s);
second.clip(s);
}
@Override
public FontRenderContext getFontRenderContext() {
return first.getFontRenderContext();
}
@Override
public Graphics create() {
return this; //?
}
@Override
public Color getColor() {
return first.getColor();
}
@Override
public void setColor(Color c) {
first.setColor(c);
second.setColor(c);
}
@Override
public void setPaintMode() {
first.setPaintMode();
second.setPaintMode();
}
@Override
public void setXORMode(Color c1) {
first.setXORMode(c1);
second.setXORMode(c1);
}
@Override
public Font getFont() {
return first.getFont();
}
@Override
public void setFont(Font font) {
first.setFont(font);
second.setFont(font);
}
@Override
public FontMetrics getFontMetrics(Font f) {
return first.getFontMetrics();
}
@Override
public Rectangle getClipBounds() {
return first.getClipBounds();
}
@Override
public void clipRect(int x, int y, int width, int height) {
first.clearRect(x, y, width, height);
second.clipRect(x, y, width, height);
}
@Override
public void setClip(int x, int y, int width, int height) {
first.setClip(x, y, width, height);
second.setClip(x, y, width, height);
}
@Override
public Shape getClip() {
return first.getClip();
}
@Override
public void setClip(Shape clip) {
first.setClip(clip);
if (clip == null) {
clip = new Rectangle2D.Double(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE); //?
}
second.setClip(clip);
}
@Override
public void copyArea(int x, int y, int width, int height, int dx, int dy) {
first.copyArea(x, y, width, height, dx, dy);
second.copyArea(x, y, width, height, dx, dy);
}
@Override
public void drawLine(int x1, int y1, int x2, int y2) {
first.drawLine(x1, y1, x2, y2);
second.drawLine(x1, y1, x2, y2);
}
@Override
public void fillRect(int x, int y, int width, int height) {
first.fillRect(x, y, width, height);
second.fillRect(x, y, width, height);
}
@Override
public void clearRect(int x, int y, int width, int height) {
first.clearRect(x, y, width, height);
second.clearRect(x, y, width, height);
}
@Override
public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
first.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
second.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
}
@Override
public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
first.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
second.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
}
@Override
public void drawOval(int x, int y, int width, int height) {
first.drawOval(x, y, width, height);
second.drawOval(x, y, width, height);
}
@Override
public void fillOval(int x, int y, int width, int height) {
first.fillOval(x, y, width, height);
second.fillOval(x, y, width, height);
}
@Override
public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
first.drawArc(x, y, width, height, startAngle, arcAngle);
second.drawArc(x, y, width, height, startAngle, arcAngle);
}
@Override
public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
first.fillArc(x, y, width, height, startAngle, arcAngle);
second.fillArc(x, y, width, height, startAngle, arcAngle);
}
@Override
public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) {
first.drawPolyline(xPoints, yPoints, nPoints);
second.drawPolyline(xPoints, yPoints, nPoints);
}
@Override
public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) {
first.drawPolyline(xPoints, yPoints, nPoints);
second.drawPolyline(xPoints, yPoints, nPoints);
}
@Override
public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) {
first.fillPolygon(xPoints, yPoints, nPoints);
second.fillPolygon(xPoints, yPoints, nPoints);
}
@Override
public boolean drawImage(Image img, int x, int y, ImageObserver observer) {
boolean ok1 = first.drawImage(img, x, y, observer);
boolean ok2 = second.drawImage(img, x, y, observer);
return ok1 && ok2;
}
@Override
public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) {
boolean ok1 = first.drawImage(img, x, y, width, height, observer);
boolean ok2 = second.drawImage(img, x, y, width, height, observer);
return ok1 && ok2;
}
@Override
public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) {
boolean ok1 = first.drawImage(img, x, y, bgcolor, observer);
boolean ok2 = second.drawImage(img, x, y, bgcolor, observer);
return ok1 && ok2;
}
@Override
public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) {
boolean ok1 = first.drawImage(img, x, y, width, height, bgcolor, observer);
boolean ok2 = second.drawImage(img, x, y, width, height, bgcolor, observer);
return ok1 && ok2;
}
@Override
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) {
boolean ok1 = first.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer);
boolean ok2 = second.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer);
return ok1 && ok2;
}
@Override
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) {
boolean ok1 = first.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bgcolor, observer);
boolean ok2 = second.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bgcolor, observer);
return ok1 && ok2;
}
@Override
public void dispose() {
first.dispose();
second.dispose();
}
}

View File

@@ -36,11 +36,14 @@ import com.jpexs.decompiler.flash.helpers.BMPFile;
import com.jpexs.decompiler.flash.helpers.ImageHelper;
import com.jpexs.decompiler.flash.tags.DefineEditTextTag;
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
import com.jpexs.decompiler.flash.tags.DefineText2Tag;
import com.jpexs.decompiler.flash.tags.DefineTextTag;
import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.tags.base.RenderContext;
import com.jpexs.decompiler.flash.tags.base.StaticTextTag;
import com.jpexs.decompiler.flash.tags.base.TextTag;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
@@ -65,13 +68,33 @@ import com.jpexs.decompiler.flash.types.filters.GRADIENTBEVELFILTER;
import com.jpexs.decompiler.flash.types.filters.GRADIENTGLOWFILTER;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.Path;
import com.jpexs.helpers.SerializableImage;
import com.jpexs.helpers.utf8.Utf8Helper;
import gnu.jpdf.PDFGraphics;
import gnu.jpdf.PDFJob;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ImageObserver;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderableImage;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.io.BufferedOutputStream;
@@ -80,6 +103,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.AttributedCharacterIterator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -469,13 +493,18 @@ public class FrameExporter {
PageFormat pf = new PageFormat();
pf.setOrientation(PageFormat.PORTRAIT);
Paper p = new Paper();
BufferedImage img = frameImages.next();
p.setSize(img.getWidth() + 10, img.getHeight() + 10);
pf.setPaper(p);
/*BufferedImage img = frameImages.next();
p.setSize(img.getWidth() + 10, img.getHeight() + 10);*/
int pos = 0;
RECT rect = tim.displayRect;
double w = (rect.getWidth() * settings.zoom / SWF.unitDivisor);
double h = (rect.getHeight() * settings.zoom / SWF.unitDivisor);
p.setSize(w + 10, h + 10);
pf.setPaper(p);
double zoom = settings.zoom;
Matrix m = new Matrix();
m.translate(-rect.Xmin * zoom, -rect.Ymin * zoom);
@@ -483,19 +512,59 @@ public class FrameExporter {
Matrix transformation = m;
Map<Integer, Font> existingFonts = new HashMap<>();
while (true) {
while (pos < fframes.size()) {
int fframe = fframes.get(pos);
Graphics2D g = (Graphics2D) job.getGraphics(pf);
g.drawImage(img, 5, 5, img.getWidth(), img.getHeight(), null);
final Graphics2D g = (Graphics2D) job.getGraphics(pf);
//g.drawImage(img, 5, 5, img.getWidth(), img.getHeight(), null);
printStringsToImage(existingFonts, g, fframe, swf, tim, transformation);
SerializableImage image = new SerializableImage((int) w + 1, (int) h + 1, SerializableImage.TYPE_INT_ARGB_PRE) {
private Graphics2D compositeGraphics;
@Override
public Graphics getGraphics() {
if (compositeGraphics != null) {
return compositeGraphics;
}
final Graphics2D parentGraphics = (Graphics2D) super.getGraphics();
compositeGraphics = new DualGraphics2D(parentGraphics, g);
return compositeGraphics;
}
@Override
public void fillTransparent() {
}
};
//if (backGroundColor == null) {
// image.fillTransparent();
int imgWidth = (int) (rect.getWidth() * zoom / SWF.unitDivisor) + 1;
int imgHeight = (int) (rect.getHeight() * zoom / SWF.unitDivisor) + 1;
if (!fusesTransparency && fbackgroundColor != null) {
g.setComposite(AlphaComposite.Src);
g.setColor(fbackgroundColor);
g.fill(new Rectangle(imgWidth, imgHeight));
}
RenderContext renderContext = new RenderContext();
renderContext.cursorPosition = new Point(-1, -1);
renderContext.mouseButton = 0;
renderContext.stateUnderCursor = new ArrayList<>();
try {
tim.toImage(fframe, fframe, renderContext, image, false, m, new Matrix(), m, null, zoom, true);
} catch (Exception ex) {
ex.printStackTrace();
}
//printStringsToImage(existingFonts, g, fframe, swf, tim, transformation);
g.dispose();
if (frameImages.hasNext()) {
/*if (frameImages.hasNext()) {
img = frameImages.next();
} else {
break;
}
}*/
pos++;
}
@@ -538,12 +607,12 @@ public class FrameExporter {
Matrix layerMatrix = new Matrix(layer.matrix);
Matrix absMat = absoluteTransformation.concatenate(layerMatrix);
if (character instanceof DrawableTag) {
printStringsDrawDrawable(existingFonts, g, swf, layerMatrix, transformation, absMat, time, layer.ratio, (DrawableTag) character, unzoom);
printStringsDrawDrawable(existingFonts, g, swf, layerMatrix, transformation, absMat, time, layer.ratio, (DrawableTag) character, unzoom, layer.colorTransForm);
}
}
}
private static void printStringsDrawDrawable(Map<Integer, Font> existingFonts, Graphics2D g, SWF swf, Matrix layerMatrix, Matrix transformation, Matrix absMat, int time, int ratio, DrawableTag drawable, double unzoom) {
private static void printStringsDrawDrawable(Map<Integer, Font> existingFonts, Graphics2D g, SWF swf, Matrix layerMatrix, Matrix transformation, Matrix absMat, int time, int ratio, DrawableTag drawable, double unzoom, ColorTransform colorTransform) {
int drawableFrameCount = drawable.getNumFrames();
if (drawableFrameCount == 0) {
drawableFrameCount = 1;
@@ -555,8 +624,7 @@ public class FrameExporter {
Matrix m = mat; //mat.preConcatenate(Matrix.getTranslateInstance(-rect.xMin, -rect.yMin));
if (drawable instanceof DefineSpriteTag) {
printStringsToImage(existingFonts, g, dframe, swf, ((Timelined) drawable).getTimeline(), m);
}
if (drawable instanceof TextTag) {
} else if (drawable instanceof TextTag) {
TextTag textTag = (TextTag) drawable;
List<TEXTRECORD> textRecords = new ArrayList<>();
@@ -579,7 +647,21 @@ public class FrameExporter {
int textHeight = 12;
int x = 0;
int y = 0;
int textColor = 0;
for (TEXTRECORD rec : textRecords) {
if (rec.styleFlagsHasColor) {
if (!(textTag instanceof DefineTextTag)) {
textColor = rec.textColorA.toInt();
} else {
textColor = rec.textColor.toInt();
}
if (colorTransform != null) {
textColor = colorTransform.apply(textColor);
}
}
if (rec.styleFlagsHasFont) {
font = swf.getFont(rec.fontId);
textHeight = rec.textHeight;
@@ -621,8 +703,12 @@ public class FrameExporter {
}
g2.setTransform(trans.toTransform());
g2.drawTransparentString(text.toString(), (float) x, (float) y);
Color textColor2 = new Color(textColor, true);
g2.setColor(textColor2);
g2.drawString(text.toString(), (float) x, (float) y);
}
} else {
}
}

View File

@@ -122,7 +122,7 @@ public class ShapeExporter {
}
Matrix m = Matrix.getScaleInstance(settings.zoom);
m.translate(-rect.Xmin, -rect.Ymin);
st.toImage(0, 0, 0, new RenderContext(), img, false, m, m, m, new CXFORMWITHALPHA(), unzoom);
st.toImage(0, 0, 0, new RenderContext(), img, false, m, m, m, new CXFORMWITHALPHA(), unzoom, false);
if (settings.mode == ShapeExportMode.PNG) {
ImageHelper.write(img.getBufferedImage(), ImageFormat.PNG, file);
} else {

View File

@@ -961,7 +961,7 @@ public class DefineEditTextTag extends TextTag {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage) {
render(TextRenderMode.BITMAP, image, null, null, transformation, colorTransform, 1);
}

View File

@@ -368,8 +368,8 @@ public class DefineSpriteTag extends DrawableTag implements Timelined {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom) {
getTimeline().toImage(frame, time, renderContext, image, isClip, transformation, strokeTransformation, absoluteTransformation, colorTransform, unzoom);
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage) {
getTimeline().toImage(frame, time, renderContext, image, isClip, transformation, strokeTransformation, absoluteTransformation, colorTransform, unzoom, sameImage);
}
@Override

View File

@@ -97,8 +97,8 @@ public abstract class ButtonTag extends DrawableTag implements Timelined {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom) {
getTimeline().toImage(frame, time, renderContext, image, isClip, transformation, strokeTransformation, absoluteTransformation, colorTransform, unzoom);
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage) {
getTimeline().toImage(frame, time, renderContext, image, isClip, transformation, strokeTransformation, absoluteTransformation, colorTransform, unzoom, sameImage);
}
@Override

View File

@@ -45,7 +45,7 @@ public abstract class DrawableTag extends CharacterTag implements BoundedTag {
public abstract Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked);
public abstract void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix prevTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom);
public abstract void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix prevTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage);
public abstract void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException;

View File

@@ -417,7 +417,7 @@ public abstract class FontTag extends DrawableTag implements AloneTag {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage) {
SHAPERECORD.shapeListToImage(swf, getGlyphShapeTable(), image, frame, Color.black, colorTransform);
}

View File

@@ -230,7 +230,7 @@ public abstract class ImageTag extends DrawableTag {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage) {
BitmapExporter.export(swf, getShape(), null, image, transformation, strokeTransformation, colorTransform);
}

View File

@@ -313,7 +313,7 @@ public abstract class MorphShapeTag extends DrawableTag {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage) {
SHAPEWITHSTYLE shape = getShapeAtRatio(ratio);
// morphShape using shapeNum=3, morphShape2 using shapeNum=4
// todo: Currently the generated image is not cached, because the cache

View File

@@ -171,7 +171,7 @@ public abstract class ShapeTag extends DrawableTag implements LazyObject {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage) {
BitmapExporter.export(swf, getShapes(), null, image, transformation, strokeTransformation, colorTransform);
if (Configuration._debugMode.get()) { // show control points
List<GeneralPath> paths = PathExporter.export(swf, getShapes());

View File

@@ -652,7 +652,7 @@ public abstract class StaticTextTag extends TextTag {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage) {
staticTextToImage(swf, textRecords, getTextNum(), image, textMatrix, transformation, colorTransform);
/*try {
TextTag originalTag = (TextTag) getOriginalTag();

View File

@@ -605,7 +605,7 @@ public class Timeline {
toImage(frame, time, renderContext, image, isClip, transforms[i], absoluteTransformation, colorTransform, targetRect[i]);
}
}*/
private void drawDrawable(Matrix strokeTransform, DepthState layer, Matrix layerMatrix, Graphics2D g, ColorTransform colorTransForm, int blendMode, List<Clip> clips, Matrix transformation, boolean isClip, int clipDepth, Matrix absMat, int time, int ratio, RenderContext renderContext, SerializableImage image, DrawableTag drawable, List<FILTER> filters, double unzoom, ColorTransform clrTrans) {
private void drawDrawable(Matrix strokeTransform, DepthState layer, Matrix layerMatrix, Graphics2D g, ColorTransform colorTransForm, int blendMode, List<Clip> clips, Matrix transformation, boolean isClip, int clipDepth, Matrix absMat, int time, int ratio, RenderContext renderContext, SerializableImage image, DrawableTag drawable, List<FILTER> filters, double unzoom, ColorTransform clrTrans, boolean sameImage) {
Matrix drawMatrix = new Matrix();
int drawableFrameCount = drawable.getNumFrames();
if (drawableFrameCount == 0) {
@@ -670,7 +670,10 @@ public class Timeline {
rect.xMin = Math.max(0, rect.xMin);
rect.yMin = Math.max(0, rect.yMin);
drawMatrix.translate(rect.xMin, rect.yMin);
drawMatrix.translateX /= SWF.unitDivisor;
drawMatrix.translateY /= SWF.unitDivisor;
boolean canUseSameImage = true;
if (img == null) {
int newWidth = (int) (rect.getWidth() / SWF.unitDivisor);
int newHeight = (int) (rect.getHeight() / SWF.unitDivisor);
@@ -704,9 +707,25 @@ public class Timeline {
}
}
if (filters != null && !filters.isEmpty()) {
canUseSameImage = false;
}
if (blendMode > 1) {
canUseSameImage = false;
}
if (clipDepth > -1) {
canUseSameImage = false;
}
img = new SerializableImage(newWidth, newHeight, SerializableImage.TYPE_INT_ARGB_PRE);
img.fillTransparent();
if (canUseSameImage && sameImage) {
img = image;
m = mat.clone();
//m = m.concatenate(drawMatrix);
}
ColorTransform clrTrans2 = clrTrans;
if (clipDepth > -1) {
//Make transparent colors opaque, mask should be only made by shapes
@@ -720,8 +739,9 @@ public class Timeline {
clrTrans2 = clrMask;
}
if (!(drawable instanceof ImageTag) || (swf.isAS3() && layer.hasImage)) {
drawable.toImage(dframe, time, ratio, renderContext, img, isClip || clipDepth > -1, m, strokeTransform, absMat, clrTrans2, unzoom);
drawable.toImage(dframe, time, ratio, renderContext, img, isClip || clipDepth > -1, m, strokeTransform, absMat, clrTrans2, unzoom, sameImage);
} else {
// todo: show one time warning
}
@@ -737,13 +757,11 @@ public class Timeline {
}
}
if (cacheAsBitmap && renderContext.displayObjectCache != null) {
if (!sameImage && cacheAsBitmap && renderContext.displayObjectCache != null) {
renderContext.displayObjectCache.put(layer.placeObjectTag, img);
}
}
drawMatrix.translateX /= SWF.unitDivisor;
drawMatrix.translateY /= SWF.unitDivisor;
AffineTransform trans = drawMatrix.toTransform();
switch (blendMode) {
@@ -830,12 +848,14 @@ public class Timeline {
g2.draw(shape);
}
g.setTransform(trans);
g.drawImage(img.getBufferedImage(), 0, 0, null);
if (!(sameImage && canUseSameImage)) {
g.setTransform(drawMatrix.toTransform());
g.drawImage(img.getBufferedImage(), 0, 0, null);
}
}
}
public void toImage(int frame, int time, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom) {
public void toImage(int frame, int time, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage) {
//double unzoom = SWF.unitDivisor;
//unzoom = SWF.unitDivisor;
if (getFrameCount() <= frame) {
@@ -849,8 +869,10 @@ public class Timeline {
// g.setClip(new Rectangle2D.Double(targetRect.xMin, targetRect.yMin, targetRect.getWidth(), targetRect.getHeight()));
//}
g.setPaint(frameObj.backgroundColor.toColor());
g.fill(new Rectangle(image.getWidth(), image.getHeight()));
if (!sameImage) {
g.setPaint(frameObj.backgroundColor.toColor());
g.fill(new Rectangle(image.getWidth(), image.getHeight()));
}
g.setTransform(transformation.toTransform());
List<Clip> clips = new ArrayList<>();
@@ -958,7 +980,7 @@ public class Timeline {
Rectangle2D r = new Rectangle2D.Double(p1.xMin, p1.yMin, p1.getWidth(), p1.getHeight());
g.setClip(r);
drawDrawable(strokeTransformation.preConcatenate(layerMatrix), layer, transforms[s], g, colorTransform, layer.blendMode, clips, transformation, isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, (DrawableTag) character, layer.filters, unzoom, clrTrans);
drawDrawable(strokeTransformation.preConcatenate(layerMatrix), layer, transforms[s], g, colorTransform, layer.blendMode, clips, transformation, isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage);
s++;
}
}
@@ -977,7 +999,7 @@ public class Timeline {
}*/
g.setTransform(origTransform);
} else {
drawDrawable(strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, clips, transformation, isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, (DrawableTag) character, layer.filters, unzoom, clrTrans);
drawDrawable(strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, clips, transformation, isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage);
}
} else if (character instanceof BoundedTag) {
showPlaceholder = true;
@@ -1000,8 +1022,7 @@ public class Timeline {
}
}
g.setTransform(
new AffineTransform());
g.setTransform(new AffineTransform());
g.setClip(prevClip);
}