Code

eliminate direct accesses to SPCurve::bpath
[inkscape.git] / src / extension / internal / odf.cpp
index 1487293bbcf9d18faeddc5ddf0db1021be9c26bf..16ff0f18f2469e3d7a01ecf1a0966d241b0373ea 100644 (file)
@@ -5,7 +5,10 @@
  * the inputting and outputting of OpenDocument Format (ODF) files from
  * within Inkscape.  Although the initial implementations will be very lossy
  * do to the differences in the models of SVG and ODF, they will hopefully
- * improve greatly with time.
+ * improve greatly with time.  People should consider this to be a framework
+ * that can be continously upgraded for ever improving fidelity.  Potential
+ * developers should especially look in preprocess() and writeTree() to see how
+ * the SVG tree is scanned, read, translated, and then written to ODF.
  *
  * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html
  *
@@ -855,6 +858,9 @@ int SingularValueDecomposition::rank()
 //# O U T P U T
 //########################################################################
 
+/**
+ * Get the value of a node/attribute pair
+ */
 static std::string getAttribute( Inkscape::XML::Node *node, char *attrName)
 {
     std::string val;
@@ -865,6 +871,10 @@ static std::string getAttribute( Inkscape::XML::Node *node, char *attrName)
 }
 
 
+
+/**
+ * Get the extension suffix from the end of a file name
+ */
 static std::string getExtension(const std::string &fname)
 {
     std::string ext;
@@ -898,6 +908,7 @@ static std::string formatTransform(NR::Matrix &tf)
 
 
 
+
 /**
  * Get the general transform from SVG pixels to
  * ODF cm
@@ -917,6 +928,8 @@ static NR::Matrix getODFTransform(const SPItem *item)
 }
 
 
+
+
 /**
  * Get the bounding box of an item, as mapped onto
  * an ODF document, in cm.
@@ -983,7 +996,8 @@ static void analyzeTransform(NR::Matrix &tf,
 
 
 /**
- * Method descends into the repr tree, converting image and style info
+ * FIRST PASS.
+ * Method descends into the repr tree, converting image, style, and gradient info
  * into forms compatible in ODF.
  */
 void
@@ -1019,7 +1033,7 @@ OdfOutput::preprocess(ZipFile &zf, Inkscape::XML::Node *node)
                 {
                 char buf[64];
                 snprintf(buf, 63, "Pictures/image%d%s",
-                    imageTable.size(), ext.c_str());
+                    (int)imageTable.size(), ext.c_str());
                 std::string newName = buf;
                 imageTable[oldName] = newName;
                 std::string comment = "old name was: ";
@@ -1052,6 +1066,10 @@ OdfOutput::preprocess(ZipFile &zf, Inkscape::XML::Node *node)
         bool isGradient = false;
 
         StyleInfo si;
+        //## Style.  Look in writeStyle() below to see what info
+        //   we need to read into StyleInfo.  Note that we need to
+        //   determine whether information goes into a style element
+        //   or a gradient element.
         //## FILL
         if (style->fill.type == SP_PAINT_TYPE_COLOR)
             {
@@ -1072,6 +1090,8 @@ OdfOutput::preprocess(ZipFile &zf, Inkscape::XML::Node *node)
             }
         else if (style->fill.type == SP_PAINT_TYPE_PAINTSERVER)
             {
+            //## Gradient.  Look in writeStyle() below to see what info
+            //   we need to read into GradientInfo.
             if (!SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)))
                 return;
             isGradient = true;
@@ -1117,7 +1137,7 @@ OdfOutput::preprocess(ZipFile &zf, Inkscape::XML::Node *node)
             if (!gradientMatch)
                 {
                 char buf[16];
-                snprintf(buf, 15, "gradient%d", gradientTable.size());
+                snprintf(buf, 15, "gradient%d", (int)gradientTable.size());
                 std::string gradientName = buf;
                 gi.name = gradientName;
                 gradientTable.push_back(gi);
@@ -1166,7 +1186,7 @@ OdfOutput::preprocess(ZipFile &zf, Inkscape::XML::Node *node)
             if (!styleMatch)
                 {
                 char buf[16];
-                snprintf(buf, 15, "style%d", styleTable.size());
+                snprintf(buf, 15, "style%d", (int)styleTable.size());
                 std::string styleName = buf;
                 si.name = styleName;
                 styleTable.push_back(si);
@@ -1182,6 +1202,10 @@ OdfOutput::preprocess(ZipFile &zf, Inkscape::XML::Node *node)
 
 
 
+/**
+ * Writes the manifest.  Currently it only changes according to the
+ * file names of images packed into the zip file.
+ */
 bool OdfOutput::writeManifest(ZipFile &zf)
 {
     BufferOutputStream bouts;
@@ -1241,6 +1265,9 @@ bool OdfOutput::writeManifest(ZipFile &zf)
 }
 
 
+/**
+ * This writes the document meta information to meta.xml
+ */
 bool OdfOutput::writeMeta(ZipFile &zf)
 {
     BufferOutputStream bouts;
@@ -1302,6 +1329,12 @@ bool OdfOutput::writeMeta(ZipFile &zf)
 }
 
 
+
+
+/**
+ * This is called just before writeTree(), since it will write style and
+ * gradient information above the <draw> tag in the content.xml file
+ */
 bool OdfOutput::writeStyle(Writer &outs)
 {
     outs.printf("<office:automatic-styles>\n");
@@ -1319,7 +1352,21 @@ bool OdfOutput::writeStyle(Writer &outs)
     outs.printf("  <style:paragraph-properties fo:text-align=\"center\"/>\n");
     outs.printf("</style:style>\n");
 
-    //##  Dump our style table
+    /*
+    ==========================================================
+    Dump our style table.  Styles should have a general layout
+    something like the following.  Look in:
+    http://books.evc-cit.info/odbook/ch06.html#draw-style-file-section
+    for style and gradient information.
+    <style:style style:name="gr13"
+      style:family="graphic" style:parent-style-name="standard">
+        <style:graphic-properties draw:stroke="solid"
+            svg:stroke-width="0.1cm"
+            svg:stroke-color="#ff0000"
+            draw:fill="solid" draw:fill-color="#e6e6ff"/>
+    </style:style>
+    ==========================================================
+    */
     outs.printf("<!-- ####### Styles from Inkscape document ####### -->\n");
     std::vector<StyleInfo>::iterator iter;
     for (iter = styleTable.begin() ; iter != styleTable.end() ; iter++)
@@ -1353,13 +1400,37 @@ bool OdfOutput::writeStyle(Writer &outs)
         {
         GradientInfo gi(*giter);
         outs.printf("<draw:gradient draw:name=\"%s\" ", gi.name.c_str());
-        outs.printf("draw:display-name=\"%s\" ", gi.name.c_str());
         outs.printf("draw:style=\"%s\" ", gi.style.c_str());
         if (gi.style == "linear")
             {
+            /*
+            ===================================================================
+            LINEAR gradient.  We need something that looks like this:
+            <draw:gradient draw:name="Gradient_20_7"
+                draw:display-name="Gradient 7"
+                draw:style="linear"
+                draw:start-color="#008080" draw:end-color="#993366"
+                draw:start-intensity="100%" draw:end-intensity="100%"
+                draw:angle="150" draw:border="0%"/>
+            ===================================================================
+            */
+            outs.printf("draw:display-name=\"linear borderless\" ");
             }
-        else if (gi.style == "gradient")
+        else if (gi.style == "radial")
             {
+            /*
+            ===================================================================
+            RADIAL gradient.  We need something that looks like this:
+            <!-- radial gradient, light gray to white, centered, 0% border -->
+            <draw:gradient draw:name="radial_20_borderless"
+                draw:display-name="radial borderless"
+                draw:style="radial"
+                draw:cx="50%" draw:cy="50%"
+                draw:start-color="#999999" draw:end-color="#ffffff"
+                draw:border="0%"/>
+            ===================================================================
+            */
+            outs.printf("draw:display-name=\"radial borderless\" ");
             outs.printf("draw:cx=\".2f%%\" draw:cy=\".2f%%\" ", gi.cx, gi.cy);
             }
         else
@@ -1433,8 +1504,10 @@ writePath(Writer &outs, NArtBpath const *bpath,
 
 
 /**
+ * SECOND PASS.
  * This is the main SPObject tree output to ODF.  preprocess()
- * must be called prior to this
+ * must be called prior to this, as elements will often reference
+ * data parsed and tabled in preprocess().
  */
 bool OdfOutput::writeTree(Writer &outs, Inkscape::XML::Node *node)
 {
@@ -1601,7 +1674,7 @@ bool OdfOutput::writeTree(Writer &outs, Inkscape::XML::Node *node)
                       bbox_width * 1000.0, bbox_height * 1000.0);
 
        outs.printf("    svg:d=\"");
-       writePath(outs, curve->bpath, tf, bbox_x, bbox_y);
+       writePath(outs, SP_CURVE_BPATH(curve), tf, bbox_x, bbox_y);
        outs.printf("\"");
 
        outs.printf(">\n");
@@ -1616,7 +1689,10 @@ bool OdfOutput::writeTree(Writer &outs, Inkscape::XML::Node *node)
 
 
 
-
+/**
+ * Write the content.xml file.  Writes the namesspace headers, then
+ * calls writeStyle() and writeTree().
+ */
 bool OdfOutput::writeContent(ZipFile &zf, Inkscape::XML::Node *node)
 {
     BufferOutputStream bouts;
@@ -1670,8 +1746,6 @@ bool OdfOutput::writeContent(ZipFile &zf, Inkscape::XML::Node *node)
     outs.printf("<office:scripts/>\n");
     outs.printf("\n");
     outs.printf("\n");
-    //AffineTransform trans = new AffineTransform();
-    //trans.scale(12.0, 12.0);
     outs.printf("<!-- ######### CONVERSION FROM SVG STARTS ######## -->\n");
     outs.printf("<!--\n");
     outs.printf("*************************************************************************\n");