mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-13 12:18:26 +00:00
Merge origin/master
Conflicts: libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ShapeImporter.java
This commit is contained in:
@@ -91,6 +91,7 @@ import com.jpexs.decompiler.flash.tags.FileAttributesTag;
|
||||
import com.jpexs.decompiler.flash.tags.JPEGTablesTag;
|
||||
import com.jpexs.decompiler.flash.tags.MetadataTag;
|
||||
import com.jpexs.decompiler.flash.tags.ProtectTag;
|
||||
import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
|
||||
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
|
||||
import com.jpexs.decompiler.flash.tags.SymbolClassTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
@@ -562,6 +563,16 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
return null;
|
||||
}
|
||||
|
||||
public SetBackgroundColorTag getBackgroundColor() {
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof SetBackgroundColorTag) {
|
||||
return (SetBackgroundColorTag) t;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public EnableTelemetryTag getEnableTelemetry() {
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof EnableTelemetryTag) {
|
||||
|
||||
@@ -538,6 +538,11 @@ public class Configuration {
|
||||
@ConfigurationCategory("import")
|
||||
public static final ConfigurationItem<Boolean> warningSvgImport = null;
|
||||
|
||||
@ConfigurationDefaultBoolean(false)
|
||||
@ConfigurationName("shapeImport.useNonSmoothedFill")
|
||||
@ConfigurationCategory("import")
|
||||
public static final ConfigurationItem<Boolean> shapeImportUseNonSmoothedFill = null;
|
||||
|
||||
private enum OSId {
|
||||
|
||||
WINDOWS, OSX, UNIX
|
||||
|
||||
@@ -34,7 +34,6 @@ import com.jpexs.decompiler.flash.helpers.BMPFile;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
|
||||
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.enums.ImageFormat;
|
||||
import com.jpexs.decompiler.flash.timeline.DepthState;
|
||||
@@ -173,13 +172,9 @@ public class FrameExporter {
|
||||
final List<Integer> fframes = frames;
|
||||
|
||||
Color backgroundColor = null;
|
||||
if (settings.mode == FrameExportMode.AVI) {
|
||||
for (Tag t : swf.tags) {
|
||||
if (t instanceof SetBackgroundColorTag) {
|
||||
SetBackgroundColorTag sb = (SetBackgroundColorTag) t;
|
||||
backgroundColor = sb.backgroundColor.toColor();
|
||||
}
|
||||
}
|
||||
SetBackgroundColorTag setBgColorTag = swf.getBackgroundColor();
|
||||
if (setBgColorTag != null) {
|
||||
backgroundColor = setBgColorTag.backgroundColor.toColor();
|
||||
}
|
||||
|
||||
if (settings.mode == FrameExportMode.SVG) {
|
||||
@@ -189,7 +184,7 @@ public class FrameExporter {
|
||||
}
|
||||
|
||||
final int fi = i;
|
||||
final Color fbackgroundColor = backgroundColor;
|
||||
final Color fbackgroundColor = null;
|
||||
new RetryTask(() -> {
|
||||
int frame = fframes.get(fi);
|
||||
File f = new File(foutdir + File.separator + frame + ".svg");
|
||||
@@ -223,7 +218,7 @@ public class FrameExporter {
|
||||
}
|
||||
|
||||
final Timeline ftim = tim;
|
||||
final Color fbackgroundColor = backgroundColor;
|
||||
final Color fbackgroundColor = null;
|
||||
final SWF fswf = swf;
|
||||
new RetryTask(() -> {
|
||||
File fcanvas = new File(foutdir + File.separator + "canvas.js");
|
||||
@@ -259,11 +254,8 @@ public class FrameExporter {
|
||||
}
|
||||
sb.append("\r\n");
|
||||
RGB backgroundColor1 = new RGB(255, 255, 255);
|
||||
for (Tag t : fswf.tags) {
|
||||
if (t instanceof SetBackgroundColorTag) {
|
||||
SetBackgroundColorTag sbgct = (SetBackgroundColorTag) t;
|
||||
backgroundColor1 = sbgct.backgroundColor;
|
||||
}
|
||||
if (setBgColorTag != null) {
|
||||
backgroundColor1 = setBgColorTag.backgroundColor;
|
||||
}
|
||||
|
||||
sb.append("var backgroundColor = \"").append(backgroundColor1.toHexRGB()).append("\";\r\n");
|
||||
|
||||
@@ -247,6 +247,13 @@ public final class Matrix implements Cloneable {
|
||||
transformStr = transformStr.substring(funcName.length() + 1);
|
||||
String params = transformStr.split("\\)")[0];
|
||||
transformStr = transformStr.substring(params.length() + 1);
|
||||
while (params.contains(" ")) {
|
||||
params = params.replaceAll(" ", " ");
|
||||
}
|
||||
|
||||
params = params.trim();
|
||||
params = params.replace(", ", ",");
|
||||
params = params.replace(" ", ",");
|
||||
String[] args = params.split(",");
|
||||
funcName = funcName.trim();
|
||||
switch (funcName) {
|
||||
|
||||
@@ -689,82 +689,58 @@ public class ShapeImporter {
|
||||
}
|
||||
|
||||
double rcp = Math.sqrt(4 - 2 * Math.sqrt(2));
|
||||
double delta = Math.PI / 4 / 45;
|
||||
if (deltaTheta > 0) {
|
||||
int segmentCount = (int) Math.ceil(deltaTheta / delta);
|
||||
double delta = Math.signum(deltaTheta) * Math.PI / 4;
|
||||
|
||||
double theta = theta1;
|
||||
int segmentCount = (int) Math.ceil(deltaTheta / delta);
|
||||
double theta = theta1;
|
||||
|
||||
PathCommand sera;
|
||||
for (int i = 0; i < segmentCount - 1; i++) {
|
||||
theta += delta;
|
||||
sera = new PathCommand();
|
||||
sera.command = 'L';
|
||||
double x12 = Math.cos(theta) * rx;
|
||||
double y12 = Math.sin(theta) * ry;
|
||||
x1Comma = Math.cos(fi) * x12 - Math.sin(fi) * y12;
|
||||
y1Comma = Math.sin(fi) * x12 + Math.cos(fi) * y12;
|
||||
sera.params = new double[]{cx + x1Comma, cy + y1Comma};
|
||||
pathCommands.add(sera);
|
||||
|
||||
/*sera = new PathCommand();
|
||||
sera.command = 'Q';
|
||||
double x12 = Math.cos(theta) * rx;
|
||||
double y12 = Math.sin(theta) * ry;
|
||||
x1Comma = Math.cos(fi) * x12 - Math.sin(fi) * y12;
|
||||
y1Comma = Math.sin(fi) * x12 + Math.cos(fi) * y12;
|
||||
|
||||
double theta2 = theta - Math.PI / 8;
|
||||
x12 = Math.cos(theta2) * rx * rcp;
|
||||
y12 = Math.sin(theta2) * ry * rcp;
|
||||
double x1Comma2 = Math.cos(fi) * x12 - Math.sin(fi) * y12;
|
||||
double y1Comma2 = Math.sin(fi) * x12 + Math.cos(fi) * y12;
|
||||
sera.params = new double[]{cx + x1Comma2, cy + y1Comma2, cx + x1Comma, cy + y1Comma};
|
||||
pathCommands.add(sera);*/
|
||||
}
|
||||
PathCommand sera;
|
||||
for (int i = 0; i < segmentCount - 1; i++) {
|
||||
theta += delta;
|
||||
/*sera = new PathCommand();
|
||||
sera.command = 'L';
|
||||
double x12 = Math.cos(theta) * rx;
|
||||
double y12 = Math.sin(theta) * ry;
|
||||
x1Comma = Math.cos(fi) * x12 - Math.sin(fi) * y12;
|
||||
y1Comma = Math.sin(fi) * x12 + Math.cos(fi) * y12;
|
||||
sera.params = new double[]{cx + x1Comma, cy + y1Comma};
|
||||
pathCommands.add(sera);*/
|
||||
|
||||
sera = new PathCommand();
|
||||
sera.command = 'L';
|
||||
sera.params = new double[]{x, y};
|
||||
pathCommands.add(sera);
|
||||
} else {
|
||||
int segmentCount = (int) Math.ceil(-deltaTheta / delta);
|
||||
sera.command = 'Q';
|
||||
double x12 = Math.cos(theta) * rx;
|
||||
double y12 = Math.sin(theta) * ry;
|
||||
x1Comma = Math.cos(fi) * x12 - Math.sin(fi) * y12;
|
||||
y1Comma = Math.sin(fi) * x12 + Math.cos(fi) * y12;
|
||||
|
||||
double theta = theta1;
|
||||
|
||||
PathCommand sera;
|
||||
for (int i = 0; i < segmentCount - 1; i++) {
|
||||
theta -= delta;
|
||||
sera = new PathCommand();
|
||||
sera.command = 'L';
|
||||
double x12 = Math.cos(theta) * rx;
|
||||
double y12 = Math.sin(theta) * ry;
|
||||
x1Comma = Math.cos(fi) * x12 - Math.sin(fi) * y12;
|
||||
y1Comma = Math.sin(fi) * x12 + Math.cos(fi) * y12;
|
||||
sera.params = new double[]{cx + x1Comma, cy + y1Comma};
|
||||
pathCommands.add(sera);
|
||||
|
||||
/*sera = new PathCommand();
|
||||
sera.command = 'Q';
|
||||
double x12 = Math.cos(theta) * rx;
|
||||
double y12 = Math.sin(theta) * ry;
|
||||
x1Comma = Math.cos(fi) * x12 - Math.sin(fi) * y12;
|
||||
y1Comma = Math.sin(fi) * x12 + Math.cos(fi) * y12;
|
||||
|
||||
double theta2 = theta + Math.PI / 8;
|
||||
x12 = Math.cos(theta2) * rx * rcp;
|
||||
y12 = Math.sin(theta2) * ry * rcp;
|
||||
double x1Comma2 = Math.cos(fi) * x12 - Math.sin(fi) * y12;
|
||||
double y1Comma2 = Math.sin(fi) * x12 + Math.cos(fi) * y12;
|
||||
sera.params = new double[]{cx + x1Comma2, cy + y1Comma2, cx + x1Comma, cy + y1Comma};
|
||||
pathCommands.add(sera);*/
|
||||
}
|
||||
|
||||
sera = new PathCommand();
|
||||
sera.command = 'L';
|
||||
sera.params = new double[]{x, y};
|
||||
double theta2 = theta - delta / 2;
|
||||
x12 = Math.cos(theta2) * rx * rcp;
|
||||
y12 = Math.sin(theta2) * ry * rcp;
|
||||
double x1Comma2 = Math.cos(fi) * x12 - Math.sin(fi) * y12;
|
||||
double y1Comma2 = Math.sin(fi) * x12 + Math.cos(fi) * y12;
|
||||
sera.params = new double[]{cx + x1Comma2, cy + y1Comma2, cx + x1Comma, cy + y1Comma};
|
||||
pathCommands.add(sera);
|
||||
}
|
||||
|
||||
sera = new PathCommand();
|
||||
sera.command = 'Q';
|
||||
|
||||
theta += delta;
|
||||
double diff = theta1 + deltaTheta - theta;
|
||||
diff = -delta - diff;
|
||||
theta = theta - delta - diff / 2;
|
||||
|
||||
double rcpm = 1 + (rcp - 1) * (diff / delta) * (diff / delta);
|
||||
double x12 = Math.cos(theta) * rx * rcpm;
|
||||
double y12 = Math.sin(theta) * ry * rcpm;
|
||||
x1Comma = Math.cos(fi) * x12 - Math.sin(fi) * y12;
|
||||
y1Comma = Math.sin(fi) * x12 + Math.cos(fi) * y12;
|
||||
sera.params = new double[]{cx + x1Comma, cy + y1Comma, x, y};
|
||||
pathCommands.add(sera);
|
||||
/*sera = new PathCommand();
|
||||
sera.command = 'L';
|
||||
sera.params = new double[]{x, y};
|
||||
pathCommands.add(sera);*/
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -787,12 +763,6 @@ public class ShapeImporter {
|
||||
processCommands(shapeNum, shapes, pathCommands, transform, style);
|
||||
}
|
||||
|
||||
private double[] getCoordinates() {
|
||||
//rx, -sqrt2Minus1RY,
|
||||
//sqrt2RXHalf, -sqrt2RYHalf,
|
||||
return null;
|
||||
}
|
||||
|
||||
private double calcAngle(double ux, double uy, double vx, double vy) {
|
||||
double lu = Math.sqrt(ux * ux + uy * uy);
|
||||
double lv = Math.sqrt(ux * ux + uy * uy);
|
||||
|
||||
@@ -149,15 +149,15 @@ public class PlaceObject2Tag extends PlaceObjectTypeTag implements ASMSourceCont
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
public PlaceObject2Tag(SWF swf, boolean placeFlagHasClipActions, boolean placeFlagHasClipDepth, boolean placeFlagHasName, boolean placeFlagHasRatio, boolean placeFlagHasColorTransform, boolean placeFlagHasMatrix, boolean placeFlagHasCharacter, boolean placeFlagMove, int depth, int characterId, MATRIX matrix, CXFORMWITHALPHA colorTransform, int ratio, String name, int clipDepth, CLIPACTIONS clipActions) {
|
||||
public PlaceObject2Tag(SWF swf, boolean placeFlagMove, int depth, int characterId, MATRIX matrix, CXFORMWITHALPHA colorTransform, int ratio, String name, int clipDepth, CLIPACTIONS clipActions) {
|
||||
super(swf, ID, NAME, null);
|
||||
this.placeFlagHasClipActions = placeFlagHasClipActions;
|
||||
this.placeFlagHasClipDepth = placeFlagHasClipDepth;
|
||||
this.placeFlagHasName = placeFlagHasName;
|
||||
this.placeFlagHasRatio = placeFlagHasRatio;
|
||||
this.placeFlagHasColorTransform = placeFlagHasColorTransform;
|
||||
this.placeFlagHasMatrix = placeFlagHasMatrix;
|
||||
this.placeFlagHasCharacter = placeFlagHasCharacter;
|
||||
this.placeFlagHasClipActions = clipActions != null;
|
||||
this.placeFlagHasClipDepth = clipDepth >= 0;
|
||||
this.placeFlagHasName = name != null;
|
||||
this.placeFlagHasRatio = ratio >= 0;
|
||||
this.placeFlagHasColorTransform = colorTransform != null;
|
||||
this.placeFlagHasMatrix = matrix != null;
|
||||
this.placeFlagHasCharacter = characterId >= 0;
|
||||
this.placeFlagMove = placeFlagMove;
|
||||
this.depth = depth;
|
||||
this.characterId = characterId;
|
||||
@@ -256,6 +256,11 @@ public class PlaceObject2Tag extends PlaceObjectTypeTag implements ASMSourceCont
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlaceObjectNum() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getClipDepth() {
|
||||
if (placeFlagHasClipDepth) {
|
||||
@@ -329,6 +334,11 @@ public class PlaceObject2Tag extends PlaceObjectTypeTag implements ASMSourceCont
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMatrix(MATRIX matrix) {
|
||||
this.matrix = matrix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstanceName() {
|
||||
if (placeFlagHasName) {
|
||||
|
||||
@@ -239,6 +239,38 @@ public class PlaceObject3Tag extends PlaceObjectTypeTag implements ASMSourceCont
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
public PlaceObject3Tag(SWF swf, boolean placeFlagMove, int depth, String className, int characterId, MATRIX matrix, CXFORMWITHALPHA colorTransform, int ratio, String name, int clipDepth, List<FILTER> surfaceFilterList, int blendMode, int bitmapCache, int visible, RGBA backgroundColor, CLIPACTIONS clipActions) {
|
||||
super(swf, ID, NAME, null);
|
||||
this.placeFlagHasClassName = className != null;
|
||||
this.placeFlagHasFilterList = surfaceFilterList != null;
|
||||
this.placeFlagHasBlendMode = blendMode >= 0;
|
||||
this.placeFlagHasCacheAsBitmap = bitmapCache >= 0;
|
||||
this.placeFlagHasVisible = visible >= 0;
|
||||
this.placeFlagOpaqueBackground = backgroundColor != null;
|
||||
this.placeFlagHasClipActions = clipActions != null;
|
||||
this.placeFlagHasClipDepth = clipDepth >= 0;
|
||||
this.placeFlagHasName = name != null;
|
||||
this.placeFlagHasRatio = ratio >= 0;
|
||||
this.placeFlagHasColorTransform = colorTransform != null;
|
||||
this.placeFlagHasMatrix = matrix != null;
|
||||
this.placeFlagHasCharacter = characterId >= 0;
|
||||
this.placeFlagMove = placeFlagMove;
|
||||
this.depth = depth;
|
||||
this.className = className;
|
||||
this.characterId = characterId;
|
||||
this.matrix = matrix;
|
||||
this.colorTransform = colorTransform;
|
||||
this.ratio = ratio;
|
||||
this.name = name;
|
||||
this.clipDepth = clipDepth;
|
||||
this.surfaceFilterList = surfaceFilterList;
|
||||
this.blendMode = blendMode;
|
||||
this.bitmapCache = bitmapCache;
|
||||
this.visible = visible;
|
||||
this.backgroundColor = backgroundColor;
|
||||
this.clipActions = clipActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -390,12 +422,8 @@ public class PlaceObject3Tag extends PlaceObjectTypeTag implements ASMSourceCont
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FILTER> getFilters() {
|
||||
if (placeFlagHasFilterList) {
|
||||
return surfaceFilterList;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
public int getPlaceObjectNum() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -406,6 +434,15 @@ public class PlaceObject3Tag extends PlaceObjectTypeTag implements ASMSourceCont
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FILTER> getFilters() {
|
||||
if (placeFlagHasFilterList) {
|
||||
return surfaceFilterList;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all sub-items
|
||||
*
|
||||
@@ -466,6 +503,11 @@ public class PlaceObject3Tag extends PlaceObjectTypeTag implements ASMSourceCont
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMatrix(MATRIX matrix) {
|
||||
this.matrix = matrix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstanceName() {
|
||||
if (placeFlagHasName) {
|
||||
|
||||
@@ -241,6 +241,39 @@ public class PlaceObject4Tag extends PlaceObjectTypeTag implements ASMSourceCont
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
public PlaceObject4Tag(SWF swf, boolean placeFlagMove, int depth, String className, int characterId, MATRIX matrix, CXFORMWITHALPHA colorTransform, int ratio, String name, int clipDepth, List<FILTER> surfaceFilterList, int blendMode, int bitmapCache, int visible, RGBA backgroundColor, CLIPACTIONS clipActions, byte[] amfData) {
|
||||
super(swf, ID, NAME, null);
|
||||
this.placeFlagHasClassName = className != null;
|
||||
this.placeFlagHasFilterList = surfaceFilterList != null;
|
||||
this.placeFlagHasBlendMode = blendMode >= 0;
|
||||
this.placeFlagHasCacheAsBitmap = bitmapCache >= 0;
|
||||
this.placeFlagHasVisible = visible >= 0;
|
||||
this.placeFlagOpaqueBackground = backgroundColor != null;
|
||||
this.placeFlagHasClipActions = clipActions != null;
|
||||
this.placeFlagHasClipDepth = clipDepth >= 0;
|
||||
this.placeFlagHasName = name != null;
|
||||
this.placeFlagHasRatio = ratio >= 0;
|
||||
this.placeFlagHasColorTransform = colorTransform != null;
|
||||
this.placeFlagHasMatrix = matrix != null;
|
||||
this.placeFlagHasCharacter = characterId >= 0;
|
||||
this.placeFlagMove = placeFlagMove;
|
||||
this.depth = depth;
|
||||
this.className = className;
|
||||
this.characterId = characterId;
|
||||
this.matrix = matrix;
|
||||
this.colorTransform = colorTransform;
|
||||
this.ratio = ratio;
|
||||
this.name = name;
|
||||
this.clipDepth = clipDepth;
|
||||
this.surfaceFilterList = surfaceFilterList;
|
||||
this.blendMode = blendMode;
|
||||
this.bitmapCache = bitmapCache;
|
||||
this.visible = visible;
|
||||
this.backgroundColor = backgroundColor;
|
||||
this.clipActions = clipActions;
|
||||
this.amfData = amfData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -394,12 +427,8 @@ public class PlaceObject4Tag extends PlaceObjectTypeTag implements ASMSourceCont
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FILTER> getFilters() {
|
||||
if (placeFlagHasFilterList) {
|
||||
return surfaceFilterList;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
public int getPlaceObjectNum() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -410,6 +439,15 @@ public class PlaceObject4Tag extends PlaceObjectTypeTag implements ASMSourceCont
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FILTER> getFilters() {
|
||||
if (placeFlagHasFilterList) {
|
||||
return surfaceFilterList;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all sub-items
|
||||
*
|
||||
@@ -470,6 +508,11 @@ public class PlaceObject4Tag extends PlaceObjectTypeTag implements ASMSourceCont
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMatrix(MATRIX matrix) {
|
||||
this.matrix = matrix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstanceName() {
|
||||
if (placeFlagHasName) {
|
||||
|
||||
@@ -127,8 +127,8 @@ public class PlaceObjectTag extends PlaceObjectTypeTag {
|
||||
public CXFORM colorTransform;
|
||||
|
||||
@Override
|
||||
public List<FILTER> getFilters() {
|
||||
return null;
|
||||
public int getPlaceObjectNum() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -136,6 +136,11 @@ public class PlaceObjectTag extends PlaceObjectTypeTag {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FILTER> getFilters() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
needed.add(characterId);
|
||||
@@ -172,6 +177,11 @@ public class PlaceObjectTag extends PlaceObjectTypeTag {
|
||||
return matrix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMatrix(MATRIX matrix) {
|
||||
this.matrix = matrix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstanceName() {
|
||||
return null;
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.tags.base;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.configuration.SwfSpecificConfiguration;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter;
|
||||
@@ -181,16 +182,30 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
|
||||
}
|
||||
|
||||
public String getSystemFontName() {
|
||||
Map<String, String> fontPairs = Configuration.getFontToNameMap();
|
||||
String key = swf.getShortFileName() + "_" + getFontId() + "_" + getFontNameIntag();
|
||||
if (fontPairs.containsKey(key)) {
|
||||
return fontPairs.get(key);
|
||||
int fontId = getFontId();
|
||||
String selectedFont = swf.sourceFontNamesMap.get(fontId);
|
||||
if (selectedFont == null) {
|
||||
SwfSpecificConfiguration swfConf = Configuration.getSwfSpecificConfiguration(swf.getShortFileName());
|
||||
String key = fontId + "_" + getFontNameIntag();
|
||||
if (swfConf != null) {
|
||||
selectedFont = swfConf.fontPairingMap.get(key);
|
||||
}
|
||||
}
|
||||
key = getFontNameIntag();
|
||||
if (fontPairs.containsKey(key)) {
|
||||
return fontPairs.get(key);
|
||||
|
||||
if (selectedFont == null) {
|
||||
selectedFont = Configuration.getFontToNameMap().get(getFontNameIntag());
|
||||
}
|
||||
return defaultFontName;
|
||||
|
||||
if (selectedFont != null && FontTag.installedFontsByName.containsKey(selectedFont)) {
|
||||
return selectedFont;
|
||||
}
|
||||
|
||||
// findInstalledFontName always returns an available font name
|
||||
return FontTag.findInstalledFontName(getFontName());
|
||||
}
|
||||
|
||||
public Font getSystemFont() {
|
||||
return FontTag.installedFontsByName.get(getSystemFontName());
|
||||
}
|
||||
|
||||
protected void shiftGlyphIndices(int fontId, int startIndex) {
|
||||
|
||||
@@ -207,7 +207,8 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag {
|
||||
shape.fillStyles = new FILLSTYLEARRAY();
|
||||
shape.fillStyles.fillStyles = new FILLSTYLE[1];
|
||||
FILLSTYLE fillStyle = new FILLSTYLE();
|
||||
fillStyle.fillStyleType = FILLSTYLE.REPEATING_BITMAP;
|
||||
fillStyle.fillStyleType = Configuration.shapeImportUseNonSmoothedFill.get()
|
||||
? FILLSTYLE.NON_SMOOTHED_REPEATING_BITMAP : FILLSTYLE.REPEATING_BITMAP;
|
||||
fillStyle.bitmapId = getCharacterId();
|
||||
MATRIX matrix = new MATRIX();
|
||||
matrix.hasScale = true;
|
||||
|
||||
@@ -38,10 +38,14 @@ public abstract class PlaceObjectTypeTag extends Tag implements CharacterIdTag {
|
||||
super(swf, id, name, data);
|
||||
}
|
||||
|
||||
public abstract int getPlaceObjectNum();
|
||||
|
||||
public abstract int getDepth();
|
||||
|
||||
public abstract MATRIX getMatrix();
|
||||
|
||||
public abstract void setMatrix(MATRIX matrix);
|
||||
|
||||
public abstract String getInstanceName();
|
||||
|
||||
public abstract void setInstanceName(String name);
|
||||
|
||||
@@ -261,6 +261,12 @@ public abstract class StaticTextTag extends TextTag {
|
||||
writer.append("font ").append(rec.fontId).newLine();
|
||||
writer.append("height ").append(rec.textHeight).newLine();
|
||||
}
|
||||
if (fnt != null) {
|
||||
int letterSpacing = detectLetterSpacing(rec, fnt, rec.textHeight);
|
||||
if (letterSpacing != 0) {
|
||||
writer.append("letterspacing ").append(letterSpacing).newLine();
|
||||
}
|
||||
}
|
||||
if (rec.styleFlagsHasColor) {
|
||||
if (getTextNum() == 1) {
|
||||
writer.append("color ").append(rec.textColor.toHexRGB()).newLine();
|
||||
@@ -296,8 +302,8 @@ public abstract class StaticTextTag extends TextTag {
|
||||
RGBA colorA = null;
|
||||
int fontId = -1;
|
||||
int textHeight = -1;
|
||||
int letterSpacing = 0;
|
||||
FontTag font = null;
|
||||
String fontName = null;
|
||||
Integer x = null;
|
||||
Integer y = null;
|
||||
int currentX = 0;
|
||||
@@ -342,7 +348,6 @@ public abstract class StaticTextTag extends TextTag {
|
||||
}
|
||||
|
||||
font = (FontTag) ft;
|
||||
fontName = font.getSystemFontName();
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new TextParseException("Invalid font id - number expected. Found: " + paramValue, lexer.yyline());
|
||||
}
|
||||
@@ -354,6 +359,13 @@ public abstract class StaticTextTag extends TextTag {
|
||||
throw new TextParseException("Invalid font height - number expected. Found: " + paramValue, lexer.yyline());
|
||||
}
|
||||
break;
|
||||
case "letterspacing":
|
||||
try {
|
||||
letterSpacing = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new TextParseException("Invalid font letter spacing - number expected. Found: " + paramValue, lexer.yyline());
|
||||
}
|
||||
break;
|
||||
case "x":
|
||||
try {
|
||||
x = Integer.parseInt(paramValue);
|
||||
@@ -527,17 +539,7 @@ public abstract class StaticTextTag extends TextTag {
|
||||
GLYPHENTRY ge = new GLYPHENTRY();
|
||||
ge.glyphIndex = font.charToGlyph(c);
|
||||
|
||||
int advance;
|
||||
if (font.hasLayout()) {
|
||||
int kerningAdjustment = 0;
|
||||
if (nextChar != null) {
|
||||
kerningAdjustment = font.getCharKerningAdjustment(c, nextChar);
|
||||
}
|
||||
advance = (int) Math.round(((double) textHeight * (font.getGlyphAdvance(ge.glyphIndex) + kerningAdjustment)) / (font.getDivider() * 1024.0));
|
||||
} else {
|
||||
advance = (int) Math.round(SWF.unitDivisor * FontTag.getSystemFontAdvance(fontName, font.getFontStyle(), (int) (textHeight / SWF.unitDivisor), c, nextChar));
|
||||
}
|
||||
|
||||
int advance = getAdvance(font, ge.glyphIndex, textHeight, c, nextChar) + letterSpacing;
|
||||
ge.glyphAdvance = advance;
|
||||
tr.glyphEntries.add(ge);
|
||||
|
||||
@@ -568,6 +570,42 @@ public abstract class StaticTextTag extends TextTag {
|
||||
return true;
|
||||
}
|
||||
|
||||
private int getAdvance(FontTag font, int glyphIndex, int textHeight, char c, Character nextChar) {
|
||||
int advance;
|
||||
if (font.hasLayout()) {
|
||||
int kerningAdjustment = 0;
|
||||
if (nextChar != null) {
|
||||
kerningAdjustment = font.getCharKerningAdjustment(c, nextChar);
|
||||
}
|
||||
advance = (int) Math.round(((double) textHeight * (font.getGlyphAdvance(glyphIndex) + kerningAdjustment)) / (font.getDivider() * 1024.0));
|
||||
} else {
|
||||
String fontName = font.getSystemFontName();
|
||||
advance = (int) Math.round(SWF.unitDivisor * FontTag.getSystemFontAdvance(fontName, font.getFontStyle(), (int) (textHeight / SWF.unitDivisor), c, nextChar));
|
||||
}
|
||||
|
||||
return advance;
|
||||
}
|
||||
|
||||
private int detectLetterSpacing(TEXTRECORD textRecord, FontTag font, int textHeight) {
|
||||
int totalLetterSpacing = 0;
|
||||
List<GLYPHENTRY> glyphEntries = textRecord.glyphEntries;
|
||||
for (int i = 0; i < glyphEntries.size(); i++) {
|
||||
GLYPHENTRY glyph = glyphEntries.get(i);
|
||||
GLYPHENTRY nextGlyph = null;
|
||||
if (i + 1 < glyphEntries.size()) {
|
||||
nextGlyph = glyphEntries.get(i + 1);
|
||||
}
|
||||
|
||||
char c = font.glyphToChar(glyph.glyphIndex);
|
||||
Character nextChar = nextGlyph == null ? null : font.glyphToChar(nextGlyph.glyphIndex);
|
||||
int advance = getAdvance(font, glyph.glyphIndex, textHeight, c, nextChar);
|
||||
int letterSpacing = glyph.glyphAdvance - advance;
|
||||
totalLetterSpacing += letterSpacing;
|
||||
}
|
||||
|
||||
return (int) Math.round(totalLetterSpacing / glyphEntries.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
for (TEXTRECORD tr : textRecords) {
|
||||
|
||||
@@ -17,8 +17,14 @@
|
||||
package com.jpexs.decompiler.flash.timeline;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.tags.PlaceObject2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.PlaceObject3Tag;
|
||||
import com.jpexs.decompiler.flash.tags.PlaceObject4Tag;
|
||||
import com.jpexs.decompiler.flash.tags.PlaceObjectTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
|
||||
import com.jpexs.decompiler.flash.types.CLIPACTIONS;
|
||||
import com.jpexs.decompiler.flash.types.CXFORM;
|
||||
import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RGBA;
|
||||
@@ -35,11 +41,11 @@ public class DepthState {
|
||||
|
||||
public int characterId = -1;
|
||||
|
||||
public MATRIX matrix = null;
|
||||
public MATRIX matrix;
|
||||
|
||||
public String instanceName = null;
|
||||
public String instanceName;
|
||||
|
||||
public ColorTransform colorTransForm = null;
|
||||
public ColorTransform colorTransForm;
|
||||
|
||||
public boolean cacheAsBitmap = false;
|
||||
|
||||
@@ -49,9 +55,11 @@ public class DepthState {
|
||||
|
||||
public boolean isVisible = true;
|
||||
|
||||
public RGBA backGroundColor = null;
|
||||
public RGBA backGroundColor;
|
||||
|
||||
public CLIPACTIONS clipActions = null;
|
||||
public CLIPACTIONS clipActions;
|
||||
|
||||
public byte[] amfData;
|
||||
|
||||
public int ratio = -1;
|
||||
|
||||
@@ -67,6 +75,8 @@ public class DepthState {
|
||||
|
||||
public PlaceObjectTypeTag placeObjectTag;
|
||||
|
||||
public int minPlaceObjectNum;
|
||||
|
||||
public long instanceId;
|
||||
|
||||
public boolean motionTween = false;
|
||||
@@ -100,6 +110,7 @@ public class DepthState {
|
||||
clipDepth = obj.clipDepth;
|
||||
time = obj.time;
|
||||
placeObjectTag = obj.placeObjectTag;
|
||||
minPlaceObjectNum = obj.minPlaceObjectNum;
|
||||
if (sameInstance) {
|
||||
time++;
|
||||
instanceId = obj.instanceId;
|
||||
@@ -107,4 +118,20 @@ public class DepthState {
|
||||
instanceId = getNewInstanceId();
|
||||
}
|
||||
}
|
||||
|
||||
public PlaceObjectTypeTag toPlaceObjectTag(int depth) {
|
||||
if (minPlaceObjectNum <= 1) {
|
||||
CXFORM cxForm0 = colorTransForm == null ? null : new CXFORM(colorTransForm);
|
||||
return new PlaceObjectTag(swf, characterId, depth, matrix, cxForm0);
|
||||
} else if (minPlaceObjectNum == 2) {
|
||||
CXFORMWITHALPHA cxForm = colorTransForm == null ? null : new CXFORMWITHALPHA(colorTransForm);
|
||||
return new PlaceObject2Tag(swf, false, depth, characterId, matrix, cxForm, ratio, instanceName, clipDepth, clipActions);
|
||||
} else if (minPlaceObjectNum == 3) {
|
||||
CXFORMWITHALPHA cxForm = colorTransForm == null ? null : new CXFORMWITHALPHA(colorTransForm);
|
||||
return new PlaceObject3Tag(swf, false, depth, null/*todo: className*/, characterId, matrix, cxForm, ratio, instanceName, clipDepth, filters, blendMode, cacheAsBitmap ? 1 : 0, isVisible ? 1 : 0, backGroundColor, clipActions);
|
||||
}
|
||||
|
||||
CXFORMWITHALPHA cxForm = colorTransForm == null ? null : new CXFORMWITHALPHA(colorTransForm);
|
||||
return new PlaceObject4Tag(swf, false, depth, null/*todo: className*/, characterId, matrix, cxForm, ratio, instanceName, clipDepth, filters, blendMode, cacheAsBitmap ? 1 : 0, isVisible ? 1 : 0, backGroundColor, clipActions, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,6 +263,7 @@ public class Timeline {
|
||||
}
|
||||
frame.layersChanged = true;
|
||||
fl.placeObjectTag = po;
|
||||
fl.minPlaceObjectNum = Math.max(fl.minPlaceObjectNum, po.getPlaceObjectNum());
|
||||
int characterId = po.getCharacterId();
|
||||
if (characterId != -1) {
|
||||
fl.characterId = characterId;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.types;
|
||||
|
||||
import com.jpexs.decompiler.flash.types.annotations.Calculated;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
|
||||
/**
|
||||
@@ -44,36 +45,42 @@ public class CXFORM extends ColorTransform {
|
||||
/**
|
||||
* Red multiply value
|
||||
*/
|
||||
@Conditional("hasMultTerms")
|
||||
@SWFType(value = BasicType.SB, countField = "nbits")
|
||||
public int redMultTerm;
|
||||
|
||||
/**
|
||||
* Green multiply value
|
||||
*/
|
||||
@Conditional("hasMultTerms")
|
||||
@SWFType(value = BasicType.SB, countField = "nbits")
|
||||
public int greenMultTerm;
|
||||
|
||||
/**
|
||||
* Blue multiply value
|
||||
*/
|
||||
@Conditional("hasMultTerms")
|
||||
@SWFType(value = BasicType.SB, countField = "nbits")
|
||||
public int blueMultTerm;
|
||||
|
||||
/**
|
||||
* Red addition value
|
||||
*/
|
||||
@Conditional("hasAddTerms")
|
||||
@SWFType(value = BasicType.SB, countField = "nbits")
|
||||
public int redAddTerm;
|
||||
|
||||
/**
|
||||
* Green addition value
|
||||
*/
|
||||
@Conditional("hasAddTerms")
|
||||
@SWFType(value = BasicType.SB, countField = "nbits")
|
||||
public int greenAddTerm;
|
||||
|
||||
/**
|
||||
* Blue addition value
|
||||
*/
|
||||
@Conditional("hasAddTerms")
|
||||
@SWFType(value = BasicType.SB, countField = "nbits")
|
||||
public int blueAddTerm;
|
||||
|
||||
@@ -107,6 +114,20 @@ public class CXFORM extends ColorTransform {
|
||||
return hasMultTerms ? blueMultTerm : super.getBlueMulti();
|
||||
}
|
||||
|
||||
public CXFORM() {
|
||||
}
|
||||
|
||||
public CXFORM(ColorTransform colorTransform) {
|
||||
redMultTerm = colorTransform.getRedMulti();
|
||||
greenMultTerm = colorTransform.getGreenMulti();
|
||||
blueMultTerm = colorTransform.getBlueMulti();
|
||||
redAddTerm = colorTransform.getRedAdd();
|
||||
greenAddTerm = colorTransform.getGreenAdd();
|
||||
blueAddTerm = colorTransform.getBlueAdd();
|
||||
hasAddTerms = redAddTerm != 0 || greenAddTerm != 0 || blueAddTerm != 0;
|
||||
hasMultTerms = redMultTerm != 255 || greenMultTerm != 255 || blueMultTerm != 255;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CXFORM clone() {
|
||||
CXFORM ret = (CXFORM) super.clone();
|
||||
|
||||
@@ -38,6 +38,10 @@ public class CXFORMWITHALPHA extends ColorTransform {
|
||||
*/
|
||||
public boolean hasMultTerms;
|
||||
|
||||
@Calculated
|
||||
@SWFType(value = BasicType.UB, count = 4)
|
||||
public int nbits;
|
||||
|
||||
/**
|
||||
* Red multiply value
|
||||
*/
|
||||
@@ -94,10 +98,6 @@ public class CXFORMWITHALPHA extends ColorTransform {
|
||||
@SWFType(value = BasicType.SB, countField = "nbits")
|
||||
public int alphaAddTerm;
|
||||
|
||||
@Calculated
|
||||
@SWFType(value = BasicType.UB, count = 4)
|
||||
public int nbits;
|
||||
|
||||
@Override
|
||||
public int getRedAdd() {
|
||||
return hasAddTerms ? redAddTerm : super.getRedAdd();
|
||||
@@ -138,6 +138,22 @@ public class CXFORMWITHALPHA extends ColorTransform {
|
||||
return hasMultTerms ? alphaMultTerm : super.getAlphaMulti();
|
||||
}
|
||||
|
||||
public CXFORMWITHALPHA() {
|
||||
}
|
||||
|
||||
public CXFORMWITHALPHA(ColorTransform colorTransform) {
|
||||
redMultTerm = colorTransform.getRedMulti();
|
||||
greenMultTerm = colorTransform.getGreenMulti();
|
||||
blueMultTerm = colorTransform.getBlueMulti();
|
||||
alphaMultTerm = colorTransform.getAlphaMulti();
|
||||
redAddTerm = colorTransform.getRedAdd();
|
||||
greenAddTerm = colorTransform.getGreenAdd();
|
||||
blueAddTerm = colorTransform.getBlueAdd();
|
||||
alphaAddTerm = colorTransform.getAlphaAdd();
|
||||
hasAddTerms = redAddTerm != 0 || greenAddTerm != 0 || blueAddTerm != 0 || alphaAddTerm != 0;
|
||||
hasMultTerms = redMultTerm != 255 || greenMultTerm != 255 || blueMultTerm != 255 || alphaMultTerm != 255;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CXFORMWITHALPHA clone() {
|
||||
CXFORMWITHALPHA ret = (CXFORMWITHALPHA) super.clone();
|
||||
|
||||
@@ -103,7 +103,6 @@ import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
|
||||
import com.jpexs.decompiler.flash.types.sound.MP3FRAME;
|
||||
import com.jpexs.decompiler.flash.types.sound.MP3SOUNDDATA;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.Path;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
@@ -2688,12 +2687,11 @@ public class XFLConverter {
|
||||
Map<Integer, String> characterVariables = getCharacterVariables(swf.tags);
|
||||
|
||||
String backgroundColor = "#ffffff";
|
||||
for (Tag t : swf.tags) {
|
||||
if (t instanceof SetBackgroundColorTag) {
|
||||
SetBackgroundColorTag sbc = (SetBackgroundColorTag) t;
|
||||
backgroundColor = sbc.backgroundColor.toHexRGB();
|
||||
}
|
||||
SetBackgroundColorTag setBgColorTag = swf.getBackgroundColor();
|
||||
if (setBgColorTag != null) {
|
||||
backgroundColor = setBgColorTag.backgroundColor.toHexRGB();
|
||||
}
|
||||
|
||||
domDocument.append("<DOMDocument xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://ns.adobe.com/xfl/2008/\" currentTimeline=\"1\" xflVersion=\"").append(flaVersion.xflVersion()).append("\" creatorInfo=\"").append(generator).append("\" platform=\"Windows\" versionInfo=\"Saved by ").append(generatorVerName).append("\" majorVersion=\"").append(generatorVersion).append("\" buildNumber=\"\" nextSceneIdentifier=\"2\" playOptionsPlayLoop=\"false\" playOptionsPlayPages=\"false\" playOptionsPlayFrameActions=\"false\" autoSaveHasPrompted=\"true\"");
|
||||
domDocument.append(" backgroundColor=\"").append(backgroundColor).append("\"");
|
||||
domDocument.append(" frameRate=\"").append((int) swf.frameRate).append("\""); // todo: is the cast to int needed?
|
||||
|
||||
Reference in New Issue
Block a user