ooo-build r12683 - in branches/ooo-build-2-4-1: . patches/src680



Author: thorstenb
Date: Wed May 28 00:34:47 2008
New Revision: 12683
URL: http://svn.gnome.org/viewvc/ooo-build?rev=12683&view=rev

Log:
	* patches/src680/svg-import-filter-gfxfilter.diff: first draft of
	a svg graphics importer (imports a metafile, not a standalone
	document)



Added:
   branches/ooo-build-2-4-1/patches/src680/svg-import-filter-gfxfilter.diff
Modified:
   branches/ooo-build-2-4-1/ChangeLog

Added: branches/ooo-build-2-4-1/patches/src680/svg-import-filter-gfxfilter.diff
==============================================================================
--- (empty file)
+++ branches/ooo-build-2-4-1/patches/src680/svg-import-filter-gfxfilter.diff	Wed May 28 00:34:47 2008
@@ -0,0 +1,809 @@
+diff -ur filter_orig/source/config/fragments/internalgraphicfilters/svg_Export.xcu filter/source/config/fragments/internalgraphicfilters/svg_Export.xcu
+--- filter_orig/source/config/fragments/internalgraphicfilters/svg_Export.xcu	2005-07-20 13:19:27.000000000 +0200
++++ filter/source/config/fragments/internalgraphicfilters/svg_Export.xcu	2008-05-28 02:30:15.000000000 +0200
+@@ -8,3 +8,13 @@
+ 		</prop>
+ 		<prop oor:name="Flags"><value>EXPORT</value></prop>
+ 	</node>
++	<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>
+Only in filter/source/config/fragments/internalgraphicfilters: svg_Export.xcu~
+diff -ur filter_orig/source/svg/exports.map filter/source/svg/exports.map
+--- filter_orig/source/svg/exports.map	2008-05-28 02:27:09.000000000 +0200
++++ filter/source/svg/exports.map	2008-05-27 23:32:34.000000000 +0200
+@@ -3,6 +3,7 @@
+                 component_getImplementationEnvironment;
+                 component_getFactory;
+                 component_writeInfo;
++                GraphicImport;
+ 
+         local:
+                 *;
+diff -ur filter_orig/source/svg/makefile.mk filter/source/svg/makefile.mk
+--- filter_orig/source/svg/makefile.mk	2008-05-28 02:27:09.000000000 +0200
++++ filter/source/svg/makefile.mk	2008-05-28 02:16:23.000000000 +0200
+@@ -78,6 +78,7 @@
+ 	$(UNOTOOLSLIB)		\
+ 	$(TOOLSLIB)			\
+ 	$(COMPHELPERLIB)	\
++	$(SVTOOLLIB)	    \
+ 	$(CPPUHELPERLIB)	\
+ 	$(CPPULIB)			\
+ 	$(SALLIB)			\
+diff -ur filter_orig/source/svg/svgfilter.cxx filter/source/svg/svgfilter.cxx
+--- filter_orig/source/svg/svgfilter.cxx	2008-05-28 02:27:09.000000000 +0200
++++ filter/source/svg/svgfilter.cxx	2008-05-27 23:32:59.000000000 +0200
+@@ -243,3 +243,11 @@
+ {
+     return SVGFilter_getSupportedServiceNames();
+ }
++
++// -----------------------------------------------------------------------------
++
++class FilterConfigItem;
++extern "C" BOOL __LOADONCALLAPI GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem*, BOOL )
++{
++	return importSvg( rStream, rGraphic );
++}
+diff -ur filter_orig/source/svg/svgfilter.hxx filter/source/svg/svgfilter.hxx
+--- filter_orig/source/svg/svgfilter.hxx	2008-05-28 02:27:09.000000000 +0200
++++ filter/source/svg/svgfilter.hxx	2008-05-27 23:03:42.000000000 +0200
+@@ -328,4 +328,11 @@
+ 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 -ur filter_orig/source/svg/svgreader.cxx filter/source/svg/svgreader.cxx
+--- filter_orig/source/svg/svgreader.cxx	2008-05-28 02:27:09.000000000 +0200
++++ filter/source/svg/svgreader.cxx	2008-05-28 02:05:51.000000000 +0200
+@@ -7,6 +7,7 @@
+  *      Thorsten Behrens <tbehrens 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 2.1.
+@@ -41,6 +42,15 @@
+ #include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
+ #include <com/sun/star/xml/dom/NodeType.hpp>
+ 
++#include <comphelper/processfactory.hxx>
++#include <basegfx/polygon/b2dpolypolygontools.hxx>
++#include <unotools/streamwrap.hxx>
++#include <vcl/graph.hxx>
++#include <vcl/virdev.hxx>
++#include <vcl/gradient.hxx>
++#include <svx/impgrf.hxx>
++#include <tools/zcodec.hxx>
++
+ #include <boost/bind.hpp>
+ #include <hash_set>
+ #include <map>
+@@ -432,6 +442,9 @@
+         // 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 )
+         {
+@@ -1896,4 +1909,690 @@
+     return sal_True;
+ }
+ 
++///////////////////////////////////////////////////////////////
++
++struct ShapeRenderingVisitor
++{
++    ShapeRenderingVisitor(StatePool&    rStatePool,
++                          StateMap&     rStateMap,
++                          OutputDevice& rOutDev,
++                          const std::vector< Gradient >& rGradientVector,
++                          const std::vector< GradientStop >& rGradientStopVector) :
++        mrStates(rStatePool),
++        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());
++        maCurrState = pOrigState != mrStateMap.end() ? pOrigState->second : maParentStates.back();
++
++        OSL_TRACE("the CTM is now #2: %f %f %f %f %f %f", 
++                  maCurrState.maCTM.get(0,0),
++                  maCurrState.maCTM.get(0,1),
++                  maCurrState.maCTM.get(0,2),
++                  maCurrState.maCTM.get(1,0),
++                  maCurrState.maCTM.get(1,1),
++                  maCurrState.maCTM.get(1,2));
++        
++        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);
++                            break;
++                        case XML_X2:
++                            x2 = convLength(sAttributeValue);
++                            break;
++                        case XML_Y1:
++                            y1 = convLength(sAttributeValue);
++                            break;
++                        case XML_Y2:
++                            y2 = convLength(sAttributeValue);
++                            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 )
++                    aPoly.setClosed(true);
++
++				// assuming the coordinates are in pts since they are interpreted as such by different renderers
++				basegfx::B2DHomMatrix aScale;
++				aScale.scale(2540.0f/72.0f,2540.0f/72.0f);
++				aPoly.transform(aScale);
++
++                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);
++                            break;
++                        case XML_Y:
++                            y = convLength(sAttributeValue);
++                            break;
++                        case XML_WIDTH:
++                            width = convLength(sAttributeValue);
++                            break;
++                        case XML_HEIGHT:
++                            height = convLength(sAttributeValue);
++                            break;
++                        case XML_RX:
++                            rx = convLength(sAttributeValue);
++                            bRxSeen=true;
++                            break;
++                        case XML_RY:
++                            ry = convLength(sAttributeValue);
++                            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);
++
++				// assuming the coordinates are in pts since they are interpreted as such by different renderers
++				basegfx::B2DHomMatrix aScale;
++				aScale.scale(2540.0f/72.0f,2540.0f/72.0f);
++				aPoly.transform(aScale);
++				
++                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);
++                            break;
++                        case XML_CY:
++                            cy = convLength(sAttributeValue);
++                            break;
++                        case XML_R:
++                            r = convLength(sAttributeValue);
++                        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);
++                            break;
++                        case XML_CY:
++                            cy = convLength(sAttributeValue);
++                            break;
++                        case XML_RX:
++                            rx = convLength(sAttributeValue);
++							break;
++						case XML_RY:
++							ry = convLength(sAttributeValue);
++                        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);
++                            break;
++                        case XML_Y:
++                            y = convLength(sAttributeValue);
++                            break;
++                        case XML_WIDTH:
++                            width = convLength(sAttributeValue);
++                            break;
++                        case XML_HEIGHT:
++                            height = convLength(sAttributeValue);
++                            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;
++
++                    SvMemoryStream aSrc(const_cast<char*>(sLinkValue.c_str()), 
++                                        sLinkValue.length(), STREAM_READ);
++                    USHORT nFormat = GRFILTER_FORMAT_DONTKNOW;
++                    USHORT pDeterminedFormat = GRFILTER_FORMAT_DONTKNOW;
++                    GetGrfFilter()->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);
++                                        GetGrfFilter()->ImportGraphic( aGraphic, String(), *pDest ,nFormat,&pDeterminedFormat );
++                                    }
++                                }
++                                delete pDest;
++                            }
++                        }
++                    }
++                    // -> blatant copy from svx/source/xml/xmlgrhlp.cxx
++
++                    aGraphic.Draw(&mrOutDev,
++                                  Point(basegfx::fround(x),
++                                        basegfx::fround(y)),
++                                  Size(basegfx::fround(width),
++                                       basegfx::fround(height)));
++                }
++                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);
++                            break;
++                        case XML_Y:
++                            y = convLength(sAttributeValue);
++                            break;
++                        case XML_WIDTH:
++                            width = convLength(sAttributeValue);
++                            break;
++                        case XML_HEIGHT:
++                            height = convLength(sAttributeValue);
++                            break;
++                        default:
++                            // skip
++                            break;
++                    }
++                }
++
++                // actually export text
++                Font aFont(maCurrState.maFontFamily, 
++                           Size(0,
++                                basegfx::fround(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));
++                }
++
++                mrOutDev.SetFont(aFont);
++                mrOutDev.DrawText(Point(basegfx::fround(x),
++                                        basegfx::fround(y)),
++                                  sText.makeStringAndClear());
++                break;
++            }
++        }
++    }
++
++    void push()
++    {
++        maParentStates.push_back(maCurrState);
++    }
++
++    void pop()
++    {
++        maParentStates.pop_back();
++    }
++	
++    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)
++        std::vector<basegfx::B2DPolyPolygon> aPolys(1,rPoly);
++        State aState = maCurrState;
++		
++        OSL_TRACE("the CTM is now #2: %f %f %f %f %f %f", 
++                  maCurrState.maCTM.get(0,0),
++                  maCurrState.maCTM.get(0,1),
++                  maCurrState.maCTM.get(0,2),
++                  maCurrState.maCTM.get(1,0),
++                  maCurrState.maCTM.get(1,1),
++                  maCurrState.maCTM.get(1,2));        
++
++		if( aState.maDashArray.size() ||
++            aState.mnStrokeWidth != 1.0 )
++        {
++            // vcl thick lines are severly borked - generate filled polygon instead
++            aPolys.clear();
++            for( sal_uInt32 i=0; i<rPoly.count(); ++i )
++            {                
++                aPolys.push_back(
++                    basegfx::tools::createAreaGeometryForPolygon(
++                        rPoly.getB2DPolygon(i),
++                        aState.mnStrokeWidth/2.0,
++                        aState.meLineJoin));
++                // TODO(F2): line ends
++            }
++
++            State aEmulatedStrokeState( aState );
++            aEmulatedStrokeState.meFillType = aState.meStrokeType;
++            aEmulatedStrokeState.mnFillOpacity = aState.mnStrokeOpacity;
++            aEmulatedStrokeState.maFillColor = aState.maStrokeColor;
++            aEmulatedStrokeState.maFillGradient = aState.maStrokeGradient;
++            aEmulatedStrokeState.meFillRule = EVEN_ODD;
++            aEmulatedStrokeState.meStrokeType = NONE;
++
++            aState = aEmulatedStrokeState;
++        }
++
++        std::for_each(aPolys.begin(),aPolys.end(),
++                      boost::bind(&basegfx::B2DPolyPolygon::transform,
++                                  _1,boost::cref(aState.maCTM)));
++
++        // 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;
++
++                // modulate gradient opacity with overall fill opacity
++                aTransparencyGradient.SetEndColor(
++                    basegfx::fround(mrGradientStopVector[
++                                        aState.maFillGradient.maStops[0]].maStopColor.a*
++                                    aState.mnFillOpacity*100.0));
++                aTransparencyGradient.SetStartColor(
++                    basegfx::fround(mrGradientStopVector[
++                                        aState.maFillGradient.maStops[1]].maStopColor.a*
++                                    aState.mnFillOpacity*100.0));
++
++                VirtualDevice	aVDev;
++                GDIMetaFile		aMtf;
++
++                aVDev.EnableOutput( FALSE );
++                aMtf.Record( &aVDev );
++                basegfx::B2DRange aBounds;
++                // TODO(P3): limit bounds to actual polygon bbox
++                for( sal_uInt32 i=0; i<aPolys.size(); ++i )
++                {
++                    aBounds.expand(basegfx::tools::getRange(aPolys[i]));
++                    aVDev.DrawGradient(::PolyPolygon(aPolys[i]),aGradient);
++                }
++
++                aMtf.Stop();
++                aMtf.WindStart();
++                aMtf.SetPrefMapMode( MAP_100TH_MM );
++                aMtf.SetPrefSize( Size(basegfx::fround(aBounds.getMaxX()),
++                                       basegfx::fround(aBounds.getMaxY())) );
++
++                mrOutDev.DrawTransparent(aMtf,
++                                         Point(),
++                                         aMtf.GetPrefSize(),
++                                         aTransparencyGradient);
++            }
++            else
++            {
++                for( sal_uInt32 i=0; i<aPolys.size(); ++i )
++                    mrOutDev.DrawGradient(::PolyPolygon(aPolys[i]),aGradient);
++            }
++        }
++        else
++        {
++            if( aState.meFillType == NONE )
++                mrOutDev.SetFillColor();
++            else
++                mrOutDev.SetFillColor(getVclColor(aState.maFillColor));
++
++            if( aState.meStrokeType == NONE )
++                mrOutDev.SetLineColor();
++            else
++                mrOutDev.SetLineColor(getVclColor(aState.maStrokeColor));
++
++            for( sal_uInt32 i=0; i<aPolys.size(); ++i )
++                if( maCurrState.mnFillOpacity != 1.0 )
++                    mrOutDev.DrawTransparent(::PolyPolygon(aPolys[i]),
++                                             basegfx::fround(
++                                                 maCurrState.mnFillOpacity*100.0));
++                else
++                    mrOutDev.DrawPolyPolygon(::PolyPolygon(aPolys[i]));
++        }
++    }
++
++    State                                      maCurrState;
++    std::vector<State>                         maParentStates;
++    StatePool&                                 mrStates;
++    StateMap&                                  mrStateMap;
++    OutputDevice&                               mrOutDev;
++    const std::vector< Gradient >&             mrGradientVector;
++    const std::vector< GradientStop >&         mrGradientStopVector;
++};
++
++/// Write out shapes from DOM tree
++static void renderShapes( StatePool&                                        rStatePool,
++                          StateMap&                                         rStateMap,
++                          const uno::Reference<xml::dom::XElement>          xElem,
++                          OutputDevice&                                     rOutDev,
++                          const std::vector< Gradient >&                    rGradientVector,
++                          const std::vector< GradientStop >&                rGradientStopVector)
++{
++    ShapeRenderingVisitor aVisitor(rStatePool,rStateMap,rOutDev,rGradientVector,rGradientStopVector);
++    visitElements(aVisitor, xElem);
++}
++
+ } // 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::StatePool aStatePool;
++    svgi::StateMap  aStateMap;
++    svgi::AnnotatingVisitor aVisitor(aStatePool,
++                                     aStateMap,
++                                     uno::Reference<xml::sax::XDocumentHandler>());
++    svgi::visitElements(aVisitor, xDocElem);
++
++#ifdef VERBOSE
++    dumpTree(xDocElem);
++#endif
++
++    // render all shapes to mtf
++    svgi::renderShapes(aStatePool,
++                       aStateMap,
++                       xDocElem,
++                       aVDev,
++                       aVisitor.maGradientVector,
++                       aVisitor.maGradientStopVector);
++
++    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( basegfx::fround(svgi::convLength(xDocElem->getAttribute(USTR("width")))), 
++                            basegfx::fround(svgi::convLength(xDocElem->getAttribute(USTR("height")))) ));
++
++
++    rGraphic = aMtf;
++    
++    return sal_True;
++}
++
++
+diff -ur filter_orig/source/svg/test/makefile.mk filter/source/svg/test/makefile.mk
+--- filter_orig/source/svg/test/makefile.mk	2008-05-28 02:27:09.000000000 +0200
++++ filter/source/svg/test/makefile.mk	2008-05-28 02:18:07.000000000 +0200
+@@ -40,6 +40,7 @@
+ 	$(UNOTOOLSLIB)		\
+ 	$(TOOLSLIB)			\
+ 	$(COMPHELPERLIB)	\
++	$(SVTOOLLIB)	    \
+ 	$(CPPUHELPERLIB)	\
+ 	$(CPPULIB)			\
+ 	$(SALLIB)			\



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]