Package org.joshy.sketch.actions.io

Source Code of org.joshy.sketch.actions.io.SaveSVGAction$SVGExport

package org.joshy.sketch.actions.io;

import com.joshondesign.xml.XMLWriter;
import org.joshy.gfx.draw.*;
import org.joshy.gfx.util.u;
import org.joshy.sketch.actions.ExportProcessor;
import org.joshy.sketch.actions.ShapeExporter;
import org.joshy.sketch.model.*;
import org.joshy.sketch.modes.DocContext;

import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.PathIterator;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.util.List;

public class SaveSVGAction extends BaseExportAction {
    private static DecimalFormat df = new DecimalFormat();
    static {
        df.setMaximumFractionDigits(2);
    }


    public SaveSVGAction(DocContext context) {
        super(context);
    }

    @Override
    protected String getStandardFileExtension() {
        return "svg";
    }

    public void export(File file, SketchDocument doc) {
        try {
            XMLWriter out = new XMLWriter(file);
            ExportProcessor.process(new SVGExport(), out, doc);
            out.close();
        } catch (Exception ex) {
            u.p(ex);
        }
    }

    private  static class SVGExport implements ShapeExporter<XMLWriter> {
        public void docStart(XMLWriter out, SketchDocument doc) {
            out.header();
            out.start("svg")
                    .attr("xmlns","http://www.w3.org/2000/svg")
                    .attr("version","1.2")
                    .attr("baseProfile","tiny");
            out.attr("viewBox","0 0 500 500");
        }

        public void pageStart(XMLWriter out, SketchDocument.SketchPage page) {
        }

        public void exportPre(XMLWriter out, SNode shape) {
            if(shape instanceof SGroup) {
                out.start("g")
                    .attr("transform","translate("+shape.getTranslateX()+","+shape.getTranslateY()+")");
            }
            if(shape instanceof SRect) draw(out,(SRect)shape);
            if(shape instanceof SArea) draw(out,(SArea)shape);
            if(shape instanceof SOval) draw(out,(SOval)shape);
            if(shape instanceof SText) draw(out,(SText)shape);
            if(shape instanceof SPoly) draw(out,(SPoly)shape);
            if(shape instanceof NGondraw(out, (NGon)shape);
            if(shape instanceof SPath) draw(out, (SPath)shape);
        }

        public void exportPost(XMLWriter out, SNode shape) {
            if(shape instanceof SGroup) out.end();
        }

        public void pageEnd(XMLWriter out, SketchDocument.SketchPage page) {
        }

        public void docEnd(XMLWriter out, SketchDocument document) {
            out.end();
        }

        public boolean isContainer(SNode n) {
            if(n instanceof SGroup) return true;
            if(n instanceof ResizableGrid9Shape) return true;
            return false;
        }

        public Iterable<? extends SNode> getChildNodes(SNode n) {
            if(n instanceof SGroup) return ((SGroup)n).getNodes();
            if(n instanceof ResizableGrid9Shape) return ((ResizableGrid9Shape)n).getNodes();
            return null;
        }

        private void draw(XMLWriter out, SPath shape) {
            out.start("path");
            out.attr("transform", "translate(" + shape.getTranslateX() + "," + shape.getTranslateY() + ")");
            StringBuffer data = new StringBuffer();
            int count = 0;
           
            for(SPath.SubPath sub : shape.getSubPaths()) {
                boolean first = true;
                SPath.PathPoint prev = null;
                for(SPath.PathPoint point : sub.getPoints()) {
                    if(first) {
                        data.append(" M " + point.x + " " +  point.y);
                    } else {
                        data.append(" C " + prev.cx2 + " " + prev.cy2);
                        data.append(" " + point.cx1 + " " + point.cy1);
                        data.append(" " + point.x + " " + point.y);
                    }
                    data.append(" ");
                    prev = point;
                    first = false;
                }
            }

            data.append(" z");
            out.attr("d", data.toString());

            out.attr("fill", toRGBString(shape.getFillPaint()));
            out.attr("fill-opacity", df.format(shape.getFillOpacity()));
            out.attr("stroke", toRGBString(shape.getStrokePaint()));
            out.attr("stroke-width", shape.getStrokeWidth() + "");
            out.end();
        }

        private void draw(XMLWriter out, SArea shape) {
            out.start("path");
            out.attr("transform","translate("+ shape.getTranslateX()+","+ shape.getTranslateY()+")");
            //the vector data
            StringBuffer data = new StringBuffer();
            int count = 0;
            Area area = shape.toArea();
            PathIterator it = area.getPathIterator(new AffineTransform());
            while(!it.isDone()) {
                double[] coords = new double[6];
                int n = it.currentSegment(coords);
                if(n == PathIterator.SEG_MOVETO) {
                    data.append(" M "+coords[0]+" "+coords[1]);
                }
                if(n == PathIterator.SEG_LINETO) {
                    data.append(" L " + coords[0]+" " +coords[1]);
                }
                if(n == PathIterator.SEG_CUBICTO) {
                    data.append(" C "
                            +coords[0]+" "+coords[1] + " "
                            +coords[2]+" "+coords[3] + " "
                            +coords[4]+" "+coords[5] + " "
                            );
                }
                if(n == PathIterator.SEG_CLOSE) {
                    data.append(" z");
                    break;
                }
                it.next();
            }
            out.attr("d", data.toString());
/*
        for(int i=0; i<points.size(); i++) {
            if(i == 0) {
                out.print(" M "+points.get(i).x + " " + points.get(i).y);
            } else {
                out.print(" C "
                        +points.get(i-1).cx2 + " " + points.get(i-1).cy2 + " "
                        +points.get(i).cx1 + " " + points.get(i).cy1 + " "
                        +points.get(i).x + " " + points.get(i).y + " "
                        );
            }
            out.print(" ");
        }*/
            //out.println(" z'");

            out.attr("fill",toRGBString(shape.getFillPaint())+"");
            out.attr("fill-opacity",df.format(shape.getFillOpacity())+"");
            out.attr("stroke",toRGBString(shape.getStrokePaint())+"");
            out.attr("stroke-width",shape.getStrokeWidth()+"");
            out.end();
        }


        private void draw(XMLWriter out, SRect rect) {
            //String id = Math.random();
            String id = "A"+Long.toHexString(Double.doubleToLongBits(Math.random()));
            /*
            if(rect.getFillPaint() instanceof GradientFill) {
                GradientFill grad = (GradientFill) rect.getFillPaint();
                out.start("linearGradient")
                        .attr("id",id);
                out.start("stop")
                        .attr("offset","0.0")
                        .attr("style","stop-color:"+toRGBString(grad.start))
                        .end();
                out.start("stop")
                        .attr("offset","1.0")
                        .attr("style","stop-color:"+toRGBString(grad.end))
                        .end();
                out.end();
            }
            */

            if(rect.getFillPaint() instanceof LinearGradientFill) {
                LinearGradientFill grad = (LinearGradientFill) rect.getFillPaint();
                out.start("g");
                out.start("defs");
                out.start("linearGradient")
                        .attr("id",id)
                        .attr("x1",(grad.getStartX()/rect.getWidth()*100)+"%")
                        .attr("y1",(grad.getStartY()/rect.getHeight()*100)+"%")
                        .attr("x2",(grad.getEndX()/rect.getWidth()*100)+"%")
                        .attr("y2",(grad.getEndY()/rect.getHeight()*100)+"%");
                for(MultiGradientFill.Stop stop : grad.getStops()) {
                    out.start("stop")
                            .attr("offset",stop.getPosition()+"")
                            .attr("stop-color",toHexString(stop.getColor()))
                            .end();
                }
                out.end(); //linearGradient
                out.end(); //defs
            }
            out.start("rect")
                    .attr("x",""+rect.getX())
                    .attr("y",""+rect.getY())
                    .attr("width",""+rect.getWidth())
                    .attr("height",""+rect.getHeight())
                    .attr("transform","translate("+rect.getTranslateX()+","+rect.getTranslateY()+")");

            if(rect.getFillPaint() instanceof FlatColor) {
                out.attr("fill",toRGBString(rect.getFillPaint()));
            }
            if(rect.getFillPaint() instanceof LinearGradientFill) {
                out.attr("fill","url(#"+id+")");
            }
            if(rect.getFillOpacity() != 1) {
                out.attr("fill-opacity",df.format(rect.getFillOpacity()));
            }

            out.attr("stroke",toRGBString(rect.getStrokePaint()));
            out.attr("stroke-width",""+rect.getStrokeWidth());

            out.end();//rect
            if(rect.getFillPaint() instanceof LinearGradientFill) {
                out.end(); //g
            }
        }

        private void draw(XMLWriter out, SOval shape) {
            out.start("ellipse")
                    .attr("cx",(shape.getX() + shape.getWidth() /2)+"");
            out.attr("cy", (shape.getY() + shape.getHeight() / 2) + "");
            out.attr("rx", shape.getWidth() / 2 + "");
            out.attr("ry", shape.getHeight() / 2 + "");
            out.attr("transform", "translate(" + shape.getTranslateX() + "," + shape.getTranslateY() + ")");
            out.attr("fill", toRGBString(shape.getFillPaint()) + "");
            out.attr("fill-opacity", df.format(shape.getFillOpacity()));
            out.attr("stroke", toRGBString(shape.getStrokePaint()) + "");
            out.attr("stroke-width", shape.getStrokeWidth() + "");
            out.end();
        }

        private void draw(XMLWriter out, SText text) {
            org.joshy.gfx.draw.Font font = org.joshy.gfx.draw.Font.DEFAULT;
            font = org.joshy.gfx.draw.Font.name(font.getName())
                    .size((float)text.getFontSize())
                    .weight(text.getWeight())
                    .style(text.getStyle())
                    .resolve();
            out.start("text");
            out.attr("x", (text.getX() + text.getTranslateX()) + "");
            out.attr("y", (text.getY() + text.getTranslateY() + font.getAscender()) + "");
            out.attr("fill", toRGBString(text.getFillPaint()) + "");
            out.attr("fill-opacity", df.format(text.getFillOpacity()) + "");
            out.attr("font-family", font.getName() + "");
            out.attr("font-size", text.getFontSize() + "");
            out.text(text.getText());
            out.end();
        }

        private void draw(XMLWriter out, SPoly shape) {
            if(shape.isClosed()) {
                out.start("polygon");
            } else {
                out.start("polyline");
            }
            StringBuffer points = new StringBuffer();
            for(int i=0; i<shape.pointCount(); i++) {
                points.append("" + (shape.getPoint(i).getX() + shape.getTranslateX())
                        + "," + (shape.getPoint(i).getY() + shape.getTranslateY()) + " ");
            }
            out.attr("points", points.toString());

            if(shape.isClosed()) {
                out.attr("fill", toRGBString(shape.getFillPaint()));
                out.attr("fill-opacity",df.format(shape.getFillOpacity()));
            } else {
                out.attr("fill", "none");
            }
            out.attr("stroke", toRGBString(shape.getStrokePaint()) + "");
            out.attr("stroke-width", shape.getStrokeWidth() + "");

            out.end();
        }

        private void draw(XMLWriter out, NGon shape) {
            out.start("polygon");

            //the vector data
            StringBuffer data = new StringBuffer();
            double[] points = shape.toPoints();
            for(int i=0; i<points.length; i+=2) {
                data.append(""  + (points[i]+shape.getTranslateX())
                        + "," + (points[i+1]+shape.getTranslateY()) + " ");
            }
            out.attr("points", data.toString());


            out.attr("fill", toRGBString(shape.getFillPaint()));
            out.attr("fill-opacity", df.format(shape.getFillOpacity()));
            out.attr("stroke", toRGBString(shape.getStrokePaint()) + "");
            out.attr("stroke-width", shape.getStrokeWidth() + "");
            out.end();
        }

        private static String toHexString(FlatColor color) {
            return "#"+Integer.toHexString(color.getRGBA()&0x00FFFFFF);
        }

        private static String toRGBString(Paint paint) {
            if(paint instanceof FlatColor){
                FlatColor color = (FlatColor) paint;
                return "rgb("+df.format(color.getRed()*100)+"%,"
                        +df.format(color.getGreen()*100)+"%,"
                        +df.format(color.getBlue()*100)+"%)";
            } else {
                return toRGBString(FlatColor.BLACK);
            }
        }
    }

}
TOP

Related Classes of org.joshy.sketch.actions.io.SaveSVGAction$SVGExport

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.