[ooo-build-commit] .: 9 commits - filter/source

Fridrich Strba fridrich at kemper.freedesktop.org
Tue Sep 14 01:06:05 PDT 2010


 filter/source/config/fragments/fcfg_drawgraphics.mk                       |    1 
 filter/source/config/fragments/fcfg_internalgraphics.mk                   |    1 
 filter/source/config/fragments/filters/SVG___Scalable_Vector_Graphics.xcu |   13 
 filter/source/config/fragments/internalgraphicfilters/svg_Import.xcu      |   10 
 filter/source/config/fragments/types/svg_Scalable_Vector_Graphics.xcu     |    6 
 filter/source/svg/b2dellipse.cxx                                          |  139 
 filter/source/svg/b2dellipse.hxx                                          |   77 
 filter/source/svg/exports.map                                             |   10 
 filter/source/svg/gentoken.pl                                             |   58 
 filter/source/svg/gfxtypes.hxx                                            |  345 +
 filter/source/svg/makefile.mk                                             |   55 
 filter/source/svg/parserfragments.cxx                                     |  600 ++
 filter/source/svg/parserfragments.hxx                                     |   74 
 filter/source/svg/spirit_supplements.hxx                                  |  115 
 filter/source/svg/svgfilter.cxx                                           |  112 
 filter/source/svg/svgfilter.hxx                                           |   46 
 filter/source/svg/svgimport.cxx                                           |  191 
 filter/source/svg/svgreader.cxx                                           | 2778 ++++++++++
 filter/source/svg/svgreader.hxx                                           |   43 
 filter/source/svg/test/makefile.mk                                        |  115 
 filter/source/svg/test/odfserializer.cxx                                  |  140 
 filter/source/svg/test/odfserializer.hxx                                  |   31 
 filter/source/svg/test/parsertest.cxx                                     |  209 
 filter/source/svg/test/svg2odf.cxx                                        |  124 
 filter/source/svg/tokenmap.cxx                                            |   62 
 filter/source/svg/tokenmap.hxx                                            |   32 
 filter/source/svg/tokens.txt                                              |  403 +
 filter/source/svg/units.cxx                                               |  116 
 filter/source/svg/units.hxx                                               |   60 
 29 files changed, 5715 insertions(+), 251 deletions(-)

New commits:
commit 7d1ef3204f28dd1222cde8acf64d7c948a2fbc3a
Author: Thorsten Behrens <tbehrens at novell.com>
Date:   Tue Sep 14 09:58:36 2010 +0200

    svg-import-empty-gradient-fix.diff: guard against empty gradient stops
    
    n#560255

diff --git a/filter/source/svg/svgreader.cxx b/filter/source/svg/svgreader.cxx
index 21f6f19..6097607 100644
--- a/filter/source/svg/svgreader.cxx
+++ b/filter/source/svg/svgreader.cxx
@@ -308,10 +308,11 @@ struct AnnotatingVisitor
     bool hasGradientOpacity( const Gradient& rGradient )
     {
         return
-            maGradientStopVector[
-                rGradient.maStops[0]].maStopColor.a != 1.0 ||
-            maGradientStopVector[
-                rGradient.maStops[1]].maStopColor.a != 1.0;
+            !rGradient.maStops.empty() &&
+            (maGradientStopVector[
+                 rGradient.maStops[0]].maStopColor.a != 1.0 ||
+             maGradientStopVector[
+                 rGradient.maStops[1]].maStopColor.a != 1.0);
     }
 
     struct StopSorter
@@ -2464,10 +2465,11 @@ struct ShapeRenderingVisitor
     bool hasGradientOpacity( const Gradient& rGradient )
     {
         return
-            mrGradientStopVector[
-                rGradient.maStops[0]].maStopColor.a != 1.0 ||
-            mrGradientStopVector[
-                rGradient.maStops[1]].maStopColor.a != 1.0;
+            !rGradient.maStops.empty() &&
+            (mrGradientStopVector[
+                 rGradient.maStops[0]].maStopColor.a != 1.0 ||
+             mrGradientStopVector[
+                 rGradient.maStops[1]].maStopColor.a != 1.0);
     }
 
     sal_Int8 toByteColor( double val )
commit e7ebe0078a17e47b701781657d63dfaf687d33a3
Author: Thorsten Behrens <tbehrens at novell.com>
Date:   Tue Sep 14 09:57:31 2010 +0200

    svg-import-opacity-fix.diff: fixing handling of opacity attribute

diff --git a/filter/source/svg/gfxtypes.hxx b/filter/source/svg/gfxtypes.hxx
index d247b69..fc52b22 100644
--- a/filter/source/svg/gfxtypes.hxx
+++ b/filter/source/svg/gfxtypes.hxx
@@ -174,6 +174,7 @@ struct State
         mbVisibility(true),
         meFillType(SOLID),
         mnFillOpacity(1.0),
+        mnOpacity(1.0),
         meStrokeType(NONE),
         mnStrokeOpacity(1.0),
         meViewportFillType(NONE),
@@ -220,6 +221,7 @@ struct State
 
     PaintType                   meFillType;
     double                      mnFillOpacity;
+    double                      mnOpacity;
     PaintType                   meStrokeType;
     double                      mnStrokeOpacity;
     PaintType                   meViewportFillType;
diff --git a/filter/source/svg/svgreader.cxx b/filter/source/svg/svgreader.cxx
index 46ed6a8..21f6f19 100644
--- a/filter/source/svg/svgreader.cxx
+++ b/filter/source/svg/svgreader.cxx
@@ -519,12 +519,12 @@ struct AnnotatingVisitor
                                       rtl::OUString::valueOf(
                                           maGradientStopVector[
                                               rState.maFillGradient.maStops[0]].maStopColor.a*
-                                          maCurrState.mnFillOpacity*100.0)+USTR("%" ) );
+                                          maCurrState.mnFillOpacity*maCurrState.mnOpacity*100.0)+USTR("%" ) );
                 xAttrs->AddAttribute( USTR( "draw:start" ),
                                       rtl::OUString::valueOf(
                                           maGradientStopVector[
                                               rState.maFillGradient.maStops[1]].maStopColor.a*
-                                          maCurrState.mnFillOpacity*100.0)+USTR("%" ) );
+                                          maCurrState.mnFillOpacity*maCurrState.mnOpacity*100.0)+USTR("%" ) );
                 xAttrs->AddAttribute( USTR( "draw:border" ), USTR("0%") );
                 mxDocumentHandler->startElement( USTR("draw:opacity"),
                                                  xUnoAttrs );
@@ -616,17 +616,17 @@ struct AnnotatingVisitor
                         xAttrs->AddAttribute( USTR( "draw:opacity-name" ),
                                               getStyleName("svgopacity", rState.maFillGradient.mnId) );
                     }
-                    else if( maCurrState.mnFillOpacity != 1.0 )
+                    else if( maCurrState.mnFillOpacity*maCurrState.mnOpacity != 1.0 )
                         xAttrs->AddAttribute( USTR( "draw:opacity" ),
-                                              rtl::OUString::valueOf(100.0*maCurrState.mnFillOpacity)+USTR("%") );
+                                              rtl::OUString::valueOf(100.0*maCurrState.mnFillOpacity*maCurrState.mnOpacity)+USTR("%") );
                 }
                 else
                 {
                     xAttrs->AddAttribute( USTR( "draw:fill" ), USTR("solid"));
                     xAttrs->AddAttribute( USTR( "draw:fill-color" ), getOdfColor(rState.maFillColor));
-                    if( maCurrState.mnFillOpacity != 1.0 )
+                    if( maCurrState.mnFillOpacity*maCurrState.mnOpacity != 1.0 )
                         xAttrs->AddAttribute( USTR( "draw:opacity" ),
-                                              rtl::OUString::valueOf(100.0*maCurrState.mnFillOpacity)+USTR("%") );
+                                              rtl::OUString::valueOf(100.0*maCurrState.mnFillOpacity*maCurrState.mnOpacity)+USTR("%") );
                 }
             }
             else
@@ -652,9 +652,9 @@ struct AnnotatingVisitor
                 xAttrs->AddAttribute( USTR( "draw:stroke-linejoin"), USTR("round"));
             else if( maCurrState.meLineJoin == basegfx::B2DLINEJOIN_BEVEL )
                 xAttrs->AddAttribute( USTR( "draw:stroke-linejoin"), USTR("bevel"));
-            if( maCurrState.mnStrokeOpacity != 1.0 )
+            if( maCurrState.mnStrokeOpacity*maCurrState.mnOpacity != 1.0 )
                 xAttrs->AddAttribute( USTR("svg:stroke-opacity"),
-                                      rtl::OUString::valueOf(100.0*maCurrState.mnStrokeOpacity)+USTR("%"));
+                                      rtl::OUString::valueOf(100.0*maCurrState.mnStrokeOpacity*maCurrState.mnOpacity)+USTR("%"));
         }
 
         mxDocumentHandler->startElement( USTR("style:graphic-properties"),
@@ -876,6 +876,12 @@ struct AnnotatingVisitor
                     maCurrState.meFillRule = maParentStates.back().meFillRule;
                 break;
             }
+            case XML_OPACITY:
+                if( aValueUtf8 == "inherit" )
+                    maCurrState.mnOpacity = maParentStates.back().mnOpacity;
+                else
+                    maCurrState.mnOpacity = aValueUtf8.toDouble();
+                break;
             case XML_FILL_OPACITY:
                 if( aValueUtf8 == "inherit" )
                     maCurrState.mnFillOpacity = maParentStates.back().mnFillOpacity;
@@ -2540,13 +2546,13 @@ struct ShapeRenderingVisitor
                 const BYTE	cTransStart( 255-
                     basegfx::fround(mrGradientStopVector[
                                         aState.maFillGradient.maStops[1]].maStopColor.a*
-                                    aState.mnFillOpacity*255.0));
+                                    aState.mnFillOpacity*maCurrState.mnOpacity*255.0));
                 const Color aTransStart( cTransStart, cTransStart, cTransStart );
 
                 const BYTE	cTransEnd( 255-
                     basegfx::fround(mrGradientStopVector[
                                         aState.maFillGradient.maStops[0]].maStopColor.a*
-                                    aState.mnFillOpacity*255.0));
+                                    aState.mnFillOpacity*maCurrState.mnOpacity*255.0));
                 const Color aTransEnd( cTransEnd, cTransEnd, cTransEnd );
 
                 // modulate gradient opacity with overall fill opacity
@@ -2594,10 +2600,10 @@ struct ShapeRenderingVisitor
             else
                 mrOutDev.SetFillColor(getVclColor(aState.maFillColor));
 
-            if( aState.mnFillOpacity != 1.0 )
+            if( aState.mnFillOpacity*maCurrState.mnOpacity != 1.0 )
                 mrOutDev.DrawTransparent(::PolyPolygon(aPoly),
                                          basegfx::fround(
-                                             (1.0-aState.mnFillOpacity)*100.0));
+                                             (1.0-(aState.mnFillOpacity*maCurrState.mnOpacity))*100.0));
             else
                 mrOutDev.DrawPolyPolygon(::PolyPolygon(aPoly));
         }
@@ -2652,10 +2658,10 @@ struct ShapeRenderingVisitor
 
             for( sal_uInt32 i=0; i<aPolys.size(); ++i )
             {
-                if( aState.mnStrokeOpacity != 1.0 )
+                if( aState.mnStrokeOpacity*maCurrState.mnOpacity != 1.0 )
                     mrOutDev.DrawTransparent(::PolyPolygon(aPolys[i]),
                                              basegfx::fround(
-                                                 (1.0-aState.mnStrokeOpacity)*100.0));
+                                                 (1.0-(aState.mnStrokeOpacity*maCurrState.mnOpacity))*100.0));
                 else
                     mrOutDev.DrawPolyPolygon(::PolyPolygon(aPolys[i]));
 
@@ -2675,10 +2681,10 @@ struct ShapeRenderingVisitor
             else
                 mrOutDev.SetLineColor(getVclColor(aState.maStrokeColor));
 
-            if( aState.mnStrokeOpacity != 1.0 )
+            if( aState.mnStrokeOpacity*maCurrState.mnOpacity != 1.0 )
                 mrOutDev.DrawTransparent(::PolyPolygon(aPoly),
                                          basegfx::fround(
-                                             (1.0-aState.mnStrokeOpacity)*100.0));
+                                             (1.0-(aState.mnStrokeOpacity*maCurrState.mnOpacity))*100.0));
             else
                 mrOutDev.DrawPolyPolygon(::PolyPolygon(aPoly));
         }
commit a50c1d659fcf774493d2f0408474da2717ad4815
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Tue Sep 14 09:56:06 2010 +0200

    svg-import-eh-fix.diff: eat exceptions before they reach unaware code

diff --git a/filter/source/svg/svgfilter.cxx b/filter/source/svg/svgfilter.cxx
index 1975c0a..248a92f 100644
--- a/filter/source/svg/svgfilter.cxx
+++ b/filter/source/svg/svgfilter.cxx
@@ -208,7 +208,14 @@ rtl::OUString SAL_CALL SVGFilter::detect( Sequence< PropertyValue >& io_rDescrip
 class FilterConfigItem;
 extern "C" SAL_DLLPUBLIC_EXPORT BOOL __LOADONCALLAPI GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem*, BOOL )
 {
-    return importSvg( rStream, rGraphic );
+    BOOL bRet = FALSE;
+    try
+    {
+        bRet = importSvg( rStream, rGraphic );
+    }
+    catch (const uno::Exception&) {
+    }
+    return bRet;
 }
 
 // -----------------------------------------------------------------------------
diff --git a/filter/source/svg/svgreader.cxx b/filter/source/svg/svgreader.cxx
index 4136a21..46ed6a8 100644
--- a/filter/source/svg/svgreader.cxx
+++ b/filter/source/svg/svgreader.cxx
@@ -1796,7 +1796,7 @@ sal_Bool SVGReader::parseAndConvert()
 {
     uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder(
         m_xServiceFactory->createInstance(
-            rtl::OUString::createFromAscii("com.sun.star.xml.dom.DocumentBuilder")), uno::UNO_QUERY );
+            rtl::OUString::createFromAscii("com.sun.star.xml.dom.DocumentBuilder")), uno::UNO_QUERY_THROW );
 
     uno::Reference<xml::dom::XDocument> xDom(
         xDomBuilder->parse(m_xInputStream),
@@ -2702,7 +2702,7 @@ bool importSvg(SvStream & rStream, Graphic & rGraphic )
     uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder(
         xServiceFactory->createInstance(
             rtl::OUString::createFromAscii("com.sun.star.xml.dom.DocumentBuilder")),
-        uno::UNO_QUERY );
+        uno::UNO_QUERY_THROW );
 
     uno::Reference<io::XInputStream> xStream(
         new utl::OInputStreamWrapper(rStream) );
commit 27913e127acb3f5ab8447dee6d458a4f430192e9
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Tue Sep 14 09:54:19 2010 +0200

    svg-import-convlength-fix.diff: fixing relative size calculation

diff --git a/filter/source/svg/units.cxx b/filter/source/svg/units.cxx
index b727a42..9c98cac 100644
--- a/filter/source/svg/units.cxx
+++ b/filter/source/svg/units.cxx
@@ -35,10 +35,6 @@ namespace svgi
 
 double convLength( double value, SvgUnit unit, const State& rState, char dir )
 {
-    const double fBoxLen( dir=='h' ? rState.maViewBox.getWidth() :
-                          (dir=='v' ? rState.maViewBox.getHeight() :
-                           rState.maViewBox.getRange().getLength()));
-
     // convert svg unit to internal coordinates ("pixel"). Since the
     // OOo drawing layer is still largely integer-based, the initial
     // viewport transformation includes a certain scale factor
@@ -55,7 +51,28 @@ double convLength( double value, SvgUnit unit, const State& rState, char dir )
         case SVG_LENGTH_UNIT_PT: break;
         case SVG_LENGTH_UNIT_EM: fRet *= rState.mnFontSize; break;
         case SVG_LENGTH_UNIT_EX: fRet *= rState.mnFontSize / 2.0; break;
-        case SVG_LENGTH_UNIT_PERCENTAGE: fRet *= fBoxLen; break;
+        case SVG_LENGTH_UNIT_PERCENTAGE:
+        {
+            double fBoxLen;
+            if (rState.maViewBox.isEmpty())
+            {
+                basegfx::B2DRange aDefaultBox(0, 0,
+                  convLength(210, SVG_LENGTH_UNIT_MM, rState, 'h'),
+                  convLength(297, SVG_LENGTH_UNIT_MM, rState, 'v'));
+                fBoxLen = (dir=='h' ? aDefaultBox.getWidth() :
+                          (dir=='v' ? aDefaultBox.getHeight() :
+                           aDefaultBox.getRange().getLength()));
+            }
+            else
+            {
+                fBoxLen = (dir=='h' ? rState.maViewBox.getWidth() :
+                          (dir=='v' ? rState.maViewBox.getHeight() :
+                           rState.maViewBox.getRange().getLength()));
+            }
+
+            fRet *= fBoxLen/100.0;
+        }
+        break;
         default: OSL_TRACE( "Unknown length type" ); break;
     }
 
commit 7aa4106187316461ea8e986343c5c9995c45a297
Author: Thorsten Behrens <tbehrens at novell.com>
Date:   Tue Sep 14 09:51:31 2010 +0200

    svg-import-textimport.diff: much improved text import

diff --git a/filter/source/svg/gfxtypes.hxx b/filter/source/svg/gfxtypes.hxx
index 3675e30..d247b69 100644
--- a/filter/source/svg/gfxtypes.hxx
+++ b/filter/source/svg/gfxtypes.hxx
@@ -155,19 +155,6 @@ enum CapStyle
     ROUND
 };
 
-enum FontStyle
-{
-    STYLE_NORMAL,
-    STYLE_OBLIQUE,
-    STYLE_ITALIC
-};
-
-enum FontVariant
-{
-    VARIANT_NORMAL,
-    VARIANT_SMALLCAPS
-};
-
 struct State
 {
     State() :
@@ -177,8 +164,8 @@ struct State
         maViewBox(),
         maFontFamily(), // app-default
         mnFontSize(12.0),
-        meFontStyle(STYLE_NORMAL),
-        meFontVariant(VARIANT_NORMAL),
+        maFontStyle(RTL_CONSTASCII_USTRINGPARAM("normal")),
+        maFontVariant(RTL_CONSTASCII_USTRINGPARAM("normal")),
         mnFontWeight(400.0),
         meTextAnchor(BEFORE),
         meTextDisplayAlign(BEFORE),
@@ -220,8 +207,8 @@ struct State
 
      */
     double                      mnFontSize;
-    FontStyle                   meFontStyle;
-    FontVariant                 meFontVariant;
+    rtl::OUString               maFontStyle;
+    rtl::OUString               maFontVariant;
     double                      mnFontWeight;
 
     TextAlign                   meTextAnchor; // text-anchor
@@ -265,8 +252,8 @@ inline bool operator==(const State& rLHS, const State& rRHS )
         rLHS.maViewBox==rRHS.maViewBox &&
         rLHS.maFontFamily==rRHS.maFontFamily &&
         rLHS.mnFontSize==rRHS.mnFontSize &&
-        rLHS.meFontStyle==rRHS.meFontStyle &&
-        rLHS.meFontVariant==rRHS.meFontVariant &&
+        rLHS.maFontStyle==rRHS.maFontStyle &&
+        rLHS.maFontVariant==rRHS.maFontVariant &&
         rLHS.mnFontWeight==rRHS.mnFontWeight &&
         rLHS.meTextAnchor==rRHS.meTextAnchor &&
         rLHS.meTextDisplayAlign==rRHS.meTextDisplayAlign &&
@@ -310,8 +297,8 @@ struct StateHash
             ^  size_t(rState.maViewBox.getHeight())
             ^  size_t(rState.maFontFamily.hashCode())
             ^  size_t(rState.mnFontSize)
-            ^  size_t(rState.meFontStyle)
-            ^  size_t(rState.meFontVariant)
+            ^  size_t(rState.maFontStyle.hashCode())
+            ^  size_t(rState.maFontVariant.hashCode())
             ^  size_t(rState.mnFontWeight)
             ^  size_t(rState.meTextAnchor)
             ^  size_t(rState.meTextDisplayAlign)
diff --git a/filter/source/svg/svgreader.cxx b/filter/source/svg/svgreader.cxx
index 8913300..4136a21 100644
--- a/filter/source/svg/svgreader.cxx
+++ b/filter/source/svg/svgreader.cxx
@@ -415,6 +415,24 @@ struct AnnotatingVisitor
         return aBuf.makeStringAndClear();
     }
 
+    rtl::OUString getOdfAlign( TextAlign eAlign )
+    {
+        static ::rtl::OUString aStart(USTR("start"));
+        static ::rtl::OUString aEnd(USTR("end"));
+        // static ::rtl::OUString aJustify(USTR("justify"));
+        static ::rtl::OUString aCenter(USTR("center"));
+        switch(eAlign)
+        {
+            default:
+            case BEFORE:
+                return aStart;
+            case CENTER:
+                return aCenter;
+            case AFTER:
+                return aEnd;
+        }
+    }
+
     bool writeStyle(State& rState, const sal_Int32 nTagId)
     {
         rtl::Reference<SvXMLAttributeList> xAttrs( new SvXMLAttributeList() );
@@ -443,7 +461,7 @@ struct AnnotatingVisitor
         // do we have a gradient fill? then write out gradient as well
         if( rState.meFillType == GRADIENT && rState.maFillGradient.maStops.size() > 1 )
         {
-            // TODO(F3): ODF12 supposedly also groks svg:linear/radialGradient
+            // TODO(F3): ODF12 supposedly also groks svg:linear/radialGradient. But CL says: nope.
             xAttrs->AddAttribute( USTR( "draw:name" ), getStyleName("svggradient", rState.maFillGradient.mnId) );
             if( rState.maFillGradient.meType == Gradient::LINEAR )
             {
@@ -515,6 +533,47 @@ struct AnnotatingVisitor
         }
 
         // serialize to automatic-style section
+        if( nTagId == XML_TEXT )
+        {
+            // write paragraph style attributes
+            xAttrs->Clear();
+
+            xAttrs->AddAttribute( USTR( "style:name" ), getStyleName("svgparagraphstyle", mnCurrStateId) );
+            xAttrs->AddAttribute( USTR( "style:family" ), USTR("paragraph") );
+            mxDocumentHandler->startElement( USTR("style:style"),
+                                             xUnoAttrs );
+
+            xAttrs->Clear();
+            xAttrs->AddAttribute( USTR( "fo:text-align"), getOdfAlign(rState.meTextAnchor));
+
+            mxDocumentHandler->startElement( USTR("style:paragraph-properties"),
+                                             xUnoAttrs );
+            mxDocumentHandler->endElement( USTR("style:paragraph-properties") );
+            mxDocumentHandler->endElement( USTR("style:style") );
+
+            // write text style attributes
+            xAttrs->Clear();
+
+            xAttrs->AddAttribute( USTR( "style:name" ), getStyleName("svgtextstyle", mnCurrStateId) );
+            xAttrs->AddAttribute( USTR( "style:family" ), USTR("text") );
+            mxDocumentHandler->startElement( USTR("style:style"),
+                                             xUnoAttrs );
+            xAttrs->Clear();
+            xAttrs->AddAttribute( USTR( "fo:font-family"), rState.maFontFamily);
+            xAttrs->AddAttribute( USTR( "fo:font-size"),
+                                  rtl::OUString::valueOf(pt2mm(rState.mnFontSize))+USTR("mm"));
+            xAttrs->AddAttribute( USTR( "fo:font-style"), rState.maFontStyle);
+            xAttrs->AddAttribute( USTR( "fo:font-variant"), rState.maFontVariant);
+            xAttrs->AddAttribute( USTR( "fo:font-weight"),
+                                  rtl::OUString::valueOf(rState.mnFontWeight));
+            xAttrs->AddAttribute( USTR( "fo:color"), getOdfColor(rState.maFillColor));
+
+            mxDocumentHandler->startElement( USTR("style:text-properties"),
+                                             xUnoAttrs );
+            mxDocumentHandler->endElement( USTR("style:text-properties") );
+            mxDocumentHandler->endElement( USTR("style:style") );
+        }
+
         xAttrs->Clear();
         xAttrs->AddAttribute( USTR( "style:name" ), getStyleName("svggraphicstyle", mnCurrStateId) );
         xAttrs->AddAttribute( USTR( "style:family" ), USTR("graphic") );
@@ -928,13 +987,16 @@ struct AnnotatingVisitor
                 maCurrState.mnFontSize=convLength(sValue,maCurrState,'v');
                 break;
             case XML_FONT_STYLE:
-                maCurrState.meFontStyle=STYLE_ITALIC; // TODO: sValue.toStyleId();
+                parseFontStyle(maCurrState,sValue,aValueUtf8.getStr());
                 break;
             case XML_FONT_WEIGHT:
                 maCurrState.mnFontWeight=sValue.toDouble();
                 break;
             case XML_FONT_VARIANT:
-                maCurrState.meFontVariant=VARIANT_SMALLCAPS; // TODO: sValue.toDouble();
+                parseFontVariant(maCurrState,sValue,aValueUtf8.getStr());
+                break;
+            case XML_TEXT_ANCHOR:
+                parseTextAlign(maCurrState,aValueUtf8.getStr());
                 break;
             case XML_STOP_COLOR:
                 if( maGradientVector.empty() ||
@@ -987,6 +1049,34 @@ struct AnnotatingVisitor
         while( nIndex != -1 );
     }
 
+    void parseFontStyle( State&               io_rInitialState,
+                         const rtl::OUString& rValue,
+                         const char*          sValue )
+    {
+        if( strcmp(sValue,"inherit") != 0 )
+            io_rInitialState.maFontStyle = rValue;
+    }
+
+    void parseFontVariant( State&               io_rInitialState,
+                           const rtl::OUString& rValue,
+                           const char*          sValue )
+    {
+        if( strcmp(sValue,"inherit") != 0 )
+            io_rInitialState.maFontVariant = rValue;
+    }
+
+    void parseTextAlign( State&      io_rInitialState,
+                         const char* sValue )
+    {
+        if( strcmp(sValue,"start") == 0 )
+            io_rInitialState.meTextAnchor = BEFORE;
+        else if( strcmp(sValue,"middle") == 0 )
+            io_rInitialState.meTextAnchor = CENTER;
+        else if( strcmp(sValue,"end") == 0 )
+            io_rInitialState.meTextAnchor = AFTER;
+        // keep current val for sValue == "inherit"
+    }
+
     void parsePaint( const rtl::OUString& rValue,
                      const char*      sValue,
                      PaintType&       rType,
@@ -1391,6 +1481,10 @@ struct ShapeWritingVisitor
                 // actually export text
                 xAttrs->Clear();
 
+                // some heuristic attempts to have text output
+                // baseline-relative
+                y -= 2.0*maCurrState.mnFontSize/3.0;
+
                 // extract basic transformations out of CTM
                 basegfx::B2DTuple aScale, aTranslate;
                 double fRotate, fShearX;
@@ -1423,9 +1517,16 @@ struct ShapeWritingVisitor
 
                 xAttrs->Clear();
                 mxDocumentHandler->startElement(USTR("draw:text-box"),xUnoAttrs);
-                // TODO: put text style in here
+                xAttrs->AddAttribute( USTR( "text:style-name" ), USTR("svgparagraphstyle")+sStyleId);
                 mxDocumentHandler->startElement(USTR("text:p"),xUnoAttrs);
+
+                xAttrs->Clear();
+                xAttrs->AddAttribute( USTR( "text:style-name" ), USTR("svgtextstyle")+sStyleId);
+                mxDocumentHandler->startElement(USTR("text:span"),xUnoAttrs);
+
+                xAttrs->Clear();
                 mxDocumentHandler->characters(sText.makeStringAndClear());
+                mxDocumentHandler->endElement(USTR("text:span"));
                 mxDocumentHandler->endElement(USTR("text:p"));
                 mxDocumentHandler->endElement(USTR("draw:text-box"));
                 mxDocumentHandler->endElement(USTR("draw:frame"));
@@ -2291,6 +2392,14 @@ struct ShapeRenderingVisitor
                 Font aFont(maCurrState.maFontFamily,
                            Size(0,
                                 basegfx::fround(pt100thmm(maCurrState.mnFontSize))));
+                aFont.SetAlign(ALIGN_BASELINE);
+                aFont.SetColor(getVclColor(maCurrState.maFillColor));
+                aFont.SetFillColor(getVclColor(maCurrState.maFillColor));
+
+                if( !maCurrState.maFontStyle.equalsAscii("normal") )
+                    aFont.SetItalic(ITALIC_NORMAL); // TODO: discriminate
+                if( !maCurrState.mnFontWeight != 400.0 )
+                    aFont.SetWeight(WEIGHT_BOLD); // TODO: discriminate
 
                 // extract basic transformations out of CTM
                 basegfx::B2DTuple aScale, aTranslate;
@@ -2312,9 +2421,27 @@ struct ShapeRenderingVisitor
 
                 // TODO(F2): update bounds
                 mrOutDev.SetFont(aFont);
+                const ::rtl::OUString aText( sText.makeStringAndClear() );
+                switch( maCurrState.meTextAnchor )
+                {
+                    default:
+                    case BEFORE:
+                        break;
+
+                    case CENTER:
+                    {
+                        const long nWidth=mrOutDev.GetTextWidth(aText);
+                        x -= nWidth/2;
+                    }
+                    break;
+
+                    case AFTER:
+                        x -= mrOutDev.GetTextWidth(aText);
+                        break;
+                }
                 mrOutDev.DrawText(Point(basegfx::fround(pt100thmm(x)),
                                         basegfx::fround(pt100thmm(y))),
-                                  sText.makeStringAndClear());
+                                  aText);
                 break;
             }
         }
@@ -2592,6 +2719,7 @@ bool importSvg(SvStream & rStream, Graphic & rGraphic )
 
     aVDev.EnableOutput( FALSE );
     aMtf.Record( &aVDev );
+    aVDev.SetTextAlign(ALIGN_BASELINE);
 
     // parse styles and fill state stack
     svgi::State      aInitialState;
commit 8f76a23286bcf997d7cf369f984d21b459086941
Author: Thorsten Behrens <tbehrens at novell.com>
Date:   Tue Sep 14 09:49:34 2010 +0200

    svg-import-painturi-fix.diff: improves parsing of paint fragments

diff --git a/filter/source/svg/parserfragments.cxx b/filter/source/svg/parserfragments.cxx
index 147f778..8cdc831 100644
--- a/filter/source/svg/parserfragments.cxx
+++ b/filter/source/svg/parserfragments.cxx
@@ -117,52 +117,72 @@ geometry::AffineMatrix2D multiplyMatrix( const geometry::AffineMatrix2D& rLHS,
     return basegfx::unotools::affineMatrixFromHomMatrix(aRet,aRHS);
 }
 
+namespace
+{
+    struct ColorGrammar : public ::boost::spirit::grammar< ColorGrammar >
+    {
+    public:
+        ARGBColor& m_rColor;
+        explicit ColorGrammar( ARGBColor& rColor ) : m_rColor(rColor) {}
+        template< typename ScannerT >
+        struct definition
+        {
+            ::boost::spirit::rule< ScannerT > colorExpression;
+            definition( const ColorGrammar& self )
+            {
+                using namespace ::boost::spirit;
+
+                int_parser<sal_uInt8,10,1,3> byte_p;
+                colorExpression =
+                    (
+                        // the #rrggbb form
+                        ('#' >> (xdigit_p >> xdigit_p)[boost::bind(&setEightBitColor,
+                                                                   boost::ref(self.m_rColor.r),_1,_2)]
+                             >> (xdigit_p >> xdigit_p)[boost::bind(&setEightBitColor,
+                                                                   boost::ref(self.m_rColor.g),_1,_2)]
+                             >> (xdigit_p >> xdigit_p)[boost::bind(&setEightBitColor,
+                                                                   boost::ref(self.m_rColor.b),_1,_2)])
+                        |
+                        // the #rgb form
+                        ('#' >> xdigit_p[boost::bind(&setFourBitColor,
+                                                     boost::ref(self.m_rColor.r),_1)]
+                             >> xdigit_p[boost::bind(&setFourBitColor,
+                                                     boost::ref(self.m_rColor.g),_1)]
+                             >> xdigit_p[boost::bind(&setFourBitColor,
+                                                     boost::ref(self.m_rColor.b),_1)])
+                        |
+                        // rgb() form
+                        (str_p("rgb")
+                            >> '(' >>
+                            (
+                                // rgb(int,int,int)
+                                (byte_p[boost::bind(&setIntColor,
+                                                    boost::ref(self.m_rColor.r),_1)] >> ',' >>
+                                 byte_p[boost::bind(&setIntColor,
+                                                    boost::ref(self.m_rColor.g),_1)] >> ',' >>
+                                 byte_p[boost::bind(&setIntColor,
+                                                    boost::ref(self.m_rColor.b),_1)])
+                             |
+                                // rgb(double,double,double)
+                                (real_p[assign_a(self.m_rColor.r)] >> ',' >>
+                                 real_p[assign_a(self.m_rColor.g)] >> ',' >>
+                                 real_p[assign_a(self.m_rColor.b)])
+                             )
+                         >> ')')
+                     );
+            }
+            ::boost::spirit::rule<ScannerT> const& start() const { return colorExpression; }
+        };
+    };
+}
+
 bool parseColor( const char* sColor, ARGBColor& rColor  )
 {
     using namespace ::boost::spirit;
 
-    int_parser<sal_uInt8,10,1,3> byte_p;
-
     if( parse(sColor,
-            //  Begin grammar
-            (
-                // the #rrggbb form
-                ('#' >> (xdigit_p >> xdigit_p)[boost::bind(&setEightBitColor,
-                                                           boost::ref(rColor.r),_1,_2)]
-                     >> (xdigit_p >> xdigit_p)[boost::bind(&setEightBitColor,
-                                                           boost::ref(rColor.g),_1,_2)]
-                     >> (xdigit_p >> xdigit_p)[boost::bind(&setEightBitColor,
-                                                           boost::ref(rColor.b),_1,_2)])
-              |
-                // the #rgb form
-                ('#' >> xdigit_p[boost::bind(&setFourBitColor,
-                                             boost::ref(rColor.r),_1)]
-                     >> xdigit_p[boost::bind(&setFourBitColor,
-                                             boost::ref(rColor.g),_1)]
-                     >> xdigit_p[boost::bind(&setFourBitColor,
-                                             boost::ref(rColor.b),_1)])
-              |
-                // rgb() form
-                (str_p("rgb")
-                 >> '(' >>
-                     (
-                             // rgb(int,int,int)
-                             (byte_p[boost::bind(&setIntColor,
-                                                 boost::ref(rColor.r),_1)] >> ',' >>
-                              byte_p[boost::bind(&setIntColor,
-                                                 boost::ref(rColor.g),_1)] >> ',' >>
-                              byte_p[boost::bind(&setIntColor,
-                                                 boost::ref(rColor.b),_1)])
-                           |
-                             // rgb(double,double,double)
-                             (real_p[assign_a(rColor.r)] >> ',' >>
-                              real_p[assign_a(rColor.g)] >> ',' >>
-                              real_p[assign_a(rColor.b)])
-                     )
-                 >> ')')
-            ) >> end_p,
-            //  End grammar
-            space_p).full )
+              ColorGrammar(rColor) >> end_p,
+              space_p).full )
     {
         // free-form color found & parsed
         return true;
@@ -520,6 +540,32 @@ bool parseDashArray( const char* sDashArray, std::vector<double>& rOutputVector
 
 //////////////////////////////////////////////////////////////
 
+bool parsePaintUri( std::pair<const char*,const char*>& o_rPaintUri,
+                    std::pair<ARGBColor,bool>&          io_rColor,
+                    const char*                         sPaintUri )
+{
+    using namespace ::boost::spirit;
+
+    const bool bRes = parse(sPaintUri,
+        //  Begin grammar
+        (
+            str_p("url(#") >>
+            (+alnum_p)[assign_a(o_rPaintUri)] >>
+            str_p(")") >>
+            *( str_p("none")[assign_a(io_rColor.second,false)] |
+               str_p("currentColor")[assign_a(io_rColor.second,true)] |
+               ColorGrammar(io_rColor.first)
+               // TODO(F1): named color
+             )
+        ) >> end_p,
+        //  End grammar
+        space_p).full;
+
+    return bRes;
+}
+
+//////////////////////////////////////////////////////////////
+
 namespace
 {
 void appendChar( std::string& str, char character)
diff --git a/filter/source/svg/parserfragments.hxx b/filter/source/svg/parserfragments.hxx
index bcb6427..d2b6992 100644
--- a/filter/source/svg/parserfragments.hxx
+++ b/filter/source/svg/parserfragments.hxx
@@ -18,6 +18,7 @@
 
 #include <sal/config.h>
 #include <vector>
+#include <utility>
 #include <string>
 
 namespace basegfx
@@ -42,6 +43,29 @@ namespace svgi
     /// Parse given string for a list of double values, comma-delimited
     bool parseDashArray( const char* sDashArray, std::vector<double>& rOutputVector );
 
+    /** Parse paint uri
+
+        @param o_rPaintUri
+        Start and end ptr for uri substring (within
+        [sPaintUri,sPaintUri+strlen(sPaintUri)]
+
+        @param io_rColor
+        The optional paint color to use. if o_rPaintUri is empty,
+        parser sets io_rColor.second to false for color="None", to
+        true and keeps current io_rColor.first entry for
+        "currentColor", and to true and sets io_rColor.first to parsed
+        color otherwise.
+
+        @param sPaintUri
+        String to parse. Permitted to contain the optional paint
+        stuff, like fallback color.
+
+        @return true, if a paint uri was successfully parsed.
+     */
+    bool parsePaintUri( std::pair<const char*,const char*>& o_rPaintUri,
+                        std::pair<ARGBColor,bool>&          io_rColor,
+                        const char*                         sPaintUri );
+
     /// Parse given string for the xlink attribute
     bool parseXlinkHref( const char* xlink, std::string& data );
 
diff --git a/filter/source/svg/svgreader.cxx b/filter/source/svg/svgreader.cxx
index 1143d36..8913300 100644
--- a/filter/source/svg/svgreader.cxx
+++ b/filter/source/svg/svgreader.cxx
@@ -996,6 +996,9 @@ struct AnnotatingVisitor
                      const ARGBColor& rInheritColor,
                      const Gradient&  rInheritGradient )
     {
+        std::pair<const char*,const char*> aPaintUri(NULL,NULL);
+        std::pair<ARGBColor,bool>          aColor(maCurrState.maCurrentColor,
+                                                  false);
         if( strcmp(sValue,"none") == 0 )
             rType = NONE;
         else if( strcmp(sValue,"currentColor") == 0 )
@@ -1009,19 +1012,33 @@ struct AnnotatingVisitor
             rColor = rInheritColor;
             rGradient = rInheritGradient;
         }
-        else if( strncmp(sValue,"url(#",5) == 0 )
+        else if( parsePaintUri(aPaintUri,aColor,sValue) )
         {
-            // assuming gradient. assumption does not hold generally
-            if( rValue.getLength() > 5 )
+            if( aPaintUri.first != aPaintUri.second )
             {
-                ElementRefMapType::iterator aRes;
-                if( (aRes=maGradientIdMap.find(rValue.copy(5,
-                                                           rValue.getLength()-6))) != maGradientIdMap.end() )
+                // assuming gradient. assumption does not hold generally
+                const char* pClosingBracket;
+                if( (pClosingBracket=strstr(sValue,")")) && rValue.getLength() > 5 )
                 {
-                    rGradient = maGradientVector[aRes->second];
-                    rType = GRADIENT;
+                    ElementRefMapType::iterator aRes;
+                    if( (aRes=maGradientIdMap.find(
+                             rValue.copy(aPaintUri.first-sValue,
+                                         aPaintUri.second-aPaintUri.first))) != maGradientIdMap.end() )
+                    {
+                        rGradient = maGradientVector[aRes->second];
+                        rType = GRADIENT;
+                    }
                 }
             }
+            else if( aColor.second )
+            {
+                rType = SOLID;
+                rColor = aColor.first;
+            }
+            else
+            {
+                rType = NONE;
+            }
         }
         else
         {
commit c3935f2d15d810240b9ab3a943308e52b2fff862
Author: Thorsten Behrens <tbehrens at novell.com>
Date:   Tue Sep 14 09:47:53 2010 +0200

    svg-import-viewbox-fix.diff: fixes some nastiness with viewbox

diff --git a/filter/source/svg/parserfragments.cxx b/filter/source/svg/parserfragments.cxx
index d11ceca..147f778 100644
--- a/filter/source/svg/parserfragments.cxx
+++ b/filter/source/svg/parserfragments.cxx
@@ -510,7 +510,8 @@ bool parseDashArray( const char* sDashArray, std::vector<double>& rOutputVector
             list_p.direct
             (
                 real_p[push_back_a(rOutputVector)],
-                ','
+                // list delimiter is either ',' or space
+                ',' | eps_p
             )
         ) >> end_p,
         //  End grammar
diff --git a/filter/source/svg/svgreader.cxx b/filter/source/svg/svgreader.cxx
index 0c0c2f8..1143d36 100644
--- a/filter/source/svg/svgreader.cxx
+++ b/filter/source/svg/svgreader.cxx
@@ -254,6 +254,7 @@ struct AnnotatingVisitor
                 // init state. inherit defaults from parent.
                 maCurrState = maParentStates.back();
                 maCurrState.maTransform.identity();
+                maCurrState.maViewBox.reset();
 
                 // scan for style info
                 const sal_Int32 nNumAttrs( xAttributes->getLength() );
commit bd1429cfb3244ecb97a31cce633b0f0f44ac9ab4
Author: Fridrich Å trba <fridrich.strba at bluewin.ch>
Date:   Tue Sep 14 09:42:47 2010 +0200

    svg-import-filter-gfxfilter.diff: SVG Graphics filter implementation

diff --git a/filter/source/config/fragments/fcfg_internalgraphics.mk b/filter/source/config/fragments/fcfg_internalgraphics.mk
index ae978f0..d1f628a 100644
--- a/filter/source/config/fragments/fcfg_internalgraphics.mk
+++ b/filter/source/config/fragments/fcfg_internalgraphics.mk
@@ -68,6 +68,7 @@ F4_INTERNALGRAPHICS = \
     sgf_Import \
     sgv_Import \
     svg_Export \
+    svg_Import \
     svm_Export \
     svm_Import \
     tga_Import \
diff --git a/filter/source/config/fragments/internalgraphicfilters/svg_Import.xcu b/filter/source/config/fragments/internalgraphicfilters/svg_Import.xcu
new file mode 100644
index 0000000..3393237
--- /dev/null
+++ b/filter/source/config/fragments/internalgraphicfilters/svg_Import.xcu
@@ -0,0 +1,10 @@
+    <node oor:name="svg_Import" oor:op="replace"  >
+        <prop oor:name="Type"><value>svg_Scalable_Vector_Graphics</value></prop>
+        <prop oor:name="FormatName"><value>svgfilter</value></prop>
+        <prop oor:name="RealFilterName"/>
+        <prop oor:name="UIComponent"/>
+        <prop oor:name="UIName">
+            <value xml:lang="en-US">SVG - Scalable Vector Graphics</value>
+        </prop>
+        <prop oor:name="Flags"><value>IMPORT</value></prop>
+    </node>
diff --git a/filter/source/svg/exports.map b/filter/source/svg/exports.map
new file mode 100644
index 0000000..afb1469
--- /dev/null
+++ b/filter/source/svg/exports.map
@@ -0,0 +1,10 @@
+UDK_3_0_0 {
+        global:
+                component_getImplementationEnvironment;
+                component_getFactory;
+                component_writeInfo;
+                GraphicImport;
+
+        local:
+                *;
+};
diff --git a/filter/source/svg/makefile.mk b/filter/source/svg/makefile.mk
index c9f8e09..715ed82 100644
--- a/filter/source/svg/makefile.mk
+++ b/filter/source/svg/makefile.mk
@@ -74,6 +74,7 @@ SHL1STDLIBS=\
     $(UNOTOOLSLIB)		\
     $(TOOLSLIB)			\
     $(COMPHELPERLIB)	\
+    $(SVTOOLLIB)	    \
     $(CPPUHELPERLIB)	\
     $(CPPULIB)			\
     $(SALLIB)			\
@@ -82,7 +83,7 @@ SHL1STDLIBS=\
 SHL1DEPN=
 SHL1IMPLIB=	i$(SHL1TARGET)
 SHL1LIBS=	$(SLB)$/$(TARGET).lib
-SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+SHL1VERSIONMAP=exports.map
 SHL1DEF=	$(MISC)$/$(SHL1TARGET).def
 
 DEF1NAME=$(SHL1TARGET)
diff --git a/filter/source/svg/svgfilter.cxx b/filter/source/svg/svgfilter.cxx
index ec4fcc1..1975c0a 100644
--- a/filter/source/svg/svgfilter.cxx
+++ b/filter/source/svg/svgfilter.cxx
@@ -205,6 +205,14 @@ rtl::OUString SAL_CALL SVGFilter::detect( Sequence< PropertyValue >& io_rDescrip
 
 // -----------------------------------------------------------------------------
 
+class FilterConfigItem;
+extern "C" SAL_DLLPUBLIC_EXPORT BOOL __LOADONCALLAPI GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem*, BOOL )
+{
+    return importSvg( rStream, rGraphic );
+}
+
+// -----------------------------------------------------------------------------
+
 namespace sdecl = comphelper::service_decl;
  sdecl::class_<SVGFilter> serviceImpl;
  const sdecl::ServiceDecl svgFilter(
diff --git a/filter/source/svg/svgfilter.hxx b/filter/source/svg/svgfilter.hxx
index 2200f31..36405f2 100644
--- a/filter/source/svg/svgfilter.hxx
+++ b/filter/source/svg/svgfilter.hxx
@@ -268,4 +268,11 @@ sal_Bool SAL_CALL SVGFilter_supportsService( const ::rtl::OUString& ServiceName
 SAL_CALL SVGFilter_createInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & rSMgr)
     throw ( ::com::sun::star::uno::Exception );
 
+// -----------------------------------------------------------------------------
+
+class SvStream;
+class Graphic;
+
+bool importSvg(SvStream & rStream, Graphic & rGraphic );
+
 #endif // SVGFILTER_HXX
diff --git a/filter/source/svg/svgreader.cxx b/filter/source/svg/svgreader.cxx
index d24ab71..0c0c2f8 100644
--- a/filter/source/svg/svgreader.cxx
+++ b/filter/source/svg/svgreader.cxx
@@ -7,6 +7,7 @@
  *      Thorsten Behrens <tbehrens at novell.com>
  *
  *      Copyright (C) 2008, Novell Inc.
+ *      Parts copyright 2005 by Sun Microsystems, Inc.
  *
  *   The Contents of this file are made available subject to
  *   the terms of GNU Lesser General Public License Version 3.
@@ -41,6 +42,17 @@
 #include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
 #include <com/sun/star/xml/dom/NodeType.hpp>
 
+#include <comphelper/processfactory.hxx>
+#include <basegfx/polygon/b2dpolygoncutandtouch.hxx>
+#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
+#include <unotools/streamwrap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/gradient.hxx>
+#include <svtools/filter.hxx>
+#include <tools/zcodec.hxx>
+
 #include <boost/bind.hpp>
 #include <hash_set>
 #include <map>
@@ -424,6 +436,9 @@ struct AnnotatingVisitor
         // start&end color)
         optimizeGradientStops(rState.maFillGradient);
 
+        if( !mxDocumentHandler.is() )
+            return true; // cannot write style, svm import case
+
         // do we have a gradient fill? then write out gradient as well
         if( rState.meFillType == GRADIENT && rState.maFillGradient.maStops.size() > 1 )
         {
@@ -1505,10 +1520,12 @@ struct ShapeWritingVisitor
             for( sal_uInt32 i=0; i<rPoly.count(); ++i )
             {
                 aPolys.push_back(
-                    basegfx::tools::createAreaGeometryForPolygon(
-                        rPoly.getB2DPolygon(i),
-                        aState.mnStrokeWidth/2.0,
-                        aState.meLineJoin));
+                    basegfx::tools::stripNeutralPolygons(
+                        basegfx::tools::prepareForPolygonOperation(
+                            basegfx::tools::createAreaGeometry(
+                                rPoly.getB2DPolygon(i),
+                                aState.mnStrokeWidth/2.0,
+                                aState.meLineJoin))));
                 // TODO(F2): line ends
             }
 
@@ -1873,4 +1890,735 @@ sal_Bool SVGReader::parseAndConvert()
     return sal_True;
 }
 
+///////////////////////////////////////////////////////////////
+
+struct ShapeRenderingVisitor
+{
+    ShapeRenderingVisitor(StatePool&    /*rStatePool*/,
+                          StateMap&     rStateMap,
+                          OutputDevice& rOutDev,
+                          const std::vector< Gradient >& rGradientVector,
+                          const std::vector< GradientStop >& rGradientStopVector) :
+        mrStateMap(rStateMap),
+        mrOutDev(rOutDev),
+        mrGradientVector(rGradientVector),
+        mrGradientStopVector(rGradientStopVector)
+    {}
+
+    void operator()( const uno::Reference<xml::dom::XElement>& )
+    {
+    }
+
+    void operator()( const uno::Reference<xml::dom::XElement>&      xElem,
+                     const uno::Reference<xml::dom::XNamedNodeMap>& xAttributes )
+    {
+        sal_Int32 nDummyIndex(0);
+        rtl::OUString sStyleId(
+            xElem->getAttribute(
+                USTR("internal-style-ref")).getToken(
+                    0,'$',nDummyIndex));
+        StateMap::iterator pOrigState=mrStateMap.find(
+            sStyleId.toInt32());
+
+        if( pOrigState == mrStateMap.end() )
+            return; // non-exportable element, e.g. linearGradient
+
+        maCurrState = pOrigState->second;
+
+        const sal_Int32 nTokenId(getTokenId(xElem->getNodeName()));
+        switch(nTokenId)
+        {
+            case XML_LINE:
+            {
+                // collect attributes
+                const sal_Int32 nNumAttrs( xAttributes->getLength() );
+                rtl::OUString sAttributeValue;
+                double x1=0.0,y1=0.0,x2=0.0,y2=0.0;
+                for( sal_Int32 i=0; i<nNumAttrs; ++i )
+                {
+                    sAttributeValue = xAttributes->item(i)->getNodeValue();
+                    const sal_Int32 nAttribId(
+                        getTokenId(xAttributes->item(i)->getNodeName()));
+                    switch(nAttribId)
+                    {
+                        case XML_X1:
+                            x1= convLength(sAttributeValue,maCurrState,'h');
+                            break;
+                        case XML_X2:
+                            x2 = convLength(sAttributeValue,maCurrState,'h');
+                            break;
+                        case XML_Y1:
+                            y1 = convLength(sAttributeValue,maCurrState,'v');
+                            break;
+                        case XML_Y2:
+                            y2 = convLength(sAttributeValue,maCurrState,'v');
+                            break;
+                        default:
+                            // skip
+                            break;
+                    }
+                }
+
+                basegfx::B2DPolygon aPoly;
+                aPoly.append(basegfx::B2DPoint(x1,y1));
+                aPoly.append(basegfx::B2DPoint(x2,y2));
+
+                renderPathShape(basegfx::B2DPolyPolygon(aPoly));
+                break;
+            }
+            case XML_POLYGON:
+            case XML_POLYLINE:
+            {
+                rtl::OUString sPoints = xElem->hasAttribute(USTR("points")) ? xElem->getAttribute(USTR("points")) : USTR("");
+                basegfx::B2DPolygon aPoly;
+                basegfx::tools::importFromSvgPoints(aPoly, sPoints);
+                if( nTokenId == XML_POLYGON || maCurrState.meFillType != NONE )
+                    aPoly.setClosed(true);
+
+                renderPathShape(basegfx::B2DPolyPolygon(aPoly));
+                break;
+            }
+            case XML_RECT:
+            {
+                // collect attributes
+                const sal_Int32 nNumAttrs( xAttributes->getLength() );
+                rtl::OUString sAttributeValue;
+                bool bRxSeen=false, bRySeen=false;
+                double x=0.0,y=0.0,width=0.0,height=0.0,rx=0.0,ry=0.0;
+                for( sal_Int32 i=0; i<nNumAttrs; ++i )
+                {
+                    sAttributeValue = xAttributes->item(i)->getNodeValue();
+                    const sal_Int32 nAttribId(
+                        getTokenId(xAttributes->item(i)->getNodeName()));
+                    switch(nAttribId)
+                    {
+                        case XML_X:
+                            x = convLength(sAttributeValue,maCurrState,'h');
+                            break;
+                        case XML_Y:
+                            y = convLength(sAttributeValue,maCurrState,'v');
+                            break;
+                        case XML_WIDTH:
+                            width = convLength(sAttributeValue,maCurrState,'h');
+                            break;
+                        case XML_HEIGHT:
+                            height = convLength(sAttributeValue,maCurrState,'v');
+                            break;
+                        case XML_RX:
+                            rx = convLength(sAttributeValue,maCurrState,'h');
+                            bRxSeen=true;
+                            break;
+                        case XML_RY:
+                            ry = convLength(sAttributeValue,maCurrState,'v');
+                            bRySeen=true;
+                            break;
+                        default:
+                            // skip
+                            break;
+                    }
+                }
+
+                if( bRxSeen && !bRySeen )
+                    ry = rx;
+                else if( bRySeen && !bRxSeen )
+                    rx = ry;
+
+                basegfx::B2DPolygon aPoly;
+                aPoly = basegfx::tools::createPolygonFromRect(
+                    basegfx::B2DRange(x,y,x+width,y+height),
+                    rx, ry );
+
+                renderPathShape(basegfx::B2DPolyPolygon(aPoly));
+                break;
+            }
+            case XML_PATH:
+            {
+                rtl::OUString sPath = xElem->hasAttribute(USTR("d")) ? xElem->getAttribute(USTR("d")) : USTR("");
+                basegfx::B2DPolyPolygon aPoly;
+                basegfx::tools::importFromSvgD(aPoly, sPath);
+
+                renderPathShape(aPoly);
+                break;
+            }
+            case XML_CIRCLE:
+            {
+                // collect attributes
+                const sal_Int32 nNumAttrs( xAttributes->getLength() );
+                rtl::OUString sAttributeValue;
+                double cx=0.0,cy=0.0,r=0.0;
+                for( sal_Int32 i=0; i<nNumAttrs; ++i )
+                {
+                    sAttributeValue = xAttributes->item(i)->getNodeValue();
+                    const sal_Int32 nAttribId(
+                        getTokenId(xAttributes->item(i)->getNodeName()));
+                    switch(nAttribId)
+                    {
+                        case XML_CX:
+                            cx = convLength(sAttributeValue,maCurrState,'h');
+                            break;
+                        case XML_CY:
+                            cy = convLength(sAttributeValue,maCurrState,'v');
+                            break;
+                        case XML_R:
+                            r = convLength(sAttributeValue,maCurrState,'o');
+                        default:
+                            // skip
+                            break;
+                    }
+                }
+
+                basegfx::B2DEllipse aEllipse(basegfx::B2DPoint(cx, cy), basegfx::B2DTuple(r,r));
+                basegfx::B2DPolygon aPoly = basegfx::tools::createPolygonFromEllipse(
+                    aEllipse.getB2DEllipseCenter(),
+                    aEllipse.getB2DEllipseRadius().getX(),
+                    aEllipse.getB2DEllipseRadius().getY());
+
+                renderPathShape(basegfx::B2DPolyPolygon(aPoly));
+                break;
+            }
+            case XML_ELLIPSE:
+            {
+                // collect attributes
+                const sal_Int32 nNumAttrs( xAttributes->getLength() );
+                rtl::OUString sAttributeValue;
+                double cx=0.0,cy=0.0,rx=0.0, ry=0.0;
+                for( sal_Int32 i=0; i<nNumAttrs; ++i )
+                {
+                    sAttributeValue = xAttributes->item(i)->getNodeValue();
+                    const sal_Int32 nAttribId(
+                        getTokenId(xAttributes->item(i)->getNodeName()));
+                    switch(nAttribId)
+                    {
+                        case XML_CX:
+                            cx = convLength(sAttributeValue,maCurrState,'h');
+                            break;
+                        case XML_CY:
+                            cy = convLength(sAttributeValue,maCurrState,'v');
+                            break;
+                        case XML_RX:
+                            rx = convLength(sAttributeValue,maCurrState,'h');
+                            break;
+                        case XML_RY:
+                            ry = convLength(sAttributeValue,maCurrState,'v');
+                        default:
+                            // skip
+                            break;
+                    }
+                }
+
+                basegfx::B2DEllipse aEllipse(basegfx::B2DPoint(cx, cy), basegfx::B2DTuple(rx,ry));
+                basegfx::B2DPolygon aPoly = basegfx::tools::createPolygonFromEllipse(
+                    aEllipse.getB2DEllipseCenter(),
+                    aEllipse.getB2DEllipseRadius().getX(),
+                    aEllipse.getB2DEllipseRadius().getY());
+
+                renderPathShape(basegfx::B2DPolyPolygon(aPoly));
+                break;
+            }
+            case XML_IMAGE:
+            {
+                // collect attributes
+                const sal_Int32 nNumAttrs( xAttributes->getLength() );
+                rtl::OUString sAttributeValue;
+                double x=0.0,y=0.0,width=0.0,height=0.0;
+                for( sal_Int32 i=0; i<nNumAttrs; ++i )
+                {
+                    sAttributeValue = xAttributes->item(i)->getNodeValue();
+                    const sal_Int32 nAttribId(
+                        getTokenId(xAttributes->item(i)->getNodeName()));
+                    switch(nAttribId)
+                    {
+                        case XML_X:
+                            x = convLength(sAttributeValue,maCurrState,'h');
+                            break;
+                        case XML_Y:
+                            y = convLength(sAttributeValue,maCurrState,'v');
+                            break;
+                        case XML_WIDTH:
+                            width = convLength(sAttributeValue,maCurrState,'h');
+                            break;
+                        case XML_HEIGHT:
+                            height = convLength(sAttributeValue,maCurrState,'v');
+                            break;
+                        default:
+                            // skip
+                            break;
+                    }
+                }
+
+                rtl::OUString sValue = xElem->hasAttribute(USTR("href")) ? xElem->getAttribute(USTR("href")) : USTR("");
+                rtl::OString aValueUtf8( sValue.getStr(), sValue.getLength(), RTL_TEXTENCODING_UTF8 );
+                std::string sLinkValue;
+                parseXlinkHref(aValueUtf8.getStr(), sLinkValue);
+
+                if (!sLinkValue.empty())
+                {
+                    // <- blatant copy from svx/source/xml/xmlgrhlp.cxx
+                    Graphic aGraphic;
+
+                    uno::Sequence<sal_Int8> aData;
+                    SvXMLUnitConverter::decodeBase64(aData,
+                                                     rtl::OUString::createFromAscii(sLinkValue.c_str()));
+                    SvMemoryStream aSrc(aData.getArray(),
+                                        aData.getLength(),
+                                        STREAM_READ);
+                    USHORT nFormat = GRFILTER_FORMAT_DONTKNOW;
+                    USHORT pDeterminedFormat = GRFILTER_FORMAT_DONTKNOW;
+                    GraphicFilter::GetGraphicFilter()->ImportGraphic( aGraphic, String(), aSrc ,nFormat,&pDeterminedFormat );
+
+                    if (pDeterminedFormat == GRFILTER_FORMAT_DONTKNOW)
+                    {
+                        //Read the first two byte to check whether it is a gzipped stream, is so it may be in wmz or emz format
+                        //unzip them and try again
+
+                        BYTE    sFirstBytes[ 2 ];
+
+                        aSrc.Seek( STREAM_SEEK_TO_END );
+                        ULONG nStreamLen = aSrc.Tell();
+                        aSrc.Seek( 0 );
+
+                        if ( !nStreamLen )
+                        {
+                            SvLockBytes* pLockBytes = aSrc.GetLockBytes();
+                            if ( pLockBytes  )
+                                pLockBytes->SetSynchronMode( TRUE );
+
+                            aSrc.Seek( STREAM_SEEK_TO_END );
+                            nStreamLen = aSrc.Tell();
+                            aSrc.Seek( 0 );
+                        }
+                        if( nStreamLen >= 2 )
+                        {
+                            //read two byte
+                            aSrc.Read( sFirstBytes, 2 );
+
+                            if( sFirstBytes[0] == 0x1f && sFirstBytes[1] == 0x8b )
+                            {
+                                SvMemoryStream* pDest = new SvMemoryStream;
+                                ZCodec aZCodec( 0x8000, 0x8000 );
+                                aZCodec.BeginCompression(ZCODEC_GZ_LIB);
+                                aSrc.Seek( 0 );
+                                aZCodec.Decompress( aSrc, *pDest );
+
+                                if (aZCodec.EndCompression() && pDest )
+                                {
+                                    pDest->Seek( STREAM_SEEK_TO_END );
+                                    ULONG nStreamLen_ = pDest->Tell();
+                                    if (nStreamLen_)
+                                    {
+                                        pDest->Seek(0L);
+                                        GraphicFilter::GetGraphicFilter()->ImportGraphic( aGraphic, String(), *pDest ,nFormat,&pDeterminedFormat );
+                                    }
+                                }
+                                delete pDest;
+                            }
+                        }
+                    }
+                    // -> blatant copy from svx/source/xml/xmlgrhlp.cxx
+
+                    const Rectangle aBounds(
+                        Point(basegfx::fround(pt100thmm(x)),
+                              basegfx::fround(pt100thmm(y))),
+                        Size(basegfx::fround(pt100thmm(width)),
+                             basegfx::fround(pt100thmm(height))));
+                    aGraphic.Draw(&mrOutDev,
+                                  aBounds.TopLeft(),
+                                  aBounds.GetSize());
+                    maBounds.Union(aBounds);
+                }
+                break;
+            }
+            case XML_TEXT:
+            {
+                // collect text from all TEXT_NODE children into sText
+                rtl::OUStringBuffer sText;
+                visitChildren(boost::bind(
+                                  (rtl::OUStringBuffer& (rtl::OUStringBuffer::*)(const sal_Unicode* str))&rtl::OUStringBuffer::append,
+                                  boost::ref(sText),
+                                  boost::bind(&xml::dom::XNode::getNodeValue,
+                                              _1)),
+                              xElem,
+                              xml::dom::NodeType_TEXT_NODE);
+
+                // collect attributes
+                const sal_Int32 nNumAttrs( xAttributes->getLength() );
+                rtl::OUString sAttributeValue;
+                double x=0.0,y=0.0,width=0.0,height=0.0;
+                for( sal_Int32 i=0; i<nNumAttrs; ++i )
+                {
+                    sAttributeValue = xAttributes->item(i)->getNodeValue();
+                    const sal_Int32 nAttribId(
+                        getTokenId(xAttributes->item(i)->getNodeName()));
+                    switch(nAttribId)
+                    {
+                        case XML_X:
+                            x = convLength(sAttributeValue,maCurrState,'h');
+                            break;
+                        case XML_Y:
+                            y = convLength(sAttributeValue,maCurrState,'v');
+                            break;
+                        case XML_WIDTH:
+                            width = convLength(sAttributeValue,maCurrState,'h');
+                            break;
+                        case XML_HEIGHT:
+                            height = convLength(sAttributeValue,maCurrState,'v');
+                            break;
+                        default:
+                            // skip
+                            break;
+                    }
+                }
+
+                // actually export text
+                Font aFont(maCurrState.maFontFamily,
+                           Size(0,
+                                basegfx::fround(pt100thmm(maCurrState.mnFontSize))));
+
+                // extract basic transformations out of CTM
+                basegfx::B2DTuple aScale, aTranslate;
+                double fRotate, fShearX;
+                ::rtl::OUString sTransformValue;
+                if (maCurrState.maCTM.decompose(aScale, aTranslate, fRotate, fShearX))
+                {
+                    rtl::OUString sTransform;
+                    x += aTranslate.getX();
+                    y += aTranslate.getY();
+
+                    aFont.SetSize(
+                        Size(basegfx::fround(aFont.GetWidth()*aScale.getX()),
+                             basegfx::fround(aFont.GetHeight()*aScale.getY())));
+
+                    if( fRotate )
+                        aFont.SetOrientation(basegfx::fround(fRotate*1800.0/M_PI));
+                }
+
+                // TODO(F2): update bounds
+                mrOutDev.SetFont(aFont);
+                mrOutDev.DrawText(Point(basegfx::fround(pt100thmm(x)),
+                                        basegfx::fround(pt100thmm(y))),
+                                  sText.makeStringAndClear());
+                break;
+            }
+        }
+    }
+
+    void push()
+    {
+    }
+
+    void pop()
+    {
+    }
+
+    bool hasGradientOpacity( const Gradient& rGradient )
+    {
+        return
+            mrGradientStopVector[
+                rGradient.maStops[0]].maStopColor.a != 1.0 ||
+            mrGradientStopVector[
+                rGradient.maStops[1]].maStopColor.a != 1.0;
+    }
+
+    sal_Int8 toByteColor( double val )
+    {
+        // TODO(Q3): duplicated from vcl::unotools
+        return sal::static_int_cast<sal_Int8>(
+            basegfx::fround(val*255.0));
+    }
+
+    ::Color getVclColor( const ARGBColor& rColor )
+    {
+        const sal_uInt8 nRed  ( toByteColor(rColor.r)   );
+        const sal_uInt8 nGreen( toByteColor(rColor.g) );
+        const sal_uInt8 nBlue ( toByteColor(rColor.b)  );
+
+        return ::Color(nRed,nGreen,nBlue);
+    }
+
+    void renderPathShape(const basegfx::B2DPolyPolygon& rPoly)
+    {
+        // we might need to split up polypolygon into multiple path
+        // shapes (e.g. when emulating line stroking)
+        State aState = maCurrState;
+
+        // bring polygon from pt coordinate system to 100th millimeter
+        aState.maCTM.scale(2540.0/72.0,2540.0/72.0);
+
+        basegfx::B2DPolyPolygon aPoly(rPoly);
+        aPoly.transform(aState.maCTM);
+
+        const basegfx::B2DRange aBounds=basegfx::tools::getRange(aPoly);
+        maBounds.Union(
+            Rectangle(
+                basegfx::fround(aBounds.getMinX()),
+                basegfx::fround(aBounds.getMinY()),
+                basegfx::fround(aBounds.getMaxX()),
+                basegfx::fround(aBounds.getMaxY())));
+
+        // fill first
+        mrOutDev.SetLineColor();
+
+        // do we have a gradient fill?
+        if( aState.meFillType == GRADIENT && aState.maFillGradient.maStops.size() > 1 )
+        {
+            ::Gradient aGradient;
+
+            if( aState.maFillGradient.meType == Gradient::LINEAR )
+            {
+                // should the optimizeGradientStops method decide that
+                // this is a three-color gradient, it prolly wanted us
+                // to take axial instead
+                aGradient = ::Gradient( aState.maFillGradient.maStops.size() == 3 ?
+                                        GRADIENT_AXIAL :
+                                        GRADIENT_LINEAR );
+            }
+            else
+            {
+                aGradient = ::Gradient( GRADIENT_ELLIPTICAL );
+            }
+
+            basegfx::B2DTuple rScale, rTranslate;
+            double rRotate, rShearX;
+            if( aState.maFillGradient.maTransform.decompose(rScale, rTranslate, rRotate, rShearX) )
+                aGradient.SetAngle( basegfx::fround(rRotate*1800.0/M_PI) );
+            aGradient.SetStartColor( getVclColor(
+                                         mrGradientStopVector[
+                                             aState.maFillGradient.maStops[0]].maStopColor) );
+            aGradient.SetEndColor( getVclColor(
+                                       mrGradientStopVector[
+                                           aState.maFillGradient.maStops[1]].maStopColor) );
+
+            if( hasGradientOpacity(aState.maFillGradient) )
+            {
+                ::Gradient aTransparencyGradient=aGradient;
+
+                const BYTE	cTransStart( 255-
+                    basegfx::fround(mrGradientStopVector[
+                                        aState.maFillGradient.maStops[1]].maStopColor.a*
+                                    aState.mnFillOpacity*255.0));
+                const Color aTransStart( cTransStart, cTransStart, cTransStart );
+
+                const BYTE	cTransEnd( 255-
+                    basegfx::fround(mrGradientStopVector[
+                                        aState.maFillGradient.maStops[0]].maStopColor.a*
+                                    aState.mnFillOpacity*255.0));
+                const Color aTransEnd( cTransEnd, cTransEnd, cTransEnd );
+
+                // modulate gradient opacity with overall fill opacity
+                aTransparencyGradient.SetStartColor(aTransStart);
+                aTransparencyGradient.SetEndColor(aTransEnd);
+
+                VirtualDevice	aVDev;
+                GDIMetaFile		aMtf;
+
+                aVDev.EnableOutput( FALSE );
+                aVDev.SetMapMode( mrOutDev.GetMapMode() );
+                aMtf.Record( &aVDev );
+
+                aVDev.SetLineColor();
+                aVDev.SetFillColor();
+                aVDev.DrawGradient(::PolyPolygon(aPoly),aGradient);
+
+                const Rectangle aMtfBounds(
+                    basegfx::fround(aBounds.getMinX()),
+                    basegfx::fround(aBounds.getMinY()),
+                    basegfx::fround(aBounds.getMaxX()),
+                    basegfx::fround(aBounds.getMaxY()));
+
+                MapMode aMap(mrOutDev.GetMapMode());
+                aMtf.Stop();
+                aMtf.WindStart();
+                aMap.SetOrigin( aMtfBounds.TopLeft() );
+                aMtf.SetPrefMapMode( aMap );
+                aMtf.SetPrefSize( aMtfBounds.GetSize() );
+
+                mrOutDev.DrawTransparent(aMtf,
+                                         aMtfBounds.TopLeft(),
+                                         aMtfBounds.GetSize(),
+                                         aTransparencyGradient);
+            }
+            else
+            {
+                mrOutDev.DrawGradient(::PolyPolygon(aPoly),aGradient);
+            }
+        }
+        else
+        {
+            if( aState.meFillType == NONE )
+                mrOutDev.SetFillColor();
+            else
+                mrOutDev.SetFillColor(getVclColor(aState.maFillColor));
+
+            if( aState.mnFillOpacity != 1.0 )
+                mrOutDev.DrawTransparent(::PolyPolygon(aPoly),
+                                         basegfx::fround(
+                                             (1.0-aState.mnFillOpacity)*100.0));
+            else
+                mrOutDev.DrawPolyPolygon(::PolyPolygon(aPoly));
+        }
+
+        // Stroking now
+        mrOutDev.SetFillColor();
+
+        if( aState.meStrokeType != NONE &&
+            (aState.maDashArray.size() ||
+             aState.mnStrokeWidth != 1.0) )
+        {
+            // vcl thick lines are severly borked - generate filled
+            // polygon instead
+            std::vector<basegfx::B2DPolyPolygon> aPolys;
+            aPoly = rPoly;
+            if( !aState.maDashArray.empty() )
+            {
+                aPoly.clear();
+                basegfx::B2DPolyPolygon aSegment;
+                for( sal_uInt32 i=0; i<rPoly.count(); ++i )
+                {
+                    basegfx::tools::applyLineDashing(rPoly,
+                                                     aState.maDashArray,
+                                                     &aSegment);
+                    aPoly.append(aSegment);
+                }
+            }
+
+            // applied line dashing to original rPoly above, to get
+            // correctly transformed lengths - need to transform
+            // again, now
+            aPoly.transform(aState.maCTM);
+
+            for( sal_uInt32 i=0; i<aPoly.count(); ++i )
+            {
+                // ugly. convert to integer-based tools polygon
+                // first, and only _then_ remove intersections (we
+                // might get new ones from the rounding)
+                aPolys.push_back(
+                    basegfx::tools::stripNeutralPolygons(
+                        basegfx::tools::prepareForPolygonOperation(
+                            ::PolyPolygon(
+                                basegfx::tools::createAreaGeometry(
+                                    aPoly.getB2DPolygon(i),
+                                    pt100thmm(aState.mnStrokeWidth/2.0),
+                                    aState.meLineJoin)).getB2DPolyPolygon())));
+                // TODO(F2): line ends
+            }
+
+            mrOutDev.SetLineColor();
+            mrOutDev.SetFillColor(getVclColor(aState.maStrokeColor));
+
+            for( sal_uInt32 i=0; i<aPolys.size(); ++i )
+            {
+                if( aState.mnStrokeOpacity != 1.0 )
+                    mrOutDev.DrawTransparent(::PolyPolygon(aPolys[i]),
+                                             basegfx::fround(
+                                                 (1.0-aState.mnStrokeOpacity)*100.0));
+                else
+                    mrOutDev.DrawPolyPolygon(::PolyPolygon(aPolys[i]));
+
+                const basegfx::B2DRange aStrokeBounds=basegfx::tools::getRange(aPolys[i]);
+                maBounds.Union(
+                    Rectangle(
+                        basegfx::fround(aStrokeBounds.getMinX()),
+                        basegfx::fround(aStrokeBounds.getMinY()),
+                        basegfx::fround(aStrokeBounds.getMaxX()),
+                        basegfx::fround(aStrokeBounds.getMaxY())));
+            }
+        }
+        else
+        {
+            if( aState.meStrokeType == NONE )
+                mrOutDev.SetLineColor();
+            else
+                mrOutDev.SetLineColor(getVclColor(aState.maStrokeColor));
+
+            if( aState.mnStrokeOpacity != 1.0 )
+                mrOutDev.DrawTransparent(::PolyPolygon(aPoly),
+                                         basegfx::fround(
+                                             (1.0-aState.mnStrokeOpacity)*100.0));
+            else
+                mrOutDev.DrawPolyPolygon(::PolyPolygon(aPoly));
+        }
+    }
+
+    State                                      maCurrState;
+    StateMap&                                  mrStateMap;
+    OutputDevice&                               mrOutDev;
+    const std::vector< Gradient >&             mrGradientVector;
+    const std::vector< GradientStop >&         mrGradientStopVector;
+    Rectangle                                   maBounds;
+};
+
 } // namespace svgi
+
+bool importSvg(SvStream & rStream, Graphic & rGraphic )
+{
+    const uno::Reference<lang::XMultiServiceFactory> xServiceFactory(
+        ::comphelper::getProcessServiceFactory());
+
+    uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder(
+        xServiceFactory->createInstance(
+            rtl::OUString::createFromAscii("com.sun.star.xml.dom.DocumentBuilder")),
+        uno::UNO_QUERY );
+
+    uno::Reference<io::XInputStream> xStream(
+        new utl::OInputStreamWrapper(rStream) );
+
+    uno::Reference<xml::dom::XDocument> xDom(
+        xDomBuilder->parse(xStream),
+        uno::UNO_QUERY_THROW );
+
+    uno::Reference<xml::dom::XElement> xDocElem( xDom->getDocumentElement(),
+                                                 uno::UNO_QUERY_THROW );
+
+    VirtualDevice	aVDev;
+    GDIMetaFile		aMtf;
+
+    aVDev.EnableOutput( FALSE );
+    aMtf.Record( &aVDev );
+
+    // parse styles and fill state stack
+    svgi::State      aInitialState;
+    svgi::StatePool aStatePool;
+    svgi::StateMap  aStateMap;
+    svgi::AnnotatingVisitor aVisitor(aStatePool,
+                                     aStateMap,
+                                     aInitialState,
+                                     uno::Reference<xml::sax::XDocumentHandler>());
+    svgi::visitElements(aVisitor, xDocElem);
+
+#ifdef VERBOSE
+    dumpTree(xDocElem);
+#endif
+
+    // render all shapes to mtf
+    svgi::ShapeRenderingVisitor aRenderer(aStatePool,aStateMap,aVDev,
+                                         aVisitor.maGradientVector,
+                                         aVisitor.maGradientStopVector);
+    svgi::visitElements(aRenderer, xDocElem);
+
+    aMtf.Stop();
+
+    aMtf.WindStart();
+    aMtf.SetPrefMapMode( MAP_100TH_MM );
+
+    // get the document dimensions
+
+    // if the "width" and "height" attributes are missing, inkscape fakes
+    // A4 portrait for. Let's do the same.
+    if (!xDocElem->hasAttribute(USTR("width")))
+        xDocElem->setAttribute(USTR("width"), USTR("210mm"));
+    if (!xDocElem->hasAttribute(USTR("height")))
+        xDocElem->setAttribute(USTR("height"), USTR("297mm"));
+
+    aMtf.SetPrefSize(
+        Size(
+            std::max(
+                sal_Int32(aRenderer.maBounds.Right()),
+                basegfx::fround( svgi::pt100thmm(svgi::convLength(xDocElem->getAttribute(USTR("width")),aInitialState,'h')) )),
+            std::max(
+                sal_Int32(aRenderer.maBounds.Bottom()),
+                basegfx::fround( svgi::pt100thmm(svgi::convLength(xDocElem->getAttribute(USTR("height")),aInitialState,'v')) ))));
+
+    rGraphic = aMtf;
+
+    return sal_True;
+}
diff --git a/filter/source/svg/test/makefile.mk b/filter/source/svg/test/makefile.mk
index d51fdda..669d549 100644
--- a/filter/source/svg/test/makefile.mk
+++ b/filter/source/svg/test/makefile.mk
@@ -41,6 +41,7 @@ SHL1STDLIBS= 	        \
     $(UNOTOOLSLIB)		\
     $(TOOLSLIB)			\
     $(COMPHELPERLIB)	\
+    $(SVTOOLLIB)	    \
     $(CPPUHELPERLIB)	\
     $(CPPULIB)			\
     $(SALLIB)			\
commit 428f18501084a2826098086e4b93491d5c286865
Author: Fridrich Å trba <fridrich.strba at bluewin.ch>
Date:   Tue Sep 14 09:36:14 2010 +0200

    svg-import-filter.diff: SVG Import Filter implementation in filter module

diff --git a/filter/source/config/fragments/fcfg_drawgraphics.mk b/filter/source/config/fragments/fcfg_drawgraphics.mk
index 7038e27..41a4625 100644
--- a/filter/source/config/fragments/fcfg_drawgraphics.mk
+++ b/filter/source/config/fragments/fcfg_drawgraphics.mk
@@ -54,6 +54,7 @@ F4_DRAWGRAPHICS = \
     SGF___StarOffice_Writer_SGF \
     SGV___StarDraw_2_0 \
     SVM___StarView_Metafile \
+    SVG___Scalable_Vector_Graphics \
     TGA___Truevision_TARGA \
     TIF___Tag_Image_File \
     WMF___MS_Windows_Metafile \
diff --git a/filter/source/config/fragments/filters/SVG___Scalable_Vector_Graphics.xcu b/filter/source/config/fragments/filters/SVG___Scalable_Vector_Graphics.xcu
new file mode 100644
index 0000000..1212e05
--- /dev/null
+++ b/filter/source/config/fragments/filters/SVG___Scalable_Vector_Graphics.xcu
@@ -0,0 +1,13 @@
+    <node oor:name="SVG - Scalable Vector Graphics" oor:op="replace">
+        <prop oor:name="Flags"><value>IMPORT ALIEN USESOPTIONS 3RDPARTYFILTER PREFERRED</value></prop>
+        <prop oor:name="UIComponent"/>
+        <prop oor:name="FilterService"><value>com.sun.star.comp.Draw.SVGFilter</value></prop>
+        <prop oor:name="UserData"><value></value></prop>
+        <prop oor:name="UIName">
+            <value xml:lang="x-default">SVG - Scalable Vector Graphics</value>
+        </prop>
+        <prop oor:name="FileFormatVersion"><value>0</value></prop>
+        <prop oor:name="Type"><value>svg_Scalable_Vector_Graphics</value></prop>
+        <prop oor:name="TemplateName"/>
+        <prop oor:name="DocumentService"><value>com.sun.star.drawing.DrawingDocument</value></prop>
+    </node>
diff --git a/filter/source/config/fragments/types/svg_Scalable_Vector_Graphics.xcu b/filter/source/config/fragments/types/svg_Scalable_Vector_Graphics.xcu
index 37643df..8865dee 100644
--- a/filter/source/config/fragments/types/svg_Scalable_Vector_Graphics.xcu
+++ b/filter/source/config/fragments/types/svg_Scalable_Vector_Graphics.xcu
@@ -1,10 +1,10 @@
     <node oor:name="svg_Scalable_Vector_Graphics" oor:op="replace" >
-        <prop oor:name="DetectService"/>
+        <prop oor:name="DetectService"><value>com.sun.star.comp.Draw.SVGFilter</value></prop>
         <prop oor:name="URLPattern"/>
         <prop oor:name="Extensions"><value>svg</value></prop>
         <prop oor:name="MediaType"><value>image/svg+xml</value></prop>
-        <prop oor:name="Preferred"><value>false</value></prop>
-        <prop oor:name="PreferredFilter"/>
+        <prop oor:name="Preferred"><value>true</value></prop>
+        <prop oor:name="PreferredFilter"><value>SVG - Scalable Vector Graphics</value></prop>
         <prop oor:name="UIName">
             <value>SVG - Scalable Vector Graphics</value>
         </prop>
diff --git a/filter/source/svg/b2dellipse.cxx b/filter/source/svg/b2dellipse.cxx
new file mode 100644
index 0000000..924c5ab
--- /dev/null
+++ b/filter/source/svg/b2dellipse.cxx
@@ -0,0 +1,139 @@
+/*************************************************************************
+ *
+ *    OpenOffice.org - a multi-platform office productivity suite
+ *
+ *    Author:
+ *      Fridrich Strba  <fridrich.strba at bluewin.ch>
+ *      Thorsten Behrens <tbehrens at novell.com>
+ *
+ *      Copyright (C) 2008, Novell Inc.
+ *
+ *   The Contents of this file are made available subject to
+ *   the terms of GNU Lesser General Public License Version 3.
+ *
+ ************************************************************************/
+
+#include "b2dellipse.hxx"
+
+#include <osl/diagnose.h>
+
+#include <basegfx/point/b2dpoint.hxx>
+
+#include <basegfx/matrix/b2dhommatrix.hxx>
+
+#include <rtl/instance.hxx>
+
+#include <boost/scoped_ptr.hpp>
+#include <vector>
+#include <algorithm>
+
+class ImplB2DEllipse
+{
+     basegfx::B2DPoint maCenter;
+     basegfx::B2DTuple maRadius;
+
+public:
+    ImplB2DEllipse()
+    :	maCenter(0.0f, 0.0f),
+        maRadius(0.0f, 0.0f)
+    {}
+
+    ImplB2DEllipse(const ImplB2DEllipse& rToBeCopied)
+    :	maCenter(rToBeCopied.maCenter),
+        maRadius(rToBeCopied.maRadius)
+    {}
+
+    ImplB2DEllipse& operator=( const ImplB2DEllipse& rToBeCopied )
+    {
+        maCenter = rToBeCopied.maCenter;
+        maRadius = rToBeCopied.maRadius;
+
+        return *this;
+    }
+
+    bool isEqual(const ImplB2DEllipse& rCandidate) const
+    {
+        return (maCenter == rCandidate.maCenter)
+            && (maRadius == rCandidate.maRadius);
+    }
+
+    basegfx::B2DPoint getCenter() const
+    {
+        return maCenter;
+    }
+
+    void setCenter(const basegfx::B2DPoint& rCenter)
+    {
+        maCenter = rCenter;
+    }
+
+    basegfx::B2DTuple getRadius() const
+    {
+        return maRadius;
+    }
+
+    void setRadius(const basegfx::B2DTuple& rRadius)
+    {
+        maRadius = rRadius;
+    }
+
+
+    void transform(const basegfx::B2DHomMatrix& /* rMatrix */)
+    {
+    }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+
+    B2DEllipse::B2DEllipse()
+    {}
+
+    B2DEllipse::B2DEllipse(const basegfx::B2DPoint& rCenter, const basegfx::B2DTuple& rRadius)
+    :	maCenter(rCenter), maRadius(rRadius)
+    {
+    }
+
+    B2DEllipse::~B2DEllipse()
+    {
+    }
+
+    bool B2DEllipse::operator==(const B2DEllipse& rEllipse) const
+    {
+        return (maCenter == rEllipse.maCenter) && (maRadius == rEllipse.maRadius);
+    }
+
+    bool B2DEllipse::operator!=(const B2DEllipse& rEllipse) const
+    {
+        return !(*this == rEllipse);
+    }
+
+    basegfx::B2DPoint B2DEllipse::getB2DEllipseCenter() const
+    {
+        return maCenter;
+    }
+
+    void B2DEllipse::setB2DEllipseCenter(const basegfx::B2DPoint& rCenter)
+    {
+        maCenter = rCenter;
+    }
+
+    basegfx::B2DTuple B2DEllipse::getB2DEllipseRadius() const
+    {
+        return maRadius;
+    }
+
+    void B2DEllipse::setB2DEllipseRadius(const basegfx::B2DTuple& rRadius)
+    {
+        maRadius = rRadius;
+    }
+
+    void B2DEllipse::transform(const basegfx::B2DHomMatrix& /* rMatrix */)
+    {
+    }
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/filter/source/svg/b2dellipse.hxx b/filter/source/svg/b2dellipse.hxx
new file mode 100644
index 0000000..a63d839
--- /dev/null
+++ b/filter/source/svg/b2dellipse.hxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ *    OpenOffice.org - a multi-platform office productivity suite
+ *
+ *    Author:
+ *      Fridrich Strba  <fridrich.strba at bluewin.ch>
+ *      Thorsten Behrens <tbehrens at novell.com>
+ *
+ *      Copyright (C) 2008, Novell Inc.
+ *
+ *   The Contents of this file are made available subject to
+ *   the terms of GNU Lesser General Public License Version 3.
+ *
+ ************************************************************************/
+
+#ifndef _BASEGFX_B2DELLIPSE_HXX
+#define _BASEGFX_B2DELLIPSE_HXX
+
+#include <sal/types.h>
+
+#include <o3tl/cow_wrapper.hxx>
+
+#include <basegfx/point/b2dpoint.hxx>
+
+#include <basegfx/tuple/b2dtuple.hxx>
+
+#include <basegfx/vector/b2enums.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+// predeclarations
+class ImplB2DEllipse;
+
+namespace basegfx
+{
+    class B2DPoint;
+    class B2DVector;
+    class B2DHomMatrix;
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+    class B2DEllipse
+    {
+    private:
+     basegfx::B2DPoint maCenter;
+     basegfx::B2DTuple maRadius;
+
+    public:
+        B2DEllipse();
+        B2DEllipse(const B2DEllipse& rEllipse);
+        B2DEllipse(const basegfx::B2DPoint& rCenter, const basegfx::B2DTuple& rRadius);
+        ~B2DEllipse();
+
+        // assignment operator
+        B2DEllipse& operator=(const B2DEllipse& rEllipse);
+
+        // compare operators
+        bool operator==(const B2DEllipse& rEllipse) const;
+        bool operator!=(const B2DEllipse& rEllipse) const;
+
+        // Coordinate interface
+        basegfx::B2DPoint getB2DEllipseCenter() const;
+        void setB2DEllipseCenter(const basegfx::B2DPoint& rCenter);
+
+        basegfx::B2DTuple getB2DEllipseRadius() const;
+        void setB2DEllipseRadius(const basegfx::B2DTuple& rRadius);
+
+        // apply transformation given in matrix form to the Ellipse
+        void transform(const basegfx::B2DHomMatrix& rMatrix);
+    };
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif /* _BASEGFX_B2DELLIPSE_HXX */
diff --git a/filter/source/svg/gentoken.pl b/filter/source/svg/gentoken.pl
new file mode 100644
index 0000000..75bb1e2
--- /dev/null
+++ b/filter/source/svg/gentoken.pl
@@ -0,0 +1,58 @@
+# from oox/source/token - should really put this into solenv
+
+$ARGV0 = shift @ARGV;
+$ARGV1 = shift @ARGV;
+$ARGV2 = shift @ARGV;
+
+open ( TOKENS, $ARGV0 ) || die "can't open token file: $!";
+my %tokens;
+
+while ( defined ($line = <TOKENS>) )
+{
+    if( !($line =~ /^#/) )
+    {
+        chomp($line);
+        @token = split(/\s+/,$line);
+        if ( not defined ($token[1]) )
+        {
+            $token[1] = "XML_".$token[0];
+            $token[1] =~ tr/\-\.\:/___/;
+            $token[1] =~ s/\+/PLUS/g;
+            $token[1] =~ s/\-/MINUS/g;
+        }
+
+        $tokens{$token[0]} = uc($token[1]);
+    }
+}
+close ( TOKENS );
+
+open ( HXX, ">$ARGV1" ) || die "can't open tokens.hxx file: $!";
+open ( GPERF, ">$ARGV2" ) || die "can't open tokens.gperf file: $!";
+
+print ( GPERF "%language=C++\n" );
+print ( GPERF "%global-table\n" );
+print ( GPERF "%null-strings\n" );
+print ( GPERF "%struct-type\n" );
+print ( GPERF "struct xmltoken\n" );
+print ( GPERF "{\n" );
+print ( GPERF "  const sal_Char *name; sal_Int32 nToken; \n" );
+print ( GPERF "};\n" );
+print ( GPERF "%%\n" );
+
+print ( HXX "#ifndef INCLUDED_AUTOGEN_TOKEN_HXX\n" );
+print ( HXX "#define INCLUDED_AUTOGEN_TOKEN_HXX\n\n" );
+print ( HXX "#include <sal/types.h>\n\n" );
+
+$i = 0;
+foreach( sort(keys(%tokens)) )
+{
+    print( HXX "const sal_Int32 $tokens{$_} = $i;\n" );
+    print( GPERF "$_,$tokens{$_}\n" );
+    $i = $i + 1;
+}
+print ( GPERF "%%\n" );
+print ( HXX "const sal_Int32 XML_TOKEN_COUNT = $i;\n" );
+print ( HXX "const sal_Int32 XML_TOKEN_INVALID = -1;\n\n" );
+print ( HXX "#endif\n" );
+close ( HXX );
+close ( GPERF );
diff --git a/filter/source/svg/gfxtypes.hxx b/filter/source/svg/gfxtypes.hxx
new file mode 100644
index 0000000..3675e30
--- /dev/null
+++ b/filter/source/svg/gfxtypes.hxx
@@ -0,0 +1,356 @@
+/*************************************************************************
+ *
+ *    OpenOffice.org - a multi-platform office productivity suite
+ *
+ *    Author:
+ *      Fridrich Strba  <fridrich.strba at bluewin.ch>
+ *      Thorsten Behrens <tbehrens at novell.com>
+ *
+ *      Copyright (C) 2008, Novell Inc.
+ *
+ *   The Contents of this file are made available subject to
+ *   the terms of GNU Lesser General Public License Version 3.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_GFXTYPES_HXX
+#define INCLUDED_GFXTYPES_HXX
+
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/polygon/b2dlinegeometry.hxx>
+
+#include <hash_set>
+#include <hash_map>
+#include <rtl/ustring.hxx>
+
+namespace svgi
+{
+
+struct ARGBColor
+{
+    double toDoubleColor( sal_uInt8 val ) { return val/255.0; }
+
+    ARGBColor() : a(1.0), r(0.0), g(0.0), b(0.0)
+    {}
+    explicit ARGBColor(double fGrey) : a(1.0), r(fGrey), g(fGrey), b(fGrey)
+    {}
+    ARGBColor( double r_, double g_, double b_ ) :
+        a(1.0), r(r_), g(g_), b(b_)
+    {}
+    ARGBColor( double a_, double r_, double g_, double b_ ) :
+        a(a_), r(r_), g(g_), b(b_)
+    {}
+    ARGBColor( int r_, int g_, int b_ ) :
+        a(1.0),
+        r(toDoubleColor(sal::static_int_cast<sal_uInt8>(r_))),
+        g(toDoubleColor(sal::static_int_cast<sal_uInt8>(g_))),
+        b(toDoubleColor(sal::static_int_cast<sal_uInt8>(b_)))
+    {}
+    ARGBColor( int a_, int r_, int g_, int b_ ) :
+        a(toDoubleColor(sal::static_int_cast<sal_uInt8>(a_))),
+        r(toDoubleColor(sal::static_int_cast<sal_uInt8>(r_))),
+        g(toDoubleColor(sal::static_int_cast<sal_uInt8>(g_))),
+        b(toDoubleColor(sal::static_int_cast<sal_uInt8>(b_)))
+    {}
+    double a;
+    double r;
+    double g;
+    double b;
+};
+inline bool operator==( const ARGBColor& rLHS, const ARGBColor& rRHS )
+{ return rLHS.a==rRHS.a && rLHS.r==rRHS.r && rLHS.g==rRHS.g && rLHS.b==rRHS.b; }
+inline bool operator!=( const ARGBColor& rLHS, const ARGBColor& rRHS )
+{ return !(rLHS==rRHS); }
+
+struct GradientStop
+{
+    GradientStop() : maStopColor(), mnStopPosition(0.0)
+    {}
+    ARGBColor     maStopColor;
+    double        mnStopPosition;
+};
+inline bool operator==( const GradientStop& rLHS, const GradientStop& rRHS )
+{ return rLHS.mnStopPosition==rRHS.mnStopPosition && rLHS.maStopColor==rRHS.maStopColor; }
+
+struct Gradient
+{
+    enum GradientType { LINEAR, RADIAL};
+    std::vector<sal_Size> maStops;
+    basegfx::B2DHomMatrix maTransform;
+    GradientType          meType;
+    union
+    {
+        double test;
+        struct
+        {
+            double                mfX1;
+            double                mfX2;
+            double                mfY1;
+            double                mfY2;
+        } linear;
+        struct
+        {
+            double                mfCX;
+            double                mfCY;
+            double                mfFX;
+            double                mfFY;
+            double                mfR;
+        } radial;
+    } maCoords;
+    sal_Int32             mnId;
+    bool                  mbBoundingBoxUnits;
+    bool                  mbLinearBoundingBoxUnits;
+
+//    explicit Gradient(GradientType eType) : maStops(), maTransform(), meType(eType), maCoords.mfCX(0.0), maCoords.mfCY(0.0), maCoords.mfFX(0.0), maCoords.mfFY(0.0), maCoords.mfR(0.0), mnId(0), mbBoundingBoxUnits(false)
+    explicit Gradient(GradientType eType) : maStops(), maTransform(), meType(eType), mnId(0), mbBoundingBoxUnits(false)
+    {
+        maCoords.radial.mfCX = 0.0;
+        maCoords.radial.mfCY = 0.0;
+        maCoords.radial.mfFX = 0.0;
+        maCoords.radial.mfFY = 0.0;
+        maCoords.radial.mfR  = 0.0;
+    }
+};
+
+inline bool operator==( const Gradient& rLHS, const Gradient& rRHS )
+{
+    if( rLHS.meType != rRHS.meType )
+        return false;
+    if( rLHS.meType == Gradient::LINEAR )
+        return rLHS.mbBoundingBoxUnits==rRHS.mbBoundingBoxUnits && rLHS.maStops==rRHS.maStops &&
+            rLHS.maCoords.linear.mfX1 == rRHS.maCoords.linear.mfX1 && rLHS.maCoords.linear.mfX2 == rRHS.maCoords.linear.mfX2 &&
+            rLHS.maCoords.linear.mfY1 == rRHS.maCoords.linear.mfY1 && rLHS.maCoords.linear.mfY2 == rRHS.maCoords.linear.mfY2;
+    else
+        return rLHS.mbBoundingBoxUnits==rRHS.mbBoundingBoxUnits && rLHS.maStops==rRHS.maStops &&
+            rLHS.maCoords.radial.mfCX == rRHS.maCoords.radial.mfCX && rLHS.maCoords.radial.mfCY == rRHS.maCoords.radial.mfCY &&
+            rLHS.maCoords.radial.mfFX == rRHS.maCoords.radial.mfFX && rLHS.maCoords.radial.mfFY == rRHS.maCoords.radial.mfFY &&
+            rLHS.maCoords.radial.mfR == rRHS.maCoords.radial.mfR;
+}
+
+enum PaintType
+{
+    NONE,
+    SOLID,
+    GRADIENT
+};
+
+enum FillRule
+{
+    NON_ZERO,
+    EVEN_ODD
+};
+
+enum TextAlign
+{
+    BEFORE,
+    CENTER,
+    AFTER
+};
+
+enum CapStyle
+{
+    BUTT,
+    RECT,
+    ROUND
+};
+
+enum FontStyle
+{
+    STYLE_NORMAL,
+    STYLE_OBLIQUE,
+    STYLE_ITALIC
+};
+
+enum FontVariant
+{
+    VARIANT_NORMAL,
+    VARIANT_SMALLCAPS
+};
+
+struct State
+{
+    State() :
+        maCTM(),
+        maTransform(),
+        maViewport(),
+        maViewBox(),
+        maFontFamily(), // app-default
+        mnFontSize(12.0),
+        meFontStyle(STYLE_NORMAL),
+        meFontVariant(VARIANT_NORMAL),
+        mnFontWeight(400.0),
+        meTextAnchor(BEFORE),
+        meTextDisplayAlign(BEFORE),
+        mnTextLineIncrement(0.0),
+        maCurrentColor(1.0),
+        mbVisibility(true),
+        meFillType(SOLID),
+        mnFillOpacity(1.0),
+        meStrokeType(NONE),
+        mnStrokeOpacity(1.0),
+        meViewportFillType(NONE),
+        mnViewportFillOpacity(1.0),
+        maFillColor(0.0),
+        maFillGradient(Gradient::LINEAR),
+        meFillRule(NON_ZERO),
+        maStrokeColor(0.0),
+        maStrokeGradient(Gradient::LINEAR),
+        maDashArray(),
+        mnDashOffset(0.0),
+        meLineCap(BUTT),
+        meLineJoin(basegfx::B2DLINEJOIN_MITER),
+        mnMiterLimit(4.0),
+        mnStrokeWidth(1.0),
+        maViewportFillColor(1.0),
+        maViewportFillGradient(Gradient::LINEAR),
+        mnStyleId(0)
+    {}
+
+    basegfx::B2DHomMatrix       maCTM;
+    basegfx::B2DHomMatrix       maTransform;
+    basegfx::B2DRange           maViewport;
+    basegfx::B2DRange           maViewBox;
+
+    rtl::OUString               maFontFamily;
+    /** Absolute: xx-small=6.94 | x-small=8.33 | small=10 | medium=12 | large=14.4 | x-large=17.28 | xx-large=20.736
+
+        Relative(to parent): larger (enlarge by 1.2)
+                             smaller (shrink by 1.2)
+
+     */
+    double                      mnFontSize;
+    FontStyle                   meFontStyle;
+    FontVariant                 meFontVariant;
+    double                      mnFontWeight;
+
+    TextAlign                   meTextAnchor; // text-anchor
+    TextAlign                   meTextDisplayAlign; // display-align
+    double                      mnTextLineIncrement; // 0.0 means auto
+
+    ARGBColor                   maCurrentColor;
+    bool                        mbVisibility;
+
+    PaintType                   meFillType;
+    double                      mnFillOpacity;
+    PaintType                   meStrokeType;
+    double                      mnStrokeOpacity;
+    PaintType                   meViewportFillType;
+    double                      mnViewportFillOpacity;
+
+    ARGBColor                   maFillColor;
+    Gradient                    maFillGradient;
+    FillRule                    meFillRule;
+
+    ARGBColor                   maStrokeColor;
+    Gradient                    maStrokeGradient;
+    std::vector<double>         maDashArray;
+    double                      mnDashOffset;
+    CapStyle                    meLineCap;
+    basegfx::B2DLineJoin        meLineJoin;
+    double                      mnMiterLimit;
+    double                      mnStrokeWidth;
+
+    ARGBColor                   maViewportFillColor;
+    Gradient                    maViewportFillGradient;
+
+    sal_Int32                   mnStyleId;
+};
+
+inline bool operator==(const State& rLHS, const State& rRHS )
+{
+    return rLHS.maCTM==rRHS.maCTM &&
+        rLHS.maTransform==rRHS.maTransform &&
+        rLHS.maViewport==rRHS.maViewport &&
+        rLHS.maViewBox==rRHS.maViewBox &&
+        rLHS.maFontFamily==rRHS.maFontFamily &&
+        rLHS.mnFontSize==rRHS.mnFontSize &&
+        rLHS.meFontStyle==rRHS.meFontStyle &&
+        rLHS.meFontVariant==rRHS.meFontVariant &&
+        rLHS.mnFontWeight==rRHS.mnFontWeight &&
+        rLHS.meTextAnchor==rRHS.meTextAnchor &&
+        rLHS.meTextDisplayAlign==rRHS.meTextDisplayAlign &&
+        rLHS.mnTextLineIncrement==rRHS.mnTextLineIncrement &&
+        rLHS.maCurrentColor==rRHS.maCurrentColor &&
+        rLHS.mbVisibility==rRHS.mbVisibility &&
+        rLHS.meFillType==rRHS.meFillType &&
+        rLHS.mnFillOpacity==rRHS.mnFillOpacity &&
+        rLHS.meStrokeType==rRHS.meStrokeType &&
+        rLHS.mnStrokeOpacity==rRHS.mnStrokeOpacity &&
+        rLHS.meViewportFillType==rRHS.meViewportFillType &&
+        rLHS.mnViewportFillOpacity==rRHS.mnViewportFillOpacity &&
+        rLHS.maFillColor==rRHS.maFillColor &&
+        rLHS.maFillGradient==rRHS.maFillGradient &&
+        rLHS.meFillRule==rRHS.meFillRule &&
+        rLHS.maStrokeColor==rRHS.maStrokeColor &&
+        rLHS.maStrokeGradient==rRHS.maStrokeGradient &&
+        rLHS.maDashArray==rRHS.maDashArray &&
+        rLHS.mnDashOffset==rRHS.mnDashOffset &&
+        rLHS.meLineCap==rRHS.meLineCap &&
+        rLHS.meLineJoin==rRHS.meLineJoin &&
+        rLHS.mnMiterLimit==rRHS.mnMiterLimit &&
+        rLHS.mnStrokeWidth==rRHS.mnStrokeWidth &&
+        rLHS.maViewportFillColor==rRHS.maViewportFillColor &&
+        rLHS.maViewportFillGradient==rRHS.maViewportFillGradient;
+}
+
+struct StateHash
+{
+    size_t operator()(const State& rState ) const
+    {
+        return size_t(rState.maCTM.get( 0, 0 ))
+            ^  size_t(rState.maCTM.get( 1, 0 ))
+            ^  size_t(rState.maCTM.get( 0, 1 ))
+            ^  size_t(rState.maCTM.get( 1, 1 ))
+            ^  size_t(rState.maCTM.get( 0, 2 ))
+            ^  size_t(rState.maCTM.get( 1, 2 ))
+            ^  size_t(rState.maViewport.getWidth())
+            ^  size_t(rState.maViewport.getHeight())
+            ^  size_t(rState.maViewBox.getWidth())
+            ^  size_t(rState.maViewBox.getHeight())
+            ^  size_t(rState.maFontFamily.hashCode())
+            ^  size_t(rState.mnFontSize)
+            ^  size_t(rState.meFontStyle)
+            ^  size_t(rState.meFontVariant)
+            ^  size_t(rState.mnFontWeight)
+            ^  size_t(rState.meTextAnchor)
+            ^  size_t(rState.meTextDisplayAlign)
+            ^  size_t(rState.mnTextLineIncrement)
+            ^  size_t(rState.mbVisibility)
+            ^  size_t(rState.meFillType)
+            ^  size_t(rState.mnFillOpacity)
+            ^  size_t(rState.meStrokeType)
+            ^  size_t(rState.mnStrokeOpacity)
+            ^  size_t(rState.meViewportFillType)
+            ^  size_t(rState.mnViewportFillOpacity)
+            ^  size_t(rState.maFillColor.a)
+            ^  size_t(rState.maFillColor.r)
+            ^  size_t(rState.maFillColor.g)
+            ^  size_t(rState.maFillColor.b)
+            ^  size_t(rState.maFillGradient.maStops.size())
+            ^  size_t(rState.meFillRule)
+            ^  size_t(rState.maStrokeColor.a)
+            ^  size_t(rState.maStrokeColor.r)
+            ^  size_t(rState.maStrokeColor.g)
+            ^  size_t(rState.maStrokeColor.b)
+            ^  size_t(rState.maStrokeGradient.maStops.size())
+            ^  size_t(rState.maDashArray.size())
+            ^  size_t(rState.mnDashOffset)
+            ^  size_t(rState.meLineCap)
+            ^  size_t(rState.meLineJoin)
+            ^  size_t(rState.mnMiterLimit)
+            ^  size_t(rState.mnStrokeWidth)
+            ^  size_t(rState.maViewportFillColor.a)
+            ^  size_t(rState.maViewportFillColor.r)
+            ^  size_t(rState.maViewportFillColor.g)
+            ^  size_t(rState.maViewportFillColor.b)
+            ^  size_t(rState.maViewportFillGradient.maStops.size());
+    }
+};
+
+typedef std::hash_set<State, StateHash> StatePool;
+typedef std::hash_map<sal_Int32, State> StateMap;
+
+} // namespace svgi
+
+#endif
diff --git a/filter/source/svg/makefile.mk b/filter/source/svg/makefile.mk

... etc. - the rest is truncated


More information about the ooo-build-commit mailing list