Code

LIBNR REMOVAL. remove nartbpath code!!!
[inkscape.git] / src / extension / internal / javafx-out.cpp
index 29c2bdab0eafdb6da0fd42325a48d9e3386a4793..967ddd92d72a57fd541a29b13b08a42ae31f390e 100644 (file)
@@ -6,6 +6,8 @@
  *\r
  * Authors:\r
  *   Bob Jamison <ishmal@inkscape.org>\r
+ *   Silveira Neto <silveiraneto@gmail.com>\r
+ *   Jim Clarke <Jim.Clarke@sun.com>\r
  *\r
  * Copyright (C) 2008 Authors\r
  *\r
@@ -24,6 +26,8 @@
 #include <sp-radial-gradient.h>\r
 #include <style.h>\r
 #include <display/curve.h>\r
+#include <display/canvas-bpath.h>\r
+#include <svg/svg.h>\r
 #include <extension/system.h>\r
 #include <2geom/pathvector.h>\r
 #include <2geom/rect.h>\r
@@ -56,9 +60,11 @@ namespace Internal
 static void err(const char *fmt, ...)\r
 {\r
     va_list args;\r
+    g_log(NULL,  G_LOG_LEVEL_WARNING, "javafx-out err: ");\r
     va_start(args, fmt);\r
     g_logv(NULL, G_LOG_LEVEL_WARNING, fmt, args);\r
     va_end(args);\r
+    g_log(NULL,  G_LOG_LEVEL_WARNING, "\n");\r
 }\r
 \r
 \r
@@ -80,9 +86,8 @@ static double effective_opacity(const SPStyle *style)
     for (SPObject const *obj = style->object; obj ; obj = obj->parent)\r
         {\r
         style = SP_OBJECT_STYLE(obj);\r
-        if (!style)\r
-            return val;\r
-        val *= SP_SCALE24_TO_FLOAT(style->opacity.value);\r
+        if (style)\r
+            val *= SP_SCALE24_TO_FLOAT(style->opacity.value);\r
         }\r
     return val;\r
 }\r
@@ -93,7 +98,8 @@ static double effective_opacity(const SPStyle *style)
 \r
 \r
 /**\r
- * We want to control floating output format\r
+ * We want to control floating output format.\r
+ * Especially to avoid localization. (decimal ',' for example)\r
  */\r
 static JavaFXOutput::String dstr(double d)\r
 {\r
@@ -104,6 +110,22 @@ static JavaFXOutput::String dstr(double d)
     return s;\r
 }\r
 \r
+#define DSTR(d) (dstr(d).c_str())\r
+\r
+\r
+/**\r
+ * Format a double as an integer\r
+ */\r
+static JavaFXOutput::String istr(double d)\r
+{\r
+    char dbuf[G_ASCII_DTOSTR_BUF_SIZE+1];\r
+    g_ascii_formatd(dbuf, G_ASCII_DTOSTR_BUF_SIZE,\r
+                  "%.0f", (gdouble)d);\r
+    JavaFXOutput::String s = dbuf;\r
+    return s;\r
+}\r
+\r
+#define ISTR(d) (istr(d).c_str())\r
 \r
 \r
 /**\r
@@ -116,8 +138,8 @@ static JavaFXOutput::String rgba(guint32 rgba)
     unsigned int b = SP_RGBA32_B_U(rgba);\r
     unsigned int a = SP_RGBA32_A_U(rgba);\r
     char buf[80];\r
-    snprintf(buf, 79, "rgba(0x%02x, 0x%02x, 0x%02x, 0x%02x)",\r
-                           r, g, b, a);\r
+    snprintf(buf, 79, "Color.rgb(0x%02x, 0x%02x, 0x%02x, %s)",\r
+                           r, g, b, DSTR((double)a/256.0));\r
     JavaFXOutput::String s = buf;\r
     return s;\r
 }\r
@@ -131,6 +153,38 @@ static JavaFXOutput::String rgba(SPColor color, gdouble alpha)
     return rgba(color.toRGBA32(alpha));\r
 }\r
 \r
+/**\r
+ * Map Inkscape linecap styles to JavaFX\r
+ */\r
+static JavaFXOutput::String getStrokeLineCap(unsigned value) {\r
+    switch(value) {\r
+        case SP_STROKE_LINECAP_BUTT:\r
+            return "StrokeLineCap.BUTT";\r
+        case SP_STROKE_LINECAP_ROUND:\r
+            return "StrokeLineCap.ROUND";\r
+        case SP_STROKE_LINECAP_SQUARE:\r
+            return "StrokeLineCap.SQUARE";\r
+        default:\r
+            return "INVALID LINE CAP";\r
+    }\r
+}\r
+\r
+\r
+/**\r
+ * Map Inkscape linejoin styles to JavaFX\r
+ */\r
+static JavaFXOutput::String getStrokeLineJoin(unsigned value) {\r
+    switch(value) {\r
+        case SP_STROKE_LINEJOIN_MITER:\r
+            return "StrokeLineJoin.MITER";\r
+        case SP_STROKE_LINEJOIN_ROUND:\r
+            return "StrokeLineJoin.ROUND";\r
+        case SP_STROKE_LINEJOIN_BEVEL:\r
+            return "StrokeLineJoin.BEVEL";\r
+        default:\r
+            return "INVALID LINE JOIN";\r
+    }\r
+}\r
 \r
 \r
 \r
@@ -147,18 +201,6 @@ void JavaFXOutput::out(const char *fmt, ...)
     g_free(output);\r
 }\r
 \r
-/**\r
- *  Output header data to the buffer, printf()-style\r
- */\r
-void JavaFXOutput::fout(const char *fmt, ...)\r
-{\r
-    va_list args;\r
-    va_start(args, fmt);\r
-    gchar *output = g_strdup_vprintf(fmt, args);\r
-    va_end(args);\r
-    foutbuf.append(output);\r
-    g_free(output);\r
-}\r
 \r
 \r
 /**\r
@@ -170,7 +212,7 @@ bool JavaFXOutput::doHeader()
     out("/*###################################################################\n");\r
     out("### This JavaFX document was generated by Inkscape\n");\r
     out("### http://www.inkscape.org\n");\r
-    out("### Created: %s", ctime(&tim));\r
+    out("### Created: %s",   ctime(&tim));\r
     out("### Version: %s\n", INKSCAPE_VERSION);\r
     out("#####################################################################\n");\r
     out("### NOTES:\n");\r
@@ -188,36 +230,23 @@ bool JavaFXOutput::doHeader()
     out("##   Exports in this file\n");\r
     out("##==========================\n");\r
     out("##    Shapes   : %d\n", nrShapes);\r
-    out("##    Segments : %d\n", nrSegments);\r
     out("##    Nodes    : %d\n", nrNodes);\r
     out("###################################################################*/\n");\r
     out("\n\n");\r
-    out("import javafx.ui.UIElement;\n");\r
-    out("import javafx.ui.*;\n");\r
-    out("import javafx.ui.canvas.*;\n");\r
+\r
+    // import javafx libraries we can need\r
+    out("import javafx.application.*;\n");\r
+    out("import javafx.scene.*;\n");\r
+    out("import javafx.scene.geometry.*;\n");\r
+    out("import javafx.scene.transform.*;\n");\r
+    out("import javafx.scene.paint.*;\n");\r
     out("\n");\r
-    out("import java.lang.System;\n");\r
-    out("\n\n");\r
-    out("public class %s extends CompositeNode {\n", name.c_str());\r
-    for (unsigned int i = 0 ; i < linearGradients.size() ; i++)\r
-        {\r
-        out("    public function %s(): LinearGradient;\n",\r
-            linearGradients[i].c_str());\r
-        }\r
-    for (unsigned int i = 0 ; i < radialGradients.size() ; i++)\r
-        {\r
-        out("    public function %s(): RadialGradient;\n",\r
-            radialGradients[i].c_str());\r
-        }\r
-    out("}\n");\r
-    out("\n\n");\r
-    outbuf.append(foutbuf);\r
+\r
     out("\n\n");\r
-    out("function %s.composeNode() =\n", name.c_str());\r
-    out("Group\n");\r
-    out("    {\n");\r
-    out("    content:\n");\r
-    out("        [\n");\r
+\r
+    // Creates a class extended from CustomNode\r
+    out("public class %s extends CustomNode {\n", name.c_str());\r
+\r
     return true;\r
 }\r
 \r
@@ -228,26 +257,33 @@ bool JavaFXOutput::doHeader()
  */\r
 bool JavaFXOutput::doTail()\r
 {\r
-    int border = 25.0;\r
-    out("        ] // content\n");\r
-    out("    transform: [ translate(%s, %s), ]\n",\r
-                 dstr((-minx) + border).c_str(), dstr((-miny) + border).c_str());\r
-    out("    }; // Group\n");\r
-    out("// end function %s.composeNode()\n", name.c_str());\r
-    out("\n\n\n\n");\r
+    float border = 25.0;\r
+\r
+    // Write the tail of CustomNode\r
+    out("           ] // content\n");\r
+    out("           transform: Translate { x : %s, y : %s }\n",\r
+                 DSTR((-minx) + border), DSTR((-miny) + border) );\r
+    out("       } // Group\n");\r
+    out("   } // function create()\n");\r
+    out("} // class %s\n", name.c_str());\r
+    out("\n");\r
+\r
+    // Frame\r
     out("Frame {\n");\r
-    out("    title: \"Test\"\n");\r
-    out("    width: %s\n", dstr(maxx-minx + border * 2.0).c_str());\r
-    out("    height: %s\n", dstr(maxy-miny + border * 2.0).c_str());\r
-    out("    onClose: function()\n");\r
-    out("        {\n");\r
-    out("        return System.exit( 0 );\n");\r
-    out("        }\n");\r
+    out("    title: \"%s\"\n", name.c_str());\r
+    out("    width: %s\n",  ISTR(maxx-minx + border * 2.0));\r
+    out("    height: %s\n", ISTR(maxy-miny + border * 2.0));\r
     out("    visible: true\n");\r
-    out("    content: Canvas {\n");\r
+\r
+    // Stage\r
+    out("    stage: Stage {\n");\r
     out("        content: %s{}\n", name.c_str());\r
-    out("    }\n");\r
-    out("}\n");\r
+    out("    } // Stage\n");\r
+\r
+    out("} // Frame\n");\r
+\r
+    out("\n");\r
+\r
     out("/*###################################################################\n");\r
     out("### E N D   C L A S S    %s\n", name.c_str());\r
     out("###################################################################*/\n");\r
@@ -265,65 +301,57 @@ bool JavaFXOutput::doGradient(SPGradient *grad, const String &id)
     if (SP_IS_LINEARGRADIENT(grad))\r
         {\r
         SPLinearGradient *g = SP_LINEARGRADIENT(grad);\r
-        linearGradients.push_back(id);\r
-        fout("function %s.%s() =\n", name.c_str(), id.c_str());\r
-        fout("    [\n");\r
-        fout("    LinearGradient\n");\r
-        fout("        {\n");\r
+        out("    /* create LinearGradient for %s */\n", id.c_str());\r
+        out("    private function %s(): LinearGradient {\n",  id.c_str());\r
+        out("        LinearGradient {\n");\r
         std::vector<SPGradientStop> stops = g->vector.stops;\r
         if (stops.size() > 0)\r
             {\r
-            fout("        stops:\n");\r
-            fout("            [\n");\r
+            out("            stops:\n");\r
+            out("                [\n");\r
             for (unsigned int i = 0 ; i<stops.size() ; i++)\r
                 {\r
                 SPGradientStop stop = stops[i];\r
-                fout("            Stop\n");\r
-                fout("                {\n");\r
-                fout("                offset: %s\n", dstr(stop.offset).c_str());\r
-                fout("                color: %s\n", rgba(stop.color, stop.opacity).c_str());\r
-                fout("                },\n");\r
+                out("                Stop {\n");\r
+                out("                    offset: %s\n", DSTR(stop.offset));\r
+                out("                    color: %s\n",  rgba(stop.color, stop.opacity).c_str());\r
+                out("                },\n");\r
                 }\r
-            fout("            ]\n");\r
+            out("            ]\n");\r
             }\r
-        fout("        },\n");\r
-        fout("    ];\n");\r
-        fout("\n\n");\r
+        out("        };\n");\r
+        out("    } // end LinearGradient: %s\n", id.c_str());\r
+        out("\n\n");\r
         }\r
     else if (SP_IS_RADIALGRADIENT(grad))\r
         {\r
         SPRadialGradient *g = SP_RADIALGRADIENT(grad);\r
-        radialGradients.push_back(id);\r
-        fout("function %s.%s() =\n", name.c_str(), id.c_str());\r
-        fout("    [\n");\r
-        fout("    RadialGradient\n");\r
-        fout("        {\n");\r
-        fout("        cx: %s\n", dstr(g->cx.value).c_str());\r
-        fout("        cy: %s\n", dstr(g->cy.value).c_str());\r
-        fout("        focusX: %s\n", dstr(g->fx.value).c_str());\r
-        fout("        focusY: %s\n", dstr(g->fy.value).c_str());\r
-        fout("        radius: %s\n", dstr(g->r.value).c_str());\r
-        fout("        gradientUnits: OBJECT_BOUNDING_BOX\n");\r
-        fout("        spreadMethod: PAD\n");\r
+        out("    /* create RadialGradient for %s */\n", id.c_str());\r
+        out("    private function %s() {\n", id.c_str());\r
+        out("        RadialGradient {\n");\r
+        out("            centerX: %s\n", DSTR(g->cx.value));\r
+        out("            centerY: %s\n", DSTR(g->cy.value));\r
+        out("            focusX: %s\n",  DSTR(g->fx.value));\r
+        out("            focusY: %s\n",  DSTR(g->fy.value));\r
+        out("            radius: %s\n",  DSTR(g->r.value ));\r
         std::vector<SPGradientStop> stops = g->vector.stops;\r
         if (stops.size() > 0)\r
             {\r
-            fout("        stops:\n");\r
-            fout("            [\n");\r
+            out("            stops:\n");\r
+            out("            [\n");\r
             for (unsigned int i = 0 ; i<stops.size() ; i++)\r
                 {\r
                 SPGradientStop stop = stops[i];\r
-                fout("            Stop\n");\r
-                fout("                {\n");\r
-                fout("                offset: %s\n", dstr(stop.offset).c_str());\r
-                fout("                color: %s\n", rgba(stop.color, stop.opacity).c_str());\r
-                fout("                },\n");\r
+                out("                Stop {\n");\r
+                out("                    offset: %s\n", DSTR(stop.offset));\r
+                out("                    color: %s\n",  rgba(stop.color, stop.opacity).c_str());\r
+                out("                },\n");\r
                 }\r
-            fout("            ]\n");\r
+            out("            ]\n");\r
             }\r
-        fout("        },\n");\r
-        fout("    ];\n");\r
-        fout("\n\n");\r
+        out("        };\n");\r
+        out("    } // end RadialGradient: %s\n", id.c_str());\r
+        out("\n\n");\r
         }\r
     else\r
         {\r
@@ -346,7 +374,7 @@ bool JavaFXOutput::doStyle(SPStyle *style)
     if (!style)\r
         return true;\r
 \r
-    out("        opacity: %s\n", dstr(effective_opacity(style)).c_str());\r
+    out("            opacity: %s\n", DSTR(effective_opacity(style)));\r
 \r
     /**\r
      * Fill\r
@@ -355,19 +383,18 @@ bool JavaFXOutput::doStyle(SPStyle *style)
     if (fill.isColor())\r
         {\r
         // see color.h for how to parse SPColor\r
-        out("        fill: %s\n",\r
+        out("            fill: %s\n",\r
             rgba(fill.value.color, SP_SCALE24_TO_FLOAT(style->fill_opacity.value)).c_str());\r
         }\r
-    else if (fill.isPaintserver())\r
-        {\r
-        if (fill.value.href && fill.value.href->getURI() )\r
-            {\r
+    else if (fill.isPaintserver()){\r
+        if (fill.value.href && fill.value.href->getURI() ){\r
             String uri = fill.value.href->getURI()->toString();\r
-            if (uri.size()>0 && uri[0]=='#')\r
+            /* trim the anchor '#' from the front */\r
+            if (uri.size() > 0 && uri[0]=='#')\r
                 uri = uri.substr(1);\r
-            out("        fill: %s()\n", uri.c_str());\r
-            }\r
+            out("            fill: %s()\n", uri.c_str());\r
         }\r
+    }\r
 \r
 \r
     /**\r
@@ -389,17 +416,37 @@ bool JavaFXOutput::doStyle(SPStyle *style)
     if (style->stroke_opacity.value > 0)\r
         {\r
         SPIPaint stroke = style->stroke;\r
-        out("        stroke: %s\n",\r
+        out("            stroke: %s\n",\r
             rgba(stroke.value.color, SP_SCALE24_TO_FLOAT(style->stroke_opacity.value)).c_str());\r
         double strokewidth = style->stroke_width.value;\r
-        out("        strokeWidth: %s\n", dstr(strokewidth).c_str());\r
+        unsigned linecap   = style->stroke_linecap.value;\r
+        unsigned linejoin  = style->stroke_linejoin.value;\r
+        out("            strokeWidth: %s\n",      DSTR(strokewidth));\r
+        out("            strokeLineCap: %s\n",    getStrokeLineCap(linecap).c_str());\r
+        out("            strokeLineJoin: %s\n",   getStrokeLineJoin(linejoin).c_str());\r
+        out("            strokeMiterLimit: %s\n", DSTR(style->stroke_miterlimit.value));\r
+        if(style->stroke_dasharray_set) {\r
+           if(style->stroke_dashoffset_set) {\r
+               out("            strokeDashOffset: %s\n", DSTR(style->stroke_dash.offset));\r
+           }\r
+           out("            strokeDashArray: [ ");\r
+           for(int i = 0; i < style->stroke_dash.n_dash; i++ ) {\r
+               if(i > 0) {\r
+                   out(", %.2lf", style->stroke_dash.dash[i]);\r
+               }else {\r
+                   out(" %.2lf", style->stroke_dash.dash[i]);\r
+               }\r
+           }\r
+           out(" ]\n");\r
+        }\r
+\r
         }\r
 \r
     return true;\r
 }\r
 \r
 \r
-\r
+#if 1\r
 \r
 /**\r
  *  Output the curve data to buffer\r
@@ -420,12 +467,10 @@ bool JavaFXOutput::doCurve(SPItem *item, const String &id)
 \r
     nrShapes++;\r
 \r
-    out("        /*###################################################\n");\r
-    out("        ### PATH:  %s\n", id.c_str());\r
-    out("        ###################################################*/\n");\r
-    out("        Path \n");\r
-    out("        {\n");\r
-    out("        id: \"%s\"\n", id.c_str());\r
+    out("    /** path %s */\n", id.c_str());\r
+    out("    private function %s() : Path {\n",id.c_str());\r
+    out("        Path {\n");\r
+    out("            id: \"%s\"\n", id.c_str());\r
 \r
     /**\r
      * Output the style information\r
@@ -446,41 +491,40 @@ bool JavaFXOutput::doCurve(SPItem *item, const String &id)
             segmentCount += 1;\r
     }\r
 \r
-    out("        d:\n");\r
-    out("            [\n");\r
+    out("            elements: [\n");\r
 \r
     unsigned int segmentNr = 0;\r
 \r
-    nrSegments += segmentCount;\r
+    nrNodes += segmentCount;\r
 \r
-    Geom::Rect cminmax( pathv.front().initialPoint(), pathv.front().initialPoint() ); \r
+    Geom::Rect cminmax( pathv.front().initialPoint(), pathv.front().initialPoint() );\r
 \r
     /**\r
      * For all Subpaths in the <path>\r
-     */             \r
+     */\r
     for (Geom::PathVector::const_iterator pit = pathv.begin(); pit != pathv.end(); ++pit)\r
         {\r
         Geom::Point p = pit->front().initialPoint();\r
         cminmax.expandTo(p);\r
-        out("            MoveTo {\n");\r
-        out("                x: %s\n", dstr(p[X]).c_str());\r
-        out("                y: %s\n", dstr(p[Y]).c_str());\r
-        out("                absolute: true\n");\r
+        out("                MoveTo {\n");\r
+        out("                    x: %s\n", DSTR(p[X]));\r
+        out("                    y: %s\n", DSTR(p[Y]));\r
         out("                },\n");\r
-        \r
+\r
         /**\r
          * For all segments in the subpath\r
-         */                     \r
+         */\r
         for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_closed(); ++cit)\r
             {\r
             //### LINE\r
-            if( is_straight_curve(*cit) )\r
+            if( dynamic_cast<Geom::LineSegment  const *> (&*cit) ||\r
+                dynamic_cast<Geom::HLineSegment const *> (&*cit) ||\r
+                dynamic_cast<Geom::VLineSegment const *> (&*cit) )\r
                 {\r
                 Geom::Point p = cit->finalPoint();\r
-                out("            LineTo {\n");\r
-                out("                x: %s\n", dstr(p[X]).c_str());\r
-                out("                y: %s\n", dstr(p[Y]).c_str());\r
-                out("                absolute: true\n");\r
+                out("                LineTo {\n");\r
+                out("                    x: %s\n", DSTR(p[X]));\r
+                out("                    y: %s\n", DSTR(p[Y]));\r
                 out("                },\n");\r
                 nrNodes++;\r
                 }\r
@@ -491,14 +535,13 @@ bool JavaFXOutput::doCurve(SPItem *item, const String &id)
                 Geom::Point p1 = points[1];\r
                 Geom::Point p2 = points[2];\r
                 Geom::Point p3 = points[3];\r
-                out("            CurveTo {\n");\r
-                out("                x1: %s\n", dstr(p1[X]).c_str());\r
-                out("                y1: %s\n", dstr(p1[Y]).c_str());\r
-                out("                x2: %s\n", dstr(p2[X]).c_str());\r
-                out("                y2: %s\n", dstr(p2[Y]).c_str());\r
-                out("                x3: %s\n", dstr(p3[X]).c_str());\r
-                out("                y3: %s\n", dstr(p3[Y]).c_str());\r
-                out("                absolute: true\n");\r
+                out("                CurveTo {\n");\r
+                out("                    controlX1: %s\n", DSTR(p1[X]));\r
+                out("                    controlY1: %s\n", DSTR(p1[Y]));\r
+                out("                    controlX2: %s\n", DSTR(p2[X]));\r
+                out("                    controlY2: %s\n", DSTR(p2[Y]));\r
+                out("                    x: %s\n",         DSTR(p3[X]));\r
+                out("                    y: %s\n",         DSTR(p3[Y]));\r
                 out("                },\n");\r
                 nrNodes++;\r
                 }\r
@@ -511,17 +554,13 @@ bool JavaFXOutput::doCurve(SPItem *item, const String &id)
             }\r
         if (pit->closed())\r
             {\r
-            out("            ClosePath {},\n");\r
+            out("                ClosePath {},\n");\r
             }\r
         }\r
 \r
-    out("            ] // d\n");\r
-    out("        }, // Path\n");\r
-\r
-                 \r
-    out("        /*###################################################\n");\r
-    out("        ### end path %s\n", id.c_str());\r
-    out("        ###################################################*/\n\n\n\n");\r
+    out("            ] // elements\n");\r
+    out("        }; // Path\n");\r
+    out("    } // end path %s\n\n", id.c_str());\r
 \r
     double cminx = cminmax.min()[X];\r
     double cmaxx = cminmax.max()[X];\r
@@ -541,17 +580,108 @@ bool JavaFXOutput::doCurve(SPItem *item, const String &id)
 }\r
 \r
 \r
+\r
+#else\r
+\r
 /**\r
  *  Output the curve data to buffer\r
  */\r
-bool JavaFXOutput::doCurvesRecursive(SPDocument *doc, Inkscape::XML::Node *node)\r
+bool JavaFXOutput::doCurve(SPItem *item, const String &id)\r
+{\r
+    using Geom::X;\r
+    using Geom::Y;\r
+\r
+    //### Get the Shape\r
+    if (!SP_IS_SHAPE(item))//Bulia's suggestion.  Allow all shapes\r
+        return true;\r
+\r
+    SPShape *shape = SP_SHAPE(item);\r
+    SPCurve *curve = shape->curve;\r
+    if (curve->is_empty())\r
+        return true;\r
+\r
+    nrShapes++;\r
+\r
+    out("        SVGPath \n");\r
+    out("        {\n");\r
+    out("        id: \"%s\"\n", id.c_str());\r
+\r
+    /**\r
+     * Output the style information\r
+     */\r
+    if (!doStyle(SP_OBJECT_STYLE(shape)))\r
+        return false;\r
+\r
+    // convert the path to only lineto's and cubic curveto's:\r
+    Geom::Scale yflip(1.0, -1.0);\r
+    Geom::Matrix tf = sp_item_i2d_affine(item) * yflip;\r
+    Geom::PathVector pathv = pathv_to_linear_and_cubic_beziers( curve->get_pathvector() * tf );\r
+    \r
+    //Count the NR_CURVETOs/LINETOs (including closing line segment)\r
+    nrNodes = 0;\r
+    for(Geom::PathVector::const_iterator it = pathv.begin(); it != pathv.end(); ++it) {\r
+        nrNodes += (*it).size();\r
+        if (it->closed())\r
+            nrNodes += 1;\r
+    }\r
+\r
+    char *dataStr = sp_svg_write_path(pathv);\r
+    out("        content: \"%s\"\n", dataStr);\r
+    free(dataStr);\r
+\r
+    Geom::Rect cminmax( pathv.front().initialPoint(), pathv.front().initialPoint() ); \r
+\r
+    /**\r
+     * Get the Min and Max X and Y extends for the Path. \r
+     * ....For all Subpaths in the <path>\r
+     */             \r
+    for (Geom::PathVector::const_iterator pit = pathv.begin(); pit != pathv.end(); ++pit)\r
+        {\r
+        cminmax.expandTo(pit->front().initialPoint());\r
+        /**\r
+         * For all segments in the subpath\r
+         */                     \r
+        for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_closed(); ++cit)\r
+            {\r
+            cminmax.expandTo(cit->finalPoint());\r
+            }\r
+        }\r
+\r
+    out("        },\n");\r
+\r
+    double cminx = cminmax.min()[X];\r
+    double cmaxx = cminmax.max()[X];\r
+    double cminy = cminmax.min()[Y];\r
+    double cmaxy = cminmax.max()[Y];\r
+\r
+    if (cminx < minx)\r
+        minx = cminx;\r
+    if (cmaxx > maxx)\r
+        maxx = cmaxx;\r
+    if (cminy < miny)\r
+        miny = cminy;\r
+    if (cmaxy > maxy)\r
+        maxy = cmaxy;\r
+\r
+    return true;\r
+}\r
+\r
+\r
+\r
+#endif  /* #if o */\r
+\r
+\r
+\r
+/**\r
+ *  Output the tree data to buffer\r
+ */\r
+bool JavaFXOutput::doTreeRecursive(SPDocument *doc, SPObject *obj)\r
 {\r
     /**\r
      * Check the type of node and process\r
      */\r
     String id;\r
-    char *idstr = (char *) node->attribute("id");\r
-    if (!idstr)\r
+    if (!obj->id)\r
         {\r
         char buf[16];\r
         sprintf(buf, "id%d", idindex++);\r
@@ -559,18 +689,17 @@ bool JavaFXOutput::doCurvesRecursive(SPDocument *doc, Inkscape::XML::Node *node)
         }\r
     else\r
         {\r
-        id = idstr;\r
+        id = obj->id;\r
         }\r
-    SPObject *reprobj = doc->getObjectByRepr(node);\r
-    if (SP_IS_ITEM(reprobj))\r
+    if (SP_IS_ITEM(obj))\r
         {\r
-        SPItem *item = SP_ITEM(reprobj);\r
+        SPItem *item = SP_ITEM(obj);\r
         if (!doCurve(item, id))\r
             return false;\r
         }\r
-    else if (SP_IS_GRADIENT(reprobj))\r
+    else if (SP_IS_GRADIENT(obj))\r
         {\r
-        SPGradient *grad = SP_GRADIENT(reprobj);\r
+        SPGradient *grad = SP_GRADIENT(obj);\r
         if (!doGradient(grad, id))\r
             return false;\r
         }\r
@@ -578,10 +707,9 @@ bool JavaFXOutput::doCurvesRecursive(SPDocument *doc, Inkscape::XML::Node *node)
     /**\r
      * Descend into children\r
      */             \r
-    for (Inkscape::XML::Node *child = node->firstChild() ; child ;\r
-              child = child->next())\r
+    for (SPObject *child = obj->firstChild() ; child ; child = child->next)\r
         {\r
-               if (!doCurvesRecursive(doc, child))\r
+               if (!doTreeRecursive(doc, child))\r
                    return false;\r
                }\r
 \r
@@ -592,7 +720,7 @@ bool JavaFXOutput::doCurvesRecursive(SPDocument *doc, Inkscape::XML::Node *node)
 /**\r
  *  Output the curve data to buffer\r
  */\r
-bool JavaFXOutput::doCurves(SPDocument *doc)\r
+bool JavaFXOutput::doTree(SPDocument *doc)\r
 {\r
 \r
     double bignum = 1000000.0;\r
@@ -601,7 +729,7 @@ bool JavaFXOutput::doCurves(SPDocument *doc)
     miny  =  bignum;\r
     maxy  = -bignum;\r
 \r
-    if (!doCurvesRecursive(doc, doc->rroot))\r
+    if (!doTreeRecursive(doc, doc->root))\r
         return false;\r
 \r
     return true;\r
@@ -609,6 +737,51 @@ bool JavaFXOutput::doCurves(SPDocument *doc)
 }\r
 \r
 \r
+bool JavaFXOutput::doBody(SPDocument *doc, SPObject *obj) {\r
+    /**\r
+     * Check the type of node and process\r
+     */\r
+    String id;\r
+    if (!obj->id)\r
+        {\r
+        char buf[16];\r
+        sprintf(buf, "id%d", idindex++);\r
+        id = buf;\r
+        }\r
+    else\r
+        {\r
+        id = obj->id;\r
+        }\r
+\r
+    if (SP_IS_ITEM(obj)) {\r
+        SPItem *item = SP_ITEM(obj);\r
+        //### Get the Shape\r
+        if (SP_IS_SHAPE(item)) {//Bulia's suggestion.  Allow all shapes\r
+            SPShape *shape = SP_SHAPE(item);\r
+            SPCurve *curve = shape->curve;\r
+            if (!curve->is_empty())\r
+                out("               %s(),\n", id.c_str());\r
+        }\r
+    }\r
+    else if (SP_IS_GRADIENT(obj)) {\r
+        //TODO: what to do with Gradient within body?????\r
+        //SPGradient *grad = SP_GRADIENT(reprobj);\r
+        //if (!doGradient(grad, id))\r
+        //    return false;\r
+    }\r
+\r
+    /**\r
+     * Descend into children\r
+     */\r
+    for (SPObject *child = obj->firstChild() ; child ; child = child->next)\r
+        {\r
+               if (!doBody(doc, child))\r
+                   return false;\r
+               }\r
+\r
+    return true;\r
+}\r
+\r
 \r
 \r
 //########################################################################\r
@@ -623,14 +796,11 @@ bool JavaFXOutput::doCurves(SPDocument *doc)
 void JavaFXOutput::reset()\r
 {\r
     nrNodes    = 0;\r
-    nrSegments = 0;\r
     nrShapes   = 0;\r
     idindex    = 0;\r
     name.clear();\r
     outbuf.clear();\r
     foutbuf.clear();\r
-    linearGradients.clear();\r
-    radialGradients.clear();\r
 }\r
 \r
 \r
@@ -649,25 +819,35 @@ bool JavaFXOutput::saveDocument(SPDocument *doc, gchar const *uri)
         name = name.substr(0, pos);\r
 \r
 \r
-    //###### SAVE IN POV FORMAT TO BUFFER\r
+    //###### SAVE IN JAVAFX FORMAT TO BUFFER\r
     //# Lets do the curves first, to get the stats\r
-    \r
-    if (!doCurves(doc))\r
+\r
+    if (!doTree(doc))\r
         return false;\r
     String curveBuf = outbuf;\r
     outbuf.clear();\r
 \r
     if (!doHeader())\r
         return false;\r
-    \r
+\r
     outbuf.append(curveBuf);\r
 \r
+#ifdef JAVAFX_SDK_1_0\r
+    out("   override function create(): Node {\n");\r
+#else\r
+    out("   public function create(): Node {\n");\r
+#endif\r
+    out("       Group {\n");\r
+    out("           content: [\n");\r
+    idindex    = 0;\r
+\r
+    doBody(doc, doc->root);\r
+\r
     if (!doTail())\r
         return false;\r
 \r
 \r
 \r
-\r
     //###### WRITE TO FILE\r
     FILE *f = Inkscape::IO::fopen_utf8name(uri, "w");\r
     if (!f)\r