svg export: clipping +code formatting

This commit is contained in:
Honfika
2014-04-29 13:41:25 +02:00
parent f784b4791f
commit 0cd7a6a2e0
53 changed files with 431 additions and 420 deletions

View File

@@ -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));

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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());
}

View File

@@ -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;

View File

@@ -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");

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View 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;
}
}

View File

@@ -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;

View File

@@ -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));

View File

@@ -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 + "]";

View File

@@ -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;
}
}

View File

@@ -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)+\")\"";
}
}

View File

@@ -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;
}
}

View File

@@ -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,

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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];

View File

@@ -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();
}

View File

@@ -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()));

View File

@@ -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;

View File

@@ -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();

View File

@@ -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);

View File

@@ -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;

View File

@@ -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());

View File

@@ -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];

View File

@@ -323,5 +323,5 @@ public class DefineFontTag extends FontTag {
@Override
public int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex) {
return 0;
}
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}
/**

View File

@@ -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());

View File

@@ -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?
}
}

View File

@@ -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();

View File

@@ -311,7 +311,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
}
return dfn.fontCopyright;
}
@Override
public String toHtmlCanvas(double unitDivisor) {
return ""; //TODO

View File

@@ -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());
}
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}

View 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;
}
}

View File

@@ -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) {

View File

@@ -26,5 +26,5 @@ public interface Timelined extends BoundedTag {
public Timeline getTimeline();
public void resetTimeline();
public void resetTimeline();
}

View File

@@ -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;

View File

@@ -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();

View File

@@ -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;

View File

@@ -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;