$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: john_at_[hidden]
Date: 2008-04-09 07:45:16
Author: johnmaddock
Date: 2008-04-09 07:45:15 EDT (Wed, 09 Apr 2008)
New Revision: 44124
URL: http://svn.boost.org/trac/boost/changeset/44124
Log:
Added improved SVG support.
Text files modified: 
   trunk/tools/quickbook/detail/actions.cpp |    73 ++++++++++++++++++++++++++++++++++++++- 
   1 files changed, 71 insertions(+), 2 deletions(-)
Modified: trunk/tools/quickbook/detail/actions.cpp
==============================================================================
--- trunk/tools/quickbook/detail/actions.cpp	(original)
+++ trunk/tools/quickbook/detail/actions.cpp	2008-04-09 07:45:15 EDT (Wed, 09 Apr 2008)
@@ -12,6 +12,7 @@
 #include <functional>
 #include <boost/bind.hpp>
 #include <boost/filesystem/convenience.hpp>
+#include <boost/filesystem/fstream.hpp>
 #include <boost/lexical_cast.hpp>
 #include "./actions.hpp"
 #include "./utils.hpp"
@@ -324,7 +325,11 @@
         temp.swap(str);
         phrase.swap(save);
 
-        out << "<programlisting>\n";
+        //
+        // We must not place a \n after the <programlisting> tag
+        // otherwise PDF output starts code blocks with a blank line:
+        //
+        out << "<programlisting>";
         out << str;
         out << "</programlisting>\n";
     }
@@ -376,9 +381,73 @@
     {
         fs::path const img_path(std::string(first, last));
 
+        std::string attr_text;
+        if(fs::extension(img_path) == ".svg")
+        {
+           //
+           // SVG's need special handling:
+           //
+           // 1) We must set the "format" attribute, otherwise
+           //    HTML generation produces code that will not display
+           //    the image at all.
+           // 2) We need to set the "contentwidth" and "contentdepth"
+           //    attributes, otherwise the image will be displayed inside
+           //    a tiny box with scrollbars (Firefox), or else cropped to
+           //    fit in a tiny box (IE7).
+           //
+           attr_text = " format=\"SVG\"";
+           //
+           // Image paths are relative to the html subdirectory:
+           //
+           fs::path img;
+           if(img_path.root_path().empty())
+              img = "html" / img_path;  // relative path
+           else
+              img = img_path;   // absolute path
+           //
+           // Now load the SVG file:
+           //
+           std::string svg_text;
+           fs::ifstream fs(img);
+           char c;
+           while(fs.get(c) && fs.good())
+              svg_text.push_back(c);
+           //
+           // Extract the svg header from the file:
+           //
+           std::string::size_type a, b;
+           a = svg_text.find("<svg");
+           b = svg_text.find('>', a);
+           svg_text = (a == std::string::npos) ? "" : svg_text.substr(a, b - a);
+           //
+           // Now locate the "width" and "height" attributes
+           // and borrow their values:
+           //
+           a = svg_text.find("width");
+           a = svg_text.find('=', a);
+           a = svg_text.find('\"', a);
+           b = svg_text.find('\"', a + 1);
+           if(a != std::string::npos)
+           {
+              attr_text.append(" contentwidth=");
+              attr_text.append(svg_text.begin() + a, svg_text.begin() + b + 1);
+           }
+           a = svg_text.find("height");
+           a = svg_text.find('=', a);
+           a = svg_text.find('\"', a);
+           b = svg_text.find('\"', a + 1);
+           if(a != std::string::npos)
+           {
+              attr_text.append(" contentdepth=");
+              attr_text.append(svg_text.begin() + a, svg_text.begin() + b + 1);
+           }
+        }
+
         phrase << "<inlinemediaobject>";
 
-        phrase << "<imageobject><imagedata fileref=\"";
+        phrase << "<imageobject><imagedata ";
+        phrase << attr_text;
+        phrase << " fileref=\"";
         while (first != last)
             detail::print_char(*first++, phrase.get());
         phrase << "\"></imagedata></imageobject>";