LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/mspub/src/lib - MSPUBSVGGenerator.cpp (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 397 0.0 %
Date: 2012-12-17 Functions: 0 25 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* libmspub
       3             :  * Version: MPL 1.1 / GPLv2+ / LGPLv2+
       4             :  *
       5             :  * The contents of this file are subject to the Mozilla Public License Version
       6             :  * 1.1 (the "License"); you may not use this file except in compliance with
       7             :  * the License or as specified alternatively below. You may obtain a copy of
       8             :  * the License at http://www.mozilla.org/MPL/
       9             :  *
      10             :  * Software distributed under the License is distributed on an "AS IS" basis,
      11             :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12             :  * for the specific language governing rights and limitations under the
      13             :  * License.
      14             :  *
      15             :  * Major Contributor(s):
      16             :  * Copyright (C) 2012 Fridrich Strba <fridrich.strba@bluewin.ch>
      17             :  * Copyright (C) 2011 Eilidh McAdam <tibbylickle@gmail.com>
      18             :  *
      19             :  * All Rights Reserved.
      20             :  *
      21             :  * For minor contributions see the git repository.
      22             :  *
      23             :  * Alternatively, the contents of this file may be used under the terms of
      24             :  * either the GNU General Public License Version 2 or later (the "GPLv2+"), or
      25             :  * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
      26             :  * in which case the provisions of the GPLv2+ or the LGPLv2+ are applicable
      27             :  * instead of those above.
      28             :  */
      29             : 
      30             : #include "MSPUBSVGGenerator.h"
      31             : #include "libmspub.h"
      32             : #include <locale.h>
      33             : #include <sstream>
      34             : #include <string>
      35             : 
      36           0 : static std::string doubleToString(const double value)
      37             : {
      38           0 :   std::ostringstream tempStream;
      39           0 :   tempStream << value;
      40             : #ifndef __ANDROID__
      41           0 :   std::string decimalPoint(localeconv()->decimal_point);
      42             : #else
      43             :   std::string decimalPoint(".");
      44             : #endif
      45           0 :   if ((decimalPoint.size() == 0) || (decimalPoint == "."))
      46           0 :     return tempStream.str();
      47           0 :   std::string stringValue(tempStream.str());
      48           0 :   if (!stringValue.empty())
      49             :   {
      50             :     std::string::size_type pos;
      51           0 :     while ((pos = stringValue.find(decimalPoint)) != std::string::npos)
      52           0 :       stringValue.replace(pos,decimalPoint.size(),".");
      53             :   }
      54           0 :   return stringValue;
      55             : }
      56             : 
      57           0 : static unsigned stringToColour(const ::WPXString &s)
      58             : {
      59           0 :   std::string str(s.cstr());
      60           0 :   if (str[0] == '#')
      61             :   {
      62           0 :     if (str.length() != 7)
      63           0 :       return 0;
      64             :     else
      65           0 :       str.erase(str.begin());
      66             :   }
      67             :   else
      68           0 :     return 0;
      69             : 
      70           0 :   std::istringstream istr(str);
      71           0 :   unsigned val = 0;
      72           0 :   istr >> std::hex >> val;
      73           0 :   return val;
      74             : }
      75             : 
      76           0 : libmspub::MSPUBSVGGenerator::MSPUBSVGGenerator(libmspub::MSPUBStringVector &vec): m_gradient(), m_style(), m_gradientIndex(1), m_patternIndex(1), m_shadowIndex(1), m_outputSink(), m_vec(vec)
      77             : {
      78           0 : }
      79             : 
      80           0 : libmspub::MSPUBSVGGenerator::~MSPUBSVGGenerator()
      81             : {
      82           0 : }
      83             : 
      84           0 : void libmspub::MSPUBSVGGenerator::startGraphics(const WPXPropertyList &propList)
      85             : {
      86           0 :   m_outputSink << "<svg:svg version=\"1.1\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" ";
      87           0 :   if (propList["svg:width"])
      88           0 :     m_outputSink << "width=\"" << doubleToString(72*(propList["svg:width"]->getDouble())) << "\" ";
      89           0 :   if (propList["svg:height"])
      90           0 :     m_outputSink << "height=\"" << doubleToString(72*(propList["svg:height"]->getDouble())) << "\"";
      91           0 :   m_outputSink << " >\n";
      92           0 : }
      93             : 
      94           0 : void libmspub::MSPUBSVGGenerator::endGraphics()
      95             : {
      96           0 :   m_outputSink << "</svg:svg>\n";
      97           0 :   m_vec.append(m_outputSink.str().c_str());
      98           0 :   m_outputSink.str("");
      99           0 : }
     100             : 
     101           0 : void libmspub::MSPUBSVGGenerator::setStyle(const ::WPXPropertyList &propList, const ::WPXPropertyListVector &gradient)
     102             : {
     103           0 :   m_style.clear();
     104           0 :   m_style = propList;
     105             : 
     106           0 :   m_gradient = gradient;
     107           0 :   if(m_style["draw:shadow"] && m_style["draw:shadow"]->getStr() == "visible")
     108             :   {
     109           0 :     double shadowRed = 0.0;
     110           0 :     double shadowGreen = 0.0;
     111           0 :     double shadowBlue = 0.0;
     112           0 :     if (m_style["draw:shadow-color"])
     113             :     {
     114           0 :       unsigned shadowColour = stringToColour(m_style["draw:shadow-color"]->getStr());
     115           0 :       shadowRed = (double)((shadowColour & 0x00ff0000) >> 16)/255.0;
     116           0 :       shadowGreen = (double)((shadowColour & 0x0000ff00) >> 8)/255.0;
     117           0 :       shadowBlue = (double)(shadowColour & 0x000000ff)/255.0;
     118             :     }
     119           0 :     m_outputSink << "<svg:defs>\n";
     120           0 :     m_outputSink << "<svg:filter filterUnits=\"userSpaceOnUse\" id=\"shadow" << m_shadowIndex++ << "\">";
     121           0 :     m_outputSink << "<svg:feOffset in=\"SourceGraphic\" result=\"offset\" ";
     122           0 :     m_outputSink << "dx=\"" << doubleToString(72*m_style["draw:shadow-offset-x"]->getDouble()) << "\" ";
     123           0 :     m_outputSink << "dy=\"" << doubleToString(72*m_style["draw:shadow-offset-y"]->getDouble()) << "\"/>";
     124           0 :     m_outputSink << "<svg:feColorMatrix in=\"offset\" result=\"offset-color\" type=\"matrix\" values=\"";
     125           0 :     m_outputSink << "0 0 0 0 " << doubleToString(shadowRed) ;
     126           0 :     m_outputSink << " 0 0 0 0 " << doubleToString(shadowGreen);
     127           0 :     m_outputSink << " 0 0 0 0 " << doubleToString(shadowBlue);
     128           0 :     if(m_style["draw:opacity"] && m_style["draw:opacity"]->getDouble() < 1)
     129           0 :       m_outputSink << " 0 0 0 "   << doubleToString(m_style["draw:shadow-opacity"]->getDouble()/m_style["draw:opacity"]->getDouble()) << " 0\"/>";
     130             :     else
     131           0 :       m_outputSink << " 0 0 0 "   << doubleToString(m_style["draw:shadow-opacity"]->getDouble()) << " 0\"/>";
     132           0 :     m_outputSink << "<svg:feMerge><svg:feMergeNode in=\"offset-color\" /><svg:feMergeNode in=\"SourceGraphic\" /></svg:feMerge></svg:filter></svg:defs>";
     133             :   }
     134             : 
     135           0 :   if(m_style["draw:fill"] && m_style["draw:fill"]->getStr() == "gradient")
     136             :   {
     137           0 :     double angle = (m_style["draw:angle"] ? m_style["draw:angle"]->getDouble() : 0.0);
     138           0 :     angle *= -1.0;
     139           0 :     while(angle < 0)
     140           0 :       angle += 360;
     141           0 :     while(angle > 360)
     142           0 :       angle -= 360;
     143             : 
     144           0 :     if (!m_gradient.count())
     145             :     {
     146           0 :       if (m_style["draw:style"] &&
     147           0 :           (m_style["draw:style"]->getStr() == "radial" ||
     148           0 :            m_style["draw:style"]->getStr() == "rectangular" ||
     149           0 :            m_style["draw:style"]->getStr() == "square" ||
     150           0 :            m_style["draw:style"]->getStr() == "ellipsoid"))
     151             :       {
     152           0 :         m_outputSink << "<svg:defs>\n";
     153           0 :         m_outputSink << "  <svg:radialGradient id=\"grad" << m_gradientIndex++ << "\"";
     154             : 
     155           0 :         if (m_style["svg:cx"])
     156           0 :           m_outputSink << " cx=\"" << m_style["svg:cx"]->getStr().cstr() << "\"";
     157           0 :         else if (m_style["draw:cx"])
     158           0 :           m_outputSink << " cx=\"" << m_style["draw:cx"]->getStr().cstr() << "\"";
     159             : 
     160           0 :         if (m_style["svg:cy"])
     161           0 :           m_outputSink << " cy=\"" << m_style["svg:cy"]->getStr().cstr() << "\"";
     162           0 :         else if (m_style["draw:cy"])
     163           0 :           m_outputSink << " cy=\"" << m_style["draw:cy"]->getStr().cstr() << "\"";
     164           0 :         m_outputSink << " r=\"" << (1 - (m_style["draw:border"] ? m_style["draw:border"]->getDouble() : 0))*100.0 << "%\" >\n";
     165           0 :         m_outputSink << " >\n";
     166             : 
     167           0 :         if (m_style["draw:start-color"] && m_style["draw:end-color"])
     168             :         {
     169           0 :           m_outputSink << "    <svg:stop offset=\"0%\"";
     170           0 :           m_outputSink << " stop-color=\"" << m_style["draw:end-color"]->getStr().cstr() << "\"";
     171           0 :           m_outputSink << " stop-opacity=\"" << (m_style["libwpg:end-opacity"] ? m_style["libwpg:end-opacity"]->getDouble() : 1) << "\" />" << std::endl;
     172             : 
     173           0 :           m_outputSink << "    <svg:stop offset=\"100%\"";
     174           0 :           m_outputSink << " stop-color=\"" << m_style["draw:start-color"]->getStr().cstr() << "\"";
     175           0 :           m_outputSink << " stop-opacity=\"" << (m_style["libwpg:start-opacity"] ? m_style["libwpg:start-opacity"]->getDouble() : 1) << "\" />" << std::endl;
     176             :         }
     177           0 :         m_outputSink << "  </svg:radialGradient>\n";
     178           0 :         m_outputSink << "</svg:defs>\n";
     179             :       }
     180           0 :       else if (m_style["draw:style"] && m_style["draw:style"]->getStr() == "linear")
     181             :       {
     182           0 :         m_outputSink << "<svg:defs>\n";
     183           0 :         m_outputSink << "  <svg:linearGradient id=\"grad" << m_gradientIndex++ << "\" >\n";
     184             : 
     185           0 :         if (m_style["draw:start-color"] && m_style["draw:end-color"])
     186             :         {
     187           0 :           m_outputSink << "    <svg:stop offset=\"0%\"";
     188           0 :           m_outputSink << " stop-color=\"" << m_style["draw:start-color"]->getStr().cstr() << "\"";
     189           0 :           m_outputSink << " stop-opacity=\"" << (m_style["libwpg:start-opacity"] ? m_style["libwpg:start-opacity"]->getDouble() : 1) << "\" />" << std::endl;
     190             : 
     191           0 :           m_outputSink << "    <svg:stop offset=\"100%\"";
     192           0 :           m_outputSink << " stop-color=\"" << m_style["draw:end-color"]->getStr().cstr() << "\"";
     193           0 :           m_outputSink << " stop-opacity=\"" << (m_style["libwpg:end-opacity"] ? m_style["libwpg:end-opacity"]->getDouble() : 1) << "\" />" << std::endl;
     194             :         }
     195           0 :         m_outputSink << "  </svg:linearGradient>\n";
     196             : 
     197             :         // not a simple horizontal gradient
     198           0 :         if(angle != 270)
     199             :         {
     200           0 :           m_outputSink << "  <svg:linearGradient xlink:href=\"#grad" << m_gradientIndex-1 << "\"";
     201           0 :           m_outputSink << " id=\"grad" << m_gradientIndex++ << "\" ";
     202           0 :           m_outputSink << "x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\" ";
     203           0 :           m_outputSink << "gradientTransform=\"rotate(" << angle << " .5 .5)\" ";
     204           0 :           m_outputSink << "gradientUnits=\"objectBoundingBox\" >\n";
     205           0 :           m_outputSink << "  </svg:linearGradient>\n";
     206             :         }
     207             : 
     208           0 :         m_outputSink << "</svg:defs>\n";
     209             :       }
     210           0 :       else if (m_style["draw:style"] && m_style["draw:style"]->getStr() == "axial")
     211             :       {
     212           0 :         m_outputSink << "<svg:defs>\n";
     213           0 :         m_outputSink << "  <svg:linearGradient id=\"grad" << m_gradientIndex++ << "\" >\n";
     214             : 
     215           0 :         if (m_style["draw:start-color"] && m_style["draw:end-color"])
     216             :         {
     217           0 :           m_outputSink << "    <svg:stop offset=\"0%\"";
     218           0 :           m_outputSink << " stop-color=\"" << m_style["draw:end-color"]->getStr().cstr() << "\"";
     219           0 :           m_outputSink << " stop-opacity=\"" << (m_style["libwpg:end-opacity"] ? m_style["libwpg:end-opacity"]->getDouble() : 1) << "\" />" << std::endl;
     220             : 
     221           0 :           m_outputSink << "    <svg:stop offset=\"50%\"";
     222           0 :           m_outputSink << " stop-color=\"" << m_style["draw:start-color"]->getStr().cstr() << "\"";
     223           0 :           m_outputSink << " stop-opacity=\"" << (m_style["libwpg:start-opacity"] ? m_style["libwpg:start-opacity"]->getDouble() : 1) << "\" />" << std::endl;
     224             : 
     225           0 :           m_outputSink << "    <svg:stop offset=\"100%\"";
     226           0 :           m_outputSink << " stop-color=\"" << m_style["draw:end-color"]->getStr().cstr() << "\"";
     227           0 :           m_outputSink << " stop-opacity=\"" << (m_style["libwpg:end-opacity"] ? m_style["libwpg:end-opacity"]->getDouble() : 1) << "\" />" << std::endl;
     228             :         }
     229           0 :         m_outputSink << "  </svg:linearGradient>\n";
     230             : 
     231             :         // not a simple horizontal gradient
     232           0 :         if(angle != 270)
     233             :         {
     234           0 :           m_outputSink << "  <svg:linearGradient xlink:href=\"#grad" << m_gradientIndex-1 << "\"";
     235           0 :           m_outputSink << " id=\"grad" << m_gradientIndex++ << "\" ";
     236           0 :           m_outputSink << "x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\" ";
     237           0 :           m_outputSink << "gradientTransform=\"rotate(" << angle << " .5 .5)\" ";
     238           0 :           m_outputSink << "gradientUnits=\"objectBoundingBox\" >\n";
     239           0 :           m_outputSink << "  </svg:linearGradient>\n";
     240             :         }
     241             : 
     242           0 :         m_outputSink << "</svg:defs>\n";
     243             :       }
     244             :     }
     245             :     else
     246             :     {
     247           0 :       if (m_style["draw:style"] && m_style["draw:style"]->getStr() == "radial")
     248             :       {
     249           0 :         m_outputSink << "<svg:defs>\n";
     250           0 :         m_outputSink << "  <svg:radialGradient id=\"grad" << m_gradientIndex++ << "\" cx=\"" << m_style["svg:cx"]->getStr().cstr() << "\" cy=\"" << m_style["svg:cy"]->getStr().cstr() << "\" r=\"" << m_style["svg:r"]->getStr().cstr() << "\" >\n";
     251           0 :         for(unsigned c = 0; c < m_gradient.count(); c++)
     252             :         {
     253           0 :           m_outputSink << "    <svg:stop offset=\"" << m_gradient[c]["svg:offset"]->getStr().cstr() << "\"";
     254             : 
     255           0 :           m_outputSink << " stop-color=\"" << m_gradient[c]["svg:stop-color"]->getStr().cstr() << "\"";
     256           0 :           m_outputSink << " stop-opacity=\"" << m_gradient[c]["svg:stop-opacity"]->getDouble() << "\" />" << std::endl;
     257             : 
     258             :         }
     259           0 :         m_outputSink << "  </svg:radialGradient>\n";
     260           0 :         m_outputSink << "</svg:defs>\n";
     261             :       }
     262             :       else
     263             :       {
     264           0 :         m_outputSink << "<svg:defs>\n";
     265           0 :         m_outputSink << "  <svg:linearGradient id=\"grad" << m_gradientIndex++ << "\" >\n";
     266           0 :         for(unsigned c = 0; c < m_gradient.count(); c++)
     267             :         {
     268           0 :           m_outputSink << "    <svg:stop offset=\"" << m_gradient[c]["svg:offset"]->getStr().cstr() << "\"";
     269             : 
     270           0 :           m_outputSink << " stop-color=\"" << m_gradient[c]["svg:stop-color"]->getStr().cstr() << "\"";
     271           0 :           m_outputSink << " stop-opacity=\"" << m_gradient[c]["svg:stop-opacity"]->getDouble() << "\" />" << std::endl;
     272             : 
     273             :         }
     274           0 :         m_outputSink << "  </svg:linearGradient>\n";
     275             : 
     276             :         // not a simple horizontal gradient
     277           0 :         if(angle != 270)
     278             :         {
     279           0 :           m_outputSink << "  <svg:linearGradient xlink:href=\"#grad" << m_gradientIndex-1 << "\"";
     280           0 :           m_outputSink << " id=\"grad" << m_gradientIndex++ << "\" ";
     281           0 :           m_outputSink << "x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\" ";
     282           0 :           m_outputSink << "gradientTransform=\"rotate(" << angle << " .5 .5)\" ";
     283           0 :           m_outputSink << "gradientUnits=\"objectBoundingBox\" >\n";
     284           0 :           m_outputSink << "  </svg:linearGradient>\n";
     285             :         }
     286             : 
     287           0 :         m_outputSink << "</svg:defs>\n";
     288             :       }
     289             :     }
     290             :   }
     291           0 :   else if(m_style["draw:fill"] && m_style["draw:fill"]->getStr() == "bitmap")
     292             :   {
     293           0 :     if (m_style["draw:fill-image"] && m_style["libwpg:mime-type"])
     294             :     {
     295           0 :       m_outputSink << "<svg:defs>\n";
     296           0 :       m_outputSink << "  <svg:pattern id=\"img" << m_patternIndex++ << "\" patternUnits=\"userSpaceOnUse\" ";
     297           0 :       if (m_style["svg:width"])
     298           0 :         m_outputSink << "width=\"" << doubleToString(72*(m_style["svg:width"]->getDouble())) << "\" ";
     299             :       else
     300           0 :         m_outputSink << "width=\"100\" ";
     301             : 
     302           0 :       if (m_style["svg:height"])
     303           0 :         m_outputSink << "height=\"" << doubleToString(72*(m_style["svg:height"]->getDouble())) << "\">" << std::endl;
     304             :       else
     305           0 :         m_outputSink << "height=\"100\">" << std::endl;
     306           0 :       m_outputSink << "<svg:image ";
     307             : 
     308           0 :       if (m_style["svg:x"])
     309           0 :         m_outputSink << "x=\"" << doubleToString(72*(m_style["svg:x"]->getDouble())) << "\" ";
     310             :       else
     311           0 :         m_outputSink << "x=\"0\" ";
     312             : 
     313           0 :       if (m_style["svg:y"])
     314           0 :         m_outputSink << "y=\"" << doubleToString(72*(m_style["svg:y"]->getDouble())) << "\" ";
     315             :       else
     316           0 :         m_outputSink << "y=\"0\" ";
     317             : 
     318           0 :       if (m_style["svg:width"])
     319           0 :         m_outputSink << "width=\"" << doubleToString(72*(m_style["svg:width"]->getDouble())) << "\" ";
     320             :       else
     321           0 :         m_outputSink << "width=\"100\" ";
     322             : 
     323           0 :       if (m_style["svg:height"])
     324           0 :         m_outputSink << "height=\"" << doubleToString(72*(m_style["svg:height"]->getDouble())) << "\" ";
     325             :       else
     326           0 :         m_outputSink << "height=\"100\" ";
     327             : 
     328           0 :       m_outputSink << "xlink:href=\"data:" << m_style["libwpg:mime-type"]->getStr().cstr() << ";base64,";
     329           0 :       m_outputSink << m_style["draw:fill-image"]->getStr().cstr();
     330           0 :       m_outputSink << "\" />\n";
     331           0 :       m_outputSink << "  </svg:pattern>\n";
     332           0 :       m_outputSink << "</svg:defs>\n";
     333             :     }
     334             :   }
     335           0 : }
     336             : 
     337           0 : void libmspub::MSPUBSVGGenerator::startLayer(const ::WPXPropertyList &propList)
     338             : {
     339           0 :   m_outputSink << "<svg:g";
     340           0 :   if (propList["svg:id"])
     341           0 :     m_outputSink << " id=\"Layer" << propList["svg:id"]->getStr().cstr() << "\"";
     342           0 :   if (propList["svg:fill-rule"])
     343           0 :     m_outputSink << " fill-rule=\"" << propList["svg:fill-rule"]->getStr().cstr() << "\"";
     344           0 :   m_outputSink << " >\n";
     345           0 : }
     346             : 
     347           0 : void libmspub::MSPUBSVGGenerator::endLayer()
     348             : {
     349           0 :   m_outputSink << "</svg:g>\n";
     350           0 : }
     351             : 
     352           0 : void libmspub::MSPUBSVGGenerator::drawRectangle(const ::WPXPropertyList &propList)
     353             : {
     354           0 :   m_outputSink << "<svg:rect ";
     355           0 :   m_outputSink << "x=\"" << doubleToString(72*propList["svg:x"]->getDouble()) << "\" y=\"" << doubleToString(72*propList["svg:y"]->getDouble()) << "\" ";
     356           0 :   m_outputSink << "width=\"" << doubleToString(72*propList["svg:width"]->getDouble()) << "\" height=\"" << doubleToString(72*propList["svg:height"]->getDouble()) << "\" ";
     357           0 :   if((propList["svg:rx"] && propList["svg:rx"]->getInt() !=0) || (propList["svg:ry"] && propList["svg:ry"]->getInt() !=0))
     358           0 :     m_outputSink << "rx=\"" << doubleToString(72*propList["svg:rx"]->getDouble()) << "\" ry=\"" << doubleToString(72*propList["svg:ry"]->getDouble()) << "\" ";
     359           0 :   writeStyle();
     360           0 :   m_outputSink << "/>\n";
     361           0 : }
     362             : 
     363           0 : void libmspub::MSPUBSVGGenerator::drawEllipse(const WPXPropertyList &propList)
     364             : {
     365           0 :   m_outputSink << "<svg:ellipse ";
     366           0 :   m_outputSink << "cx=\"" << doubleToString(72*propList["svg:cx"]->getDouble()) << "\" cy=\"" << doubleToString(72*propList["svg:cy"]->getDouble()) << "\" ";
     367           0 :   m_outputSink << "rx=\"" << doubleToString(72*propList["svg:rx"]->getDouble()) << "\" ry=\"" << doubleToString(72*propList["svg:ry"]->getDouble()) << "\" ";
     368           0 :   writeStyle();
     369           0 :   if (propList["libwpg:rotate"] && propList["libwpg:rotate"]->getDouble() != 0.0)
     370           0 :     m_outputSink << " transform=\" translate(" << doubleToString(72*propList["svg:cx"]->getDouble()) << ", " << doubleToString(72*propList["svg:cy"]->getDouble())
     371           0 :                  << ") rotate(" << doubleToString(-propList["libwpg:rotate"]->getDouble())
     372           0 :                  << ") translate(" << doubleToString(-72*propList["svg:cx"]->getDouble())
     373           0 :                  << ", " << doubleToString(-72*propList["svg:cy"]->getDouble())
     374           0 :                  << ")\" ";
     375           0 :   m_outputSink << "/>\n";
     376           0 : }
     377             : 
     378           0 : void libmspub::MSPUBSVGGenerator::drawPolyline(const ::WPXPropertyListVector &vertices)
     379             : {
     380           0 :   drawPolySomething(vertices, false);
     381           0 : }
     382             : 
     383           0 : void libmspub::MSPUBSVGGenerator::drawPolygon(const ::WPXPropertyListVector &vertices)
     384             : {
     385           0 :   drawPolySomething(vertices, true);
     386           0 : }
     387             : 
     388           0 : void libmspub::MSPUBSVGGenerator::drawPolySomething(const ::WPXPropertyListVector &vertices, bool isClosed)
     389             : {
     390           0 :   if(vertices.count() < 2)
     391           0 :     return;
     392             : 
     393           0 :   if(vertices.count() == 2)
     394             :   {
     395           0 :     m_outputSink << "<svg:line ";
     396           0 :     m_outputSink << "x1=\"" << doubleToString(72*(vertices[0]["svg:x"]->getDouble())) << "\"  y1=\"" << doubleToString(72*(vertices[0]["svg:y"]->getDouble())) << "\" ";
     397           0 :     m_outputSink << "x2=\"" << doubleToString(72*(vertices[1]["svg:x"]->getDouble())) << "\"  y2=\"" << doubleToString(72*(vertices[1]["svg:y"]->getDouble())) << "\"\n";
     398           0 :     writeStyle();
     399           0 :     m_outputSink << "/>\n";
     400             :   }
     401             :   else
     402             :   {
     403           0 :     if (isClosed)
     404           0 :       m_outputSink << "<svg:polygon ";
     405             :     else
     406           0 :       m_outputSink << "<svg:polyline ";
     407             : 
     408           0 :     m_outputSink << "points=\"";
     409           0 :     for(unsigned i = 0; i < vertices.count(); i++)
     410             :     {
     411           0 :       m_outputSink << doubleToString(72*(vertices[i]["svg:x"]->getDouble())) << " " << doubleToString(72*(vertices[i]["svg:y"]->getDouble()));
     412           0 :       if (i < vertices.count()-1)
     413           0 :         m_outputSink << ", ";
     414             :     }
     415           0 :     m_outputSink << "\"\n";
     416           0 :     writeStyle(isClosed);
     417           0 :     m_outputSink << "/>\n";
     418             :   }
     419             : }
     420             : 
     421           0 : void libmspub::MSPUBSVGGenerator::drawPath(const ::WPXPropertyListVector &path)
     422             : {
     423           0 :   m_outputSink << "<svg:path d=\" ";
     424           0 :   bool isClosed = false;
     425           0 :   unsigned i=0;
     426           0 :   for(i=0; i < path.count(); i++)
     427             :   {
     428           0 :     WPXPropertyList propList = path[i];
     429           0 :     if (propList["libwpg:path-action"] && propList["libwpg:path-action"]->getStr() == "M")
     430             :     {
     431           0 :       m_outputSink << "\nM";
     432           0 :       m_outputSink << doubleToString(72*(propList["svg:x"]->getDouble())) << "," << doubleToString(72*(propList["svg:y"]->getDouble()));
     433             :     }
     434           0 :     else if (propList["libwpg:path-action"] && propList["libwpg:path-action"]->getStr() == "L")
     435             :     {
     436           0 :       m_outputSink << "\nL";
     437           0 :       m_outputSink << doubleToString(72*(propList["svg:x"]->getDouble())) << "," << doubleToString(72*(propList["svg:y"]->getDouble()));
     438             :     }
     439           0 :     else if (propList["libwpg:path-action"] && propList["libwpg:path-action"]->getStr() == "C")
     440             :     {
     441           0 :       m_outputSink << "\nC";
     442           0 :       m_outputSink << doubleToString(72*(propList["svg:x1"]->getDouble())) << "," << doubleToString(72*(propList["svg:y1"]->getDouble())) << " ";
     443           0 :       m_outputSink << doubleToString(72*(propList["svg:x2"]->getDouble())) << "," << doubleToString(72*(propList["svg:y2"]->getDouble())) << " ";
     444           0 :       m_outputSink << doubleToString(72*(propList["svg:x"]->getDouble())) << "," << doubleToString(72*(propList["svg:y"]->getDouble()));
     445             :     }
     446           0 :     else if (propList["libwpg:path-action"] && propList["libwpg:path-action"]->getStr() == "Q")
     447             :     {
     448           0 :       m_outputSink << "\nQ";
     449           0 :       m_outputSink << doubleToString(72*(propList["svg:x1"]->getDouble())) << "," << doubleToString(72*(propList["svg:y1"]->getDouble())) << " ";
     450           0 :       m_outputSink << doubleToString(72*(propList["svg:x"]->getDouble())) << "," << doubleToString(72*(propList["svg:y"]->getDouble()));
     451             :     }
     452           0 :     else if (propList["libwpg:path-action"] && propList["libwpg:path-action"]->getStr() == "A")
     453             :     {
     454           0 :       m_outputSink << "\nA";
     455           0 :       m_outputSink << doubleToString(72*(propList["svg:rx"]->getDouble())) << "," << doubleToString(72*(propList["svg:ry"]->getDouble())) << " ";
     456           0 :       m_outputSink << doubleToString(propList["libwpg:rotate"] ? propList["libwpg:rotate"]->getDouble() : 0) << " ";
     457           0 :       m_outputSink << (propList["libwpg:large-arc"] ? propList["libwpg:large-arc"]->getInt() : 1) << ",";
     458           0 :       m_outputSink << (propList["libwpg:sweep"] ? propList["libwpg:sweep"]->getInt() : 1) << " ";
     459           0 :       m_outputSink << doubleToString(72*(propList["svg:x"]->getDouble())) << "," << doubleToString(72*(propList["svg:y"]->getDouble()));
     460             :     }
     461           0 :     else if ((i >= path.count()-1 && i > 2) && propList["libwpg:path-action"] && propList["libwpg:path-action"]->getStr() == "Z" )
     462             :     {
     463           0 :       isClosed = true;
     464           0 :       m_outputSink << "\nZ";
     465             :     }
     466           0 :   }
     467             : 
     468           0 :   m_outputSink << "\" \n";
     469           0 :   writeStyle(isClosed);
     470           0 :   m_outputSink << "/>\n";
     471           0 : }
     472             : 
     473           0 : void libmspub::MSPUBSVGGenerator::drawGraphicObject(const ::WPXPropertyList &propList, const ::WPXBinaryData &binaryData)
     474             : {
     475           0 :   if (!propList["libwpg:mime-type"] || propList["libwpg:mime-type"]->getStr().len() <= 0)
     476           0 :     return;
     477           0 :   WPXString base64 = binaryData.getBase64Data();
     478           0 :   m_outputSink << "<svg:image ";
     479           0 :   if (propList["svg:x"] && propList["svg:y"] && propList["svg:width"] && propList["svg:height"])
     480             :   {
     481           0 :     m_outputSink << "x=\"" << doubleToString(72*(propList["svg:x"]->getDouble())) << "\" y=\"" << doubleToString(72*(propList["svg:y"]->getDouble())) << "\" ";
     482           0 :     m_outputSink << "width=\"" << doubleToString(72*(propList["svg:width"]->getDouble())) << "\" height=\"" << doubleToString(72*(propList["svg:height"]->getDouble())) << "\" ";
     483             :   }
     484           0 :   m_outputSink << "xlink:href=\"data:" << propList["libwpg:mime-type"]->getStr().cstr() << ";base64,";
     485           0 :   m_outputSink << base64.cstr();
     486           0 :   m_outputSink << "\" />\n";
     487             : }
     488             : 
     489           0 : void libmspub::MSPUBSVGGenerator::startTextObject(const ::WPXPropertyList &propList, const ::WPXPropertyListVector & /* path */)
     490             : {
     491           0 :   m_outputSink << "<svg:text ";
     492           0 :   if (propList["svg:x"] && propList["svg:y"])
     493           0 :     m_outputSink << "x=\"" << doubleToString(72*(propList["svg:x"]->getDouble())) << "\" y=\"" << doubleToString(72*(propList["svg:y"]->getDouble())) << "\"";
     494           0 :   if (propList["libwpg:rotate"] && propList["libwpg:rotate"]->getDouble() != 0.0)
     495           0 :     m_outputSink << " transform=\"translate(" << doubleToString(72*propList["svg:x"]->getDouble()) << ", " << doubleToString(72*propList["svg:y"]->getDouble())
     496           0 :                  << ") rotate(" << doubleToString(-propList["libwpg:rotate"]->getDouble())
     497           0 :                  << ") translate(" << doubleToString(-72*propList["svg:x"]->getDouble())
     498           0 :                  << ", " << doubleToString(-72*propList["svg:y"]->getDouble())
     499           0 :                  << ")\"";
     500           0 :   m_outputSink << ">\n";
     501             : 
     502           0 : }
     503             : 
     504           0 : void libmspub::MSPUBSVGGenerator::endTextObject()
     505             : {
     506           0 :   m_outputSink << "</svg:text>\n";
     507           0 : }
     508             : 
     509           0 : void libmspub::MSPUBSVGGenerator::startTextSpan(const ::WPXPropertyList &propList)
     510             : {
     511           0 :   m_outputSink << "<svg:tspan ";
     512           0 :   if (propList["style:font-name"])
     513           0 :     m_outputSink << "font-family=\"" << propList["style:font-name"]->getStr().cstr() << "\" ";
     514           0 :   if (propList["fo:font-style"])
     515           0 :     m_outputSink << "font-style=\"" << propList["fo:font-style"]->getStr().cstr() << "\" ";
     516           0 :   if (propList["fo:font-weight"])
     517           0 :     m_outputSink << "font-weight=\"" << propList["fo:font-weight"]->getStr().cstr() << "\" ";
     518           0 :   if (propList["fo:font-variant"])
     519           0 :     m_outputSink << "font-variant=\"" << propList["fo:font-variant"]->getStr().cstr() << "\" ";
     520           0 :   if (propList["fo:font-size"])
     521           0 :     m_outputSink << "font-size=\"" << doubleToString(propList["fo:font-size"]->getDouble()) << "\" ";
     522           0 :   if (propList["fo:color"])
     523           0 :     m_outputSink << "fill=\"" << propList["fo:color"]->getStr().cstr() << "\" ";
     524           0 :   if (propList["fo:text-transform"])
     525           0 :     m_outputSink << "text-transform=\"" << propList["fo:text-transform"]->getStr().cstr() << "\" ";
     526           0 :   if (propList["svg:fill-opacity"])
     527           0 :     m_outputSink << "fill-opacity=\"" << doubleToString(propList["svg:fill-opacity"]->getDouble()) << "\" ";
     528           0 :   if (propList["svg:stroke-opacity"])
     529           0 :     m_outputSink << "stroke-opacity=\"" << doubleToString(propList["svg:stroke-opacity"]->getDouble()) << "\" ";
     530           0 :   m_outputSink << ">\n";
     531           0 : }
     532             : 
     533           0 : void libmspub::MSPUBSVGGenerator::endTextSpan()
     534             : {
     535           0 :   m_outputSink << "</svg:tspan>\n";
     536           0 : }
     537             : 
     538           0 : void libmspub::MSPUBSVGGenerator::insertText(const ::WPXString &str)
     539             : {
     540           0 :   WPXString tempUTF8(str, true);
     541           0 :   m_outputSink << tempUTF8.cstr() << "\n";
     542           0 : }
     543             : 
     544             : // create "style" attribute based on current pen and brush
     545           0 : void libmspub::MSPUBSVGGenerator::writeStyle(bool /* isClosed */)
     546             : {
     547           0 :   m_outputSink << "style=\"";
     548             : 
     549           0 :   if (m_style["svg:stroke-width"])
     550             :   {
     551           0 :     double width = m_style["svg:stroke-width"]->getDouble();
     552           0 :     if (width == 0.0 && m_style["draw:stroke"] && m_style["draw:stroke"]->getStr() != "none")
     553           0 :       width = 0.2 / 72.0; // reasonable hairline
     554           0 :     m_outputSink << "stroke-width: " << doubleToString(72*width) << "; ";
     555             :   }
     556           0 :   if ((m_style["draw:stroke"] && m_style["draw:stroke"]->getStr() != "none"))
     557             :   {
     558           0 :     if (m_style["svg:stroke-color"])
     559           0 :       m_outputSink << "stroke: " << m_style["svg:stroke-color"]->getStr().cstr()  << "; ";
     560           0 :     if(m_style["svg:stroke-opacity"] &&  m_style["svg:stroke-opacity"]->getInt()!= 1)
     561           0 :       m_outputSink << "stroke-opacity: " << doubleToString(m_style["svg:stroke-opacity"]->getDouble()) << "; ";
     562             :   }
     563             : 
     564           0 :   if (m_style["draw:stroke"] && m_style["draw:stroke"]->getStr() == "solid")
     565           0 :     m_outputSink << "stroke-dasharray:  solid; ";
     566           0 :   else if (m_style["draw:stroke"] && m_style["draw:stroke"]->getStr() == "dash")
     567             :   {
     568           0 :     int dots1 = m_style["draw:dots1"]->getInt();
     569           0 :     int dots2 = m_style["draw:dots2"]->getInt();
     570           0 :     double dots1len = m_style["draw:dots1-length"]->getDouble();
     571           0 :     double dots2len = m_style["draw:dots2-length"]->getDouble();
     572           0 :     double gap = m_style["draw:distance"]->getDouble();
     573           0 :     m_outputSink << "stroke-dasharray: ";
     574           0 :     for (int i = 0; i < dots1; i++)
     575             :     {
     576           0 :       if (i)
     577           0 :         m_outputSink << ", ";
     578           0 :       m_outputSink << (int)dots1len;
     579           0 :       m_outputSink << ", ";
     580           0 :       m_outputSink << (int)gap;
     581             :     }
     582           0 :     for (int j = 0; j < dots2; j++)
     583             :     {
     584           0 :       m_outputSink << ", ";
     585           0 :       m_outputSink << (int)dots2len;
     586           0 :       m_outputSink << ", ";
     587           0 :       m_outputSink << (int)gap;
     588             :     }
     589           0 :     m_outputSink << "; ";
     590             :   }
     591             : 
     592           0 :   if (m_style["svg:stroke-linecap"])
     593           0 :     m_outputSink << "stroke-linecap: " << m_style["svg:stroke-linecap"]->getStr().cstr() << "; ";
     594             : 
     595           0 :   if (m_style["svg:stroke-linejoin"])
     596           0 :     m_outputSink << "stroke-linejoin: " << m_style["svg:stroke-linejoin"]->getStr().cstr() << "; ";
     597             : 
     598           0 :   if(m_style["draw:fill"] && m_style["draw:fill"]->getStr() == "none")
     599           0 :     m_outputSink << "fill: none; ";
     600           0 :   else if(m_style["svg:fill-rule"])
     601           0 :     m_outputSink << "fill-rule: " << m_style["svg:fill-rule"]->getStr().cstr() << "; ";
     602             : 
     603           0 :   if(m_style["draw:fill"] && m_style["draw:fill"]->getStr() == "gradient")
     604           0 :     m_outputSink << "fill: url(#grad" << m_gradientIndex-1 << "); ";
     605             : 
     606           0 :   if(m_style["draw:fill"] && m_style["draw:fill"]->getStr() == "bitmap")
     607           0 :     m_outputSink << "fill: url(#img" << m_patternIndex-1 << "); ";
     608             : 
     609           0 :   if(m_style["draw:shadow"] && m_style["draw:shadow"]->getStr() == "visible")
     610           0 :     m_outputSink << "filter:url(#shadow" << m_shadowIndex-1 << "); ";
     611             : 
     612           0 :   if(m_style["draw:fill"] && m_style["draw:fill"]->getStr() == "solid")
     613           0 :     if (m_style["draw:fill-color"])
     614           0 :       m_outputSink << "fill: " << m_style["draw:fill-color"]->getStr().cstr() << "; ";
     615           0 :   if(m_style["draw:opacity"] && m_style["draw:opacity"]->getDouble() < 1)
     616           0 :     m_outputSink << "fill-opacity: " << doubleToString(m_style["draw:opacity"]->getDouble()) << "; ";
     617           0 :   m_outputSink << "\""; // style
     618           0 : }
     619             : /* vim:set shiftwidth=2 softtabstop=2 expandtab: */

Generated by: LCOV version 1.10