[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