ooo-build r12683 - in branches/ooo-build-2-4-1: . patches/src680
- From: thorstenb svn gnome org
- To: svn-commits-list gnome org
- Subject: ooo-build r12683 - in branches/ooo-build-2-4-1: . patches/src680
- Date: Wed, 28 May 2008 00:34:47 +0000 (UTC)
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]