mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-17 03:31:53 +00:00
svg export: clipping +code formatting
This commit is contained in:
@@ -109,6 +109,7 @@ import com.jpexs.decompiler.flash.tags.base.TextTag;
|
||||
import com.jpexs.decompiler.flash.timeline.Clip;
|
||||
import com.jpexs.decompiler.flash.timeline.DepthState;
|
||||
import com.jpexs.decompiler.flash.timeline.Frame;
|
||||
import com.jpexs.decompiler.flash.timeline.SvgClip;
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import com.jpexs.decompiler.flash.treeitems.AS2PackageNodeItem;
|
||||
@@ -1341,27 +1342,27 @@ public final class SWF implements TreeItem, Timelined {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static String getTypePrefix(CharacterTag c){
|
||||
if(c instanceof ShapeTag){
|
||||
|
||||
private static String getTypePrefix(CharacterTag c) {
|
||||
if (c instanceof ShapeTag) {
|
||||
return "shape";
|
||||
}
|
||||
if(c instanceof MorphShapeTag){
|
||||
if (c instanceof MorphShapeTag) {
|
||||
return "morphshape";
|
||||
}
|
||||
if(c instanceof DefineSpriteTag){
|
||||
if (c instanceof DefineSpriteTag) {
|
||||
return "sprite";
|
||||
}
|
||||
if(c instanceof TextTag){
|
||||
if (c instanceof TextTag) {
|
||||
return "text";
|
||||
}
|
||||
if(c instanceof ButtonTag){
|
||||
if (c instanceof ButtonTag) {
|
||||
return "button";
|
||||
}
|
||||
if(c instanceof FontTag){
|
||||
if (c instanceof FontTag) {
|
||||
return "font";
|
||||
}
|
||||
if(c instanceof ImageTag){
|
||||
if (c instanceof ImageTag) {
|
||||
return "image";
|
||||
}
|
||||
return "character";
|
||||
@@ -1452,9 +1453,9 @@ public final class SWF implements TreeItem, Timelined {
|
||||
getNeededCharacters(timeline, fframes, library);
|
||||
|
||||
for (int c : library) {
|
||||
CharacterTag ch = fswf.characters.get(c);
|
||||
if(ch instanceof ImageTag){
|
||||
ImageTag image=(ImageTag)ch;
|
||||
CharacterTag ch = fswf.characters.get(c);
|
||||
if (ch instanceof ImageTag) {
|
||||
ImageTag image = (ImageTag) ch;
|
||||
String format = image.getImageFormat();
|
||||
InputStream imageStream = image.getImageData();
|
||||
byte[] imageData;
|
||||
@@ -1469,22 +1470,21 @@ public final class SWF implements TreeItem, Timelined {
|
||||
imageData = baos.toByteArray();
|
||||
}
|
||||
String base64ImgData = DatatypeConverter.printBase64Binary(imageData);
|
||||
fos.write(Utf8Helper.getBytes("var image"+c+" = document.createElement(\"img\");\r\nimage"+c+".src=\"data:image/" + format + ";base64," + base64ImgData + "\";\r\n"));
|
||||
}else{
|
||||
fos.write(Utf8Helper.getBytes("function " + getTypePrefix(ch)+c + "(ctx,frame,ratio){\r\n"));
|
||||
if(ch instanceof DrawableTag){
|
||||
fos.write(Utf8Helper.getBytes(((DrawableTag)ch).toHtmlCanvas(1)));
|
||||
fos.write(Utf8Helper.getBytes("var image" + c + " = document.createElement(\"img\");\r\nimage" + c + ".src=\"data:image/" + format + ";base64," + base64ImgData + "\";\r\n"));
|
||||
} else {
|
||||
fos.write(Utf8Helper.getBytes("function " + getTypePrefix(ch) + c + "(ctx,frame,ratio){\r\n"));
|
||||
if (ch instanceof DrawableTag) {
|
||||
fos.write(Utf8Helper.getBytes(((DrawableTag) ch).toHtmlCanvas(1)));
|
||||
}
|
||||
fos.write(Utf8Helper.getBytes("}\r\n\r\n"));
|
||||
}
|
||||
}
|
||||
|
||||
String currentName = timeline.id == 0?"main":getTypePrefix(fswf.characters.get(timeline.id))+timeline.id;
|
||||
|
||||
fos.write(Utf8Helper.getBytes("function "+currentName + "(ctx,frame,ratio){\r\n"));
|
||||
|
||||
String currentName = timeline.id == 0 ? "main" : getTypePrefix(fswf.characters.get(timeline.id)) + timeline.id;
|
||||
|
||||
fos.write(Utf8Helper.getBytes("function " + currentName + "(ctx,frame,ratio){\r\n"));
|
||||
fos.write(Utf8Helper.getBytes(framesToHtmlCanvas(unitDivisor, ftim, fframes, 0, null, 0, displayRect, new ColorTransform(), fbackgroundColor)));
|
||||
fos.write(Utf8Helper.getBytes("}\r\n\r\n"));
|
||||
|
||||
|
||||
fos.write(Utf8Helper.getBytes("var frame = -1;\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("var frames = [];\r\n"));
|
||||
@@ -1495,7 +1495,7 @@ public final class SWF implements TreeItem, Timelined {
|
||||
fos.write(Utf8Helper.getBytes("function nextFrame(ctx){\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tctx.clearRect(0,0," + width + "," + height + ");\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tframe = (frame+1)%frames.length;\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\t"+currentName + "(ctx,frames[frame],0);\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\t" + currentName + "(ctx,frames[frame],0);\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("}\r\n\r\n"));
|
||||
|
||||
fos.write(Utf8Helper.getBytes("if(frames.length==1){nextFrame(ctx);}else{window.setInterval(function(){nextFrame(ctx);}," + (int) (1000.0 / timeline.swf.frameRate) + ");};\r\n"));
|
||||
@@ -1516,7 +1516,7 @@ public final class SWF implements TreeItem, Timelined {
|
||||
while ((cnt = fis.read(buf)) > 0) {
|
||||
fos.write(buf, 0, cnt);
|
||||
}
|
||||
if(Configuration.packJavaScripts.get()){
|
||||
if (Configuration.packJavaScripts.get()) {
|
||||
fos.write(Utf8Helper.getBytes(";"));
|
||||
}
|
||||
fos.write(Utf8Helper.getBytes(CanvasShapeExporter.getHtmlSuffix()));
|
||||
@@ -2165,7 +2165,7 @@ public final class SWF implements TreeItem, Timelined {
|
||||
DepthState layer = frameObj.layers.get(depth);
|
||||
if (!timeline.swf.characters.containsKey(layer.characterId)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
usedCharacters.add(layer.characterId);
|
||||
CharacterTag character = timeline.swf.characters.get(layer.characterId);
|
||||
usedCharacters.add(layer.characterId);
|
||||
@@ -2220,7 +2220,7 @@ public final class SWF implements TreeItem, Timelined {
|
||||
DefineSpriteTag sp = (DefineSpriteTag) character;
|
||||
Timeline tim = sp.getTimeline();
|
||||
f = layer.time % tim.getFrameCount();
|
||||
}
|
||||
}
|
||||
sb.append("\t\t\tctx.save();\r\n");
|
||||
sb.append("\t\t\tctx.transform(").append(placeMatrix.scaleX).append(",");
|
||||
sb.append(placeMatrix.rotateSkew0).append(",");
|
||||
@@ -2229,7 +2229,7 @@ public final class SWF implements TreeItem, Timelined {
|
||||
sb.append(placeMatrix.translateX).append(",");
|
||||
sb.append(placeMatrix.translateY);
|
||||
sb.append(");\r\n");
|
||||
sb.append("\t\t\t").append(getTypePrefix(character)).append(layer.characterId).append("(ctx,").append(f).append(",").append(layer.ratio<0?0:layer.ratio).append(");\r\n");
|
||||
sb.append("\t\t\t").append(getTypePrefix(character)).append(layer.characterId).append("(ctx,").append(f).append(",").append(layer.ratio < 0 ? 0 : layer.ratio).append(");\r\n");
|
||||
sb.append("\t\t\tctx.restore();\r\n");
|
||||
}
|
||||
sb.append("\t\t\tbreak;\r\n");
|
||||
@@ -2243,14 +2243,13 @@ public final class SWF implements TreeItem, Timelined {
|
||||
return;
|
||||
}
|
||||
Frame frameObj = timeline.frames.get(frame);
|
||||
// TODO g.setTransform(transformation.toTransform());
|
||||
List<Clip> clips = new ArrayList<>();
|
||||
List<Shape> prevClips = new ArrayList<>();
|
||||
List<SvgClip> clips = new ArrayList<>();
|
||||
List<String> prevClips = new ArrayList<>();
|
||||
|
||||
for (int i = 1; i <= timeline.getMaxDepth(); i++) {
|
||||
for (int c = 0; c < clips.size(); c++) {
|
||||
if (clips.get(c).depth == i) {
|
||||
// TODO exporter.setClip(prevClips.get(c));
|
||||
exporter.setClip(prevClips.get(c));
|
||||
prevClips.remove(c);
|
||||
clips.remove(c);
|
||||
}
|
||||
@@ -2295,10 +2294,20 @@ public final class SWF implements TreeItem, Timelined {
|
||||
|
||||
// TODO: if (layer.filters != null)
|
||||
// TODO: if (layer.blendMode > 1)
|
||||
Matrix mat = Matrix.getTranslateInstance(rect.xMin, rect.yMin).preConcatenate(new Matrix(layer.matrix));
|
||||
exporter.addUse(mat, boundRect, assetName);
|
||||
|
||||
// TODO: if (layer.clipDepth > -1)...
|
||||
if (layer.clipDepth > -1) {
|
||||
String clipName = exporter.getUniqueId("clipPath");
|
||||
exporter.createClipPath(new Matrix(), clipName);
|
||||
SvgClip clip = new SvgClip(clipName, layer.clipDepth);
|
||||
clips.add(clip);
|
||||
prevClips.add(exporter.getClip());
|
||||
Matrix mat = Matrix.getTranslateInstance(rect.xMin, rect.yMin).preConcatenate(new Matrix(layer.matrix));
|
||||
exporter.addUse(mat, boundRect, assetName);
|
||||
exporter.setClip(clip.shape);
|
||||
exporter.endGroup();
|
||||
} else {
|
||||
Matrix mat = Matrix.getTranslateInstance(rect.xMin, rect.yMin).preConcatenate(new Matrix(layer.matrix));
|
||||
exporter.addUse(mat, boundRect, assetName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2321,7 +2330,7 @@ public final class SWF implements TreeItem, Timelined {
|
||||
}
|
||||
return exporter.getUniqueId("tag");
|
||||
}
|
||||
|
||||
|
||||
public static SerializableImage frameToImageGet(Timeline timeline, int frame, int time, DepthState stateUnderCursor, int mouseButton, RECT displayRect, Matrix transformation, ColorTransform colorTransform, Color backGroundColor) {
|
||||
String key = "frame_" + frame + "_" + timeline.id + "_" + timeline.swf.hashCode();
|
||||
SerializableImage image = getFromCache(key);
|
||||
@@ -2555,7 +2564,7 @@ public final class SWF implements TreeItem, Timelined {
|
||||
gm.fillRect(0, 0, image.getWidth(), image.getHeight());
|
||||
gm.setTransform(trans);
|
||||
gm.drawImage(img.getBufferedImage(), 0, 0, null);
|
||||
Clip clip = new Clip(Helper.imageToShape(mask), layer.clipDepth); //Maybe we can get corrent outline instead converting from image (?)
|
||||
Clip clip = new Clip(Helper.imageToShape(mask), layer.clipDepth); //Maybe we can get current outline instead converting from image (?)
|
||||
clips.add(clip);
|
||||
prevClips.add(g.getClip());
|
||||
g.setTransform(AffineTransform.getTranslateInstance(0, 0));
|
||||
|
||||
@@ -2303,9 +2303,9 @@ public class SWFInputStream extends InputStream {
|
||||
scr.lineStyle = (int) readUB(lineBits);
|
||||
}
|
||||
if (stateNewStyles) {
|
||||
if(morphShape){
|
||||
if (morphShape) {
|
||||
//This should never happen
|
||||
}else{
|
||||
} else {
|
||||
scr.fillStyles = readFILLSTYLEARRAY(shapeNum);
|
||||
scr.lineStyles = readLINESTYLEARRAY(shapeNum);
|
||||
}
|
||||
@@ -2347,6 +2347,7 @@ public class SWFInputStream extends InputStream {
|
||||
* Reads one SHAPE value from the stream
|
||||
*
|
||||
* @param shapeNum 1 in DefineShape, 2 in DefineShape2...
|
||||
* @param morphShape
|
||||
* @return SHAPE value
|
||||
* @throws IOException
|
||||
*/
|
||||
@@ -2362,6 +2363,7 @@ public class SWFInputStream extends InputStream {
|
||||
* Reads one SHAPEWITHSTYLE value from the stream
|
||||
*
|
||||
* @param shapeNum 1 in DefineShape, 2 in DefineShape2...
|
||||
* @param morphShape
|
||||
* @return SHAPEWITHSTYLE value
|
||||
* @throws IOException
|
||||
*/
|
||||
@@ -2547,12 +2549,12 @@ public class SWFInputStream extends InputStream {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads one MORPHFOCALGRADIENT value from the stream
|
||||
*
|
||||
* This is undocumented feature
|
||||
*
|
||||
*
|
||||
* @return MORPHGRADIENT value
|
||||
* @throws IOException
|
||||
*/
|
||||
@@ -2569,7 +2571,6 @@ public class SWFInputStream extends InputStream {
|
||||
ret.endFocalPoint = readFIXED8();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads one MORPHFILLSTYLE value from the stream
|
||||
@@ -2594,7 +2595,7 @@ public class SWFInputStream extends InputStream {
|
||||
|| (ret.fillStyleType == MORPHFILLSTYLE.RADIAL_GRADIENT)) {
|
||||
ret.gradient = readMORPHGRADIENT();
|
||||
}
|
||||
if(ret.fillStyleType == MORPHFILLSTYLE.FOCAL_RADIAL_GRADIENT){
|
||||
if (ret.fillStyleType == MORPHFILLSTYLE.FOCAL_RADIAL_GRADIENT) {
|
||||
ret.gradient = readMORPHFOCALGRADIENT();
|
||||
}
|
||||
|
||||
|
||||
@@ -1503,12 +1503,12 @@ public class SWFOutputStream extends OutputStream {
|
||||
writeMORPHGRADRECORD(value.gradientRecords[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes MORPHFOCALGRADIENT value to the stream
|
||||
*
|
||||
* Undocumented feature
|
||||
*
|
||||
*
|
||||
* @param value MORPHGRADIENT value
|
||||
* @param shapeNum 1 in DefineMorphShape, 2 in DefineMorphShape2,...
|
||||
* @throws IOException
|
||||
|
||||
@@ -1868,7 +1868,7 @@ public class AVM2Code implements Serializable {
|
||||
|
||||
if (ins.definition instanceof NewFunctionIns) {
|
||||
MethodBody innerBody = abc.findBody(ins.operands[0]);
|
||||
innerBody.autoFillStats(abc, stats.initscope + (stats.has_activation ? 1 : 0),false);
|
||||
innerBody.autoFillStats(abc, stats.initscope + (stats.has_activation ? 1 : 0), false);
|
||||
}
|
||||
|
||||
stats.instructionStats[pos].seen = true;
|
||||
|
||||
@@ -167,7 +167,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
public List<GraphSourceItem> generate(SourceGeneratorLocalData localData, AndItem item) throws CompilationException {
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
ret.addAll(generateToActionList(localData, item.leftSide));
|
||||
if(!(""+item.leftSide.returnType()).equals("Boolean")){
|
||||
if (!("" + item.leftSide.returnType()).equals("Boolean")) {
|
||||
ret.add(ins(new ConvertBIns()));
|
||||
}
|
||||
ret.add(ins(new DupIns()));
|
||||
@@ -199,7 +199,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
public List<GraphSourceItem> generate(SourceGeneratorLocalData localData, OrItem item) throws CompilationException {
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
ret.addAll(generateToActionList(localData, item.leftSide));
|
||||
if(!(""+item.leftSide.returnType()).equals("Boolean")){
|
||||
if (!("" + item.leftSide.returnType()).equals("Boolean")) {
|
||||
ret.add(ins(new ConvertBIns()));
|
||||
}
|
||||
ret.add(ins(new DupIns()));
|
||||
@@ -1189,7 +1189,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
}
|
||||
|
||||
//Class initializer
|
||||
int staticMi = method(false, new ArrayList<MethodBody>(), pkg.packageName, staticNeedsActivation, sinitVariables, initScope + 1 + (implementsStr.isEmpty()?0:1), false, 0, isInterface ? null : name, superName, false, localData, new ArrayList<GraphTargetItem>(), new ArrayList<String>(), new ArrayList<GraphTargetItem>(), staticInit, TypeItem.UNBOUNDED);
|
||||
int staticMi = method(false, new ArrayList<MethodBody>(), pkg.packageName, staticNeedsActivation, sinitVariables, initScope + 1 + (implementsStr.isEmpty() ? 0 : 1), false, 0, isInterface ? null : name, superName, false, localData, new ArrayList<GraphTargetItem>(), new ArrayList<String>(), new ArrayList<GraphTargetItem>(), staticInit, TypeItem.UNBOUNDED);
|
||||
MethodBody sinitBody = abc.findBody(staticMi);
|
||||
|
||||
List<AVM2Instruction> sinitcode = new ArrayList<>();
|
||||
@@ -1239,7 +1239,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
}
|
||||
}
|
||||
sinitBody.markOffsets();
|
||||
sinitBody.autoFillStats(abc, initScope + 1 + (implementsStr.isEmpty()?0:1), true);
|
||||
sinitBody.autoFillStats(abc, initScope + 1 + (implementsStr.isEmpty() ? 0 : 1), true);
|
||||
|
||||
classInfo.cinit_index = staticMi;
|
||||
if (!isInterface) {
|
||||
|
||||
@@ -511,7 +511,7 @@ public class ActionScriptParser {
|
||||
throw new ParseException("Only one final keyword allowed", lexer.yyline());
|
||||
}
|
||||
isFinal = true;
|
||||
} else if (s.type == SymbolType.DYNAMIC) {
|
||||
} else if (s.type == SymbolType.DYNAMIC) {
|
||||
if (isDynamic) {
|
||||
throw new ParseException("Only one dynamic keyword allowed", lexer.yyline());
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class MethodAVM2Item extends FunctionAVM2Item {
|
||||
public String customNamespace;
|
||||
public boolean isInterface;
|
||||
|
||||
public MethodAVM2Item(boolean isInterface,String customNamespace, boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<AssignableAVM2Item> subvariables, GraphTargetItem retType) {
|
||||
public MethodAVM2Item(boolean isInterface, String customNamespace, boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<AssignableAVM2Item> subvariables, GraphTargetItem retType) {
|
||||
super(isInterface, needsActivation, namespace, hasRest, line, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType);
|
||||
this.isStatic = isStatic;
|
||||
this.override = override;
|
||||
|
||||
@@ -125,7 +125,6 @@ public class NameAVM2Item extends AssignableAVM2Item {
|
||||
this.definition = definition;
|
||||
}
|
||||
|
||||
|
||||
public void setNsKind(int nsKind) {
|
||||
this.nsKind = nsKind;
|
||||
}
|
||||
@@ -239,7 +238,6 @@ public class NameAVM2Item extends AssignableAVM2Item {
|
||||
Reference<Integer> ns_temp = new Reference<>(-1);
|
||||
Reference<Integer> index_temp = new Reference<>(-1);
|
||||
Reference<Integer> ret_temp = new Reference<>(-1);
|
||||
|
||||
|
||||
if (assignedValue != null) {
|
||||
List<String> basicTypes = Arrays.asList("int", "Number");
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.util.List;
|
||||
public class SetterAVM2Item extends MethodAVM2Item {
|
||||
|
||||
public SetterAVM2Item(boolean isInterface, String customNamespace, boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<AssignableAVM2Item> subvariables, GraphTargetItem retType) {
|
||||
super(isInterface,customNamespace, needsActivation, hasRest, line, override, isFinal, isStatic, namespace, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType);
|
||||
super(isInterface, customNamespace, needsActivation, hasRest, line, override, isFinal, isStatic, namespace, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -243,8 +243,8 @@ public class MethodBody implements Cloneable, Serializable {
|
||||
abc.method_info.get(method_info).setFlagSetsdxns(stats.has_set_dxns);
|
||||
abc.method_info.get(method_info).setFlagNeed_activation(stats.has_activation);
|
||||
MethodInfo mi = abc.method_info.get(method_info);
|
||||
int min_regs = mi.param_types.length+(hasThis?1:0)+(mi.flagNeed_rest()?1:0);
|
||||
if(max_regs<min_regs){
|
||||
int min_regs = mi.param_types.length + (hasThis ? 1 : 0) + (mi.flagNeed_rest() ? 1 : 0);
|
||||
if (max_regs < min_regs) {
|
||||
max_regs = min_regs;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -269,8 +269,7 @@ public class Configuration {
|
||||
@ConfigurationDefaultBoolean(true)
|
||||
@ConfigurationName("warning.experimental.as3edit")
|
||||
public static final ConfigurationItem<Boolean> warningExperimentalAS3Edit = null;
|
||||
|
||||
|
||||
|
||||
@ConfigurationDefaultBoolean(true)
|
||||
public static final ConfigurationItem<Boolean> packJavaScripts = null;
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ public class FontExporter {
|
||||
}
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
|
||||
public void exportFont(final FontTag t, FontExportMode mode, File file) throws IOException {
|
||||
List<SHAPE> shapes = t.getGlyphShapeTable();
|
||||
Fontastic f = new Fontastic(t.getFontName(), file);
|
||||
|
||||
@@ -64,7 +64,7 @@ public class MorphShapeExporter {
|
||||
if (t instanceof CharacterTag) {
|
||||
characterID = ((CharacterTag) t).getCharacterId();
|
||||
}
|
||||
String ext = settings.mode==MorphShapeExportMode.CANVAS?"html":"svg";
|
||||
String ext = settings.mode == MorphShapeExportMode.CANVAS ? "html" : "svg";
|
||||
|
||||
final File file = new File(outdir + File.separator + characterID + "." + ext);
|
||||
final int fcharacterID = characterID;
|
||||
@@ -82,14 +82,14 @@ public class MorphShapeExporter {
|
||||
}
|
||||
break;
|
||||
case CANVAS:
|
||||
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||
int deltaX = -Math.min(mst.getStartBounds().Xmin,mst.getEndBounds().Xmin);
|
||||
int deltaY = -Math.min(mst.getStartBounds().Ymin,mst.getEndBounds().Ymin);
|
||||
CanvasMorphShapeExporter cse = new CanvasMorphShapeExporter(((Tag)mst).getSwf(),mst.getShapeAtRatio(0),mst.getShapeAtRatio(DefineMorphShapeTag.MAX_RATIO), new CXFORMWITHALPHA(),SWF.unitDivisor,deltaX,deltaY);
|
||||
cse.export();
|
||||
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||
int deltaX = -Math.min(mst.getStartBounds().Xmin, mst.getEndBounds().Xmin);
|
||||
int deltaY = -Math.min(mst.getStartBounds().Ymin, mst.getEndBounds().Ymin);
|
||||
CanvasMorphShapeExporter cse = new CanvasMorphShapeExporter(((Tag) mst).getSwf(), mst.getShapeAtRatio(0), mst.getShapeAtRatio(DefineMorphShapeTag.MAX_RATIO), new CXFORMWITHALPHA(), SWF.unitDivisor, deltaX, deltaY);
|
||||
cse.export();
|
||||
fos.write(Utf8Helper.getBytes(cse.getHtml()));
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -106,8 +106,8 @@ public class ShapeExporter {
|
||||
SHAPE shp = st.getShapes();
|
||||
int deltaX = -shp.getBounds().Xmin;
|
||||
int deltaY = -shp.getBounds().Ymin;
|
||||
CanvasShapeExporter cse = new CanvasShapeExporter(null,SWF.unitDivisor,((Tag)st).getSwf(),shp, new CXFORMWITHALPHA(),deltaX,deltaY);
|
||||
cse.export();
|
||||
CanvasShapeExporter cse = new CanvasShapeExporter(null, SWF.unitDivisor, ((Tag) st).getSwf(), shp, new CXFORMWITHALPHA(), deltaX, deltaY);
|
||||
cse.export();
|
||||
fos.write(Utf8Helper.getBytes(cse.getHtml()));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -80,7 +80,7 @@ public class TextExporter {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if (settings.singleFile) {
|
||||
final File file = new File(outdir + File.separator
|
||||
+ (settings.mode == TextExportMode.FORMATTED ? TEXT_EXPORT_FILENAME_FORMATTED : TEXT_EXPORT_FILENAME_PLAIN));
|
||||
|
||||
@@ -210,6 +210,21 @@ public class Matrix {
|
||||
return transform;
|
||||
}
|
||||
|
||||
public String getTransformationString(double translateDivisor, double unitDivisor) {
|
||||
double translateX = roundPixels400(this.translateX / translateDivisor);
|
||||
double translateY = roundPixels400(this.translateY / translateDivisor);
|
||||
double rotateSkew0 = roundPixels400(this.rotateSkew0 / unitDivisor);
|
||||
double rotateSkew1 = roundPixels400(this.rotateSkew1 / unitDivisor);
|
||||
double scaleX = roundPixels400(this.scaleX / unitDivisor);
|
||||
double scaleY = roundPixels400(this.scaleY / unitDivisor);
|
||||
return "matrix(" + scaleX + ", " + rotateSkew0 + ", "
|
||||
+ rotateSkew1 + ", " + scaleY + ", " + translateX + ", " + translateY + ")";
|
||||
}
|
||||
|
||||
private double roundPixels400(double pixels) {
|
||||
return Math.round(pixels * 10000) / 10000.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[Matrix scale:" + scaleX + "," + scaleY + ", rotate:" + rotateSkew0 + "," + rotateSkew1 + ", translate:" + translateX + "," + translateY + "]";
|
||||
|
||||
@@ -70,6 +70,7 @@ public class SVGExporter {
|
||||
public Map<Tag, Map<Character, String>> exportedChars = new HashMap<>();
|
||||
private final Map<String, Integer> lastIds = new HashMap<>();
|
||||
private final HashSet<String> fontFaces = new HashSet<>();
|
||||
private String clip;
|
||||
public boolean useTextTag = Configuration.textExportExportFontFace.get();
|
||||
|
||||
public SVGExporter(ExportRectangle bounds) {
|
||||
@@ -101,7 +102,7 @@ public class SVGExporter {
|
||||
}
|
||||
return _svgDefs;
|
||||
}
|
||||
|
||||
|
||||
private CDATASection getStyle() {
|
||||
if (_svgStyle == null) {
|
||||
Element style = _svg.createElement("style");
|
||||
@@ -111,7 +112,7 @@ public class SVGExporter {
|
||||
}
|
||||
return _svgStyle;
|
||||
}
|
||||
|
||||
|
||||
public final void createDefGroup(ExportRectangle bounds, String id) {
|
||||
Element g = _svg.createElement("g");
|
||||
if (bounds != null) {
|
||||
@@ -122,13 +123,13 @@ public class SVGExporter {
|
||||
g.setAttribute("id", id);
|
||||
}
|
||||
if (_svgGs.size() == 0) {
|
||||
_svg.getDocumentElement().appendChild(g);
|
||||
_svg.getDocumentElement().appendChild(g);
|
||||
} else {
|
||||
getDefs().appendChild(g);
|
||||
}
|
||||
_svgGs.add(g);
|
||||
}
|
||||
|
||||
|
||||
public void endGroup() {
|
||||
Element g = _svgGs.pop();
|
||||
if (g.getChildNodes().getLength() == 0) {
|
||||
@@ -136,21 +137,30 @@ public class SVGExporter {
|
||||
}
|
||||
}
|
||||
|
||||
public final void createSubGroup(Matrix transform, String id) {
|
||||
Element g = _svg.createElement("g");
|
||||
double translateX = roundPixels400(transform.translateX / SWF.unitDivisor);
|
||||
double translateY = roundPixels400(transform.translateY / SWF.unitDivisor);
|
||||
double rotateSkew0 = roundPixels400(transform.rotateSkew0);
|
||||
double rotateSkew1 = roundPixels400(transform.rotateSkew1);
|
||||
double scaleX = roundPixels400(transform.scaleX);
|
||||
double scaleY = roundPixels400(transform.scaleY);
|
||||
g.setAttribute("transform", "matrix(" + scaleX + ", " + rotateSkew0
|
||||
+ ", " + rotateSkew1 + ", " + scaleY + ", " + translateX + ", " + translateY + ")");
|
||||
if (id != null) {
|
||||
g.setAttribute("id", id);
|
||||
public final Element createSubGroup(Matrix transform, String id) {
|
||||
Element group = createSubGroup(transform, id, "g");
|
||||
group.setAttribute("transform", transform.getTransformationString(SWF.unitDivisor, 1));
|
||||
return group;
|
||||
}
|
||||
|
||||
public final Element createClipPath(Matrix transform, String id) {
|
||||
Element group = createSubGroup(transform, id, "clipPath");
|
||||
Node parent = group.getParentNode();
|
||||
if (parent instanceof Element) {
|
||||
Element parentElement = (Element) parent;
|
||||
group.setAttribute("transform", parentElement.getAttribute("transform"));
|
||||
}
|
||||
_svgGs.peek().appendChild(g);
|
||||
_svgGs.add(g);
|
||||
return group;
|
||||
}
|
||||
|
||||
private Element createSubGroup(Matrix transform, String id, String tagName) {
|
||||
Element group = _svg.createElement(tagName);
|
||||
if (id != null) {
|
||||
group.setAttribute("id", id);
|
||||
}
|
||||
_svgGs.peek().appendChild(group);
|
||||
_svgGs.add(group);
|
||||
return group;
|
||||
}
|
||||
|
||||
public void addToGroup(Node newChild) {
|
||||
@@ -189,24 +199,20 @@ public class SVGExporter {
|
||||
public Element addUse(Matrix transform, RECT boundRect, String href) {
|
||||
Element image = _svg.createElement("use");
|
||||
if (transform != null) {
|
||||
double translateX = roundPixels400(transform.translateX / SWF.unitDivisor);
|
||||
double translateY = roundPixels400(transform.translateY / SWF.unitDivisor);
|
||||
double rotateSkew0 = roundPixels400(transform.rotateSkew0);
|
||||
double rotateSkew1 = roundPixels400(transform.rotateSkew1);
|
||||
double scaleX = roundPixels400(transform.scaleX);
|
||||
double scaleY = roundPixels400(transform.scaleY);
|
||||
image.setAttribute("transform", "matrix(" + scaleX + ", " + rotateSkew0
|
||||
+ ", " + rotateSkew1 + ", " + scaleY + ", " + translateX + ", " + translateY + ")");
|
||||
image.setAttribute("transform", transform.getTransformationString(SWF.unitDivisor, 1));
|
||||
image.setAttribute("width", Double.toString(boundRect.getWidth() / (double) SWF.unitDivisor));
|
||||
image.setAttribute("height", Double.toString(boundRect.getHeight() / (double) SWF.unitDivisor));
|
||||
}
|
||||
image.setAttribute("xlink:href", "#" + href);
|
||||
if (clip != null) {
|
||||
image.setAttribute("clip-path", "url(#" + clip + ")");
|
||||
}
|
||||
_svgGs.peek().appendChild(image);
|
||||
return image;
|
||||
}
|
||||
|
||||
public void addStyle(String fontFace, byte[] data, FontExportMode mode) {
|
||||
if (!fontFaces.contains(fontFace)){
|
||||
if (!fontFaces.contains(fontFace)) {
|
||||
fontFaces.add(fontFace);
|
||||
String base64Data = DatatypeConverter.printBase64Binary(data);
|
||||
String value = getStyle().getTextContent();
|
||||
@@ -225,7 +231,7 @@ public class SVGExporter {
|
||||
getStyle().setTextContent(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getUniqueId(String prefix) {
|
||||
Integer lastId = lastIds.get(prefix);
|
||||
if (lastId == null) {
|
||||
@@ -236,12 +242,16 @@ public class SVGExporter {
|
||||
lastIds.put(prefix, lastId);
|
||||
return prefix + lastId;
|
||||
}
|
||||
|
||||
|
||||
public void setClip(String clip) {
|
||||
this.clip = clip;
|
||||
}
|
||||
|
||||
public String getClip() {
|
||||
return clip;
|
||||
}
|
||||
|
||||
protected static double roundPixels20(double pixels) {
|
||||
return Math.round(pixels * 100) / 100.0;
|
||||
}
|
||||
|
||||
protected static double roundPixels400(double pixels) {
|
||||
return Math.round(pixels * 10000) / 10000.0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,16 +57,14 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
protected String lastRadColor = null;
|
||||
protected int repeatCnt = 0;
|
||||
protected SWF swf;
|
||||
|
||||
|
||||
protected String lineFillData = null;
|
||||
protected String lineLastRadColor = null;
|
||||
protected Matrix lineFillMatrix = null;
|
||||
protected Matrix lineFillMatrixEnd = null;
|
||||
protected int lineRepeatCnt = 0;
|
||||
|
||||
|
||||
|
||||
public CanvasMorphShapeExporter(SWF swf,SHAPE shape, SHAPE endShape, ColorTransform colorTransform, double unitDivisor,int deltaX, int deltaY) {
|
||||
|
||||
public CanvasMorphShapeExporter(SWF swf, SHAPE shape, SHAPE endShape, ColorTransform colorTransform, double unitDivisor, int deltaX, int deltaY) {
|
||||
super(shape, endShape, colorTransform);
|
||||
this.deltaX = deltaX;
|
||||
this.deltaY = deltaY;
|
||||
@@ -74,38 +72,36 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
this.swf = swf;
|
||||
}
|
||||
|
||||
|
||||
public String getHtml() {
|
||||
int width = (int) (Math.max(shape.getBounds().getWidth(),shapeEnd.getBounds().getWidth())/unitDivisor);
|
||||
int height = (int) (Math.max(shape.getBounds().getHeight(),shapeEnd.getBounds().getHeight())/unitDivisor);
|
||||
|
||||
return CanvasShapeExporter.getHtmlPrefix(width, height)+getJsPrefix()+shapeData+getJsSuffix(width,height)+CanvasShapeExporter.getHtmlSuffix();
|
||||
public String getHtml() {
|
||||
int width = (int) (Math.max(shape.getBounds().getWidth(), shapeEnd.getBounds().getWidth()) / unitDivisor);
|
||||
int height = (int) (Math.max(shape.getBounds().getHeight(), shapeEnd.getBounds().getHeight()) / unitDivisor);
|
||||
|
||||
return CanvasShapeExporter.getHtmlPrefix(width, height) + getJsPrefix() + shapeData + getJsSuffix(width, height) + CanvasShapeExporter.getHtmlSuffix();
|
||||
}
|
||||
|
||||
|
||||
public static String getJsSuffix(int width,int height){
|
||||
|
||||
public static String getJsSuffix(int width, int height) {
|
||||
String ret = "";
|
||||
ret += "}\r\n";
|
||||
int step = Math.round(65535 / 100);
|
||||
int rate = 10;
|
||||
ret += "var step = "+step+";\r\n";
|
||||
ret += "var step = " + step + ";\r\n";
|
||||
ret += "var ratio = -1;\r\n";
|
||||
ret += "function nextFrame(ctx){\r\n";
|
||||
ret +="\tctx.clearRect(0,0," + width + "," + height + ");\r\n";
|
||||
ret +="\tratio = (ratio+step)%65535;\r\n";
|
||||
ret +="\tmorphshape(ctx,ratio);\r\n";
|
||||
ret +="}\r\n";
|
||||
ret += "\tctx.clearRect(0,0," + width + "," + height + ");\r\n";
|
||||
ret += "\tratio = (ratio+step)%65535;\r\n";
|
||||
ret += "\tmorphshape(ctx,ratio);\r\n";
|
||||
ret += "}\r\n";
|
||||
|
||||
ret +="window.setInterval(function(){nextFrame(ctx)},"+rate+");\r\n";
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String getJsPrefix(){
|
||||
String ret = CanvasShapeExporter.getJsPrefix();
|
||||
ret+="function morphshape(ctx,ratio){\r\n";
|
||||
ret += "window.setInterval(function(){nextFrame(ctx)}," + rate + ");\r\n";
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public static String getJsPrefix() {
|
||||
String ret = CanvasShapeExporter.getJsPrefix();
|
||||
ret += "function morphshape(ctx,ratio){\r\n";
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginShape() {
|
||||
}
|
||||
@@ -134,7 +130,7 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
@Override
|
||||
public void beginFill(RGB color, RGB colorEnd) {
|
||||
finalizePath();
|
||||
fillData += "\tctx.fillStyle="+useRatioColor(color,colorEnd)+";\r\n";
|
||||
fillData += "\tctx.fillStyle=" + useRatioColor(color, colorEnd) + ";\r\n";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -153,15 +149,14 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
start.y += deltaY;
|
||||
end.x += deltaX;
|
||||
end.y += deltaY;
|
||||
|
||||
|
||||
|
||||
Point start2 = matrixEnd.transform(new Point(-16384 - 32768 * repeatCnt, 0));
|
||||
Point end2 = matrixEnd.transform(new Point(16384 + 32768 * repeatCnt, 0));
|
||||
start2.x += deltaX;
|
||||
start2.y += deltaY;
|
||||
end2.x += deltaX;
|
||||
end2.y += deltaY;
|
||||
|
||||
|
||||
fillData += "\tvar grd=ctx.createLinearGradient(" + useRatioPos(start.x, start2.x) + "," + useRatioPos(start.y, start2.y) + "," + useRatioPos(end.x, end2.x) + "," + useRatioPos(end.y, end2.y) + ");\r\n";
|
||||
} else {
|
||||
matrix.translateX /= unitDivisor;
|
||||
@@ -174,9 +169,6 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
matrix.translateY += deltaY / unitDivisor;
|
||||
fillMatrix = matrix;
|
||||
|
||||
|
||||
|
||||
|
||||
matrixEnd.translateX /= unitDivisor;
|
||||
matrixEnd.translateY /= unitDivisor;
|
||||
matrixEnd.scaleX /= unitDivisor;
|
||||
@@ -187,8 +179,7 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
matrixEnd.translateY += deltaY / unitDivisor;
|
||||
fillMatrixEnd = matrixEnd;
|
||||
|
||||
|
||||
fillData += "\tvar grd=ctx.createRadialGradient("+useRatioDouble(focalPointRatio*16384,focalPointRatioEnd*16384)+",0,0,0,0," + (16384 + 32768 * repeatCnt) + ");\r\n";
|
||||
fillData += "\tvar grd=ctx.createRadialGradient(" + useRatioDouble(focalPointRatio * 16384, focalPointRatioEnd * 16384) + ",0,0,0,0," + (16384 + 32768 * repeatCnt) + ");\r\n";
|
||||
}
|
||||
int repeatTotal = repeatCnt * 2 + 1;
|
||||
double oneHeight = 1.0 / repeatTotal;
|
||||
@@ -200,16 +191,16 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
for (int i = 0; i < repeatTotal; i++) {
|
||||
if (spreadMethod == GRADIENT.SPREAD_REFLECT_MODE) {
|
||||
revert = !revert;
|
||||
}
|
||||
for(int j=0;j<gradientRecords.length;j++){
|
||||
}
|
||||
for (int j = 0; j < gradientRecords.length; j++) {
|
||||
GRADRECORD r = gradientRecords[j];
|
||||
GRADRECORD r2 = gradientRecordsEnd[j];
|
||||
fillData += "\tvar s = "+useRatioDouble(
|
||||
fillData += "\tvar s = " + useRatioDouble(
|
||||
pos + (oneHeight * (revert ? 255 - r.ratio : r.ratio) / 255.0),
|
||||
pos + (oneHeight * (revert ? 255 - r2.ratio : r2.ratio) / 255.0)
|
||||
)+";\r\n\tif(s<0) s = 0;\r\n\tif(s>1) s = 1;\r\n";
|
||||
fillData += "\tgrd.addColorStop(s," + useRatioColor(r.color,r2.color) + ");\r\n";
|
||||
lastRadColor = useRatioColor(r.color,r2.color);
|
||||
) + ";\r\n\tif(s<0) s = 0;\r\n\tif(s>1) s = 1;\r\n";
|
||||
fillData += "\tgrd.addColorStop(s," + useRatioColor(r.color, r2.color) + ");\r\n";
|
||||
lastRadColor = useRatioColor(r.color, r2.color);
|
||||
}
|
||||
pos += oneHeight;
|
||||
}
|
||||
@@ -247,7 +238,7 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
imageData = baos.toByteArray();
|
||||
}
|
||||
//String base64ImgData = DatatypeConverter.printBase64Binary(imageData);
|
||||
if (matrix != null) {
|
||||
if (matrix != null) {
|
||||
fillMatrix = matrix.clone();
|
||||
fillMatrix.translateX /= unitDivisor;
|
||||
fillMatrix.translateY /= unitDivisor;
|
||||
@@ -257,8 +248,7 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
fillMatrix.rotateSkew1 /= unitDivisor;
|
||||
fillMatrix.translateX += deltaX / unitDivisor;
|
||||
fillMatrix.translateY += deltaY / unitDivisor;
|
||||
|
||||
|
||||
|
||||
fillMatrixEnd = matrixEnd.clone();
|
||||
fillMatrixEnd.translateX /= unitDivisor;
|
||||
fillMatrixEnd.translateY /= unitDivisor;
|
||||
@@ -272,7 +262,7 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
}
|
||||
|
||||
//fillData += "\tvar img = document.createElement(\"img\");\r\nimg.src=\"data:image/" + format + ";base64," + base64ImgData + "\";\r\n";
|
||||
fillData += "\tvar pat=ctx.createPattern(image"+bitmapId+",\"repeat\");\r\n";
|
||||
fillData += "\tvar pat=ctx.createPattern(image" + bitmapId + ",\"repeat\");\r\n";
|
||||
fillData += "\tctx.fillStyle = pat;\r\n";
|
||||
}
|
||||
}
|
||||
@@ -288,10 +278,10 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
finalizePath();
|
||||
thickness /= unitDivisor;
|
||||
thicknessEnd /= unitDivisor;
|
||||
if(color!=null){ //for gradient line fill
|
||||
strokeData += "\tctx.strokeStyle=" + useRatioColor(color,colorEnd) + ";\r\n";
|
||||
if (color != null) { //for gradient line fill
|
||||
strokeData += "\tctx.strokeStyle=" + useRatioColor(color, colorEnd) + ";\r\n";
|
||||
}
|
||||
strokeData += "\tctx.lineWidth="+useRatioDouble(thickness,thicknessEnd)+";\r\n";
|
||||
strokeData += "\tctx.lineWidth=" + useRatioDouble(thickness, thicknessEnd) + ";\r\n";
|
||||
switch (startCaps) {
|
||||
case LINESTYLE2.NO_CAP:
|
||||
strokeData += "\tctx.lineCap=\"butt\";\r\n";
|
||||
@@ -320,7 +310,6 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
@Override
|
||||
public void lineGradientStyle(int type, GRADRECORD[] gradientRecords, GRADRECORD[] gradientRecordsEnd, Matrix matrix, Matrix matrixEnd, int spreadMethod, int interpolationMethod, float focalPointRatio, float focalPointRatioEnd) {
|
||||
lineFillData = "";
|
||||
|
||||
|
||||
//TODO: How many repeats is ideal?
|
||||
final int REPEAT_CNT = 5;
|
||||
@@ -334,14 +323,13 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
start.y += deltaY;
|
||||
end.x += deltaX;
|
||||
end.y += deltaY;
|
||||
|
||||
|
||||
|
||||
Point start2 = matrixEnd.transform(new Point(-16384 - 32768 * repeatCnt, 0));
|
||||
Point end2 = matrixEnd.transform(new Point(16384 + 32768 * repeatCnt, 0));
|
||||
start2.x += deltaX;
|
||||
start2.y += deltaY;
|
||||
end2.x += deltaX;
|
||||
end2.y += deltaY;
|
||||
end2.y += deltaY;
|
||||
lineFillData += "\tvar grd=ctx.createLinearGradient(" + useRatioPos(start.x, start2.x) + "," + useRatioPos(start.y, start2.y) + "," + useRatioPos(end.x, end2.x) + "," + useRatioPos(end.y, end2.y) + ");\r\n";
|
||||
} else {
|
||||
matrix.translateX /= unitDivisor;
|
||||
@@ -354,9 +342,6 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
matrix.translateY += deltaY / unitDivisor;
|
||||
lineFillMatrix = matrix;
|
||||
|
||||
|
||||
|
||||
|
||||
matrixEnd.translateX /= unitDivisor;
|
||||
matrixEnd.translateY /= unitDivisor;
|
||||
matrixEnd.scaleX /= unitDivisor;
|
||||
@@ -367,8 +352,7 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
matrixEnd.translateY += deltaY / unitDivisor;
|
||||
lineFillMatrixEnd = matrixEnd;
|
||||
|
||||
|
||||
lineFillData += "\tvar grd=ctx.createRadialGradient("+useRatioDouble(focalPointRatio*16384,focalPointRatioEnd*16384)+",0,0,0,0," + (16384 + 32768 * repeatCnt) + ");\r\n";
|
||||
lineFillData += "\tvar grd=ctx.createRadialGradient(" + useRatioDouble(focalPointRatio * 16384, focalPointRatioEnd * 16384) + ",0,0,0,0," + (16384 + 32768 * repeatCnt) + ");\r\n";
|
||||
}
|
||||
int repeatTotal = lineRepeatCnt * 2 + 1;
|
||||
double oneHeight = 1.0 / repeatTotal;
|
||||
@@ -381,27 +365,27 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
if (spreadMethod == GRADIENT.SPREAD_REFLECT_MODE) {
|
||||
revert = !revert;
|
||||
}
|
||||
for (int j=0;j<gradientRecords.length;j++) {
|
||||
for (int j = 0; j < gradientRecords.length; j++) {
|
||||
GRADRECORD r = gradientRecords[j];
|
||||
GRADRECORD r2 = gradientRecordsEnd[j];
|
||||
lineFillData += "\tvar s="+useRatioDouble(pos + (oneHeight * (revert ? 255 - r.ratio : r.ratio) / 255.0), pos + (oneHeight * (revert ? 255 - r2.ratio : r2.ratio) / 255.0))+";\r\n";
|
||||
lineFillData += "\tvar s=" + useRatioDouble(pos + (oneHeight * (revert ? 255 - r.ratio : r.ratio) / 255.0), pos + (oneHeight * (revert ? 255 - r2.ratio : r2.ratio) / 255.0)) + ";\r\n";
|
||||
lineFillData += "\tif(s<0) s = 0;\r\n\tif(s>1) s = 1;\r\n";
|
||||
lineFillData += "\tgrd.addColorStop(s," + useRatioColor(r.color,r2.color) + ");\r\n";
|
||||
lineLastRadColor = useRatioColor(r.color,r2.color);
|
||||
lineFillData += "\tgrd.addColorStop(s," + useRatioColor(r.color, r2.color) + ");\r\n";
|
||||
lineLastRadColor = useRatioColor(r.color, r2.color);
|
||||
}
|
||||
pos += oneHeight;
|
||||
}
|
||||
lineFillData += "\tctx.fillStyle = grd;\r\n";
|
||||
|
||||
|
||||
String preStrokeData = "";
|
||||
|
||||
|
||||
preStrokeData += "\tvar lcanvas = document.createElement(\"canvas\");\r\n";
|
||||
preStrokeData += "\tlcanvas.width = canvas.width;\r\n";
|
||||
preStrokeData += "\tlcanvas.height=canvas.height;\r\n";
|
||||
preStrokeData += "\tvar lctx = lcanvas.getContext(\"2d\");\r\n";
|
||||
preStrokeData += "\tenhanceContext(lctx);\r\n";
|
||||
preStrokeData += "\tlctx.applyTransforms(ctx._matrices);\r\n";
|
||||
preStrokeData += "\tctx = lctx;\r\n";
|
||||
preStrokeData += "\tctx = lctx;\r\n";
|
||||
strokeData = preStrokeData + strokeData;
|
||||
}
|
||||
|
||||
@@ -412,8 +396,8 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
x2 += deltaX;
|
||||
y2 += deltaY;
|
||||
pathData += "\tctx.moveTo("
|
||||
+ useRatioPos(x,x2) + ","
|
||||
+ useRatioPos(y,y2) + ");\r\n";
|
||||
+ useRatioPos(x, x2) + ","
|
||||
+ useRatioPos(y, y2) + ");\r\n";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -423,8 +407,8 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
x2 += deltaX;
|
||||
y2 += deltaY;
|
||||
pathData += "\tctx.lineTo("
|
||||
+ useRatioPos(x,x2) + ","
|
||||
+ useRatioPos(y,y2) + ");\r\n";
|
||||
+ useRatioPos(x, x2) + ","
|
||||
+ useRatioPos(y, y2) + ");\r\n";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -433,23 +417,22 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
anchorX += deltaX;
|
||||
controlY += deltaY;
|
||||
anchorY += deltaY;
|
||||
|
||||
|
||||
controlX2 += deltaX;
|
||||
anchorX2 += deltaX;
|
||||
controlY2 += deltaY;
|
||||
anchorY2 += deltaY;
|
||||
|
||||
|
||||
pathData += "\tctx.quadraticCurveTo(" + useRatioPos(controlX,controlX2) + ","
|
||||
+ useRatioPos(controlY,controlY2) + ","
|
||||
+ useRatioPos(anchorX,anchorX2) + ","
|
||||
+ useRatioPos(anchorY,anchorY2) + ");\r\n";
|
||||
|
||||
pathData += "\tctx.quadraticCurveTo(" + useRatioPos(controlX, controlX2) + ","
|
||||
+ useRatioPos(controlY, controlY2) + ","
|
||||
+ useRatioPos(anchorX, anchorX2) + ","
|
||||
+ useRatioPos(anchorY, anchorY2) + ");\r\n";
|
||||
}
|
||||
|
||||
protected void finalizePath() {
|
||||
if (!"".equals(pathData)) {
|
||||
pathData = "\tctx.beginPath();\r\n" + pathData + "\tctx.closePath();\r\n";
|
||||
if(lineFillData!=null){
|
||||
if (lineFillData != null) {
|
||||
String preLineFillData = "";
|
||||
preLineFillData += "\tvar oldctx = ctx;\r\n";
|
||||
preLineFillData += "\tctx.save();\r\n";
|
||||
@@ -466,28 +449,26 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
if (lineLastRadColor != null) {
|
||||
preLineFillData += "\tctx.fillStyle=" + lineLastRadColor + ";\r\n ctx.fill(\"evenodd\");\r\n";
|
||||
}
|
||||
preLineFillData += "\tctx.transform(" + useRatioDouble(lineFillMatrix.scaleX,lineFillMatrixEnd.scaleX) + "," + useRatioDouble(lineFillMatrix.rotateSkew0,lineFillMatrixEnd.rotateSkew0) + "," + useRatioDouble(lineFillMatrix.rotateSkew1,lineFillMatrixEnd.rotateSkew1) + "," + useRatioDouble(lineFillMatrix.scaleY,lineFillMatrixEnd.scaleY) + "," + useRatioDouble(lineFillMatrix.translateX,lineFillMatrixEnd.translateX) + "," + useRatioDouble(lineFillMatrix.translateY,lineFillMatrixEnd.translateY) + ");\r\n";
|
||||
preLineFillData += "\tctx.transform(" + useRatioDouble(lineFillMatrix.scaleX, lineFillMatrixEnd.scaleX) + "," + useRatioDouble(lineFillMatrix.rotateSkew0, lineFillMatrixEnd.rotateSkew0) + "," + useRatioDouble(lineFillMatrix.rotateSkew1, lineFillMatrixEnd.rotateSkew1) + "," + useRatioDouble(lineFillMatrix.scaleY, lineFillMatrixEnd.scaleY) + "," + useRatioDouble(lineFillMatrix.translateX, lineFillMatrixEnd.translateX) + "," + useRatioDouble(lineFillMatrix.translateY, lineFillMatrixEnd.translateY) + ");\r\n";
|
||||
lineFillData = preLineFillData + lineFillData;
|
||||
lineFillData += "\tctx.fillRect(" + (-16384 - 32768 * lineRepeatCnt) + "," + (-16384 - 32768 * lineRepeatCnt) + "," + (2 * 16384 + 32768 * 2 * lineRepeatCnt) + "," + (2 * 16384 + 32768 * 2 * lineRepeatCnt) + ");\r\n";
|
||||
lineFillData += "\tctx = oldctx;\r\n";
|
||||
|
||||
|
||||
lineFillData += "\tctx = oldctx;\r\n";
|
||||
|
||||
//lcanvas - stroke
|
||||
//lfcanvas - stroke background
|
||||
|
||||
lineFillData += "\tvar limgd = lctx.getImageData(0, 0, lcanvas.width, lcanvas.height);\r\n"
|
||||
+ "\tvar lpix = limgd.data;\r\n"
|
||||
+ "\tvar lfimgd = lfctx.getImageData(0, 0, lfcanvas.width, lfcanvas.height);\r\n"
|
||||
+ "\tvar lfpix = lfimgd.data;\r\n"
|
||||
+ "\tvar imgd = ctx.getImageData(0, 0, canvas.width, canvas.height);\r\n"
|
||||
+ "\tvar pix = imgd.data;\r\n"
|
||||
+ "\tfor (var i = 0; i < lpix.length; i += 4) {\r\n" +
|
||||
"\t\tif(lpix[i+3]>0){ pix[i] = lfpix[i]; pix[i+1] = lfpix[i+1]; pix[i+2] = lfpix[i+2]; pix[i+3] = lfpix[i+3];}\r\n" +
|
||||
"\t}\r\n"
|
||||
+ "\tfor (var i = 0; i < lpix.length; i += 4) {\r\n"
|
||||
+ "\t\tif(lpix[i+3]>0){ pix[i] = lfpix[i]; pix[i+1] = lfpix[i+1]; pix[i+2] = lfpix[i+2]; pix[i+3] = lfpix[i+3];}\r\n"
|
||||
+ "\t}\r\n"
|
||||
+ "\tctx.putImageData(imgd, 0, 0);\r\n";
|
||||
lineFillData += "\tctx.restore();\r\n";
|
||||
lineFillData += "\tctx.restore();\r\n";
|
||||
strokeData = "";
|
||||
}else{
|
||||
} else {
|
||||
pathData += strokeData;
|
||||
}
|
||||
if (fillMatrix != null) {
|
||||
@@ -496,7 +477,7 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
}
|
||||
pathData += "\tctx.save();\r\n";
|
||||
pathData += "\tctx.clip();\r\n";
|
||||
pathData += "\tctx.transform(" + useRatioDouble(fillMatrix.scaleX,fillMatrixEnd.scaleX) + "," + useRatioDouble(fillMatrix.rotateSkew0,fillMatrixEnd.rotateSkew0) + "," + useRatioDouble(fillMatrix.rotateSkew1,fillMatrixEnd.rotateSkew1) + "," + useRatioDouble(fillMatrix.scaleY,fillMatrixEnd.scaleY) + "," + useRatioDouble(fillMatrix.translateX,fillMatrixEnd.translateX) + "," + useRatioDouble(fillMatrix.translateY,fillMatrixEnd.translateY) + ");\r\n";
|
||||
pathData += "\tctx.transform(" + useRatioDouble(fillMatrix.scaleX, fillMatrixEnd.scaleX) + "," + useRatioDouble(fillMatrix.rotateSkew0, fillMatrixEnd.rotateSkew0) + "," + useRatioDouble(fillMatrix.rotateSkew1, fillMatrixEnd.rotateSkew1) + "," + useRatioDouble(fillMatrix.scaleY, fillMatrixEnd.scaleY) + "," + useRatioDouble(fillMatrix.translateX, fillMatrixEnd.translateX) + "," + useRatioDouble(fillMatrix.translateY, fillMatrixEnd.translateY) + ");\r\n";
|
||||
pathData += fillData;
|
||||
pathData += "\tctx.fillRect(" + (-16384 - 32768 * repeatCnt) + "," + (-16384 - 32768 * repeatCnt) + "," + (2 * 16384 + 32768 * 2 * repeatCnt) + "," + (2 * 16384 + 32768 * 2 * repeatCnt) + ");\r\n";
|
||||
pathData += "\tctx.restore();\r\n";
|
||||
@@ -509,7 +490,7 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
}
|
||||
if (!"".equals(strokeData)) {
|
||||
shapeData += "\tctx.stroke();\r\n";
|
||||
}else if(lineFillData!=null){
|
||||
} else if (lineFillData != null) {
|
||||
shapeData += lineFillData;
|
||||
}
|
||||
}
|
||||
@@ -521,7 +502,7 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
fillMatrix = null;
|
||||
fillMatrixEnd = null;
|
||||
lastRadColor = null;
|
||||
|
||||
|
||||
lineRepeatCnt = 0;
|
||||
lineFillData = null;
|
||||
lineLastRadColor = null;
|
||||
@@ -529,23 +510,23 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
lineFillMatrixEnd = null;
|
||||
}
|
||||
|
||||
private String useRatioPos(double a, double b){
|
||||
return (a / unitDivisor) + "+ratio*(" +((b-a)/unitDivisor)+")/"+DefineMorphShapeTag.MAX_RATIO;
|
||||
private String useRatioPos(double a, double b) {
|
||||
return (a / unitDivisor) + "+ratio*(" + ((b - a) / unitDivisor) + ")/" + DefineMorphShapeTag.MAX_RATIO;
|
||||
}
|
||||
|
||||
private String useRatioInt(int a, int b){
|
||||
return "Math.round("+ a + "+ratio*(" +((b-a))+")/"+DefineMorphShapeTag.MAX_RATIO+")";
|
||||
|
||||
private String useRatioInt(int a, int b) {
|
||||
return "Math.round(" + a + "+ratio*(" + ((b - a)) + ")/" + DefineMorphShapeTag.MAX_RATIO + ")";
|
||||
}
|
||||
|
||||
private String useRatioDouble(double a, double b){
|
||||
return "" + a + "+ratio*(" +((b-a))+")/"+DefineMorphShapeTag.MAX_RATIO;
|
||||
|
||||
private String useRatioDouble(double a, double b) {
|
||||
return "" + a + "+ratio*(" + ((b - a)) + ")/" + DefineMorphShapeTag.MAX_RATIO;
|
||||
}
|
||||
|
||||
public String getShapeData() {
|
||||
return shapeData;
|
||||
}
|
||||
|
||||
private String useRatioColor(RGB color, RGB colorEnd){
|
||||
return "\"rgba(\"+" + useRatioInt(color.red,colorEnd.red)+"+\",\"+"+useRatioInt(color.green,colorEnd.green)+"+\",\"+"+useRatioInt(color.blue,colorEnd.blue)+"+\",\"+(("+useRatioInt((color instanceof RGBA)?((RGBA)color).alpha:255,(colorEnd instanceof RGBA)?((RGBA)colorEnd).alpha:255) + ")/255)+\")\"";
|
||||
}
|
||||
|
||||
private String useRatioColor(RGB color, RGB colorEnd) {
|
||||
return "\"rgba(\"+" + useRatioInt(color.red, colorEnd.red) + "+\",\"+" + useRatioInt(color.green, colorEnd.green) + "+\",\"+" + useRatioInt(color.blue, colorEnd.blue) + "+\",\"+((" + useRatioInt((color instanceof RGBA) ? ((RGBA) color).alpha : 255, (colorEnd instanceof RGBA) ? ((RGBA) colorEnd).alpha : 255) + ")/255)+\")\"";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,8 +144,4 @@ public abstract class DefaultSVGMorphShapeExporter extends MorphShapeExporterBas
|
||||
protected double roundPixels20(double pixels) {
|
||||
return Math.round(pixels * 100) / 100.0;
|
||||
}
|
||||
|
||||
protected double roundPixels400(double pixels) {
|
||||
return Math.round(pixels * 10000) / 10000.0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -431,7 +431,7 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
|
||||
case FILLSTYLE.FOCAL_RADIAL_GRADIENT:
|
||||
// Gradient fill
|
||||
Matrix matrix = new Matrix(fillStyle.gradientMatrix);
|
||||
Matrix matrixEnd = new Matrix(fillStyleEnd.gradientMatrix);
|
||||
Matrix matrixEnd = new Matrix(fillStyleEnd.gradientMatrix);
|
||||
lineGradientStyle(
|
||||
fillStyle.fillStyleType,
|
||||
fillStyle.gradient.gradientRecords,
|
||||
|
||||
@@ -254,41 +254,35 @@ public class SVGMorphShapeExporter extends DefaultSVGMorphShapeExporter {
|
||||
private void addMatrixAnimation(Element element, String attribute, Matrix matrix, Matrix matrixEnd) {
|
||||
final int animationLength = 2; // todo
|
||||
final String animationLengthStr = animationLength + "s";
|
||||
|
||||
element.setAttribute(attribute, matrix.getTransformationString(SWF.unitDivisor, 1));
|
||||
|
||||
// QR decomposition
|
||||
double translateX = roundPixels400(matrix.translateX / SWF.unitDivisor);
|
||||
double translateY = roundPixels400(matrix.translateY / SWF.unitDivisor);
|
||||
double rotateSkew0 = roundPixels400(matrix.rotateSkew0);
|
||||
double rotateSkew1 = roundPixels400(matrix.rotateSkew1);
|
||||
double scaleXStart = roundPixels400(matrix.scaleX);
|
||||
double scaleYStart = roundPixels400(matrix.scaleY);
|
||||
|
||||
element.setAttribute(attribute, "matrix(" + scaleXStart + ", " + rotateSkew0
|
||||
+ ", " + rotateSkew1 + ", " + scaleYStart + ", " + translateX + ", " + translateY + ")");
|
||||
|
||||
// QR decomposition
|
||||
|
||||
double a = roundPixels400(matrix.scaleX);
|
||||
double b = roundPixels400(matrix.rotateSkew0);
|
||||
double c = roundPixels400(matrix.rotateSkew1);
|
||||
double d = roundPixels400(matrix.scaleY);
|
||||
double a = matrix.scaleX;
|
||||
double b = matrix.rotateSkew0;
|
||||
double c = matrix.rotateSkew1;
|
||||
double d = matrix.scaleY;
|
||||
double r = Math.sqrt(a * a + b * b);
|
||||
double det = a * d - b * c;
|
||||
double rotate = Math.signum(b) * Math.acos(a / r) * 180 / Math.PI;
|
||||
double scaleX = r;
|
||||
double scaleY = det / r;
|
||||
double skewX = Math.atan((a * c + b * d) / (r * r)) * 180 / Math.PI;
|
||||
double rotate = roundPixels400(Math.signum(b) * Math.acos(a / r) * 180 / Math.PI);
|
||||
double scaleX = roundPixels400(r);
|
||||
double scaleY = roundPixels400(det / r);
|
||||
double skewX = roundPixels400(Math.atan((a * c + b * d) / (r * r)) * 180 / Math.PI);
|
||||
|
||||
double translateXEnd = roundPixels400(matrixEnd.translateX / SWF.unitDivisor);
|
||||
double translateYEnd = roundPixels400(matrixEnd.translateY / SWF.unitDivisor);
|
||||
a = roundPixels400(matrixEnd.scaleX);
|
||||
b = roundPixels400(matrixEnd.rotateSkew0);
|
||||
c = roundPixels400(matrixEnd.rotateSkew1);
|
||||
d = roundPixels400(matrixEnd.scaleY);
|
||||
a = matrixEnd.scaleX;
|
||||
b = matrixEnd.rotateSkew0;
|
||||
c = matrixEnd.rotateSkew1;
|
||||
d = matrixEnd.scaleY;
|
||||
double rEnd = Math.sqrt(a * a + b * b);
|
||||
double detEnd = a * d - b * c;
|
||||
double rotateEnd = Math.signum(b) * Math.acos(a / rEnd) * 180 / Math.PI;
|
||||
double scaleXEnd = rEnd;
|
||||
double scaleYEnd = detEnd / rEnd;
|
||||
double skewXEnd = Math.atan((a * c + b * d) / (rEnd * rEnd)) * 180 / Math.PI;
|
||||
double rotateEnd = roundPixels400(Math.signum(b) * Math.acos(a / rEnd) * 180 / Math.PI);
|
||||
double scaleXEnd = roundPixels400(rEnd);
|
||||
double scaleYEnd = roundPixels400(detEnd / rEnd);
|
||||
double skewXEnd = roundPixels400(Math.atan((a * c + b * d) / (rEnd * rEnd)) * 180 / Math.PI);
|
||||
|
||||
Element animateClear = exporter.createElement("animateTransform");
|
||||
animateClear.setAttribute("dur", animationLengthStr);
|
||||
@@ -342,82 +336,84 @@ public class SVGMorphShapeExporter extends DefaultSVGMorphShapeExporter {
|
||||
element.appendChild(animateSkewX);
|
||||
|
||||
/*
|
||||
// LDU decomposition
|
||||
// LDU decomposition
|
||||
|
||||
double a = roundPixels400(matrix.scaleX);
|
||||
double b = roundPixels400(matrix.rotateSkew0);
|
||||
double c = roundPixels400(matrix.rotateSkew1);
|
||||
double d = roundPixels400(matrix.scaleY);
|
||||
double det = a * d - b * c;
|
||||
double skewY = Math.atan2(b, a) * 180 / Math.PI;
|
||||
double scaleX = a;
|
||||
double scaleY = det / a;
|
||||
double skewX = Math.atan2(c, a) * 180 / Math.PI;
|
||||
double translateX = roundPixels400(matrix.translateX / SWF.unitDivisor);
|
||||
double translateY = roundPixels400(matrix.translateY / SWF.unitDivisor);
|
||||
double a = matrix.scaleX;
|
||||
double b = matrix.rotateSkew0;
|
||||
double c = matrix.rotateSkew1;
|
||||
double d = matrix.scaleY;
|
||||
double det = a * d - b * c;
|
||||
double skewY = roundPixels400(Math.atan2(b, a) * 180 / Math.PI);
|
||||
double scaleX = roundPixels400(a);
|
||||
double scaleY = roundPixels400(det / a);
|
||||
double skewX = roundPixels400(Math.atan2(c, a) * 180 / Math.PI);
|
||||
|
||||
double translateXEnd = roundPixels400(matrixEnd.translateX / SWF.unitDivisor);
|
||||
double translateYEnd = roundPixels400(matrixEnd.translateY / SWF.unitDivisor);
|
||||
a = roundPixels400(matrixEnd.scaleX);
|
||||
b = roundPixels400(matrixEnd.rotateSkew0);
|
||||
c = roundPixels400(matrixEnd.rotateSkew1);
|
||||
d = roundPixels400(matrixEnd.scaleY);
|
||||
double detEnd = a * d - b * c;
|
||||
double skewYEnd = Math.atan2(b, a) * 180 / Math.PI;
|
||||
double scaleXEnd = a;
|
||||
double scaleYEnd = detEnd / a;
|
||||
double skewXEnd = Math.atan2(c, a) * 180 / Math.PI;
|
||||
double translateXEnd = roundPixels400(matrixEnd.translateX / SWF.unitDivisor);
|
||||
double translateYEnd = roundPixels400(matrixEnd.translateY / SWF.unitDivisor);
|
||||
a = matrixEnd.scaleX;
|
||||
b = matrixEnd.rotateSkew0;
|
||||
c = matrixEnd.rotateSkew1;
|
||||
d = matrixEnd.scaleY;
|
||||
double detEnd = a * d - b * c;
|
||||
double skewYEnd = roundPixels400(Math.atan2(b, a) * 180 / Math.PI);
|
||||
double scaleXEnd = roundPixels400(a);
|
||||
double scaleYEnd = roundPixels400(detEnd / a);
|
||||
double skewXEnd = roundPixels400(Math.atan2(c, a) * 180 / Math.PI);
|
||||
|
||||
Element animateClear = exporter.createElement("animateTransform");
|
||||
animateClear.setAttribute("dur", animationLengthStr);
|
||||
animateClear.setAttribute("repeatCount", "indefinite");
|
||||
animateClear.setAttribute("attributeName", attribute);
|
||||
animateClear.setAttribute("type", "scale");
|
||||
animateClear.setAttribute("additive", "replace");
|
||||
animateClear.setAttribute("from", "1");
|
||||
animateClear.setAttribute("to", "1");
|
||||
Element animateClear = exporter.createElement("animateTransform");
|
||||
animateClear.setAttribute("dur", animationLengthStr);
|
||||
animateClear.setAttribute("repeatCount", "indefinite");
|
||||
animateClear.setAttribute("attributeName", attribute);
|
||||
animateClear.setAttribute("type", "scale");
|
||||
animateClear.setAttribute("additive", "replace");
|
||||
animateClear.setAttribute("from", "1");
|
||||
animateClear.setAttribute("to", "1");
|
||||
|
||||
Element animateTranslate = exporter.createElement("animateTransform");
|
||||
animateTranslate.setAttribute("dur", animationLengthStr);
|
||||
animateTranslate.setAttribute("repeatCount", "indefinite");
|
||||
animateTranslate.setAttribute("attributeName", attribute);
|
||||
animateTranslate.setAttribute("type", "translate");
|
||||
animateTranslate.setAttribute("additive", "sum");
|
||||
animateTranslate.setAttribute("from", translateX + " " + translateY);
|
||||
animateTranslate.setAttribute("to", translateXEnd + " " + translateYEnd);
|
||||
Element animateTranslate = exporter.createElement("animateTransform");
|
||||
animateTranslate.setAttribute("dur", animationLengthStr);
|
||||
animateTranslate.setAttribute("repeatCount", "indefinite");
|
||||
animateTranslate.setAttribute("attributeName", attribute);
|
||||
animateTranslate.setAttribute("type", "translate");
|
||||
animateTranslate.setAttribute("additive", "sum");
|
||||
animateTranslate.setAttribute("from", translateX + " " + translateY);
|
||||
animateTranslate.setAttribute("to", translateXEnd + " " + translateYEnd);
|
||||
|
||||
Element animateSkewY = exporter.createElement("animateTransform");
|
||||
animateSkewY.setAttribute("dur", animationLengthStr);
|
||||
animateSkewY.setAttribute("repeatCount", "indefinite");
|
||||
animateSkewY.setAttribute("attributeName", attribute);
|
||||
animateSkewY.setAttribute("type", "skewY");
|
||||
animateSkewY.setAttribute("additive", "sum");
|
||||
animateSkewY.setAttribute("from", Double.toString(skewY));
|
||||
animateSkewY.setAttribute("to", Double.toString(skewYEnd));
|
||||
Element animateSkewY = exporter.createElement("animateTransform");
|
||||
animateSkewY.setAttribute("dur", animationLengthStr);
|
||||
animateSkewY.setAttribute("repeatCount", "indefinite");
|
||||
animateSkewY.setAttribute("attributeName", attribute);
|
||||
animateSkewY.setAttribute("type", "skewY");
|
||||
animateSkewY.setAttribute("additive", "sum");
|
||||
animateSkewY.setAttribute("from", Double.toString(skewY));
|
||||
animateSkewY.setAttribute("to", Double.toString(skewYEnd));
|
||||
|
||||
Element animateScale = exporter.createElement("animateTransform");
|
||||
animateScale.setAttribute("dur", animationLengthStr);
|
||||
animateScale.setAttribute("repeatCount", "indefinite");
|
||||
animateScale.setAttribute("attributeName", attribute);
|
||||
animateScale.setAttribute("type", "scale");
|
||||
animateScale.setAttribute("additive", "sum");
|
||||
animateScale.setAttribute("from", scaleX + " " + scaleY);
|
||||
animateScale.setAttribute("to", scaleXEnd + " " + scaleYEnd);
|
||||
Element animateScale = exporter.createElement("animateTransform");
|
||||
animateScale.setAttribute("dur", animationLengthStr);
|
||||
animateScale.setAttribute("repeatCount", "indefinite");
|
||||
animateScale.setAttribute("attributeName", attribute);
|
||||
animateScale.setAttribute("type", "scale");
|
||||
animateScale.setAttribute("additive", "sum");
|
||||
animateScale.setAttribute("from", scaleX + " " + scaleY);
|
||||
animateScale.setAttribute("to", scaleXEnd + " " + scaleYEnd);
|
||||
|
||||
Element animateSkewX = exporter.createElement("animateTransform");
|
||||
animateSkewX.setAttribute("dur", animationLengthStr);
|
||||
animateSkewX.setAttribute("repeatCount", "indefinite");
|
||||
animateSkewX.setAttribute("attributeName", attribute);
|
||||
animateSkewX.setAttribute("type", "skewX");
|
||||
animateSkewX.setAttribute("additive", "sum");
|
||||
animateSkewX.setAttribute("from", Double.toString(skewX));
|
||||
animateSkewX.setAttribute("to", Double.toString(skewXEnd));
|
||||
Element animateSkewX = exporter.createElement("animateTransform");
|
||||
animateSkewX.setAttribute("dur", animationLengthStr);
|
||||
animateSkewX.setAttribute("repeatCount", "indefinite");
|
||||
animateSkewX.setAttribute("attributeName", attribute);
|
||||
animateSkewX.setAttribute("type", "skewX");
|
||||
animateSkewX.setAttribute("additive", "sum");
|
||||
animateSkewX.setAttribute("from", Double.toString(skewX));
|
||||
animateSkewX.setAttribute("to", Double.toString(skewXEnd));
|
||||
|
||||
element.appendChild(animateClear);
|
||||
element.appendChild(animateTranslate);
|
||||
element.appendChild(animateSkewY);
|
||||
element.appendChild(animateScale);
|
||||
element.appendChild(animateSkewX);*/
|
||||
element.appendChild(animateClear);
|
||||
element.appendChild(animateTranslate);
|
||||
element.appendChild(animateSkewY);
|
||||
element.appendChild(animateScale);
|
||||
element.appendChild(animateSkewX);*/
|
||||
}
|
||||
|
||||
|
||||
protected void populateGradientElement(Element gradient, int type, GRADRECORD[] gradientRecords, GRADRECORD[] gradientRecordsEnd, Matrix matrix, Matrix matrixEnd, int spreadMethod, int interpolationMethod, float focalPointRatio) {
|
||||
gradient.setAttribute("gradientUnits", "userSpaceOnUse");
|
||||
if (type == FILLSTYLE.LINEAR_GRADIENT) {
|
||||
@@ -472,4 +468,8 @@ public class SVGMorphShapeExporter extends DefaultSVGMorphShapeExporter {
|
||||
gradient.appendChild(gradientEntry);
|
||||
}
|
||||
}
|
||||
|
||||
protected double roundPixels400(double pixels) {
|
||||
return Math.round(pixels * 10000) / 10000.0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class CanvasShapeExporter extends ShapeExporterBase {
|
||||
protected String lineLastRadColor = null;
|
||||
protected Matrix lineFillMatrix = null;
|
||||
protected int lineRepeatCnt = 0;
|
||||
|
||||
|
||||
public static String getJsPrefix() {
|
||||
return "var canvas=document.getElementById(\"myCanvas\");\r\n"
|
||||
+ "var ctx=canvas.getContext(\"2d\");\r\n"
|
||||
@@ -344,7 +344,6 @@ public class CanvasShapeExporter extends ShapeExporterBase {
|
||||
@Override
|
||||
public void lineGradientStyle(int type, GRADRECORD[] gradientRecords, Matrix matrix, int spreadMethod, int interpolationMethod, float focalPointRatio) {
|
||||
lineFillData = "";
|
||||
|
||||
|
||||
//TODO: How many repeats is ideal?
|
||||
final int REPEAT_CNT = 5;
|
||||
@@ -391,16 +390,16 @@ public class CanvasShapeExporter extends ShapeExporterBase {
|
||||
pos += oneHeight;
|
||||
}
|
||||
lineFillData += "\tctx.fillStyle = grd;\r\n";
|
||||
|
||||
|
||||
String preStrokeData = "";
|
||||
|
||||
|
||||
preStrokeData += "\tvar lcanvas = document.createElement(\"canvas\");\r\n";
|
||||
preStrokeData += "\tlcanvas.width = canvas.width;\r\n";
|
||||
preStrokeData += "\tlcanvas.height=canvas.height;\r\n";
|
||||
preStrokeData += "\tvar lctx = lcanvas.getContext(\"2d\");\r\n";
|
||||
preStrokeData += "\tenhanceContext(lctx);\r\n";
|
||||
preStrokeData += "\tlctx.applyTransforms(ctx._matrices);\r\n";
|
||||
preStrokeData += "\tctx = lctx;\r\n";
|
||||
preStrokeData += "\tctx = lctx;\r\n";
|
||||
strokeData = preStrokeData + strokeData;
|
||||
}
|
||||
|
||||
@@ -436,8 +435,8 @@ public class CanvasShapeExporter extends ShapeExporterBase {
|
||||
protected void finalizePath() {
|
||||
if (!"".equals(pathData)) {
|
||||
pathData = "\tctx.beginPath();\r\n" + pathData + "\tctx.closePath();\r\n";
|
||||
|
||||
if(lineFillData!=null){
|
||||
|
||||
if (lineFillData != null) {
|
||||
String preLineFillData = "";
|
||||
preLineFillData += "\tvar oldctx = ctx;\r\n";
|
||||
preLineFillData += "\tctx.save();\r\n";
|
||||
@@ -458,26 +457,24 @@ public class CanvasShapeExporter extends ShapeExporterBase {
|
||||
preLineFillData += "\tctx.transform(" + lineFillMatrix.scaleX + "," + lineFillMatrix.rotateSkew0 + "," + lineFillMatrix.rotateSkew1 + "," + lineFillMatrix.scaleY + "," + lineFillMatrix.translateX + "," + lineFillMatrix.translateY + ");\r\n";
|
||||
lineFillData = preLineFillData + lineFillData;
|
||||
lineFillData += "\tctx.fillRect(" + (-16384 - 32768 * lineRepeatCnt) + "," + (-16384 - 32768 * lineRepeatCnt) + "," + (2 * 16384 + 32768 * 2 * lineRepeatCnt) + "," + (2 * 16384 + 32768 * 2 * lineRepeatCnt) + ");\r\n";
|
||||
|
||||
lineFillData += "\tctx = oldctx;\r\n";
|
||||
|
||||
|
||||
|
||||
lineFillData += "\tctx = oldctx;\r\n";
|
||||
|
||||
//lcanvas - stroke
|
||||
//lfcanvas - stroke background
|
||||
|
||||
lineFillData += "\tvar limgd = lctx.getImageData(0, 0, lcanvas.width, lcanvas.height);\r\n"
|
||||
+ "\tvar lpix = limgd.data;\r\n"
|
||||
+ "\tvar lfimgd = lfctx.getImageData(0, 0, lfcanvas.width, lfcanvas.height);\r\n"
|
||||
+ "\tvar lfpix = lfimgd.data;\r\n"
|
||||
+ "\tvar imgd = ctx.getImageData(0, 0, canvas.width, canvas.height);\r\n"
|
||||
+ "\tvar pix = imgd.data;\r\n"
|
||||
+ "\tfor (var i = 0; i < lpix.length; i += 4) {\r\n" +
|
||||
"\t\tif(lpix[i+3]>0){ pix[i] = lfpix[i]; pix[i+1] = lfpix[i+1]; pix[i+2] = lfpix[i+2]; pix[i+3] = lfpix[i+3];}\r\n" +
|
||||
"\t}\r\n"
|
||||
+ "\tfor (var i = 0; i < lpix.length; i += 4) {\r\n"
|
||||
+ "\t\tif(lpix[i+3]>0){ pix[i] = lfpix[i]; pix[i+1] = lfpix[i+1]; pix[i+2] = lfpix[i+2]; pix[i+3] = lfpix[i+3];}\r\n"
|
||||
+ "\t}\r\n"
|
||||
+ "\tctx.putImageData(imgd, 0, 0);\r\n";
|
||||
lineFillData += "\tctx.restore();\r\n";
|
||||
lineFillData += "\tctx.restore();\r\n";
|
||||
strokeData = "";
|
||||
}else{
|
||||
} else {
|
||||
pathData += strokeData;
|
||||
}
|
||||
if (fillMatrix != null) {
|
||||
@@ -499,19 +496,19 @@ public class CanvasShapeExporter extends ShapeExporterBase {
|
||||
}
|
||||
if (!"".equals(strokeData)) {
|
||||
shapeData += "\tctx.stroke();\r\n";
|
||||
}else if(lineFillData!=null){
|
||||
} else if (lineFillData != null) {
|
||||
shapeData += lineFillData;
|
||||
}
|
||||
}
|
||||
|
||||
repeatCnt = 0;
|
||||
|
||||
|
||||
pathData = "";
|
||||
fillData = "";
|
||||
strokeData = "";
|
||||
fillMatrix = null;
|
||||
lastRadColor = null;
|
||||
|
||||
|
||||
lineRepeatCnt = 0;
|
||||
lineFillData = null;
|
||||
lineLastRadColor = null;
|
||||
|
||||
@@ -131,8 +131,4 @@ public abstract class DefaultSVGShapeExporter extends ShapeExporterBase {
|
||||
protected double roundPixels20(double pixels) {
|
||||
return Math.round(pixels * 100) / 100.0;
|
||||
}
|
||||
|
||||
protected double roundPixels400(double pixels) {
|
||||
return Math.round(pixels * 10000) / 10000.0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,14 +144,7 @@ public class SVGShapeExporter extends DefaultSVGShapeExporter {
|
||||
pattern.setAttribute("height", "" + height);
|
||||
pattern.setAttribute("viewBox", "0 0 " + width + " " + height);
|
||||
if (matrix != null) {
|
||||
double translateX = roundPixels400(matrix.translateX / SWF.unitDivisor);
|
||||
double translateY = roundPixels400(matrix.translateY / SWF.unitDivisor);
|
||||
double rotateSkew0 = roundPixels400(matrix.rotateSkew0 / SWF.unitDivisor);
|
||||
double rotateSkew1 = roundPixels400(matrix.rotateSkew1 / SWF.unitDivisor);
|
||||
double scaleX = roundPixels400(matrix.scaleX / SWF.unitDivisor);
|
||||
double scaleY = roundPixels400(matrix.scaleY / SWF.unitDivisor);
|
||||
pattern.setAttribute("patternTransform", "matrix(" + scaleX + ", " + rotateSkew0
|
||||
+ ", " + rotateSkew1 + ", " + scaleY + ", " + translateX + ", " + translateY + ")");
|
||||
pattern.setAttribute("patternTransform", matrix.getTransformationString(SWF.unitDivisor, SWF.unitDivisor));
|
||||
}
|
||||
Element imageElement = exporter.createElement("image");
|
||||
imageElement.setAttribute("width", "" + width);
|
||||
@@ -261,14 +254,7 @@ public class SVGShapeExporter extends DefaultSVGShapeExporter {
|
||||
gradient.setAttribute("color-interpolation", "linearRGB");
|
||||
}
|
||||
if (matrix != null) {
|
||||
double translateX = roundPixels400(matrix.translateX / SWF.unitDivisor);
|
||||
double translateY = roundPixels400(matrix.translateY / SWF.unitDivisor);
|
||||
double rotateSkew0 = roundPixels400(matrix.rotateSkew0);
|
||||
double rotateSkew1 = roundPixels400(matrix.rotateSkew1);
|
||||
double scaleX = roundPixels400(matrix.scaleX);
|
||||
double scaleY = roundPixels400(matrix.scaleY);
|
||||
gradient.setAttribute("gradientTransform", "matrix(" + scaleX + ", " + rotateSkew0
|
||||
+ ", " + rotateSkew1 + ", " + scaleY + ", " + translateX + ", " + translateY + ")");
|
||||
gradient.setAttribute("gradientTransform", matrix.getTransformationString(SWF.unitDivisor, 1));
|
||||
}
|
||||
for (int i = 0; i < gradientRecords.length; i++) {
|
||||
GRADRECORD record = gradientRecords[i];
|
||||
|
||||
@@ -1014,14 +1014,14 @@ public class Main {
|
||||
public static void exit() {
|
||||
Configuration.saveConfig();
|
||||
/*if (proxyFrame != null && Main.proxyFrame.isVisible()) {
|
||||
return;
|
||||
}
|
||||
if (loadFromMemoryFrame != null && Main.loadFromMemoryFrame.isVisible()) {
|
||||
return;
|
||||
}
|
||||
if (loadFromCacheFrame != null && loadFromCacheFrame.isVisible()) {
|
||||
return;
|
||||
}*/
|
||||
return;
|
||||
}
|
||||
if (loadFromMemoryFrame != null && Main.loadFromMemoryFrame.isVisible()) {
|
||||
return;
|
||||
}
|
||||
if (loadFromCacheFrame != null && loadFromCacheFrame.isVisible()) {
|
||||
return;
|
||||
}*/
|
||||
if (mainFrame != null && mainFrame.getPanel() != null) {
|
||||
mainFrame.getPanel().unloadFlashPlayer();
|
||||
}
|
||||
|
||||
@@ -1700,7 +1700,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void importTextsSingleFileFormatted(File textsFile, SWF swf) {
|
||||
String texts = Helper.readTextFile(textsFile.getPath());
|
||||
Map<Integer, String[]> records = splitTextRecords(texts);
|
||||
@@ -1723,7 +1723,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void importTextsMultipleFiles(String folder, SWF swf) {
|
||||
File textsFolder = new File(Path.combine(folder, TextExporter.TEXT_EXPORT_FOLDER));
|
||||
String[] files = textsFolder.list(new FilenameFilter() {
|
||||
@@ -1775,7 +1775,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void importText(final SWF swf) {
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
chooser.setCurrentDirectory(new File(Configuration.lastExportDir.get()));
|
||||
|
||||
@@ -185,7 +185,7 @@ public class PreviewImage extends JPanel {
|
||||
int h2 = PREVIEW_SIZE;
|
||||
|
||||
int w;
|
||||
int h = h1 * w2 / w1;
|
||||
int h = h1 * w2 / w1;
|
||||
if (h > h2) {
|
||||
w = w1 * h2 / h1;
|
||||
h = h2;
|
||||
|
||||
@@ -693,7 +693,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se
|
||||
decompiledTextArea.setClassIndex(-1);
|
||||
navigator.setClassIndex(-1, oldIndex);
|
||||
setDecompiledEditMode(false);
|
||||
View.showMessageDialog(this, AppStrings.translate("message.action.saved"));
|
||||
View.showMessageDialog(this, AppStrings.translate("message.action.saved"));
|
||||
reload();
|
||||
} catch (ParseException ex) {
|
||||
ex.printStackTrace();
|
||||
|
||||
@@ -131,7 +131,7 @@ public class MultinameTableModel implements TableModel {
|
||||
if (rowIndex == 0) {
|
||||
return "";
|
||||
}
|
||||
if (abc.constants.getMultiname(rowIndex).namespace_index <= 0 ) {
|
||||
if (abc.constants.getMultiname(rowIndex).namespace_index <= 0) {
|
||||
return "-";
|
||||
}
|
||||
return abc.constants.getMultiname(rowIndex).getNamespace(abc.constants).getNameWithKind(abc.constants);
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui.player;
|
||||
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
|
||||
import com.jpexs.decompiler.flash.gui.FlashUnsupportedException;
|
||||
import com.jpexs.helpers.CancellableWorker;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
|
||||
@@ -765,9 +765,8 @@ public class DefineEditTextTag extends TextTag {
|
||||
render(false, image, transformation, colorTransform);
|
||||
}
|
||||
|
||||
|
||||
private String render(boolean canvas,SerializableImage image, Matrix transformation, ColorTransform colorTransform){
|
||||
if(image == null){
|
||||
private String render(boolean canvas, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
|
||||
if (image == null) {
|
||||
return ""; //TODO: handle Html Canvas conversion
|
||||
}
|
||||
if (border) {
|
||||
@@ -945,8 +944,8 @@ public class DefineEditTextTag extends TextTag {
|
||||
staticTextToImage(swf, allTextRecords, 2, image, getTextMatrix(), transformation, colorTransform);
|
||||
}
|
||||
return ""; //TODO: Return HTML Canvas converted
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) {
|
||||
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
@@ -973,7 +972,7 @@ public class DefineEditTextTag extends TextTag {
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toHtmlCanvas(double unitDivisor) {
|
||||
return render(true, null, new Matrix(), new ColorTransform());
|
||||
|
||||
@@ -236,7 +236,7 @@ public class DefineFont2Tag extends FontTag {
|
||||
|
||||
glyphShapeTable = new ArrayList<>();
|
||||
for (int i = 0; i < numGlyphs; i++) {
|
||||
glyphShapeTable.add(sis.readSHAPE(1,false));
|
||||
glyphShapeTable.add(sis.readSHAPE(1, false));
|
||||
}
|
||||
|
||||
codeTable = new ArrayList<>(); //[numGlyphs];
|
||||
|
||||
@@ -323,5 +323,5 @@ public class DefineFontTag extends FontTag {
|
||||
@Override
|
||||
public int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,8 +160,8 @@ public class DefineMorphShape2Tag extends CharacterTag implements MorphShapeTag
|
||||
long offset = sis.readUI32();
|
||||
morphFillStyles = sis.readMORPHFILLSTYLEARRAY();
|
||||
morphLineStyles = sis.readMORPHLINESTYLEARRAY(2);
|
||||
startEdges = sis.readSHAPE(2,true);
|
||||
endEdges = sis.readSHAPE(2,true);
|
||||
startEdges = sis.readSHAPE(2, true);
|
||||
endEdges = sis.readSHAPE(2, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -357,12 +357,12 @@ public class DefineMorphShape2Tag extends CharacterTag implements MorphShapeTag
|
||||
public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) {
|
||||
return transformation.toTransform().createTransformedShape(getShapeAtRatio(ratio).getOutline());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toHtmlCanvas(double unitDivisor) {
|
||||
CanvasMorphShapeExporter cmse = new CanvasMorphShapeExporter(swf, getShapeAtRatio(0), getShapeAtRatio(MAX_RATIO), new ColorTransform(), unitDivisor, 0, 0);
|
||||
cmse.export();
|
||||
|
||||
|
||||
return cmse.getShapeData();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,8 +133,8 @@ public class DefineMorphShapeTag extends CharacterTag implements MorphShapeTag {
|
||||
long offset = sis.readUI32(); //ignore
|
||||
morphFillStyles = sis.readMORPHFILLSTYLEARRAY();
|
||||
morphLineStyles = sis.readMORPHLINESTYLEARRAY(1);
|
||||
startEdges = sis.readSHAPE(1,true);
|
||||
endEdges = sis.readSHAPE(1,true);
|
||||
startEdges = sis.readSHAPE(1, true);
|
||||
endEdges = sis.readSHAPE(1, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -340,12 +340,12 @@ public class DefineMorphShapeTag extends CharacterTag implements MorphShapeTag {
|
||||
public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) {
|
||||
return transformation.toTransform().createTransformedShape(getShapeAtRatio(ratio).getOutline());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toHtmlCanvas(double unitDivisor) {
|
||||
CanvasMorphShapeExporter cmse = new CanvasMorphShapeExporter(swf, getShapeAtRatio(0), getShapeAtRatio(MAX_RATIO), new ColorTransform(), unitDivisor, 0, 0);
|
||||
cmse.export();
|
||||
|
||||
|
||||
return cmse.getShapeData();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class DefineShape2Tag extends ShapeTag {
|
||||
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), swf.version);
|
||||
shapeId = sis.readUI16();
|
||||
shapeBounds = sis.readRECT();
|
||||
shapes = sis.readSHAPEWITHSTYLE(2,false);
|
||||
shapes = sis.readSHAPEWITHSTYLE(2, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -65,7 +65,7 @@ public class DefineShape3Tag extends ShapeTag {
|
||||
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), swf.version);
|
||||
shapeId = sis.readUI16();
|
||||
shapeBounds = sis.readRECT();
|
||||
shapes = sis.readSHAPEWITHSTYLE(3,false);
|
||||
shapes = sis.readSHAPEWITHSTYLE(3, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -78,7 +78,7 @@ public class DefineShape4Tag extends ShapeTag {
|
||||
usesFillWindingRule = sis.readUB(1) == 1;
|
||||
usesNonScalingStrokes = sis.readUB(1) == 1;
|
||||
usesScalingStrokes = sis.readUB(1) == 1;
|
||||
shapes = sis.readSHAPEWITHSTYLE(4,false);
|
||||
shapes = sis.readSHAPEWITHSTYLE(4, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -62,7 +62,7 @@ public class DefineShapeTag extends ShapeTag {
|
||||
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), swf.version);
|
||||
shapeId = sis.readUI16();
|
||||
shapeBounds = sis.readRECT();
|
||||
shapes = sis.readSHAPEWITHSTYLE(1,false);
|
||||
shapes = sis.readSHAPEWITHSTYLE(1, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -528,7 +528,7 @@ public class DefineTextTag extends TextTag {
|
||||
public boolean isSingleFrame() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toHtmlCanvas(double unitDivisor) {
|
||||
return staticTextToHtmlCanvas(unitDivisor, swf, textRecords, 1, textBounds, textMatrix, new ColorTransform());
|
||||
|
||||
@@ -78,10 +78,8 @@ public abstract class ButtonTag extends CharacterTag implements DrawableTag, Tim
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toHtmlCanvas(double unitDivisor) {
|
||||
public String toHtmlCanvas(double unitDivisor) {
|
||||
return getTimeline().toHtmlCanvas(unitDivisor, Arrays.asList(0)); //TODO: handle states?
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public interface DrawableTag extends BoundedTag {
|
||||
public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform);
|
||||
|
||||
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException;
|
||||
|
||||
|
||||
public String toHtmlCanvas(double unitDivisor);
|
||||
|
||||
public int getNumFrames();
|
||||
|
||||
@@ -311,7 +311,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
|
||||
}
|
||||
return dfn.fontCopyright;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toHtmlCanvas(double unitDivisor) {
|
||||
return ""; //TODO
|
||||
|
||||
@@ -80,5 +80,5 @@ public abstract class ImageTag extends CharacterTag {
|
||||
protected static Color multiplyAlpha(Color c) {
|
||||
float multiplier = c.getAlpha() == 0 ? 0 : 255.0f / c.getAlpha();
|
||||
return new Color(max255(c.getRed() * multiplier), max255(c.getGreen() * multiplier), max255(c.getBlue() * multiplier), c.getAlpha());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,17 +54,16 @@ public abstract class ShapeTag extends CharacterTag implements BoundedTag, Drawa
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException{
|
||||
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException {
|
||||
SVGShapeExporter shapeExporter = new SVGShapeExporter(swf, getShapes(), exporter, null, colorTransform);
|
||||
shapeExporter.export();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toHtmlCanvas(double unitDivisor) {
|
||||
CanvasShapeExporter cse = new CanvasShapeExporter(null,unitDivisor, swf, getShapes(), new ColorTransform(), 0, 0);
|
||||
CanvasShapeExporter cse = new CanvasShapeExporter(null, unitDivisor, swf, getShapes(), new ColorTransform(), 0, 0);
|
||||
cse.export();
|
||||
return cse.getShapeData();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ public abstract class TextTag extends CharacterTag implements BoundedTag, Drawab
|
||||
return att;
|
||||
}
|
||||
|
||||
public static SHAPE getBorderShape(RGB borderColor, RGB fillColor, RECT rect){
|
||||
public static SHAPE getBorderShape(RGB borderColor, RGB fillColor, RECT rect) {
|
||||
SHAPEWITHSTYLE shape = new SHAPEWITHSTYLE();
|
||||
shape.fillStyles = new FILLSTYLEARRAY();
|
||||
if (fillColor != null) {
|
||||
@@ -263,9 +263,9 @@ public abstract class TextTag extends CharacterTag implements BoundedTag, Drawab
|
||||
shape.shapeRecords.add(new EndShapeRecord());
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
||||
public static void drawBorder(SWF swf, SerializableImage image, RGB borderColor, RGB fillColor, RECT rect, MATRIX textMatrix, Matrix transformation, ColorTransform colorTransform) {
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
Matrix mat = transformation.clone();
|
||||
mat = mat.concatenate(new Matrix(textMatrix));
|
||||
BitmapExporter.export(swf, getBorderShape(borderColor, fillColor, rect), null, image, mat, colorTransform);
|
||||
@@ -316,7 +316,6 @@ public abstract class TextTag extends CharacterTag implements BoundedTag, Drawab
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String staticTextToHtmlCanvas(double unitDivisor, SWF swf, List<TEXTRECORD> textRecords, int numText, RECT bounds, MATRIX textMatrix, ColorTransform colorTransform) {
|
||||
Color textColor = new Color(0, 0, 0);
|
||||
String ret = "";
|
||||
@@ -353,9 +352,9 @@ public abstract class TextTag extends CharacterTag implements BoundedTag, Drawab
|
||||
// shapeNum: 1
|
||||
ret += "\tctx.save();\r\n";
|
||||
ret += "\tctx.transform(" + mat.scaleX + "," + mat.rotateSkew0 + "," + mat.rotateSkew1 + "," + mat.scaleY + "," + mat.translateX + "," + mat.translateY + ");\r\n";
|
||||
|
||||
|
||||
SHAPE shape = glyphs.get(entry.glyphIndex);
|
||||
CanvasShapeExporter exporter = new CanvasShapeExporter(new RGBA(textColor),unitDivisor, swf, shape, colorTransform,0,0);
|
||||
CanvasShapeExporter exporter = new CanvasShapeExporter(new RGBA(textColor), unitDivisor, swf, shape, colorTransform, 0, 0);
|
||||
exporter.export();
|
||||
ret += exporter.getShapeData();
|
||||
ret += "\tctx.restore();\r\n";
|
||||
@@ -365,7 +364,7 @@ public abstract class TextTag extends CharacterTag implements BoundedTag, Drawab
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public static void staticTextToSVG(SWF swf, List<TEXTRECORD> textRecords, int numText, SVGExporter exporter, RECT bounds, MATRIX textMatrix, ColorTransform colorTransform) {
|
||||
Color textColor = new Color(0, 0, 0);
|
||||
FontTag font = null;
|
||||
@@ -415,7 +414,7 @@ public abstract class TextTag extends CharacterTag implements BoundedTag, Drawab
|
||||
if (hasOffset) {
|
||||
exporter.createSubGroup(Matrix.getTranslateInstance(offsetX, offsetY), null);
|
||||
}
|
||||
|
||||
|
||||
Element textElement = exporter.createElement("text");
|
||||
textElement.setAttribute("font-size", Double.toString(rat * 1024));
|
||||
textElement.setAttribute("font-family", font.getFontName());
|
||||
@@ -430,11 +429,11 @@ public abstract class TextTag extends CharacterTag implements BoundedTag, Drawab
|
||||
textElement.setAttribute("fill-opacity", Float.toString(colorA.getAlphaFloat()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
exporter.addToGroup(textElement);
|
||||
FontExportMode fontExportMode = FontExportMode.TTF; // todo: change this to WOFF
|
||||
exporter.addStyle(font.getFontName(), new FontExporter().exportFont(font, fontExportMode), fontExportMode);
|
||||
|
||||
|
||||
if (hasOffset) {
|
||||
exporter.endGroup();
|
||||
}
|
||||
|
||||
32
trunk/src/com/jpexs/decompiler/flash/timeline/SvgClip.java
Normal file
32
trunk/src/com/jpexs/decompiler/flash/timeline/SvgClip.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.timeline;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SvgClip {
|
||||
|
||||
public String shape;
|
||||
public int depth;
|
||||
|
||||
public SvgClip(String shape, int depth) {
|
||||
this.shape = shape;
|
||||
this.depth = depth;
|
||||
}
|
||||
}
|
||||
@@ -169,10 +169,9 @@ public class Timeline {
|
||||
public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
|
||||
SWF.frameToImage(this, frame, time, stateUnderCursor, mouseButton, image, transformation, colorTransform);
|
||||
}
|
||||
|
||||
|
||||
public String toHtmlCanvas(double unitDivisor,List<Integer> frames){
|
||||
return SWF.framesToHtmlCanvas(unitDivisor, this, frames, 0, null, 0, displayRect, new ColorTransform(),null);
|
||||
|
||||
public String toHtmlCanvas(double unitDivisor, List<Integer> frames) {
|
||||
return SWF.framesToHtmlCanvas(unitDivisor, this, frames, 0, null, 0, displayRect, new ColorTransform(), null);
|
||||
}
|
||||
|
||||
public void getSounds(int frame, int time, DepthState stateUnderCursor, int mouseButton, List<Integer> sounds, List<String> soundClasses) {
|
||||
|
||||
@@ -26,5 +26,5 @@ public interface Timelined extends BoundedTag {
|
||||
|
||||
public Timeline getTimeline();
|
||||
|
||||
public void resetTimeline();
|
||||
public void resetTimeline();
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public class MORPHFILLSTYLE implements NeedsCharacters, Serializable {
|
||||
|
||||
public static final int SOLID = 0x0;
|
||||
public static final int LINEAR_GRADIENT = 0x10;
|
||||
public static final int RADIAL_GRADIENT = 0x12;
|
||||
public static final int RADIAL_GRADIENT = 0x12;
|
||||
public static final int FOCAL_RADIAL_GRADIENT = 0x13;
|
||||
public static final int REPEATING_BITMAP = 0x40;
|
||||
public static final int CLIPPED_BITMAP = 0x41;
|
||||
@@ -55,7 +55,7 @@ public class MORPHFILLSTYLE implements NeedsCharacters, Serializable {
|
||||
|
||||
@Conditional(value = "fillStyleType", options = {LINEAR_GRADIENT, RADIAL_GRADIENT})
|
||||
public MORPHGRADIENT gradient;
|
||||
|
||||
|
||||
@Conditional(value = "fillStyleType", options = {CLIPPED_BITMAP, NON_SMOOTHED_REPEATING_BITMAP, NON_SMOOTHED_CLIPPED_BITMAP})
|
||||
public int bitmapId;
|
||||
|
||||
@@ -86,12 +86,12 @@ public class MORPHFILLSTYLE implements NeedsCharacters, Serializable {
|
||||
}
|
||||
MATRIX ret = new MATRIX();
|
||||
double ratio_d = ratio / 65535.0;
|
||||
ret.scaleX = (int)Math.round(a.getScaleX() + (b.getScaleX() - a.getScaleX()) * ratio_d);
|
||||
ret.scaleY = (int)Math.round(a.getScaleY() + (b.getScaleY() - a.getScaleY()) * ratio_d);
|
||||
ret.rotateSkew0 = (int)Math.round(a.getRotateSkew0() + (b.getRotateSkew0() - a.getRotateSkew0()) * ratio_d);
|
||||
ret.rotateSkew1 = (int)Math.round(a.getRotateSkew1() + (b.getRotateSkew1() - a.getRotateSkew1()) * ratio_d);
|
||||
ret.translateX = (int)Math.round(a.translateX + (b.translateX - a.translateX) * ratio_d);
|
||||
ret.translateY = (int)Math.round(a.translateY + (b.translateY - a.translateY) * ratio_d);
|
||||
ret.scaleX = (int) Math.round(a.getScaleX() + (b.getScaleX() - a.getScaleX()) * ratio_d);
|
||||
ret.scaleY = (int) Math.round(a.getScaleY() + (b.getScaleY() - a.getScaleY()) * ratio_d);
|
||||
ret.rotateSkew0 = (int) Math.round(a.getRotateSkew0() + (b.getRotateSkew0() - a.getRotateSkew0()) * ratio_d);
|
||||
ret.rotateSkew1 = (int) Math.round(a.getRotateSkew1() + (b.getRotateSkew1() - a.getRotateSkew1()) * ratio_d);
|
||||
ret.translateX = (int) Math.round(a.translateX + (b.translateX - a.translateX) * ratio_d);
|
||||
ret.translateY = (int) Math.round(a.translateY + (b.translateY - a.translateY) * ratio_d);
|
||||
ret.hasRotate = true;
|
||||
ret.hasScale = true;
|
||||
return ret;
|
||||
|
||||
@@ -21,16 +21,17 @@ import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Well, this structure is undocumented, but exists
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MORPHFOCALGRADIENT extends MORPHGRADIENT implements Serializable {
|
||||
|
||||
@SWFType(BasicType.FIXED8)
|
||||
public float startFocalPoint;
|
||||
|
||||
|
||||
@SWFType(BasicType.FIXED8)
|
||||
public float endFocalPoint;
|
||||
|
||||
|
||||
@Override
|
||||
public GRADIENT getGradientAt(int ratio) {
|
||||
FOCALGRADIENT ret = new FOCALGRADIENT();
|
||||
|
||||
@@ -78,10 +78,10 @@ public class MORPHLINESTYLE2 implements Serializable {
|
||||
ret.pixelHintingFlag = pixelHintingFlag;
|
||||
ret.noClose = noClose;
|
||||
ret.endCapStyle = endCapStyle;
|
||||
ret.miterLimitFactor = miterLimitFactor;
|
||||
ret.miterLimitFactor = miterLimitFactor;
|
||||
if (hasFillFlag) {
|
||||
ret.fillType = fillType.getFillStyleAt(ratio);
|
||||
}else{
|
||||
} else {
|
||||
ret.color = MORPHGRADIENT.morphColor(startColor, endColor, ratio);
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -20,11 +20,8 @@ import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
|
||||
import com.jpexs.decompiler.flash.types.LINESTYLEARRAY;
|
||||
import com.jpexs.decompiler.flash.types.MORPHFILLSTYLEARRAY;
|
||||
import com.jpexs.decompiler.flash.types.MORPHLINESTYLEARRAY;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Calculated;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
@@ -70,7 +67,7 @@ public class StyleChangeRecord extends SHAPERECORD implements Cloneable {
|
||||
|
||||
@Conditional("stateNewStyles")
|
||||
public FILLSTYLEARRAY fillStyles;
|
||||
|
||||
|
||||
@Conditional("stateNewStyles")
|
||||
public LINESTYLEARRAY lineStyles;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user