diff --git a/trunk/src/com/jpexs/asdec/types/shaperecords/CurvedEdgeRecord.java b/trunk/src/com/jpexs/asdec/types/shaperecords/CurvedEdgeRecord.java index 3a7663618..053321607 100644 --- a/trunk/src/com/jpexs/asdec/types/shaperecords/CurvedEdgeRecord.java +++ b/trunk/src/com/jpexs/asdec/types/shaperecords/CurvedEdgeRecord.java @@ -36,4 +36,36 @@ public class CurvedEdgeRecord extends SHAPERECORD { public String toString() { return "[CurvedEdgeRecord numBits=" + numBits + ", controlDeltaX=" + controlDeltaX + ", controlDeltaY=" + controlDeltaY + ", anchorDeltaX=" + anchorDeltaX + ". anchorDeltaY=" + anchorDeltaY + "]"; } + + @Override + public String toSWG(int oldX,int oldY) { + return "Q " + twipToPixel(oldX+controlDeltaX) + " " + twipToPixel(oldY+controlDeltaY) + " " + twipToPixel(oldX+controlDeltaX + anchorDeltaX) + " " + twipToPixel(oldY+controlDeltaY + anchorDeltaY); + + } + + @Override + public int changeX(int x) { + return x+(controlDeltaX+anchorDeltaX); + } + + @Override + public int changeY(int y) { + return y+(controlDeltaY+anchorDeltaY); + } + + @Override + public void flip() { + int tmp; + tmp=controlDeltaX; + controlDeltaX=-anchorDeltaX; + anchorDeltaX=-tmp; + tmp=controlDeltaY; + controlDeltaY=-anchorDeltaY; + anchorDeltaY=-tmp ; + } + + @Override + public boolean isMove() { + return true; + } } diff --git a/trunk/src/com/jpexs/asdec/types/shaperecords/EndShapeRecord.java b/trunk/src/com/jpexs/asdec/types/shaperecords/EndShapeRecord.java index ef68b9a1c..1acd9fc5a 100644 --- a/trunk/src/com/jpexs/asdec/types/shaperecords/EndShapeRecord.java +++ b/trunk/src/com/jpexs/asdec/types/shaperecords/EndShapeRecord.java @@ -31,4 +31,29 @@ public class EndShapeRecord extends SHAPERECORD { public String toString() { return "[EndShapeRecord]"; } + + @Override + public String toSWG(int oldX,int oldY) { + return ""; + } + + @Override + public int changeX(int x) { + return x; + } + + @Override + public int changeY(int y) { + return y; + } + + @Override + public void flip() { + + } + + @Override + public boolean isMove() { + return false; + } } diff --git a/trunk/src/com/jpexs/asdec/types/shaperecords/SHAPERECORD.java b/trunk/src/com/jpexs/asdec/types/shaperecords/SHAPERECORD.java index e4af8cc7e..952b57a0a 100644 --- a/trunk/src/com/jpexs/asdec/types/shaperecords/SHAPERECORD.java +++ b/trunk/src/com/jpexs/asdec/types/shaperecords/SHAPERECORD.java @@ -26,27 +26,70 @@ import com.jpexs.asdec.types.RGB; import java.util.ArrayList; import java.util.List; import java.util.Random; +import java.util.logging.Level; +import java.util.logging.Logger; /** * * @author JPEXS */ -public abstract class SHAPERECORD { +public abstract class SHAPERECORD implements Cloneable { public static float twipToPixel(int twip) { return ((float) twip) / 20.0f; } private static class Path { + public LINESTYLE lineStyle; public LINESTYLE2 lineStyle2; public boolean useLineStyle2; public FILLSTYLE fillStyle0; public FILLSTYLE fillStyle1; - public String points; + public List edges = new ArrayList(); + + public boolean sameStyle(Path p){ + return fillStyle0==p.fillStyle0 && ((useLineStyle2&&(p.lineStyle2==lineStyle2)) || ((!useLineStyle2)&&(p.lineStyle==lineStyle))); + } + + public String toSVG(int shapeNum){ + String ret=""; + String params = ""; + String f = ""; + if (fillStyle0 != null) { + if (fillStyle0.fillStyleType == FILLSTYLE.SOLID) { + f = " fill=\"" + ((shapeNum >= 3) ? fillStyle0.colorA.toHexRGB() : fillStyle0.color.toHexRGB()) + "\""; + } + } + params += f; + if ((!useLineStyle2) && lineStyle != null) { + params += " stroke=\"" + ((shapeNum >= 3) ? lineStyle.colorA.toHexRGB() : lineStyle.color.toHexRGB()) + "\""; + } + if (useLineStyle2 && lineStyle2 != null) { + params += " stroke-width=\"" + twipToPixel(lineStyle2.width) + "\" stroke=\"" + lineStyle2.color.toHexRGB() + "\""; + } + String points=""; + int x=0; + int y=0; + for(SHAPERECORD r:edges){ + points+=" "+r.toSWG(x,y); + x=r.changeX(x); + y=r.changeY(y); + } + ret += ""; + return ret; + } } + + public abstract String toSWG(int oldX,int oldY); + + public abstract int changeX(int x); + + public abstract int changeY(int y); + + public abstract void flip(); - public static RECT getBounds(List records){ + public static RECT getBounds(List records) { int x = 0; int y = 0; int max_x = 0; @@ -55,40 +98,17 @@ public abstract class SHAPERECORD { int min_y = Integer.MAX_VALUE; boolean started = false; for (SHAPERECORD r : records) { - if (r instanceof StyleChangeRecord) { - StyleChangeRecord scr = (StyleChangeRecord) r; - if (scr.stateMoveTo) { - x = scr.moveDeltaX; - y = scr.moveDeltaY; - started = true; - } - } - if (r instanceof StraightEdgeRecord) { - StraightEdgeRecord ser = (StraightEdgeRecord) r; - if (ser.generalLineFlag) { - x += ser.deltaX; - y += ser.deltaY; - started = true; - } else if (ser.vertLineFlag) { - y += ser.deltaY; - started = true; - } else { - x += ser.deltaX; - started = true; - } - } - if (r instanceof CurvedEdgeRecord) { - CurvedEdgeRecord cer = (CurvedEdgeRecord) r; - x += cer.controlDeltaX + cer.anchorDeltaX; - y += cer.controlDeltaY + cer.anchorDeltaY; - started = true; - } + x = r.changeX(x); + y = r.changeY(y); if (x > max_x) { max_x = x; } if (y > max_y) { max_y = y; } + if(r.isMove()){ + started=true; + } if (started) { if (y < min_y) { min_y = y; @@ -98,14 +118,14 @@ public abstract class SHAPERECORD { } } } - return new RECT(min_x,max_x,min_y,max_y); + return new RECT(min_x, max_x, min_y, max_y); } /** * EXPERIMENTAL - convert shape to SVG - * + * * TODO: Fix fill styles - * + * * @param shapeNum * @param fillStyles * @param lineStylesList @@ -118,7 +138,6 @@ public abstract class SHAPERECORD { String ret = ""; List paths = new ArrayList(); Path path = new Path(); - boolean styleChanged = false; int x = 0; int y = 0; int max_x = 0; @@ -129,6 +148,9 @@ public abstract class SHAPERECORD { for (SHAPERECORD r : records) { if (r instanceof StyleChangeRecord) { StyleChangeRecord scr = (StyleChangeRecord) r; + paths.add(path); + path = new Path(); + if (scr.stateNewStyles) { fillStyles = scr.fillStyles; lineStylesList = scr.lineStyles; @@ -136,7 +158,6 @@ public abstract class SHAPERECORD { numLineBits = scr.numLineBits; } if (scr.stateFillStyle0) { - styleChanged = true; if (scr.fillStyle0 == 0) { path.fillStyle0 = null; } else { @@ -144,7 +165,6 @@ public abstract class SHAPERECORD { } } if (scr.stateFillStyle1) { - styleChanged = true; if (scr.fillStyle1 == 0) { path.fillStyle1 = null; } else { @@ -152,8 +172,7 @@ public abstract class SHAPERECORD { } } if (scr.stateLineStyle) { - styleChanged = true; - if (shapeNum>=4) { + if (shapeNum >= 4) { path.useLineStyle2 = true; if (scr.lineStyle == 0) { path.lineStyle2 = null; @@ -168,44 +187,13 @@ public abstract class SHAPERECORD { path.lineStyle = lineStylesList.lineStyles[scr.lineStyle - 1]; } } - } - if (scr.stateMoveTo) { - ret += "M " + twipToPixel(scr.moveDeltaX) + " " + twipToPixel(scr.moveDeltaY); - x = scr.moveDeltaX; - y = scr.moveDeltaY; - - started = true; - } - } else if (styleChanged) { - styleChanged = false; - path.points = ret; - ret = "M " + twipToPixel(x) + " " + twipToPixel(y); - paths.add(path); - path = new Path(); - } - if (r instanceof StraightEdgeRecord) { - StraightEdgeRecord ser = (StraightEdgeRecord) r; - if (ser.generalLineFlag) { - ret += "l " + twipToPixel(ser.deltaX) + " " + twipToPixel(ser.deltaY); - x += ser.deltaX; - y += ser.deltaY; - started = true; - } else if (ser.vertLineFlag) { - ret += "v " + twipToPixel(ser.deltaY); - y += ser.deltaY; - started = true; - } else { - ret += "h " + twipToPixel(ser.deltaX); - x += ser.deltaX; - started = true; - } - } - if (r instanceof CurvedEdgeRecord) { - CurvedEdgeRecord cer = (CurvedEdgeRecord) r; - ret += "q " + twipToPixel(cer.controlDeltaX) + " " + twipToPixel(cer.controlDeltaY) + " " + twipToPixel(cer.controlDeltaX + cer.anchorDeltaX) + " " + twipToPixel(cer.controlDeltaY + cer.anchorDeltaY); - x += cer.controlDeltaX + cer.anchorDeltaX; - y += cer.controlDeltaY + cer.anchorDeltaY; - started = true; + } + } + path.edges.add(r); + x=r.changeX(x); + y=r.changeY(y); + if(r.isMove()){ + started=true; } if (x > max_x) { max_x = x; @@ -222,42 +210,72 @@ public abstract class SHAPERECORD { } } } - path.points = ret; paths.add(path); + List paths2=new ArrayList(); + for(Path p:paths){ + if(p.fillStyle0!=null){ + paths2.add(p); + } + if(p.fillStyle1!=null){ + Path f=new Path(); + f.edges=new ArrayList(); + f.fillStyle0=p.fillStyle1; + f.lineStyle=p.lineStyle; + f.lineStyle2=p.lineStyle2; + f.useLineStyle2=p.useLineStyle2; + x=0; + y=0; + for(SHAPERECORD r:p.edges){ + x=r.changeX(x); + y=r.changeY(y); + SHAPERECORD r2=null; + try { + r2 = (SHAPERECORD)r.clone(); + } catch (CloneNotSupportedException ex) { + Logger.getLogger(SHAPERECORD.class.getName()).log(Level.SEVERE, null, ex); + } + r2.flip(); + f.edges.add(0,r2); + } + StyleChangeRecord scr=new StyleChangeRecord(); + scr.stateMoveTo=true; + scr.moveDeltaX=x; + scr.moveDeltaY=y; + f.edges.add(0,scr); + paths2.add(f); + } + } + List paths3=new ArrayList(); + for(Path p1:paths2){ + boolean found=false; + for(Path p2:paths3){ + if(p1==p2){ + continue; + } + if(p1.sameStyle(p2)){ + p2.edges.addAll(p1.edges); + found=true; + break; + } + } + if(!found){ + paths3.add(p1); + } + } ret = ""; - for (Path p : paths) { - String params = ""; - String f = ""; - if (p.fillStyle0 != null) { - if (p.fillStyle0.fillStyleType == FILLSTYLE.SOLID) { - f = " fill=\"" + ((shapeNum >= 3) ? p.fillStyle0.colorA.toHexRGB() : p.fillStyle0.color.toHexRGB()) + "\""; - } - } else if (p.fillStyle1 != null) { - if (p.fillStyle1.fillStyleType == FILLSTYLE.SOLID) { - f = " fill=\"" + ((shapeNum >= 3) ? p.fillStyle1.colorA.toHexRGB() : p.fillStyle1.color.toHexRGB()) + "\""; - } - } - if (p.fillStyle0 != null && p.fillStyle1 != null) { - Random rnd = new Random(); - f = " fill=\"" + (new RGB(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256))).toHexRGB() + "\""; - } - params += f; - if ((!p.useLineStyle2) && p.lineStyle != null) { - params += " stroke=\"" + ((shapeNum >= 3) ? p.lineStyle.colorA.toHexRGB() : p.lineStyle.color.toHexRGB()) + "\""; - } - if (p.useLineStyle2 && p.lineStyle2 != null) { - params += " stroke-width=\"" + twipToPixel(p.lineStyle2.width) + "\" stroke=\"" + p.lineStyle2.color.toHexRGB() + "\""; - } - ret += ""; + for (Path p : paths3) { + ret+=p.toSVG(shapeNum); } ret = " \n" + "\n" + "" + ret + "" + ""; return ret; } + + public abstract boolean isMove(); } diff --git a/trunk/src/com/jpexs/asdec/types/shaperecords/StraightEdgeRecord.java b/trunk/src/com/jpexs/asdec/types/shaperecords/StraightEdgeRecord.java index f6c47ceb9..07064a0ba 100644 --- a/trunk/src/com/jpexs/asdec/types/shaperecords/StraightEdgeRecord.java +++ b/trunk/src/com/jpexs/asdec/types/shaperecords/StraightEdgeRecord.java @@ -14,8 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - - package com.jpexs.asdec.types.shaperecords; /** @@ -36,4 +34,48 @@ public class StraightEdgeRecord extends SHAPERECORD { public String toString() { return "[StraightEdgeRecord numBits=" + numBits + ", generalLineFlag=" + generalLineFlag + ", vertLineFlag=" + vertLineFlag + ", deltaX=" + deltaX + ", deltaY=" + deltaY + "]"; } + + @Override + public String toSWG(int oldX,int oldY) { + if (generalLineFlag) { + return "L " + twipToPixel(oldX+deltaX) + " " + twipToPixel(oldY+deltaY); + } else if (vertLineFlag) { + return "V " + twipToPixel(oldY+deltaY); + } else { + return "H " + twipToPixel(oldX+deltaX); + } + } + + @Override + public int changeX(int x) { + if (generalLineFlag) { + return x+deltaX; + } else if (vertLineFlag) { + return x; + } else { + return x+deltaX; + } + } + + @Override + public int changeY(int y) { + if (generalLineFlag) { + return y+deltaY; + } else if (vertLineFlag) { + return y+deltaY; + } else { + return y; + } + } + + @Override + public void flip() { + deltaX=-deltaX; + deltaY=-deltaY; + } + + @Override + public boolean isMove() { + return true; + } } diff --git a/trunk/src/com/jpexs/asdec/types/shaperecords/StyleChangeRecord.java b/trunk/src/com/jpexs/asdec/types/shaperecords/StyleChangeRecord.java index 6480795b0..306edf877 100644 --- a/trunk/src/com/jpexs/asdec/types/shaperecords/StyleChangeRecord.java +++ b/trunk/src/com/jpexs/asdec/types/shaperecords/StyleChangeRecord.java @@ -14,8 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - - package com.jpexs.asdec.types.shaperecords; import com.jpexs.asdec.types.FILLSTYLEARRAY; @@ -50,4 +48,38 @@ public class StyleChangeRecord extends SHAPERECORD { + " stateFillStyle0=" + stateFillStyle0 + ", stateMoveTo=" + stateMoveTo + ", moveBits=" + moveBits + ", moveDeltaX=" + moveDeltaX + ", moveDeltaY=" + moveDeltaY + "," + " fillStyle0=" + fillStyle0 + ", fillStyle1=" + fillStyle1 + ", lineStyle=" + lineStyle + ", fillStyles=" + fillStyles + ", lineStyles=" + lineStyles + ", numFillBits=" + numFillBits + ", numLineBits=" + numLineBits + "]"; } + + @Override + public String toSWG(int oldX,int oldY) { + if (stateMoveTo) { + return "M " + twipToPixel(moveDeltaX) + " " + twipToPixel(moveDeltaY); + } + return ""; + } + + @Override + public int changeX(int x) { + if (stateMoveTo) { + return moveDeltaX; + } + return 0; + } + + @Override + public int changeY(int y) { + if (stateMoveTo) { + return moveDeltaY; + } + return 0; + } + + @Override + public void flip() { + + } + + @Override + public boolean isMove() { + return stateMoveTo; + } }