summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Module_ooo.mk3
-rwxr-xr-xRepository.mk1
-rw-r--r--basegfx/inc/basegfx/color/bcolor.hxx6
-rw-r--r--basegfx/inc/basegfx/color/bcolormodifier.hxx10
-rw-r--r--basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx4
-rw-r--r--basegfx/inc/basegfx/polygon/b2dpolygon.hxx4
-rw-r--r--basegfx/inc/basegfx/polygon/b2dpolypolygon.hxx4
-rw-r--r--basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx9
-rw-r--r--basegfx/source/color/bcolormodifier.cxx9
-rw-r--r--basegfx/source/polygon/b2dpolypolygon.cxx12
-rw-r--r--basegfx/source/polygon/b2dpolypolygoncutter.cxx96
-rw-r--r--basegfx/source/polygon/b2dsvgpolypolygon.cxx13
-rw-r--r--cppcanvas/source/mtfrenderer/implrenderer.cxx27
-rw-r--r--cppcanvas/source/mtfrenderer/makefile.mk1
-rw-r--r--cppcanvas/source/mtfrenderer/rendergraphicaction.cxx201
-rw-r--r--cppcanvas/source/mtfrenderer/rendergraphicaction.hxx77
-rw-r--r--cppcanvas/source/mtfrenderer/transparencygroupaction.cxx1
-rwxr-xr-xdrawinglayer/Library_drawinglayer.mk10
-rwxr-xr-xdrawinglayer/Package_inc.mk11
-rw-r--r--drawinglayer/drawinglayer.component28
-rw-r--r--drawinglayer/inc/drawinglayer/primitive2d/baseprimitive2d.hxx4
-rw-r--r--drawinglayer/inc/drawinglayer/primitive2d/cropprimitive2d.hxx105
-rw-r--r--drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx7
-rw-r--r--drawinglayer/inc/drawinglayer/primitive2d/patternfillprimitive2d.hxx84
-rw-r--r--drawinglayer/inc/drawinglayer/primitive2d/rendergraphicprimitive2d.hxx95
-rw-r--r--drawinglayer/inc/drawinglayer/primitive2d/svggradientprimitive2d.hxx468
-rw-r--r--drawinglayer/inc/drawinglayer/primitive2d/textbreakuphelper.hxx91
-rw-r--r--drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx6
-rw-r--r--drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx6
-rw-r--r--drawinglayer/inc/drawinglayer/processor2d/canvasprocessor.hxx2
-rw-r--r--drawinglayer/inc/drawinglayer/processor2d/contourextractor2d.hxx4
-rw-r--r--drawinglayer/inc/drawinglayer/processor2d/linegeometryextractor2d.hxx9
-rw-r--r--drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx2
-rw-r--r--drawinglayer/inc/drawinglayer/processor3d/shadow3dextractor.hxx11
-rw-r--r--drawinglayer/inc/drawinglayer/tools/converters.hxx49
-rw-r--r--drawinglayer/source/drawinglayeruno/drawinglayeruno.cxx95
-rw-r--r--drawinglayer/source/drawinglayeruno/xprimitive2drenderer.cxx223
-rw-r--r--drawinglayer/source/primitive2d/baseprimitive2d.cxx21
-rw-r--r--drawinglayer/source/primitive2d/cropprimitive2d.cxx202
-rw-r--r--drawinglayer/source/primitive2d/graphicprimitive2d.cxx165
-rw-r--r--drawinglayer/source/primitive2d/metafileprimitive2d.cxx28
-rw-r--r--drawinglayer/source/primitive2d/patternfillprimitive2d.cxx158
-rw-r--r--drawinglayer/source/primitive2d/rendergraphicprimitive2d.cxx92
-rw-r--r--drawinglayer/source/primitive2d/svggradientprimitive2d.cxx1249
-rw-r--r--drawinglayer/source/primitive2d/textbreakuphelper.cxx294
-rw-r--r--drawinglayer/source/processor2d/hittestprocessor2d.cxx1
-rw-r--r--drawinglayer/source/processor2d/linegeometryextractor2d.cxx1
-rw-r--r--drawinglayer/source/processor2d/textaspolygonextractor2d.cxx1
-rw-r--r--drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx10
-rw-r--r--drawinglayer/source/processor2d/vclpixelprocessor2d.cxx7
-rw-r--r--drawinglayer/source/processor2d/vclprocessor2d.cxx71
-rw-r--r--drawinglayer/source/processor3d/shadow3dextractor.cxx27
-rw-r--r--drawinglayer/source/tools/converters.cxx143
-rw-r--r--editeng/inc/editeng/unoprnms.hxx1
-rw-r--r--filter/source/flash/swfwriter1.cxx14
-rw-r--r--filter/source/graphicfilter/eos2met/eos2met.cxx20
-rw-r--r--filter/source/graphicfilter/epict/epict.cxx13
-rw-r--r--filter/source/graphicfilter/eps/eps.cxx18
-rw-r--r--filter/source/svg/svgwriter.cxx18
-rw-r--r--filter/source/svg/svgwriter.hxx1
-rw-r--r--offapi/com/sun/star/graphic/Primitive2DTools.idl43
-rw-r--r--offapi/com/sun/star/graphic/SvgTools.idl44
-rw-r--r--offapi/com/sun/star/graphic/XPrimitive2DRenderer.idl80
-rw-r--r--offapi/com/sun/star/graphic/XSvgParser.idl50
-rwxr-xr-xoffapi/com/sun/star/graphic/makefile.mk6
-rw-r--r--postprocess/packcomponents/makefile.mk2
-rw-r--r--postprocess/prj/build.lst2
-rwxr-xr-xscp2/source/ooo/file_library_ooo.scp1
-rw-r--r--scp2/source/ooo/module_hidden_ooo.scp1
-rwxr-xr-xsd/source/ui/view/drviews2.cxx29
-rwxr-xr-xsd/source/ui/view/drviews6.cxx2
-rwxr-xr-xsd/source/ui/view/drviews7.cxx9
-rwxr-xr-xsd/source/ui/view/drviewsc.cxx19
-rwxr-xr-xsd/source/ui/view/drviewsj.cxx19
-rwxr-xr-xsd/source/ui/view/sdview.cxx11
-rwxr-xr-xsd/source/ui/view/sdview3.cxx1
-rwxr-xr-xsd/source/ui/view/sdview4.cxx4
-rw-r--r--solenv/inc/libs.mk2
-rw-r--r--splitbuild/framework.lst2
-rw-r--r--svgio/Library_svgio.mk93
-rw-r--r--svgio/Makefile32
-rw-r--r--svgio/Module_svgio.mk29
-rw-r--r--svgio/Package_inc.mk53
-rw-r--r--svgio/inc/makefile.mk41
-rw-r--r--svgio/inc/pch/precompiled_svgio.cxx23
-rw-r--r--svgio/inc/pch/precompiled_svgio.hxx26
-rw-r--r--svgio/inc/svgio/svgiodllapi.h33
-rw-r--r--svgio/inc/svgio/svgreader/svgcharacternode.hxx184
-rw-r--r--svgio/inc/svgio/svgreader/svgcirclenode.hxx80
-rwxr-xr-xsvgio/inc/svgio/svgreader/svgclippathnode.hxx73
-rw-r--r--svgio/inc/svgio/svgreader/svgdocument.hxx88
-rw-r--r--svgio/inc/svgio/svgreader/svgdocumenthandler.hxx75
-rw-r--r--svgio/inc/svgio/svgreader/svgellipsenode.hxx85
-rw-r--r--svgio/inc/svgio/svgreader/svggnode.hxx66
-rw-r--r--svgio/inc/svgio/svgreader/svggradientnode.hxx137
-rw-r--r--svgio/inc/svgio/svgreader/svggradientstopnode.hxx64
-rw-r--r--svgio/inc/svgio/svgreader/svgimagenode.hxx99
-rw-r--r--svgio/inc/svgio/svgreader/svglinenode.hxx85
-rwxr-xr-xsvgio/inc/svgio/svgreader/svgmarkernode.hxx123
-rwxr-xr-xsvgio/inc/svgio/svgreader/svgmasknode.hxx98
-rw-r--r--svgio/inc/svgio/svgreader/svgnode.hxx127
-rw-r--r--svgio/inc/svgio/svgreader/svgpaint.hxx65
-rw-r--r--svgio/inc/svgio/svgreader/svgpathnode.hxx75
-rwxr-xr-xsvgio/inc/svgio/svgreader/svgpatternnode.hxx126
-rw-r--r--svgio/inc/svgio/svgreader/svgpolynode.hxx78
-rw-r--r--svgio/inc/svgio/svgreader/svgrectnode.hxx95
-rw-r--r--svgio/inc/svgio/svgreader/svgstyleattributes.hxx411
-rw-r--r--svgio/inc/svgio/svgreader/svgstylenode.hxx64
-rw-r--r--svgio/inc/svgio/svgreader/svgsvgnode.hxx97
-rw-r--r--svgio/inc/svgio/svgreader/svgsymbolnode.hxx68
-rw-r--r--svgio/inc/svgio/svgreader/svgtextnode.hxx80
-rw-r--r--svgio/inc/svgio/svgreader/svgtextpathnode.hxx86
-rw-r--r--svgio/inc/svgio/svgreader/svgtoken.hxx194
-rw-r--r--svgio/inc/svgio/svgreader/svgtools.hxx228
-rw-r--r--svgio/inc/svgio/svgreader/svgtrefnode.hxx65
-rw-r--r--svgio/inc/svgio/svgreader/svgtspannode.hxx64
-rw-r--r--svgio/inc/svgio/svgreader/svgusenode.hxx89
-rw-r--r--svgio/prj/build.lst2
-rwxr-xr-xsvgio/prj/d.lst0
-rw-r--r--svgio/prj/makefile.mk40
-rw-r--r--svgio/source/svgreader/svgcharacternode.cxx725
-rw-r--r--svgio/source/svgreader/svgcirclenode.cxx154
-rwxr-xr-xsvgio/source/svgreader/svgclippathnode.cxx184
-rw-r--r--svgio/source/svgreader/svgdocument.cxx121
-rw-r--r--svgio/source/svgreader/svgdocumenthandler.cxx518
-rw-r--r--svgio/source/svgreader/svgellipsenode.cxx169
-rw-r--r--svgio/source/svgreader/svggnode.cxx114
-rw-r--r--svgio/source/svgreader/svggradientnode.cxx507
-rw-r--r--svgio/source/svgreader/svggradientstopnode.cxx87
-rw-r--r--svgio/source/svgreader/svgimagenode.cxx353
-rw-r--r--svgio/source/svgreader/svglinenode.cxx165
-rwxr-xr-xsvgio/source/svgreader/svgmarkernode.cxx212
-rwxr-xr-xsvgio/source/svgreader/svgmasknode.cxx317
-rw-r--r--svgio/source/svgreader/svgnode.cxx288
-rw-r--r--svgio/source/svgreader/svgpaint.cxx37
-rw-r--r--svgio/source/svgreader/svgpathnode.cxx132
-rwxr-xr-xsvgio/source/svgreader/svgpatternnode.cxx462
-rw-r--r--svgio/source/svgreader/svgpolynode.cxx128
-rw-r--r--svgio/source/svgreader/svgrectnode.cxx226
-rw-r--r--svgio/source/svgreader/svgstyleattributes.cxx2435
-rw-r--r--svgio/source/svgreader/svgstylenode.cxx115
-rw-r--r--svgio/source/svgreader/svgsvgnode.cxx395
-rw-r--r--svgio/source/svgreader/svgsymbolnode.cxx93
-rw-r--r--svgio/source/svgreader/svgtextnode.cxx273
-rw-r--r--svgio/source/svgreader/svgtextpathnode.cxx510
-rw-r--r--svgio/source/svgreader/svgtoken.cxx321
-rw-r--r--svgio/source/svgreader/svgtools.cxx1581
-rw-r--r--svgio/source/svgreader/svgtrefnode.cxx90
-rw-r--r--svgio/source/svgreader/svgtspannode.cxx77
-rw-r--r--svgio/source/svgreader/svgusenode.cxx197
-rw-r--r--svgio/source/svguno/svguno.cxx95
-rw-r--r--svgio/source/svguno/xsvgparser.cxx194
-rw-r--r--svgio/svgio.component28
-rw-r--r--svtools/inc/svtools/grfmgr.hxx4
-rw-r--r--svtools/source/filter/filter.cxx88
-rw-r--r--svtools/source/filter/wmf/emfwr.cxx21
-rw-r--r--svtools/source/filter/wmf/wmfwr.cxx22
-rw-r--r--svtools/source/graphic/descriptor.cxx5
-rw-r--r--svtools/source/graphic/grfcache.cxx54
-rw-r--r--svtools/source/graphic/grfmgr.cxx4
-rw-r--r--svtools/source/graphic/grfmgr2.cxx2
-rw-r--r--svtools/source/graphic/provider.cxx25
-rw-r--r--svx/inc/svx/sdr/contact/objectcontacttools.hxx3
-rw-r--r--svx/inc/svx/svdograf.hxx7
-rw-r--r--svx/inc/svx/svdstr.hrc9
-rw-r--r--svx/inc/svx/svdxcgv.hxx4
-rw-r--r--svx/inc/svx/unoshprp.hxx14
-rw-r--r--svx/source/dialog/_bmpmask.cxx3
-rw-r--r--svx/source/sdr/contact/viewcontactofgraphic.cxx11
-rw-r--r--svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx8
-rw-r--r--svx/source/svdraw/svddrgmt.cxx13
-rw-r--r--svx/source/svdraw/svdedtv.cxx17
-rw-r--r--svx/source/svdraw/svdedtv2.cxx29
-rw-r--r--svx/source/svdraw/svdfmtf.cxx21
-rw-r--r--svx/source/svdraw/svdfmtf.hxx1
-rw-r--r--svx/source/svdraw/svdobj.cxx6
-rw-r--r--svx/source/svdraw/svdograf.cxx230
-rw-r--r--svx/source/svdraw/svdorect.cxx5
-rw-r--r--svx/source/svdraw/svdstr.src16
-rw-r--r--svx/source/svdraw/svdxcgv.cxx46
-rw-r--r--svx/source/tbxctrls/grafctrl.cxx3
-rw-r--r--svx/source/unodraw/unoshap2.cxx14
-rw-r--r--svx/source/xml/xmlgrhlp.cxx4
-rw-r--r--sw/inc/cmdid.h2
-rw-r--r--sw/inc/ndgrf.hxx2
-rw-r--r--sw/inc/unoprnms.hxx5
-rw-r--r--sw/source/core/doc/notxtfrm.cxx103
-rwxr-xr-xsw/source/core/graphic/ndgrf.cxx41
-rwxr-xr-xsw/source/core/unocore/unoframe.cxx24
-rw-r--r--sw/source/core/unocore/unomap.cxx1
-rw-r--r--sw/source/core/unocore/unoprnms.cxx1
-rw-r--r--sw/source/ui/shells/grfsh.cxx7
-rwxr-xr-xvcl/Library_vcl.mk4
-rw-r--r--vcl/Package_inc.mk4
-rw-r--r--vcl/inc/impgraph.hxx22
-rwxr-xr-xvcl/inc/sallayout.hxx6
-rw-r--r--vcl/inc/vcl/gdimtf.hxx11
-rw-r--r--vcl/inc/vcl/graph.hxx9
-rw-r--r--vcl/inc/vcl/metaact.hxx43
-rw-r--r--vcl/inc/vcl/outdev.hxx6
-rw-r--r--vcl/inc/vcl/rendergraphic.hxx124
-rw-r--r--vcl/inc/vcl/rendergraphicrasterizer.hxx111
-rw-r--r--vcl/inc/vcl/svgdata.hxx82
-rw-r--r--vcl/inc/vcl/svgread.hxx80
-rw-r--r--vcl/source/gdi/gdimtf.cxx226
-rw-r--r--vcl/source/gdi/graph.cxx37
-rw-r--r--vcl/source/gdi/impgraph.cxx258
-rwxr-xr-xvcl/source/gdi/makefile.mk4
-rw-r--r--vcl/source/gdi/metaact.cxx86
-rw-r--r--vcl/source/gdi/outdev6.cxx23
-rw-r--r--vcl/source/gdi/pdfwriter_impl2.cxx12
-rw-r--r--vcl/source/gdi/print2.cxx28
-rw-r--r--vcl/source/gdi/rendergraphic.cxx240
-rw-r--r--vcl/source/gdi/rendergraphicrasterizer.cxx401
-rw-r--r--vcl/source/gdi/svgdata.cxx194
-rw-r--r--vcl/source/gdi/svgread.cxx127
-rw-r--r--vcl/util/makefile.mk2
-rw-r--r--xmloff/Library_xo.mk1
-rw-r--r--xmloff/Package_inc.mk1
-rw-r--r--xmloff/inc/xmloff/txtparae.hxx1
-rw-r--r--xmloff/inc/xmloff/xmlmultiimagehelper.hxx62
-rw-r--r--xmloff/source/core/xmlmultiimagehelper.cxx146
-rw-r--r--xmloff/source/draw/shapeexport2.cxx25
-rw-r--r--xmloff/source/draw/ximpshap.cxx93
-rw-r--r--xmloff/source/draw/ximpshap.hxx8
-rw-r--r--xmloff/source/text/XMLTextFrameContext.cxx66
-rw-r--r--xmloff/source/text/XMLTextFrameContext.hxx8
-rw-r--r--xmloff/source/text/txtparae.cxx29
228 files changed, 20325 insertions, 2744 deletions
diff --git a/Module_ooo.mk b/Module_ooo.mk
index 2913794a827f..da1306da015f 100644
--- a/Module_ooo.mk
+++ b/Module_ooo.mk
@@ -30,7 +30,8 @@ $(eval $(call gb_Module_Module,ooo))
$(eval $(call gb_Module_add_moduledirs,ooo,\
comphelper \
drawinglayer \
- editeng \
+ svgio \
+ editeng \
framework \
padmin \
sfx2 \
diff --git a/Repository.mk b/Repository.mk
index 656d457d0dc7..e3971a050424 100755
--- a/Repository.mk
+++ b/Repository.mk
@@ -52,6 +52,7 @@ $(eval $(call gb_Helper_register_libraries,OOOLIBS, \
cui \
desktop_detector \
drawinglayer \
+ svgio \
editeng \
fwe \
fwi \
diff --git a/basegfx/inc/basegfx/color/bcolor.hxx b/basegfx/inc/basegfx/color/bcolor.hxx
index 76596bdb4d5f..724fe057afab 100644
--- a/basegfx/inc/basegfx/color/bcolor.hxx
+++ b/basegfx/inc/basegfx/color/bcolor.hxx
@@ -151,9 +151,9 @@ namespace basegfx
// luminance
double luminance() const
{
- const double fRedWeight(77.0 / 256.0);
- const double fGreenWeight(151.0 / 256.0);
- const double fBlueWeight(28.0 / 256.0);
+ const double fRedWeight(77.0 / 256.0); // 0.30
+ const double fGreenWeight(151.0 / 256.0); // 0.59
+ const double fBlueWeight(28.0 / 256.0); // 0.11
return (mfX * fRedWeight + mfY * fGreenWeight + mfZ * fBlueWeight);
}
diff --git a/basegfx/inc/basegfx/color/bcolormodifier.hxx b/basegfx/inc/basegfx/color/bcolormodifier.hxx
index 55ed936985e2..afdc38c8b9a7 100644
--- a/basegfx/inc/basegfx/color/bcolormodifier.hxx
+++ b/basegfx/inc/basegfx/color/bcolormodifier.hxx
@@ -35,10 +35,12 @@ namespace basegfx
*/
enum BColorModifyMode
{
- BCOLORMODIFYMODE_REPLACE, // replace all color with local color
- BCOLORMODIFYMODE_INTERPOLATE, // interpolate color between given and local with local value
- BCOLORMODIFYMODE_GRAY, // convert color to gray
- BCOLORMODIFYMODE_BLACKANDWHITE // convert color to B&W, local value is treshhold
+ BCOLORMODIFYMODE_REPLACE, // replace all color with local color
+ BCOLORMODIFYMODE_INTERPOLATE, // interpolate color between given and local with local value
+ BCOLORMODIFYMODE_GRAY, // convert color to gray
+ BCOLORMODIFYMODE_BLACKANDWHITE, // convert color to B&W, local value is treshhold
+ BCOLORMODIFYMODE_INVERT, // invert color
+ BCOLORMODIFYMODE_LUMINANCE_TO_ALPHA // convert color to alpha value (used for Svg Mask)
};
/** Class to hold a color, value and mode for a color modification. Color modification is
diff --git a/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx b/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx
index 51b955eb2dfe..267cf570b7ce 100644
--- a/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx
+++ b/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx
@@ -149,7 +149,7 @@ namespace basegfx
double mfShearX;
public:
- B2DHomMatrixBufferedDecompose(const B2DHomMatrix& rB2DHomMatrix)
+ B2DHomMatrixBufferedDecompose(const B2DHomMatrix& rB2DHomMatrix = B2DHomMatrix())
: maScale(),
maTranslate(),
mfRotate(0.0),
@@ -201,7 +201,7 @@ namespace basegfx
}
public:
- B2DHomMatrixBufferedOnDemandDecompose(const B2DHomMatrix& rB2DHomMatrix)
+ B2DHomMatrixBufferedOnDemandDecompose(const B2DHomMatrix& rB2DHomMatrix = B2DHomMatrix())
: maB2DHomMatrix(rB2DHomMatrix),
maScale(),
maTranslate(),
diff --git a/basegfx/inc/basegfx/polygon/b2dpolygon.hxx b/basegfx/inc/basegfx/polygon/b2dpolygon.hxx
index 12b8b8d34ee6..fd988a382f86 100644
--- a/basegfx/inc/basegfx/polygon/b2dpolygon.hxx
+++ b/basegfx/inc/basegfx/polygon/b2dpolygon.hxx
@@ -263,6 +263,10 @@ namespace basegfx
B2DPoint* begin();
B2DPoint* end();
};
+
+ // typedef for a vector of B2DPolygons
+ typedef ::std::vector< B2DPolygon > B2DPolygonVector;
+
} // end of namespace basegfx
//////////////////////////////////////////////////////////////////////////////
diff --git a/basegfx/inc/basegfx/polygon/b2dpolypolygon.hxx b/basegfx/inc/basegfx/polygon/b2dpolypolygon.hxx
index 75d2685593c9..68b7a5090ead 100644
--- a/basegfx/inc/basegfx/polygon/b2dpolypolygon.hxx
+++ b/basegfx/inc/basegfx/polygon/b2dpolypolygon.hxx
@@ -128,6 +128,10 @@ namespace basegfx
B2DPolygon* begin();
B2DPolygon* end();
};
+
+ // typedef for a vector of B2DPolyPolygons
+ typedef ::std::vector< B2DPolyPolygon > B2DPolyPolygonVector;
+
} // end of namespace basegfx
#endif /* _BGFX_POLYGON_B2DPOLYPOLYGON_HXX */
diff --git a/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx b/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx
index 1be6c1950af9..d43af8c53e7a 100644
--- a/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx
+++ b/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx
@@ -65,6 +65,13 @@ namespace basegfx
// can be combined for logical polygon operations or polygon clipping.
B2DPolyPolygon stripDispensablePolygons(const B2DPolyPolygon& rCandidate, bool bKeepAboveZero = false);
+ // geometrically convert PolyPolygons which are proposed to use nonzero fill rule
+ // to a representation where evenodd paint will give the same result. To do this
+ // all intersections and self-intersections get solved (the polygons will be rearranged
+ // if needed). Then all polygons which are inside another one with the same orientation
+ // get deleted
+ B2DPolyPolygon createNonzeroConform(const B2DPolyPolygon& rCandidate);
+
// For convenience: The four basic operations OR, XOR, AND and DIFF for
// two PolyPolygons. These are combinations of the above methods. To not be forced
// to do evtl. already done preparations twice, You have to do the operations Yourself.
@@ -104,7 +111,7 @@ namespace basegfx
@return A single PolyPolygon containing the Or-merged result
*/
- B2DPolyPolygon mergeToSinglePolyPolygon(const std::vector< basegfx::B2DPolyPolygon >& rInput);
+ B2DPolyPolygon mergeToSinglePolyPolygon(const B2DPolyPolygonVector& rInput);
} // end of namespace tools
} // end of namespace basegfx
diff --git a/basegfx/source/color/bcolormodifier.cxx b/basegfx/source/color/bcolormodifier.cxx
index 50215f3f71a2..517fe417cae6 100644
--- a/basegfx/source/color/bcolormodifier.cxx
+++ b/basegfx/source/color/bcolormodifier.cxx
@@ -56,6 +56,15 @@ namespace basegfx
return ::basegfx::BColor(1.0, 1.0, 1.0);
}
}
+ case BCOLORMODIFYMODE_INVERT :
+ {
+ return ::basegfx::BColor(1.0 - aSourceColor.getRed(), 1.0 - aSourceColor.getGreen(), 1.0 - aSourceColor.getBlue());
+ }
+ case BCOLORMODIFYMODE_LUMINANCE_TO_ALPHA:
+ {
+ const double fAlpha(1.0 - ((aSourceColor.getRed() * 0.2125) + (aSourceColor.getGreen() * 0.7154) + (aSourceColor.getBlue() * 0.0721)));
+ return ::basegfx::BColor(fAlpha, fAlpha, fAlpha);
+ }
default : // BCOLORMODIFYMODE_REPLACE
{
return maBColor;
diff --git a/basegfx/source/polygon/b2dpolypolygon.cxx b/basegfx/source/polygon/b2dpolypolygon.cxx
index 94b8745871a5..28f8270ece65 100644
--- a/basegfx/source/polygon/b2dpolypolygon.cxx
+++ b/basegfx/source/polygon/b2dpolypolygon.cxx
@@ -38,9 +38,7 @@
class ImplB2DPolyPolygon
{
- typedef ::std::vector< basegfx::B2DPolygon > PolygonVector;
-
- PolygonVector maPolygons;
+ basegfx::B2DPolygonVector maPolygons;
public:
ImplB2DPolyPolygon() : maPolygons()
@@ -80,7 +78,7 @@ public:
if(nCount)
{
// add nCount copies of rPolygon
- PolygonVector::iterator aIndex(maPolygons.begin());
+ basegfx::B2DPolygonVector::iterator aIndex(maPolygons.begin());
aIndex += nIndex;
maPolygons.insert(aIndex, nCount, rPolygon);
}
@@ -94,7 +92,7 @@ public:
{
// add nCount polygons from rPolyPolygon
maPolygons.reserve(maPolygons.size() + nCount);
- PolygonVector::iterator aIndex(maPolygons.begin());
+ basegfx::B2DPolygonVector::iterator aIndex(maPolygons.begin());
aIndex += nIndex;
for(sal_uInt32 a(0L); a < nCount; a++)
@@ -110,9 +108,9 @@ public:
if(nCount)
{
// remove polygon data
- PolygonVector::iterator aStart(maPolygons.begin());
+ basegfx::B2DPolygonVector::iterator aStart(maPolygons.begin());
aStart += nIndex;
- const PolygonVector::iterator aEnd(aStart + nCount);
+ const basegfx::B2DPolygonVector::iterator aEnd(aStart + nCount);
maPolygons.erase(aStart, aEnd);
}
diff --git a/basegfx/source/polygon/b2dpolypolygoncutter.cxx b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
index 37a81ff334cb..849fc3811f0d 100644
--- a/basegfx/source/polygon/b2dpolypolygoncutter.cxx
+++ b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
@@ -701,6 +701,94 @@ namespace basegfx
//////////////////////////////////////////////////////////////////////////////
+ B2DPolyPolygon createNonzeroConform(const B2DPolyPolygon& rCandidate)
+ {
+ B2DPolyPolygon aCandidate;
+
+ // remove all self-intersections and intersections
+ if(rCandidate.count() == 1)
+ {
+ aCandidate = basegfx::tools::solveCrossovers(rCandidate.getB2DPolygon(0));
+ }
+ else
+ {
+ aCandidate = basegfx::tools::solveCrossovers(rCandidate);
+ }
+
+ // cleanup evtl. neutral polygons
+ aCandidate = basegfx::tools::stripNeutralPolygons(aCandidate);
+
+ // remove all polygons which have the same orientation as the polygon they are directly contained in
+ const sal_uInt32 nCount(aCandidate.count());
+
+ if(nCount > 1)
+ {
+ sal_uInt32 a, b;
+ ::std::vector< StripHelper > aHelpers;
+ aHelpers.resize(nCount);
+
+ for(a = 0; a < nCount; a++)
+ {
+ const B2DPolygon aCand(aCandidate.getB2DPolygon(a));
+ StripHelper* pNewHelper = &(aHelpers[a]);
+ pNewHelper->maRange = tools::getRange(aCand);
+ pNewHelper->meOrinetation = tools::getOrientation(aCand);
+
+ // initialize with own orientation
+ pNewHelper->mnDepth = (ORIENTATION_NEGATIVE == pNewHelper->meOrinetation ? -1 : 1);
+ }
+
+ for(a = 0; a < nCount - 1; a++)
+ {
+ const B2DPolygon aCandA(aCandidate.getB2DPolygon(a));
+ StripHelper& rHelperA = aHelpers[a];
+
+ for(b = a + 1; b < nCount; b++)
+ {
+ const B2DPolygon aCandB(aCandidate.getB2DPolygon(b));
+ StripHelper& rHelperB = aHelpers[b];
+ const bool bAInB(rHelperB.maRange.isInside(rHelperA.maRange) && tools::isInside(aCandB, aCandA, true));
+
+ if(bAInB)
+ {
+ // A is inside B, add orientation of B to A
+ rHelperA.mnDepth += (ORIENTATION_NEGATIVE == rHelperB.meOrinetation ? -1 : 1);
+ }
+
+ const bool bBInA(rHelperA.maRange.isInside(rHelperB.maRange) && tools::isInside(aCandA, aCandB, true));
+
+ if(bBInA)
+ {
+ // B is inside A, add orientation of A to B
+ rHelperB.mnDepth += (ORIENTATION_NEGATIVE == rHelperA.meOrinetation ? -1 : 1);
+ }
+ }
+ }
+
+ const B2DPolyPolygon aSource(aCandidate);
+ aCandidate.clear();
+
+ for(a = 0L; a < nCount; a++)
+ {
+ const StripHelper& rHelper = aHelpers[a];
+ // for contained unequal oriented polygons sum will be 0
+ // for contained equal it will be >=2 or <=-2
+ // for free polygons (not contained) it will be 1 or -1
+ // -> accept all which are >=-1 && <= 1
+ bool bAcceptEntry(rHelper.mnDepth >= -1 && rHelper.mnDepth <= 1);
+
+ if(bAcceptEntry)
+ {
+ aCandidate.append(aSource.getB2DPolygon(a));
+ }
+ }
+ }
+
+ return aCandidate;
+ }
+
+ //////////////////////////////////////////////////////////////////////////////
+
B2DPolyPolygon stripDispensablePolygons(const B2DPolyPolygon& rCandidate, bool bKeepAboveZero)
{
const sal_uInt32 nCount(rCandidate.count());
@@ -922,15 +1010,15 @@ namespace basegfx
}
}
- B2DPolyPolygon mergeToSinglePolyPolygon(const std::vector< basegfx::B2DPolyPolygon >& rInput)
+ B2DPolyPolygon mergeToSinglePolyPolygon(const B2DPolyPolygonVector& rInput)
{
- std::vector< basegfx::B2DPolyPolygon > aInput(rInput);
+ B2DPolyPolygonVector aInput(rInput);
// first step: prepareForPolygonOperation and simple merge of non-overlapping
// PolyPolygons for speedup; this is possible for the wanted OR-operation
if(aInput.size())
{
- std::vector< basegfx::B2DPolyPolygon > aResult;
+ B2DPolyPolygonVector aResult;
aResult.reserve(aInput.size());
for(sal_uInt32 a(0); a < aInput.size(); a++)
@@ -972,7 +1060,7 @@ namespace basegfx
// second step: melt pairwise to a single PolyPolygon
while(aInput.size() > 1)
{
- std::vector< basegfx::B2DPolyPolygon > aResult;
+ B2DPolyPolygonVector aResult;
aResult.reserve((aInput.size() / 2) + 1);
for(sal_uInt32 a(0); a < aInput.size(); a += 2)
diff --git a/basegfx/source/polygon/b2dsvgpolypolygon.cxx b/basegfx/source/polygon/b2dsvgpolypolygon.cxx
index bfac98f3e5f1..1ac1258d7cdd 100644
--- a/basegfx/source/polygon/b2dsvgpolypolygon.cxx
+++ b/basegfx/source/polygon/b2dsvgpolypolygon.cxx
@@ -782,9 +782,16 @@ namespace basegfx
// (since
// createPolygonFromEllipseSegment()
// normalizes to e.g. cw arc)
- const bool bFlipSegment( (bLargeArcFlag!=0) ==
- (fmod(fTheta2+2*M_PI-fTheta1,
- 2*M_PI)<M_PI) );
+
+ // ALG: In my opinion flipping the segment only
+ // depends on the sweep flag. At least, this gives
+ // correct results forthe SVG example (see SVG doc 8.3.8 ff)
+ //
+ //const bool bFlipSegment( (bLargeArcFlag!=0) ==
+ // (fmod(fTheta2+2*M_PI-fTheta1,
+ // 2*M_PI)<M_PI) );
+ const bool bFlipSegment(!bSweepFlag);
+
if( bFlipSegment )
std::swap(fTheta1,fTheta2);
diff --git a/cppcanvas/source/mtfrenderer/implrenderer.cxx b/cppcanvas/source/mtfrenderer/implrenderer.cxx
index 96ce84546cb2..a395092f1ad3 100644
--- a/cppcanvas/source/mtfrenderer/implrenderer.cxx
+++ b/cppcanvas/source/mtfrenderer/implrenderer.cxx
@@ -79,7 +79,6 @@
#include <lineaction.hxx>
#include <pointaction.hxx>
#include <polypolyaction.hxx>
-#include <rendergraphicaction.hxx>
#include <textaction.hxx>
#include <transparencygroupaction.hxx>
#include <vector>
@@ -2650,32 +2649,6 @@ namespace cppcanvas
}
break;
- case META_RENDERGRAPHIC_ACTION:
- {
- MetaRenderGraphicAction* pAct = static_cast<MetaRenderGraphicAction*>(pCurrAct);
-
- ActionSharedPtr pRenderGraphicAction(
- internal::RenderGraphicActionFactory::createRenderGraphicAction(
- pAct->GetRenderGraphic(),
- getState( rStates ).mapModeTransform *
- ::vcl::unotools::b2DPointFromPoint( pAct->GetPoint() ),
- getState( rStates ).mapModeTransform *
- ::vcl::unotools::b2DSizeFromSize( pAct->GetSize() ),
- rCanvas,
- getState( rStates ) ) );
-
- if( pRenderGraphicAction )
- {
- maActions.push_back(
- MtfAction(
- pRenderGraphicAction,
- io_rCurrActionIndex ) );
-
- io_rCurrActionIndex += pRenderGraphicAction->getActionCount()-1;
- }
- }
- break;
-
default:
OSL_ENSURE( false,
"Unknown meta action type encountered" );
diff --git a/cppcanvas/source/mtfrenderer/makefile.mk b/cppcanvas/source/mtfrenderer/makefile.mk
index 92ae7e1200bc..d142731f81af 100644
--- a/cppcanvas/source/mtfrenderer/makefile.mk
+++ b/cppcanvas/source/mtfrenderer/makefile.mk
@@ -48,7 +48,6 @@ SLOFILES = $(SLO)$/cachedprimitivebase.obj \
$(SLO)$/lineaction.obj \
$(SLO)$/pointaction.obj \
$(SLO)$/polypolyaction.obj \
- $(SLO)$/rendergraphicaction.obj \
$(SLO)$/textaction.obj \
$(SLO)$/transparencygroupaction.obj \
$(SLO)$/mtftools.obj
diff --git a/cppcanvas/source/mtfrenderer/rendergraphicaction.cxx b/cppcanvas/source/mtfrenderer/rendergraphicaction.cxx
deleted file mode 100644
index 764d3eabc6af..000000000000
--- a/cppcanvas/source/mtfrenderer/rendergraphicaction.cxx
+++ /dev/null
@@ -1,201 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_cppcanvas.hxx"
-
-#include <rtl/logfile.hxx>
-#include <com/sun/star/rendering/XBitmap.hpp>
-#include <com/sun/star/rendering/RepaintResult.hpp>
-#include <com/sun/star/rendering/XCachedPrimitive.hpp>
-#include <vcl/rendergraphicrasterizer.hxx>
-#include <tools/gen.hxx>
-#include <vcl/canvastools.hxx>
-#include <canvas/canvastools.hxx>
-#include <basegfx/matrix/b2dhommatrix.hxx>
-#include <basegfx/vector/b2dsize.hxx>
-#include <basegfx/point/b2dpoint.hxx>
-#include <basegfx/range/b2drange.hxx>
-#include <basegfx/tools/canvastools.hxx>
-#include <boost/utility.hpp>
-#include "cachedprimitivebase.hxx"
-#include "rendergraphicaction.hxx"
-#include "outdevstate.hxx"
-#include "mtftools.hxx"
-#include <basegfx/matrix/b2dhommatrixtools.hxx>
-
-
-using namespace ::com::sun::star;
-
-namespace cppcanvas
-{
- namespace internal
- {
- namespace
- {
-
- class RenderGraphicAction : public CachedPrimitiveBase
- {
- public:
- RenderGraphicAction( const ::vcl::RenderGraphic& rRenderGraphic,
- const ::basegfx::B2DPoint& rDstPoint,
- const ::basegfx::B2DVector& rDstSize,
- const CanvasSharedPtr&,
- const OutDevState& );
-
- virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation,
- const Subset& rSubset ) const;
-
- virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
- virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
- const Subset& rSubset ) const;
-
- virtual sal_Int32 getActionCount() const;
-
- private:
- using Action::render;
- virtual bool render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
- const ::basegfx::B2DHomMatrix& rTransformation ) const;
-
- ::vcl::RenderGraphic maRenderGraphic;
- uno::Reference< rendering::XBitmap > mxBitmap;
- CanvasSharedPtr mpCanvas;
- rendering::RenderState maState;
- };
-
- RenderGraphicAction::RenderGraphicAction( const ::vcl::RenderGraphic& rRenderGraphic,
- const ::basegfx::B2DPoint& rDstPoint,
- const ::basegfx::B2DVector& rDstSize,
- const CanvasSharedPtr& rCanvas,
- const OutDevState& rState ) :
- CachedPrimitiveBase( rCanvas, true ),
- maRenderGraphic( rRenderGraphic ),
- mpCanvas( rCanvas )
- {
- tools::initRenderState( maState,rState );
-
- const ::vcl::RenderGraphicRasterizer aRasterizer( rRenderGraphic );
- const BitmapEx aBmpEx( aRasterizer.Rasterize( ::vcl::unotools::sizeFromB2DSize( rDstSize ) ) );
- const Size aRasteredSizePixel( aBmpEx.GetSizePixel() );
-
- if( aRasteredSizePixel.Width() && aRasteredSizePixel.Height() )
- {
- const ::basegfx::B2DVector aScale( rDstSize.getX() / aRasteredSizePixel.Width(),
- rDstSize.getY() / aRasteredSizePixel.Height() );
- const basegfx::B2DHomMatrix aLocalTransformation(
- basegfx::tools::createScaleTranslateB2DHomMatrix( aScale, rDstPoint)) ;
-
- ::canvas::tools::appendToRenderState( maState, aLocalTransformation );
-
- // correct clip (which is relative to original transform)
- tools::modifyClip( maState, rState, rCanvas, rDstPoint, &aScale, NULL );
-
- mxBitmap = ::vcl::unotools::xBitmapFromBitmapEx( rCanvas->getUNOCanvas()->getDevice(), aBmpEx );
- }
- }
-
- bool RenderGraphicAction::render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
- const ::basegfx::B2DHomMatrix& rTransformation ) const
- {
- RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::RenderGraphicAction::render()" );
- RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::RenderGraphicAction: 0x%X", this );
-
- if( mxBitmap.is() )
- {
- rendering::RenderState aLocalState( maState );
- ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
-
- rCachedPrimitive = mpCanvas->getUNOCanvas()->drawBitmap( mxBitmap,
- mpCanvas->getViewState(),
- aLocalState );
- }
-
- return true;
- }
-
- bool RenderGraphicAction::render( const ::basegfx::B2DHomMatrix& rTransformation,
- const Subset& rSubset ) const
- {
- // rendergraphic only contains a single action, fail if subset
- // requests different range
- if( rSubset.mnSubsetBegin != 0 ||
- rSubset.mnSubsetEnd != 1 )
- return false;
-
- return CachedPrimitiveBase::render( rTransformation );
- }
-
- ::basegfx::B2DRange RenderGraphicAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
- {
- ::basegfx::B2DRange aRet;
-
- if( mxBitmap.is() )
- {
- rendering::RenderState aLocalState( maState );
- ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
-
- geometry::IntegerSize2D aSize( mxBitmap->getSize() );
-
- aRet = tools::calcDevicePixelBounds( ::basegfx::B2DRange( 0, 0, aSize.Width, aSize.Height ),
- mpCanvas->getViewState(), aLocalState );
- }
-
- return( aRet );
- }
-
- ::basegfx::B2DRange RenderGraphicAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
- const Subset& rSubset ) const
- {
- // rendergraphic only contains a single action, empty bounds
- // if subset requests different range
- if( rSubset.mnSubsetBegin != 0 ||
- rSubset.mnSubsetEnd != 1 )
- return ::basegfx::B2DRange();
-
- return getBounds( rTransformation );
- }
-
- sal_Int32 RenderGraphicAction::getActionCount() const
- {
- return 1;
- }
- }
-
- ActionSharedPtr RenderGraphicActionFactory::createRenderGraphicAction( const ::vcl::RenderGraphic& rRenderGraphic,
- const ::basegfx::B2DPoint& rDstPoint,
- const ::basegfx::B2DVector& rDstSize,
- const CanvasSharedPtr& rCanvas,
- const OutDevState& rState )
- {
- return ActionSharedPtr( new RenderGraphicAction(rRenderGraphic,
- rDstPoint,
- rDstSize,
- rCanvas,
- rState ) );
- }
- }
-}
diff --git a/cppcanvas/source/mtfrenderer/rendergraphicaction.hxx b/cppcanvas/source/mtfrenderer/rendergraphicaction.hxx
deleted file mode 100644
index f1e2dccdfe0d..000000000000
--- a/cppcanvas/source/mtfrenderer/rendergraphicaction.hxx
+++ /dev/null
@@ -1,77 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-#ifndef _CPPCANVAS_RENDERGRAPHICACTION_HXX
-#define _CPPCANVAS_RENDERGRAPHICACTION_HXX
-
-#include <cppcanvas/canvas.hxx>
-#include <action.hxx>
-
-namespace basegfx {
- class B2DPoint;
- class B2DVector;
-}
-namespace vcl {
- class RenderGraphic;
-}
-
-/* Definition of internal::RenderGraphicActionFactory class */
-
-namespace cppcanvas
-{
- namespace internal
- {
- struct OutDevState;
-
- /** Creates encapsulated converters between GDIMetaFile and
- XCanvas. The Canvas argument is deliberately placed at the
- constructor, to force reconstruction of this object for a
- new canvas. This considerably eases internal state
- handling, since a lot of the internal state (e.g. fonts,
- text layout) is Canvas-dependent.
- */
- class RenderGraphicActionFactory
- {
- public:
- /// Scaled rendergraphic action, dest point and dest size
- static ActionSharedPtr createRenderGraphicAction( const ::vcl::RenderGraphic& rRenderGraphic,
- const ::basegfx::B2DPoint& rDstPoint,
- const ::basegfx::B2DVector& rDstSize,
- const CanvasSharedPtr&,
- const OutDevState& );
-
- private:
- // static factory, disable big four
- RenderGraphicActionFactory();
- ~RenderGraphicActionFactory();
- RenderGraphicActionFactory(const RenderGraphicActionFactory&);
- RenderGraphicActionFactory& operator=( const RenderGraphicActionFactory& );
- };
- }
-}
-
-#endif /*_CPPCANVAS_RENDERGRAPHICACTION_HXX */
diff --git a/cppcanvas/source/mtfrenderer/transparencygroupaction.cxx b/cppcanvas/source/mtfrenderer/transparencygroupaction.cxx
index 3d62fb64fe24..a3229f7e8cf9 100644
--- a/cppcanvas/source/mtfrenderer/transparencygroupaction.cxx
+++ b/cppcanvas/source/mtfrenderer/transparencygroupaction.cxx
@@ -387,7 +387,6 @@ namespace cppcanvas
case META_TEXTLINE_ACTION:
case META_TEXTRECT_ACTION:
case META_STRETCHTEXT_ACTION:
- case META_RENDERGRAPHIC_ACTION:
// output-generating action - only
// copy, if we're within the
// requested subset
diff --git a/drawinglayer/Library_drawinglayer.mk b/drawinglayer/Library_drawinglayer.mk
index e96d5af8b6e0..3b2041fd5e6f 100755
--- a/drawinglayer/Library_drawinglayer.mk
+++ b/drawinglayer/Library_drawinglayer.mk
@@ -27,6 +27,8 @@
$(eval $(call gb_Library_Library,drawinglayer))
+$(eval $(call gb_Library_set_componentfile,drawinglayer,drawinglayer/drawinglayer))
+
$(eval $(call gb_Library_add_package_headers,drawinglayer,drawinglayer_inc))
$(eval $(call gb_Library_add_precompiled_header,drawinglayer,$(SRCDIR)/drawinglayer/inc/pch/precompiled_drawinglayer))
@@ -94,6 +96,7 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\
drawinglayer/source/primitive2d/borderlineprimitive2d \
drawinglayer/source/primitive2d/chartprimitive2d \
drawinglayer/source/primitive2d/controlprimitive2d \
+ drawinglayer/source/primitive2d/cropprimitive2d \
drawinglayer/source/primitive2d/discretebitmapprimitive2d \
drawinglayer/source/primitive2d/discreteshadowprimitive2d \
drawinglayer/source/primitive2d/embedded3dprimitive2d \
@@ -114,14 +117,16 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\
drawinglayer/source/primitive2d/metafileprimitive2d \
drawinglayer/source/primitive2d/modifiedcolorprimitive2d \
drawinglayer/source/primitive2d/pagepreviewprimitive2d \
+ drawinglayer/source/primitive2d/patternfillprimitive2d \
drawinglayer/source/primitive2d/polypolygonprimitive2d \
drawinglayer/source/primitive2d/polygonprimitive2d \
drawinglayer/source/primitive2d/primitivetools2d \
- drawinglayer/source/primitive2d/rendergraphicprimitive2d \
drawinglayer/source/primitive2d/sceneprimitive2d \
drawinglayer/source/primitive2d/sdrdecompositiontools2d \
drawinglayer/source/primitive2d/shadowprimitive2d \
drawinglayer/source/primitive2d/structuretagprimitive2d \
+ drawinglayer/source/primitive2d/svggradientprimitive2d \
+ drawinglayer/source/primitive2d/textbreakuphelper \
drawinglayer/source/primitive2d/texteffectprimitive2d \
drawinglayer/source/primitive2d/textenumsprimitive2d \
drawinglayer/source/primitive2d/textlayoutdevice \
@@ -176,6 +181,9 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\
drawinglayer/source/processor3d/zbufferprocessor3d \
drawinglayer/source/texture/texture \
drawinglayer/source/texture/texture3d \
+ drawinglayer/source/tools/converters \
+ drawinglayer/source/drawinglayeruno/drawinglayeruno \
+ drawinglayer/source/drawinglayeruno/xprimitive2drenderer \
))
# vim: set noet sw=4 ts=4:
diff --git a/drawinglayer/Package_inc.mk b/drawinglayer/Package_inc.mk
index 77d1e0659d57..3be2c7ff9f00 100755
--- a/drawinglayer/Package_inc.mk
+++ b/drawinglayer/Package_inc.mk
@@ -36,6 +36,7 @@ $(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/borderlineprimitive2d.hxx,drawinglayer/primitive2d/borderlineprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/chartprimitive2d.hxx,drawinglayer/primitive2d/chartprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/controlprimitive2d.hxx,drawinglayer/primitive2d/controlprimitive2d.hxx))
+$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/cropprimitive2d.hxx,drawinglayer/primitive2d/cropprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/discretebitmapprimitive2d.hxx,drawinglayer/primitive2d/discretebitmapprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/discreteshadowprimitive2d.hxx,drawinglayer/primitive2d/discreteshadowprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/embedded3dprimitive2d.hxx,drawinglayer/primitive2d/embedded3dprimitive2d.hxx))
@@ -54,6 +55,7 @@ $(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/metafileprimitive2d.hxx,drawinglayer/primitive2d/metafileprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx,drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/pagepreviewprimitive2d.hxx,drawinglayer/primitive2d/pagepreviewprimitive2d.hxx))
+$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/patternfillprimitive2d.hxx,drawinglayer/primitive2d/patternfillprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/pointarrayprimitive2d.hxx,drawinglayer/primitive2d/pointarrayprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/polygonprimitive2d.hxx,drawinglayer/primitive2d/polygonprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/polypolygonprimitive2d.hxx,drawinglayer/primitive2d/polypolygonprimitive2d.hxx))
@@ -62,10 +64,14 @@ $(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/sceneprimitive2d.hxx,drawinglayer/primitive2d/sceneprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/shadowprimitive2d.hxx,drawinglayer/primitive2d/shadowprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/structuretagprimitive2d.hxx,drawinglayer/primitive2d/structuretagprimitive2d.hxx))
+$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/svggradientprimitive2d.hxx,drawinglayer/primitive2d/svggradientprimitive2d.hxx))
+$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/textbreakuphelper.hxx,drawinglayer/primitive2d/textbreakuphelper.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/textenumsprimitive2d.hxx,drawinglayer/primitive2d/textenumsprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/texteffectprimitive2d.hxx,drawinglayer/primitive2d/texteffectprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/textlayoutdevice.hxx,drawinglayer/primitive2d/textlayoutdevice.hxx))
+$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/textlineprimitive2d.hxx,drawinglayer/primitive2d/textlineprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/textprimitive2d.hxx,drawinglayer/primitive2d/textprimitive2d.hxx))
+$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx,drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx,drawinglayer/primitive2d/textdecoratedprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/texthierarchyprimitive2d.hxx,drawinglayer/primitive2d/texthierarchyprimitive2d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive2d/transformprimitive2d.hxx,drawinglayer/primitive2d/transformprimitive2d.hxx))
@@ -76,6 +82,7 @@ $(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive3d/
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive3d/baseprimitive3d.hxx,drawinglayer/primitive3d/baseprimitive3d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive3d/groupprimitive3d.hxx,drawinglayer/primitive3d/groupprimitive3d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive3d/hatchtextureprimitive3d.hxx,drawinglayer/primitive3d/hatchtextureprimitive3d.hxx))
+$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive3d/hiddengeometryprimitive3d.hxx,drawinglayer/primitive3d/hiddengeometryprimitive3d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx,drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive3d/polygonprimitive3d.hxx,drawinglayer/primitive3d/polygonprimitive3d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/primitive3d/polygontubeprimitive3d.hxx,drawinglayer/primitive3d/polygontubeprimitive3d.hxx))
@@ -110,6 +117,8 @@ $(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/processor2d/
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/processor3d/baseprocessor3d.hxx,drawinglayer/processor3d/baseprocessor3d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/processor3d/cutfindprocessor3d.hxx,drawinglayer/processor3d/cutfindprocessor3d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/processor3d/defaultprocessor3d.hxx,drawinglayer/processor3d/defaultprocessor3d.hxx))
+$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/processor3d/geometry2dextractor.hxx,drawinglayer/processor3d/geometry2dextractor.hxx))
+$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/processor3d/shadow3dextractor.hxx,drawinglayer/processor3d/shadow3dextractor.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/processor3d/zbufferprocessor3d.hxx,drawinglayer/processor3d/zbufferprocessor3d.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/fillgradientattribute.hxx,drawinglayer/attribute/fillgradientattribute.hxx))
@@ -132,3 +141,5 @@ $(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/li
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/attribute/linestartendattribute.hxx,drawinglayer/attribute/linestartendattribute.hxx))
$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/texture/texture.hxx,drawinglayer/texture/texture.hxx))
+
+$(eval $(call gb_Package_add_file,drawinglayer_inc,inc/drawinglayer/tools/converters.hxx,drawinglayer/tools/converters.hxx))
diff --git a/drawinglayer/drawinglayer.component b/drawinglayer/drawinglayer.component
new file mode 100644
index 000000000000..73630675a849
--- /dev/null
+++ b/drawinglayer/drawinglayer.component
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--******************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http:\\www.apache.org\licenses\LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="drawinglayer::unorenderer::XPrimitive2DRenderer">
+ <service name="com.sun.star.graphic.Primitive2DTools"/>
+ </implementation>
+</component>
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/baseprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/baseprimitive2d.hxx
index 0222c8ed37f0..b907d7536012 100644
--- a/drawinglayer/inc/drawinglayer/primitive2d/baseprimitive2d.hxx
+++ b/drawinglayer/inc/drawinglayer/primitive2d/baseprimitive2d.hxx
@@ -265,6 +265,10 @@ namespace drawinglayer
{
namespace primitive2d
{
+ /// support to handle a sequence of primitives as stl vector and convert it during creation
+ typedef ::std::vector< BasePrimitive2D* > Primitive2DVector;
+ Primitive2DSequence DRAWINGLAYER_DLLPUBLIC Primitive2DVectorToPrimitive2DSequence(const Primitive2DVector& rSource, bool bInvert = false);
+
/// get B2DRange from a given Primitive2DReference
basegfx::B2DRange DRAWINGLAYER_DLLPUBLIC getB2DRangeFromPrimitive2DReference(const Primitive2DReference& rCandidate, const geometry::ViewInformation2D& aViewInformation);
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/cropprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/cropprimitive2d.hxx
new file mode 100644
index 000000000000..86b218d2665a
--- /dev/null
+++ b/drawinglayer/inc/drawinglayer/primitive2d/cropprimitive2d.hxx
@@ -0,0 +1,105 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_CROPPRIMITIVE2D_HXX
+#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_CROPPRIMITIVE2D_HXX
+
+#include <drawinglayer/drawinglayerdllapi.h>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ /** CropPrimitive2D class
+
+ Caution: Due to old constraints (old core definitions) the
+ crop distances describe how the uncropped content is defined
+ relative to the current object size. This means that maTransformation
+ describes the rurrent object size (the part of the object visible
+ with the crop applied). To get the original size and orientation
+ of the uncropped content it is necessary to calc back from the
+ current situation (maTransformation) using the crop values
+ to get to the uncropped original content.
+
+ Thus a transformation has to be calculated which will be applied
+ to the already exsisting content to get it to the uncropped state
+ ans then this is masked with the current state (mask polygon
+ created from unit polygon and maTransformation).
+
+ At least in this primitive the units of the crop values are
+ already in the local coordinate system; inthe core these distances
+ are defined relative to the object content size (PrefMapMode
+ and PrefSize of the content)...
+
+ Of course this is a primitive, so feel free to just ignore all that
+ stuff and use the automatically generated decomposition. Sigh.
+ */
+ class DRAWINGLAYER_DLLPUBLIC CropPrimitive2D : public GroupPrimitive2D
+ {
+ private:
+ // the transformation already applied to the child geometry
+ basegfx::B2DHomMatrix maTransformation;
+
+ // the crop offsets relative to the range of the unrotated content
+ double mfCropLeft;
+ double mfCropTop;
+ double mfCropRight;
+ double mfCropBottom;
+
+ public:
+ /// constructor
+ CropPrimitive2D(
+ const Primitive2DSequence& rChildren,
+ const basegfx::B2DHomMatrix& rTransformation,
+ double fCropLeft,
+ double fCropTop,
+ double fCropRight,
+ double fCropBottom);
+
+ /// data read access
+ const basegfx::B2DHomMatrix& getTransformation() const { return maTransformation; }
+ double getCropLeft() const { return mfCropLeft; }
+ double getCropTop() const { return mfCropTop; }
+ double getCropRight() const { return mfCropRight; }
+ double getCropBottom() const { return mfCropBottom; }
+
+ /// compare operator
+ virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
+
+ /// local decomposition
+ virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
+
+ /// provide unique ID
+ DeclPrimitrive2DIDBlock()
+ };
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_CROPPRIMITIVE2D_HXX
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx
index e14751122198..4aacc64fba71 100644
--- a/drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx
+++ b/drawinglayer/inc/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx
@@ -99,7 +99,12 @@
#define PRIMITIVE2D_ID_EPSPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 60)
#define PRIMITIVE2D_ID_DISCRETESHADOWPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 61)
#define PRIMITIVE2D_ID_HIDDENGEOMETRYPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 62)
-#define PRIMITIVE2D_ID_RENDERGRAPHICPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 63)
+#define PRIMITIVE2D_ID_SVGLINEARGRADIENTPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 63)
+#define PRIMITIVE2D_ID_SVGRADIALGRADIENTPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 64)
+#define PRIMITIVE2D_ID_SVGLINEARATOMPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 65)
+#define PRIMITIVE2D_ID_SVGRADIALATOMPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 66)
+#define PRIMITIVE2D_ID_CROPPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 67)
+#define PRIMITIVE2D_ID_PATTERNFILLPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 68)
//////////////////////////////////////////////////////////////////////////////
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/patternfillprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/patternfillprimitive2d.hxx
new file mode 100644
index 000000000000..5d760e2e0d1d
--- /dev/null
+++ b/drawinglayer/inc/drawinglayer/primitive2d/patternfillprimitive2d.hxx
@@ -0,0 +1,84 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_PATTERNFILLPRIMITIVE2D_HXX
+#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_PATTERNFILLPRIMITIVE2D_HXX
+
+#include <drawinglayer/drawinglayerdllapi.h>
+#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ /** PatternFillPrimitive2D class
+
+ This primitive allows filling a given PolyPolygon with a pattern
+ defined by a sequence of primitives which are mapped to the unit range.
+ The pattern is defined using a reference range which defines a rectangular
+ area relative to the PolyPolygon (in unit coordinates) which is virtually
+ infinitely repeated.
+ */
+ class DRAWINGLAYER_DLLPUBLIC PatternFillPrimitive2D : public BufferedDecompositionPrimitive2D
+ {
+ private:
+ const basegfx::B2DPolyPolygon maMask;
+ const Primitive2DSequence maChildren;
+ const basegfx::B2DRange maReferenceRange;
+
+ protected:
+ /// create local decomposition
+ virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
+
+ public:
+ /// constructor
+ PatternFillPrimitive2D(
+ const basegfx::B2DPolyPolygon& rMask,
+ const Primitive2DSequence& rChildren,
+ const basegfx::B2DRange& rReferenceRange);
+
+ /// data read access
+ const basegfx::B2DPolyPolygon& getMask() const { return maMask; }
+ const Primitive2DSequence& getChildren() const { return maChildren; }
+ const basegfx::B2DRange& getReferenceRange() const { return maReferenceRange; }
+
+ /// compare operator
+ virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
+
+ /// get range
+ virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const;
+
+ /// provide unique ID
+ DeclPrimitrive2DIDBlock()
+ };
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_PATTERNFILLPRIMITIVE2D_HXX
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/rendergraphicprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/rendergraphicprimitive2d.hxx
deleted file mode 100644
index 190439442917..000000000000
--- a/drawinglayer/inc/drawinglayer/primitive2d/rendergraphicprimitive2d.hxx
+++ /dev/null
@@ -1,95 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_RENDERGRAPHICPRIMITIVE2D_HXX
-#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_RENDERGRAPHICPRIMITIVE2D_HXX
-
-#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
-#include <basegfx/matrix/b2dhommatrix.hxx>
-#include <vcl/rendergraphic.hxx>
-#include <memory>
-
-//////////////////////////////////////////////////////////////////////////////
-// RenderGraphicPrimitive2D class
-
-namespace vcl { class RenderGraphicRasterizer; }
-
-namespace drawinglayer
-{
- namespace primitive2d
- {
- /** RenderGraphicPrimitive2D class
-
- This class is the central primitive for RenderGraphic-based primitives.
- */
- class RenderGraphicPrimitive2D : public BasePrimitive2D
- {
- private:
- /// the RenderGraphic data
- vcl::RenderGraphic maRenderGraphic;
- mutable std::auto_ptr< vcl::RenderGraphicRasterizer > mapCurrentRasterizer;
-
- /** the object transformation from unit coordinates, defining
- size, shear, rotate and position
- */
- basegfx::B2DHomMatrix maTransform;
-
- public:
- /// constructor
- RenderGraphicPrimitive2D(
- const vcl::RenderGraphic& rRenderGraphic,
- const basegfx::B2DHomMatrix& rTransform);
-
- /// data read access
- inline const vcl::RenderGraphic& getRenderGraphic() const { return maRenderGraphic; }
- inline const basegfx::B2DHomMatrix& getTransform() const { return maTransform; }
-
- // access to latest used vcl::GraphicRasterizer for possibly reusing
- // an already rendered vcl::RenderGraphic with the same transform
- // properties during the next rendering process
- void setCurrentRasterizer() const;
- void setCurrentRasterizer( const vcl::RenderGraphicRasterizer& rCurrentGraphicRasterizer ) const;
- inline const vcl::RenderGraphicRasterizer* getCurrentRasterizer() const { return( mapCurrentRasterizer.get() ); }
-
- /// compare operator
- virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
-
- /// get range
- virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const;
-
- /// provide unique ID
- DeclPrimitrive2DIDBlock()
- };
- } // end of namespace primitive2d
-} // end of namespace drawinglayer
-
-//////////////////////////////////////////////////////////////////////////////
-
-#endif // INCLUDED_DRAWINGLAYER_PRIMITIVE2D_RENDERGRAPHICPRIMITIVE2D_HXX
-
-//////////////////////////////////////////////////////////////////////////////
-// eof
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/svggradientprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/svggradientprimitive2d.hxx
new file mode 100644
index 000000000000..e2e12cff19ff
--- /dev/null
+++ b/drawinglayer/inc/drawinglayer/primitive2d/svggradientprimitive2d.hxx
@@ -0,0 +1,468 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http:\\www.apache.org\licenses\LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_SVGGRADIENTPRIMITIVE2D_HXX
+#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_SVGGRADIENTPRIMITIVE2D_HXX
+
+#include <drawinglayer/drawinglayerdllapi.h>
+#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
+#include <basegfx/color/bcolor.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <drawinglayer/primitive2d/primitivetools2d.hxx>
+#include <vector>
+
+//////////////////////////////////////////////////////////////////////////////
+// SvgGradientEntry class
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ /// a single GradientStop defining a color and opacity at a distance
+ class SvgGradientEntry
+ {
+ private:
+ double mfOffset;
+ basegfx::BColor maColor;
+ double mfOpacity;
+
+ public:
+ SvgGradientEntry(double fOffset, const basegfx::BColor& rColor = basegfx::BColor(0.0, 0.0, 0.0), double fOpacity = 1.0)
+ : mfOffset(fOffset),
+ maColor(rColor),
+ mfOpacity(fOpacity)
+ {
+ }
+
+ double getOffset() const { return mfOffset; }
+ const basegfx::BColor& getColor() const { return maColor; }
+ double getOpacity() const { return mfOpacity; }
+
+ bool operator==(const SvgGradientEntry& rCompare) const
+ {
+ return (getOffset() == rCompare.getOffset()
+ && getColor() == getColor()
+ && getOpacity() == getOpacity());
+ }
+
+ bool operator<(const SvgGradientEntry& rCompare) const
+ {
+ return getOffset() < rCompare.getOffset();
+ }
+ };
+
+ typedef ::std::vector< SvgGradientEntry > SvgGradientEntryVector;
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// SvgGradientHelper class
+#define DEFAULT_OVERLAPPING_VALUE (1.0/512.0)
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ enum SpreadMethod
+ {
+ Spread_pad = 0,
+ Spread_reflect,
+ Spread_repeat
+ };
+
+ /* helper for linear and radial gradient, both get derived from this
+ to share common definitions and functionality
+ **/
+ class SvgGradientHelper
+ {
+ private:
+ /// geometric definition, the geometry to be filled
+ basegfx::B2DPolyPolygon maPolyPolygon;
+
+ /// the gradient definition
+ SvgGradientEntryVector maGradientEntries;
+
+ /// start and/or center point
+ basegfx::B2DPoint maStart;
+
+ /// how to spread
+ SpreadMethod maSpreadMethod;
+
+ /* allows to set an overlapping value to be able to create
+ slightly overlapping PolyPolygons/Polygons for the decomposition.
+ This is needed since when creating geometrically correct decompositions
+ many visualisations will show artefacts at the borders, even when these
+ borders are absolutely correctly defined. It is possible to define a
+ useful value for this since the coordinate system we are working in is
+ in unit coordinates so that the whole gradient is from [0.0 .. 1.0] range.
+ This explains the default value which is 1/512 by a maximum possible
+ color count of 255 steps per GradientStop.
+ Give a 0.0 here to go to geometrically correct gradient decompositions if
+ needed.
+ An alternative would be to create no PolyPolygons from outside to inside
+ (example for radial), but this leads to up to 255 filled polygons per
+ GradientStop and thus to enormous rendering costs.
+ **/
+ double mfOverlapping;
+
+ /// bitfield
+ bool mbPreconditionsChecked : 1;
+ bool mbCreatesContent : 1;
+ bool mbSingleEntry : 1;
+ bool mbFullyOpaque : 1;
+
+ protected:
+ /// local helpers
+ Primitive2DSequence createSingleGradientEntryFill() const;
+ virtual void createAtom(
+ Primitive2DVector& rTargetColor,
+ Primitive2DVector& rTargetOpacity,
+ const SvgGradientEntry& rFrom,
+ const SvgGradientEntry& rTo,
+ sal_Int32 nOffset) const = 0;
+ double createRun(
+ Primitive2DVector& rTargetColor,
+ Primitive2DVector& rTargetOpacity,
+ double fPos,
+ double fMax,
+ const SvgGradientEntryVector& rEntries,
+ sal_Int32 nOffset) const;
+ virtual void checkPreconditions();
+ Primitive2DSequence SvgGradientHelper::createResult(
+ const Primitive2DVector& rTargetColor,
+ const Primitive2DVector& rTargetOpacity,
+ const basegfx::B2DHomMatrix& rUnitGradientToObject,
+ bool bInvert = false) const;
+ bool getCreatesContent() const { return mbCreatesContent; }
+ bool getSingleEntry() const { return mbSingleEntry; }
+ void setSingleEntry() { mbSingleEntry = true; }
+ bool getPreconditionsChecked() const { return mbPreconditionsChecked; }
+ bool getFullyOpaque() const { return mbFullyOpaque; }
+
+ public:
+ /// constructor
+ SvgGradientHelper(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
+ const SvgGradientEntryVector& rGradientEntries,
+ const basegfx::B2DPoint& rStart,
+ SpreadMethod aSpreadMethod = Spread_pad,
+ double fOverlapping = DEFAULT_OVERLAPPING_VALUE);
+
+ /// data read access
+ const basegfx::B2DPolyPolygon& getPolyPolygon() const { return maPolyPolygon; }
+ const SvgGradientEntryVector& getGradientEntries() const { return maGradientEntries; }
+ const basegfx::B2DPoint& getStart() const { return maStart; }
+ SpreadMethod getSpreadMethod() const { return maSpreadMethod; }
+ const double getOverlapping() const { return mfOverlapping; }
+
+ /// compare operator
+ virtual bool operator==(const SvgGradientHelper& rSvgGradientHelper) const;
+ };
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// SvgLinearGradientPrimitive2D class
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ /// the basic linear gradient primitive
+ class DRAWINGLAYER_DLLPUBLIC SvgLinearGradientPrimitive2D : public BufferedDecompositionPrimitive2D, public SvgGradientHelper
+ {
+ private:
+ /// the end point for linear gradient
+ basegfx::B2DPoint maEnd;
+
+ /// local helpers
+ void ensureGeometry(
+ basegfx::B2DPolyPolygon& rPolyPolygon,
+ const SvgGradientEntry& rFrom,
+ const SvgGradientEntry& rTo,
+ sal_Int32 nOffset) const;
+
+ protected:
+ /// local helpers
+ virtual void createAtom(
+ Primitive2DVector& rTargetColor,
+ Primitive2DVector& rTargetOpacity,
+ const SvgGradientEntry& rFrom,
+ const SvgGradientEntry& rTo,
+ sal_Int32 nOffset) const;
+ virtual void checkPreconditions();
+
+ /// local decomposition.
+ virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
+
+ public:
+ /// constructor
+ SvgLinearGradientPrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
+ const SvgGradientEntryVector& rGradientEntries,
+ const basegfx::B2DPoint& rStart,
+ const basegfx::B2DPoint& rEnd,
+ SpreadMethod aSpreadMethod = Spread_pad,
+ double fOverlapping = DEFAULT_OVERLAPPING_VALUE);
+
+ /// data read access
+ const basegfx::B2DPoint& getEnd() const { return maEnd; }
+
+ /// compare operator
+ virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
+
+ /// get range
+ virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const;
+
+ /// provide unique ID
+ DeclPrimitrive2DIDBlock()
+ };
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// SvgRadialGradientPrimitive2D class
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ /// the basic radial gradient primitive
+ class DRAWINGLAYER_DLLPUBLIC SvgRadialGradientPrimitive2D : public BufferedDecompositionPrimitive2D, public SvgGradientHelper
+ {
+ private:
+ /// the geometric definition
+ double mfRadius;
+
+ /// Focal only used when focal is set at all, see constructors
+ basegfx::B2DPoint maFocal;
+ basegfx::B2DVector maFocalVector;
+ double maFocalLength;
+
+ // internal helper for case Spread_reflect
+ SvgGradientEntryVector maMirroredGradientEntries;
+
+ /// bitfield
+ bool mbFocalSet : 1;
+
+ /// local helpers
+ const SvgGradientEntryVector& getMirroredGradientEntries() const;
+ void createMirroredGradientEntries();
+ void ensureGeometry(
+ basegfx::B2DPolyPolygon& rPolyPolygon,
+ const SvgGradientEntry& rFrom,
+ const SvgGradientEntry& rTo,
+ sal_Int32 nOffset) const;
+
+ protected:
+ /// local helpers
+ virtual void createAtom(
+ Primitive2DVector& rTargetColor,
+ Primitive2DVector& rTargetOpacity,
+ const SvgGradientEntry& rFrom,
+ const SvgGradientEntry& rTo,
+ sal_Int32 nOffset) const;
+ virtual void checkPreconditions();
+
+ /// local decomposition.
+ virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
+
+ public:
+ /// constructor
+ SvgRadialGradientPrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
+ const SvgGradientEntryVector& rGradientEntries,
+ const basegfx::B2DPoint& rStart,
+ double fRadius,
+ SpreadMethod aSpreadMethod = Spread_pad,
+ const basegfx::B2DPoint* pFocal = 0,
+ double fOverlapping = DEFAULT_OVERLAPPING_VALUE);
+
+ /// data read access
+ double getRadius() const { return mfRadius; }
+ const basegfx::B2DPoint& getFocal() const { return maFocal; }
+ bool isFocalSet() const { return mbFocalSet; }
+
+ /// compare operator
+ virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
+
+ /// get range
+ virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const;
+
+ /// provide unique ID
+ DeclPrimitrive2DIDBlock()
+ };
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// SvgLinearAtomPrimitive2D class
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ /* basic primitive for a single linear GradientRun in unit coordiantes.
+ It's derived from DiscreteMetricDependentPrimitive2D to allow view-dependent
+ decompositions allowing reduced color steps
+ **/
+ class DRAWINGLAYER_DLLPUBLIC SvgLinearAtomPrimitive2D : public DiscreteMetricDependentPrimitive2D
+ {
+ private:
+ /// the geometric definition in unit coordiantes
+ basegfx::BColor maColorA;
+ basegfx::BColor maColorB;
+ double mfOffsetA;
+ double mfOffsetB;
+ double mfOverlapping;
+
+ protected:
+
+ /// local decomposition.
+ virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
+
+ public:
+ /// constructor
+ SvgLinearAtomPrimitive2D(
+ const basegfx::BColor& aColorA, double fOffsetA,
+ const basegfx::BColor& aColorB, double fOffsetB,
+ double fOverlapping = DEFAULT_OVERLAPPING_VALUE)
+ : DiscreteMetricDependentPrimitive2D(),
+ maColorA(aColorA),
+ maColorB(aColorB),
+ mfOffsetA(fOffsetA),
+ mfOffsetB(fOffsetB),
+ mfOverlapping(fOverlapping)
+ {
+ }
+
+ /// data read access
+ const basegfx::BColor& getColorA() const { return maColorA; }
+ const basegfx::BColor& getColorB() const { return maColorB; }
+ double getOffsetA() const { return mfOffsetA; }
+ double getOffsetB() const { return mfOffsetB; }
+ const double getOverlapping() const { return mfOverlapping; }
+
+ /// compare operator
+ virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
+
+ /// provide unique ID
+ DeclPrimitrive2DIDBlock()
+ };
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// SvgRadialAtomPrimitive2D class
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ /* basic primitive for a single radial GradientRun in unit coordiantes.
+ It's derived from DiscreteMetricDependentPrimitive2D to allow view-dependent
+ decompositions allowing reduced color steps
+ **/
+ class DRAWINGLAYER_DLLPUBLIC SvgRadialAtomPrimitive2D : public DiscreteMetricDependentPrimitive2D
+ {
+ private:
+ /// the geometric definition in unit coordiantes
+ basegfx::BColor maColorA;
+ basegfx::BColor maColorB;
+ double mfScaleA;
+ double mfScaleB;
+
+ /// Only used when focal is set
+ basegfx::B2DVector maTranslateA;
+ basegfx::B2DVector maTranslateB;
+
+ double mfOverlapping;
+
+ /// bitfield
+ bool mbTranslateSet : 1;
+
+ protected:
+
+ /// local decomposition.
+ virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
+
+ public:
+ /// constructor
+ SvgRadialAtomPrimitive2D(
+ const basegfx::BColor& aColorA, double fScaleA, const basegfx::B2DVector& rTranslateA,
+ const basegfx::BColor& aColorB, double fScaleB, const basegfx::B2DVector& rTranslateB,
+ double fOverlapping = DEFAULT_OVERLAPPING_VALUE)
+ : DiscreteMetricDependentPrimitive2D(),
+ maColorA(aColorA),
+ maColorB(aColorB),
+ mfScaleA(fScaleA),
+ mfScaleB(fScaleB),
+ maTranslateA(rTranslateA),
+ maTranslateB(rTranslateB),
+ mfOverlapping(fOverlapping),
+ mbTranslateSet(true)
+ {
+ mbTranslateSet = !maTranslateA.equal(maTranslateB);
+ }
+
+ SvgRadialAtomPrimitive2D(
+ const basegfx::BColor& aColorA, double fScaleA,
+ const basegfx::BColor& aColorB, double fScaleB,
+ double fOverlapping = DEFAULT_OVERLAPPING_VALUE)
+ : DiscreteMetricDependentPrimitive2D(),
+ maColorA(aColorA),
+ maColorB(aColorB),
+ mfScaleA(fScaleA),
+ mfScaleB(fScaleB),
+ maTranslateA(),
+ maTranslateB(),
+ mfOverlapping(fOverlapping),
+ mbTranslateSet(false)
+ {
+ }
+
+ /// data read access
+ const basegfx::BColor& getColorA() const { return maColorA; }
+ const basegfx::BColor& getColorB() const { return maColorB; }
+ double getScaleA() const { return mfScaleA; }
+ double getScaleB() const { return mfScaleB; }
+ const basegfx::B2DVector& getTranslateA() const { return maTranslateA; }
+ const basegfx::B2DVector& getTranslateB() const { return maTranslateB; }
+ const double getOverlapping() const { return mfOverlapping; }
+ bool getTranslateSet() const { return mbTranslateSet; }
+
+ /// compare operator
+ virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
+
+ /// provide unique ID
+ DeclPrimitrive2DIDBlock()
+ };
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_SVGGRADIENTPRIMITIVE2D_HXX
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textbreakuphelper.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textbreakuphelper.hxx
new file mode 100644
index 000000000000..66560938221c
--- /dev/null
+++ b/drawinglayer/inc/drawinglayer/primitive2d/textbreakuphelper.hxx
@@ -0,0 +1,91 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http:\\www.apache.org\licenses\LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_TEXTBREAKUPHELPER_HXX
+#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_TEXTBREAKUPHELPER_HXX
+
+#include <drawinglayer/drawinglayerdllapi.h>
+#include <drawinglayer/primitive2d/textprimitive2d.hxx>
+#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ enum BreakupUnit
+ {
+ BreakupUnit_character,
+ BreakupUnit_word,
+ BreakupUnit_sentence
+ };
+
+ class DRAWINGLAYER_DLLPUBLIC TextBreakupHelper
+ {
+ private:
+ const Primitive2DReference mxSource;
+ Primitive2DSequence mxResult;
+ const TextSimplePortionPrimitive2D* mpSource;
+ TextLayouterDevice maTextLayouter;
+ basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose maDecTrans;
+
+ /// bitfield
+ bool mbNoDXArray : 1;
+
+ /// create a portion from nIndex to nLength and append to rTempResult
+ void breakupPortion(Primitive2DVector& rTempResult, sal_uInt32 nIndex, sal_uInt32 nLength);
+
+ /// breakup complete primitive
+ void breakup(BreakupUnit aBreakupUnit);
+
+ protected:
+ /// allow user callback to allow changes to the new TextTransformation. Default
+ /// does nothing. Retval defines if a primitive gets created, e.g. return false
+ /// to suppress creation
+ virtual bool allowChange(sal_uInt32 nCount, basegfx::B2DHomMatrix& rNewTransform, sal_uInt32 nIndex, sal_uInt32 nLength);
+
+ /// allow read access to evtl. useful local parts
+ const TextSimplePortionPrimitive2D* getCastedSource() const { return mpSource; }
+ const TextLayouterDevice& getTextLayouter() const { return maTextLayouter; }
+ const basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose& getDecTrans() const { return maDecTrans; }
+
+ public:
+ TextBreakupHelper(const Primitive2DReference& rxSource);
+ virtual ~TextBreakupHelper();
+
+ /// get result
+ const Primitive2DSequence& getResult(BreakupUnit aBreakupUnit = BreakupUnit_character) const;
+
+ /// data read access
+ const Primitive2DReference& getSource() const { return mxSource; }
+ };
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_TEXTBREAKUPHELPER_HXX
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx
index 9ffb1d3ea527..e87c378c6f50 100644
--- a/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx
+++ b/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx
@@ -30,6 +30,7 @@
#include <basegfx/range/b2drange.hxx>
#include <vector>
#include <com/sun/star/lang/Locale.hpp>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
//////////////////////////////////////////////////////////////////////////////
// predefines
@@ -43,11 +44,6 @@ namespace drawinglayer { namespace attribute {
class FontAttribute;
}}
-namespace basegfx {
- class B2DPolyPolygon;
- typedef ::std::vector< B2DPolyPolygon > B2DPolyPolygonVector;
-}
-
//////////////////////////////////////////////////////////////////////////////
// access to one global impTimedRefDev incarnation in namespace drawinglayer::primitive
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx
index 6abc4ad6458a..a9bbea65f16d 100644
--- a/drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx
+++ b/drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx
@@ -33,15 +33,11 @@
#include <vector>
#include <com/sun/star/lang/Locale.hpp>
#include <drawinglayer/attribute/fontattribute.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
//////////////////////////////////////////////////////////////////////////////
// predefines
-namespace basegfx {
- class B2DPolyPolygon;
- typedef ::std::vector< B2DPolyPolygon > B2DPolyPolygonVector;
-}
-
class OutputDevice;
//////////////////////////////////////////////////////////////////////////////
diff --git a/drawinglayer/inc/drawinglayer/processor2d/canvasprocessor.hxx b/drawinglayer/inc/drawinglayer/processor2d/canvasprocessor.hxx
index d9f32533b0a4..c3457044bc4a 100644
--- a/drawinglayer/inc/drawinglayer/processor2d/canvasprocessor.hxx
+++ b/drawinglayer/inc/drawinglayer/processor2d/canvasprocessor.hxx
@@ -53,7 +53,6 @@ namespace drawinglayer { namespace primitive2d {
class MetafilePrimitive2D;
class TextSimplePortionPrimitive2D;
class BitmapPrimitive2D;
- class RenderGraphicPrimitive2D;
class TransparencePrimitive2D;
class PolygonStrokePrimitive2D;
class FillBitmapPrimitive2D;
@@ -106,7 +105,6 @@ namespace drawinglayer
void impRenderMetafilePrimitive2D(const primitive2d::MetafilePrimitive2D& rMetaCandidate);
void impRenderTextSimplePortionPrimitive2D(const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate);
void impRenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate);
- void impRenderRenderGraphicPrimitive2D(const primitive2d::RenderGraphicPrimitive2D& rRenderGraphicCandidate);
void impRenderTransparencePrimitive2D(const primitive2d::TransparencePrimitive2D& rTransparenceCandidate);
void impRenderPolygonStrokePrimitive2D(const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokePrimitive);
void impRenderFillBitmapPrimitive2D(const primitive2d::FillBitmapPrimitive2D& rFillBitmapPrimitive2D);
diff --git a/drawinglayer/inc/drawinglayer/processor2d/contourextractor2d.hxx b/drawinglayer/inc/drawinglayer/processor2d/contourextractor2d.hxx
index 921eb95eb502..37421fd3b854 100644
--- a/drawinglayer/inc/drawinglayer/processor2d/contourextractor2d.hxx
+++ b/drawinglayer/inc/drawinglayer/processor2d/contourextractor2d.hxx
@@ -44,7 +44,7 @@ namespace drawinglayer
{
private:
/// the extracted contour
- std::vector< basegfx::B2DPolyPolygon > maExtractedContour;
+ basegfx::B2DPolyPolygonVector maExtractedContour;
/// tooling methods
void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate);
@@ -53,7 +53,7 @@ namespace drawinglayer
ContourExtractor2D(const geometry::ViewInformation2D& rViewInformation);
virtual ~ContourExtractor2D();
- const std::vector< basegfx::B2DPolyPolygon >& getExtractedContour() const { return maExtractedContour; }
+ const basegfx::B2DPolyPolygonVector& getExtractedContour() const { return maExtractedContour; }
};
} // end of namespace processor2d
} // end of namespace drawinglayer
diff --git a/drawinglayer/inc/drawinglayer/processor2d/linegeometryextractor2d.hxx b/drawinglayer/inc/drawinglayer/processor2d/linegeometryextractor2d.hxx
index 13402c050ba6..408614c26fe5 100644
--- a/drawinglayer/inc/drawinglayer/processor2d/linegeometryextractor2d.hxx
+++ b/drawinglayer/inc/drawinglayer/processor2d/linegeometryextractor2d.hxx
@@ -27,6 +27,7 @@
#include <drawinglayer/drawinglayerdllapi.h>
#include <drawinglayer/processor2d/baseprocessor2d.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
//////////////////////////////////////////////////////////////////////////////
@@ -42,8 +43,8 @@ namespace drawinglayer
class DRAWINGLAYER_DLLPUBLIC LineGeometryExtractor2D : public BaseProcessor2D
{
private:
- std::vector< basegfx::B2DPolygon > maExtractedHairlines;
- std::vector< basegfx::B2DPolyPolygon > maExtractedLineFills;
+ basegfx::B2DPolygonVector maExtractedHairlines;
+ basegfx::B2DPolyPolygonVector maExtractedLineFills;
/// bitfield
unsigned mbInLineGeometry : 1;
@@ -55,8 +56,8 @@ namespace drawinglayer
LineGeometryExtractor2D(const geometry::ViewInformation2D& rViewInformation);
virtual ~LineGeometryExtractor2D();
- const std::vector< basegfx::B2DPolygon >& getExtractedHairlines() const { return maExtractedHairlines; }
- const std::vector< basegfx::B2DPolyPolygon >& getExtractedLineFills() const { return maExtractedLineFills; }
+ const basegfx::B2DPolygonVector& getExtractedHairlines() const { return maExtractedHairlines; }
+ const basegfx::B2DPolyPolygonVector& getExtractedLineFills() const { return maExtractedLineFills; }
};
} // end of namespace processor2d
} // end of namespace drawinglayer
diff --git a/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx b/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx
index b3c8fb0b6799..b5db89f98332 100644
--- a/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx
+++ b/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx
@@ -38,7 +38,6 @@ namespace drawinglayer { namespace primitive2d {
class TextSimplePortionPrimitive2D;
class PolygonHairlinePrimitive2D;
class BitmapPrimitive2D;
- class RenderGraphicPrimitive2D;
class FillBitmapPrimitive2D;
class PolyPolygonGradientPrimitive2D;
class PolyPolygonBitmapPrimitive2D;
@@ -95,7 +94,6 @@ namespace drawinglayer
void RenderTextSimpleOrDecoratedPortionPrimitive2D(const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate);
void RenderPolygonHairlinePrimitive2D(const primitive2d::PolygonHairlinePrimitive2D& rPolygonCandidate, bool bPixelBased);
void RenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate);
- void RenderRenderGraphicPrimitive2D(const primitive2d::RenderGraphicPrimitive2D& rRenderGraphicCandidate);
void RenderFillBitmapPrimitive2D(const primitive2d::FillBitmapPrimitive2D& rFillBitmapCandidate);
void RenderPolyPolygonGradientPrimitive2D(const primitive2d::PolyPolygonGradientPrimitive2D& rPolygonCandidate);
void RenderPolyPolygonBitmapPrimitive2D(const primitive2d::PolyPolygonBitmapPrimitive2D& rPolygonCandidate);
diff --git a/drawinglayer/inc/drawinglayer/processor3d/shadow3dextractor.hxx b/drawinglayer/inc/drawinglayer/processor3d/shadow3dextractor.hxx
index 24caa31905b0..d33c89ef0c76 100644
--- a/drawinglayer/inc/drawinglayer/processor3d/shadow3dextractor.hxx
+++ b/drawinglayer/inc/drawinglayer/processor3d/shadow3dextractor.hxx
@@ -51,12 +51,9 @@ namespace drawinglayer
class DRAWINGLAYER_DLLPUBLIC Shadow3DExtractingProcessor : public BaseProcessor3D
{
private:
- /// typedef for data handling
- typedef std::vector< primitive2d::BasePrimitive2D* > BasePrimitive2DVector;
-
/// result holding vector (2D) and target vector for stacking (inited to &maPrimitive2DSequence)
- BasePrimitive2DVector maPrimitive2DSequence;
- BasePrimitive2DVector* mpPrimitive2DSequence;
+ primitive2d::Primitive2DVector maPrimitive2DSequence;
+ primitive2d::Primitive2DVector* mpPrimitive2DSequence;
/// object transformation for scene for 2d definition
basegfx::B2DHomMatrix maObjectTransformation;
@@ -93,10 +90,6 @@ namespace drawinglayer
*/
virtual void processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate);
- /// helper to convert from BasePrimitive2DVector to primitive2d::Primitive2DSequence
- const primitive2d::Primitive2DSequence getPrimitive2DSequenceFromBasePrimitive2DVector(
- const BasePrimitive2DVector& rVector) const;
-
public:
Shadow3DExtractingProcessor(
const geometry::ViewInformation3D& rViewInformation,
diff --git a/drawinglayer/inc/drawinglayer/tools/converters.hxx b/drawinglayer/inc/drawinglayer/tools/converters.hxx
new file mode 100644
index 000000000000..1233f17717d1
--- /dev/null
+++ b/drawinglayer/inc/drawinglayer/tools/converters.hxx
@@ -0,0 +1,49 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http:\\www.apache.org\licenses\LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_DRAWINGLAYER_TOOLS_CONVERTERS_HXX
+#define INCLUDED_DRAWINGLAYER_TOOLS_CONVERTERS_HXX
+
+#include <drawinglayer/drawinglayerdllapi.h>
+#include <vcl/bitmapex.hxx>
+#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace tools
+ {
+ BitmapEx DRAWINGLAYER_DLLPUBLIC convertToBitmapEx(
+ const drawinglayer::primitive2d::Primitive2DSequence& rSeq,
+ const geometry::ViewInformation2D& rViewInformation2D,
+ sal_uInt32 nDiscreteWidth,
+ sal_uInt32 nDiscreteHeight,
+ sal_uInt32 nMaxQuadratPixels);
+
+ } // end of namespace tools
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_DRAWINGLAYER_TOOLS_CONVERTERS_HXX
+
+// eof
diff --git a/drawinglayer/source/drawinglayeruno/drawinglayeruno.cxx b/drawinglayer/source/drawinglayeruno/drawinglayeruno.cxx
new file mode 100644
index 000000000000..8ead3d1023b9
--- /dev/null
+++ b/drawinglayer/source/drawinglayeruno/drawinglayeruno.cxx
@@ -0,0 +1,95 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http:\\www.apache.org\licenses\LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/drawinglayerdllapi.h>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <uno/environment.h>
+#include <cppuhelper/factory.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace ::com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+// predefines
+
+namespace drawinglayer
+{
+ namespace unorenderer
+ {
+ extern uno::Sequence< rtl::OUString > SAL_CALL XPrimitive2DRenderer_getSupportedServiceNames();
+ extern rtl::OUString SAL_CALL XPrimitive2DRenderer_getImplementationName();
+ extern uno::Reference< uno::XInterface > SAL_CALL XPrimitive2DRenderer_createInstance( const uno::Reference< lang::XMultiServiceFactory > & );
+ } // end of namespace unorenderer
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// component_getImplementationEnvironment
+
+extern "C"
+{
+ DRAWINGLAYER_DLLPUBLIC void SAL_CALL component_getImplementationEnvironment( const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */ )
+ {
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// component_getFactory
+
+extern "C"
+{
+ DRAWINGLAYER_DLLPUBLIC void* SAL_CALL component_getFactory( const sal_Char* pImplName, void* pServiceManager, void* /* pRegistryKey */ )
+ {
+ uno::Reference< lang::XSingleServiceFactory > xFactory;
+ void* pRet = 0;
+
+ if(drawinglayer::unorenderer::XPrimitive2DRenderer_getImplementationName().equalsAscii(pImplName))
+ {
+ xFactory = ::cppu::createSingleFactory(
+ reinterpret_cast< lang::XMultiServiceFactory * >(pServiceManager),
+ drawinglayer::unorenderer::XPrimitive2DRenderer_getImplementationName(),
+ drawinglayer::unorenderer::XPrimitive2DRenderer_createInstance,
+ drawinglayer::unorenderer::XPrimitive2DRenderer_getSupportedServiceNames());
+ }
+
+ if(xFactory.is())
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/drawinglayeruno/xprimitive2drenderer.cxx b/drawinglayer/source/drawinglayeruno/xprimitive2drenderer.cxx
new file mode 100644
index 000000000000..c6667ad2319f
--- /dev/null
+++ b/drawinglayer/source/drawinglayeruno/xprimitive2drenderer.cxx
@@ -0,0 +1,223 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http:\\www.apache.org\licenses\LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <com/sun/star/graphic/XPrimitive2DRenderer.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/implbase2.hxx>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <comphelper/processfactory.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <basegfx/numeric/ftools.hxx>
+#include <vcl/bitmapex.hxx>
+#include <drawinglayer/tools/converters.hxx>
+#include <vcl/canvastools.hxx>
+#include <com/sun/star/geometry/RealRectangle2D.hpp>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace ::com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace unorenderer
+ {
+ class XPrimitive2DRenderer : public ::cppu::WeakAggImplHelper2< graphic::XPrimitive2DRenderer, lang::XServiceInfo >
+ {
+ private:
+ XPrimitive2DRenderer(const XPrimitive2DRenderer&);
+ XPrimitive2DRenderer& operator=(const XPrimitive2DRenderer&);
+
+ protected:
+ public:
+ XPrimitive2DRenderer();
+ virtual ~XPrimitive2DRenderer();
+
+ // XPrimitive2DRenderer
+ virtual uno::Reference< rendering::XBitmap > SAL_CALL rasterize(
+ const uno::Sequence< uno::Reference< graphic::XPrimitive2D > >& Primitive2DSequence,
+ const uno::Sequence< beans::PropertyValue >& aViewInformationSequence,
+ ::sal_uInt32 DPI_X,
+ ::sal_uInt32 DPI_Y,
+ const ::com::sun::star::geometry::RealRectangle2D& Range,
+ ::sal_uInt32 MaximumQuadraticPixels) throw (uno::RuntimeException);
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL getImplementationName() throw(uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL supportsService(const rtl::OUString&) throw(uno::RuntimeException);
+ virtual uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames() throw(uno::RuntimeException);
+ };
+ } // end of namespace unorenderer
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// uno functions
+
+namespace drawinglayer
+{
+ namespace unorenderer
+ {
+ uno::Sequence< rtl::OUString > XPrimitive2DRenderer_getSupportedServiceNames()
+ {
+ static rtl::OUString aServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.graphic.Primitive2DTools" ) );
+ static uno::Sequence< rtl::OUString > aServiceNames( &aServiceName, 1 );
+
+ return( aServiceNames );
+ }
+
+ rtl::OUString XPrimitive2DRenderer_getImplementationName()
+ {
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "drawinglayer::unorenderer::XPrimitive2DRenderer" ) );
+ }
+
+ uno::Reference< uno::XInterface > SAL_CALL XPrimitive2DRenderer_createInstance(const uno::Reference< lang::XMultiServiceFactory >&)
+ {
+ return static_cast< ::cppu::OWeakObject* >(new XPrimitive2DRenderer);
+ }
+ } // end of namespace unorenderer
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace unorenderer
+ {
+ XPrimitive2DRenderer::XPrimitive2DRenderer()
+ {
+ }
+
+ XPrimitive2DRenderer::~XPrimitive2DRenderer()
+ {
+ }
+
+ uno::Reference< rendering::XBitmap > XPrimitive2DRenderer::rasterize(
+ const uno::Sequence< uno::Reference< graphic::XPrimitive2D > >& Primitive2DSequence,
+ const uno::Sequence< beans::PropertyValue >& aViewInformationSequence,
+ ::sal_uInt32 DPI_X,
+ ::sal_uInt32 DPI_Y,
+ const ::com::sun::star::geometry::RealRectangle2D& Range,
+ ::sal_uInt32 MaximumQuadraticPixels) throw (uno::RuntimeException)
+ {
+ uno::Reference< rendering::XBitmap > XBitmap;
+
+ if(Primitive2DSequence.hasElements())
+ {
+ const basegfx::B2DRange aRange(Range.X1, Range.Y1, Range.X2, Range.Y2);
+ const double fWidth(aRange.getWidth());
+ const double fHeight(aRange.getHeight());
+
+ if(basegfx::fTools::more(fWidth, 0.0) && basegfx::fTools::more(fHeight, 0.0))
+ {
+ if(0 == DPI_X)
+ {
+ DPI_X = 75;
+ }
+
+ if(0 == DPI_Y)
+ {
+ DPI_Y = 75;
+ }
+
+ if(0 == MaximumQuadraticPixels)
+ {
+ MaximumQuadraticPixels = 500000;
+ }
+
+ const geometry::ViewInformation2D aViewInformation2D(aViewInformationSequence);
+ const double fFactor100th_mmToInch(2.54/1000.0);
+ const sal_uInt32 nDiscreteWidth(basegfx::fround((fWidth * fFactor100th_mmToInch) * DPI_X));
+ const sal_uInt32 nDiscreteHeight(basegfx::fround((fHeight * fFactor100th_mmToInch) * DPI_Y));
+
+ basegfx::B2DHomMatrix aEmbedding(
+ basegfx::tools::createTranslateB2DHomMatrix(
+ -aRange.getMinX(),
+ -aRange.getMinY()));
+
+ aEmbedding.scale(
+ nDiscreteWidth / fWidth,
+ nDiscreteHeight / fHeight);
+
+ const primitive2d::Primitive2DReference xEmbedRef(
+ new primitive2d::TransformPrimitive2D(
+ aEmbedding,
+ Primitive2DSequence));
+ const primitive2d::Primitive2DSequence xEmbedSeq(&xEmbedRef, 1);
+
+ BitmapEx aBitmapEx(
+ tools::convertToBitmapEx(
+ xEmbedSeq,
+ aViewInformation2D,
+ nDiscreteWidth,
+ nDiscreteHeight,
+ MaximumQuadraticPixels));
+
+ if(!aBitmapEx.IsEmpty())
+ {
+ const uno::Reference< rendering::XGraphicDevice > xGraphicDevice;
+
+ aBitmapEx.SetPrefMapMode(MapMode(MAP_100TH_MM));
+ aBitmapEx.SetPrefSize(Size(basegfx::fround(fWidth), basegfx::fround(fHeight)));
+ XBitmap = vcl::unotools::xBitmapFromBitmapEx(xGraphicDevice, aBitmapEx);
+ }
+ }
+ }
+
+ return XBitmap;
+ }
+
+ rtl::OUString SAL_CALL XPrimitive2DRenderer::getImplementationName() throw(uno::RuntimeException)
+ {
+ return(XPrimitive2DRenderer_getImplementationName());
+ }
+
+ sal_Bool SAL_CALL XPrimitive2DRenderer::supportsService(const rtl::OUString& rServiceName) throw(uno::RuntimeException)
+ {
+ const uno::Sequence< rtl::OUString > aServices(XPrimitive2DRenderer_getSupportedServiceNames());
+
+ for(sal_Int32 nService(0); nService < aServices.getLength(); nService++)
+ {
+ if(rServiceName == aServices[nService])
+ {
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+ }
+
+ uno::Sequence< rtl::OUString > SAL_CALL XPrimitive2DRenderer::getSupportedServiceNames() throw(uno::RuntimeException)
+ {
+ return XPrimitive2DRenderer_getSupportedServiceNames();
+ }
+
+ } // end of namespace unorenderer
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/baseprimitive2d.cxx b/drawinglayer/source/primitive2d/baseprimitive2d.cxx
index 8f5d7b14a157..868305b45208 100644
--- a/drawinglayer/source/primitive2d/baseprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/baseprimitive2d.cxx
@@ -115,6 +115,27 @@ namespace drawinglayer
{
namespace primitive2d
{
+ // convert helper stl vector of primitives to Primitive2DSequence
+ Primitive2DSequence Primitive2DVectorToPrimitive2DSequence(const Primitive2DVector& rSource, bool bInvert)
+ {
+ const sal_uInt32 nSize(rSource.size());
+ Primitive2DSequence aRetval;
+
+ aRetval.realloc(nSize);
+
+ for(sal_uInt32 a(0); a < nSize; a++)
+ {
+ aRetval[bInvert ? nSize - 1 - a : a] = rSource[a];
+ }
+
+ // all entries taken over to Uno References as owners. To avoid
+ // errors with users of this mechanism to delete pointers to BasePrimitive2D
+ // itself, clear given vector
+ const_cast< Primitive2DVector& >(rSource).clear();
+
+ return aRetval;
+ }
+
// get B2DRange from a given Primitive2DReference
basegfx::B2DRange getB2DRangeFromPrimitive2DReference(const Primitive2DReference& rCandidate, const geometry::ViewInformation2D& aViewInformation)
{
diff --git a/drawinglayer/source/primitive2d/cropprimitive2d.cxx b/drawinglayer/source/primitive2d/cropprimitive2d.cxx
new file mode 100644
index 000000000000..f4b6e82b9df0
--- /dev/null
+++ b/drawinglayer/source/primitive2d/cropprimitive2d.cxx
@@ -0,0 +1,202 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/cropprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ CropPrimitive2D::CropPrimitive2D(
+ const Primitive2DSequence& rChildren,
+ const basegfx::B2DHomMatrix& rTransformation,
+ double fCropLeft,
+ double fCropTop,
+ double fCropRight,
+ double fCropBottom)
+ : GroupPrimitive2D(rChildren),
+ maTransformation(rTransformation),
+ mfCropLeft(fCropLeft),
+ mfCropTop(fCropTop),
+ mfCropRight(fCropRight),
+ mfCropBottom(fCropBottom)
+ {
+ }
+
+ bool CropPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(GroupPrimitive2D::operator==(rPrimitive))
+ {
+ const CropPrimitive2D& rCompare = static_cast< const CropPrimitive2D& >(rPrimitive);
+
+ return (getTransformation() == rCompare.getTransformation()
+ && getCropLeft() == rCompare.getCropLeft()
+ && getCropTop() == rCompare.getCropTop()
+ && getCropRight() == rCompare.getCropRight()
+ && getCropBottom() == rCompare.getCropBottom());
+ }
+
+ return false;
+ }
+
+ Primitive2DSequence CropPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ Primitive2DSequence xRetval;
+
+ if(getChildren().hasElements())
+ {
+ // decompose to have current translate and scale
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+
+ getTransformation().decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // detect 180 degree rotation, this is the same as mirrored in X and Y,
+ // thus change to mirroring. Prefer mirroring here. Use the equal call
+ // with getSmallValue here, the original which uses rtl::math::approxEqual
+ // is too correct here. Maybe this changes with enhanced precision in aw080
+ // to the better so that this can be reduced to the more precise call again
+ if(basegfx::fTools::equal(fRotate, F_PI, 0.000000001))
+ {
+ aScale.setX(aScale.getX() * -1.0);
+ aScale.setY(aScale.getY() * -1.0);
+ fRotate = 0.0;
+ }
+
+ // create target translate and scale
+ const bool bMirroredX(aScale.getX() < 0.0);
+ const bool bMirroredY(aScale.getY() < 0.0);
+ basegfx::B2DVector aTargetScale(aScale);
+ basegfx::B2DVector aTargetTranslate(aTranslate);
+
+ if(bMirroredX)
+ {
+ aTargetTranslate.setX(aTargetTranslate.getX() + getCropRight());
+ aTargetScale.setX(aTargetScale.getX() - getCropLeft() - getCropRight());
+ }
+ else
+ {
+ aTargetTranslate.setX(aTargetTranslate.getX() - getCropLeft());
+ aTargetScale.setX(aTargetScale.getX() + getCropRight() + getCropLeft());
+ }
+
+ if(bMirroredY)
+ {
+ aTargetTranslate.setY(aTargetTranslate.getY() + getCropBottom());
+ aTargetScale.setY(aTargetScale.getY() - getCropTop() - getCropBottom());
+ }
+ else
+ {
+ aTargetTranslate.setY(aTargetTranslate.getY() - getCropTop());
+ aTargetScale.setY(aTargetScale.getY() + getCropBottom() + getCropTop());
+ }
+
+ // create ranges to make comparisons
+ const basegfx::B2DRange aCurrent(
+ aTranslate.getX(), aTranslate.getY(),
+ aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY());
+ const basegfx::B2DRange aCropped(
+ aTargetTranslate.getX(), aTargetTranslate.getY(),
+ aTargetTranslate.getX() + aTargetScale.getX(), aTargetTranslate.getY() + aTargetScale.getY());
+
+ if(aCropped.isEmpty())
+ {
+ // nothing to return since cropped content is completely empty
+ }
+ else if(aCurrent.equal(aCropped))
+ {
+ // no crop, just use content
+ xRetval = getChildren();
+ }
+ else
+ {
+ // build new combined content transformation
+ basegfx::B2DHomMatrix aNewObjectTransform(getTransformation());
+
+ // remove content transform by inverting
+ aNewObjectTransform.invert();
+
+ // add target values and original shear/rotate
+ aNewObjectTransform = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
+ aTargetScale.getX(),
+ aTargetScale.getY(),
+ fShearX,
+ fRotate,
+ aTargetTranslate.getX(),
+ aTargetTranslate.getY())
+ * aNewObjectTransform;
+
+ // prepare TransformPrimitive2D with xPrimitive
+ const Primitive2DReference xTransformPrimitive(
+ new TransformPrimitive2D(
+ aNewObjectTransform,
+ getChildren()));
+
+ if(aCurrent.isInside(aCropped))
+ {
+ // crop just shrunk so that its inside content,
+ // no need to use a mask since not really cropped.
+ xRetval = Primitive2DSequence(&xTransformPrimitive, 1);
+ }
+ else
+ {
+ // mask with original object's bounds
+ basegfx::B2DPolyPolygon aMaskPolyPolygon(basegfx::tools::createUnitPolygon());
+ aMaskPolyPolygon.transform(getTransformation());
+
+ // create maskPrimitive with aMaskPolyPolygon and aMaskContentVector
+ const Primitive2DReference xMask(
+ new MaskPrimitive2D(
+ aMaskPolyPolygon,
+ Primitive2DSequence(&xTransformPrimitive, 1)));
+
+ xRetval = Primitive2DSequence(&xMask, 1);
+ }
+ }
+ }
+
+ return xRetval;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(CropPrimitive2D, PRIMITIVE2D_ID_CROPPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
index f7a3930610d1..0703f9225b45 100644
--- a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
@@ -27,14 +27,14 @@
#include <drawinglayer/primitive2d/graphicprimitive2d.hxx>
#include <drawinglayer/animation/animationtiming.hxx>
#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
-#include <drawinglayer/primitive2d/rendergraphicprimitive2d.hxx>
#include <drawinglayer/primitive2d/animatedprimitive2d.hxx>
#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
-#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+#include <drawinglayer/primitive2d/cropprimitive2d.hxx>
#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
//////////////////////////////////////////////////////////////////////////////
// helper class for animated graphics
@@ -259,8 +259,8 @@ namespace drawinglayer
aSuppressGraphicAttr.SetRotation(0);
aSuppressGraphicAttr.SetMirrorFlags(0);
- const GraphicObject& rGraphicObject = getGraphicObject();
- const Graphic aTransformedGraphic(rGraphicObject.GetTransformedGraphic(&aSuppressGraphicAttr));
+ const GraphicObject& rGraphicObject = getGraphicObject();
+ const Graphic aTransformedGraphic(rGraphicObject.GetTransformedGraphic(&aSuppressGraphicAttr));
switch(aTransformedGraphic.GetType())
{
@@ -293,6 +293,32 @@ namespace drawinglayer
xPrimitive = Primitive2DReference(new AnimatedSwitchPrimitive2D(aAnimationList, aBitmapPrimitives, false));
}
}
+ else if(aTransformedGraphic.getSvgData().get())
+ {
+ // embedded Svg fill, create embed transform
+ const basegfx::B2DRange& rSvgRange(aTransformedGraphic.getSvgData()->getRange());
+
+ if(basegfx::fTools::more(rSvgRange.getWidth(), 0.0) && basegfx::fTools::more(rSvgRange.getHeight(), 0.0))
+ {
+ // translate back to origin, scale to unit coordinates
+ basegfx::B2DHomMatrix aEmbedSvg(
+ basegfx::tools::createTranslateB2DHomMatrix(
+ -rSvgRange.getMinX(),
+ -rSvgRange.getMinY()));
+
+ aEmbedSvg.scale(
+ 1.0 / rSvgRange.getWidth(),
+ 1.0 / rSvgRange.getHeight());
+
+ // apply created object transformation
+ aEmbedSvg = aTransform * aEmbedSvg;
+
+ // add Svg primitives embedded
+ xPrimitive = new TransformPrimitive2D(
+ aEmbedSvg,
+ aTransformedGraphic.getSvgData()->getPrimitive2DSequence());
+ }
+ }
else
{
xPrimitive = Primitive2DReference(new BitmapPrimitive2D(aTransformedGraphic.GetBitmapEx(), aTransform));
@@ -745,41 +771,31 @@ namespace drawinglayer
// create MetafilePrimitive2D
const GDIMetaFile& rMetafile = aTransformedGraphic.GetGDIMetaFile();
- if( aTransformedGraphic.IsRenderGraphic() )
+ xPrimitive = Primitive2DReference(
+ new MetafilePrimitive2D(
+ aTransform,
+ rMetafile));
+
+ // #i100357# find out if clipping is needed for this primitive. Unfortunately,
+ // there exist Metafiles who's content is bigger than the proposed PrefSize set
+ // at them. This is an error, but we need to work around this
+ const Size aMetaFilePrefSize(rMetafile.GetPrefSize());
+ const Size aMetaFileRealSize(
+ const_cast< GDIMetaFile& >(rMetafile).GetBoundRect(
+ *Application::GetDefaultDevice()).GetSize());
+
+ if(aMetaFileRealSize.getWidth() > aMetaFilePrefSize.getWidth()
+ || aMetaFileRealSize.getHeight() > aMetaFilePrefSize.getHeight())
{
+ // clipping needed. Embed to MaskPrimitive2D. Create childs and mask polygon
+ const primitive2d::Primitive2DSequence aChildContent(&xPrimitive, 1);
+ basegfx::B2DPolygon aMaskPolygon(basegfx::tools::createUnitPolygon());
+ aMaskPolygon.transform(aTransform);
+
xPrimitive = Primitive2DReference(
- new RenderGraphicPrimitive2D(
- static_cast< MetaRenderGraphicAction* >(rMetafile.GetAction(0))->GetRenderGraphic(),
- aTransform));
- }
- else
- {
- xPrimitive = Primitive2DReference(
- new MetafilePrimitive2D(
- aTransform,
- rMetafile));
-
- // #i100357# find out if clipping is needed for this primitive. Unfortunately,
- // there exist Metafiles who's content is bigger than the proposed PrefSize set
- // at them. This is an error, but we need to work around this
- const Size aMetaFilePrefSize(rMetafile.GetPrefSize());
- const Size aMetaFileRealSize(
- const_cast< GDIMetaFile& >(rMetafile).GetBoundRect(
- *Application::GetDefaultDevice()).GetSize());
-
- if(aMetaFileRealSize.getWidth() > aMetaFilePrefSize.getWidth()
- || aMetaFileRealSize.getHeight() > aMetaFilePrefSize.getHeight())
- {
- // clipping needed. Embed to MaskPrimitive2D. Create childs and mask polygon
- const primitive2d::Primitive2DSequence aChildContent(&xPrimitive, 1);
- basegfx::B2DPolygon aMaskPolygon(basegfx::tools::createUnitPolygon());
- aMaskPolygon.transform(aTransform);
-
- xPrimitive = Primitive2DReference(
- new MaskPrimitive2D(
- basegfx::B2DPolyPolygon(aMaskPolygon),
- aChildContent));
- }
+ new MaskPrimitive2D(
+ basegfx::B2DPolyPolygon(aMaskPolygon),
+ aChildContent));
}
#ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
}
@@ -800,16 +816,6 @@ namespace drawinglayer
// check for cropping
if(getGraphicAttr().IsCropped())
{
- // decompose to get current pos and size
- basegfx::B2DVector aScale, aTranslate;
- double fRotate, fShearX;
- getTransform().decompose(aScale, aTranslate, fRotate, fShearX);
-
- // create ranges. The current object range is just scale and translate
- const basegfx::B2DRange aCurrent(
- aTranslate.getX(), aTranslate.getY(),
- aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY());
-
// calculate scalings between real image size and logic object size. This
// is necessary since the crop values are relative to original bitmap size
double fFactorX(1.0);
@@ -831,68 +837,31 @@ namespace drawinglayer
const double fDivX(aBitmapSize.Width() - getGraphicAttr().GetLeftCrop() - getGraphicAttr().GetRightCrop());
const double fDivY(aBitmapSize.Height() - getGraphicAttr().GetTopCrop() - getGraphicAttr().GetBottomCrop());
+ const basegfx::B2DVector aScale(aTransform * basegfx::B2DVector(1.0, 1.0));
if(!basegfx::fTools::equalZero(fDivX))
{
- fFactorX = aScale.getX() / fDivX;
+ fFactorX = fabs(aScale.getX()) / fDivX;
}
if(!basegfx::fTools::equalZero(fDivY))
{
- fFactorY = aScale.getY() / fDivY;
+ fFactorY = fabs(aScale.getY()) / fDivY;
}
}
- // Create cropped range, describes the bounds of the original graphic
- basegfx::B2DRange aCropped;
- aCropped.expand(aCurrent.getMinimum() - basegfx::B2DPoint(getGraphicAttr().GetLeftCrop() * fFactorX, getGraphicAttr().GetTopCrop() * fFactorY));
- aCropped.expand(aCurrent.getMaximum() + basegfx::B2DPoint(getGraphicAttr().GetRightCrop() * fFactorX, getGraphicAttr().GetBottomCrop() * fFactorY));
-
- if(aCropped.isEmpty())
- {
- // nothing to add since cropped bitmap is completely empty
- // xPrimitive will not be used
- }
- else
- {
- // build new object transformation for transform primitive which contains xPrimitive
- basegfx::B2DHomMatrix aNewObjectTransform(getTransform());
- aNewObjectTransform.invert();
- aNewObjectTransform = basegfx::tools::createScaleTranslateB2DHomMatrix(
- aCropped.getWidth(), aCropped.getHeight(),
- aCropped.getMinX() - aCurrent.getMinX(), aCropped.getMinY() - aCurrent.getMinY())
- * aNewObjectTransform;
-
- // add shear, rotate and translate using combined matrix to speedup
- const basegfx::B2DHomMatrix aCombinedMatrix(basegfx::tools::createShearXRotateTranslateB2DHomMatrix(
- fShearX, fRotate, aTranslate.getX(), aTranslate.getY()));
- aNewObjectTransform = aCombinedMatrix * aNewObjectTransform;
-
- // prepare TransformPrimitive2D with xPrimitive
- const Primitive2DReference xTransformPrimitive(new TransformPrimitive2D(aNewObjectTransform, Primitive2DSequence(&xPrimitive, 1L)));
-
- if(aCurrent.isInside(aCropped))
- {
- // cropped just got smaller, no need to really use a mask. Add to destination directly
- appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xTransformPrimitive);
- }
- else
- {
- // cropped got bigger, mask it with original object's bounds
- basegfx::B2DPolyPolygon aMaskPolyPolygon(basegfx::tools::createUnitPolygon());
- aMaskPolyPolygon.transform(getTransform());
-
- // create maskPrimitive with aMaskPolyPolygon and aMaskContentVector
- const Primitive2DReference xRefB(new MaskPrimitive2D(aMaskPolyPolygon, Primitive2DSequence(&xTransformPrimitive, 1L)));
- appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xRefB);
- }
- }
- }
- else
- {
- // add to decomposition
- appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xPrimitive);
+ // embed content in cropPrimitive
+ xPrimitive = new CropPrimitive2D(
+ Primitive2DSequence(&xPrimitive, 1),
+ aTransform,
+ getGraphicAttr().GetLeftCrop() * fFactorX,
+ getGraphicAttr().GetTopCrop() * fFactorY,
+ getGraphicAttr().GetRightCrop() * fFactorX,
+ getGraphicAttr().GetBottomCrop() * fFactorY);
}
+
+ // add to decomposition
+ appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xPrimitive);
}
}
diff --git a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
index 4d11fe523754..a3eff771d4da 100644
--- a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
@@ -59,7 +59,6 @@
#include <drawinglayer/primitive2d/textlineprimitive2d.hxx>
#include <drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx>
#include <drawinglayer/primitive2d/epsprimitive2d.hxx>
-#include <drawinglayer/primitive2d/rendergraphicprimitive2d.hxx>
#include <numeric>
//////////////////////////////////////////////////////////////////////////////
@@ -3065,33 +3064,6 @@ namespace
break;
}
- case META_RENDERGRAPHIC_ACTION :
- {
- const MetaRenderGraphicAction* pA = (const MetaRenderGraphicAction*)pAction;
- const Rectangle aRectangle(pA->GetPoint(), pA->GetSize());
-
- if(!aRectangle.IsEmpty())
- {
- // create object transform
- basegfx::B2DHomMatrix aObjectTransform;
-
- aObjectTransform.set(0, 0, aRectangle.GetWidth());
- aObjectTransform.set(1, 1, aRectangle.GetHeight());
- aObjectTransform.set(0, 2, aRectangle.Left());
- aObjectTransform.set(1, 2, aRectangle.Top());
-
- // add current transformation
- aObjectTransform = rPropertyHolders.Current().getTransformation() * aObjectTransform;
-
- // embed using EpsPrimitive
- rTargetHolders.Current().append(
- new drawinglayer::primitive2d::RenderGraphicPrimitive2D(
- pA->GetRenderGraphic(),
- aObjectTransform ) );
- }
-
- break;
- }
case META_COMMENT_ACTION :
{
/** CHECKED, WORKS WELL */
diff --git a/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx b/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx
new file mode 100644
index 000000000000..3c334d2770c9
--- /dev/null
+++ b/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx
@@ -0,0 +1,158 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/patternfillprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <drawinglayer/texture/texture.hxx>
+#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence PatternFillPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ Primitive2DSequence aRetval;
+
+ if(getChildren().hasElements())
+ {
+ if(!getReferenceRange().isEmpty() && getReferenceRange().getWidth() > 0.0 && getReferenceRange().getHeight() > 0.0)
+ {
+ const basegfx::B2DRange aMaskRange(getMask().getB2DRange());
+
+ if(!aMaskRange.isEmpty() && aMaskRange.getWidth() > 0.0 && aMaskRange.getHeight() > 0.0)
+ {
+ // create tiling matrices
+ ::std::vector< basegfx::B2DHomMatrix > aMatrices;
+ texture::GeoTexSvxTiled aTiling(getReferenceRange().getMinimum(), getReferenceRange().getRange());
+ aTiling.appendTransformations(aMatrices);
+
+ // check if content needs to be clipped
+ const basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0);
+ const basegfx::B2DRange aContentRange(getB2DRangeFromPrimitive2DSequence(getChildren(), rViewInformation));
+ Primitive2DSequence aContent(getChildren());
+
+ if(!aUnitRange.isInside(aContentRange))
+ {
+ const Primitive2DReference xRef(
+ new MaskPrimitive2D(
+ basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(aUnitRange)),
+ aContent));
+
+ aContent = Primitive2DSequence(&xRef, 1);
+ }
+
+ // resize result
+ aRetval.realloc(aMatrices.size());
+
+ // create one primitive for each matrix
+ for(sal_uInt32 a(0); a < aMatrices.size(); a++)
+ {
+ aRetval[a] = new TransformPrimitive2D(
+ aMatrices[a],
+ aContent);
+ }
+
+ // transform result which is in unit coordinates to mask's object coordiantes
+ {
+ const basegfx::B2DHomMatrix aMaskTransform(
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ aMaskRange.getRange(),
+ aMaskRange.getMinimum()));
+
+ const Primitive2DReference xRef(
+ new TransformPrimitive2D(
+ aMaskTransform,
+ aRetval));
+
+ aRetval = Primitive2DSequence(&xRef, 1);
+ }
+
+ // embed result in mask
+ {
+ const Primitive2DReference xRef(
+ new MaskPrimitive2D(
+ getMask(),
+ aRetval));
+
+ aRetval = Primitive2DSequence(&xRef, 1);
+ }
+
+ }
+ }
+ }
+
+ return aRetval;
+ }
+
+ PatternFillPrimitive2D::PatternFillPrimitive2D(
+ const basegfx::B2DPolyPolygon& rMask,
+ const Primitive2DSequence& rChildren,
+ const basegfx::B2DRange& rReferenceRange)
+ : BufferedDecompositionPrimitive2D(),
+ maMask(rMask),
+ maChildren(rChildren),
+ maReferenceRange(rReferenceRange)
+ {
+ }
+
+ bool PatternFillPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
+ {
+ const PatternFillPrimitive2D& rCompare = static_cast< const PatternFillPrimitive2D& >(rPrimitive);
+
+ return (getMask() == rCompare.getMask()
+ && getChildren() == rCompare.getChildren()
+ && getReferenceRange() == rCompare.getReferenceRange());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange PatternFillPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ return getMask().getB2DRange();
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(PatternFillPrimitive2D, PRIMITIVE2D_ID_PATTERNFILLPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/rendergraphicprimitive2d.cxx b/drawinglayer/source/primitive2d/rendergraphicprimitive2d.cxx
deleted file mode 100644
index 439937f5d0f5..000000000000
--- a/drawinglayer/source/primitive2d/rendergraphicprimitive2d.cxx
+++ /dev/null
@@ -1,92 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_drawinglayer.hxx"
-
-#include <drawinglayer/primitive2d/rendergraphicprimitive2d.hxx>
-#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
-#include <basegfx/tools/canvastools.hxx>
-#include <vcl/rendergraphicrasterizer.hxx>
-
-//////////////////////////////////////////////////////////////////////////////
-
-using namespace com::sun::star;
-
-//////////////////////////////////////////////////////////////////////////////
-
-namespace drawinglayer
-{
- namespace primitive2d
- {
- RenderGraphicPrimitive2D::RenderGraphicPrimitive2D(
- const vcl::RenderGraphic& rRenderGraphic,
- const basegfx::B2DHomMatrix& rTransform)
- : BasePrimitive2D(),
- maRenderGraphic(rRenderGraphic),
- maTransform(rTransform)
- {
- }
-
- void RenderGraphicPrimitive2D::setCurrentRasterizer() const
- {
- mapCurrentRasterizer.reset();
- }
-
- void RenderGraphicPrimitive2D::setCurrentRasterizer( const vcl::RenderGraphicRasterizer& rCurrentRasterizer ) const
- {
- mapCurrentRasterizer.reset( new vcl::RenderGraphicRasterizer( rCurrentRasterizer ) );
- }
-
- bool RenderGraphicPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
- {
- if(BasePrimitive2D::operator==(rPrimitive))
- {
- const RenderGraphicPrimitive2D& rCompare = (RenderGraphicPrimitive2D&)rPrimitive;
-
- return (getRenderGraphic() == rCompare.getRenderGraphic()
- && getTransform() == rCompare.getTransform());
- }
-
- return false;
- }
-
- basegfx::B2DRange RenderGraphicPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
- {
- basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
- aRetval.transform(maTransform);
- return aRetval;
- }
-
- // provide unique ID
- ImplPrimitrive2DIDBlock(RenderGraphicPrimitive2D, PRIMITIVE2D_ID_RENDERGRAPHICPRIMITIVE2D)
-
- } // end of namespace primitive2d
-} // end of namespace drawinglayer
-
-//////////////////////////////////////////////////////////////////////////////
-// eof
diff --git a/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx b/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
new file mode 100644
index 000000000000..199fc3d3fb03
--- /dev/null
+++ b/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
@@ -0,0 +1,1249 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http:\\www.apache.org\licenses\LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/svggradientprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <drawinglayer/primitive2d/transparenceprimitive2d.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence SvgGradientHelper::createSingleGradientEntryFill() const
+ {
+ const SvgGradientEntryVector& rEntries = getGradientEntries();
+ const sal_uInt32 nCount(rEntries.size());
+ Primitive2DSequence xRetval;
+
+ if(nCount)
+ {
+ const SvgGradientEntry& rSingleEntry = rEntries[nCount - 1];
+ const double fOpacity(rSingleEntry.getOpacity());
+
+ if(fOpacity > 0.0)
+ {
+ Primitive2DReference xRef(
+ new PolyPolygonColorPrimitive2D(
+ getPolyPolygon(),
+ rSingleEntry.getColor()));
+
+ if(fOpacity < 1.0)
+ {
+ const Primitive2DSequence aContent(&xRef, 1);
+
+ xRef = Primitive2DReference(
+ new UnifiedTransparencePrimitive2D(
+ aContent,
+ 1.0 - fOpacity));
+ }
+
+ xRetval = Primitive2DSequence(&xRef, 1);
+ }
+ }
+ else
+ {
+ OSL_ENSURE(false, "Single gradient entry construction without entry (!)");
+ }
+
+ return xRetval;
+ }
+
+ void SvgGradientHelper::checkPreconditions()
+ {
+ mbPreconditionsChecked = true;
+ const SvgGradientEntryVector& rEntries = getGradientEntries();
+
+ if(rEntries.empty())
+ {
+ // no fill at all
+ }
+ else
+ {
+ const sal_uInt32 nCount(rEntries.size());
+
+ if(1 == nCount)
+ {
+ // fill with single existing color
+ setSingleEntry();
+ }
+ else
+ {
+ // sort maGradientEntries when more than one
+ std::sort(maGradientEntries.begin(), maGradientEntries.end());
+
+ // gradient with at least two colors
+ bool bAllInvisible(true);
+
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ const SvgGradientEntry& rCandidate = rEntries[a];
+
+ if(basegfx::fTools::equalZero(rCandidate.getOpacity()))
+ {
+ // invisible
+ mbFullyOpaque = false;
+ }
+ else if(basegfx::fTools::equal(rCandidate.getOpacity(), 1.0))
+ {
+ // completely opaque
+ bAllInvisible = false;
+ }
+ else
+ {
+ // opacity
+ bAllInvisible = false;
+ mbFullyOpaque = false;
+ }
+ }
+
+ if(bAllInvisible)
+ {
+ // all invisible, nothing to do
+ }
+ else
+ {
+ const basegfx::B2DRange aPolyRange(getPolyPolygon().getB2DRange());
+
+ if(aPolyRange.isEmpty())
+ {
+ // no range to fill, nothing to do
+ }
+ else
+ {
+ const double fPolyWidth(aPolyRange.getWidth());
+ const double fPolyHeight(aPolyRange.getHeight());
+
+ if(basegfx::fTools::equalZero(fPolyWidth) || basegfx::fTools::equalZero(fPolyHeight))
+ {
+ // no width/height to fill, nothing to do
+ }
+ else
+ {
+ mbCreatesContent = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ double SvgGradientHelper::createRun(
+ Primitive2DVector& rTargetColor,
+ Primitive2DVector& rTargetOpacity,
+ double fPos,
+ double fMax,
+ const SvgGradientEntryVector& rEntries,
+ sal_Int32 nOffset) const
+ {
+ const sal_uInt32 nCount(rEntries.size());
+
+ if(nCount)
+ {
+ const SvgGradientEntry& rStart = rEntries[0];
+ const bool bCreateStartPad(fPos < 0.0 && Spread_pad == getSpreadMethod());
+ const bool bCreateStartFill(rStart.getOffset() > 0.0);
+ sal_uInt32 nIndex(0);
+
+ if(bCreateStartPad || bCreateStartFill)
+ {
+ const SvgGradientEntry aTemp(bCreateStartPad ? fPos : 0.0, rStart.getColor(), rStart.getOpacity());
+
+ createAtom(rTargetColor, rTargetOpacity, aTemp, rStart, nOffset);
+ fPos = rStart.getOffset();
+ }
+
+ while(fPos < 1.0 && nIndex + 1 < nCount)
+ {
+ const SvgGradientEntry& rCandidateA = rEntries[nIndex++];
+ const SvgGradientEntry& rCandidateB = rEntries[nIndex];
+
+ createAtom(rTargetColor, rTargetOpacity, rCandidateA, rCandidateB, nOffset);
+ fPos = rCandidateB.getOffset();
+ }
+
+ const SvgGradientEntry& rEnd = rEntries[nCount - 1];
+ const bool bCreateEndPad(fPos < fMax && Spread_pad == getSpreadMethod());
+ const bool bCreateEndFill(rEnd.getOffset() < 1.0);
+
+ if(bCreateEndPad || bCreateEndFill)
+ {
+ fPos = bCreateEndPad ? fMax : 1.0;
+ const SvgGradientEntry aTemp(fPos, rEnd.getColor(), rEnd.getOpacity());
+
+ createAtom(rTargetColor, rTargetOpacity, rEnd, aTemp, nOffset);
+ }
+ }
+ else
+ {
+ OSL_ENSURE(false, "GradientAtom creation without ColorStops (!)");
+ fPos = fMax;
+ }
+
+ return fPos;
+ }
+
+ Primitive2DSequence SvgGradientHelper::createResult(
+ const Primitive2DVector& rTargetColor,
+ const Primitive2DVector& rTargetOpacity,
+ const basegfx::B2DHomMatrix& rUnitGradientToObject,
+ bool bInvert) const
+ {
+ Primitive2DSequence xRetval;
+ const Primitive2DSequence aTargetColorEntries(Primitive2DVectorToPrimitive2DSequence(rTargetColor, bInvert));
+ const Primitive2DSequence aTargetOpacityEntries(Primitive2DVectorToPrimitive2DSequence(rTargetOpacity, bInvert));
+
+ if(aTargetColorEntries.hasElements())
+ {
+ Primitive2DReference xRefContent;
+
+ if(aTargetOpacityEntries.hasElements())
+ {
+ const Primitive2DReference xRefOpacity = new TransparencePrimitive2D(
+ aTargetColorEntries,
+ aTargetOpacityEntries);
+
+ xRefContent = new TransformPrimitive2D(
+ rUnitGradientToObject,
+ Primitive2DSequence(&xRefOpacity, 1));
+ }
+ else
+ {
+ xRefContent = new TransformPrimitive2D(
+ rUnitGradientToObject,
+ aTargetColorEntries);
+ }
+
+ xRefContent = new MaskPrimitive2D(
+ getPolyPolygon(),
+ Primitive2DSequence(&xRefContent, 1));
+
+ xRetval = Primitive2DSequence(&xRefContent, 1);
+ }
+
+ return xRetval;
+ }
+
+ SvgGradientHelper::SvgGradientHelper(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
+ const SvgGradientEntryVector& rGradientEntries,
+ const basegfx::B2DPoint& rStart,
+ SpreadMethod aSpreadMethod,
+ double fOverlapping)
+ : maPolyPolygon(rPolyPolygon),
+ maGradientEntries(rGradientEntries),
+ maStart(rStart),
+ maSpreadMethod(aSpreadMethod),
+ mfOverlapping(fOverlapping),
+ mbPreconditionsChecked(false),
+ mbCreatesContent(false),
+ mbSingleEntry(false),
+ mbFullyOpaque(true)
+ {
+ }
+
+ bool SvgGradientHelper::operator==(const SvgGradientHelper& rSvgGradientHelper) const
+ {
+ const SvgGradientHelper& rCompare = static_cast< const SvgGradientHelper& >(rSvgGradientHelper);
+
+ return (getPolyPolygon() == rCompare.getPolyPolygon()
+ && getGradientEntries() == rCompare.getGradientEntries()
+ && getStart() == rCompare.getStart()
+ && getSpreadMethod() == rCompare.getSpreadMethod()
+ && getOverlapping() == rCompare.getOverlapping());
+ }
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ void SvgLinearGradientPrimitive2D::checkPreconditions()
+ {
+ // call parent
+ SvgGradientHelper::checkPreconditions();
+
+ if(getCreatesContent())
+ {
+ // Check Vector
+ const basegfx::B2DVector aVector(getEnd() - getStart());
+
+ if(basegfx::fTools::equalZero(aVector.getX()) && basegfx::fTools::equalZero(aVector.getY()))
+ {
+ // fill with single color using last stop color
+ setSingleEntry();
+ }
+ }
+ }
+
+ void SvgLinearGradientPrimitive2D::ensureGeometry(
+ basegfx::B2DPolyPolygon& rPolyPolygon,
+ const SvgGradientEntry& rFrom,
+ const SvgGradientEntry& rTo,
+ sal_Int32 nOffset) const
+ {
+ if(!rPolyPolygon.count())
+ {
+ rPolyPolygon.append(
+ basegfx::tools::createPolygonFromRect(
+ basegfx::B2DRange(
+ rFrom.getOffset() - getOverlapping() + nOffset,
+ 0.0,
+ rTo.getOffset() + getOverlapping() + nOffset,
+ 1.0)));
+ }
+ }
+
+ void SvgLinearGradientPrimitive2D::createAtom(
+ Primitive2DVector& rTargetColor,
+ Primitive2DVector& rTargetOpacity,
+ const SvgGradientEntry& rFrom,
+ const SvgGradientEntry& rTo,
+ sal_Int32 nOffset) const
+ {
+ // create gradient atom [rFrom.getOffset() .. rTo.getOffset()] with (rFrom.getOffset() > rTo.getOffset())
+ if(rFrom.getOffset() == rTo.getOffset())
+ {
+ OSL_ENSURE(false, "SvgGradient Atom creation with no step width (!)");
+ }
+ else
+ {
+ const bool bColorChange(rFrom.getColor() != rTo.getColor());
+ const bool bOpacityChange(rFrom.getOpacity() != rTo.getOpacity());
+ basegfx::B2DPolyPolygon aPolyPolygon;
+
+ if(bColorChange)
+ {
+ rTargetColor.push_back(
+ new SvgLinearAtomPrimitive2D(
+ rFrom.getColor(), rFrom.getOffset() + nOffset,
+ rTo.getColor(), rTo.getOffset() + nOffset,
+ getOverlapping()));
+ }
+ else
+ {
+ ensureGeometry(aPolyPolygon, rFrom, rTo, nOffset);
+ rTargetColor.push_back(
+ new PolyPolygonColorPrimitive2D(
+ aPolyPolygon,
+ rFrom.getColor()));
+ }
+
+ if(bOpacityChange)
+ {
+ const double fTransFrom(1.0 - rFrom.getOpacity());
+ const double fTransTo(1.0 - rTo.getOpacity());
+
+ rTargetOpacity.push_back(
+ new SvgLinearAtomPrimitive2D(
+ basegfx::BColor(fTransFrom, fTransFrom, fTransFrom), rFrom.getOffset() + nOffset,
+ basegfx::BColor(fTransTo,fTransTo, fTransTo), rTo.getOffset() + nOffset,
+ getOverlapping()));
+ }
+ else if(!getFullyOpaque())
+ {
+ const double fTransparence(1.0 - rFrom.getOpacity());
+
+ ensureGeometry(aPolyPolygon, rFrom, rTo, nOffset);
+ rTargetOpacity.push_back(
+ new PolyPolygonColorPrimitive2D(
+ aPolyPolygon,
+ basegfx::BColor(fTransparence, fTransparence, fTransparence)));
+ }
+ }
+ }
+
+ Primitive2DSequence SvgLinearGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ Primitive2DSequence xRetval;
+
+ if(!getPreconditionsChecked())
+ {
+ const_cast< SvgLinearGradientPrimitive2D* >(this)->checkPreconditions();
+ }
+
+ if(getSingleEntry())
+ {
+ // fill with last existing color
+ xRetval = createSingleGradientEntryFill();
+ }
+ else if(getCreatesContent())
+ {
+ // at least two color stops in range [0.0 .. 1.0], sorted, non-null vector, not completely
+ // invisible, width and height to fill are not empty
+ const basegfx::B2DRange aPolyRange(getPolyPolygon().getB2DRange());
+ const double fPolyWidth(aPolyRange.getWidth());
+ const double fPolyHeight(aPolyRange.getHeight());
+
+ // create ObjectTransform based on polygon range
+ const basegfx::B2DHomMatrix aObjectTransform(
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ fPolyWidth, fPolyHeight,
+ aPolyRange.getMinX(), aPolyRange.getMinY()));
+
+ // create unit transform from unit vector [0.0 .. 1.0] along the X-Axis to given
+ // gradient vector defined by Start,End
+ const basegfx::B2DVector aVector(getEnd() - getStart());
+ const double fVectorLength(aVector.getLength());
+ basegfx::B2DHomMatrix aUnitGradientToGradient;
+
+ aUnitGradientToGradient.scale(fVectorLength, 1.0);
+ aUnitGradientToGradient.rotate(atan2(aVector.getY(), aVector.getX()));
+ aUnitGradientToGradient.translate(getStart().getX(), getStart().getY());
+
+ // create full transform from unit gradient coordinates to object coordinates
+ // including the SvgGradient transformation
+ basegfx::B2DHomMatrix aUnitGradientToObject(aObjectTransform * aUnitGradientToGradient);
+
+ // create inverse from it
+ basegfx::B2DHomMatrix aObjectToUnitGradient(aUnitGradientToObject);
+ aObjectToUnitGradient.invert();
+
+ // back-transform polygon to unit gradient coordinates and get
+ // UnitRage. This is the range the gradient has to cover
+ basegfx::B2DPolyPolygon aUnitPoly(getPolyPolygon());
+ aUnitPoly.transform(aObjectToUnitGradient);
+ const basegfx::B2DRange aUnitRange(aUnitPoly.getB2DRange());
+
+ // prepare result vectors
+ Primitive2DVector aTargetColor;
+ Primitive2DVector aTargetOpacity;
+
+ if(basegfx::fTools::more(aUnitRange.getWidth(), 0.0))
+ {
+ // add a pre-multiply to aUnitGradientToObject to allow
+ // multiplication of the polygon(xl, 0.0, xr, 1.0)
+ const basegfx::B2DHomMatrix aPreMultiply(
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ 1.0, aUnitRange.getHeight(), 0.0, aUnitRange.getMinY()));
+ aUnitGradientToObject = aUnitGradientToObject * aPreMultiply;
+
+ // create central run, may also already do all necessary when
+ // Spread_pad is set as SpreadMethod and/or the range is smaller
+ double fPos(createRun(aTargetColor, aTargetOpacity, aUnitRange.getMinX(), aUnitRange.getMaxX(), getGradientEntries(), 0));
+
+ if(fPos < aUnitRange.getMaxX())
+ {
+ // can only happen when SpreadMethod is Spread_reflect or Spread_repeat,
+ // else the start and end pads are already created and fPos == aUnitRange.getMaxX().
+ // Its possible to express the repeated linear gradient by adding the
+ // transformed central run. Crete it this way
+ Primitive2DSequence aTargetColorEntries(Primitive2DVectorToPrimitive2DSequence(aTargetColor));
+ Primitive2DSequence aTargetOpacityEntries(Primitive2DVectorToPrimitive2DSequence(aTargetOpacity));
+ aTargetColor.clear();
+ aTargetOpacity.clear();
+
+ if(aTargetColorEntries.hasElements())
+ {
+ // add original central run as group primitive
+ aTargetColor.push_back(new GroupPrimitive2D(aTargetColorEntries));
+
+ if(aTargetOpacityEntries.hasElements())
+ {
+ aTargetOpacity.push_back(new GroupPrimitive2D(aTargetOpacityEntries));
+ }
+
+ // add negative runs
+ fPos = 0.0;
+ sal_Int32 nOffset(0);
+
+ while(fPos > aUnitRange.getMinX())
+ {
+ fPos -= 1.0;
+ nOffset++;
+
+ basegfx::B2DHomMatrix aTransform;
+ const bool bMirror(Spread_reflect == getSpreadMethod() && (nOffset % 2));
+
+ if(bMirror)
+ {
+ aTransform.scale(-1.0, 1.0);
+ aTransform.translate(fPos + 1.0, 0.0);
+ }
+ else
+ {
+ aTransform.translate(fPos, 0.0);
+ }
+
+ aTargetColor.push_back(new TransformPrimitive2D(aTransform, aTargetColorEntries));
+
+ if(aTargetOpacityEntries.hasElements())
+ {
+ aTargetOpacity.push_back(new TransformPrimitive2D(aTransform, aTargetOpacityEntries));
+ }
+ }
+
+ // add positive runs
+ fPos = 1.0;
+ nOffset = 1;
+
+ while(fPos < aUnitRange.getMaxX())
+ {
+ basegfx::B2DHomMatrix aTransform;
+ const bool bMirror(Spread_reflect == getSpreadMethod() && (nOffset % 2));
+
+ if(bMirror)
+ {
+ aTransform.scale(-1.0, 1.0);
+ aTransform.translate(fPos + 1.0, 0.0);
+ }
+ else
+ {
+ aTransform.translate(fPos, 0.0);
+ }
+
+ aTargetColor.push_back(new TransformPrimitive2D(aTransform, aTargetColorEntries));
+
+ if(aTargetOpacityEntries.hasElements())
+ {
+ aTargetOpacity.push_back(new TransformPrimitive2D(aTransform, aTargetOpacityEntries));
+ }
+
+ fPos += 1.0;
+ nOffset++;
+ }
+ }
+ }
+ }
+
+ xRetval = createResult(aTargetColor, aTargetOpacity, aUnitGradientToObject);
+ }
+
+ return xRetval;
+ }
+
+ SvgLinearGradientPrimitive2D::SvgLinearGradientPrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
+ const SvgGradientEntryVector& rGradientEntries,
+ const basegfx::B2DPoint& rStart,
+ const basegfx::B2DPoint& rEnd,
+ SpreadMethod aSpreadMethod,
+ double fOverlapping)
+ : BufferedDecompositionPrimitive2D(),
+ SvgGradientHelper(rPolyPolygon, rGradientEntries, rStart, aSpreadMethod, fOverlapping),
+ maEnd(rEnd)
+ {
+ }
+
+ bool SvgLinearGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ const SvgGradientHelper* pSvgGradientHelper = dynamic_cast< const SvgGradientHelper* >(&rPrimitive);
+
+ if(pSvgGradientHelper && SvgGradientHelper::operator==(*pSvgGradientHelper))
+ {
+ const SvgLinearGradientPrimitive2D& rCompare = static_cast< const SvgLinearGradientPrimitive2D& >(rPrimitive);
+
+ return (getEnd() == rCompare.getEnd());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange SvgLinearGradientPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // return ObjectRange
+ return getPolyPolygon().getB2DRange();
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(SvgLinearGradientPrimitive2D, PRIMITIVE2D_ID_SVGLINEARGRADIENTPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ void SvgRadialGradientPrimitive2D::checkPreconditions()
+ {
+ // call parent
+ SvgGradientHelper::checkPreconditions();
+
+ if(getCreatesContent())
+ {
+ // Check Radius
+ if(basegfx::fTools::equalZero(getRadius()))
+ {
+ // fill with single color using last stop color
+ setSingleEntry();
+ }
+ }
+ }
+
+ void SvgRadialGradientPrimitive2D::ensureGeometry(
+ basegfx::B2DPolyPolygon& rPolyPolygon,
+ const SvgGradientEntry& rFrom,
+ const SvgGradientEntry& rTo,
+ sal_Int32 nOffset) const
+ {
+ if(!rPolyPolygon.count())
+ {
+ basegfx::B2DPolygon aPolygonA(basegfx::tools::createPolygonFromUnitCircle());
+ basegfx::B2DPolygon aPolygonB(basegfx::tools::createPolygonFromUnitCircle());
+ double fScaleFrom(rFrom.getOffset() + nOffset);
+ const double fScaleTo(rTo.getOffset() + nOffset);
+
+ if(fScaleFrom > getOverlapping())
+ {
+ fScaleFrom -= getOverlapping();
+ }
+
+ if(isFocalSet())
+ {
+ const basegfx::B2DVector aTranslateFrom(maFocalVector * (maFocalLength - fScaleFrom));
+ const basegfx::B2DVector aTranslateTo(maFocalVector * (maFocalLength - fScaleTo));
+
+ aPolygonA.transform(
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ fScaleFrom,
+ fScaleFrom,
+ aTranslateFrom.getX(),
+ aTranslateFrom.getY()));
+ aPolygonB.transform(
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ fScaleTo,
+ fScaleTo,
+ aTranslateTo.getX(),
+ aTranslateTo.getY()));
+ }
+ else
+ {
+ aPolygonA.transform(
+ basegfx::tools::createScaleB2DHomMatrix(
+ fScaleFrom,
+ fScaleFrom));
+ aPolygonB.transform(
+ basegfx::tools::createScaleB2DHomMatrix(
+ fScaleTo,
+ fScaleTo));
+ }
+
+ // add the outer polygon first
+ rPolyPolygon.append(aPolygonB);
+ rPolyPolygon.append(aPolygonA);
+ }
+ }
+
+ void SvgRadialGradientPrimitive2D::createAtom(
+ Primitive2DVector& rTargetColor,
+ Primitive2DVector& rTargetOpacity,
+ const SvgGradientEntry& rFrom,
+ const SvgGradientEntry& rTo,
+ sal_Int32 nOffset) const
+ {
+ // create gradient atom [rFrom.getOffset() .. rTo.getOffset()] with (rFrom.getOffset() > rTo.getOffset())
+ if(rFrom.getOffset() == rTo.getOffset())
+ {
+ OSL_ENSURE(false, "SvgGradient Atom creation with no step width (!)");
+ }
+ else
+ {
+ const bool bColorChange(rFrom.getColor() != rTo.getColor());
+ const bool bOpacityChange(rFrom.getOpacity() != rTo.getOpacity());
+ basegfx::B2DPolyPolygon aPolyPolygon;
+
+ if(bColorChange)
+ {
+ const double fScaleFrom(rFrom.getOffset() + nOffset);
+ const double fScaleTo(rTo.getOffset() + nOffset);
+
+ if(isFocalSet())
+ {
+ const basegfx::B2DVector aTranslateFrom(maFocalVector * (maFocalLength - fScaleFrom));
+ const basegfx::B2DVector aTranslateTo(maFocalVector * (maFocalLength - fScaleTo));
+
+ rTargetColor.push_back(
+ new SvgRadialAtomPrimitive2D(
+ rFrom.getColor(), fScaleFrom, aTranslateFrom,
+ rTo.getColor(), fScaleTo, aTranslateTo,
+ getOverlapping()));
+ }
+ else
+ {
+ rTargetColor.push_back(
+ new SvgRadialAtomPrimitive2D(
+ rFrom.getColor(), fScaleFrom,
+ rTo.getColor(), fScaleTo,
+ getOverlapping()));
+ }
+ }
+ else
+ {
+ ensureGeometry(aPolyPolygon, rFrom, rTo, nOffset);
+ rTargetColor.push_back(
+ new PolyPolygonColorPrimitive2D(
+ aPolyPolygon,
+ rFrom.getColor()));
+ }
+
+ if(bOpacityChange)
+ {
+ const double fTransFrom(1.0 - rFrom.getOpacity());
+ const double fTransTo(1.0 - rTo.getOpacity());
+ const basegfx::BColor aColorFrom(fTransFrom, fTransFrom, fTransFrom);
+ const basegfx::BColor aColorTo(fTransTo, fTransTo, fTransTo);
+ const double fScaleFrom(rFrom.getOffset() + nOffset);
+ const double fScaleTo(rTo.getOffset() + nOffset);
+
+ if(isFocalSet())
+ {
+ const basegfx::B2DVector aTranslateFrom(maFocalVector * (maFocalLength - fScaleFrom));
+ const basegfx::B2DVector aTranslateTo(maFocalVector * (maFocalLength - fScaleTo));
+
+ rTargetOpacity.push_back(
+ new SvgRadialAtomPrimitive2D(
+ aColorFrom, fScaleFrom, aTranslateFrom,
+ aColorTo, fScaleTo, aTranslateTo,
+ getOverlapping()));
+ }
+ else
+ {
+ rTargetOpacity.push_back(
+ new SvgRadialAtomPrimitive2D(
+ aColorFrom, fScaleFrom,
+ aColorTo, fScaleTo,
+ getOverlapping()));
+ }
+ }
+ else if(!getFullyOpaque())
+ {
+ const double fTransparence(1.0 - rFrom.getOpacity());
+
+ ensureGeometry(aPolyPolygon, rFrom, rTo, nOffset);
+ rTargetOpacity.push_back(
+ new PolyPolygonColorPrimitive2D(
+ aPolyPolygon,
+ basegfx::BColor(fTransparence, fTransparence, fTransparence)));
+ }
+ }
+ }
+
+ const SvgGradientEntryVector& SvgRadialGradientPrimitive2D::getMirroredGradientEntries() const
+ {
+ if(maMirroredGradientEntries.empty() && !getGradientEntries().empty())
+ {
+ const_cast< SvgRadialGradientPrimitive2D* >(this)->createMirroredGradientEntries();
+ }
+
+ return maMirroredGradientEntries;
+ }
+
+ void SvgRadialGradientPrimitive2D::createMirroredGradientEntries()
+ {
+ if(maMirroredGradientEntries.empty() && !getGradientEntries().empty())
+ {
+ const sal_uInt32 nCount(getGradientEntries().size());
+ maMirroredGradientEntries.clear();
+ maMirroredGradientEntries.reserve(nCount);
+
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ const SvgGradientEntry& rCandidate = getGradientEntries()[nCount - 1 - a];
+
+ maMirroredGradientEntries.push_back(
+ SvgGradientEntry(
+ 1.0 - rCandidate.getOffset(),
+ rCandidate.getColor(),
+ rCandidate.getOpacity()));
+ }
+ }
+ }
+
+ Primitive2DSequence SvgRadialGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ Primitive2DSequence xRetval;
+
+ if(!getPreconditionsChecked())
+ {
+ const_cast< SvgRadialGradientPrimitive2D* >(this)->checkPreconditions();
+ }
+
+ if(getSingleEntry())
+ {
+ // fill with last existing color
+ xRetval = createSingleGradientEntryFill();
+ }
+ else if(getCreatesContent())
+ {
+ // at least two color stops in range [0.0 .. 1.0], sorted, non-null vector, not completely
+ // invisible, width and height to fill are not empty
+ const SvgGradientEntryVector& rEntries = getGradientEntries();
+ const basegfx::B2DRange aPolyRange(getPolyPolygon().getB2DRange());
+ const double fPolyWidth(aPolyRange.getWidth());
+ const double fPolyHeight(aPolyRange.getHeight());
+
+ // create ObjectTransform based on polygon range
+ const basegfx::B2DHomMatrix aObjectTransform(
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ fPolyWidth, fPolyHeight,
+ aPolyRange.getMinX(), aPolyRange.getMinY()));
+
+ // create unit transform from unit vector to given linear gradient vector
+ basegfx::B2DHomMatrix aUnitGradientToGradient;
+
+ aUnitGradientToGradient.scale(getRadius(), getRadius());
+ aUnitGradientToGradient.translate(getStart().getX(), getStart().getY());
+
+ // create full transform from unit gradient coordinates to object coordinates
+ // including the SvgGradient transformation
+ basegfx::B2DHomMatrix aUnitGradientToObject(aObjectTransform * aUnitGradientToGradient);
+
+ // create inverse from it
+ basegfx::B2DHomMatrix aObjectToUnitGradient(aUnitGradientToObject);
+ aObjectToUnitGradient.invert();
+
+ // back-transform polygon to unit gradient coordinates and get
+ // UnitRage. This is the range the gradient has to cover
+ basegfx::B2DPolyPolygon aUnitPoly(getPolyPolygon());
+ aUnitPoly.transform(aObjectToUnitGradient);
+ const basegfx::B2DRange aUnitRange(aUnitPoly.getB2DRange());
+
+ // create range which the gradient has to cover to cover the whole given geometry.
+ // For circle, go from 0.0 to max radius in all directions (the corners)
+ double fMax(basegfx::B2DVector(aUnitRange.getMinimum()).getLength());
+ fMax = std::max(fMax, basegfx::B2DVector(aUnitRange.getMaximum()).getLength());
+ fMax = std::max(fMax, basegfx::B2DVector(aUnitRange.getMinX(), aUnitRange.getMaxY()).getLength());
+ fMax = std::max(fMax, basegfx::B2DVector(aUnitRange.getMaxX(), aUnitRange.getMinY()).getLength());
+
+ // prepare result vectors
+ Primitive2DVector aTargetColor;
+ Primitive2DVector aTargetOpacity;
+
+ if(0.0 < fMax)
+ {
+ // prepare maFocalVector
+ if(isFocalSet())
+ {
+ const_cast< SvgRadialGradientPrimitive2D* >(this)->maFocalLength = fMax;
+ }
+
+ // create central run, may also already do all necessary when
+ // Spread_pad is set as SpreadMethod and/or the range is smaller
+ double fPos(createRun(aTargetColor, aTargetOpacity, 0.0, fMax, getGradientEntries(), 0));
+
+ if(fPos < fMax)
+ {
+ // can only happen when SpreadMethod is Spread_reflect or Spread_repeat,
+ // else the start and end pads are already created and fPos == fMax.
+ // For radial there is no way to transform the already created
+ // central run, it needs to be created from 1.0 to fMax
+ sal_Int32 nOffset(1);
+
+ while(fPos < fMax)
+ {
+ const bool bMirror(Spread_reflect == getSpreadMethod() && (nOffset % 2));
+
+ if(bMirror)
+ {
+ createRun(aTargetColor, aTargetOpacity, 0.0, fMax, getMirroredGradientEntries(), nOffset);
+ }
+ else
+ {
+ createRun(aTargetColor, aTargetOpacity, 0.0, fMax, getGradientEntries(), nOffset);
+ }
+
+ nOffset++;
+ fPos += 1.0;
+ }
+ }
+ }
+
+ xRetval = createResult(aTargetColor, aTargetOpacity, aUnitGradientToObject, true);
+ }
+
+ return xRetval;
+ }
+
+ SvgRadialGradientPrimitive2D::SvgRadialGradientPrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
+ const SvgGradientEntryVector& rGradientEntries,
+ const basegfx::B2DPoint& rStart,
+ double fRadius,
+ SpreadMethod aSpreadMethod,
+ const basegfx::B2DPoint* pFocal,
+ double fOverlapping)
+ : BufferedDecompositionPrimitive2D(),
+ SvgGradientHelper(rPolyPolygon, rGradientEntries, rStart, aSpreadMethod, fOverlapping),
+ mfRadius(fRadius),
+ maFocal(rStart),
+ maFocalVector(0.0, 0.0),
+ maFocalLength(0.0),
+ maMirroredGradientEntries(),
+ mbFocalSet(false)
+ {
+ if(pFocal)
+ {
+ maFocal = *pFocal;
+ maFocalVector = maFocal - getStart();
+ mbFocalSet = true;
+ }
+ }
+
+ bool SvgRadialGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ const SvgGradientHelper* pSvgGradientHelper = dynamic_cast< const SvgGradientHelper* >(&rPrimitive);
+
+ if(pSvgGradientHelper && SvgGradientHelper::operator==(*pSvgGradientHelper))
+ {
+ const SvgRadialGradientPrimitive2D& rCompare = static_cast< const SvgRadialGradientPrimitive2D& >(rPrimitive);
+
+ if(getRadius() == rCompare.getRadius())
+ {
+ if(isFocalSet() == rCompare.isFocalSet())
+ {
+ if(isFocalSet())
+ {
+ return getFocal() == rCompare.getFocal();
+ }
+ else
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange SvgRadialGradientPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // return ObjectRange
+ return getPolyPolygon().getB2DRange();
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(SvgRadialGradientPrimitive2D, PRIMITIVE2D_ID_SVGRADIALGRADIENTPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// SvgLinearAtomPrimitive2D class
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence SvgLinearAtomPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ Primitive2DSequence xRetval;
+ const double fDelta(getOffsetB() - getOffsetA());
+
+ if(!basegfx::fTools::equalZero(fDelta))
+ {
+ if(getColorA() == getColorB())
+ {
+ const basegfx::B2DPolygon aPolygon(
+ basegfx::tools::createPolygonFromRect(
+ basegfx::B2DRange(
+ getOffsetA() - getOverlapping(),
+ 0.0,
+ getOffsetB() + getOverlapping(),
+ 1.0)));
+
+ xRetval.realloc(1);
+ xRetval[0] = new PolyPolygonColorPrimitive2D(
+ basegfx::B2DPolyPolygon(aPolygon),
+ getColorA());
+ }
+ else
+ {
+ // calc discrete length to change color all 2.5 pixels
+ sal_uInt32 nSteps(basegfx::fround(fDelta / (getDiscreteUnit() * 2.5)));
+
+ // use color distance, assume to do every 3rd
+ const double fColorDistance(getColorA().getDistance(getColorB()));
+ const sal_uInt32 nColorSteps(basegfx::fround(fColorDistance * (255.0 * 0.3)));
+ nSteps = std::min(nSteps, nColorSteps);
+
+ // roughly cut when too big
+ nSteps = std::min(nSteps, sal_uInt32(100));
+ nSteps = std::max(nSteps, sal_uInt32(1));
+
+ // preapare iteration
+ double fStart(0.0);
+ double fStep(fDelta / nSteps);
+
+ xRetval.realloc(nSteps);
+
+ for(sal_uInt32 a(0); a < nSteps; a++, fStart += fStep)
+ {
+ const double fLeft(getOffsetA() + fStart);
+ const double fRight(fLeft + fStep);
+ const basegfx::B2DPolygon aPolygon(
+ basegfx::tools::createPolygonFromRect(
+ basegfx::B2DRange(
+ fLeft - getOverlapping(),
+ 0.0,
+ fRight + getOverlapping(),
+ 1.0)));
+
+ xRetval[a] = new PolyPolygonColorPrimitive2D(
+ basegfx::B2DPolyPolygon(aPolygon),
+ basegfx::interpolate(getColorA(), getColorB(), fStart/fDelta));
+ }
+ }
+ }
+
+ return xRetval;
+ }
+
+ bool SvgLinearAtomPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
+ {
+ const SvgLinearAtomPrimitive2D& rCompare = static_cast< const SvgLinearAtomPrimitive2D& >(rPrimitive);
+
+ return (getColorA() == rCompare.getColorA()
+ && getColorB() == rCompare.getColorB()
+ && getOffsetA() == rCompare.getOffsetA()
+ && getOffsetB() == rCompare.getOffsetB()
+ && getOverlapping() == rCompare.getOverlapping());
+ }
+
+ return false;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(SvgLinearAtomPrimitive2D, PRIMITIVE2D_ID_SVGLINEARATOMPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// SvgRadialAtomPrimitive2D class
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence SvgRadialAtomPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ Primitive2DSequence xRetval;
+ const double fDeltaScale(getScaleB() - getScaleA());
+
+ if(!basegfx::fTools::equalZero(fDeltaScale))
+ {
+ if(getColorA() == getColorB())
+ {
+ basegfx::B2DPolygon aPolygonA(basegfx::tools::createPolygonFromUnitCircle());
+ basegfx::B2DPolygon aPolygonB(basegfx::tools::createPolygonFromUnitCircle());
+ double fScaleA(getScaleA());
+ const double fScaleB(getScaleB());
+
+ if(fScaleA > getOverlapping())
+ {
+ fScaleA -= getOverlapping();
+ }
+
+ const bool bUseA(basegfx::fTools::equalZero(fScaleA));
+
+ if(getTranslateSet())
+ {
+ if(bUseA)
+ {
+ aPolygonA.transform(
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ fScaleA,
+ fScaleA,
+ getTranslateA().getX(),
+ getTranslateA().getY()));
+ }
+
+ aPolygonB.transform(
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ fScaleB,
+ fScaleB,
+ getTranslateB().getX(),
+ getTranslateB().getY()));
+ }
+ else
+ {
+ if(bUseA)
+ {
+ aPolygonA.transform(
+ basegfx::tools::createScaleB2DHomMatrix(
+ fScaleA,
+ fScaleA));
+ }
+
+ aPolygonB.transform(
+ basegfx::tools::createScaleB2DHomMatrix(
+ fScaleB,
+ fScaleB));
+ }
+
+ basegfx::B2DPolyPolygon aPolyPolygon(aPolygonB);
+
+ if(bUseA)
+ {
+ aPolyPolygon.append(aPolygonA);
+ }
+
+ xRetval.realloc(1);
+
+ xRetval[0] = new PolyPolygonColorPrimitive2D(
+ aPolyPolygon,
+ getColorA());
+ }
+ else
+ {
+ // calc discrete length to change color all 2.5 pixels
+ sal_uInt32 nSteps(basegfx::fround(fDeltaScale / (getDiscreteUnit() * 2.5)));
+
+ // use color distance, assume to do every 3rd
+ const double fColorDistance(getColorA().getDistance(getColorB()));
+ const sal_uInt32 nColorSteps(basegfx::fround(fColorDistance * (255.0 * 0.3)));
+ nSteps = std::min(nSteps, nColorSteps);
+
+ // roughly cut when too big
+ nSteps = std::min(nSteps, sal_uInt32(100));
+ nSteps = std::max(nSteps, sal_uInt32(1));
+
+ // preapare iteration
+ double fStartScale(0.0);
+ double fStepScale(fDeltaScale / nSteps);
+
+ xRetval.realloc(nSteps);
+
+ for(sal_uInt32 a(0); a < nSteps; a++, fStartScale += fStepScale)
+ {
+ double fScaleA(getScaleA() + fStartScale);
+ const double fScaleB(fScaleA + fStepScale);
+ const double fUnitScale(fStartScale/fDeltaScale);
+ basegfx::B2DPolygon aPolygonA(basegfx::tools::createPolygonFromUnitCircle());
+ basegfx::B2DPolygon aPolygonB(basegfx::tools::createPolygonFromUnitCircle());
+
+ if(fScaleA > getOverlapping())
+ {
+ fScaleA -= getOverlapping();
+ }
+
+ const bool bUseA(basegfx::fTools::equalZero(fScaleA));
+
+ if(getTranslateSet())
+ {
+ const double fUnitScaleEnd((fStartScale + fStepScale)/fDeltaScale);
+ const basegfx::B2DVector aTranslateB(basegfx::interpolate(getTranslateA(), getTranslateB(), fUnitScaleEnd));
+
+ if(bUseA)
+ {
+ const basegfx::B2DVector aTranslateA(basegfx::interpolate(getTranslateA(), getTranslateB(), fUnitScale));
+
+ aPolygonA.transform(
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ fScaleA,
+ fScaleA,
+ aTranslateA.getX(),
+ aTranslateA.getY()));
+ }
+
+ aPolygonB.transform(
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ fScaleB,
+ fScaleB,
+ aTranslateB.getX(),
+ aTranslateB.getY()));
+ }
+ else
+ {
+ if(bUseA)
+ {
+ aPolygonA.transform(
+ basegfx::tools::createScaleB2DHomMatrix(
+ fScaleA,
+ fScaleA));
+ }
+
+ aPolygonB.transform(
+ basegfx::tools::createScaleB2DHomMatrix(
+ fScaleB,
+ fScaleB));
+ }
+
+ basegfx::B2DPolyPolygon aPolyPolygon(aPolygonB);
+
+ if(bUseA)
+ {
+ aPolyPolygon.append(aPolygonA);
+ }
+
+ xRetval[nSteps - 1 - a] = new PolyPolygonColorPrimitive2D(
+ aPolyPolygon,
+ basegfx::interpolate(getColorA(), getColorB(), fUnitScale));
+ }
+ }
+ }
+
+ return xRetval;
+ }
+
+ bool SvgRadialAtomPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
+ {
+ const SvgRadialAtomPrimitive2D& rCompare = static_cast< const SvgRadialAtomPrimitive2D& >(rPrimitive);
+
+ return (getColorA() == rCompare.getColorA()
+ && getColorB() == rCompare.getColorB()
+ && getScaleA() == rCompare.getScaleA()
+ && getScaleB() == rCompare.getScaleB()
+ && getTranslateA() == rCompare.getTranslateA()
+ && getTranslateB() == rCompare.getTranslateB()
+ && getOverlapping() == rCompare.getOverlapping());
+ }
+
+ return false;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(SvgRadialAtomPrimitive2D, PRIMITIVE2D_ID_SVGRADIALATOMPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/textbreakuphelper.cxx b/drawinglayer/source/primitive2d/textbreakuphelper.cxx
new file mode 100644
index 000000000000..4979a9932cc2
--- /dev/null
+++ b/drawinglayer/source/primitive2d/textbreakuphelper.cxx
@@ -0,0 +1,294 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http:\\www.apache.org\licenses\LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/textbreakuphelper.hxx>
+#include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx>
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/i18n/CharacterIteratorMode.hdl>
+#include <com/sun/star/i18n/WordType.hpp>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ TextBreakupHelper::TextBreakupHelper(const Primitive2DReference& rxSource)
+ : mxSource(rxSource),
+ mxResult(),
+ mpSource(dynamic_cast< const TextSimplePortionPrimitive2D* >(rxSource.get())),
+ maTextLayouter(),
+ maDecTrans(),
+ mbNoDXArray()
+ {
+ if(mpSource)
+ {
+ maDecTrans = mpSource->getTextTransform();
+ mbNoDXArray = mpSource->getDXArray().empty();
+
+ if(mbNoDXArray)
+ {
+ // init TextLayouter when no dxarray
+ maTextLayouter.setFontAttribute(
+ mpSource->getFontAttribute(),
+ maDecTrans.getScale().getX(),
+ maDecTrans.getScale().getY(),
+ mpSource->getLocale());
+ }
+ }
+ }
+
+ TextBreakupHelper::~TextBreakupHelper()
+ {
+ }
+
+ void TextBreakupHelper::breakupPortion(Primitive2DVector& rTempResult, sal_uInt32 nIndex, sal_uInt32 nLength)
+ {
+ if(mpSource && nLength && !(nIndex == mpSource->getTextPosition() && nLength == mpSource->getTextLength()))
+ {
+ // prepare values for new portion
+ basegfx::B2DHomMatrix aNewTransform;
+ ::std::vector< double > aNewDXArray;
+ const bool bNewStartIsNotOldStart(nIndex > mpSource->getTextPosition());
+
+ if(!mbNoDXArray)
+ {
+ // prepare new DXArray for the single word
+ aNewDXArray = ::std::vector< double >(
+ mpSource->getDXArray().begin() + (nIndex - mpSource->getTextPosition()),
+ mpSource->getDXArray().begin() + ((nIndex + nLength) - mpSource->getTextPosition()));
+ }
+
+ if(bNewStartIsNotOldStart)
+ {
+ // needs to be moved to a new start position
+ double fOffset(0.0);
+
+ if(mbNoDXArray)
+ {
+ // evaluate using TextLayouter
+ fOffset = maTextLayouter.getTextWidth(mpSource->getText(), mpSource->getTextPosition(), nIndex);
+ }
+ else
+ {
+ // get from DXArray
+ const sal_uInt32 nIndex(static_cast< sal_uInt32 >(nIndex - mpSource->getTextPosition()));
+ fOffset = mpSource->getDXArray()[nIndex - 1];
+ }
+
+ // need offset without FontScale for building the new transformation. The
+ // new transformation will be multiplied with the current text transformation
+ // so FontScale would be double
+ double fOffsetNoScale(fOffset);
+ const double fFontScaleX(maDecTrans.getScale().getX());
+
+ if(!basegfx::fTools::equal(fFontScaleX, 1.0)
+ && !basegfx::fTools::equalZero(fFontScaleX))
+ {
+ fOffsetNoScale /= fFontScaleX;
+ }
+
+ // apply needed offset to transformation
+ aNewTransform.translate(fOffsetNoScale, 0.0);
+
+ if(!mbNoDXArray)
+ {
+ // DXArray values need to be corrected with the offset, too. Here,
+ // take the scaled offset since the DXArray is scaled
+ const sal_uInt32 nArraySize(aNewDXArray.size());
+
+ for(sal_uInt32 a(0); a < nArraySize; a++)
+ {
+ aNewDXArray[a] -= fOffset;
+ }
+ }
+ }
+
+ // add text transformation to new transformation
+ aNewTransform = maDecTrans.getB2DHomMatrix() * aNewTransform;
+
+ // callback to allow evtl. changes
+ const bool bCreate(allowChange(rTempResult.size(), aNewTransform, nIndex, nLength));
+
+ if(bCreate)
+ {
+ // check if we have a decorated primitive as source
+ const TextDecoratedPortionPrimitive2D* pTextDecoratedPortionPrimitive2D =
+ dynamic_cast< const TextDecoratedPortionPrimitive2D* >(mpSource);
+
+ if(pTextDecoratedPortionPrimitive2D)
+ {
+ // create a TextDecoratedPortionPrimitive2D
+ rTempResult.push_back(
+ new TextDecoratedPortionPrimitive2D(
+ aNewTransform,
+ mpSource->getText(),
+ nIndex,
+ nLength,
+ aNewDXArray,
+ mpSource->getFontAttribute(),
+ mpSource->getLocale(),
+ mpSource->getFontColor(),
+
+ pTextDecoratedPortionPrimitive2D->getOverlineColor(),
+ pTextDecoratedPortionPrimitive2D->getTextlineColor(),
+ pTextDecoratedPortionPrimitive2D->getFontOverline(),
+ pTextDecoratedPortionPrimitive2D->getFontUnderline(),
+ pTextDecoratedPortionPrimitive2D->getUnderlineAbove(),
+ pTextDecoratedPortionPrimitive2D->getTextStrikeout(),
+ pTextDecoratedPortionPrimitive2D->getWordLineMode(),
+ pTextDecoratedPortionPrimitive2D->getTextEmphasisMark(),
+ pTextDecoratedPortionPrimitive2D->getEmphasisMarkAbove(),
+ pTextDecoratedPortionPrimitive2D->getEmphasisMarkBelow(),
+ pTextDecoratedPortionPrimitive2D->getTextRelief(),
+ pTextDecoratedPortionPrimitive2D->getShadow()));
+ }
+ else
+ {
+ // create a SimpleTextPrimitive
+ rTempResult.push_back(
+ new TextSimplePortionPrimitive2D(
+ aNewTransform,
+ mpSource->getText(),
+ nIndex,
+ nLength,
+ aNewDXArray,
+ mpSource->getFontAttribute(),
+ mpSource->getLocale(),
+ mpSource->getFontColor()));
+ }
+ }
+ }
+ }
+
+ bool TextBreakupHelper::allowChange(sal_uInt32 nCount, basegfx::B2DHomMatrix& rNewTransform, sal_uInt32 nIndex, sal_uInt32 nLength)
+ {
+ return true;
+ }
+
+ void TextBreakupHelper::breakup(BreakupUnit aBreakupUnit)
+ {
+ if(mpSource && mpSource->getTextLength())
+ {
+ Primitive2DVector aTempResult;
+ static ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator > xBreakIterator;
+
+ if(!xBreakIterator.is())
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMSF(::comphelper::getProcessServiceFactory());
+ xBreakIterator.set(xMSF->createInstance(rtl::OUString::createFromAscii("com.sun.star.i18n.BreakIterator")), ::com::sun::star::uno::UNO_QUERY);
+ }
+
+ if(xBreakIterator.is())
+ {
+ const rtl::OUString& rTxt = mpSource->getText();
+ const sal_Int32 nTextLength(mpSource->getTextLength());
+ const ::com::sun::star::lang::Locale& rLocale = mpSource->getLocale();
+ const sal_Int32 nTextPosition(mpSource->getTextPosition());
+ sal_Int32 nCurrent(nTextPosition);
+
+ switch(aBreakupUnit)
+ {
+ case BreakupUnit_character:
+ {
+ sal_Int32 nDone;
+ sal_Int32 nNextCellBreak(xBreakIterator->nextCharacters(rTxt, nTextPosition, rLocale, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, 0, nDone));
+ sal_Int32 a(nTextPosition);
+
+ for(; a < nTextPosition + nTextLength; a++)
+ {
+ if(a == nNextCellBreak)
+ {
+ breakupPortion(aTempResult, nCurrent, a - nCurrent);
+ nCurrent = a;
+ nNextCellBreak = xBreakIterator->nextCharacters(rTxt, a, rLocale, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, 1, nDone);
+ }
+ }
+
+ breakupPortion(aTempResult, nCurrent, a - nCurrent);
+ break;
+ }
+ case BreakupUnit_word:
+ {
+ ::com::sun::star::i18n::Boundary nNextWordBoundary(xBreakIterator->getWordBoundary(rTxt, nTextPosition, rLocale, ::com::sun::star::i18n::WordType::ANY_WORD, sal_True));
+ sal_Int32 a(nTextPosition);
+
+ for(; a < nTextPosition + nTextLength; a++)
+ {
+ if(a == nNextWordBoundary.endPos)
+ {
+ breakupPortion(aTempResult, nCurrent, a - nCurrent);
+ nCurrent = a;
+ nNextWordBoundary = xBreakIterator->getWordBoundary(rTxt, a + 1, rLocale, ::com::sun::star::i18n::WordType::ANY_WORD, sal_True);
+ }
+ }
+
+ breakupPortion(aTempResult, nCurrent, a - nCurrent);
+ break;
+ }
+ case BreakupUnit_sentence:
+ {
+ sal_Int32 nNextSentenceBreak(xBreakIterator->endOfSentence(rTxt, nTextPosition, rLocale));
+ sal_Int32 a(nTextPosition);
+
+ for(; a < nTextPosition + nTextLength; a++)
+ {
+ if(a == nNextSentenceBreak)
+ {
+ breakupPortion(aTempResult, nCurrent, a - nCurrent);
+ nCurrent = a;
+ nNextSentenceBreak = xBreakIterator->endOfSentence(rTxt, a + 1, rLocale);
+ }
+ }
+
+ breakupPortion(aTempResult, nCurrent, a - nCurrent);
+ break;
+ }
+ }
+ }
+
+ mxResult = Primitive2DVectorToPrimitive2DSequence(aTempResult);
+ }
+ }
+
+ const Primitive2DSequence& TextBreakupHelper::getResult(BreakupUnit aBreakupUnit) const
+ {
+ if(mxResult.hasElements())
+ {
+ return mxResult;
+ }
+ else if(mpSource)
+ {
+ const_cast< TextBreakupHelper* >(this)->breakup(aBreakupUnit);
+ }
+
+ return mxResult;
+ }
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/processor2d/hittestprocessor2d.cxx b/drawinglayer/source/processor2d/hittestprocessor2d.cxx
index 855535eb96e8..3b5e266f3bfd 100644
--- a/drawinglayer/source/processor2d/hittestprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/hittestprocessor2d.cxx
@@ -525,7 +525,6 @@ namespace drawinglayer
case PRIMITIVE2D_ID_FILLHATCHPRIMITIVE2D :
case PRIMITIVE2D_ID_PAGEPREVIEWPRIMITIVE2D :
case PRIMITIVE2D_ID_MEDIAPRIMITIVE2D:
- case PRIMITIVE2D_ID_RENDERGRAPHICPRIMITIVE2D:
{
if(!getHitTextOnly())
{
diff --git a/drawinglayer/source/processor2d/linegeometryextractor2d.cxx b/drawinglayer/source/processor2d/linegeometryextractor2d.cxx
index 65a87c83f4a0..97ecf9da6952 100644
--- a/drawinglayer/source/processor2d/linegeometryextractor2d.cxx
+++ b/drawinglayer/source/processor2d/linegeometryextractor2d.cxx
@@ -119,7 +119,6 @@ namespace drawinglayer
case PRIMITIVE2D_ID_MARKERARRAYPRIMITIVE2D :
case PRIMITIVE2D_ID_POINTARRAYPRIMITIVE2D :
case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D :
- case PRIMITIVE2D_ID_RENDERGRAPHICPRIMITIVE2D :
case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D :
case PRIMITIVE2D_ID_MASKPRIMITIVE2D :
{
diff --git a/drawinglayer/source/processor2d/textaspolygonextractor2d.cxx b/drawinglayer/source/processor2d/textaspolygonextractor2d.cxx
index 13cbfcb3badb..59a47fc790a6 100644
--- a/drawinglayer/source/processor2d/textaspolygonextractor2d.cxx
+++ b/drawinglayer/source/processor2d/textaspolygonextractor2d.cxx
@@ -210,7 +210,6 @@ namespace drawinglayer
case PRIMITIVE2D_ID_MARKERARRAYPRIMITIVE2D :
case PRIMITIVE2D_ID_POINTARRAYPRIMITIVE2D :
case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D :
- case PRIMITIVE2D_ID_RENDERGRAPHICPRIMITIVE2D :
case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D :
case PRIMITIVE2D_ID_MASKPRIMITIVE2D :
{
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index c56909e9dfde..63dbabf2bce5 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -34,7 +34,6 @@
#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
-#include <drawinglayer/primitive2d/rendergraphicprimitive2d.hxx>
#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
#include <basegfx/polygon/b2dpolygonclipper.hxx>
@@ -1284,12 +1283,6 @@ namespace drawinglayer
RenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate));
break;
}
- case PRIMITIVE2D_ID_RENDERGRAPHICPRIMITIVE2D :
- {
- // direct draw of transformed RenderGraphic primitive; use default processing
- RenderRenderGraphicPrimitive2D(static_cast< const primitive2d::RenderGraphicPrimitive2D& >(rCandidate));
- break;
- }
case PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D :
{
// need to handle PolyPolygonBitmapPrimitive2D here to support XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END
@@ -1657,7 +1650,8 @@ namespace drawinglayer
// the ClipRegion is built from the Polygon. A AdaptiveSubdivide on the source polygon was missing there
mpOutputDevice->Push(PUSH_CLIPREGION);
//mpOutputDevice->SetClipRegion(Region(PolyPolygon(basegfx::tools::adaptiveSubdivideByAngle(maClipPolyPolygon))));
- mpOutputDevice->SetClipRegion(Region(PolyPolygon(maClipPolyPolygon)));
+ //mpOutputDevice->SetClipRegion(Region(PolyPolygon(maClipPolyPolygon)));
+ mpOutputDevice->SetClipRegion(Region(maClipPolyPolygon));
}
// recursively paint content
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index f485aa182bd2..d71090ed7d5b 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -31,7 +31,6 @@
#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
-#include <drawinglayer/primitive2d/rendergraphicprimitive2d.hxx>
#include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx>
#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
@@ -190,12 +189,6 @@ namespace drawinglayer
RenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate));
break;
}
- case PRIMITIVE2D_ID_RENDERGRAPHICPRIMITIVE2D :
- {
- // direct draw of transformed BitmapEx primitive
- RenderRenderGraphicPrimitive2D(static_cast< const primitive2d::RenderGraphicPrimitive2D& >(rCandidate));
- break;
- }
case PRIMITIVE2D_ID_FILLBITMAPPRIMITIVE2D :
{
// direct draw of fillBitmapPrimitive
diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx
index 8027f3284909..dc79dcce648a 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -31,7 +31,6 @@
#include <vcl/outdev.hxx>
#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
-#include <drawinglayer/primitive2d/rendergraphicprimitive2d.hxx>
#include <vclhelperbitmaptransform.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <vclhelperbitmaprender.hxx>
@@ -57,7 +56,6 @@
#include <vcl/metric.hxx>
#include <drawinglayer/primitive2d/textenumsprimitive2d.hxx>
#include <drawinglayer/primitive2d/epsprimitive2d.hxx>
-#include <vcl/rendergraphicrasterizer.hxx>
//////////////////////////////////////////////////////////////////////////////
// control support
@@ -419,75 +417,6 @@ namespace drawinglayer
}
}
- void VclProcessor2D::RenderRenderGraphicPrimitive2D(const primitive2d::RenderGraphicPrimitive2D& rRenderGraphicCandidate)
- {
- // create local transform
- basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rRenderGraphicCandidate.getTransform());
- vcl::RenderGraphic aRenderGraphic(rRenderGraphicCandidate.getRenderGraphic());
- bool bPainted(false);
-
- if(maBColorModifierStack.count())
- {
- // !!! TODO
- // aRenderGraphic = impModifyRenderGraphic(maBColorModifierStack, aRenderGraphic);
-
- if(aRenderGraphic.IsEmpty())
- {
- // color gets completely replaced, get it
- const basegfx::BColor aModifiedColor(maBColorModifierStack.getModifiedColor(basegfx::BColor()));
- basegfx::B2DPolygon aPolygon(basegfx::tools::createUnitPolygon());
- aPolygon.transform(aLocalTransform);
-
- mpOutputDevice->SetFillColor(Color(aModifiedColor));
- mpOutputDevice->SetLineColor();
- mpOutputDevice->DrawPolygon(aPolygon);
-
- bPainted = true;
- }
- }
-
- if(!bPainted)
- {
- // decompose matrix to check for shear, rotate and mirroring
- basegfx::B2DVector aScale, aTranslate;
- double fRotate, fShearX;
- aLocalTransform.decompose(aScale, aTranslate, fRotate, fShearX);
-
- basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
-
- if( basegfx::fTools::equalZero( fRotate ) )
- {
- aOutlineRange.transform( aLocalTransform );
- }
- else
- {
- // !!! TODO
- // if rotated, create the unrotated output rectangle for the GraphicManager paint
- /*
- const basegfx::B2DHomMatrix aSimpleObjectMatrix(basegfx::tools::createScaleTranslateB2DHomMatrix(
- fabs(aScale.getX()), fabs(aScale.getY()),
- aTranslate.getX(), aTranslate.getY()));
-
- aOutlineRange.transform(aSimpleObjectMatrix);
- */
- }
-
- // prepare dest coordinates
- const Point aPoint( basegfx::fround(aOutlineRange.getMinX() ),
- basegfx::fround(aOutlineRange.getMinY() ) );
- const Size aSize( basegfx::fround(aOutlineRange.getWidth() ),
- basegfx::fround(aOutlineRange.getHeight() ) );
- const Size aSizePixel( mpOutputDevice->LogicToPixel( aSize ) );
- const vcl::RenderGraphicRasterizer aRasterizer( aRenderGraphic );
- const BitmapEx aBitmapEx( aRasterizer.Rasterize( aSizePixel, fRotate, fShearX ) );
-
- if( !aBitmapEx.IsEmpty() )
- {
- mpOutputDevice->DrawBitmapEx( aPoint, aSize, aBitmapEx );
- }
- }
- }
-
void VclProcessor2D::RenderFillBitmapPrimitive2D(const primitive2d::FillBitmapPrimitive2D& rFillBitmapCandidate)
{
const attribute::FillBitmapAttribute& rFillBitmapAttribute(rFillBitmapCandidate.getFillBitmap());
diff --git a/drawinglayer/source/processor3d/shadow3dextractor.cxx b/drawinglayer/source/processor3d/shadow3dextractor.cxx
index 572610805e4c..497c020f5894 100644
--- a/drawinglayer/source/processor3d/shadow3dextractor.cxx
+++ b/drawinglayer/source/processor3d/shadow3dextractor.cxx
@@ -47,25 +47,6 @@ namespace drawinglayer
{
namespace processor3d
{
- /// helper to convert from BasePrimitive2DVector to primitive2d::Primitive2DSequence
- const primitive2d::Primitive2DSequence Shadow3DExtractingProcessor::getPrimitive2DSequenceFromBasePrimitive2DVector(
- const BasePrimitive2DVector& rVector) const
- {
- const sal_uInt32 nCount(rVector.size());
- primitive2d::Primitive2DSequence aRetval(nCount);
-
- for(sal_uInt32 a(0); a < nCount; a++)
- {
- aRetval[a] = rVector[a];
- }
-
- // all entries taken over; no need to delete entries, just reset to
- // mark as empty
- const_cast< BasePrimitive2DVector& >(rVector).clear();
-
- return aRetval;
- }
-
// as tooling, the process() implementation takes over API handling and calls this
// virtual render method when the primitive implementation is BasePrimitive3D-based.
void Shadow3DExtractingProcessor::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate)
@@ -79,8 +60,8 @@ namespace drawinglayer
const primitive3d::ShadowPrimitive3D& rPrimitive = static_cast< const primitive3d::ShadowPrimitive3D& >(rCandidate);
// set new target
- BasePrimitive2DVector aNewSubList;
- BasePrimitive2DVector* pLastTargetSequence = mpPrimitive2DSequence;
+ primitive2d::Primitive2DVector aNewSubList;
+ primitive2d::Primitive2DVector* pLastTargetSequence = mpPrimitive2DSequence;
mpPrimitive2DSequence = &aNewSubList;
// activate convert
@@ -104,7 +85,7 @@ namespace drawinglayer
primitive2d::BasePrimitive2D* pNew = new primitive2d::ShadowPrimitive2D(
rPrimitive.getShadowTransform(),
rPrimitive.getShadowColor(),
- getPrimitive2DSequenceFromBasePrimitive2DVector(aNewSubList));
+ primitive2d::Primitive2DVectorToPrimitive2DSequence(aNewSubList));
if(basegfx::fTools::more(rPrimitive.getShadowTransparence(), 0.0))
{
@@ -328,7 +309,7 @@ namespace drawinglayer
const primitive2d::Primitive2DSequence Shadow3DExtractingProcessor::getPrimitive2DSequence() const
{
- return getPrimitive2DSequenceFromBasePrimitive2DVector(maPrimitive2DSequence);
+ return Primitive2DVectorToPrimitive2DSequence(maPrimitive2DSequence);
}
} // end of namespace processor3d
diff --git a/drawinglayer/source/tools/converters.cxx b/drawinglayer/source/tools/converters.cxx
new file mode 100644
index 000000000000..a7d22a5df698
--- /dev/null
+++ b/drawinglayer/source/tools/converters.cxx
@@ -0,0 +1,143 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http:\\www.apache.org\licenses\LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/tools/converters.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <drawinglayer/processor2d/vclpixelprocessor2d.hxx>
+#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <vcl/virdev.hxx>
+
+#ifdef DBG_UTIL
+#include <tools/stream.hxx>
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace tools
+ {
+ BitmapEx DRAWINGLAYER_DLLPUBLIC convertToBitmapEx(
+ const drawinglayer::primitive2d::Primitive2DSequence& rSeq,
+ const geometry::ViewInformation2D& rViewInformation2D,
+ sal_uInt32 nDiscreteWidth,
+ sal_uInt32 nDiscreteHeight,
+ sal_uInt32 nMaxQuadratPixels)
+ {
+ BitmapEx aRetval;
+
+ if(rSeq.hasElements() && nDiscreteWidth && nDiscreteHeight)
+ {
+ // get destination size in pixels
+ const MapMode aMapModePixel(MAP_PIXEL);
+ const sal_uInt32 nViewVisibleArea(nDiscreteWidth * nDiscreteHeight);
+ double fReduceFactor(1.0);
+ drawinglayer::primitive2d::Primitive2DSequence aSequence(rSeq);
+
+ if(nViewVisibleArea > nMaxQuadratPixels)
+ {
+ // reduce render size
+ fReduceFactor = sqrt((double)nMaxQuadratPixels / (double)nViewVisibleArea);
+ nDiscreteWidth = basegfx::fround((double)nDiscreteWidth * fReduceFactor);
+ nDiscreteHeight = basegfx::fround((double)nDiscreteHeight * fReduceFactor);
+
+ const drawinglayer::primitive2d::Primitive2DReference aEmbed(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ basegfx::tools::createScaleB2DHomMatrix(fReduceFactor, fReduceFactor),
+ rSeq));
+
+ aSequence = drawinglayer::primitive2d::Primitive2DSequence(&aEmbed, 1);
+ }
+
+ const Point aEmptyPoint;
+ const Size aSizePixel(nDiscreteWidth, nDiscreteHeight);
+ geometry::ViewInformation2D aViewInformation2D(rViewInformation2D);
+ VirtualDevice maContent;
+
+ // prepare vdev
+ maContent.SetOutputSizePixel(aSizePixel, false);
+ maContent.SetMapMode(aMapModePixel);
+ maContent.SetAntialiasing(true);
+
+ // set to all white
+ maContent.SetBackground(Wallpaper(Color(COL_WHITE)));
+ maContent.Erase();
+
+ // create processor
+ processor2d::VclPixelProcessor2D aContentProcessor(aViewInformation2D, maContent);
+
+ // render content
+ aContentProcessor.process(aSequence);
+
+ // get content
+ maContent.EnableMapMode(false);
+ const Bitmap aContent(maContent.GetBitmap(aEmptyPoint, aSizePixel));
+
+ // prepare for mask creation
+ maContent.SetMapMode(aMapModePixel);
+ maContent.SetAntialiasing(true);
+
+ // set alpha to all white (fully transparent)
+ maContent.Erase();
+
+ // embed primitives to paint them black
+ const primitive2d::Primitive2DReference xRef(
+ new primitive2d::ModifiedColorPrimitive2D(
+ aSequence,
+ basegfx::BColorModifier(
+ basegfx::BColor(0.0, 0.0, 0.0),
+ 0.5,
+ basegfx::BCOLORMODIFYMODE_REPLACE)));
+ const primitive2d::Primitive2DSequence xSeq(&xRef, 1);
+
+ // render
+ aContentProcessor.process(xSeq);
+
+ // get alpha cahannel from vdev
+ maContent.EnableMapMode(false);
+ const AlphaMask aAlphaMask(maContent.GetBitmap(aEmptyPoint, aSizePixel));
+
+ // create BitmapEx result
+ aRetval = BitmapEx(aContent, aAlphaMask);
+ }
+
+#ifdef DBG_UTIL
+ static bool bDoSaveForVisualControl(false);
+ if(bDoSaveForVisualControl)
+ {
+ SvFileStream aNew((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC);
+ aNew << aRetval;
+ }
+#endif
+
+ return aRetval;
+ }
+
+ } // end of namespace tools
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/editeng/inc/editeng/unoprnms.hxx b/editeng/inc/editeng/unoprnms.hxx
index f03d985537fb..9379e1b0616f 100644
--- a/editeng/inc/editeng/unoprnms.hxx
+++ b/editeng/inc/editeng/unoprnms.hxx
@@ -176,6 +176,7 @@
#define UNO_NAME_GRAPHOBJ_FILLBITMAP "GraphicObjectFillBitmap"
#define UNO_NAME_GRAPHOBJ_GRAFURL "GraphicURL"
+#define UNO_NAME_GRAPHOBJ_REPLACEMENTGRAFURL "ReplacementGraphicURL"
#define UNO_NAME_GRAPHOBJ_GRAFSTREAMURL "GraphicStreamURL"
#define UNO_NAME_GRAPHOBJ_URLPREFIX "vnd.sun.star.GraphicObject:"
#define UNO_NAME_GRAPHOBJ_URLPKGPREFIX "vnd.sun.star.Package:"
diff --git a/filter/source/flash/swfwriter1.cxx b/filter/source/flash/swfwriter1.cxx
index 24e6e0e777fc..018cae8e2b7f 100644
--- a/filter/source/flash/swfwriter1.cxx
+++ b/filter/source/flash/swfwriter1.cxx
@@ -36,7 +36,6 @@
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <svtools/filter.hxx>
#include <vcl/graphictools.hxx>
-#include <vcl/rendergraphicrasterizer.hxx>
#ifndef _ZLIB_H
#ifdef SYSTEM_ZLIB
@@ -1887,19 +1886,6 @@ void Writer::Impl_writeActions( const GDIMetaFile& rMtf )
}
break;
- case( META_RENDERGRAPHIC_ACTION ):
- {
- const MetaRenderGraphicAction* pA = (const MetaRenderGraphicAction*) pAction;
- const ::vcl::RenderGraphicRasterizer aRasterizer( pA->GetRenderGraphic() );
- const Point aPointPixel;
- const Size aSizePixel( mpVDev->LogicToPixel( pA->GetSize() ) );
- const BitmapEx aBmpEx( aRasterizer.Rasterize( aSizePixel ) );
-
- Impl_writeImage( aBmpEx, pA->GetPoint(), pA->GetSize(),
- aPointPixel, aBmpEx.GetSizePixel(), clipRect, 1 == bMap );
- }
- break;
-
case( META_MAPMODE_ACTION ):
{
// const MetaMapModeAction *pA = (const MetaMapModeAction*) pAction;
diff --git a/filter/source/graphicfilter/eos2met/eos2met.cxx b/filter/source/graphicfilter/eos2met/eos2met.cxx
index 93a9ecd78a9a..bd0ee366936d 100644
--- a/filter/source/graphicfilter/eos2met/eos2met.cxx
+++ b/filter/source/graphicfilter/eos2met/eos2met.cxx
@@ -40,7 +40,6 @@
#include <vcl/virdev.hxx>
#include <vcl/svapp.hxx>
#include <vcl/msgbox.hxx>
-#include <vcl/rendergraphicrasterizer.hxx>
#include <svl/solar.hrc>
@@ -323,7 +322,6 @@ void METWriter::CountActionsAndBitmaps(const GDIMetaFile * pMTF)
case META_BMPEX_ACTION:
case META_BMPEXSCALE_ACTION:
case META_BMPEXSCALEPART_ACTION:
- case META_RENDERGRAPHIC_ACTION:
nNumberOfBitmaps++;
break;
}
@@ -797,16 +795,6 @@ void METWriter::WriteImageObjects(const GDIMetaFile * pMTF)
}
break;
- case( META_RENDERGRAPHIC_ACTION ):
- {
- const MetaRenderGraphicAction* pA = (const MetaRenderGraphicAction*) pMA;
- const ::vcl::RenderGraphicRasterizer aRasterizer( pA->GetRenderGraphic() );
- const BitmapEx aBmpEx( aRasterizer.Rasterize( pCompDev->LogicToPixel( pA->GetSize() ) ) );
-
- METSetMix( eGDIRasterOp );
- WriteImageObject( Graphic( aBmpEx ).GetBitmap() );
- }
- break;
}
if (bStatus==sal_False)
@@ -2355,14 +2343,6 @@ void METWriter::WriteOrders( const GDIMetaFile* pMTF )
}
break;
- case( META_RENDERGRAPHIC_ACTION ):
- {
- const MetaRenderGraphicAction* pA = (const MetaRenderGraphicAction*) pMA;
-
- METSetMix( eGDIRasterOp );
- METBitBlt( pA->GetPoint(), pA->GetSize(), pCompDev->LogicToPixel( pA->GetSize(), pMTF->GetPrefMapMode() ) );
- }
- break;
}
nWrittenActions++;
diff --git a/filter/source/graphicfilter/epict/epict.cxx b/filter/source/graphicfilter/epict/epict.cxx
index 7c6b1fa8d76f..6a66b2a1ebee 100644
--- a/filter/source/graphicfilter/epict/epict.cxx
+++ b/filter/source/graphicfilter/epict/epict.cxx
@@ -42,7 +42,6 @@
#include <vcl/svapp.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/gdimtf.hxx>
-#include <vcl/rendergraphicrasterizer.hxx>
#include <tools/bigint.hxx>
@@ -223,7 +222,6 @@ void PictWriter::CountActionsAndBitmaps(const GDIMetaFile & rMTF)
case META_BMPEX_ACTION:
case META_BMPEXSCALE_ACTION:
case META_BMPEXSCALEPART_ACTION:
- case META_RENDERGRAPHIC_ACTION:
nNumberOfBitmaps++;
break;
}
@@ -2153,17 +2151,6 @@ void PictWriter::WriteOpcodes( const GDIMetaFile & rMTF )
}
break;
- case( META_RENDERGRAPHIC_ACTION ):
- {
- const MetaRenderGraphicAction* pA = (const MetaRenderGraphicAction*) pMA;
- const ::vcl::RenderGraphicRasterizer aRasterizer( pA->GetRenderGraphic() );
- VirtualDevice aVirDev;
- const Bitmap aBmp( Graphic( aRasterizer.Rasterize(
- aVirDev.LogicToPixel( pA->GetSize() ) ) ).GetBitmap() );
-
- WriteOpcode_BitsRect( pA->GetPoint(), pA->GetSize(), aBmp );
- }
- break;
}
nWrittenActions++;
diff --git a/filter/source/graphicfilter/eps/eps.cxx b/filter/source/graphicfilter/eps/eps.cxx
index 4458d5f99790..2f63c27017d7 100644
--- a/filter/source/graphicfilter/eps/eps.cxx
+++ b/filter/source/graphicfilter/eps/eps.cxx
@@ -43,7 +43,6 @@
#include <svtools/fltcall.hxx>
#include <svtools/FilterConfigItem.hxx>
#include <vcl/graphictools.hxx>
-#include <vcl/rendergraphicrasterizer.hxx>
#include "strings.hrc"
#include <math.h>
@@ -1336,7 +1335,6 @@ void PSWriter::ImplWriteActions( const GDIMetaFile& rMtf, VirtualDevice& rVDev )
case META_BMPSCALEPART_ACTION :
case META_BMPEXSCALE_ACTION :
case META_BMPEXSCALEPART_ACTION :
- case META_RENDERGRAPHIC_ACTION :
{
nBitmapCount++;
nBitmapAction = nCurAction;
@@ -1396,22 +1394,6 @@ void PSWriter::ImplWriteActions( const GDIMetaFile& rMtf, VirtualDevice& rVDev )
}
break;
- case( META_RENDERGRAPHIC_ACTION ):
- {
- const MetaRenderGraphicAction* pA = (const MetaRenderGraphicAction*) pMA;
- const ::vcl::RenderGraphicRasterizer aRasterizer( pA->GetRenderGraphic() );
- const BitmapEx aBmpEx( aRasterizer.Rasterize( rVDev.LogicToPixel( pA->GetSize() ) ) );
- Bitmap aBmp( aBmpEx.GetBitmap() );
-
- if ( mbGrayScale )
- aBmp.Convert( BMP_CONVERSION_8BIT_GREYS );
-
- Bitmap aMask( aBmpEx.GetMask() );
- Size aSize( pA->GetSize() );
-
- ImplBmp( &aBmp, &aMask, pA->GetPoint(), aSize.Width(), aSize.Height() );
- }
- break;
}
}
}
diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx
index 7b78a083ca19..271f52e3e790 100644
--- a/filter/source/svg/svgwriter.cxx
+++ b/filter/source/svg/svgwriter.cxx
@@ -1658,24 +1658,6 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
}
break;
- case( META_RENDERGRAPHIC_ACTION ):
- {
- if( nWriteFlags & SVGWRITER_WRITE_FILL )
- {
- // TODO KA: try to embed the native data in case the RenderGraphic
- // contains valid SVG data (MimeType "image/svg+xml")
- // => incorporate 'use' or 'image' element (KA 01/2011)
- const MetaRenderGraphicAction* pA = (const MetaRenderGraphicAction*) pAction;
- const ::vcl::RenderGraphicRasterizer aRasterizer( pA->GetRenderGraphic() );
- const Point aPointPixel;
- const Size aSizePixel( mpVDev->LogicToPixel( pA->GetSize() ) );
- const BitmapEx aBmpEx( aRasterizer.Rasterize( aSizePixel ) );
-
- ImplWriteBmp( aBmpEx, pA->GetPoint(), pA->GetSize(), aPointPixel, aBmpEx.GetSizePixel() );
- }
- }
- break;
-
case( META_CLIPREGION_ACTION ):
case( META_ISECTRECTCLIPREGION_ACTION ):
case( META_ISECTREGIONCLIPREGION_ACTION ):
diff --git a/filter/source/svg/svgwriter.hxx b/filter/source/svg/svgwriter.hxx
index 9b84751417c2..233a244e5cd4 100644
--- a/filter/source/svg/svgwriter.hxx
+++ b/filter/source/svg/svgwriter.hxx
@@ -50,7 +50,6 @@
#include <vcl/cvtgrf.hxx>
#endif
#include <vcl/graphictools.hxx>
-#include <vcl/rendergraphicrasterizer.hxx>
#include <xmloff/xmlexp.hxx>
#include <xmloff/nmspmap.hxx>
diff --git a/offapi/com/sun/star/graphic/Primitive2DTools.idl b/offapi/com/sun/star/graphic/Primitive2DTools.idl
new file mode 100644
index 000000000000..80c8ca121907
--- /dev/null
+++ b/offapi/com/sun/star/graphic/Primitive2DTools.idl
@@ -0,0 +1,43 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http:\\www.apache.org\licenses\LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef com_sun_star_graphic_Primitive2DTools_idl
+#define com_sun_star_graphic_Primitive2DTools_idl
+
+#include <com/sun/star/graphic/XPrimitive2DRenderer.idl>
+
+module com { module sun { module star { module graphic
+{
+
+/** Service that describes the necessary interfaces and properties
+ for tooling involved with XPrimitive2D interfaces
+ */
+
+service Primitive2DTools
+{
+ /** Interface to render B2DPrimitives to a XBitmap
+ */
+ interface ::com::sun::star::graphic::XPrimitive2DRenderer;
+};
+
+} ; } ; } ; } ;
+
+#endif
diff --git a/offapi/com/sun/star/graphic/SvgTools.idl b/offapi/com/sun/star/graphic/SvgTools.idl
new file mode 100644
index 000000000000..bbb86621ce31
--- /dev/null
+++ b/offapi/com/sun/star/graphic/SvgTools.idl
@@ -0,0 +1,44 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http:\\www.apache.org\licenses\LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef com_sun_star_graphic_SvgTools_idl
+#define com_sun_star_graphic_SvgTools_idl
+
+#include <com/sun/star/graphic/XSvgParser.idl>
+
+module com { module sun { module star { module graphic
+{
+
+/** Service that describes the necessary interfaces and properties
+ to handle svg files
+ */
+
+service SvgTools
+{
+ /** Interface to parse a svg file to a sequence of
+ B2DPrimitives for internal usage
+ */
+ interface ::com::sun::star::graphic::XSvgParser;
+};
+
+} ; } ; } ; } ;
+
+#endif
diff --git a/offapi/com/sun/star/graphic/XPrimitive2DRenderer.idl b/offapi/com/sun/star/graphic/XPrimitive2DRenderer.idl
new file mode 100644
index 000000000000..b939d1ea9a73
--- /dev/null
+++ b/offapi/com/sun/star/graphic/XPrimitive2DRenderer.idl
@@ -0,0 +1,80 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http:\\www.apache.org\licenses\LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+#ifndef __com_sun_star_graphic_XPrimitive2DRenderer_idl__
+#define __com_sun_star_graphic_XPrimitive2DRenderer_idl__
+
+#include <com/sun/star/uno/XInterface.idl>
+#include <com/sun/star/rendering/XBitmap.idl>
+#include <com/sun/star/beans/PropertyValue.idl>
+#include <com/sun/star/geometry/RealRectangle2D.idl>
+
+module com { module sun { module star { module graphic {
+
+interface XPrimitive2D;
+
+/** XPrimitive2DRenderer interface
+
+ This interface allows to convert from a sequence of XPrimitive2Ds
+ to a XBitmap
+ */
+interface XPrimitive2DRenderer : ::com::sun::star::uno::XInterface
+{
+ /** return rasterized version of given XPrimitive2D
+
+ @param Primitive2DSequence
+ The graphic content description
+
+ @param aViewInformationSequence
+ The ViewInformation2D
+
+ @param DPI_X
+ The horizontal resolution of the callers device in pixel per inch. This
+ value is needed to calculate the correct dimensions of the graphic to be
+ rasterized. If a value of <value>0</value> is given, a horizontal default
+ resolution of 72 DPI is used.
+
+ @param DPI_Y
+ The vertical resolution of the callers device in pixel per inch. This
+ value is needed to calculate the correct dimensions of the graphic to be
+ rasterized. If a value of <value>0</value> is given, a vertical default
+ resolution of 72 DPI is used.
+
+ @param Range
+ The range in 1/100th mm of the graphic to be rasterized
+
+ @param MaximumQuadraticPixels
+ The maximum allowed number of pixels to be used to allow limiting the
+ possible size of used pixels. The AspectRatio is preserved, the result
+ gets limited to given number. If a value of 0 is given, a default of
+ 500000 is used.
+ */
+ com::sun::star::rendering::XBitmap rasterize(
+ [in] sequence< XPrimitive2D > Primitive2DSequence,
+ [in] sequence< ::com::sun::star::beans::PropertyValue > aViewInformationSequence,
+ [in] unsigned long DPI_X,
+ [in] unsigned long DPI_Y,
+ [in] ::com::sun::star::geometry::RealRectangle2D Range,
+ [in] unsigned long MaximumQuadraticPixels);
+};
+
+}; }; }; };
+
+#endif
diff --git a/offapi/com/sun/star/graphic/XSvgParser.idl b/offapi/com/sun/star/graphic/XSvgParser.idl
new file mode 100644
index 000000000000..5adf67897a2c
--- /dev/null
+++ b/offapi/com/sun/star/graphic/XSvgParser.idl
@@ -0,0 +1,50 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http:\\www.apache.org\licenses\LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+#ifndef __com_sun_star_graphic_XSvgParser_idl__
+#define __com_sun_star_graphic_XSvgParser_idl__
+
+#include <com/sun/star/uno/XInterface.idl>
+#include <com/sun/star/io/XInputStream.idl>
+
+module com { module sun { module star { module graphic {
+
+interface XPrimitive2D;
+
+/** XSvgParser interface
+
+ This interface allows to parse a SVG stream in form of a sequence of bytes
+ to be parsed into a sequence of XPrimitive2Ds
+ */
+interface XSvgParser : ::com::sun::star::uno::XInterface
+{
+ /** Retrieve decomposed list of simpler primitives
+
+ @param xSvgStream
+ The file containing the SVG XML data
+ */
+ sequence< XPrimitive2D > getDecomposition(
+ [in] io::XInputStream xSvgStream,
+ [in] string aAbsolutePath);
+};
+
+}; }; }; };
+
+#endif
diff --git a/offapi/com/sun/star/graphic/makefile.mk b/offapi/com/sun/star/graphic/makefile.mk
index 6e4a0187c15c..9a1452dca771 100755
--- a/offapi/com/sun/star/graphic/makefile.mk
+++ b/offapi/com/sun/star/graphic/makefile.mk
@@ -48,6 +48,8 @@ IDLFILES= \
GraphicRendererVCL.idl \
GraphicType.idl \
MediaProperties.idl \
+ Primitive2DTools.idl \
+ SvgTools.idl \
XPrimitive2D.idl \
XPrimitive3D.idl \
XPrimitiveFactory2D.idl \
@@ -56,7 +58,9 @@ IDLFILES= \
XGraphicRasterizer.idl \
XGraphicRenderer.idl \
XGraphicObject.idl \
- XGraphicTransformer.idl
+ XGraphicTransformer.idl \
+ XPrimitive2DRenderer.idl \
+ XSvgParser.idl
# --- Targets ------------------------------------------------------
diff --git a/postprocess/packcomponents/makefile.mk b/postprocess/packcomponents/makefile.mk
index e931d838bcdb..4dffeeedbc6b 100644
--- a/postprocess/packcomponents/makefile.mk
+++ b/postprocess/packcomponents/makefile.mk
@@ -55,12 +55,14 @@ my_components = \
charttools \
chartview \
component/comphelper/util/comphelp \
+ component/drawinglayer/drawinglayer \
component/framework/util/fwk \
component/framework/util/fwl \
component/framework/util/fwm \
component/vbahelper/util/msforms \
component/sfx2/util/sfx \
component/sot/util/sot \
+ component/svgio/svgio \
component/svl/source/fsstor/fsstorage \
component/svl/source/passwordcontainer/passwordcontainer \
component/svl/util/svl \
diff --git a/postprocess/prj/build.lst b/postprocess/prj/build.lst
index dfcb4c893ef7..4503e6806306 100644
--- a/postprocess/prj/build.lst
+++ b/postprocess/prj/build.lst
@@ -1,4 +1,4 @@
-po postprocess :: accessibility automation basctl bean BINFILTER:binfilter chart2 configmgr CRASHREP:crashrep cui dbaccess desktop dtrans embeddedobj embedserv EPM:epm eventattacher extensions extras fileaccess filter forms fpicker helpcontent2 hwpfilter io JAVAINSTALLER2:javainstaller2 lingucomponent MATHMLDTD:MathMLDTD ODK:odk officecfg package padmin psprint_config remotebridges sc scaddins scp2 scripting sd setup_native slideshow starmath sw sysui testtools ucb UnoControls unoxml ure wizards xmerge xmlsecurity MORE_FONTS:more_fonts OOo:pyuno OOo:readlicense_oo SO:top unodevtools JFREEREPORT:jfreereport REPORTBUILDER:reportbuilder reportdesign SDEXT:sdext SWEXT:swext smoketestdoc uui writerfilter oox MYSQLC:mysqlc LIBXSLT:libxslt NULL
+po postprocess :: svgio accessibility automation basctl bean BINFILTER:binfilter chart2 configmgr CRASHREP:crashrep cui dbaccess desktop dtrans embeddedobj embedserv EPM:epm eventattacher extensions extras fileaccess filter forms fpicker helpcontent2 hwpfilter io JAVAINSTALLER2:javainstaller2 lingucomponent MATHMLDTD:MathMLDTD ODK:odk officecfg package padmin psprint_config remotebridges sc scaddins scp2 scripting sd setup_native slideshow starmath sw sysui testtools ucb UnoControls unoxml ure wizards xmerge xmlsecurity MORE_FONTS:more_fonts OOo:pyuno OOo:readlicense_oo SO:top unodevtools JFREEREPORT:jfreereport REPORTBUILDER:reportbuilder reportdesign SDEXT:sdext SWEXT:swext smoketestdoc uui writerfilter oox MYSQLC:mysqlc LIBXSLT:libxslt NULL
po postprocess usr1 - all po_mkout NULL
po postprocess\checkxml nmake - all po_checkxml NULL
po postprocess\checkdeliver nmake - all po_checkdlv NULL
diff --git a/scp2/source/ooo/file_library_ooo.scp b/scp2/source/ooo/file_library_ooo.scp
index 419ff7c6117d..521718c1532d 100755
--- a/scp2/source/ooo/file_library_ooo.scp
+++ b/scp2/source/ooo/file_library_ooo.scp
@@ -378,6 +378,7 @@ End
#endif
STD_LIB_FILE(gid_File_Lib_Drawinglayer,drawinglayer)
+STD_LIB_FILE(gid_File_Lib_SvgIo,svgio)
SPECIAL_LIB_FILE(gid_File_Lib_Embobj,embobj)
diff --git a/scp2/source/ooo/module_hidden_ooo.scp b/scp2/source/ooo/module_hidden_ooo.scp
index 01eda12cd10f..c4bff2b139f5 100644
--- a/scp2/source/ooo/module_hidden_ooo.scp
+++ b/scp2/source/ooo/module_hidden_ooo.scp
@@ -173,6 +173,7 @@ Module gid_Module_Root_Files_4
gid_File_Lib_Dbt,
gid_File_Lib_Dbfile,
gid_File_Lib_Drawinglayer,
+ gid_File_Lib_SvgIo,
gid_File_Lib_Editeng,
gid_File_Lib_Flat,
gid_File_Lib_For,
diff --git a/sd/source/ui/view/drviews2.cxx b/sd/source/ui/view/drviews2.cxx
index 732abf866dec..ba0afc2b0b57 100755
--- a/sd/source/ui/view/drviews2.cxx
+++ b/sd/source/ui/view/drviews2.cxx
@@ -627,7 +627,9 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq)
else
{
if( mpDrawView->IsVectorizeAllowed() )
+ {
SetCurrentFunction( FuVectorize::Create( this, GetActiveWindow(), mpDrawView, GetDoc(), rReq ) );
+ }
else
{
WaitObject aWait( (Window*)GetActiveWindow() );
@@ -709,8 +711,31 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq)
break;
case SID_CONVERT_TO_BITMAP:
{
- Bitmap aBitmap (mpDrawView->GetAllMarkedBitmap ());
- aGraphic = Graphic(aBitmap);
+ bool bDone(false);
+
+ // I have to get the image here directly since GetAllMarkedBitmap works
+ // based on Bitmaps, but not on BitmapEx, thus throwing away the alpha
+ // channel. Argh! GetAllMarkedBitmap itself is too widely used to safely
+ // change that, e.g. in the exchange formats. For now I can only add this
+ // exception to get good results for Svgs. This is how the code gets more
+ // and more crowded, at last I made a remark for myself to change this
+ // as one of the next tasks.
+ if(1 == mpDrawView->GetMarkedObjectCount())
+ {
+ const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(mpDrawView->GetMarkedObjectByIndex(0));
+
+ if(pSdrGrafObj && pSdrGrafObj->isEmbeddedSvg())
+ {
+ aGraphic = Graphic(pSdrGrafObj->GetGraphic().getSvgData()->getReplacement());
+ bDone = true;
+ }
+ }
+
+ if(!bDone)
+ {
+ Bitmap aBitmap (mpDrawView->GetAllMarkedBitmap ());
+ aGraphic = Graphic(aBitmap);
+ }
}
break;
}
diff --git a/sd/source/ui/view/drviews6.cxx b/sd/source/ui/view/drviews6.cxx
index 4bedfdb69663..17ec4618c075 100755
--- a/sd/source/ui/view/drviews6.cxx
+++ b/sd/source/ui/view/drviews6.cxx
@@ -446,7 +446,7 @@ void DrawViewShell::GetBmpMaskState( SfxItemSet& rSet )
// valid graphic object?
if( pObj && pObj->ISA( SdrGrafObj ) &&
- !( ((SdrGrafObj*) pObj)->IsEPS() || ((SdrGrafObj*) pObj)->IsRenderGraphic() ) &&
+ !((SdrGrafObj*) pObj)->IsEPS() &&
!mpDrawView->IsTextEdit() )
{
bEnable = sal_True;
diff --git a/sd/source/ui/view/drviews7.cxx b/sd/source/ui/view/drviews7.cxx
index cc7ba64df08d..cb1423cc359d 100755
--- a/sd/source/ui/view/drviews7.cxx
+++ b/sd/source/ui/view/drviews7.cxx
@@ -1426,11 +1426,17 @@ void DrawViewShell::GetMenuState( SfxItemSet &rSet )
bFoundMetafile = true;
break;
case OBJ_GRAF :
+ {
bSingleGraphicSelected = nMarkCount == 1;
- switch ( ((SdrGrafObj*)pObj)->GetGraphicType() )
+ const SdrGrafObj* pSdrGrafObj = static_cast< const SdrGrafObj* >(pObj);
+ switch(pSdrGrafObj->GetGraphicType())
{
case GRAPHIC_BITMAP :
bFoundBitmap = sal_True;
+ if(pSdrGrafObj->isEmbeddedSvg())
+ {
+ bFoundMetafile = true;
+ }
break;
case GRAPHIC_GDIMETAFILE :
bFoundMetafile = sal_True;
@@ -1442,6 +1448,7 @@ void DrawViewShell::GetMenuState( SfxItemSet &rSet )
// #i25616# bFoundObjNoLine = sal_True;
// #i25616# bFoundObjNoArea = sal_True;
break;
+ }
case OBJ_TABLE:
bFoundTable = true;
break;
diff --git a/sd/source/ui/view/drviewsc.cxx b/sd/source/ui/view/drviewsc.cxx
index b5dbab402d0d..e325dc721991 100755
--- a/sd/source/ui/view/drviewsc.cxx
+++ b/sd/source/ui/view/drviewsc.cxx
@@ -363,10 +363,23 @@ void DrawViewShell::FuTemp03(SfxRequest& rReq)
SdrObject* pObj=pM->GetMarkedSdrObj();
SdrGrafObj* pGraf=PTR_CAST(SdrGrafObj,pObj);
SdrOle2Obj* pOle2=PTR_CAST(SdrOle2Obj,pObj);
- if (pGraf!=NULL && pGraf->HasGDIMetaFile())
- nCount += pGraf->GetGraphic().GetGDIMetaFile().GetActionCount();
- if(pOle2!=NULL && pOle2->GetGraphic())
+
+ if(pGraf)
+ {
+ if(pGraf->HasGDIMetaFile())
+ {
+ nCount += pGraf->GetGraphic().GetGDIMetaFile().GetActionCount();
+ }
+ else if(pGraf->isEmbeddedSvg())
+ {
+ nCount += pGraf->getMetafileFromEmbeddedSvg().GetActionCount();
+ }
+ }
+
+ if(pOle2 && pOle2->GetGraphic())
+ {
nCount += pOle2->GetGraphic()->GetGDIMetaFile().GetActionCount();
+ }
}
// anhand der erm. Summe entscheiden ob mit
diff --git a/sd/source/ui/view/drviewsj.cxx b/sd/source/ui/view/drviewsj.cxx
index 5992b678d7af..40366a4ee555 100755
--- a/sd/source/ui/view/drviewsj.cxx
+++ b/sd/source/ui/view/drviewsj.cxx
@@ -127,22 +127,22 @@ void DrawViewShell::GetMenuStateSel( SfxItemSet &rSet )
SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_TEXTATTR_DLG ) )
{
const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pObj);
+ const SdrOle2Obj* pSdrOle2Obj = dynamic_cast< const SdrOle2Obj* >(pObj);
sal_uInt32 nInv = pObj->GetObjInventor();
sal_uInt16 nId = pObj->GetObjIdentifier();
SdrObjTransformInfoRec aInfoRec;
pObj->TakeObjInfo( aInfoRec );
-
// #91929#; don't show original size entry if not possible
- if ( pObj->ISA( SdrOle2Obj ) )
+ if(pSdrOle2Obj)
{
- SdrOle2Obj* pOleObj = PTR_CAST(SdrOle2Obj, pObj);
- if (pOleObj->GetObjRef().is() &&
- ((pOleObj->GetObjRef()->getStatus( pOleObj->GetAspect() ) & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE) ) )
+ if (pSdrOle2Obj->GetObjRef().is() &&
+ ((pSdrOle2Obj->GetObjRef()->getStatus( pSdrOle2Obj->GetAspect() ) & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE) ) )
rSet.DisableItem(SID_ORIGINAL_SIZE);
}
- if ( !( pObj->ISA( SdrGrafObj ) ) )
+ if(!pSdrGrafObj)
{
rSet.DisableItem(SID_SAVEGRAPHIC);
}
@@ -167,9 +167,10 @@ void DrawViewShell::GetMenuStateSel( SfxItemSet &rSet )
rSet.DisableItem( SID_NAME_GROUP );
}
*/
- if (!pObj->ISA(SdrGrafObj) ||
- ((SdrGrafObj*) pObj)->GetGraphicType() != GRAPHIC_BITMAP ||
- ((SdrGrafObj*) pObj)->IsLinkedGraphic())
+ if(!pSdrGrafObj ||
+ pSdrGrafObj->GetGraphicType() != GRAPHIC_BITMAP ||
+ pSdrGrafObj->IsLinkedGraphic() ||
+ pSdrGrafObj->isEmbeddedSvg())
{
rSet.DisableItem(SID_CONVERT_TO_1BIT_THRESHOLD);
rSet.DisableItem(SID_CONVERT_TO_1BIT_MATRIX);
diff --git a/sd/source/ui/view/sdview.cxx b/sd/source/ui/view/sdview.cxx
index ec4b371bf244..cf096a396b27 100755
--- a/sd/source/ui/view/sdview.cxx
+++ b/sd/source/ui/view/sdview.cxx
@@ -1073,10 +1073,15 @@ sal_Bool View::IsVectorizeAllowed() const
if( rMarkList.GetMarkCount() == 1 )
{
- const SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ const SdrGrafObj* pObj = dynamic_cast< const SdrGrafObj* >(rMarkList.GetMark( 0 )->GetMarkedSdrObj());
- if( pObj->ISA( SdrGrafObj ) && ( (SdrGrafObj*) pObj )->GetGraphicType() == GRAPHIC_BITMAP )
- bRet = sal_True;
+ if(pObj)
+ {
+ if(GRAPHIC_BITMAP == pObj->GetGraphicType() && !pObj->isEmbeddedSvg())
+ {
+ bRet = sal_True;
+ }
+ }
}
return bRet;
diff --git a/sd/source/ui/view/sdview3.cxx b/sd/source/ui/view/sdview3.cxx
index 3ed80ae038ed..7f95b212aabe 100755
--- a/sd/source/ui/view/sdview3.cxx
+++ b/sd/source/ui/view/sdview3.cxx
@@ -219,7 +219,6 @@ if( aPreviewSizePixel.Width() && aPreviewSizePixel.Height() )
case META_GRADIENTEX_ACTION:
case META_BMPSCALEPART_ACTION:
case META_BMPEXSCALEPART_ACTION:
- case META_RENDERGRAPHIC_ACTION:
bVector = true;
break;
case META_BMP_ACTION:
diff --git a/sd/source/ui/view/sdview4.cxx b/sd/source/ui/view/sdview4.cxx
index 6a34c5265f59..1f5e0f28f567 100755
--- a/sd/source/ui/view/sdview4.cxx
+++ b/sd/source/ui/view/sdview4.cxx
@@ -395,8 +395,10 @@ IMPL_LINK( View, DropInsertFileHdl, Timer*, EMPTYARG )
const bool bLink = ( ( nTempAction & DND_ACTION_LINK ) != 0 );
SdrGrafObj* pGrafObj = InsertGraphic( aGraphic, nTempAction, maDropPos, NULL, NULL );
- if( pGrafObj && bLink )
+ if(pGrafObj && bLink)
+ {
pGrafObj->SetGraphicLink( aCurrentDropFile, String() );
+ }
// return action from first inserted graphic
if( aIter == maDropFileVector.begin() )
diff --git a/solenv/inc/libs.mk b/solenv/inc/libs.mk
index 4bcc55756c2d..030d87a79e03 100644
--- a/solenv/inc/libs.mk
+++ b/solenv/inc/libs.mk
@@ -139,6 +139,7 @@ VCLLIB=-lvcl$(DLLPOSTFIX)
OOXLIB=-loox$(DLLPOSTFIX)
BASEGFXLIB=-lbasegfx$(DLLPOSTFIX)
DRAWINGLAYERLIB=-ldrawinglayer$(DLLPOSTFIX)
+SVGIOLIB=-lsvgio$(DLLPOSTFIX)
BASEBMPLIB=-lbasebmp$(DLLPOSTFIX)
CANVASTOOLSLIB=-lcanvastools$(DLLPOSTFIX)
CPPCANVASLIB=-lcppcanvas$(DLLPOSTFIX)
@@ -463,6 +464,7 @@ VCLLIB=ivcl.lib
OOXLIB=ioox.lib
BASEGFXLIB=ibasegfx.lib
DRAWINGLAYERLIB=idrawinglayer.lib
+SVGIOLIB=isvgio.lib
BASEBMPLIB=ibasebmp.lib
CANVASTOOLSLIB=icanvastools.lib
CPPCANVASLIB=icppcanvas.lib
diff --git a/splitbuild/framework.lst b/splitbuild/framework.lst
index 1333e7dc7eec..30a9d55e04a9 100644
--- a/splitbuild/framework.lst
+++ b/splitbuild/framework.lst
@@ -1 +1 @@
-automation avmedia basic basctl cui desktop drawinglayer extensions forms formula framework idl scripting sfx2 svx xmlsecurity vbahelper
+automation avmedia basic basctl cui desktop drawinglayer svgio extensions forms formula framework idl scripting sfx2 svx xmlsecurity vbahelper
diff --git a/svgio/Library_svgio.mk b/svgio/Library_svgio.mk
new file mode 100644
index 000000000000..0d80f85a63f9
--- /dev/null
+++ b/svgio/Library_svgio.mk
@@ -0,0 +1,93 @@
+#/**************************************************************
+# *
+# * Licensed to the Apache Software Foundation (ASF) under one
+# * or more contributor license agreements. See the NOTICE file
+# * distributed with this work for additional information
+# * regarding copyright ownership. The ASF licenses this file
+# * to you under the Apache License, Version 2.0 (the
+# * "License"); you may not use this file except in compliance
+# * with the License. You may obtain a copy of the License at
+# *
+# * http://www.apache.org/licenses/LICENSE-2.0
+# *
+# * Unless required by applicable law or agreed to in writing,
+# * software distributed under the License is distributed on an
+# * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# * KIND, either express or implied. See the License for the
+# * specific language governing permissions and limitations
+# * under the License.
+# *
+# *************************************************************/
+
+$(eval $(call gb_Library_Library,svgio))
+
+$(eval $(call gb_Library_set_componentfile,svgio,svgio/svgio))
+
+$(eval $(call gb_Library_add_package_headers,svgio,svgio_inc))
+
+$(eval $(call gb_Library_add_precompiled_header,svgio,$(SRCDIR)/svgio/inc/pch/precompiled_svgio))
+
+$(eval $(call gb_Library_set_include,svgio,\
+ $$(INCLUDE) \
+ -I$(SRCDIR)/svgio/inc \
+ -I$(SRCDIR)/svgio/inc/pch \
+ -I$(SRCDIR)/solenv/inc \
+ -I$(OUTDIR)/inc/offuh \
+))
+
+$(eval $(call gb_Library_set_defs,svgio,\
+ $$(DEFS) \
+ -DSVGIO_DLLIMPLEMENTATION \
+))
+
+$(eval $(call gb_Library_add_linked_libs,svgio,\
+ basegfx \
+ drawinglayer \
+ comphelper \
+ cppu \
+ cppuhelper \
+ sal \
+ stl \
+ tl \
+ sax \
+ vcl \
+ svt \
+ $(gb_STDLIBS) \
+))
+
+$(eval $(call gb_Library_add_exception_objects,svgio,\
+ svgio/source/svgreader/svgcharacternode \
+ svgio/source/svgreader/svgcirclenode \
+ svgio/source/svgreader/svgclippathnode \
+ svgio/source/svgreader/svgdocument \
+ svgio/source/svgreader/svgdocumenthandler \
+ svgio/source/svgreader/svgellipsenode \
+ svgio/source/svgreader/svggnode \
+ svgio/source/svgreader/svggradientnode \
+ svgio/source/svgreader/svggradientstopnode \
+ svgio/source/svgreader/svgimagenode \
+ svgio/source/svgreader/svglinenode \
+ svgio/source/svgreader/svgmarkernode \
+ svgio/source/svgreader/svgmasknode \
+ svgio/source/svgreader/svgnode \
+ svgio/source/svgreader/svgpaint \
+ svgio/source/svgreader/svgpathnode \
+ svgio/source/svgreader/svgpatternnode \
+ svgio/source/svgreader/svgpolynode \
+ svgio/source/svgreader/svgrectnode \
+ svgio/source/svgreader/svgstyleattributes \
+ svgio/source/svgreader/svgstylenode \
+ svgio/source/svgreader/svgsvgnode \
+ svgio/source/svgreader/svgsymbolnode \
+ svgio/source/svgreader/svgtextnode \
+ svgio/source/svgreader/svgtoken \
+ svgio/source/svgreader/svgtrefnode \
+ svgio/source/svgreader/svgtools \
+ svgio/source/svgreader/svgtextpathnode \
+ svgio/source/svgreader/svgtspannode \
+ svgio/source/svgreader/svgusenode \
+ svgio/source/svguno/svguno \
+ svgio/source/svguno/xsvgparser \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/svgio/Makefile b/svgio/Makefile
new file mode 100644
index 000000000000..631870fb0980
--- /dev/null
+++ b/svgio/Makefile
@@ -0,0 +1,32 @@
+#/**************************************************************
+# *
+# * Licensed to the Apache Software Foundation (ASF) under one
+# * or more contributor license agreements. See the NOTICE file
+# * distributed with this work for additional information
+# * regarding copyright ownership. The ASF licenses this file
+# * to you under the Apache License, Version 2.0 (the
+# * "License"); you may not use this file except in compliance
+# * with the License. You may obtain a copy of the License at
+# *
+# * http://www.apache.org/licenses/LICENSE-2.0
+# *
+# * Unless required by applicable law or agreed to in writing,
+# * software distributed under the License is distributed on an
+# * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# * KIND, either express or implied. See the License for the
+# * specific language governing permissions and limitations
+# * under the License.
+# *
+# *************************************************************/
+
+ifeq ($(strip $(SOLARENV)),)
+$(error No environment set!)
+endif
+
+gb_PARTIALBUILD := T
+GBUILDDIR := $(SOLARENV)/gbuild
+include $(GBUILDDIR)/gbuild.mk
+
+$(eval $(call gb_Module_make_global_targets,$(shell ls $(dir $(realpath $(firstword $(MAKEFILE_LIST))))/Module*.mk)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/svgio/Module_svgio.mk b/svgio/Module_svgio.mk
new file mode 100644
index 000000000000..4ca9474263e4
--- /dev/null
+++ b/svgio/Module_svgio.mk
@@ -0,0 +1,29 @@
+#/**************************************************************
+# *
+# * Licensed to the Apache Software Foundation (ASF) under one
+# * or more contributor license agreements. See the NOTICE file
+# * distributed with this work for additional information
+# * regarding copyright ownership. The ASF licenses this file
+# * to you under the Apache License, Version 2.0 (the
+# * "License"); you may not use this file except in compliance
+# * with the License. You may obtain a copy of the License at
+# *
+# * http://www.apache.org/licenses/LICENSE-2.0
+# *
+# * Unless required by applicable law or agreed to in writing,
+# * software distributed under the License is distributed on an
+# * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# * KIND, either express or implied. See the License for the
+# * specific language governing permissions and limitations
+# * under the License.
+# *
+# *************************************************************/
+
+$(eval $(call gb_Module_Module,svgio))
+
+$(eval $(call gb_Module_add_targets,svgio,\
+ Library_svgio \
+ Package_inc \
+))
+
+# vim: set noet ts=4 sw=4:
diff --git a/svgio/Package_inc.mk b/svgio/Package_inc.mk
new file mode 100644
index 000000000000..0bd9ea0ac244
--- /dev/null
+++ b/svgio/Package_inc.mk
@@ -0,0 +1,53 @@
+#/**************************************************************
+# *
+# * Licensed to the Apache Software Foundation (ASF) under one
+# * or more contributor license agreements. See the NOTICE file
+# * distributed with this work for additional information
+# * regarding copyright ownership. The ASF licenses this file
+# * to you under the Apache License, Version 2.0 (the
+# * "License"); you may not use this file except in compliance
+# * with the License. You may obtain a copy of the License at
+# *
+# * http://www.apache.org/licenses/LICENSE-2.0
+# *
+# * Unless required by applicable law or agreed to in writing,
+# * software distributed under the License is distributed on an
+# * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# * KIND, either express or implied. See the License for the
+# * specific language governing permissions and limitations
+# * under the License.
+# *
+# *************************************************************/
+
+$(eval $(call gb_Package_Package,svgio_inc,$(SRCDIR)/svgio/inc))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgiodllapi.h,svgio/svgiodllapi.h))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgcharacternode.hxx,svgio/svgreader/svgcharacternode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgcirclenode.hxx,svgio/svgreader/svgcirclenode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgclippathnode.hxx,svgio/svgreader/svgclippathnode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgdocument.hxx,svgio/svgreader/svgdocument.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgdocumenthandler.hxx,svgio/svgreader/svgdocumenthandler.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgellipsenode.hxx,svgio/svgreader/svgellipsenode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svggnode.hxx,svgio/svgreader/svggnode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svggradientnode.hxx,svgio/svgreader/svggradientnode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svggradientstopnode.hxx,svgio/svgreader/svggradientstopnode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgimagenode.hxx,svgio/svgreader/svgimagenode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svglinenode.hxx,svgio/svgreader/svglinenode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgnode.hxx,svgio/svgreader/svgnode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgmarkernode.hxx,svgio/svgreader/svgmarkernode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgmasknode.hxx,svgio/svgreader/svgmasknode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgpaint.hxx,svgio/svgreader/svgpaint.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgpathnode.hxx,svgio/svgreader/svgpathnode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgpatternnode.hxx,svgio/svgreader/svgpatternnode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgpolynode.hxx,svgio/svgreader/svgpolynode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgrectnode.hxx,svgio/svgreader/svgrectnode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgstyleattributes.hxx,svgio/svgreader/svgstyleattributes.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgstylenode.hxx,svgio/svgreader/svgstylenode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgsvgnode.hxx,svgio/svgreader/svgsvgnode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgsymbolnode.hxx,svgio/svgreader/svgsymbolnode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgtextnode.hxx,svgio/svgreader/svgtextnode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgtoken.hxx,svgio/svgreader/svgtoken.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgtrefnode.hxx,svgio/svgreader/svgtrefnode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgtools.hxx,svgio/svgreader/svgtools.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgtextpathnode.hxx,svgio/svgreader/svgtextpathnode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgtspannode.hxx,svgio/svgreader/svgtspannode.hxx))
+$(eval $(call gb_Package_add_file,svgio_inc,inc/svgio/svgreader/svgusenode.hxx,svgio/svgreader/svgusenode.hxx))
diff --git a/svgio/inc/makefile.mk b/svgio/inc/makefile.mk
new file mode 100644
index 000000000000..39e5dee8bbed
--- /dev/null
+++ b/svgio/inc/makefile.mk
@@ -0,0 +1,41 @@
+#/**************************************************************
+# *
+# * Licensed to the Apache Software Foundation (ASF) under one
+# * or more contributor license agreements. See the NOTICE file
+# * distributed with this work for additional information
+# * regarding copyright ownership. The ASF licenses this file
+# * to you under the Apache License, Version 2.0 (the
+# * "License"); you may not use this file except in compliance
+# * with the License. You may obtain a copy of the License at
+# *
+# * http://www.apache.org/licenses/LICENSE-2.0
+# *
+# * Unless required by applicable law or agreed to in writing,
+# * software distributed under the License is distributed on an
+# * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# * KIND, either express or implied. See the License for the
+# * specific language governing permissions and limitations
+# * under the License.
+# *
+# *************************************************************/
+PRJ=..
+
+PRJNAME=svgio
+TARGET=inc
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.IF "$(ENABLE_PCH)"!=""
+ALLTAR : \
+ $(SLO)$/precompiled.pch \
+ $(SLO)$/precompiled_ex.pch
+
+.ENDIF # "$(ENABLE_PCH)"!=""
+
diff --git a/svgio/inc/pch/precompiled_svgio.cxx b/svgio/inc/pch/precompiled_svgio.cxx
new file mode 100644
index 000000000000..bb4be3a78fe1
--- /dev/null
+++ b/svgio/inc/pch/precompiled_svgio.cxx
@@ -0,0 +1,23 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#include "precompiled_svgio.hxx"
+
diff --git a/svgio/inc/pch/precompiled_svgio.hxx b/svgio/inc/pch/precompiled_svgio.hxx
new file mode 100644
index 000000000000..1f660d13c16d
--- /dev/null
+++ b/svgio/inc/pch/precompiled_svgio.hxx
@@ -0,0 +1,26 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): Generated on 2006-09-01 17:49:30.796084
+
+#ifdef PRECOMPILED_HEADERS
+#endif
+
diff --git a/svgio/inc/svgio/svgiodllapi.h b/svgio/inc/svgio/svgiodllapi.h
new file mode 100644
index 000000000000..2d4265a18a68
--- /dev/null
+++ b/svgio/inc/svgio/svgiodllapi.h
@@ -0,0 +1,33 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+#ifndef INCLUDED_SVGIODLLAPI_H
+#define INCLUDED_SVGIODLLAPI_H
+
+#include "sal/types.h"
+
+#if defined(SVGIO_DLLIMPLEMENTATION)
+#define SVGIO_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
+#else
+#define SVGIO_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
+#endif
+#define SVGIO_DLLPRIVATE SAL_DLLPRIVATE
+
+#endif /* INCLUDED_SVGIODLLAPI_H */
diff --git a/svgio/inc/svgio/svgreader/svgcharacternode.hxx b/svgio/inc/svgio/svgreader/svgcharacternode.hxx
new file mode 100644
index 000000000000..6b135b8dcb9d
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgcharacternode.hxx
@@ -0,0 +1,184 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGCHARACTERNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGCHARACTERNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+// predefines
+
+namespace drawinglayer { namespace primitive2d { class TextSimplePortionPrimitive2D; }}
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgTextPositions
+ {
+ private:
+ SvgNumberVector maX;
+ SvgNumberVector maY;
+ SvgNumberVector maDx;
+ SvgNumberVector maDy;
+ SvgNumberVector maRotate;
+ SvgNumber maTextLength;
+
+ /// bitfield
+ bool mbLengthAdjust : 1; // true = spacing, false = spacingAndGlyphs
+
+ public:
+ SvgTextPositions();
+
+ void parseTextPositionAttributes(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+
+ /// X content
+ const SvgNumberVector& getX() const { return maX; }
+ void setX(const SvgNumberVector& aX) { maX = aX; }
+
+ /// Y content
+ const SvgNumberVector& getY() const { return maY; }
+ void setY(const SvgNumberVector& aY) { maY = aY; }
+
+ /// Dx content
+ const SvgNumberVector& getDx() const { return maDx; }
+ void setDx(const SvgNumberVector& aDx) { maDx = aDx; }
+
+ /// Dy content
+ const SvgNumberVector& getDy() const { return maDy; }
+ void setDy(const SvgNumberVector& aDy) { maDy = aDy; }
+
+ /// Rotate content
+ const SvgNumberVector& getRotate() const { return maRotate; }
+ void setRotate(const SvgNumberVector& aRotate) { maRotate = aRotate; }
+
+ /// TextLength content
+ const SvgNumber& getTextLength() const { return maTextLength; }
+ void setTextLength(const SvgNumber& rTextLength = SvgNumber()) { maTextLength = rTextLength; }
+
+ /// LengthAdjust content
+ bool getLengthAdjust() const { return mbLengthAdjust; }
+ void setLengthAdjust(bool bNew) { mbLengthAdjust = bNew; }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgTextPosition
+ {
+ private:
+ SvgTextPosition* mpParent;
+ ::std::vector< double > maX;
+ ::std::vector< double > maY;
+ ::std::vector< double > maRotate;
+ double mfTextLength;
+
+ // absolute, current, advancing position
+ basegfx::B2DPoint maPosition;
+
+ // advancing rotation index
+ sal_uInt32 mnRotationIndex;
+
+ /// bitfield
+ bool mbLengthAdjust : 1; // true = spacing, false = spacingAndGlyphs
+ bool mbAbsoluteX : 1;
+ bool mbAbsoluteY : 1;
+
+ public:
+ SvgTextPosition(
+ SvgTextPosition* pParent,
+ const InfoProvider& rInfoProvider,
+ const SvgTextPositions& rSvgTextPositions);
+
+ // data read access
+ const SvgTextPosition* getParent() const { return mpParent; }
+ const ::std::vector< double >& getX() const { return maX; }
+ const ::std::vector< double >& getY() const { return maY; }
+ double getTextLength() const { return mfTextLength; }
+ bool getLengthAdjust() const { return mbLengthAdjust; }
+ bool getAbsoluteX() const { return mbAbsoluteX; }
+ bool getAbsoluteY() const { return mbAbsoluteY; }
+
+ // get/set absolute, current, advancing position
+ const basegfx::B2DPoint& getPosition() const { return maPosition; }
+ void setPosition(const basegfx::B2DPoint& rNew) { maPosition = rNew; }
+
+ // rotation handling
+ bool isRotated() const;
+ double consumeRotation();
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgCharacterNode : public SvgNode
+ {
+ private:
+ /// the string data
+ rtl::OUString maText;
+
+ /// local helpers
+ drawinglayer::primitive2d::TextSimplePortionPrimitive2D* createSimpleTextPrimitive(
+ SvgTextPosition& rSvgTextPosition,
+ const SvgStyleAttributes& rSvgStyleAttributes) const;
+ void decomposeTextWithStyle(
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ SvgTextPosition& rSvgTextPosition,
+ const SvgStyleAttributes& rSvgStyleAttributes) const;
+
+ public:
+ SvgCharacterNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent,
+ const rtl::OUString& rText);
+ virtual ~SvgCharacterNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void decomposeText(drawinglayer::primitive2d::Primitive2DSequence& rTarget, SvgTextPosition& rSvgTextPosition) const;
+ void whiteSpaceHandling();
+ void addGap();
+ void concatenate(const rtl::OUString& rText);
+
+ /// Text content
+ const rtl::OUString& getText() const { return maText; }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGCHARACTERNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgcirclenode.hxx b/svgio/inc/svgio/svgreader/svgcirclenode.hxx
new file mode 100644
index 000000000000..420cfb93d5ea
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgcirclenode.hxx
@@ -0,0 +1,80 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGCIRCLENODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGCIRCLENODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgCircleNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// variable scan values, dependent of given XAttributeList
+ SvgNumber maCx;
+ SvgNumber maCy;
+ SvgNumber maR;
+ basegfx::B2DHomMatrix* mpaTransform;
+
+ public:
+ SvgCircleNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgCircleNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+ virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const;
+
+ /// Cx content, set if found in current context
+ const SvgNumber& getCx() const { return maCx; }
+ void setCx(const SvgNumber& rCx = SvgNumber()) { maCx = rCx; }
+
+ /// Cy content, set if found in current context
+ const SvgNumber& getCy() const { return maCy; }
+ void setCy(const SvgNumber& rCy = SvgNumber()) { maCy = rCy; }
+
+ /// R content, set if found in current context
+ const SvgNumber& getR() const { return maR; }
+ void setR(const SvgNumber& rR = SvgNumber()) { maR = rR; }
+
+ /// transform content, set if found in current context
+ const basegfx::B2DHomMatrix* getTransform() const { return mpaTransform; }
+ void setTransform(const basegfx::B2DHomMatrix* pMatrix = 0) { if(mpaTransform) delete mpaTransform; mpaTransform = 0; if(pMatrix) mpaTransform = new basegfx::B2DHomMatrix(*pMatrix); }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGCIRCLENODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgclippathnode.hxx b/svgio/inc/svgio/svgreader/svgclippathnode.hxx
new file mode 100755
index 000000000000..e2fc7cb11f5c
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgclippathnode.hxx
@@ -0,0 +1,73 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGCLIPPATHNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGCLIPPATHNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgClipPathNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// variable scan values, dependent of given XAttributeList
+ basegfx::B2DHomMatrix* mpaTransform;
+ SvgUnits maClipPathUnits;
+
+ public:
+ SvgClipPathNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgClipPathNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+ virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const;
+
+ /// apply contained clipPath to given geometry
+ void apply(drawinglayer::primitive2d::Primitive2DSequence& rTarget) const;
+
+ /// clipPathUnits content
+ SvgUnits getClipPathUnits() const { return maClipPathUnits; }
+ void setClipPathUnits(const SvgUnits aClipPathUnits) { maClipPathUnits = aClipPathUnits; }
+
+ /// transform content
+ const basegfx::B2DHomMatrix* getTransform() const { return mpaTransform; }
+ void setTransform(const basegfx::B2DHomMatrix* pMatrix = 0) { if(mpaTransform) delete mpaTransform; mpaTransform = 0; if(pMatrix) mpaTransform = new basegfx::B2DHomMatrix(*pMatrix); }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGCLIPPATHNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgdocument.hxx b/svgio/inc/svgio/svgreader/svgdocument.hxx
new file mode 100644
index 000000000000..ac233784afdf
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgdocument.hxx
@@ -0,0 +1,88 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGDOCUMENT_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGDOCUMENT_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <boost/utility.hpp>
+#include <svgio/svgreader/svgnode.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgDocument : private boost::noncopyable
+ {
+ private:
+ /// the document hierarchy with all root nodes
+ SvgNodeVector maNodes;
+
+ /// the absolute path of the Svg file in progress (if available)
+ const rtl::OUString maAbsolutePath;
+
+ /// hash mapper to find nodes by their id
+ typedef std::hash_map< const rtl::OUString, const SvgNode*, rtl::OUStringHash > IdTokenMapper;
+ typedef std::pair< const rtl::OUString, const SvgNode* > IdTokenValueType;
+ IdTokenMapper maIdTokenMapperList;
+
+ /// hash mapper to find css styles by their id
+ typedef std::hash_map< const rtl::OUString, const SvgStyleAttributes*, rtl::OUStringHash > IdStyleTokenMapper;
+ typedef std::pair< const rtl::OUString, const SvgStyleAttributes* > IdStyleTokenValueType;
+ IdStyleTokenMapper maIdStyleTokenMapperList;
+
+ public:
+ SvgDocument(const rtl::OUString& rAbsolutePath);
+ ~SvgDocument();
+
+ /// append anopther root node, ownership changes
+ void appendNode(SvgNode* pNode);
+
+ /// add/remove nodes with Id to mapper
+ void addSvgNodeToMapper(const rtl::OUString& rStr, const SvgNode& rNode);
+ void removeSvgNodeFromMapper(const rtl::OUString& rStr);
+
+ /// find a node by it's Id
+ bool hasSvgNodesById() const { return !maIdTokenMapperList.empty(); }
+ const SvgNode* findSvgNodeById(const rtl::OUString& rStr) const;
+
+ /// add/remove styles to mapper
+ void addSvgStyleAttributesToMapper(const rtl::OUString& rStr, const SvgStyleAttributes& rSvgStyleAttributes);
+ void removeSvgStyleAttributesFromMapper(const rtl::OUString& rStr);
+
+ /// find a style by it's Id
+ bool hasSvgStyleAttributesById() const { return !maIdStyleTokenMapperList.empty(); }
+ const SvgStyleAttributes* findSvgStyleAttributesById(const rtl::OUString& rStr) const;
+
+ /// data read access
+ const SvgNodeVector& getSvgNodeVector() const { return maNodes; }
+ const rtl::OUString& getAbsolutePath() const { return maAbsolutePath; }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGDOCUMENT_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgdocumenthandler.hxx b/svgio/inc/svgio/svgreader/svgdocumenthandler.hxx
new file mode 100644
index 000000000000..19b631acb87c
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgdocumenthandler.hxx
@@ -0,0 +1,75 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGDOCUMENTHANDLER_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGDOCUMENTHANDLER_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <svgio/svgreader/svgdocument.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+// predefines
+
+namespace svgio { namespace svgreader { class SvgCharacterNode; }}
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgDocHdl : public cppu::WeakImplHelper1< com::sun::star::xml::sax::XDocumentHandler >
+ {
+ private:
+ // the complete SVG Document
+ SvgDocument maDocument;
+
+ // current node for parsing
+ SvgNode* mpTarget;
+
+ /// bitfield
+ bool mbValidToken : 1;
+
+ public:
+ SvgDocHdl(const rtl::OUString& rAbsolutePath);
+ ~SvgDocHdl();
+
+ // Methods XDocumentHandler
+ virtual void SAL_CALL startDocument( ) throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL endDocument( ) throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL startElement( const ::rtl::OUString& aName, const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttribs ) throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL endElement( const ::rtl::OUString& aName ) throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setDocumentLocator( const com::sun::star::uno::Reference< com::sun::star::xml::sax::XLocator >& xLocator ) throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException);
+
+ const SvgDocument& getSvgDocument() const { return maDocument; }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGDOCUMENTHANDLER_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgellipsenode.hxx b/svgio/inc/svgio/svgreader/svgellipsenode.hxx
new file mode 100644
index 000000000000..108ea288d176
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgellipsenode.hxx
@@ -0,0 +1,85 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGELLIPSENODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGELLIPSENODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgEllipseNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// variable scan values, dependent of given XAttributeList
+ SvgNumber maCx;
+ SvgNumber maCy;
+ SvgNumber maRx;
+ SvgNumber maRy;
+ basegfx::B2DHomMatrix* mpaTransform;
+
+ public:
+ SvgEllipseNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgEllipseNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+ virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const;
+
+ /// Cx content, set if found in current context
+ const SvgNumber& getCx() const { return maCx; }
+ void setCx(const SvgNumber& rCx = SvgNumber()) { maCx = rCx; }
+
+ /// Cy content, set if found in current context
+ const SvgNumber& getCy() const { return maCy; }
+ void setCy(const SvgNumber& rCy = SvgNumber()) { maCy = rCy; }
+
+ /// Rx content, set if found in current context
+ const SvgNumber& getRx() const { return maRx; }
+ void setRx(const SvgNumber& rRx = SvgNumber()) { maRx = rRx; }
+
+ /// Ry content, set if found in current context
+ const SvgNumber& getRy() const { return maRy; }
+ void setRy(const SvgNumber& rRy = SvgNumber()) { maRy = rRy; }
+
+ /// transform content, set if found in current context
+ const basegfx::B2DHomMatrix* getTransform() const { return mpaTransform; }
+ void setTransform(const basegfx::B2DHomMatrix* pMatrix = 0) { if(mpaTransform) delete mpaTransform; mpaTransform = 0; if(pMatrix) mpaTransform = new basegfx::B2DHomMatrix(*pMatrix); }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGELLIPSENODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svggnode.hxx b/svgio/inc/svgio/svgreader/svggnode.hxx
new file mode 100644
index 000000000000..67929602354d
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svggnode.hxx
@@ -0,0 +1,66 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGGNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGGNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgGNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// variable scan values, dependent of given XAttributeList
+ basegfx::B2DHomMatrix* mpaTransform;
+
+ public:
+ SvgGNode(
+ SVGToken aType,
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgGNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+ virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const;
+
+ /// transform content
+ const basegfx::B2DHomMatrix* getTransform() const { return mpaTransform; }
+ void setTransform(const basegfx::B2DHomMatrix* pMatrix = 0) { if(mpaTransform) delete mpaTransform; mpaTransform = 0; if(pMatrix) mpaTransform = new basegfx::B2DHomMatrix(*pMatrix); }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGGNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svggradientnode.hxx b/svgio/inc/svgio/svgreader/svggradientnode.hxx
new file mode 100644
index 000000000000..b2cf79930365
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svggradientnode.hxx
@@ -0,0 +1,137 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGGRADIENTNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGGRADIENTNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+#include <drawinglayer/primitive2d/svggradientprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgGradientNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// linear gradient values
+ SvgNumber maX1;
+ SvgNumber maY1;
+ SvgNumber maX2;
+ SvgNumber maY2;
+
+ /// radial gradient values
+ SvgNumber maCx;
+ SvgNumber maCy;
+ SvgNumber maR;
+ SvgNumber maFx;
+ SvgNumber maFy;
+
+ /// variable scan values, dependent of given XAttributeList
+ SvgUnits maGradientUnits;
+ drawinglayer::primitive2d::SpreadMethod maSpreadMethod;
+ basegfx::B2DHomMatrix* mpaGradientTransform;
+
+ /// link to another gradient used as style. If maXLink
+ /// is set, the node can be fetched on demand by using
+ // tryToFindLink (buffered)
+ rtl::OUString maXLink;
+ const SvgGradientNode* mpXLink;
+
+ /// link on demand
+ void tryToFindLink();
+
+ public:
+ SvgGradientNode(
+ SVGToken aType,
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgGradientNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+
+ /// collect gradient stop entries
+ void collectGradientEntries(drawinglayer::primitive2d::SvgGradientEntryVector& aVector) const;
+
+ /// x1 content
+ const SvgNumber getX1() const;
+ void setX1(const SvgNumber& rX1 = SvgNumber()) { maX1 = rX1; }
+
+ /// y1 content
+ const SvgNumber getY1() const;
+ void setY1(const SvgNumber& rY1 = SvgNumber()) { maY1 = rY1; }
+
+ /// x2 content
+ const SvgNumber getX2() const;
+ void setX2(const SvgNumber& rX2 = SvgNumber()) { maX2 = rX2; }
+
+ /// y2 content
+ const SvgNumber getY2() const;
+ void setY2(const SvgNumber& rY2 = SvgNumber()) { maY2 = rY2; }
+
+ /// Cx content
+ const SvgNumber getCx() const;
+ void setCx(const SvgNumber& rCx = SvgNumber()) { maCx = rCx; }
+
+ /// Cy content
+ const SvgNumber getCy() const;
+ void setCy(const SvgNumber& rCy = SvgNumber()) { maCy = rCy; }
+
+ /// R content
+ const SvgNumber getR() const;
+ void setR(const SvgNumber& rR = SvgNumber()) { maR = rR; }
+
+ /// Fx content
+ const SvgNumber* getFx() const;
+ void setFx(const SvgNumber& rFx = SvgNumber()) { maFx = rFx; }
+
+ /// Fy content
+ const SvgNumber* getFy() const;
+ void setFy(const SvgNumber& rFy = SvgNumber()) { maFy = rFy; }
+
+ /// gradientUnits content
+ SvgUnits getGradientUnits() const { return maGradientUnits; }
+ void setGradientUnits(const SvgUnits aGradientUnits) { maGradientUnits = aGradientUnits; }
+
+ /// SpreadMethod content
+ drawinglayer::primitive2d::SpreadMethod getSpreadMethod() const { return maSpreadMethod; }
+ void setSpreadMethod(const drawinglayer::primitive2d::SpreadMethod aSpreadMethod) { maSpreadMethod = aSpreadMethod; }
+
+ /// transform content, set if found in current context
+ const basegfx::B2DHomMatrix* getGradientTransform() const;
+ void setGradientTransform(const basegfx::B2DHomMatrix* pMatrix = 0);
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGGRADIENTNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svggradientstopnode.hxx b/svgio/inc/svgio/svgreader/svggradientstopnode.hxx
new file mode 100644
index 000000000000..cc7acbf6cdd7
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svggradientstopnode.hxx
@@ -0,0 +1,64 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGGRADIENTSTOPNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGGRADIENTSTOPNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgGradientStopNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// local attributes
+ SvgNumber maOffset;
+
+ public:
+ SvgGradientStopNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgGradientStopNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+
+ /// offset content
+ const SvgNumber getOffset() const { return maOffset; }
+ void setOffset(const SvgNumber& rOffset = SvgNumber()) { maOffset = rOffset; }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGGRADIENTSTOPNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgimagenode.hxx b/svgio/inc/svgio/svgreader/svgimagenode.hxx
new file mode 100644
index 000000000000..5df5272303cd
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgimagenode.hxx
@@ -0,0 +1,99 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGIMAGENODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGIMAGENODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgImageNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// variable scan values, dependent of given XAttributeList
+ SvgAspectRatio maSvgAspectRatio;
+ basegfx::B2DHomMatrix* mpaTransform;
+ SvgNumber maX;
+ SvgNumber maY;
+ SvgNumber maWidth;
+ SvgNumber maHeight;
+
+ rtl::OUString maXLink; // internal link
+ rtl::OUString maUrl; // external link
+
+ rtl::OUString maMimeType; // mimetype and
+ rtl::OUString maData; // base64 data
+
+ public:
+ SvgImageNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgImageNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+ virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const;
+
+ /// SvgAspectRatio content
+ const SvgAspectRatio& getSvgAspectRatio() const { return maSvgAspectRatio; }
+ void setSvgAspectRatio(const SvgAspectRatio& rSvgAspectRatio = SvgAspectRatio()) { maSvgAspectRatio = rSvgAspectRatio; }
+
+ /// transform content, set if found in current context
+ const basegfx::B2DHomMatrix* getTransform() const { return mpaTransform; }
+ void setTransform(const basegfx::B2DHomMatrix* pMatrix = 0) { if(mpaTransform) delete mpaTransform; mpaTransform = 0; if(pMatrix) mpaTransform = new basegfx::B2DHomMatrix(*pMatrix); }
+
+ /// x content, set if found in current context
+ const SvgNumber& getX() const { return maX; }
+ void setX(const SvgNumber& rX = SvgNumber()) { maX = rX; }
+
+ /// y content, set if found in current context
+ const SvgNumber& getY() const { return maY; }
+ void setY(const SvgNumber& rY = SvgNumber()) { maY = rY; }
+
+ /// width content, set if found in current context
+ const SvgNumber& getWidth() const { return maWidth; }
+ void setWidth(const SvgNumber& rWidth = SvgNumber()) { maWidth = rWidth; }
+
+ /// height content, set if found in current context
+ const SvgNumber& getHeight() const { return maHeight; }
+ void setHeight(const SvgNumber& rHeight = SvgNumber()) { maHeight = rHeight; }
+
+ /// XLink access
+ const rtl::OUString& getXLink() const { return maXLink; }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGIMAGENODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svglinenode.hxx b/svgio/inc/svgio/svgreader/svglinenode.hxx
new file mode 100644
index 000000000000..b897aba28cc2
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svglinenode.hxx
@@ -0,0 +1,85 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGLINENODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGLINENODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgLineNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// variable scan values, dependent of given XAttributeList
+ SvgNumber maX1;
+ SvgNumber maY1;
+ SvgNumber maX2;
+ SvgNumber maY2;
+ basegfx::B2DHomMatrix* mpaTransform;
+
+ public:
+ SvgLineNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgLineNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+ virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const;
+
+ /// X1 content, set if found in current context
+ const SvgNumber& getX1() const { return maX1; }
+ void setX1(const SvgNumber& rX1 = SvgNumber()) { maX1 = rX1; }
+
+ /// Y1 content, set if found in current context
+ const SvgNumber& getY1() const { return maY1; }
+ void setY1(const SvgNumber& rY1 = SvgNumber()) { maY1 = rY1; }
+
+ /// X2 content, set if found in current context
+ const SvgNumber& getX2() const { return maX2; }
+ void setX2(const SvgNumber& rX2 = SvgNumber()) { maX2 = rX2; }
+
+ /// Y2 content, set if found in current context
+ const SvgNumber& getY2() const { return maY2; }
+ void setY2(const SvgNumber& rY2 = SvgNumber()) { maY2 = rY2; }
+
+ /// transform content, set if found in current context
+ const basegfx::B2DHomMatrix* getTransform() const { return mpaTransform; }
+ void setTransform(const basegfx::B2DHomMatrix* pMatrix = 0) { if(mpaTransform) delete mpaTransform; mpaTransform = 0; if(pMatrix) mpaTransform = new basegfx::B2DHomMatrix(*pMatrix); }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGLINENODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgmarkernode.hxx b/svgio/inc/svgio/svgreader/svgmarkernode.hxx
new file mode 100755
index 000000000000..b5562f70df44
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgmarkernode.hxx
@@ -0,0 +1,123 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGMARKERNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGMARKERNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgMarkerNode : public SvgNode
+ {
+ public:
+ enum MarkerUnits
+ {
+ strokeWidth,
+ userSpaceOnUse
+ };
+
+ private:
+ /// buffered decomposition
+ drawinglayer::primitive2d::Primitive2DSequence aPrimitives;
+
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// variable scan values, dependent of given XAttributeList
+ basegfx::B2DRange* mpViewBox;
+ SvgAspectRatio maSvgAspectRatio;
+ SvgNumber maRefX;
+ SvgNumber maRefY;
+ MarkerUnits maMarkerUnits;
+ SvgNumber maMarkerWidth;
+ SvgNumber maMarkerHeight;
+ double mfAngle;
+
+ /// bitfield
+ bool mbOrientAuto : 1; // true == on, false == fAngle valid
+
+ public:
+ SvgMarkerNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgMarkerNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+
+ /// get marker primitives buffered, uses decomposeSvgNode internally
+ const drawinglayer::primitive2d::Primitive2DSequence& getMarkerPrimitives() const;
+
+ /// InfoProvider support for % values
+ virtual const basegfx::B2DRange* getCurrentViewPort() const;
+
+ /// viewBox content
+ const basegfx::B2DRange* getViewBox() const { return mpViewBox; }
+ void setViewBox(const basegfx::B2DRange* pViewBox = 0) { if(mpViewBox) delete mpViewBox; mpViewBox = 0; if(pViewBox) mpViewBox = new basegfx::B2DRange(*pViewBox); }
+
+ /// SvgAspectRatio content
+ const SvgAspectRatio& getSvgAspectRatio() const { return maSvgAspectRatio; }
+ void setSvgAspectRatio(const SvgAspectRatio& rSvgAspectRatio = SvgAspectRatio()) { maSvgAspectRatio = rSvgAspectRatio; }
+
+ /// RefX content, set if found in current context
+ const SvgNumber& getRefX() const { return maRefX; }
+ void setRefX(const SvgNumber& rRefX = SvgNumber()) { maRefX = rRefX; }
+
+ /// RefY content, set if found in current context
+ const SvgNumber& getRefY() const { return maRefY; }
+ void setRefY(const SvgNumber& rRefY = SvgNumber()) { maRefY = rRefY; }
+
+ /// MarkerUnits content
+ MarkerUnits getMarkerUnits() const { return maMarkerUnits; }
+ void setMarkerUnits(const MarkerUnits aMarkerUnits) { maMarkerUnits = aMarkerUnits; }
+
+ /// MarkerWidth content, set if found in current context
+ const SvgNumber& getMarkerWidth() const { return maMarkerWidth; }
+ void setMarkerWidth(const SvgNumber& rMarkerWidth = SvgNumber()) { maMarkerWidth = rMarkerWidth; }
+
+ /// MarkerHeight content, set if found in current context
+ const SvgNumber& getMarkerHeight() const { return maMarkerHeight; }
+ void setMarkerHeight(const SvgNumber& rMarkerHeight = SvgNumber()) { maMarkerHeight = rMarkerHeight; }
+
+ /// Angle content, set if found in current context
+ double getAngle() const { return mfAngle; }
+ void setAngle(double fAngle = 0.0) { mfAngle = fAngle; mbOrientAuto = false; }
+
+ /// OrientAuto content, set if found in current context
+ bool getOrientAuto() const { return mbOrientAuto; }
+ void setOrientAuto(bool bOrientAuto = true) { mbOrientAuto = bOrientAuto; }
+
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGMARKERNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgmasknode.hxx b/svgio/inc/svgio/svgreader/svgmasknode.hxx
new file mode 100755
index 000000000000..6c3089d4a107
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgmasknode.hxx
@@ -0,0 +1,98 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGMASKNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGMASKNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgMaskNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// variable scan values, dependent of given XAttributeList
+ SvgNumber maX;
+ SvgNumber maY;
+ SvgNumber maWidth;
+ SvgNumber maHeight;
+ basegfx::B2DHomMatrix* mpaTransform;
+ SvgUnits maMaskUnits;
+ SvgUnits maMaskContentUnits;
+
+ public:
+ SvgMaskNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgMaskNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+ virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const;
+
+ /// apply contained clipPath to given geometry
+ void apply(drawinglayer::primitive2d::Primitive2DSequence& rTarget) const;
+
+ /// x content, set if found in current context
+ const SvgNumber& getX() const { return maX; }
+ void setX(const SvgNumber& rX = SvgNumber()) { maX = rX; }
+
+ /// y content, set if found in current context
+ const SvgNumber& getY() const { return maY; }
+ void setY(const SvgNumber& rY = SvgNumber()) { maY = rY; }
+
+ /// width content, set if found in current context
+ const SvgNumber& getWidth() const { return maWidth; }
+ void setWidth(const SvgNumber& rWidth = SvgNumber()) { maWidth = rWidth; }
+
+ /// height content, set if found in current context
+ const SvgNumber& getHeight() const { return maHeight; }
+ void setHeight(const SvgNumber& rHeight = SvgNumber()) { maHeight = rHeight; }
+
+ /// transform content
+ const basegfx::B2DHomMatrix* getTransform() const { return mpaTransform; }
+ void setTransform(const basegfx::B2DHomMatrix* pMatrix = 0) { if(mpaTransform) delete mpaTransform; mpaTransform = 0; if(pMatrix) mpaTransform = new basegfx::B2DHomMatrix(*pMatrix); }
+
+ /// MaskUnits content
+ SvgUnits getMaskUnits() const { return maMaskUnits; }
+ void setMaskUnits(const SvgUnits aMaskUnits) { maMaskUnits = aMaskUnits; }
+
+ /// MaskContentUnits content
+ SvgUnits getMaskContentUnits() const { return maMaskContentUnits; }
+ void setMaskContentUnits(const SvgUnits aMaskContentUnits) { maMaskContentUnits = aMaskContentUnits; }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGMASKNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgnode.hxx b/svgio/inc/svgio/svgreader/svgnode.hxx
new file mode 100644
index 000000000000..1a5add60ccc8
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgnode.hxx
@@ -0,0 +1,127 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgtools.hxx>
+#include <svgio/svgreader/svgtoken.hxx>
+#include <svgio/svgreader/svgpaint.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+#include <vector>
+#include <hash_map>
+
+//////////////////////////////////////////////////////////////////////////////
+// predefines
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgNode;
+ class SvgDocument;
+ class SvgStyleAttributes;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ typedef ::std::vector< SvgNode* > SvgNodeVector;
+
+ enum XmlSpace
+ {
+ XmlSpace_notset,
+ XmlSpace_default,
+ XmlSpace_preserve
+ };
+
+ class SvgNode : private boost::noncopyable, public InfoProvider
+ {
+ private:
+ /// basic data, Type, document we belong to and parent (if not root)
+ SVGToken maType;
+ SvgDocument& mrDocument;
+ const SvgNode* mpParent;
+ const SvgNode* mpAlternativeParent;
+
+ /// sub hierarchy
+ SvgNodeVector maChildren;
+
+ /// Id svan value
+ rtl::OUString* mpId;
+
+ /// Class svan value
+ rtl::OUString* mpClass;
+
+ /// XmlSpace value
+ XmlSpace maXmlSpace;
+
+ public:
+ SvgNode(
+ SVGToken aType,
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgNode();
+
+ void parseAttributes(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttribs);
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+ virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const;
+
+ /// basic data read access
+ const SVGToken getType() const { return maType; }
+ const SvgDocument& getDocument() const { return mrDocument; }
+ const SvgNode* getParent() const { if(mpAlternativeParent) return mpAlternativeParent; return mpParent; }
+ const SvgNodeVector& getChildren() const { return maChildren; }
+
+ /// InfoProvider support for %, em and ex values
+ virtual const basegfx::B2DRange* getCurrentViewPort() const;
+ virtual double getCurrentFontSize() const;
+ virtual double getCurrentXHeight() const;
+
+ /// Id access
+ const rtl::OUString* getId() const { return mpId; }
+ void setId(const rtl::OUString* pfId = 0);
+
+ /// Class access
+ const rtl::OUString* getClass() const { return mpClass; }
+ void setClass(const rtl::OUString* pfClass = 0);
+
+ /// XmlSpace access
+ XmlSpace getXmlSpace() const;
+ void setXmlSpace(XmlSpace eXmlSpace = XmlSpace_notset) { maXmlSpace = eXmlSpace; }
+
+ /// alternative parent
+ void setAlternativeParent(const SvgNode* pAlternativeParent = 0) { mpAlternativeParent = pAlternativeParent; }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgpaint.hxx b/svgio/inc/svgio/svgreader/svgpaint.hxx
new file mode 100644
index 000000000000..2a421973581f
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgpaint.hxx
@@ -0,0 +1,65 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGPAINT_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGPAINT_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <basegfx/color/bcolor.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgPaint
+ {
+ private:
+ basegfx::BColor maColor;
+
+ /// bitfield
+ bool mbSet : 1;
+ bool mbOn : 1;
+ bool mbCurrent : 1;
+
+ public:
+ SvgPaint(const basegfx::BColor& rColor = basegfx::BColor(0.0, 0.0, 0.0), bool bSet = false, bool bOn = false, bool bCurrent = false)
+ : maColor(rColor),
+ mbSet(bSet),
+ mbOn(bOn),
+ mbCurrent(bCurrent)
+ {
+ }
+
+ const basegfx::BColor& getBColor() const { return maColor; }
+ bool isSet() const { return mbSet; }
+ bool isOn() const { return mbOn; }
+ bool isCurrent() const { return mbCurrent; }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGPAINT_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgpathnode.hxx b/svgio/inc/svgio/svgreader/svgpathnode.hxx
new file mode 100644
index 000000000000..73811b13f880
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgpathnode.hxx
@@ -0,0 +1,75 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGPATHNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGPATHNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgPathNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// variable scan values, dependent of given XAttributeList
+ basegfx::B2DPolyPolygon* mpPolyPolygon;
+ basegfx::B2DHomMatrix* mpaTransform;
+ SvgNumber maPathLength;
+
+ public:
+ SvgPathNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgPathNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+ virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const;
+
+ /// path content, set if found in current context
+ const basegfx::B2DPolyPolygon* getPath() const { return mpPolyPolygon; }
+ void setPath(const basegfx::B2DPolyPolygon* pPath = 0) { if(mpPolyPolygon) delete mpPolyPolygon; mpPolyPolygon = 0; if(pPath) mpPolyPolygon = new basegfx::B2DPolyPolygon(*pPath); }
+
+ /// transform content, set if found in current context
+ const basegfx::B2DHomMatrix* getTransform() const { return mpaTransform; }
+ void setTransform(const basegfx::B2DHomMatrix* pMatrix = 0) { if(mpaTransform) delete mpaTransform; mpaTransform = 0; if(pMatrix) mpaTransform = new basegfx::B2DHomMatrix(*pMatrix); }
+
+ /// PathLength content
+ const SvgNumber& getPathLength() const { return maPathLength; }
+ void setPathLength(const SvgNumber& rPathLength = SvgNumber()) { maPathLength = rPathLength; }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGPATHNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgpatternnode.hxx b/svgio/inc/svgio/svgreader/svgpatternnode.hxx
new file mode 100755
index 000000000000..faf0994a81dd
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgpatternnode.hxx
@@ -0,0 +1,126 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGPATTERNNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGPATTERNNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgPatternNode : public SvgNode
+ {
+ private:
+ /// buffered decomposition
+ drawinglayer::primitive2d::Primitive2DSequence aPrimitives;
+
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// variable scan values, dependent of given XAttributeList
+ basegfx::B2DRange* mpViewBox;
+ SvgAspectRatio maSvgAspectRatio;
+ SvgNumber maX;
+ SvgNumber maY;
+ SvgNumber maWidth;
+ SvgNumber maHeight;
+ SvgUnits* mpPatternUnits;
+ SvgUnits* mpPatternContentUnits;
+ basegfx::B2DHomMatrix* mpaPatternTransform;
+
+ /// link to another pattern used as style. If maXLink
+ /// is set, the node can be fetched on demand by using
+ // tryToFindLink (buffered)
+ rtl::OUString maXLink;
+ const SvgPatternNode* mpXLink;
+
+ /// link on demand
+ void tryToFindLink();
+
+ public:
+ SvgPatternNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgPatternNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+
+ /// global helpers
+ void getValuesRelative(double& rfX, double& rfY, double& rfW, double& rfH, const basegfx::B2DRange& rGeoRange, SvgNode& rUser) const;
+
+ /// get pattern primitives buffered, uses decomposeSvgNode internally
+ const drawinglayer::primitive2d::Primitive2DSequence& getPatternPrimitives() const;
+
+ /// InfoProvider support for % values
+ virtual const basegfx::B2DRange* getCurrentViewPort() const;
+
+ /// viewBox content
+ const basegfx::B2DRange* getViewBox() const;
+ void setViewBox(const basegfx::B2DRange* pViewBox = 0) { if(mpViewBox) delete mpViewBox; mpViewBox = 0; if(pViewBox) mpViewBox = new basegfx::B2DRange(*pViewBox); }
+
+ /// SvgAspectRatio content
+ const SvgAspectRatio& getSvgAspectRatio() const;
+ void setSvgAspectRatio(const SvgAspectRatio& rSvgAspectRatio = SvgAspectRatio()) { maSvgAspectRatio = rSvgAspectRatio; }
+
+ /// X content, set if found in current context
+ const SvgNumber& getX() const;
+ void setX(const SvgNumber& rX = SvgNumber()) { maX = rX; }
+
+ /// Y content, set if found in current context
+ const SvgNumber& getY() const;
+ void setY(const SvgNumber& rY = SvgNumber()) { maY = rY; }
+
+ /// Width content, set if found in current context
+ const SvgNumber& getWidth() const;
+ void setWidth(const SvgNumber& rWidth = SvgNumber()) { maWidth = rWidth; }
+
+ /// Height content, set if found in current context
+ const SvgNumber& getHeight() const;
+ void setHeight(const SvgNumber& rHeight = SvgNumber()) { maHeight = rHeight; }
+
+ /// PatternUnits content
+ const SvgUnits* getPatternUnits() const;
+ void setPatternUnits(const SvgUnits aPatternUnits) { if(mpPatternUnits) delete mpPatternUnits; mpPatternUnits = 0; mpPatternUnits = new SvgUnits(aPatternUnits); }
+
+ /// PatternContentUnits content
+ const SvgUnits* getPatternContentUnits() const;
+ void setPatternContentUnits(const SvgUnits aPatternContentUnits) { if(mpPatternContentUnits) delete mpPatternContentUnits; mpPatternContentUnits = 0; mpPatternContentUnits = new SvgUnits(aPatternContentUnits); }
+
+ /// PatternTransform content
+ const basegfx::B2DHomMatrix* getPatternTransform() const;
+ void setPatternTransform(const basegfx::B2DHomMatrix* pMatrix = 0) { if(mpaPatternTransform) delete mpaPatternTransform; mpaPatternTransform = 0; if(pMatrix) mpaPatternTransform = new basegfx::B2DHomMatrix(*pMatrix); }
+
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGPATTERNNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgpolynode.hxx b/svgio/inc/svgio/svgreader/svgpolynode.hxx
new file mode 100644
index 000000000000..406d267a1ac8
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgpolynode.hxx
@@ -0,0 +1,78 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGPOLYNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGPOLYNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgPolyNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// variable scan values, dependent of given XAttributeList
+ basegfx::B2DPolygon* mpPolygon;
+ basegfx::B2DHomMatrix* mpaTransform;
+
+ /// bitfield
+ bool mbIsPolyline : 1; // true = polyline, false = polygon
+
+ public:
+ SvgPolyNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent,
+ bool bIsPolyline);
+ virtual ~SvgPolyNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+ virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const;
+
+ /// type read access
+ bool isPolyline() const { return mbIsPolyline; }
+
+ /// Polygon content, set if found in current context
+ const basegfx::B2DPolygon* getPolygon() const { return mpPolygon; }
+ void setPolygon(const basegfx::B2DPolygon* pPolygon = 0) { if(mpPolygon) delete mpPolygon; mpPolygon = 0; if(pPolygon) mpPolygon = new basegfx::B2DPolygon(*pPolygon); }
+
+ /// transform content, set if found in current context
+ const basegfx::B2DHomMatrix* getTransform() const { return mpaTransform; }
+ void setTransform(const basegfx::B2DHomMatrix* pMatrix = 0) { if(mpaTransform) delete mpaTransform; mpaTransform = 0; if(pMatrix) mpaTransform = new basegfx::B2DHomMatrix(*pMatrix); }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGPOLYNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgrectnode.hxx b/svgio/inc/svgio/svgreader/svgrectnode.hxx
new file mode 100644
index 000000000000..b8a42db45d11
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgrectnode.hxx
@@ -0,0 +1,95 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGRECTNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGRECTNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgRectNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// variable scan values, dependent of given XAttributeList
+ SvgNumber maX;
+ SvgNumber maY;
+ SvgNumber maWidth;
+ SvgNumber maHeight;
+ SvgNumber maRx;
+ SvgNumber maRy;
+ basegfx::B2DHomMatrix* mpaTransform;
+
+ public:
+ SvgRectNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgRectNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+ virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const;
+
+ /// x content, set if found in current context
+ const SvgNumber& getX() const { return maX; }
+ void setX(const SvgNumber& rX = SvgNumber()) { maX = rX; }
+
+ /// y content, set if found in current context
+ const SvgNumber& getY() const { return maY; }
+ void setY(const SvgNumber& rY = SvgNumber()) { maY = rY; }
+
+ /// width content, set if found in current context
+ const SvgNumber& getWidth() const { return maWidth; }
+ void setWidth(const SvgNumber& rWidth = SvgNumber()) { maWidth = rWidth; }
+
+ /// height content, set if found in current context
+ const SvgNumber& getHeight() const { return maHeight; }
+ void setHeight(const SvgNumber& rHeight = SvgNumber()) { maHeight = rHeight; }
+
+ /// Rx content, set if found in current context
+ const SvgNumber& getRx() const { return maRx; }
+ void setRx(const SvgNumber& rRx = SvgNumber()) { maRx = rRx; }
+
+ /// Ry content, set if found in current context
+ const SvgNumber& getRy() const { return maRy; }
+ void setRy(const SvgNumber& rRy = SvgNumber()) { maRy = rRy; }
+
+ /// transform content, set if found in current context
+ const basegfx::B2DHomMatrix* getTransform() const { return mpaTransform; }
+ void setTransform(const basegfx::B2DHomMatrix* pMatrix = 0) { if(mpaTransform) delete mpaTransform; mpaTransform = 0; if(pMatrix) mpaTransform = new basegfx::B2DHomMatrix(*pMatrix); }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGRECTNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgstyleattributes.hxx b/svgio/inc/svgio/svgreader/svgstyleattributes.hxx
new file mode 100644
index 000000000000..9be162330ad5
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgstyleattributes.hxx
@@ -0,0 +1,411 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGSTYLEATTRIBUTES_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGSTYLEATTRIBUTES_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgpaint.hxx>
+#include <svgio/svgreader/svgnode.hxx>
+#include <vcl/vclenum.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+// predefines
+
+namespace svgio { namespace svgreader {
+ class SvgGradientNode;
+ class SvgPatternNode;
+ class SvgMarkerNode;
+}}
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ enum StrokeLinecap
+ {
+ StrokeLinecap_notset,
+ StrokeLinecap_butt,
+ StrokeLinecap_round,
+ StrokeLinecap_square
+ };
+
+ enum StrokeLinejoin
+ {
+ StrokeLinejoin_notset,
+ StrokeLinejoin_miter,
+ StrokeLinejoin_round,
+ StrokeLinejoin_bevel
+ };
+
+ enum FontStretch
+ {
+ FontStretch_notset,
+ FontStretch_normal,
+ FontStretch_wider,
+ FontStretch_narrower,
+ FontStretch_ultra_condensed,
+ FontStretch_extra_condensed,
+ FontStretch_condensed,
+ FontStretch_semi_condensed,
+ FontStretch_semi_expanded,
+ FontStretch_expanded,
+ FontStretch_extra_expanded,
+ FontStretch_ultra_expanded
+ };
+
+ FontStretch getWider(FontStretch aSource);
+ FontStretch getNarrower(FontStretch aSource);
+
+ enum FontStyle
+ {
+ FontStyle_notset,
+ FontStyle_normal,
+ FontStyle_italic,
+ FontStyle_oblique
+ };
+
+ enum FontVariant
+ {
+ FontVariant_notset,
+ FontVariant_normal,
+ FontVariant_small_caps
+ };
+
+ enum FontWeight
+ {
+ FontWeight_notset,
+ FontWeight_100,
+ FontWeight_200,
+ FontWeight_300,
+ FontWeight_400, // same as FontWeight_normal
+ FontWeight_500,
+ FontWeight_600,
+ FontWeight_700, // same as FontWeight_bold
+ FontWeight_800,
+ FontWeight_900,
+ FontWeight_bolder,
+ FontWeight_lighter,
+ };
+
+ FontWeight getBolder(FontWeight aSource);
+ FontWeight getLighter(FontWeight aSource);
+ ::FontWeight getVclFontWeight(FontWeight aSource);
+
+ enum TextAlign
+ {
+ TextAlign_notset,
+ TextAlign_left,
+ TextAlign_right,
+ TextAlign_center,
+ TextAlign_justify
+ };
+
+ enum TextDecoration
+ {
+ TextDecoration_notset,
+ TextDecoration_none,
+ TextDecoration_underline,
+ TextDecoration_overline,
+ TextDecoration_line_through,
+ TextDecoration_blink
+ };
+
+ enum TextAnchor
+ {
+ TextAnchor_notset,
+ TextAnchor_start,
+ TextAnchor_middle,
+ TextAnchor_end
+ };
+
+ class SvgStyleAttributes
+ {
+ private:
+ SvgNode& mrOwner;
+ const SvgStyleAttributes* mpCssStyleParent;
+
+ SvgPaint maFill;
+ SvgPaint maStroke;
+ SvgPaint maStopColor;
+ SvgNumber maStrokeWidth;
+ SvgNumber maStopOpacity;
+ const SvgGradientNode* mpSvgGradientNodeFill;
+ const SvgGradientNode* mpSvgGradientNodeStroke;
+ const SvgPatternNode* mpSvgPatternNodeFill;
+ const SvgPatternNode* mpSvgPatternNodeStroke;
+ SvgNumber maFillOpacity;
+ SvgNumberVector maStrokeDasharray;
+ SvgNumber maStrokeDashOffset;
+ StrokeLinecap maStrokeLinecap;
+ StrokeLinejoin maStrokeLinejoin;
+ SvgNumber maStrokeMiterLimit;
+ SvgNumber maStrokeOpacity;
+ SvgStringVector maFontFamily;
+ SvgNumber maFontSize;
+ FontStretch maFontStretch;
+ FontStyle maFontStyle;
+ FontVariant maFontVariant;
+ FontWeight maFontWeight;
+ TextAlign maTextAlign;
+ TextDecoration maTextDecoration;
+ TextAnchor maTextAnchor;
+ SvgPaint maColor;
+ SvgNumber maOpacity;
+
+ /// link to content. If set, the node can be fetched on demand
+ rtl::OUString maClipPathXLink;
+ rtl::OUString maMaskXLink;
+
+ /// link to markers. If set, the node can be fetched on demand
+ rtl::OUString maMarkerStartXLink;
+ const SvgMarkerNode* mpMarkerStartXLink;
+ rtl::OUString maMarkerMidXLink;
+ const SvgMarkerNode* mpMarkerMidXLink;
+ rtl::OUString maMarkerEndXLink;
+ const SvgMarkerNode* mpMarkerEndXLink;
+
+ /// bitfield
+ bool maFillRule : 1; // true: NonZero, false: EvenOdd
+ bool maFillRuleSet : 1;
+
+ // defines if this attributes are part of a ClipPath. If yes,
+ // rough geometry will be created on decomposition by patching
+ // vaules for fill, stroke, strokeWidth and others
+ bool mbIsClipPathContent : 1;
+
+ // ClipRule setting (only valid wne mbIsClipPathContent == true)
+ bool mbClipRule : 1; // true == nonzero(default), false == evenodd
+
+ /// internal helpers
+ void add_fillGradient(
+ const basegfx::B2DPolyPolygon& rPath,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const SvgGradientNode& rFillGradient,
+ const basegfx::B2DRange& rGeoRange) const;
+ void add_fillPatternTransform(
+ const basegfx::B2DPolyPolygon& rPath,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const SvgPatternNode& rFillGradient,
+ const basegfx::B2DRange& rGeoRange) const;
+ void add_fillPattern(
+ const basegfx::B2DPolyPolygon& rPath,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const SvgPatternNode& rFillGradient,
+ const basegfx::B2DRange& rGeoRange) const;
+ void add_fill(
+ const basegfx::B2DPolyPolygon& rPath,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const basegfx::B2DRange& rGeoRange) const;
+ void add_stroke(
+ const basegfx::B2DPolyPolygon& rPath,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const basegfx::B2DRange& rGeoRange) const;
+ bool prepare_singleMarker(
+ drawinglayer::primitive2d::Primitive2DSequence& rMarkerPrimitives,
+ basegfx::B2DHomMatrix& rMarkerTransform,
+ basegfx::B2DRange& rClipRange,
+ const SvgMarkerNode& rMarker) const;
+ void add_singleMarker(
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const drawinglayer::primitive2d::Primitive2DSequence& rMarkerPrimitives,
+ const basegfx::B2DHomMatrix& rMarkerTransform,
+ const basegfx::B2DRange& rClipRange,
+ const SvgMarkerNode& rMarker,
+ const basegfx::B2DPolygon& rCandidate,
+ const sal_uInt32 nIndex) const;
+ void add_markers(
+ const basegfx::B2DPolyPolygon& rPath,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget) const;
+
+ public:
+ /// local attribute scanner
+ void parseStyleAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+
+ /// helper which does the necessary with a given path
+ void add_text(
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ drawinglayer::primitive2d::Primitive2DSequence& rSource) const;
+ void add_path(
+ const basegfx::B2DPolyPolygon& rPath,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget) const;
+ void add_postProcess(
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const drawinglayer::primitive2d::Primitive2DSequence& rSource,
+ const basegfx::B2DHomMatrix* pTransform) const;
+
+ /// helper to evtl. link to css style
+ void checkForCssStyle(const rtl::OUString& rClassStr) const;
+
+ /// scan helpers
+ void readStyle(const rtl::OUString& rCandidate);
+ const SvgStyleAttributes* getParentStyle() const;
+
+ SvgStyleAttributes(SvgNode& rOwner);
+ ~SvgStyleAttributes();
+
+ /// fill content
+ const basegfx::BColor* getFill() const;
+ void setFill(const SvgPaint& rFill) { maFill = rFill; }
+
+ /// stroke content
+ const basegfx::BColor* getStroke() const;
+ void setStroke(const SvgPaint& rStroke) { maStroke = rStroke; }
+
+ /// stop color content
+ const basegfx::BColor& getStopColor() const;
+ void setStopColor(const SvgPaint& rStopColor) { maStopColor = rStopColor; }
+
+ /// stroke-width content
+ const SvgNumber getStrokeWidth() const;
+ void setStrokeWidth(const SvgNumber& rStrokeWidth = SvgNumber()) { maStrokeWidth = rStrokeWidth; }
+
+ /// stop opacity content
+ const SvgNumber getStopOpacity() const;
+ void setStopOpacity(const SvgNumber& rStopOpacity = SvgNumber()) { maStopOpacity = rStopOpacity; }
+
+ /// access to evtl. set fill gradient
+ const SvgGradientNode* getSvgGradientNodeFill() const;
+ void setSvgGradientNodeFill(const SvgGradientNode* pNew) { mpSvgGradientNodeFill = pNew; }
+
+ /// access to evtl. set fill pattern
+ const SvgPatternNode* getSvgPatternNodeFill() const;
+ void setSvgPatternNodeFill(const SvgPatternNode* pNew) { mpSvgPatternNodeFill = pNew; }
+
+ /// access to evtl. set stroke gradient
+ const SvgGradientNode* getSvgGradientNodeStroke() const;
+ void setSvgGradientNodeStroke(const SvgGradientNode* pNew) { mpSvgGradientNodeStroke = pNew; }
+
+ /// access to evtl. set stroke pattern
+ const SvgPatternNode* getSvgPatternNodeStroke() const;
+ void setSvgPatternNodeStroke(const SvgPatternNode* pNew) { mpSvgPatternNodeStroke = pNew; }
+
+ /// fill opacity content
+ const SvgNumber getFillOpacity() const;
+ void setFillOpacity(const SvgNumber& rFillOpacity = SvgNumber()) { maFillOpacity = rFillOpacity; }
+
+ /// fill rule content
+ bool getFillRule() const;
+ void setFillRule(const bool* pFillRule = 0);
+
+ /// fill StrokeDasharray content
+ const SvgNumberVector& getStrokeDasharray() const;
+ void setStrokeDasharray(const SvgNumberVector& rStrokeDasharray = SvgNumberVector()) { maStrokeDasharray = rStrokeDasharray; }
+
+ /// StrokeDashOffset content
+ const SvgNumber getStrokeDashOffset() const;
+ void setStrokeDashOffset(const SvgNumber& rStrokeDashOffset = SvgNumber()) { maStrokeDashOffset = rStrokeDashOffset; }
+
+ /// StrokeLinecap content
+ const StrokeLinecap getStrokeLinecap() const;
+ void setStrokeLinecap(const StrokeLinecap aStrokeLinecap = StrokeLinecap_notset) { maStrokeLinecap = aStrokeLinecap; }
+
+ /// StrokeLinejoin content
+ const StrokeLinejoin getStrokeLinejoin() const;
+ void setStrokeLinejoin(const StrokeLinejoin aStrokeLinejoin = StrokeLinejoin_notset) { maStrokeLinejoin = aStrokeLinejoin; }
+
+ /// StrokeMiterLimit content
+ const SvgNumber getStrokeMiterLimit() const;
+ void setStrokeMiterLimit(const SvgNumber& rStrokeMiterLimit = SvgNumber()) { maStrokeMiterLimit = rStrokeMiterLimit; }
+
+ /// StrokeOpacity content
+ const SvgNumber getStrokeOpacity() const;
+ void setStrokeOpacity(const SvgNumber& rStrokeOpacity = SvgNumber()) { maStrokeOpacity = rStrokeOpacity; }
+
+ /// Font content
+ const SvgStringVector& getFontFamily() const;
+ void setFontFamily(const SvgStringVector& rSvgStringVector = SvgStringVector()) { maFontFamily = rSvgStringVector; }
+
+ /// FontSize content
+ const SvgNumber getFontSize() const;
+ void setFontSize(const SvgNumber& rFontSize = SvgNumber()) { maFontSize = rFontSize; }
+
+ /// FontStretch content
+ const FontStretch getFontStretch() const;
+ void setFontStretch(const FontStretch aFontStretch = FontStretch_notset) { maFontStretch = aFontStretch; }
+
+ /// FontStyle content
+ const FontStyle getFontStyle() const;
+ void setFontStyle(const FontStyle aFontStyle = FontStyle_notset) { maFontStyle = aFontStyle; }
+
+ /// FontVariant content
+ const FontVariant getFontVariant() const;
+ void setFontVariant(const FontVariant aFontVariant = FontVariant_notset) { maFontVariant = aFontVariant; }
+
+ /// FontWeight content
+ const FontWeight getFontWeight() const;
+ void setFontWeight(const FontWeight aFontWeight = FontWeight_notset) { maFontWeight = aFontWeight; }
+
+ /// TextAlign content
+ const TextAlign getTextAlign() const;
+ void setTextAlign(const TextAlign aTextAlign = TextAlign_notset) { maTextAlign = aTextAlign; }
+
+ /// TextDecoration content
+ const SvgStyleAttributes* getTextDecorationDefiningSvgStyleAttributes() const;
+ const TextDecoration getTextDecoration() const;
+ void setTextDecoration(const TextDecoration aTextDecoration = TextDecoration_notset) { maTextDecoration = aTextDecoration; }
+
+ /// TextAnchor content
+ const TextAnchor getTextAnchor() const;
+ void setTextAnchor(const TextAnchor aTextAnchor = TextAnchor_notset) { maTextAnchor = aTextAnchor; }
+
+ /// Color content
+ const basegfx::BColor* getColor() const;
+ void setColor(const SvgPaint& rColor) { maColor = rColor; }
+
+ /// Opacity content
+ const SvgNumber getOpacity() const { return maOpacity; }
+ void setOpacity(const SvgNumber& rOpacity = SvgNumber()) { maOpacity = rOpacity; }
+
+ // ClipPathXLink content
+ const rtl::OUString getClipPathXLink() const { return maClipPathXLink; }
+ void setClipPathXLink(const rtl::OUString& rNew) { maClipPathXLink = rNew; }
+
+ // MaskXLink content
+ const rtl::OUString getMaskXLink() const { return maMaskXLink; }
+ void setMaskXLink(const rtl::OUString& rNew) { maMaskXLink = rNew; }
+
+ // MarkerStartXLink content
+ const rtl::OUString getMarkerStartXLink() const;
+ const SvgMarkerNode* accessMarkerStartXLink() const;
+ void setMarkerStartXLink(const rtl::OUString& rNew) { maMarkerStartXLink = rNew; }
+
+ // MarkerMidXLink content
+ const rtl::OUString getMarkerMidXLink() const;
+ const SvgMarkerNode* accessMarkerMidXLink() const;
+ void setMarkerMidXLink(const rtl::OUString& rNew) { maMarkerMidXLink = rNew; }
+
+ // MarkerEndXLink content
+ const rtl::OUString getMarkerEndXLink() const;
+ const SvgMarkerNode* accessMarkerEndXLink() const;
+ void setMarkerEndXLink(const rtl::OUString& rNew) { maMarkerEndXLink = rNew; }
+
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGSTYLEATTRIBUTES_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgstylenode.hxx b/svgio/inc/svgio/svgreader/svgstylenode.hxx
new file mode 100644
index 000000000000..04dc20ab5ade
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgstylenode.hxx
@@ -0,0 +1,64 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGSTYLENODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGSTYLENODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgStyleNode : public SvgNode
+ {
+ private:
+ /// use styles
+ std::vector< SvgStyleAttributes* > maSvgStyleAttributes;
+
+ /// bitfield
+ bool mbTextCss : 1; // true == type is 'text/css'
+
+ public:
+ SvgStyleNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgStyleNode();
+
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+ void addCssStyleSheet(const rtl::OUString& aContent);
+
+ /// textCss access
+ bool isTextCss() const { return mbTextCss; }
+ void setTextCss(bool bNew) { mbTextCss = bNew; }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGSTYLENODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgsvgnode.hxx b/svgio/inc/svgio/svgreader/svgsvgnode.hxx
new file mode 100644
index 000000000000..a72fcf7ad243
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgsvgnode.hxx
@@ -0,0 +1,97 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGSVGNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGSVGNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgSvgNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// variable scan values, dependent of given XAttributeList
+ basegfx::B2DRange* mpViewBox;
+ SvgAspectRatio maSvgAspectRatio;
+ SvgNumber maX;
+ SvgNumber maY;
+ SvgNumber maWidth;
+ SvgNumber maHeight;
+ SvgNumber maVersion;
+
+ public:
+ SvgSvgNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgSvgNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+ virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const;
+
+ /// InfoProvider support for % values
+ virtual const basegfx::B2DRange* getCurrentViewPort() const;
+
+ /// viewBox content
+ const basegfx::B2DRange* getViewBox() const { return mpViewBox; }
+ void setViewBox(const basegfx::B2DRange* pViewBox = 0) { if(mpViewBox) delete mpViewBox; mpViewBox = 0; if(pViewBox) mpViewBox = new basegfx::B2DRange(*pViewBox); }
+
+ /// SvgAspectRatio content
+ const SvgAspectRatio& getSvgAspectRatio() const { return maSvgAspectRatio; }
+ void setSvgAspectRatio(const SvgAspectRatio& rSvgAspectRatio = SvgAspectRatio()) { maSvgAspectRatio = rSvgAspectRatio; }
+
+ /// x content
+ const SvgNumber& getX() const { return maX; }
+ void setX(const SvgNumber& rX = SvgNumber()) { maX = rX; }
+
+ /// y content
+ const SvgNumber& getY() const { return maY; }
+ void setY(const SvgNumber& rY = SvgNumber()) { maY = rY; }
+
+ /// width content
+ const SvgNumber& getWidth() const { return maWidth; }
+ void setWidth(const SvgNumber& rWidth = SvgNumber()) { maWidth = rWidth; }
+
+ /// height content
+ const SvgNumber& getHeight() const { return maHeight; }
+ void setHeight(const SvgNumber& rHeight = SvgNumber()) { maHeight = rHeight; }
+
+ /// version content
+ const SvgNumber& getVersion() const { return maVersion; }
+ void setVersion(const SvgNumber& rVersion = SvgNumber()) { maVersion = rVersion; }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGSVGNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgsymbolnode.hxx b/svgio/inc/svgio/svgreader/svgsymbolnode.hxx
new file mode 100644
index 000000000000..b7b2df125d6e
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgsymbolnode.hxx
@@ -0,0 +1,68 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGSYMBOLNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGSYMBOLNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgSymbolNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// variable scan values, dependent of given XAttributeList
+ basegfx::B2DRange* mpViewBox;
+ SvgAspectRatio maSvgAspectRatio;
+
+ public:
+ SvgSymbolNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgSymbolNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+
+ /// viewBox content
+ const basegfx::B2DRange* getViewBox() const { return mpViewBox; }
+ void setViewBox(const basegfx::B2DRange* pViewBox = 0) { if(mpViewBox) delete mpViewBox; mpViewBox = 0; if(pViewBox) mpViewBox = new basegfx::B2DRange(*pViewBox); }
+
+ /// SvgAspectRatio content
+ const SvgAspectRatio& getSvgAspectRatio() const { return maSvgAspectRatio; }
+ void setSvgAspectRatio(const SvgAspectRatio& rSvgAspectRatio = SvgAspectRatio()) { maSvgAspectRatio = rSvgAspectRatio; }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGSYMBOLNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgtextnode.hxx b/svgio/inc/svgio/svgreader/svgtextnode.hxx
new file mode 100644
index 000000000000..9aeed6f91cbc
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgtextnode.hxx
@@ -0,0 +1,80 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGTEXTNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGTEXTNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+#include <svgio/svgreader/svgcharacternode.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgTextNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// variable scan values, dependent of given XAttributeList
+ basegfx::B2DHomMatrix* mpaTransform;
+ SvgTextPositions maSvgTextPositions;
+
+ /// local helpers
+ void DecomposeChild(
+ const SvgNode& rCandidate,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ SvgTextPosition& rSvgTextPosition) const;
+ void addTextPrimitives(
+ const SvgNode& rCandidate,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ drawinglayer::primitive2d::Primitive2DSequence& rSource) const;
+
+ public:
+ SvgTextNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgTextNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+ virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const;
+
+ /// transform content, set if found in current context
+ const basegfx::B2DHomMatrix* getTransform() const { return mpaTransform; }
+ void setTransform(const basegfx::B2DHomMatrix* pMatrix = 0) { if(mpaTransform) delete mpaTransform; mpaTransform = 0; if(pMatrix) mpaTransform = new basegfx::B2DHomMatrix(*pMatrix); }
+
+ /// access to SvgTextPositions
+ const SvgTextPositions& getSvgTextPositions() const { return maSvgTextPositions; }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGTEXTNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgtextpathnode.hxx b/svgio/inc/svgio/svgreader/svgtextpathnode.hxx
new file mode 100644
index 000000000000..fa5c3d84648c
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgtextpathnode.hxx
@@ -0,0 +1,86 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGTEXTPATHNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGTEXTPATHNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+#include <svgio/svgreader/svgpathnode.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgTextPathNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// link to path content. If maXLink
+ /// is set, the node can be fetched on demand
+ rtl::OUString maXLink;
+
+ /// variable scan values, dependent of given XAttributeList
+ SvgNumber maStartOffset;
+
+ /// bitfield
+ bool mbMethod : 1; // true = align, false = stretch
+ bool mbSpacing : 1; // true = auto, false = exact
+
+ public:
+ SvgTextPathNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgTextPathNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+ void decomposePathNode(
+ const drawinglayer::primitive2d::Primitive2DSequence& rPathContent,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const basegfx::B2DPoint& rTextStart) const;
+ bool isValid() const;
+
+ /// StartOffset content
+ const SvgNumber& getStartOffset() const { return maStartOffset; }
+ void setStartOffset(const SvgNumber& rStartOffset = SvgNumber()) { maStartOffset = rStartOffset; }
+
+ /// Method content
+ bool getMethod() const { return mbMethod; }
+ void setMethod(bool bNew) { mbMethod = bNew; }
+
+ /// Spacing content
+ bool getSpacing() const { return mbSpacing; }
+ void setSpacing(bool bNew) { mbSpacing = bNew; }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGTEXTPATHNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgtoken.hxx b/svgio/inc/svgio/svgreader/svgtoken.hxx
new file mode 100644
index 000000000000..b1d2e8463cc7
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgtoken.hxx
@@ -0,0 +1,194 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGTOKEN_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGTOKEN_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <rtl/ustring.hxx>
+#include <hash_map>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ // SVG token mapper with hashing
+ enum SVGToken
+ {
+ SVGTokenUnknown = 0,
+
+ // diverse attribute tokens
+ SVGTokenWidth,
+ SVGTokenHeight,
+ SVGTokenViewBox,
+ SVGTokenTransform,
+ SVGTokenStyle,
+ SVGTokenD,
+ SVGTokenX,
+ SVGTokenY,
+ SVGTokenXmlns,
+ SVGTokenVersion,
+ SVGTokenId,
+ SVGTokenRx,
+ SVGTokenRy,
+ SVGTokenPoints,
+ SVGTokenDx,
+ SVGTokenDy,
+ SVGTokenRotate,
+ SVGTokenTextLength,
+ SVGTokenLengthAdjust,
+ SVGTokenFont,
+ SVGTokenFontFamily,
+ SVGTokenFontSize,
+ SVGTokenFontSizeAdjust,
+ SVGTokenFontStretch,
+ SVGTokenFontStyle,
+ SVGTokenFontVariant,
+ SVGTokenFontWeight,
+ SVGTokenDirection,
+ SVGTokenLetterSpacing,
+ SVGTokenTextDecoration,
+ SVGTokenUnicodeBidi,
+ SVGTokenWordSpacing,
+ SVGTokenCharacter, // not in the hash, just for simple text handling in SvgCharacterNode
+ SVGTokenTspan,
+ SVGTokenTref,
+ SVGTokenTextPath,
+ SVGTokenStartOffset,
+ SVGTokenMethod,
+ SVGTokenSpacing,
+ SVGTokenTextAlign,
+ SVGTokenPathLength,
+ SVGTokenType,
+ SVGTokenClass,
+ SVGTokenTextAnchor,
+ SVGTokenXmlSpace,
+ SVGTokenColor,
+ SVGTokenClipPathNode,
+ SVGTokenClipPathProperty,
+ SVGTokenMask,
+ SVGTokenClipPathUnits,
+ SVGTokenMaskUnits,
+ SVGTokenMaskContentUnits,
+ SVGTokenClipRule,
+ SVGTokenMarker,
+ SVGTokenMarkerStart,
+ SVGTokenMarkerMid,
+ SVGTokenMarkerEnd,
+ SVGTokenRefX,
+ SVGTokenRefY,
+ SVGTokenMarkerUnits,
+ SVGTokenMarkerWidth,
+ SVGTokenMarkerHeight,
+ SVGTokenOrient,
+ SVGTokenPattern,
+ SVGTokenPatternUnits,
+ SVGTokenPatternContentUnits,
+ SVGTokenPatternTransform,
+ SVGTokenOpacity,
+
+ // AspectRatio and params
+ SVGTokenPreserveAspectRatio,
+ SVGTokenDefer,
+ SVGTokenNone,
+ SVGTokenXMinYMin,
+ SVGTokenXMidYMin,
+ SVGTokenXMaxYMin,
+ SVGTokenXMinYMid,
+ SVGTokenXMidYMid,
+ SVGTokenXMaxYMid,
+ SVGTokenXMinYMax,
+ SVGTokenXMidYMax,
+ SVGTokenXMaxYMax,
+ SVGTokenMeet,
+ SVGTokenSlice,
+
+ // structural elements
+ SVGTokenDefs,
+ SVGTokenG,
+ SVGTokenSvg,
+ SVGTokenSymbol,
+ SVGTokenUse,
+
+ // shape elements
+ SVGTokenCircle,
+ SVGTokenEllipse,
+ SVGTokenLine,
+ SVGTokenPath,
+ SVGTokenPolygon,
+ SVGTokenPolyline,
+ SVGTokenRect,
+ SVGTokenImage,
+
+ // gradient elements and tokens
+ SVGTokenLinearGradient,
+ SVGTokenRadialGradient,
+ SVGTokenStop,
+ SVGTokenOffset,
+ SVGTokenX1,
+ SVGTokenY1,
+ SVGTokenX2,
+ SVGTokenY2,
+ SVGTokenCx,
+ SVGTokenCy,
+ SVGTokenFx,
+ SVGTokenFy,
+ SVGTokenR,
+ SVGTokenGradientUnits,
+ SVGTokenGradientTransform,
+ SVGTokenSpreadMethod,
+ SVGTokenXlinkHref,
+ SVGTokenStopColor,
+ SVGTokenStopOpacity,
+
+ // fill tokens
+ SVGTokenFill,
+ SVGTokenFillOpacity,
+ SVGTokenFillRule,
+
+ // stroke tokens
+ SVGTokenStroke,
+ SVGTokenStrokeDasharray,
+ SVGTokenStrokeDashoffset,
+ SVGTokenStrokeLinecap,
+ SVGTokenStrokeLinejoin,
+ SVGTokenStrokeMiterlimit,
+ SVGTokenStrokeOpacity,
+ SVGTokenStrokeWidth,
+
+ // text tokens
+ SVGTokenText,
+
+ SVGTokenLast
+ };
+
+ SVGToken StrToSVGToken(const rtl::OUString& rStr);
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGTOKEN_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgtools.hxx b/svgio/inc/svgio/svgreader/svgtools.hxx
new file mode 100644
index 000000000000..3933d3b41335
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgtools.hxx
@@ -0,0 +1,228 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGTOOLS_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGTOOLS_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
+#include <basegfx/color/bcolor.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <svgio/svgreader/svgpaint.hxx>
+#include <vector>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+#ifdef DBG_UTIL
+ // error helper
+ void myAssert(const rtl::OUString& rMessage);
+#endif
+
+ // common non-token strings
+ struct commonStrings
+ {
+ static const rtl::OUString aStrUserSpaceOnUse;
+ static const rtl::OUString aStrObjectBoundingBox;
+ static const rtl::OUString aStrNonzero;
+ static const rtl::OUString aStrEvenOdd;
+ };
+
+ enum SvgUnits
+ {
+ userSpaceOnUse,
+ objectBoundingBox
+ };
+
+ enum NumberType
+ {
+ xcoordinate,
+ ycoordinate,
+ length
+ };
+
+ class InfoProvider
+ {
+ public:
+ virtual const basegfx::B2DRange* getCurrentViewPort() const = 0;
+ virtual double getCurrentFontSize() const = 0;
+ virtual double getCurrentXHeight() const = 0;
+ };
+
+ enum SvgUnit
+ {
+ Unit_em = 0, // relative to current font size
+ Unit_ex, // relative to current x-height
+
+ Unit_px, // 'user unit'
+ Unit_pt, // points, 1.25 px
+ Unit_pc, // 15.0 px
+ Unit_cm, // 35.43307 px
+ Unit_mm, // 3.543307 px
+ Unit_in, // 90 px
+
+ Unit_percent // relative to range
+ };
+
+ class SvgNumber
+ {
+ private:
+ double mfNumber;
+ SvgUnit meUnit;
+
+ /// bitfield
+ bool mbSet : 1;
+
+ public:
+ SvgNumber()
+ : mfNumber(0.0),
+ meUnit(Unit_px),
+ mbSet(false)
+ {
+ }
+
+ SvgNumber(double fNum, SvgUnit aSvgUnit = Unit_px, bool bSet = true)
+ : mfNumber(fNum),
+ meUnit(aSvgUnit),
+ mbSet(bSet)
+ {
+ }
+
+ double getNumber() const
+ {
+ return mfNumber;
+ }
+
+ SvgUnit getUnit() const
+ {
+ return meUnit;
+ }
+
+ bool isSet() const
+ {
+ return mbSet;
+ }
+
+ bool isPositive() const;
+
+ double solve(const InfoProvider& rInfoProvider, NumberType aNumberType = length) const;
+ };
+
+ typedef ::std::vector< SvgNumber > SvgNumberVector;
+
+ enum SvgAlign
+ {
+ Align_none,
+ Align_xMinYMin,
+ Align_xMidYMin,
+ Align_xMaxYMin,
+ Align_xMinYMid,
+ Align_xMidYMid, // default
+ Align_xMaxYMid,
+ Align_xMinYMax,
+ Align_xMidYMax,
+ Align_xMaxYMax
+ };
+
+ class SvgAspectRatio
+ {
+ private:
+ SvgAlign maSvgAlign;
+
+ /// bitfield
+ bool mbDefer : 1; // default is false
+ bool mbMeetOrSlice : 1; // true = meet (default), false = slice
+ bool mbSet : 1;
+
+ public:
+ SvgAspectRatio()
+ : maSvgAlign(Align_xMidYMid),
+ mbDefer(false),
+ mbMeetOrSlice(true),
+ mbSet(false)
+ {
+ }
+
+ SvgAspectRatio(SvgAlign aSvgAlign, bool bDefer, bool bMeetOrSlice)
+ : maSvgAlign(aSvgAlign),
+ mbDefer(bDefer),
+ mbMeetOrSlice(bMeetOrSlice),
+ mbSet(true)
+ {
+ }
+
+ /// data read access
+ SvgAlign getSvgAlign() const { return maSvgAlign; }
+ bool isDefer() const { return mbDefer; }
+ bool isMeetOrSlice() const { return mbMeetOrSlice; }
+ bool isSet() const { return mbSet; }
+
+ /// tooling
+ static basegfx::B2DHomMatrix createLinearMapping(const basegfx::B2DRange& rTarget, const basegfx::B2DRange& rSource);
+ basegfx::B2DHomMatrix createMapping(const basegfx::B2DRange& rTarget, const basegfx::B2DRange& rSource) const;
+ };
+
+ void skip_char(const rtl::OUString& rCandidate, const sal_Unicode& rChar, sal_Int32& nPos, const sal_Int32 nLen);
+ void skip_char(const rtl::OUString& rCandidate, const sal_Unicode& rCharA, const sal_Unicode& rCharB, sal_Int32& nPos, const sal_Int32 nLen);
+ void copySign(const rtl::OUString& rCandidate, sal_Int32& nPos, rtl::OUStringBuffer& rTarget, const sal_Int32 nLen);
+ void copyNumber(const rtl::OUString& rCandidate, sal_Int32& nPos, rtl::OUStringBuffer& rTarget, const sal_Int32 nLen);
+ void copyHex(const rtl::OUString& rCandidate, sal_Int32& nPos, rtl::OUStringBuffer& rTarget, const sal_Int32 nLen);
+ void copyString(const rtl::OUString& rCandidate, sal_Int32& nPos, rtl::OUStringBuffer& rTarget, const sal_Int32 nLen);
+ void copyToLimiter(const rtl::OUString& rCandidate, const sal_Unicode& rLimiter, sal_Int32& nPos, rtl::OUStringBuffer& rTarget, const sal_Int32 nLen);
+ bool readNumber(const rtl::OUString& rCandidate, sal_Int32& nPos, double& fNum, const sal_Int32 nLen);
+ SvgUnit readUnit(const rtl::OUString& rCandidate, sal_Int32& nPos, const sal_Int32 nLen);
+ bool readNumberAndUnit(const rtl::OUString& rCandidate, sal_Int32& nPos, SvgNumber& aNum, const sal_Int32 nLen);
+ bool readAngle(const rtl::OUString& rCandidate, sal_Int32& nPos, double& fAngle, const sal_Int32 nLen);
+ sal_Int32 read_hex(const sal_Unicode& rChar);
+ bool match_colorKeyword(basegfx::BColor& rColor, const rtl::OUString& rName);
+ bool read_color(const rtl::OUString& rCandidate, basegfx::BColor& rColor);
+ basegfx::B2DRange readViewBox(const rtl::OUString& rCandidate, InfoProvider& rInfoProvider);
+ basegfx::B2DHomMatrix readTransform(const rtl::OUString& rCandidate, InfoProvider& rInfoProvider);
+ bool readSingleNumber(const rtl::OUString& rCandidate, SvgNumber& aNum);
+ bool readLocalUrl(const rtl::OUString& rCandidate, rtl::OUString& rURL);
+ bool readSvgPaint(const rtl::OUString& rCandidate, SvgPaint& rSvgPaint, rtl::OUString& rURL);
+
+ bool readSvgNumberVector(const rtl::OUString& rCandidate, SvgNumberVector& rSvgNumberVector);
+ ::std::vector< double > solveSvgNumberVector(const SvgNumberVector& rInput, const InfoProvider& rInfoProvider, NumberType aNumberType = length);
+
+ SvgAspectRatio readSvgAspectRatio(const rtl::OUString& rCandidate);
+
+ typedef ::std::vector< rtl::OUString > SvgStringVector;
+ bool readSvgStringVector(const rtl::OUString& rCandidate, SvgStringVector& rSvgStringVector);
+
+ void readImageLink(const rtl::OUString& rCandidate, rtl::OUString& rXLink, rtl::OUString& rUrl, rtl::OUString& rMimeType, rtl::OUString& rData);
+
+ rtl::OUString convert(const rtl::OUString& rCandidate, const sal_Unicode& rPattern, const sal_Unicode& rNew, bool bRemove);
+ rtl::OUString consolidateContiguosSpace(const rtl::OUString& rCandidate);
+ rtl::OUString whiteSpaceHandlingDefault(const rtl::OUString& rCandidate);
+ rtl::OUString whiteSpaceHandlingPreserve(const rtl::OUString& rCandidate);
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGTOOLS_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgtrefnode.hxx b/svgio/inc/svgio/svgreader/svgtrefnode.hxx
new file mode 100644
index 000000000000..798de70c1094
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgtrefnode.hxx
@@ -0,0 +1,65 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGTREFNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGTREFNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+#include <svgio/svgreader/svgtextnode.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgTrefNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// link to text content. If maXLink
+ /// is set, the node can be fetched on demand
+ rtl::OUString maXLink;
+
+ public:
+ SvgTrefNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgTrefNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+
+ /// access to referenced SvgTextNode
+ const SvgTextNode* getReferencedSvgTextNode() const;
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGTREFNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgtspannode.hxx b/svgio/inc/svgio/svgreader/svgtspannode.hxx
new file mode 100644
index 000000000000..45cd1f8d03d9
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgtspannode.hxx
@@ -0,0 +1,64 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_SVGTSPANNODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_SVGTSPANNODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgcharacternode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+#include <svgio/svgreader/svgtools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgTspanNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// variable scan values, dependent of given XAttributeList
+ SvgTextPositions maSvgTextPositions;
+
+ public:
+ SvgTspanNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgTspanNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+
+ /// access to SvgTextPositions
+ const SvgTextPositions& getSvgTextPositions() const { return maSvgTextPositions; }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_SVGTSPANNODE_HXX
+
+// eof
diff --git a/svgio/inc/svgio/svgreader/svgusenode.hxx b/svgio/inc/svgio/svgreader/svgusenode.hxx
new file mode 100644
index 000000000000..e9fa0ccead17
--- /dev/null
+++ b/svgio/inc/svgio/svgreader/svgusenode.hxx
@@ -0,0 +1,89 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef INCLUDED_SVGIO_SVGREADER_USENODE_HXX
+#define INCLUDED_SVGIO_SVGREADER_USENODE_HXX
+
+#include <svgio/svgiodllapi.h>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class SvgUseNode : public SvgNode
+ {
+ private:
+ /// use styles
+ SvgStyleAttributes maSvgStyleAttributes;
+
+ /// variable scan values, dependent of given XAttributeList
+ basegfx::B2DHomMatrix* mpaTransform;
+ SvgNumber maX;
+ SvgNumber maY;
+ SvgNumber maWidth;
+ SvgNumber maHeight;
+
+ /// link to content. If maXLink is set, the node can be fetched
+ // on demand
+ rtl::OUString maXLink;
+
+ public:
+ SvgUseNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent);
+ virtual ~SvgUseNode();
+
+ virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
+ virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent);
+ virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const;
+
+ /// transform content
+ const basegfx::B2DHomMatrix* getTransform() const { return mpaTransform; }
+ void setTransform(const basegfx::B2DHomMatrix* pMatrix = 0) { if(mpaTransform) delete mpaTransform; mpaTransform = 0; if(pMatrix) mpaTransform = new basegfx::B2DHomMatrix(*pMatrix); }
+
+ /// x content
+ const SvgNumber& getX() const { return maX; }
+ void setX(const SvgNumber& rX = SvgNumber()) { maX = rX; }
+
+ /// y content
+ const SvgNumber& getY() const { return maY; }
+ void setY(const SvgNumber& rY = SvgNumber()) { maY = rY; }
+
+ /// width content
+ const SvgNumber& getWidth() const { return maWidth; }
+ void setWidth(const SvgNumber& rWidth = SvgNumber()) { maWidth = rWidth; }
+
+ /// height content
+ const SvgNumber& getHeight() const { return maHeight; }
+ void setHeight(const SvgNumber& rHeight = SvgNumber()) { maHeight = rHeight; }
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_SVGIO_SVGREADER_USENODE_HXX
+
+// eof
diff --git a/svgio/prj/build.lst b/svgio/prj/build.lst
new file mode 100644
index 000000000000..ff858ab1ddda
--- /dev/null
+++ b/svgio/prj/build.lst
@@ -0,0 +1,2 @@
+dl svgio : sal basegfx drawinglayer cppuhelper cppu svtools NULL
+dl svgio\prj nmake - all svgio_prj NULL
diff --git a/svgio/prj/d.lst b/svgio/prj/d.lst
new file mode 100755
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/svgio/prj/d.lst
diff --git a/svgio/prj/makefile.mk b/svgio/prj/makefile.mk
new file mode 100644
index 000000000000..e312a7ccab65
--- /dev/null
+++ b/svgio/prj/makefile.mk
@@ -0,0 +1,40 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..
+TARGET=prj
+
+.INCLUDE : settings.mk
+
+.IF "$(VERBOSE)"!=""
+VERBOSEFLAG :=
+.ELSE
+VERBOSEFLAG := -s
+.ENDIF
+
+all:
+ cd $(PRJ) && $(GNUMAKE) $(VERBOSEFLAG) -r -j$(MAXPROCESS) $(gb_MAKETARGET) && $(GNUMAKE) $(VERBOSEFLAG) -r deliverlog
diff --git a/svgio/source/svgreader/svgcharacternode.cxx b/svgio/source/svgreader/svgcharacternode.cxx
new file mode 100644
index 000000000000..bf37cb6e9361
--- /dev/null
+++ b/svgio/source/svgreader/svgcharacternode.cxx
@@ -0,0 +1,725 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgcharacternode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+#include <drawinglayer/attribute/fontattribute.hxx>
+#include <drawinglayer/primitive2d/textprimitive2d.hxx>
+#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
+#include <drawinglayer/primitive2d/textbreakuphelper.hxx>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
+#include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgTextPositions::SvgTextPositions()
+ : maX(),
+ maY(),
+ maDx(),
+ maDy(),
+ maRotate(),
+ maTextLength(),
+ mbLengthAdjust(true)
+ {
+ }
+
+ void SvgTextPositions::parseTextPositionAttributes(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenX:
+ {
+ if(aContent.getLength())
+ {
+ SvgNumberVector aVector;
+
+ if(readSvgNumberVector(aContent, aVector))
+ {
+ setX(aVector);
+ }
+ }
+ break;
+ }
+ case SVGTokenY:
+ {
+ if(aContent.getLength())
+ {
+ SvgNumberVector aVector;
+
+ if(readSvgNumberVector(aContent, aVector))
+ {
+ setY(aVector);
+ }
+ }
+ break;
+ }
+ case SVGTokenDx:
+ {
+ if(aContent.getLength())
+ {
+ SvgNumberVector aVector;
+
+ if(readSvgNumberVector(aContent, aVector))
+ {
+ setDx(aVector);
+ }
+ }
+ break;
+ }
+ case SVGTokenDy:
+ {
+ if(aContent.getLength())
+ {
+ SvgNumberVector aVector;
+
+ if(readSvgNumberVector(aContent, aVector))
+ {
+ setDy(aVector);
+ }
+ }
+ break;
+ }
+ case SVGTokenRotate:
+ {
+ if(aContent.getLength())
+ {
+ SvgNumberVector aVector;
+
+ if(readSvgNumberVector(aContent, aVector))
+ {
+ setRotate(aVector);
+ }
+ }
+ break;
+ }
+ case SVGTokenTextLength:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setTextLength(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenLengthAdjust:
+ {
+ if(aContent.getLength())
+ {
+ static rtl::OUString aStrSpacing(rtl::OUString::createFromAscii("spacing"));
+ static rtl::OUString aStrSpacingAndGlyphs(rtl::OUString::createFromAscii("spacingAndGlyphs"));
+
+ if(aContent.match(aStrSpacing))
+ {
+ setLengthAdjust(true);
+ }
+ else if(aContent.match(aStrSpacingAndGlyphs))
+ {
+ setLengthAdjust(false);
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class localTextBreakupHelper : public drawinglayer::primitive2d::TextBreakupHelper
+ {
+ private:
+ SvgTextPosition& mrSvgTextPosition;
+
+ protected:
+ /// allow user callback to allow changes to the new TextTransformation. Default
+ /// does nothing.
+ virtual bool allowChange(sal_uInt32 nCount, basegfx::B2DHomMatrix& rNewTransform, sal_uInt32 nIndex, sal_uInt32 nLength);
+
+ public:
+ localTextBreakupHelper(
+ const drawinglayer::primitive2d::Primitive2DReference& rxSource,
+ SvgTextPosition& rSvgTextPosition)
+ : drawinglayer::primitive2d::TextBreakupHelper(rxSource),
+ mrSvgTextPosition(rSvgTextPosition)
+ {
+ }
+ };
+
+ bool localTextBreakupHelper::allowChange(sal_uInt32 nCount, basegfx::B2DHomMatrix& rNewTransform, sal_uInt32 nIndex, sal_uInt32 nLength)
+ {
+ const double fRotation(mrSvgTextPosition.consumeRotation());
+
+ if(0.0 != fRotation)
+ {
+ const basegfx::B2DPoint aBasePoint(rNewTransform * basegfx::B2DPoint(0.0, 0.0));
+
+ rNewTransform.translate(-aBasePoint.getX(), -aBasePoint.getY());
+ rNewTransform.rotate(fRotation);
+ rNewTransform.translate(aBasePoint.getX(), aBasePoint.getY());
+ }
+
+ return true;
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgCharacterNode::SvgCharacterNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent,
+ const rtl::OUString& rText)
+ : SvgNode(SVGTokenCharacter, rDocument, pParent),
+ maText(rText)
+ {
+ }
+
+ SvgCharacterNode::~SvgCharacterNode()
+ {
+ }
+
+ const SvgStyleAttributes* SvgCharacterNode::getSvgStyleAttributes() const
+ {
+ // no own style, use parent's
+ if(getParent())
+ {
+ return getParent()->getSvgStyleAttributes();
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ drawinglayer::primitive2d::TextSimplePortionPrimitive2D* SvgCharacterNode::createSimpleTextPrimitive(
+ SvgTextPosition& rSvgTextPosition,
+ const SvgStyleAttributes& rSvgStyleAttributes) const
+ {
+ // prepare retval, index and length
+ drawinglayer::primitive2d::TextSimplePortionPrimitive2D* pRetval = 0;
+ sal_uInt32 nIndex(0);
+ sal_uInt32 nLength(getText().getLength());
+
+ if(nLength)
+ {
+ // prepare FontAttribute
+ const rtl::OUString aFontFamily = rSvgStyleAttributes.getFontFamily().empty() ?
+ rtl::OUString(rtl::OUString::createFromAscii("Times New Roman")) :
+ rSvgStyleAttributes.getFontFamily()[0];
+ const ::FontWeight nFontWeight(getVclFontWeight(rSvgStyleAttributes.getFontWeight()));
+ bool bSymbol(false);
+ bool bVertical(false);
+ bool bItalic(FontStyle_italic == rSvgStyleAttributes.getFontStyle() || FontStyle_oblique == rSvgStyleAttributes.getFontStyle());
+ bool bMonospaced(false);
+ bool bOutline(false);
+ bool bRTL(false);
+ bool bBiDiStrong(false);
+
+ const drawinglayer::attribute::FontAttribute aFontAttribute(
+ aFontFamily,
+ rtl::OUString(),
+ nFontWeight,
+ bSymbol,
+ bVertical,
+ bItalic,
+ bMonospaced,
+ bOutline,
+ bRTL,
+ bBiDiStrong);
+
+ // prepare FontSize
+ double fFontWidth(rSvgStyleAttributes.getFontSize().solve(*this, length));
+ double fFontHeight(fFontWidth);
+
+ // prepare locale
+ ::com::sun::star::lang::Locale aLocale;
+
+ // prepare TextLayouterDevice
+ drawinglayer::primitive2d::TextLayouterDevice aTextLayouterDevice;
+ aTextLayouterDevice.setFontAttribute(aFontAttribute, fFontWidth, fFontHeight, aLocale);
+
+ // prepare TextArray
+ ::std::vector< double > aTextArray(rSvgTextPosition.getX());
+
+ if(!aTextArray.empty() && aTextArray.size() < nLength)
+ {
+ const sal_uInt32 nArray(aTextArray.size());
+
+ if(nArray < nLength)
+ {
+ double fStartX(0.0);
+
+ if(rSvgTextPosition.getParent() && rSvgTextPosition.getParent()->getAbsoluteX())
+ {
+ fStartX = rSvgTextPosition.getParent()->getPosition().getX();
+ }
+ else
+ {
+ fStartX = aTextArray[nArray - 1];
+ }
+
+ ::std::vector< double > aExtendArray(aTextLayouterDevice.getTextArray(getText(), nArray, nLength - nArray));
+ aTextArray.reserve(nLength);
+
+ for(sal_uInt32 a(0); a < aExtendArray.size(); a++)
+ {
+ aTextArray.push_back(aExtendArray[a] + fStartX);
+ }
+ }
+ }
+
+ // get current TextPosition and TextWidth in units
+ basegfx::B2DPoint aPosition(rSvgTextPosition.getPosition());
+ double fTextWidth(aTextLayouterDevice.getTextWidth(getText(), nIndex, nLength));
+
+ // check for user-given TextLength
+ if(0.0 != rSvgTextPosition.getTextLength()
+ && !basegfx::fTools::equal(fTextWidth, rSvgTextPosition.getTextLength()))
+ {
+ const double fFactor(rSvgTextPosition.getTextLength() / fTextWidth);
+
+ if(rSvgTextPosition.getLengthAdjust())
+ {
+ // spacing, need to create and expand TextArray
+ if(aTextArray.empty())
+ {
+ aTextArray = aTextLayouterDevice.getTextArray(getText(), nIndex, nLength);
+ }
+
+ for(sal_uInt32 a(0); a < aTextArray.size(); a++)
+ {
+ aTextArray[a] *= fFactor;
+ }
+ }
+ else
+ {
+ // spacing and glyphs, just apply to FontWidth
+ fFontWidth *= fFactor;
+ }
+
+ fTextWidth = rSvgTextPosition.getTextLength();
+ }
+
+ // get TextAlign
+ TextAlign aTextAlign(rSvgStyleAttributes.getTextAlign());
+
+ // map TextAnchor to TextAlign, there seems not to be a difference
+ if(TextAnchor_notset != rSvgStyleAttributes.getTextAnchor())
+ {
+ switch(rSvgStyleAttributes.getTextAnchor())
+ {
+ case TextAnchor_start:
+ {
+ aTextAlign = TextAlign_left;
+ break;
+ }
+ case TextAnchor_middle:
+ {
+ aTextAlign = TextAlign_center;
+ break;
+ }
+ case TextAnchor_end:
+ {
+ aTextAlign = TextAlign_right;
+ break;
+ }
+ }
+ }
+
+ // apply TextAlign
+ switch(aTextAlign)
+ {
+ case TextAlign_right:
+ {
+ aPosition.setX(aPosition.getX() - fTextWidth);
+ break;
+ }
+ case TextAlign_center:
+ {
+ aPosition.setX(aPosition.getX() - (fTextWidth * 0.5));
+ break;
+ }
+ case TextAlign_notset:
+ case TextAlign_left:
+ case TextAlign_justify:
+ {
+ // TextAlign_notset, TextAlign_left: nothing to do
+ // TextAlign_justify is not clear currently; handle as TextAlign_left
+ break;
+ }
+ }
+
+ // get fill color
+ const basegfx::BColor aFill(rSvgStyleAttributes.getFill()
+ ? *rSvgStyleAttributes.getFill()
+ : basegfx::BColor(0.0, 0.0, 0.0));
+
+ // prepare TextTransformation
+ basegfx::B2DHomMatrix aTextTransform;
+
+ aTextTransform.scale(fFontWidth, fFontHeight);
+ aTextTransform.translate(aPosition.getX(), aPosition.getY());
+
+ // check TextDecoration and if TextDecoratedPortionPrimitive2D is needed
+ const TextDecoration aDeco(rSvgStyleAttributes.getTextDecoration());
+
+ if(TextDecoration_underline == aDeco
+ || TextDecoration_overline == aDeco
+ || TextDecoration_line_through == aDeco)
+ {
+ // get the fill for decroation as described by SVG. We cannot
+ // have different stroke colors/definitions for those, though
+ const SvgStyleAttributes* pDecoDef = rSvgStyleAttributes.getTextDecorationDefiningSvgStyleAttributes();
+ const basegfx::BColor aDecoColor(pDecoDef && pDecoDef->getFill() ? *pDecoDef->getFill() : aFill);
+
+ // create decorated text primitive
+ pRetval = new drawinglayer::primitive2d::TextDecoratedPortionPrimitive2D(
+ aTextTransform,
+ getText(),
+ nIndex,
+ nLength,
+ aTextArray,
+ aFontAttribute,
+ aLocale,
+ aFill,
+
+ // extra props for decorated
+ aDecoColor,
+ aDecoColor,
+ TextDecoration_overline == aDeco ? drawinglayer::primitive2d::TEXT_LINE_SINGLE : drawinglayer::primitive2d::TEXT_LINE_NONE,
+ TextDecoration_underline == aDeco ? drawinglayer::primitive2d::TEXT_LINE_SINGLE : drawinglayer::primitive2d::TEXT_LINE_NONE,
+ false,
+ TextDecoration_line_through == aDeco ? drawinglayer::primitive2d::TEXT_STRIKEOUT_SINGLE : drawinglayer::primitive2d::TEXT_STRIKEOUT_NONE,
+ false,
+ drawinglayer::primitive2d::TEXT_EMPHASISMARK_NONE,
+ true,
+ false,
+ drawinglayer::primitive2d::TEXT_RELIEF_NONE,
+ false);
+ }
+ else
+ {
+ // create text primitive
+ pRetval = new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
+ aTextTransform,
+ getText(),
+ nIndex,
+ nLength,
+ aTextArray,
+ aFontAttribute,
+ aLocale,
+ aFill);
+ }
+
+ // advance current TextPosition
+ rSvgTextPosition.setPosition(rSvgTextPosition.getPosition() + basegfx::B2DVector(fTextWidth, 0.0));
+ }
+
+ return pRetval;
+ }
+
+ void SvgCharacterNode::decomposeTextWithStyle(
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ SvgTextPosition& rSvgTextPosition,
+ const SvgStyleAttributes& rSvgStyleAttributes) const
+ {
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ createSimpleTextPrimitive(
+ rSvgTextPosition,
+ rSvgStyleAttributes));
+
+ if(xRef.is())
+ {
+ if(!rSvgTextPosition.isRotated())
+ {
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(rTarget, xRef);
+ }
+ else
+ {
+ // need to apply rotations to each character as given
+ localTextBreakupHelper alocalTextBreakupHelper(xRef, rSvgTextPosition);
+ const drawinglayer::primitive2d::Primitive2DSequence aResult(
+ alocalTextBreakupHelper.getResult(drawinglayer::primitive2d::BreakupUnit_character));
+
+ if(aResult.hasElements())
+ {
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aResult);
+ }
+
+ // also consume for the implied single space
+ rSvgTextPosition.consumeRotation();
+ }
+ }
+ }
+
+ void SvgCharacterNode::whiteSpaceHandling()
+ {
+ if(XmlSpace_default == getXmlSpace())
+ {
+ maText = whiteSpaceHandlingDefault(maText);
+ }
+ else
+ {
+ maText = whiteSpaceHandlingPreserve(maText);
+ }
+ }
+
+ void SvgCharacterNode::addGap()
+ {
+ maText += rtl::OUString(sal_Unicode(' '));
+ }
+
+ void SvgCharacterNode::concatenate(const rtl::OUString& rText)
+ {
+ maText += rText;
+ }
+
+ void SvgCharacterNode::decomposeText(drawinglayer::primitive2d::Primitive2DSequence& rTarget, SvgTextPosition& rSvgTextPosition) const
+ {
+ if(getText().getLength())
+ {
+ const SvgStyleAttributes* pSvgStyleAttributes = getSvgStyleAttributes();
+
+ if(pSvgStyleAttributes)
+ {
+ decomposeTextWithStyle(rTarget, rSvgTextPosition, *pSvgStyleAttributes);
+ }
+ }
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgTextPosition::SvgTextPosition(
+ SvgTextPosition* pParent,
+ const InfoProvider& rInfoProvider,
+ const SvgTextPositions& rSvgTextPositions)
+ : mpParent(pParent),
+ maX(), // computed below
+ maY(), // computed below
+ maRotate(solveSvgNumberVector(rSvgTextPositions.getRotate(), rInfoProvider, length)),
+ mfTextLength(0.0),
+ maPosition(), // computed below
+ mnRotationIndex(0),
+ mbLengthAdjust(rSvgTextPositions.getLengthAdjust()),
+ mbAbsoluteX(false),
+ mbAbsoluteY(false)
+ {
+ // get TextLength if provided
+ if(rSvgTextPositions.getTextLength().isSet())
+ {
+ mfTextLength = rSvgTextPositions.getTextLength().solve(rInfoProvider, length);
+ }
+
+ // SVG does not really define in which units a rotate for Text/TSpan is given,
+ // but it seems to be degrees. Convert here to radians
+ if(!maRotate.empty())
+ {
+ const double fFactor(F_PI / 180.0);
+
+ for(sal_uInt32 a(0); a < maRotate.size(); a++)
+ {
+ maRotate[a] *= fFactor;
+ }
+ }
+
+ // get text positions X
+ const sal_uInt32 nSizeX(rSvgTextPositions.getX().size());
+
+ if(nSizeX)
+ {
+ // we have absolute positions, get first one as current text position X
+ maPosition.setX(rSvgTextPositions.getX()[0].solve(rInfoProvider, xcoordinate));
+ mbAbsoluteX = true;
+
+ if(nSizeX > 1)
+ {
+ // fill deltas to maX
+ maX.reserve(nSizeX);
+
+ for(sal_uInt32 a(1); a < nSizeX; a++)
+ {
+ maX.push_back(rSvgTextPositions.getX()[a].solve(rInfoProvider, xcoordinate) - maPosition.getX());
+ }
+ }
+ }
+ else
+ {
+ // no absolute position, get from parent
+ if(pParent)
+ {
+ maPosition.setX(pParent->getPosition().getX());
+ }
+
+ const sal_uInt32 nSizeDx(rSvgTextPositions.getDx().size());
+
+ if(nSizeDx)
+ {
+ // relative positions given, translate position derived from parent
+ maPosition.setX(maPosition.getX() + rSvgTextPositions.getDx()[0].solve(rInfoProvider, xcoordinate));
+
+ if(nSizeDx > 1)
+ {
+ // fill deltas to maX
+ maX.reserve(nSizeDx);
+
+ for(sal_uInt32 a(1); a < nSizeDx; a++)
+ {
+ maX.push_back(rSvgTextPositions.getDx()[a].solve(rInfoProvider, xcoordinate));
+ }
+ }
+ }
+ }
+
+ // get text positions Y
+ const sal_uInt32 nSizeY(rSvgTextPositions.getY().size());
+
+ if(nSizeY)
+ {
+ // we have absolute positions, get first one as current text position Y
+ maPosition.setY(rSvgTextPositions.getY()[0].solve(rInfoProvider, ycoordinate));
+ mbAbsoluteX = true;
+
+ if(nSizeY > 1)
+ {
+ // fill deltas to maY
+ maY.reserve(nSizeY);
+
+ for(sal_uInt32 a(1); a < nSizeY; a++)
+ {
+ maY.push_back(rSvgTextPositions.getY()[a].solve(rInfoProvider, ycoordinate) - maPosition.getY());
+ }
+ }
+ }
+ else
+ {
+ // no absolute position, get from parent
+ if(pParent)
+ {
+ maPosition.setY(pParent->getPosition().getY());
+ }
+
+ const sal_uInt32 nSizeDy(rSvgTextPositions.getDy().size());
+
+ if(nSizeDy)
+ {
+ // relative positions given, translate position derived from parent
+ maPosition.setY(maPosition.getY() + rSvgTextPositions.getDy()[0].solve(rInfoProvider, ycoordinate));
+
+ if(nSizeDy > 1)
+ {
+ // fill deltas to maY
+ maY.reserve(nSizeDy);
+
+ for(sal_uInt32 a(1); a < nSizeDy; a++)
+ {
+ maY.push_back(rSvgTextPositions.getDy()[a].solve(rInfoProvider, ycoordinate));
+ }
+ }
+ }
+ }
+ }
+
+ bool SvgTextPosition::isRotated() const
+ {
+ if(maRotate.empty())
+ {
+ if(getParent())
+ {
+ return getParent()->isRotated();
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ double SvgTextPosition::consumeRotation()
+ {
+ double fRetval(0.0);
+
+ if(maRotate.empty())
+ {
+ if(getParent())
+ {
+ fRetval = mpParent->consumeRotation();
+ }
+ else
+ {
+ fRetval = 0.0;
+ }
+ }
+ else
+ {
+ const sal_uInt32 nSize(maRotate.size());
+
+ if(mnRotationIndex < nSize)
+ {
+ fRetval = maRotate[mnRotationIndex++];
+ }
+ else
+ {
+ fRetval = maRotate[nSize - 1];
+ }
+ }
+
+ return fRetval;
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgcirclenode.cxx b/svgio/source/svgreader/svgcirclenode.cxx
new file mode 100644
index 000000000000..95a81ff5611d
--- /dev/null
+++ b/svgio/source/svgreader/svgcirclenode.cxx
@@ -0,0 +1,154 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgcirclenode.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgCircleNode::SvgCircleNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenCircle, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ maCx(0),
+ maCy(0),
+ maR(0),
+ mpaTransform(0)
+ {
+ }
+
+ SvgCircleNode::~SvgCircleNode()
+ {
+ if(mpaTransform) delete mpaTransform;
+ }
+
+ const SvgStyleAttributes* SvgCircleNode::getSvgStyleAttributes() const
+ {
+ static rtl::OUString aClassStr(rtl::OUString::createFromAscii("circle"));
+ maSvgStyleAttributes.checkForCssStyle(aClassStr);
+
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgCircleNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenCx:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setCx(aNum);
+ }
+ break;
+ }
+ case SVGTokenCy:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setCy(aNum);
+ }
+ break;
+ }
+ case SVGTokenR:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setR(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenTransform:
+ {
+ const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
+
+ if(!aMatrix.isIdentity())
+ {
+ setTransform(&aMatrix);
+ }
+ break;
+ }
+ }
+ }
+
+ void SvgCircleNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
+ {
+ const SvgStyleAttributes* pStyle = getSvgStyleAttributes();
+
+ if(pStyle && getR().isSet())
+ {
+ const double fR(getR().solve(*this, xcoordinate));
+
+ if(fR > 0.0)
+ {
+ const basegfx::B2DPolygon aPath(
+ basegfx::tools::createPolygonFromCircle(
+ basegfx::B2DPoint(
+ getCx().isSet() ? getCx().solve(*this, xcoordinate) : 0.0,
+ getCy().isSet() ? getCy().solve(*this, ycoordinate) : 0.0),
+ fR));
+
+ drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
+
+ pStyle->add_path(basegfx::B2DPolyPolygon(aPath), aNewTarget);
+
+ if(aNewTarget.hasElements())
+ {
+ pStyle->add_postProcess(rTarget, aNewTarget, getTransform());
+ }
+ }
+ }
+ }
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgclippathnode.cxx b/svgio/source/svgreader/svgclippathnode.cxx
new file mode 100755
index 000000000000..11889a4437c9
--- /dev/null
+++ b/svgio/source/svgreader/svgclippathnode.cxx
@@ -0,0 +1,184 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgclippathnode.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/transparenceprimitive2d.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgClipPathNode::SvgClipPathNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenClipPathNode, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ mpaTransform(0),
+ maClipPathUnits(userSpaceOnUse)
+ {
+ }
+
+ SvgClipPathNode::~SvgClipPathNode()
+ {
+ if(mpaTransform) delete mpaTransform;
+ }
+
+ const SvgStyleAttributes* SvgClipPathNode::getSvgStyleAttributes() const
+ {
+ static rtl::OUString aClassStr(rtl::OUString::createFromAscii("clip-path"));
+ maSvgStyleAttributes.checkForCssStyle(aClassStr);
+
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgClipPathNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenTransform:
+ {
+ const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
+
+ if(!aMatrix.isIdentity())
+ {
+ setTransform(&aMatrix);
+ }
+ break;
+ }
+ case SVGTokenClipPathUnits:
+ {
+ if(aContent.getLength())
+ {
+ if(aContent.match(commonStrings::aStrUserSpaceOnUse, 0))
+ {
+ setClipPathUnits(userSpaceOnUse);
+ }
+ else if(aContent.match(commonStrings::aStrObjectBoundingBox, 0))
+ {
+ setClipPathUnits(objectBoundingBox);
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ void SvgClipPathNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
+
+ // decompose childs
+ SvgNode::decomposeSvgNode(aNewTarget, bReferenced);
+
+ if(aNewTarget.hasElements())
+ {
+ if(getTransform())
+ {
+ // create embedding group element with transformation
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ *getTransform(),
+ aNewTarget));
+
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(rTarget, xRef);
+ }
+ else
+ {
+ // append to current target
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewTarget);
+ }
+ }
+ }
+
+ void SvgClipPathNode::apply(drawinglayer::primitive2d::Primitive2DSequence& rContent) const
+ {
+ if(rContent.hasElements())
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aClipTarget;
+
+ // get clipPath definition as primitives
+ decomposeSvgNode(aClipTarget, true);
+
+ if(aClipTarget.hasElements())
+ {
+ if(objectBoundingBox == getClipPathUnits())
+ {
+ // clip is object-relative, embed in content transformation
+ const basegfx::B2DRange aContentRange(
+ drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(
+ rContent,
+ drawinglayer::geometry::ViewInformation2D()));
+
+ const drawinglayer::primitive2d::Primitive2DReference xTransform(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ aContentRange.getRange(),
+ aContentRange.getMinimum()),
+ aClipTarget));
+
+ aClipTarget = drawinglayer::primitive2d::Primitive2DSequence(&xTransform, 1);
+ }
+
+ // redefine target. Use TransparencePrimitive2D with created clip
+ // geometry. Using the automatically set mbIsClipPathContent at
+ // SvgStyleAttributes the clip definition is without fill, stroke,
+ // and strokeWidth and forced to black, thus being 100% opaque
+ const drawinglayer::primitive2d::Primitive2DReference xEmbedTransparence(
+ new drawinglayer::primitive2d::TransparencePrimitive2D(
+ rContent,
+ aClipTarget));
+
+ rContent = drawinglayer::primitive2d::Primitive2DSequence(&xEmbedTransparence, 1);
+ }
+ else
+ {
+ // An empty clipping path will completely clip away the element that had
+ // the clip-path property applied. (Svg spec)
+ rContent.realloc(0);
+ }
+ }
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgdocument.cxx b/svgio/source/svgreader/svgdocument.cxx
new file mode 100644
index 000000000000..c719dbd6c8ef
--- /dev/null
+++ b/svgio/source/svgreader/svgdocument.cxx
@@ -0,0 +1,121 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgdocument.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgDocument::SvgDocument(const rtl::OUString& rAbsolutePath)
+ : maNodes(),
+ maAbsolutePath(rAbsolutePath),
+ maIdTokenMapperList(),
+ maIdStyleTokenMapperList()
+ {
+ }
+
+ SvgDocument::~SvgDocument()
+ {
+ while(!maNodes.empty())
+ {
+ SvgNode* pCandidate = maNodes[maNodes.size() - 1];
+ delete pCandidate;
+ maNodes.pop_back();
+ }
+ }
+
+ void SvgDocument::appendNode(SvgNode* pNode)
+ {
+ OSL_ENSURE(pNode, "OOps, empty node added (!)");
+ maNodes.push_back(pNode);
+ }
+
+ void SvgDocument::addSvgNodeToMapper(const rtl::OUString& rStr, const SvgNode& rNode)
+ {
+ if(rStr.getLength())
+ {
+ maIdTokenMapperList.insert(IdTokenValueType(rStr, &rNode));
+ }
+ }
+
+ void SvgDocument::removeSvgNodeFromMapper(const rtl::OUString& rStr)
+ {
+ if(rStr.getLength())
+ {
+ maIdTokenMapperList.erase(rStr);
+ }
+ }
+
+ const SvgNode* SvgDocument::findSvgNodeById(const rtl::OUString& rStr) const
+ {
+ const IdTokenMapper::const_iterator aResult(maIdTokenMapperList.find(rStr));
+
+ if(aResult == maIdTokenMapperList.end())
+ {
+ return 0;
+ }
+ else
+ {
+ return aResult->second;
+ }
+ }
+
+ void SvgDocument::addSvgStyleAttributesToMapper(const rtl::OUString& rStr, const SvgStyleAttributes& rSvgStyleAttributes)
+ {
+ if(rStr.getLength())
+ {
+ maIdStyleTokenMapperList.insert(IdStyleTokenValueType(rStr, &rSvgStyleAttributes));
+ }
+ }
+
+ void SvgDocument::removeSvgStyleAttributesFromMapper(const rtl::OUString& rStr)
+ {
+ if(rStr.getLength())
+ {
+ maIdStyleTokenMapperList.erase(rStr);
+ }
+ }
+
+ const SvgStyleAttributes* SvgDocument::findSvgStyleAttributesById(const rtl::OUString& rStr) const
+ {
+ const IdStyleTokenMapper::const_iterator aResult(maIdStyleTokenMapperList.find(rStr));
+
+ if(aResult == maIdStyleTokenMapperList.end())
+ {
+ return 0;
+ }
+ else
+ {
+ return aResult->second;
+ }
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgdocumenthandler.cxx b/svgio/source/svgreader/svgdocumenthandler.cxx
new file mode 100644
index 000000000000..1c0fe65d79ef
--- /dev/null
+++ b/svgio/source/svgreader/svgdocumenthandler.cxx
@@ -0,0 +1,518 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgdocumenthandler.hxx>
+#include <svgio/svgreader/svgtoken.hxx>
+#include <svgio/svgreader/svgsvgnode.hxx>
+#include <svgio/svgreader/svggnode.hxx>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgpathnode.hxx>
+#include <svgio/svgreader/svgrectnode.hxx>
+#include <svgio/svgreader/svggradientnode.hxx>
+#include <svgio/svgreader/svggradientstopnode.hxx>
+#include <svgio/svgreader/svgsymbolnode.hxx>
+#include <svgio/svgreader/svgusenode.hxx>
+#include <svgio/svgreader/svgcirclenode.hxx>
+#include <svgio/svgreader/svgellipsenode.hxx>
+#include <svgio/svgreader/svglinenode.hxx>
+#include <svgio/svgreader/svgpolynode.hxx>
+#include <svgio/svgreader/svgsymbolnode.hxx>
+#include <svgio/svgreader/svgtextnode.hxx>
+#include <svgio/svgreader/svgcharacternode.hxx>
+#include <svgio/svgreader/svgtspannode.hxx>
+#include <svgio/svgreader/svgtrefnode.hxx>
+#include <svgio/svgreader/svgtextpathnode.hxx>
+#include <svgio/svgreader/svgstylenode.hxx>
+#include <svgio/svgreader/svgimagenode.hxx>
+#include <svgio/svgreader/svgclippathnode.hxx>
+#include <svgio/svgreader/svgmasknode.hxx>
+#include <svgio/svgreader/svgmarkernode.hxx>
+#include <svgio/svgreader/svgpatternnode.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace
+{
+ svgio::svgreader::SvgCharacterNode* whiteSpaceHandling(svgio::svgreader::SvgNode* pNode, svgio::svgreader::SvgCharacterNode* pLast)
+ {
+ if(pNode)
+ {
+ const svgio::svgreader::SvgNodeVector& rChilds = pNode->getChildren();
+ const sal_uInt32 nCount(rChilds.size());
+
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ svgio::svgreader::SvgNode* pCandidate = rChilds[a];
+
+ if(pCandidate)
+ {
+ switch(pCandidate->getType())
+ {
+ case svgio::svgreader::SVGTokenCharacter:
+ {
+ // clean whitespace in text span
+ svgio::svgreader::SvgCharacterNode* pCharNode = static_cast< svgio::svgreader::SvgCharacterNode* >(pCandidate);
+ pCharNode->whiteSpaceHandling();
+
+ // pCharNode may have lost all text. If that's the case, ignore
+ // as invalid character node
+ if(pCharNode->getText().getLength())
+ {
+ if(pLast)
+ {
+ // add in-between whitespace (single space) to last
+ // known character node
+ pLast->addGap();
+ }
+
+ // remember new last corected character node
+ pLast = pCharNode;
+ }
+ break;
+ }
+ case svgio::svgreader::SVGTokenTspan:
+ case svgio::svgreader::SVGTokenTextPath:
+ case svgio::svgreader::SVGTokenTref:
+ {
+ // recursively clean whitespaces in subhierarchy
+ pLast = whiteSpaceHandling(pCandidate, pLast);
+ break;
+ }
+ default:
+ {
+ OSL_ENSURE(false, "Unexpected token inside SVGTokenText (!)");
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return pLast;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgDocHdl::SvgDocHdl(const rtl::OUString& aAbsolutePath)
+ : maDocument(aAbsolutePath),
+ mpTarget(0)
+ {
+ }
+
+ SvgDocHdl::~SvgDocHdl()
+ {
+#ifdef DBG_UTIL
+ if(mpTarget)
+ {
+ OSL_ENSURE(false, "SvgDocHdl destructed with active target (!)");
+ delete mpTarget;
+ }
+#endif
+ }
+
+ void SvgDocHdl::startDocument( ) throw (xml::sax::SAXException, uno::RuntimeException)
+ {
+ OSL_ENSURE(!mpTarget, "Already a target at document start (!)");
+ }
+
+ void SvgDocHdl::endDocument( ) throw (xml::sax::SAXException, uno::RuntimeException)
+ {
+ OSL_ENSURE(!mpTarget, "Still a target at document end (!)");
+ }
+
+ void SvgDocHdl::startElement( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs ) throw (xml::sax::SAXException, uno::RuntimeException)
+ {
+ if(aName.getLength())
+ {
+ const SVGToken aSVGToken(StrToSVGToken(aName));
+
+ switch(aSVGToken)
+ {
+ /// structural elements
+ case SVGTokenSymbol:
+ {
+ /// new basic node for Symbol. Content gets scanned, but
+ /// will not be decomposed (see SvgNode::decomposeSvgNode and bReferenced)
+ mpTarget = new SvgSymbolNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+ case SVGTokenDefs:
+ case SVGTokenG:
+ {
+ /// new node for Defs/G
+ mpTarget = new SvgGNode(aSVGToken, maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+ case SVGTokenSvg:
+ {
+ /// new node for Svg
+ mpTarget = new SvgSvgNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+ case SVGTokenUse:
+ {
+ /// new node for Use
+ mpTarget = new SvgUseNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+
+ /// shape elements
+ case SVGTokenCircle:
+ {
+ /// new node for Circle
+ mpTarget = new SvgCircleNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+ case SVGTokenEllipse:
+ {
+ /// new node for Ellipse
+ mpTarget = new SvgEllipseNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+ case SVGTokenLine:
+ {
+ /// new node for Line
+ mpTarget = new SvgLineNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+ case SVGTokenPath:
+ {
+ /// new node for Path
+ mpTarget = new SvgPathNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+ case SVGTokenPolygon:
+ {
+ /// new node for Polygon
+ mpTarget = new SvgPolyNode(maDocument, mpTarget, false);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+ case SVGTokenPolyline:
+ {
+ /// new node for Polyline
+ mpTarget = new SvgPolyNode(maDocument, mpTarget, true);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+ case SVGTokenRect:
+ {
+ /// new node for Rect
+ mpTarget = new SvgRectNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+ case SVGTokenImage:
+ {
+ /// new node for Image
+ mpTarget = new SvgImageNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+
+ /// gradients
+ case SVGTokenLinearGradient:
+ case SVGTokenRadialGradient:
+ {
+ mpTarget = new SvgGradientNode(aSVGToken, maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+
+ /// gradient stops
+ case SVGTokenStop:
+ {
+ mpTarget = new SvgGradientStopNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+
+ /// text
+ case SVGTokenText:
+ {
+ mpTarget = new SvgTextNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+ case SVGTokenTspan:
+ {
+ mpTarget = new SvgTspanNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+ case SVGTokenTref:
+ {
+ mpTarget = new SvgTrefNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+ case SVGTokenTextPath:
+ {
+ mpTarget = new SvgTextPathNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+
+ /// styles (as stylesheets)
+ case SVGTokenStyle:
+ {
+ mpTarget = new SvgStyleNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+
+ /// structural elements clip-path and mask. Content gets scanned, but
+ /// will not be decomposed (see SvgNode::decomposeSvgNode and bReferenced)
+ case SVGTokenClipPathNode:
+ {
+ /// new node for ClipPath
+ mpTarget = new SvgClipPathNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+ case SVGTokenMask:
+ {
+ /// new node for Mask
+ mpTarget = new SvgMaskNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+
+ /// structural element marker
+ case SVGTokenMarker:
+ {
+ /// new node for marker
+ mpTarget = new SvgMarkerNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+
+ /// structural element pattern
+ case SVGTokenPattern:
+ {
+ /// new node for pattern
+ mpTarget = new SvgPatternNode(maDocument, mpTarget);
+ mpTarget->parseAttributes(xAttribs);
+ break;
+ }
+
+ default:
+ {
+ /// invalid token, ignore
+#ifdef DBG_UTIL
+ myAssert(
+ rtl::OUString::createFromAscii("Unknown Base SvgToken <") +
+ aName +
+ rtl::OUString::createFromAscii("> (!)"));
+#endif
+ break;
+ }
+ }
+ }
+ }
+
+ void SvgDocHdl::endElement( const ::rtl::OUString& aName ) throw (xml::sax::SAXException, uno::RuntimeException)
+ {
+ if(aName.getLength())
+ {
+ const SVGToken aSVGToken(StrToSVGToken(aName));
+ SvgNode* pWhitespaceCheck(SVGTokenText == aSVGToken ? mpTarget : 0);
+
+ switch(aSVGToken)
+ {
+ /// valid tokens for which a new one was created
+
+ /// structural elements
+ case SVGTokenDefs:
+ case SVGTokenG:
+ case SVGTokenSvg:
+ case SVGTokenSymbol:
+ case SVGTokenUse:
+
+ /// shape elements
+ case SVGTokenCircle:
+ case SVGTokenEllipse:
+ case SVGTokenLine:
+ case SVGTokenPath:
+ case SVGTokenPolygon:
+ case SVGTokenPolyline:
+ case SVGTokenRect:
+ case SVGTokenImage:
+
+ /// gradients
+ case SVGTokenLinearGradient:
+ case SVGTokenRadialGradient:
+
+ /// gradient stops
+ case SVGTokenStop:
+
+ /// text
+ case SVGTokenText:
+ case SVGTokenTspan:
+ case SVGTokenTextPath:
+ case SVGTokenTref:
+
+ /// styles (as stylesheets)
+ case SVGTokenStyle:
+
+ /// structural elements clip-path and mask
+ case SVGTokenClipPathNode:
+ case SVGTokenMask:
+
+ /// structural element marker
+ case SVGTokenMarker:
+
+ /// structural element pattern
+ case SVGTokenPattern:
+
+ /// content handling after parsing
+ {
+ if(mpTarget)
+ {
+ if(!mpTarget->getParent())
+ {
+ // last element closing, save this tree
+ maDocument.appendNode(mpTarget);
+ }
+
+ mpTarget = const_cast< SvgNode* >(mpTarget->getParent());
+ }
+ else
+ {
+ OSL_ENSURE(false, "Closing token, but no context (!)");
+ }
+ break;
+ }
+ default:
+ {
+ /// invalid token, ignore
+ }
+ }
+
+ if(pWhitespaceCheck)
+ {
+ // cleanup read strings
+ whiteSpaceHandling(pWhitespaceCheck, 0);
+ }
+ }
+ }
+
+ void SvgDocHdl::characters( const ::rtl::OUString& aChars ) throw (xml::sax::SAXException, uno::RuntimeException)
+ {
+ if(mpTarget)
+ {
+ const sal_uInt32 nLength(aChars.getLength());
+
+ if(nLength &&
+ (SVGTokenText == mpTarget->getType() ||
+ SVGTokenTspan == mpTarget->getType() ||
+ SVGTokenTextPath == mpTarget->getType() ||
+ SVGTokenStyle == mpTarget->getType()))
+ {
+ switch(mpTarget->getType())
+ {
+ case SVGTokenText:
+ case SVGTokenTspan:
+ case SVGTokenTextPath:
+ {
+ const SvgNodeVector& rChilds = mpTarget->getChildren();
+ SvgCharacterNode* pTarget = 0;
+
+ if(rChilds.size())
+ {
+ pTarget = dynamic_cast< SvgCharacterNode* >(rChilds[rChilds.size() - 1]);
+ }
+
+ if(pTarget)
+ {
+ // concatenate to current character span
+ pTarget->concatenate(aChars);
+ }
+ else
+ {
+ // add character span as simplified tspan (no arguments)
+ // as direct child of SvgTextNode/SvgTspanNode/SvgTextPathNode
+ new SvgCharacterNode(maDocument, mpTarget, aChars);
+ }
+ break;
+ }
+ case SVGTokenStyle:
+ {
+ SvgStyleNode& rSvgStyleNode = static_cast< SvgStyleNode& >(*mpTarget);
+
+ if(rSvgStyleNode.isTextCss())
+ {
+ // need to interpret css styles and remember them as StyleSheets
+ const ::rtl::OUString aTrimmedChars(aChars.trim());
+
+ if(aTrimmedChars.getLength())
+ {
+ rSvgStyleNode.addCssStyleSheet(aTrimmedChars);
+ }
+ }
+ break;
+ }
+ default:
+ {
+ // characters not used by a known node
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ void SvgDocHdl::ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (xml::sax::SAXException, uno::RuntimeException)
+ {
+ }
+
+ void SvgDocHdl::processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (xml::sax::SAXException, uno::RuntimeException)
+ {
+ }
+
+ void SvgDocHdl::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& xLocator ) throw (xml::sax::SAXException, uno::RuntimeException)
+ {
+ }
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgellipsenode.cxx b/svgio/source/svgreader/svgellipsenode.cxx
new file mode 100644
index 000000000000..7eee1b9cedb2
--- /dev/null
+++ b/svgio/source/svgreader/svgellipsenode.cxx
@@ -0,0 +1,169 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgellipsenode.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgEllipseNode::SvgEllipseNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenEllipse, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ maCx(0),
+ maCy(0),
+ maRx(0),
+ maRy(0),
+ mpaTransform(0)
+ {
+ }
+
+ SvgEllipseNode::~SvgEllipseNode()
+ {
+ if(mpaTransform) delete mpaTransform;
+ }
+
+ const SvgStyleAttributes* SvgEllipseNode::getSvgStyleAttributes() const
+ {
+ static rtl::OUString aClassStr(rtl::OUString::createFromAscii("ellipse"));
+ maSvgStyleAttributes.checkForCssStyle(aClassStr);
+
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgEllipseNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenCx:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setCx(aNum);
+ }
+ break;
+ }
+ case SVGTokenCy:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setCy(aNum);
+ }
+ break;
+ }
+ case SVGTokenRx:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setRx(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenRy:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setRy(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenTransform:
+ {
+ const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
+
+ if(!aMatrix.isIdentity())
+ {
+ setTransform(&aMatrix);
+ }
+ break;
+ }
+ }
+ }
+
+ void SvgEllipseNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
+ {
+ const SvgStyleAttributes* pStyle = getSvgStyleAttributes();
+
+ if(pStyle && getRx().isSet() && getRy().isSet())
+ {
+ const double fRx(getRx().solve(*this, xcoordinate));
+ const double fRy(getRy().solve(*this, ycoordinate));
+
+ if(fRx > 0.0 && fRy > 0.0)
+ {
+ const basegfx::B2DPolygon aPath(
+ basegfx::tools::createPolygonFromEllipse(
+ basegfx::B2DPoint(
+ getCx().isSet() ? getCx().solve(*this, xcoordinate) : 0.0,
+ getCy().isSet() ? getCy().solve(*this, ycoordinate) : 0.0),
+ fRx, fRy));
+
+ drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
+
+ pStyle->add_path(basegfx::B2DPolyPolygon(aPath), aNewTarget);
+
+ if(aNewTarget.hasElements())
+ {
+ pStyle->add_postProcess(rTarget, aNewTarget, getTransform());
+ }
+ }
+ }
+ }
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svggnode.cxx b/svgio/source/svgreader/svggnode.cxx
new file mode 100644
index 000000000000..03b49c837e5a
--- /dev/null
+++ b/svgio/source/svgreader/svggnode.cxx
@@ -0,0 +1,114 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svggnode.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgGNode::SvgGNode(
+ SVGToken aType,
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(aType, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ mpaTransform(0)
+ {
+ OSL_ENSURE(aType == SVGTokenDefs || aType == SVGTokenG, "SvgGNode should ony be used for Group and Defs (!)");
+ }
+
+ SvgGNode::~SvgGNode()
+ {
+ if(mpaTransform) delete mpaTransform;
+ }
+
+ const SvgStyleAttributes* SvgGNode::getSvgStyleAttributes() const
+ {
+ static rtl::OUString aClassStr(rtl::OUString::createFromAscii("g"));
+ maSvgStyleAttributes.checkForCssStyle(aClassStr);
+
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgGNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenTransform:
+ {
+ const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
+
+ if(!aMatrix.isIdentity())
+ {
+ setTransform(&aMatrix);
+ }
+ break;
+ }
+ }
+ }
+
+ void SvgGNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
+ {
+ const SvgStyleAttributes* pStyle = getSvgStyleAttributes();
+
+ if(pStyle)
+ {
+ const double fOpacity(pStyle->getOpacity().getNumber());
+
+ if(fOpacity > 0.0)
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aContent;
+
+ // decompose childs
+ SvgNode::decomposeSvgNode(aContent, bReferenced);
+
+ if(aContent.hasElements())
+ {
+ pStyle->add_postProcess(rTarget, aContent, getTransform());
+ }
+ }
+ }
+ }
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svggradientnode.cxx b/svgio/source/svgreader/svggradientnode.cxx
new file mode 100644
index 000000000000..c5a535250b74
--- /dev/null
+++ b/svgio/source/svgreader/svggradientnode.cxx
@@ -0,0 +1,507 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svggradientnode.hxx>
+#include <svgio/svgreader/svgdocument.hxx>
+#include <svgio/svgreader/svggradientstopnode.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ void SvgGradientNode::tryToFindLink()
+ {
+ if(!mpXLink && maXLink.getLength())
+ {
+ mpXLink = dynamic_cast< const SvgGradientNode* >(getDocument().findSvgNodeById(maXLink));
+ }
+ }
+
+ SvgGradientNode::SvgGradientNode(
+ SVGToken aType,
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(aType, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ maX1(),
+ maY1(),
+ maX2(),
+ maY2(),
+ maCx(),
+ maCy(),
+ maR(),
+ maFx(),
+ maFy(),
+ maGradientUnits(objectBoundingBox),
+ maSpreadMethod(drawinglayer::primitive2d::Spread_pad),
+ mpaGradientTransform(0),
+ maXLink(),
+ mpXLink(0)
+ {
+ }
+
+ SvgGradientNode::~SvgGradientNode()
+ {
+ if(mpaGradientTransform) delete mpaGradientTransform;
+ // do NOT delete mpXLink, it's only referenced, not owned
+ }
+
+ const SvgStyleAttributes* SvgGradientNode::getSvgStyleAttributes() const
+ {
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgGradientNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenX1:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setX1(aNum);
+ }
+ break;
+ }
+ case SVGTokenY1:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setY1(aNum);
+ }
+ break;
+ }
+ case SVGTokenX2:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setX2(aNum);
+ }
+ break;
+ }
+ case SVGTokenY2:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setY2(aNum);
+ }
+ break;
+ }
+ case SVGTokenCx:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setCx(aNum);
+ }
+ break;
+ }
+ case SVGTokenCy:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setCy(aNum);
+ }
+ break;
+ }
+ case SVGTokenFx:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setFx(aNum);
+ }
+ break;
+ }
+ case SVGTokenFy:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setFy(aNum);
+ }
+ break;
+ }
+ case SVGTokenR:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setR(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenGradientUnits:
+ {
+ if(aContent.getLength())
+ {
+ if(aContent.match(commonStrings::aStrUserSpaceOnUse, 0))
+ {
+ setGradientUnits(userSpaceOnUse);
+ }
+ else if(aContent.match(commonStrings::aStrObjectBoundingBox, 0))
+ {
+ setGradientUnits(objectBoundingBox);
+ }
+ }
+ break;
+ }
+ case SVGTokenSpreadMethod:
+ {
+ if(aContent.getLength())
+ {
+ static rtl::OUString aStrPad(rtl::OUString::createFromAscii("pad"));
+ static rtl::OUString aStrReflect(rtl::OUString::createFromAscii("reflect"));
+ static rtl::OUString aStrRepeat(rtl::OUString::createFromAscii("repeat"));
+
+ if(aContent.match(aStrPad, 0))
+ {
+ setSpreadMethod(drawinglayer::primitive2d::Spread_pad);
+ }
+ else if(aContent.match(aStrReflect, 0))
+ {
+ setSpreadMethod(drawinglayer::primitive2d::Spread_reflect);
+ }
+ else if(aContent.match(aStrRepeat, 0))
+ {
+ setSpreadMethod(drawinglayer::primitive2d::Spread_repeat);
+ }
+ }
+ break;
+ }
+ case SVGTokenGradientTransform:
+ {
+ const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
+
+ if(!aMatrix.isIdentity())
+ {
+ setGradientTransform(&aMatrix);
+ }
+ break;
+ }
+ case SVGTokenXlinkHref:
+ {
+ const sal_Int32 nLen(aContent.getLength());
+
+ if(nLen && sal_Unicode('#') == aContent[0])
+ {
+ maXLink = aContent.copy(1);
+ tryToFindLink();
+ }
+ break;
+ }
+ }
+ }
+
+ void SvgGradientNode::collectGradientEntries(drawinglayer::primitive2d::SvgGradientEntryVector& aVector) const
+ {
+ if(getChildren().empty())
+ {
+ const_cast< SvgGradientNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ mpXLink->collectGradientEntries(aVector);
+ }
+ }
+ else
+ {
+ const sal_uInt32 nCount(getChildren().size());
+
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ const SvgGradientStopNode* pCandidate = dynamic_cast< const SvgGradientStopNode* >(getChildren()[a]);
+
+ if(pCandidate)
+ {
+ const SvgStyleAttributes* pStyle = pCandidate->getSvgStyleAttributes();
+
+ if(pStyle)
+ {
+ const SvgNumber aOffset(pCandidate->getOffset());
+ double fOffset(0.0);
+
+ if(Unit_percent == aOffset.getUnit())
+ {
+ // percent is not relative to distances in ColorStop context, solve locally
+ fOffset = aOffset.getNumber() * 0.01;
+ }
+ else
+ {
+ fOffset = aOffset.solve(*this);
+ }
+
+ if(fOffset < 0.0)
+ {
+ OSL_ENSURE(false, "OOps, SvgGradientStopNode with offset out of range (!)");
+ fOffset = 0.0;
+ }
+ else if(fOffset > 1.0)
+ {
+ OSL_ENSURE(false, "OOps, SvgGradientStopNode with offset out of range (!)");
+ fOffset = 1.0;
+ }
+
+ aVector.push_back(
+ drawinglayer::primitive2d::SvgGradientEntry(
+ fOffset,
+ pStyle->getStopColor(),
+ pStyle->getStopOpacity().solve(*this)));
+ }
+ else
+ {
+ OSL_ENSURE(false, "OOps, SvgGradientStopNode without Style (!)");
+ }
+ }
+ }
+ }
+ }
+
+ const SvgNumber SvgGradientNode::getX1() const
+ {
+ if(maX1.isSet())
+ {
+ return maX1;
+ }
+
+ const_cast< SvgGradientNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getX1();
+ }
+
+ // default is 0%
+ return SvgNumber(0.0, Unit_percent);
+ }
+
+ const SvgNumber SvgGradientNode::getY1() const
+ {
+ if(maY1.isSet())
+ {
+ return maY1;
+ }
+
+ const_cast< SvgGradientNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getY1();
+ }
+
+ // default is 0%
+ return SvgNumber(0.0, Unit_percent);
+ }
+
+ const SvgNumber SvgGradientNode::getX2() const
+ {
+ if(maX2.isSet())
+ {
+ return maX2;
+ }
+
+ const_cast< SvgGradientNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getX2();
+ }
+
+ // default is 100%
+ return SvgNumber(100.0, Unit_percent);
+ }
+
+ const SvgNumber SvgGradientNode::getY2() const
+ {
+ if(maY2.isSet())
+ {
+ return maY2;
+ }
+
+ const_cast< SvgGradientNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getY2();
+ }
+
+ // default is 0%
+ return SvgNumber(0.0, Unit_percent);
+ }
+
+ const SvgNumber SvgGradientNode::getCx() const
+ {
+ if(maCx.isSet())
+ {
+ return maCx;
+ }
+
+ const_cast< SvgGradientNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getCx();
+ }
+
+ // default is 50%
+ return SvgNumber(50.0, Unit_percent);
+ }
+
+ const SvgNumber SvgGradientNode::getCy() const
+ {
+ if(maCy.isSet())
+ {
+ return maCy;
+ }
+
+ const_cast< SvgGradientNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getCy();
+ }
+
+ // default is 50%
+ return SvgNumber(50.0, Unit_percent);
+ }
+
+ const SvgNumber SvgGradientNode::getR() const
+ {
+ if(maR.isSet())
+ {
+ return maR;
+ }
+
+ const_cast< SvgGradientNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getR();
+ }
+
+ // default is 50%
+ return SvgNumber(50.0, Unit_percent);
+ }
+
+ const SvgNumber* SvgGradientNode::getFx() const
+ {
+ if(maFx.isSet())
+ {
+ return &maFx;
+ }
+
+ const_cast< SvgGradientNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getFx();
+ }
+
+ return 0;
+ }
+
+ const SvgNumber* SvgGradientNode::getFy() const
+ {
+ if(maFy.isSet())
+ {
+ return &maFy;
+ }
+
+ const_cast< SvgGradientNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getFy();
+ }
+
+ return 0;
+ }
+
+ const basegfx::B2DHomMatrix* SvgGradientNode::getGradientTransform() const
+ {
+ if(mpaGradientTransform)
+ {
+ return mpaGradientTransform;
+ }
+
+ const_cast< SvgGradientNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getGradientTransform();
+ }
+
+ return 0;
+ }
+
+ void SvgGradientNode::setGradientTransform(const basegfx::B2DHomMatrix* pMatrix)
+ {
+ if(mpaGradientTransform)
+ {
+ delete mpaGradientTransform;
+ mpaGradientTransform = 0;
+ }
+
+ if(pMatrix)
+ {
+ mpaGradientTransform = new basegfx::B2DHomMatrix(*pMatrix);
+ }
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svggradientstopnode.cxx b/svgio/source/svgreader/svggradientstopnode.cxx
new file mode 100644
index 000000000000..b6da00e584bb
--- /dev/null
+++ b/svgio/source/svgreader/svggradientstopnode.cxx
@@ -0,0 +1,87 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svggradientstopnode.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgGradientStopNode::SvgGradientStopNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenStop, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ maOffset()
+ {
+ }
+
+ SvgGradientStopNode::~SvgGradientStopNode()
+ {
+ }
+
+ const SvgStyleAttributes* SvgGradientStopNode::getSvgStyleAttributes() const
+ {
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgGradientStopNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenOffset:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setOffset(aNum);
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgimagenode.cxx b/svgio/source/svgreader/svgimagenode.cxx
new file mode 100644
index 000000000000..5ee2e0d58e9e
--- /dev/null
+++ b/svgio/source/svgreader/svgimagenode.cxx
@@ -0,0 +1,353 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgimagenode.hxx>
+#include <svgio/svgreader/svgdocument.hxx>
+#include <sax/tools/converter.hxx>
+#include <tools/stream.hxx>
+#include <vcl/bitmapex.hxx>
+#include <svtools/filter.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <rtl/uri.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgImageNode::SvgImageNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenRect, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ maSvgAspectRatio(),
+ mpaTransform(0),
+ maX(0),
+ maY(0),
+ maWidth(0),
+ maHeight(0),
+ maXLink(),
+ maUrl(),
+ maMimeType(),
+ maData()
+ {
+ }
+
+ SvgImageNode::~SvgImageNode()
+ {
+ if(mpaTransform) delete mpaTransform;
+ }
+
+ const SvgStyleAttributes* SvgImageNode::getSvgStyleAttributes() const
+ {
+ static rtl::OUString aClassStr(rtl::OUString::createFromAscii("image"));
+ maSvgStyleAttributes.checkForCssStyle(aClassStr);
+
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgImageNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenPreserveAspectRatio:
+ {
+ setSvgAspectRatio(readSvgAspectRatio(aContent));
+ break;
+ }
+ case SVGTokenTransform:
+ {
+ const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
+
+ if(!aMatrix.isIdentity())
+ {
+ setTransform(&aMatrix);
+ }
+ break;
+ }
+ case SVGTokenX:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setX(aNum);
+ }
+ break;
+ }
+ case SVGTokenY:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setY(aNum);
+ }
+ break;
+ }
+ case SVGTokenWidth:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setWidth(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenHeight:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setHeight(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenXlinkHref:
+ {
+ const sal_Int32 nLen(aContent.getLength());
+
+ if(nLen)
+ {
+ readImageLink(aContent, maXLink, maUrl, maMimeType, maData);
+ }
+ break;
+ }
+ }
+ }
+
+ void extractFromGraphic(
+ const Graphic& rGraphic,
+ drawinglayer::primitive2d::Primitive2DSequence& rEmbedded,
+ basegfx::B2DRange& rViewBox,
+ BitmapEx& rBitmapEx)
+ {
+ if(GRAPHIC_BITMAP == rGraphic.GetType())
+ {
+ if(rGraphic.getSvgData().get())
+ {
+ // embedded Svg
+ rEmbedded = rGraphic.getSvgData()->getPrimitive2DSequence();
+
+ // fill aViewBox
+ rViewBox = rGraphic.getSvgData()->getRange();
+ }
+ else
+ {
+ // get bitmap
+ rBitmapEx = rGraphic.GetBitmapEx();
+ }
+ }
+ else
+ {
+ // evtl. convert to bitmap
+ rBitmapEx = rGraphic.GetBitmapEx();
+ }
+ }
+
+ void SvgImageNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
+ {
+ // get size range and create path
+ const SvgStyleAttributes* pStyle = getSvgStyleAttributes();
+
+ if(pStyle && getWidth().isSet() && getHeight().isSet())
+ {
+ const double fWidth(getWidth().solve(*this, xcoordinate));
+ const double fHeight(getHeight().solve(*this, ycoordinate));
+
+ if(fWidth > 0.0 && fHeight > 0.0)
+ {
+ BitmapEx aBitmapEx;
+ drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
+
+ // prepare Target and ViewBox for evtl. AspectRatio mappings
+ const double fX(getX().isSet() ? getX().solve(*this, xcoordinate) : 0.0);
+ const double fY(getY().isSet() ? getY().solve(*this, ycoordinate) : 0.0);
+ const basegfx::B2DRange aTarget(fX, fY, fX + fWidth, fY + fHeight);
+ basegfx::B2DRange aViewBox(aTarget);
+
+ if(maMimeType.getLength() && maData.getLength())
+ {
+ // use embedded base64 encoded data
+ ::com::sun::star::uno::Sequence< sal_Int8 > aPass;
+ ::sax::Converter::decodeBase64(aPass, maData);
+
+ if(aPass.hasElements())
+ {
+ SvMemoryStream aStream(aPass.getArray(), aPass.getLength(), STREAM_READ);
+ Graphic aGraphic;
+
+ if(GRFILTER_OK == GraphicFilter::GetGraphicFilter()->ImportGraphic(
+ aGraphic,
+ String(),
+ aStream))
+ {
+ extractFromGraphic(aGraphic, aNewTarget, aViewBox, aBitmapEx);
+ }
+ }
+ }
+ else if(maUrl.getLength())
+ {
+ const rtl::OUString& rPath = getDocument().getAbsolutePath();
+ const rtl::OUString aAbsUrl(rtl::Uri::convertRelToAbs(rPath, maUrl));
+
+ if(aAbsUrl.getLength())
+ {
+ SvFileStream aStream(aAbsUrl, STREAM_STD_READ);
+ Graphic aGraphic;
+
+ if(GRFILTER_OK == GraphicFilter::GetGraphicFilter()->ImportGraphic(
+ aGraphic,
+ aAbsUrl,
+ aStream))
+ {
+ extractFromGraphic(aGraphic, aNewTarget, aViewBox, aBitmapEx);
+ }
+ }
+ }
+ else if(maXLink.getLength())
+ {
+ const SvgNode* mpXLink = getDocument().findSvgNodeById(maXLink);
+
+ if(mpXLink)
+ {
+ mpXLink->decomposeSvgNode(aNewTarget, true);
+
+ if(aNewTarget.hasElements())
+ {
+ aViewBox = drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(
+ aNewTarget,
+ drawinglayer::geometry::ViewInformation2D());
+ }
+ }
+ }
+
+ if(!aBitmapEx.IsEmpty())
+ {
+ // create content from created bitmap
+ aNewTarget.realloc(1);
+ aNewTarget[0] = new drawinglayer::primitive2d::BitmapPrimitive2D(
+ aBitmapEx,
+ basegfx::B2DHomMatrix());
+
+ // fill aViewBox. No size set yet, use unit size
+ aViewBox = basegfx::B2DRange(0.0, 0.0, 1.0, 1.0);
+ }
+
+ if(aNewTarget.hasElements())
+ {
+ if(aTarget.equal(aViewBox))
+ {
+ // just add to rTarget
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewTarget);
+ }
+ else
+ {
+ // create mapping
+ const SvgAspectRatio& rRatio = getSvgAspectRatio();
+
+ if(rRatio.isSet())
+ {
+ // let mapping be created from SvgAspectRatio
+ const basegfx::B2DHomMatrix aEmbeddingTransform(rRatio.createMapping(aTarget, aViewBox));
+
+ if(!aEmbeddingTransform.isIdentity())
+ {
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ aEmbeddingTransform,
+ aNewTarget));
+
+ aNewTarget = drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1);
+ }
+
+ if(!rRatio.isMeetOrSlice())
+ {
+ // need to embed in MaskPrimitive2D to ensure clipping
+ const drawinglayer::primitive2d::Primitive2DReference xMask(
+ new drawinglayer::primitive2d::MaskPrimitive2D(
+ basegfx::B2DPolyPolygon(
+ basegfx::tools::createPolygonFromRect(aTarget)),
+ aNewTarget));
+
+ aNewTarget = drawinglayer::primitive2d::Primitive2DSequence(&xMask, 1);
+ }
+ }
+ else
+ {
+ // choose default mapping
+ const basegfx::B2DHomMatrix aEmbeddingTransform(rRatio.createLinearMapping(aTarget, aViewBox));
+
+ if(!aEmbeddingTransform.isIdentity())
+ {
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ aEmbeddingTransform,
+ aNewTarget));
+
+ aNewTarget = drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1);
+ }
+ }
+
+ // embed and add to rTarget, take local extra-transform into account
+ pStyle->add_postProcess(rTarget, aNewTarget, getTransform());
+ }
+ }
+ }
+ }
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svglinenode.cxx b/svgio/source/svgreader/svglinenode.cxx
new file mode 100644
index 000000000000..12f52061f919
--- /dev/null
+++ b/svgio/source/svgreader/svglinenode.cxx
@@ -0,0 +1,165 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svglinenode.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgLineNode::SvgLineNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenLine, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ maX1(0),
+ maY1(0),
+ maX2(0),
+ maY2(0),
+ mpaTransform(0)
+ {
+ }
+
+ SvgLineNode::~SvgLineNode()
+ {
+ if(mpaTransform) delete mpaTransform;
+ }
+
+ const SvgStyleAttributes* SvgLineNode::getSvgStyleAttributes() const
+ {
+ static rtl::OUString aClassStr(rtl::OUString::createFromAscii("line"));
+ maSvgStyleAttributes.checkForCssStyle(aClassStr);
+
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgLineNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenX1:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setX1(aNum);
+ }
+ break;
+ }
+ case SVGTokenY1:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setY1(aNum);
+ }
+ break;
+ }
+ case SVGTokenX2:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setX2(aNum);
+ }
+ break;
+ }
+ case SVGTokenY2:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setY2(aNum);
+ }
+ break;
+ }
+ case SVGTokenTransform:
+ {
+ const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
+
+ if(!aMatrix.isIdentity())
+ {
+ setTransform(&aMatrix);
+ }
+ break;
+ }
+ }
+ }
+
+ void SvgLineNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
+ {
+ const SvgStyleAttributes* pStyle = getSvgStyleAttributes();
+
+ if(pStyle)
+ {
+ const basegfx::B2DPoint X(
+ getX1().isSet() ? getX1().solve(*this, xcoordinate) : 0.0,
+ getY1().isSet() ? getY1().solve(*this, ycoordinate) : 0.0);
+ const basegfx::B2DPoint Y(
+ getX2().isSet() ? getX2().solve(*this, xcoordinate) : 0.0,
+ getY2().isSet() ? getY2().solve(*this, ycoordinate) : 0.0);
+
+ if(!X.equal(Y))
+ {
+ basegfx::B2DPolygon aPath;
+
+ aPath.append(X);
+ aPath.append(Y);
+
+ drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
+
+ pStyle->add_path(basegfx::B2DPolyPolygon(aPath), aNewTarget);
+
+ if(aNewTarget.hasElements())
+ {
+ pStyle->add_postProcess(rTarget, aNewTarget, getTransform());
+ }
+ }
+ }
+ }
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgmarkernode.cxx b/svgio/source/svgreader/svgmarkernode.cxx
new file mode 100755
index 000000000000..1e0342b44e15
--- /dev/null
+++ b/svgio/source/svgreader/svgmarkernode.cxx
@@ -0,0 +1,212 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgmarkernode.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgMarkerNode::SvgMarkerNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenMarker, rDocument, pParent),
+ aPrimitives(),
+ maSvgStyleAttributes(*this),
+ mpViewBox(0),
+ maSvgAspectRatio(),
+ maRefX(0),
+ maRefY(0),
+ maMarkerUnits(strokeWidth),
+ maMarkerWidth(3),
+ maMarkerHeight(3),
+ mfAngle(0.0),
+ mbOrientAuto(false)
+ {
+ }
+
+ SvgMarkerNode::~SvgMarkerNode()
+ {
+ if(mpViewBox) delete mpViewBox;
+ }
+
+ const SvgStyleAttributes* SvgMarkerNode::getSvgStyleAttributes() const
+ {
+ static rtl::OUString aClassStr(rtl::OUString::createFromAscii("marker"));
+ maSvgStyleAttributes.checkForCssStyle(aClassStr);
+
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgMarkerNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenViewBox:
+ {
+ const basegfx::B2DRange aRange(readViewBox(aContent, *this));
+
+ if(!aRange.isEmpty())
+ {
+ setViewBox(&aRange);
+ }
+ break;
+ }
+ case SVGTokenPreserveAspectRatio:
+ {
+ setSvgAspectRatio(readSvgAspectRatio(aContent));
+ break;
+ }
+ case SVGTokenRefX:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setRefX(aNum);
+ }
+ break;
+ }
+ case SVGTokenRefY:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setRefY(aNum);
+ }
+ break;
+ }
+ case SVGTokenMarkerUnits:
+ {
+ if(aContent.getLength())
+ {
+ static rtl::OUString aStrStrokeWidth(rtl::OUString::createFromAscii("strokeWidth"));
+
+ if(aContent.match(aStrStrokeWidth, 0))
+ {
+ setMarkerUnits(strokeWidth);
+ }
+ else if(aContent.match(commonStrings::aStrUserSpaceOnUse, 0))
+ {
+ setMarkerUnits(userSpaceOnUse);
+ }
+ }
+ break;
+ }
+ case SVGTokenMarkerWidth:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setMarkerWidth(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenMarkerHeight:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setMarkerHeight(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenOrient:
+ {
+ const sal_Int32 nLen(aContent.getLength());
+
+ if(nLen)
+ {
+ static rtl::OUString aStrAuto(rtl::OUString::createFromAscii("auto"));
+
+ if(aContent.match(aStrAuto, 0))
+ {
+ setOrientAuto(true);
+ }
+ else
+ {
+ sal_Int32 nPos(0);
+ double fAngle(0.0);
+
+ if(readAngle(aContent, nPos, fAngle, nLen))
+ {
+ setAngle(fAngle);
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ const drawinglayer::primitive2d::Primitive2DSequence& SvgMarkerNode::getMarkerPrimitives() const
+ {
+ if(!aPrimitives.hasElements())
+ {
+ decomposeSvgNode(const_cast< SvgMarkerNode* >(this)->aPrimitives, true);
+ }
+
+ return aPrimitives;
+ }
+
+ const basegfx::B2DRange* SvgMarkerNode::getCurrentViewPort() const
+ {
+ if(getViewBox())
+ {
+ return getViewBox();
+ }
+ else
+ {
+ return SvgNode::getCurrentViewPort();
+ }
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgmasknode.cxx b/svgio/source/svgreader/svgmasknode.cxx
new file mode 100755
index 000000000000..45eeebab92e3
--- /dev/null
+++ b/svgio/source/svgreader/svgmasknode.cxx
@@ -0,0 +1,317 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgmasknode.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/transparenceprimitive2d.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
+#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgMaskNode::SvgMaskNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenMask, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ maX(SvgNumber(-10.0, Unit_percent, true)),
+ maY(SvgNumber(-10.0, Unit_percent, true)),
+ maWidth(SvgNumber(120.0, Unit_percent, true)),
+ maHeight(SvgNumber(120.0, Unit_percent, true)),
+ mpaTransform(0),
+ maMaskUnits(objectBoundingBox),
+ maMaskContentUnits(userSpaceOnUse)
+ {
+ }
+
+ SvgMaskNode::~SvgMaskNode()
+ {
+ if(mpaTransform) delete mpaTransform;
+ }
+
+ const SvgStyleAttributes* SvgMaskNode::getSvgStyleAttributes() const
+ {
+ static rtl::OUString aClassStr(rtl::OUString::createFromAscii("mask"));
+ maSvgStyleAttributes.checkForCssStyle(aClassStr);
+
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgMaskNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenX:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setX(aNum);
+ }
+ break;
+ }
+ case SVGTokenY:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setY(aNum);
+ }
+ break;
+ }
+ case SVGTokenWidth:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setWidth(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenHeight:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setHeight(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenTransform:
+ {
+ const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
+
+ if(!aMatrix.isIdentity())
+ {
+ setTransform(&aMatrix);
+ }
+ break;
+ }
+ case SVGTokenMaskUnits:
+ {
+ if(aContent.getLength())
+ {
+ if(aContent.match(commonStrings::aStrUserSpaceOnUse, 0))
+ {
+ setMaskUnits(userSpaceOnUse);
+ }
+ else if(aContent.match(commonStrings::aStrObjectBoundingBox, 0))
+ {
+ setMaskUnits(objectBoundingBox);
+ }
+ }
+ break;
+ }
+ case SVGTokenMaskContentUnits:
+ {
+ if(aContent.getLength())
+ {
+ if(aContent.match(commonStrings::aStrUserSpaceOnUse, 0))
+ {
+ setMaskContentUnits(userSpaceOnUse);
+ }
+ else if(aContent.match(commonStrings::aStrObjectBoundingBox, 0))
+ {
+ setMaskContentUnits(objectBoundingBox);
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ void SvgMaskNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
+
+ // decompose childs
+ SvgNode::decomposeSvgNode(aNewTarget, bReferenced);
+
+ if(aNewTarget.hasElements())
+ {
+ if(getTransform())
+ {
+ // create embedding group element with transformation
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ *getTransform(),
+ aNewTarget));
+
+ aNewTarget = drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1);
+ }
+
+ // append to current target
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewTarget);
+ }
+ }
+
+ void SvgMaskNode::apply(drawinglayer::primitive2d::Primitive2DSequence& rTarget) const
+ {
+ if(rTarget.hasElements())
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aMaskTarget;
+
+ // get mask definition as primitives
+ decomposeSvgNode(aMaskTarget, true);
+
+ if(aMaskTarget.hasElements())
+ {
+ // get range of content to be masked
+ const basegfx::B2DRange aContentRange(
+ drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(
+ rTarget,
+ drawinglayer::geometry::ViewInformation2D()));
+ const double fContentWidth(aContentRange.getWidth());
+ const double fContentHeight(aContentRange.getHeight());
+
+ if(fContentWidth > 0.0 && fContentHeight > 0.0)
+ {
+ // create OffscreenBufferRange
+ basegfx::B2DRange aOffscreenBufferRange;
+
+ if(objectBoundingBox == getMaskUnits())
+ {
+ // fractions or percentages of the bounding box of the element to which the mask is applied
+ const double fX(Unit_percent == getX().getUnit() ? getX().getNumber() * 0.01 : getX().getNumber());
+ const double fY(Unit_percent == getY().getUnit() ? getY().getNumber() * 0.01 : getY().getNumber());
+ const double fW(Unit_percent == getWidth().getUnit() ? getWidth().getNumber() * 0.01 : getWidth().getNumber());
+ const double fH(Unit_percent == getHeight().getUnit() ? getHeight().getNumber() * 0.01 : getHeight().getNumber());
+
+ aOffscreenBufferRange = basegfx::B2DRange(
+ aContentRange.getMinX() + (fX * fContentWidth),
+ aContentRange.getMinY() + (fY * fContentHeight),
+ aContentRange.getMinX() + ((fX + fW) * fContentWidth),
+ aContentRange.getMinY() + ((fY + fH) * fContentHeight));
+ }
+ else
+ {
+ const double fX(getX().isSet() ? getX().solve(*this, xcoordinate) : 0.0);
+ const double fY(getY().isSet() ? getY().solve(*this, ycoordinate) : 0.0);
+
+ aOffscreenBufferRange = basegfx::B2DRange(
+ fX,
+ fY,
+ fX + (getWidth().isSet() ? getWidth().solve(*this, xcoordinate) : 0.0),
+ fY + (getHeight().isSet() ? getHeight().solve(*this, ycoordinate) : 0.0));
+ }
+
+ if(objectBoundingBox == getMaskContentUnits())
+ {
+ // mask is object-relative, embed in content transformation
+ const drawinglayer::primitive2d::Primitive2DReference xTransform(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ aContentRange.getRange(),
+ aContentRange.getMinimum()),
+ aMaskTarget));
+
+ aMaskTarget = drawinglayer::primitive2d::Primitive2DSequence(&xTransform, 1);
+ }
+
+ // embed content to a ModifiedColorPrimitive2D since the definitions
+ // how content is used as alpha is special for Svg
+ {
+ const drawinglayer::primitive2d::Primitive2DReference xInverseMask(
+ new drawinglayer::primitive2d::ModifiedColorPrimitive2D(
+ aMaskTarget,
+ basegfx::BColorModifier(
+ basegfx::BColor(0.0, 0.0, 0.0),
+ 0.5,
+ basegfx::BCOLORMODIFYMODE_LUMINANCE_TO_ALPHA)));
+
+ aMaskTarget = drawinglayer::primitive2d::Primitive2DSequence(&xInverseMask, 1);
+ }
+
+ // prepare new content
+ drawinglayer::primitive2d::Primitive2DReference xNewContent(
+ new drawinglayer::primitive2d::TransparencePrimitive2D(
+ rTarget,
+ aMaskTarget));
+
+ // output up to now is defined by aContentRange and mask is oriented
+ // relative to it. It is possible that aOffscreenBufferRange defines
+ // a smaller area. In that case, embed to a mask primitive
+ if(!aOffscreenBufferRange.isInside(aContentRange))
+ {
+ xNewContent = new drawinglayer::primitive2d::MaskPrimitive2D(
+ basegfx::B2DPolyPolygon(
+ basegfx::tools::createPolygonFromRect(
+ aOffscreenBufferRange)),
+ drawinglayer::primitive2d::Primitive2DSequence(&xNewContent, 1));
+ }
+
+ // redefine target. Use TransparencePrimitive2D with created mask
+ // geometry
+ rTarget = drawinglayer::primitive2d::Primitive2DSequence(&xNewContent, 1);
+ }
+ else
+ {
+ // content is geometrically empty
+ rTarget.realloc(0);
+ }
+ }
+ else
+ {
+ // An empty clipping path will completely clip away the element that had
+ // the clip-path property applied. (Svg spec)
+ rTarget.realloc(0);
+ }
+ }
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgnode.cxx b/svgio/source/svgreader/svgnode.cxx
new file mode 100644
index 000000000000..bcd802be6640
--- /dev/null
+++ b/svgio/source/svgreader/svgnode.cxx
@@ -0,0 +1,288 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgnode.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <svgio/svgreader/svgdocument.hxx>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ const SvgStyleAttributes* SvgNode::getSvgStyleAttributes() const
+ {
+ return 0;
+ }
+
+ SvgNode::SvgNode(
+ SVGToken aType,
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : maType(aType),
+ mrDocument(rDocument),
+ mpParent(pParent),
+ mpAlternativeParent(0),
+ maChildren(),
+ mpId(0),
+ mpClass(0),
+ maXmlSpace(XmlSpace_notset)
+ {
+ OSL_ENSURE(SVGTokenUnknown != maType, "SvgNode with unknown type created (!)");
+
+ if(pParent)
+ {
+ pParent->maChildren.push_back(this);
+ }
+ else
+ {
+#ifdef DBG_UTIL
+ if(SVGTokenSvg != getType())
+ {
+ OSL_ENSURE(false, "No parent for this node (!)");
+ }
+#endif
+ }
+ }
+
+ SvgNode::~SvgNode()
+ {
+ while(maChildren.size())
+ {
+ delete maChildren[maChildren.size() - 1];
+ maChildren.pop_back();
+ }
+
+ if(mpId) delete mpId;
+ if(mpClass) delete mpClass;
+ }
+
+ void SvgNode::parseAttributes(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttribs)
+ {
+ const sal_uInt32 nAttributes(xAttribs->getLength());
+
+ for(sal_uInt32 a(0); a < nAttributes; a++)
+ {
+ const ::rtl::OUString aTokenName(xAttribs->getNameByIndex(a));
+
+ parseAttribute(aTokenName, StrToSVGToken(aTokenName), xAttribs->getValueByIndex(a));
+ }
+ }
+
+ void SvgNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ switch(aSVGToken)
+ {
+ case SVGTokenId:
+ {
+ if(aContent.getLength())
+ {
+ setId(&aContent);
+ }
+ break;
+ }
+ case SVGTokenClass:
+ {
+ if(aContent.getLength())
+ {
+ setClass(&aContent);
+ }
+ break;
+ }
+ case SVGTokenXmlSpace:
+ {
+ if(aContent.getLength())
+ {
+ static rtl::OUString aStrDefault(rtl::OUString::createFromAscii("default"));
+ static rtl::OUString aStrPreserve(rtl::OUString::createFromAscii("preserve"));
+
+ if(aContent.match(aStrDefault))
+ {
+ setXmlSpace(XmlSpace_default);
+ }
+ else if(aContent.match(aStrPreserve))
+ {
+ setXmlSpace(XmlSpace_preserve);
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ void SvgNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
+ {
+ if(!bReferenced)
+ {
+ if(SVGTokenDefs == getType() ||
+ SVGTokenSymbol == getType() ||
+ SVGTokenClipPathNode == getType() ||
+ SVGTokenMask == getType() ||
+ SVGTokenMarker == getType() ||
+ SVGTokenPattern == getType())
+ {
+ // do not decompose defs or symbol nodes (these hold only style-like
+ // objects which may be used by referencing them) except when doing
+ // so controlled referenced
+
+ // also do not decompose ClipPaths and Masks. These should be embedded
+ // in a defs node (which gets not decomposed by itself), but you never
+ // know
+
+ // also not directly used are Markers and Patterns, only indirecty used
+ // by reference
+ return;
+ }
+ }
+
+ const SvgNodeVector& rChildren = getChildren();
+
+ if(!rChildren.empty())
+ {
+ const sal_uInt32 nCount(rChildren.size());
+
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ SvgNode* pCandidate = rChildren[a];
+
+ if(pCandidate)
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
+
+ pCandidate->decomposeSvgNode(aNewTarget, bReferenced);
+
+ if(aNewTarget.hasElements())
+ {
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewTarget);
+ }
+ }
+ else
+ {
+ OSL_ENSURE(false, "Null-Pointer in child node list (!)");
+ }
+ }
+ }
+ }
+
+ const basegfx::B2DRange* SvgNode::getCurrentViewPort() const
+ {
+ if(getParent())
+ {
+ return getParent()->getCurrentViewPort();
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ double SvgNode::getCurrentFontSize() const
+ {
+ if(getSvgStyleAttributes())
+ {
+ return getSvgStyleAttributes()->getFontSize().solve(*this, xcoordinate);
+ }
+ else if(getParent())
+ {
+ return getParent()->getCurrentFontSize();
+ }
+ else
+ {
+ return 0.0;
+ }
+ }
+
+ double SvgNode::getCurrentXHeight() const
+ {
+ if(getSvgStyleAttributes())
+ {
+ // for XHeight, use FontSize currently
+ return getSvgStyleAttributes()->getFontSize().solve(*this, ycoordinate);
+ }
+ else if(getParent())
+ {
+ return getParent()->getCurrentXHeight();
+ }
+ else
+ {
+ return 0.0;
+ }
+ }
+
+ void SvgNode::setId(const rtl::OUString* pfId)
+ {
+ if(mpId)
+ {
+ mrDocument.removeSvgNodeFromMapper(*mpId);
+ delete mpId;
+ mpId = 0;
+ }
+
+ if(pfId)
+ {
+ mpId = new rtl::OUString(*pfId);
+ mrDocument.addSvgNodeToMapper(*mpId, *this);
+ }
+ }
+
+ void SvgNode::setClass(const rtl::OUString* pfClass)
+ {
+ if(mpClass)
+ {
+ mrDocument.removeSvgNodeFromMapper(*mpClass);
+ delete mpClass;
+ mpClass = 0;
+ }
+
+ if(pfClass)
+ {
+ mpClass = new rtl::OUString(*pfClass);
+ mrDocument.addSvgNodeToMapper(*mpClass, *this);
+ }
+ }
+
+ XmlSpace SvgNode::getXmlSpace() const
+ {
+ if(maXmlSpace != XmlSpace_notset)
+ {
+ return maXmlSpace;
+ }
+
+ if(getParent())
+ {
+ return getParent()->getXmlSpace();
+ }
+
+ // default is XmlSpace_default
+ return XmlSpace_default;
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgpaint.cxx b/svgio/source/svgreader/svgpaint.cxx
new file mode 100644
index 000000000000..18ef1343716a
--- /dev/null
+++ b/svgio/source/svgreader/svgpaint.cxx
@@ -0,0 +1,37 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgpaint.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgpathnode.cxx b/svgio/source/svgreader/svgpathnode.cxx
new file mode 100644
index 000000000000..7027f29f1a79
--- /dev/null
+++ b/svgio/source/svgreader/svgpathnode.cxx
@@ -0,0 +1,132 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgpathnode.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgPathNode::SvgPathNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenPath, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ mpPolyPolygon(0),
+ mpaTransform(0),
+ maPathLength()
+ {
+ }
+
+ SvgPathNode::~SvgPathNode()
+ {
+ if(mpPolyPolygon) delete mpPolyPolygon;
+ if(mpaTransform) delete mpaTransform;
+ }
+
+ const SvgStyleAttributes* SvgPathNode::getSvgStyleAttributes() const
+ {
+ static rtl::OUString aClassStr(rtl::OUString::createFromAscii("path"));
+ maSvgStyleAttributes.checkForCssStyle(aClassStr);
+
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgPathNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenD:
+ {
+ basegfx::B2DPolyPolygon aPath;
+
+ if(basegfx::tools::importFromSvgD(aPath, aContent))
+ {
+ if(aPath.count())
+ {
+ setPath(&aPath);
+ }
+ }
+ break;
+ }
+ case SVGTokenTransform:
+ {
+ const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
+
+ if(!aMatrix.isIdentity())
+ {
+ setTransform(&aMatrix);
+ }
+ break;
+ }
+ case SVGTokenPathLength:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setPathLength(aNum);
+ }
+ break;
+ }
+ }
+ }
+
+ void SvgPathNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
+ {
+ // fill and/or stroke needed, also a path
+ const SvgStyleAttributes* pStyle = getSvgStyleAttributes();
+
+ if(pStyle && getPath())
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
+
+ pStyle->add_path(*getPath(), aNewTarget);
+
+ if(aNewTarget.hasElements())
+ {
+ pStyle->add_postProcess(rTarget, aNewTarget, getTransform());
+ }
+ }
+ }
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgpatternnode.cxx b/svgio/source/svgreader/svgpatternnode.cxx
new file mode 100755
index 000000000000..e7df8b62344f
--- /dev/null
+++ b/svgio/source/svgreader/svgpatternnode.cxx
@@ -0,0 +1,462 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgpatternnode.hxx>
+#include <svgio/svgreader/svgdocument.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ void SvgPatternNode::tryToFindLink()
+ {
+ if(!mpXLink && maXLink.getLength())
+ {
+ mpXLink = dynamic_cast< const SvgPatternNode* >(getDocument().findSvgNodeById(maXLink));
+ }
+ }
+
+ SvgPatternNode::SvgPatternNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenPattern, rDocument, pParent),
+ aPrimitives(),
+ maSvgStyleAttributes(*this),
+ mpViewBox(0),
+ maSvgAspectRatio(),
+ maX(),
+ maY(),
+ maWidth(),
+ maHeight(),
+ mpPatternUnits(0),
+ mpPatternContentUnits(0),
+ mpaPatternTransform(0),
+ maXLink(),
+ mpXLink(0)
+ {
+ }
+
+ SvgPatternNode::~SvgPatternNode()
+ {
+ if(mpViewBox) delete mpViewBox;
+ if(mpaPatternTransform) delete mpaPatternTransform;
+ if(mpPatternUnits) delete mpPatternUnits;
+ if(mpPatternContentUnits) delete mpPatternContentUnits;
+ }
+
+ const SvgStyleAttributes* SvgPatternNode::getSvgStyleAttributes() const
+ {
+ static rtl::OUString aClassStr(rtl::OUString::createFromAscii("pattern"));
+ maSvgStyleAttributes.checkForCssStyle(aClassStr);
+
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgPatternNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenViewBox:
+ {
+ const basegfx::B2DRange aRange(readViewBox(aContent, *this));
+
+ if(!aRange.isEmpty())
+ {
+ setViewBox(&aRange);
+ }
+ break;
+ }
+ case SVGTokenPreserveAspectRatio:
+ {
+ setSvgAspectRatio(readSvgAspectRatio(aContent));
+ break;
+ }
+ case SVGTokenX:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setX(aNum);
+ }
+ break;
+ }
+ case SVGTokenY:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setY(aNum);
+ }
+ break;
+ }
+ case SVGTokenWidth:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setWidth(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenHeight:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setHeight(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenPatternUnits:
+ {
+ if(aContent.getLength())
+ {
+ if(aContent.match(commonStrings::aStrUserSpaceOnUse, 0))
+ {
+ setPatternUnits(userSpaceOnUse);
+ }
+ else if(aContent.match(commonStrings::aStrObjectBoundingBox, 0))
+ {
+ setPatternUnits(objectBoundingBox);
+ }
+ }
+ break;
+ }
+ case SVGTokenPatternContentUnits:
+ {
+ if(aContent.getLength())
+ {
+ if(aContent.match(commonStrings::aStrUserSpaceOnUse, 0))
+ {
+ setPatternContentUnits(userSpaceOnUse);
+ }
+ else if(aContent.match(commonStrings::aStrObjectBoundingBox, 0))
+ {
+ setPatternContentUnits(objectBoundingBox);
+ }
+ }
+ break;
+ }
+ case SVGTokenPatternTransform:
+ {
+ const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
+
+ if(!aMatrix.isIdentity())
+ {
+ setPatternTransform(&aMatrix);
+ }
+ break;
+ }
+ case SVGTokenXlinkHref:
+ {
+ const sal_Int32 nLen(aContent.getLength());
+
+ if(nLen && sal_Unicode('#') == aContent[0])
+ {
+ maXLink = aContent.copy(1);
+ tryToFindLink();
+ }
+ break;
+ }
+ }
+ }
+
+ void SvgPatternNode::getValuesRelative(double& rfX, double& rfY, double& rfW, double& rfH, const basegfx::B2DRange& rGeoRange, SvgNode& rUser) const
+ {
+ double fTargetWidth(rGeoRange.getWidth());
+ double fTargetHeight(rGeoRange.getHeight());
+
+ if(fTargetWidth > 0.0 && fTargetHeight > 0.0)
+ {
+ const SvgUnits aPatternUnits(getPatternUnits() ? *getPatternUnits() : objectBoundingBox);
+
+ if(objectBoundingBox == aPatternUnits)
+ {
+ rfW = (getWidth().isSet()) ? getWidth().getNumber() : 0.0;
+ rfH = (getHeight().isSet()) ? getHeight().getNumber() : 0.0;
+
+ if(Unit_percent == getWidth().getUnit())
+ {
+ rfW *= 0.01;
+ }
+
+ if(Unit_percent == getHeight().getUnit())
+ {
+ rfH *= 0.01;
+ }
+ }
+ else
+ {
+ rfW = (getWidth().isSet()) ? getWidth().solve(rUser, xcoordinate) : 0.0;
+ rfH = (getHeight().isSet()) ? getHeight().solve(rUser, ycoordinate) : 0.0;
+
+ // make relative to rGeoRange
+ rfW /= fTargetWidth;
+ rfH /= fTargetHeight;
+ }
+
+ if(rfW > 0.0 && rfH > 0.0)
+ {
+ if(objectBoundingBox == aPatternUnits)
+ {
+ rfX = (getX().isSet()) ? getX().getNumber() : 0.0;
+ rfY = (getY().isSet()) ? getY().getNumber() : 0.0;
+
+ if(Unit_percent == getX().getUnit())
+ {
+ rfX *= 0.01;
+ }
+
+ if(Unit_percent == getY().getUnit())
+ {
+ rfY *= 0.01;
+ }
+ }
+ else
+ {
+ rfX = (getX().isSet()) ? getX().solve(rUser, xcoordinate) : 0.0;
+ rfY = (getY().isSet()) ? getY().solve(rUser, ycoordinate) : 0.0;
+
+ // make relative to rGeoRange
+ rfX = (rfX - rGeoRange.getMinX()) / fTargetWidth;
+ rfY = (rfY - rGeoRange.getMinY()) / fTargetHeight;
+ }
+ }
+ }
+ }
+
+ const drawinglayer::primitive2d::Primitive2DSequence& SvgPatternNode::getPatternPrimitives() const
+ {
+ if(!aPrimitives.hasElements())
+ {
+ decomposeSvgNode(const_cast< SvgPatternNode* >(this)->aPrimitives, true);
+ }
+
+ if(!aPrimitives.hasElements() && maXLink.getLength())
+ {
+ const_cast< SvgPatternNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getPatternPrimitives();
+ }
+ }
+
+ return aPrimitives;
+ }
+
+ const basegfx::B2DRange* SvgPatternNode::getCurrentViewPort() const
+ {
+ if(getViewBox())
+ {
+ return getViewBox();
+ }
+ else
+ {
+ return SvgNode::getCurrentViewPort();
+ }
+ }
+
+ const basegfx::B2DRange* SvgPatternNode::getViewBox() const
+ {
+ if(mpViewBox)
+ {
+ return mpViewBox;
+ }
+
+ const_cast< SvgPatternNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getViewBox();
+ }
+
+ return 0;
+ }
+
+ const SvgAspectRatio& SvgPatternNode::getSvgAspectRatio() const
+ {
+ if(maSvgAspectRatio.isSet())
+ {
+ return maSvgAspectRatio;
+ }
+
+ const_cast< SvgPatternNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getSvgAspectRatio();
+ }
+
+ return maSvgAspectRatio;
+ }
+
+ const SvgNumber& SvgPatternNode::getX() const
+ {
+ if(maX.isSet())
+ {
+ return maX;
+ }
+
+ const_cast< SvgPatternNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getX();
+ }
+
+ return maX;
+ }
+
+ const SvgNumber& SvgPatternNode::getY() const
+ {
+ if(maY.isSet())
+ {
+ return maY;
+ }
+
+ const_cast< SvgPatternNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getY();
+ }
+
+ return maY;
+ }
+
+ const SvgNumber& SvgPatternNode::getWidth() const
+ {
+ if(maWidth.isSet())
+ {
+ return maWidth;
+ }
+
+ const_cast< SvgPatternNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getWidth();
+ }
+
+ return maWidth;
+ }
+
+ const SvgNumber& SvgPatternNode::getHeight() const
+ {
+ if(maHeight.isSet())
+ {
+ return maHeight;
+ }
+
+ const_cast< SvgPatternNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getHeight();
+ }
+
+ return maHeight;
+ }
+
+ const SvgUnits* SvgPatternNode::getPatternUnits() const
+ {
+ if(mpPatternUnits)
+ {
+ return mpPatternUnits;
+ }
+
+ const_cast< SvgPatternNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getPatternUnits();
+ }
+
+ return 0;
+ }
+
+ const SvgUnits* SvgPatternNode::getPatternContentUnits() const
+ {
+ if(mpPatternContentUnits)
+ {
+ return mpPatternContentUnits;
+ }
+
+ const_cast< SvgPatternNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getPatternContentUnits();
+ }
+
+ return 0;
+ }
+
+ const basegfx::B2DHomMatrix* SvgPatternNode::getPatternTransform() const
+ {
+ if(mpaPatternTransform)
+ {
+ return mpaPatternTransform;
+ }
+
+ const_cast< SvgPatternNode* >(this)->tryToFindLink();
+
+ if(mpXLink)
+ {
+ return mpXLink->getPatternTransform();
+ }
+
+ return 0;
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgpolynode.cxx b/svgio/source/svgreader/svgpolynode.cxx
new file mode 100644
index 000000000000..2b3c991a8593
--- /dev/null
+++ b/svgio/source/svgreader/svgpolynode.cxx
@@ -0,0 +1,128 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgpolynode.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgPolyNode::SvgPolyNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent,
+ bool bIsPolyline)
+ : SvgNode(SVGTokenPolygon, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ mpPolygon(0),
+ mpaTransform(0),
+ mbIsPolyline(bIsPolyline)
+ {
+ }
+
+ SvgPolyNode::~SvgPolyNode()
+ {
+ if(mpaTransform) delete mpaTransform;
+ if(mpPolygon) delete mpPolygon;
+ }
+
+ const SvgStyleAttributes* SvgPolyNode::getSvgStyleAttributes() const
+ {
+ static rtl::OUString aClassStr(rtl::OUString::createFromAscii("poly"));
+ maSvgStyleAttributes.checkForCssStyle(aClassStr);
+
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgPolyNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenPoints:
+ {
+ basegfx::B2DPolygon aPath;
+
+ if(basegfx::tools::importFromSvgPoints(aPath, aContent))
+ {
+ if(aPath.count())
+ {
+ if(!isPolyline())
+ {
+ aPath.setClosed(true);
+ }
+
+ setPolygon(&aPath);
+ }
+ }
+ break;
+ }
+ case SVGTokenTransform:
+ {
+ const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
+
+ if(!aMatrix.isIdentity())
+ {
+ setTransform(&aMatrix);
+ }
+ break;
+ }
+ }
+ }
+
+ void SvgPolyNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
+ {
+ const SvgStyleAttributes* pStyle = getSvgStyleAttributes();
+
+ if(pStyle && getPolygon())
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
+
+ pStyle->add_path(basegfx::B2DPolyPolygon(*getPolygon()), aNewTarget);
+
+ if(aNewTarget.hasElements())
+ {
+ pStyle->add_postProcess(rTarget, aNewTarget, getTransform());
+ }
+ }
+ }
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgrectnode.cxx b/svgio/source/svgreader/svgrectnode.cxx
new file mode 100644
index 000000000000..8ad8eadf8300
--- /dev/null
+++ b/svgio/source/svgreader/svgrectnode.cxx
@@ -0,0 +1,226 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgrectnode.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgRectNode::SvgRectNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenRect, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ maX(0),
+ maY(0),
+ maWidth(0),
+ maHeight(0),
+ maRx(0),
+ maRy(0),
+ mpaTransform(0)
+ {
+ }
+
+ SvgRectNode::~SvgRectNode()
+ {
+ if(mpaTransform) delete mpaTransform;
+ }
+
+ const SvgStyleAttributes* SvgRectNode::getSvgStyleAttributes() const
+ {
+ static rtl::OUString aClassStr(rtl::OUString::createFromAscii("rect"));
+ maSvgStyleAttributes.checkForCssStyle(aClassStr);
+
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgRectNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenX:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setX(aNum);
+ }
+ break;
+ }
+ case SVGTokenY:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setY(aNum);
+ }
+ break;
+ }
+ case SVGTokenWidth:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setWidth(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenHeight:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setHeight(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenRx:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setRx(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenRy:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setRy(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenTransform:
+ {
+ const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
+
+ if(!aMatrix.isIdentity())
+ {
+ setTransform(&aMatrix);
+ }
+ break;
+ }
+ }
+ }
+
+ void SvgRectNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
+ {
+ // get size range and create path
+ const SvgStyleAttributes* pStyle = getSvgStyleAttributes();
+
+ if(pStyle && getWidth().isSet() && getHeight().isSet())
+ {
+ const double fWidth(getWidth().solve(*this, xcoordinate));
+ const double fHeight(getHeight().solve(*this, ycoordinate));
+
+ if(fWidth > 0.0 && fHeight > 0.0)
+ {
+ const double fX(getX().isSet() ? getX().solve(*this, xcoordinate) : 0.0);
+ const double fY(getY().isSet() ? getY().solve(*this, ycoordinate) : 0.0);
+ const basegfx::B2DRange aRange(fX, fY, fX + fWidth, fY + fHeight);
+ basegfx::B2DPolygon aPath;
+
+ if(getRx().isSet() || getRy().isSet())
+ {
+ double frX(getRx().isSet() ? getRx().solve(*this, xcoordinate) : 0.0);
+ double frY(getRy().isSet() ? getRy().solve(*this, ycoordinate) : 0.0);
+
+ frX = std::max(0.0, frX);
+ frY = std::max(0.0, frY);
+
+ if(0.0 == frY && frX > 0.0)
+ {
+ frY = frX;
+ }
+ else if(0.0 == frX && frY > 0.0)
+ {
+ frX = frY;
+ }
+
+ frX /= fWidth;
+ frY /= fHeight;
+
+ frX = std::min(0.5, frX);
+ frY = std::min(0.5, frY);
+
+ aPath = basegfx::tools::createPolygonFromRect(aRange, frX * 2.0, frY * 2.0);
+ }
+ else
+ {
+ aPath = basegfx::tools::createPolygonFromRect(aRange);
+ }
+
+ drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
+
+ pStyle->add_path(basegfx::B2DPolyPolygon(aPath), aNewTarget);
+
+ if(aNewTarget.hasElements())
+ {
+ pStyle->add_postProcess(rTarget, aNewTarget, getTransform());
+ }
+ }
+ }
+ }
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx
new file mode 100644
index 000000000000..35204aa3ce86
--- /dev/null
+++ b/svgio/source/svgreader/svgstyleattributes.cxx
@@ -0,0 +1,2435 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgstyleattributes.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <svgio/svgreader/svgnode.hxx>
+#include <svgio/svgreader/svgdocument.hxx>
+#include <drawinglayer/primitive2d/svggradientprimitive2d.hxx>
+#include <svgio/svgreader/svggradientnode.hxx>
+#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
+#include <basegfx/vector/b2enums.hxx>
+#include <drawinglayer/processor2d/linegeometryextractor2d.hxx>
+#include <drawinglayer/processor2d/textaspolygonextractor2d.hxx>
+#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
+#include <svgio/svgreader/svgclippathnode.hxx>
+#include <svgio/svgreader/svgmasknode.hxx>
+#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <svgio/svgreader/svgmarkernode.hxx>
+#include <basegfx/curve/b2dcubicbezier.hxx>
+#include <svgio/svgreader/svgpatternnode.hxx>
+#include <drawinglayer/primitive2d/patternfillprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ basegfx::B2DLineJoin StrokeLinejoinToB2DLineJoin(StrokeLinejoin aStrokeLinejoin)
+ {
+ if(StrokeLinejoin_round == aStrokeLinejoin)
+ {
+ return basegfx::B2DLINEJOIN_ROUND;
+ }
+ else if(StrokeLinejoin_bevel == aStrokeLinejoin)
+ {
+ return basegfx::B2DLINEJOIN_BEVEL;
+ }
+
+ return basegfx::B2DLINEJOIN_MITER;
+ }
+
+ FontStretch getWider(FontStretch aSource)
+ {
+ switch(aSource)
+ {
+ case FontStretch_ultra_condensed: aSource = FontStretch_extra_condensed; break;
+ case FontStretch_extra_condensed: aSource = FontStretch_condensed; break;
+ case FontStretch_condensed: aSource = FontStretch_semi_condensed; break;
+ case FontStretch_semi_condensed: aSource = FontStretch_normal; break;
+ case FontStretch_normal: aSource = FontStretch_semi_expanded; break;
+ case FontStretch_semi_expanded: aSource = FontStretch_expanded; break;
+ case FontStretch_expanded: aSource = FontStretch_extra_expanded; break;
+ case FontStretch_extra_expanded: aSource = FontStretch_ultra_expanded; break;
+ }
+
+ return aSource;
+ }
+
+ FontStretch getNarrower(FontStretch aSource)
+ {
+ switch(aSource)
+ {
+ case FontStretch_extra_condensed: aSource = FontStretch_ultra_condensed; break;
+ case FontStretch_condensed: aSource = FontStretch_extra_condensed; break;
+ case FontStretch_semi_condensed: aSource = FontStretch_condensed; break;
+ case FontStretch_normal: aSource = FontStretch_semi_condensed; break;
+ case FontStretch_semi_expanded: aSource = FontStretch_normal; break;
+ case FontStretch_expanded: aSource = FontStretch_semi_expanded; break;
+ case FontStretch_extra_expanded: aSource = FontStretch_expanded; break;
+ case FontStretch_ultra_expanded: aSource = FontStretch_extra_expanded; break;
+ }
+
+ return aSource;
+ }
+
+ FontWeight getBolder(FontWeight aSource)
+ {
+ switch(aSource)
+ {
+ case FontWeight_100: aSource = FontWeight_200; break;
+ case FontWeight_200: aSource = FontWeight_300; break;
+ case FontWeight_300: aSource = FontWeight_400; break;
+ case FontWeight_400: aSource = FontWeight_500; break;
+ case FontWeight_500: aSource = FontWeight_600; break;
+ case FontWeight_600: aSource = FontWeight_700; break;
+ case FontWeight_700: aSource = FontWeight_800; break;
+ case FontWeight_800: aSource = FontWeight_900; break;
+ }
+
+ return aSource;
+ }
+
+ FontWeight getLighter(FontWeight aSource)
+ {
+ switch(aSource)
+ {
+ case FontWeight_200: aSource = FontWeight_100; break;
+ case FontWeight_300: aSource = FontWeight_200; break;
+ case FontWeight_400: aSource = FontWeight_300; break;
+ case FontWeight_500: aSource = FontWeight_400; break;
+ case FontWeight_600: aSource = FontWeight_500; break;
+ case FontWeight_700: aSource = FontWeight_600; break;
+ case FontWeight_800: aSource = FontWeight_700; break;
+ case FontWeight_900: aSource = FontWeight_800; break;
+ }
+
+ return aSource;
+ }
+
+ ::FontWeight getVclFontWeight(FontWeight aSource)
+ {
+ ::FontWeight nRetval(WEIGHT_NORMAL);
+
+ switch(aSource)
+ {
+ case FontWeight_100: nRetval = WEIGHT_ULTRALIGHT; break;
+ case FontWeight_200: nRetval = WEIGHT_LIGHT; break;
+ case FontWeight_300: nRetval = WEIGHT_SEMILIGHT; break;
+ case FontWeight_400: nRetval = WEIGHT_NORMAL; break;
+ case FontWeight_500: nRetval = WEIGHT_MEDIUM; break;
+ case FontWeight_600: nRetval = WEIGHT_SEMIBOLD; break;
+ case FontWeight_700: nRetval = WEIGHT_BOLD; break;
+ case FontWeight_800: nRetval = WEIGHT_ULTRABOLD; break;
+ case FontWeight_900: nRetval = WEIGHT_BLACK; break;
+ }
+
+ return nRetval;
+ }
+
+ void SvgStyleAttributes::readStyle(const rtl::OUString& rCandidate)
+ {
+ const sal_Int32 nLen(rCandidate.getLength());
+ sal_Int32 nPos(0);
+
+ while(nPos < nLen)
+ {
+ const sal_Int32 nInitPos(nPos);
+ skip_char(rCandidate, sal_Unicode(' '), nPos, nLen);
+ rtl::OUStringBuffer aTokenName;
+ copyString(rCandidate, nPos, aTokenName, nLen);
+
+ if(aTokenName.getLength())
+ {
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(':'), nPos, nLen);
+ rtl::OUStringBuffer aTokenValue;
+ copyToLimiter(rCandidate, sal_Unicode(';'), nPos, aTokenValue, nLen);
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(';'), nPos, nLen);
+ const rtl::OUString aOUTokenName(aTokenName.makeStringAndClear());
+ const rtl::OUString aOUTokenValue(aTokenValue.makeStringAndClear());
+
+ parseStyleAttribute(aOUTokenName, StrToSVGToken(aOUTokenName), aOUTokenValue);
+ }
+
+ if(nInitPos == nPos)
+ {
+ OSL_ENSURE(false, "Could not interpret on current position (!)");
+ nPos++;
+ }
+ }
+ }
+
+ void SvgStyleAttributes::checkForCssStyle(const rtl::OUString& rClassStr) const
+ {
+ if(!mpCssStyleParent)
+ {
+ const SvgDocument& rDocument = mrOwner.getDocument();
+ const SvgStyleAttributes* pNew = 0;
+
+ if(rDocument.hasSvgStyleAttributesById())
+ {
+ if(mrOwner.getClass())
+ {
+ rtl::OUString aId(rtl::OUString::createFromAscii("."));
+ aId = aId + *mrOwner.getClass();
+ pNew = rDocument.findSvgStyleAttributesById(aId);
+
+ if(!pNew)
+ {
+ aId = rClassStr + aId;
+
+ pNew = rDocument.findSvgStyleAttributesById(aId);
+ }
+ }
+ else if(mrOwner.getId())
+ {
+ pNew = rDocument.findSvgStyleAttributesById(*mrOwner.getId());
+ }
+
+ if(pNew)
+ {
+ // found css style, set as parent
+ const_cast< SvgStyleAttributes* >(this)->mpCssStyleParent = pNew;
+ }
+ }
+ }
+ }
+
+ const SvgStyleAttributes* SvgStyleAttributes::getParentStyle() const
+ {
+ if(mpCssStyleParent)
+ {
+ return mpCssStyleParent;
+ }
+
+ if(mrOwner.getParent())
+ {
+ return mrOwner.getParent()->getSvgStyleAttributes();
+ }
+
+ return 0;
+ }
+
+ void SvgStyleAttributes::add_text(
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ drawinglayer::primitive2d::Primitive2DSequence& rSource) const
+ {
+ if(rSource.hasElements())
+ {
+ // at this point the primitives in rSource are of type TextSimplePortionPrimitive2D
+ // or TextDecoratedPortionPrimitive2D and have the Fill Color (pAttributes->getFill())
+ // set. When another fill is used and also evtl. stroke is set it gets necessary to
+ // dismantle to geometry and add needed primitives
+ const basegfx::BColor* pFill = getFill();
+ const SvgGradientNode* pFillGradient = getSvgGradientNodeFill();
+ const SvgPatternNode* pFillPattern = getSvgPatternNodeFill();
+ const basegfx::BColor* pStroke = getStroke();
+ const SvgGradientNode* pStrokeGradient = getSvgGradientNodeStroke();
+ const SvgPatternNode* pStrokePattern = getSvgPatternNodeStroke();
+ basegfx::B2DPolyPolygon aMergedArea;
+
+ if(pFillGradient || pFillPattern || pStroke || pStrokeGradient || pStrokePattern)
+ {
+ // text geometry is needed, create
+ // use neutral ViewInformation and create LineGeometryExtractor2D
+ const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
+ drawinglayer::processor2d::TextAsPolygonExtractor2D aExtractor(aViewInformation2D);
+
+ // proccess
+ aExtractor.process(rSource);
+
+ // get results
+ const drawinglayer::processor2d::TextAsPolygonDataNodeVector& rResult = aExtractor.getTarget();
+ const sal_uInt32 nResultCount(rResult.size());
+ basegfx::B2DPolyPolygonVector aTextFillVector;
+ aTextFillVector.reserve(nResultCount);
+
+ for(sal_uInt32 a(0); a < nResultCount; a++)
+ {
+ const drawinglayer::processor2d::TextAsPolygonDataNode& rCandidate = rResult[a];
+
+ if(rCandidate.getIsFilled())
+ {
+ aTextFillVector.push_back(rCandidate.getB2DPolyPolygon());
+ }
+ }
+
+ if(!aTextFillVector.empty())
+ {
+ aMergedArea = basegfx::tools::mergeToSinglePolyPolygon(aTextFillVector);
+ }
+ }
+
+ const bool bStrokeUsed(pStroke || pStrokeGradient || pStrokePattern);
+
+ // add fill. Use geometry even for simple color fill when stroke
+ // is used, else text rendering and the geometry-based stroke will
+ // normally not really match optically due to divrese system text
+ // renderers
+ if(aMergedArea.count() && (pFillGradient || pFillPattern || bStrokeUsed))
+ {
+ // create text fill content based on geometry
+ add_fill(aMergedArea, rTarget, aMergedArea.getB2DRange());
+ }
+ else if(pFill)
+ {
+ // add the already prepared primitives for single color fill
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, rSource);
+ }
+
+ // add stroke
+ if(aMergedArea.count() && bStrokeUsed)
+ {
+ // create text stroke content
+ add_stroke(aMergedArea, rTarget, aMergedArea.getB2DRange());
+ }
+ }
+ }
+
+ void SvgStyleAttributes::add_fillGradient(
+ const basegfx::B2DPolyPolygon& rPath,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const SvgGradientNode& rFillGradient,
+ const basegfx::B2DRange& rGeoRange) const
+ {
+ // create fill content
+ drawinglayer::primitive2d::SvgGradientEntryVector aSvgGradientEntryVector;
+
+ // get the color stops
+ rFillGradient.collectGradientEntries(aSvgGradientEntryVector);
+
+ if(!aSvgGradientEntryVector.empty())
+ {
+ basegfx::B2DHomMatrix aGeoToUnit;
+
+ if(rFillGradient.getGradientTransform())
+ {
+ aGeoToUnit = *rFillGradient.getGradientTransform();
+ }
+
+ if(userSpaceOnUse == rFillGradient.getGradientUnits())
+ {
+ aGeoToUnit.translate(-rGeoRange.getMinX(), -rGeoRange.getMinY());
+ aGeoToUnit.scale(1.0 / rGeoRange.getWidth(), 1.0 / rGeoRange.getHeight());
+ }
+
+ if(SVGTokenLinearGradient == rFillGradient.getType())
+ {
+ basegfx::B2DPoint aStart(0.0, 0.0);
+ basegfx::B2DPoint aEnd(1.0, 0.0);
+
+ if(userSpaceOnUse == rFillGradient.getGradientUnits())
+ {
+ // all possible units
+ aStart.setX(rFillGradient.getX1().solve(mrOwner, xcoordinate));
+ aStart.setY(rFillGradient.getY1().solve(mrOwner, ycoordinate));
+ aEnd.setX(rFillGradient.getX2().solve(mrOwner, xcoordinate));
+ aEnd.setY(rFillGradient.getY2().solve(mrOwner, ycoordinate));
+ }
+ else
+ {
+ // fractions or percent relative to object bounds
+ const SvgNumber X1(rFillGradient.getX1());
+ const SvgNumber Y1(rFillGradient.getY1());
+ const SvgNumber X2(rFillGradient.getX2());
+ const SvgNumber Y2(rFillGradient.getY2());
+
+ aStart.setX(Unit_percent == X1.getUnit() ? X1.getNumber() * 0.01 : X1.getNumber());
+ aStart.setY(Unit_percent == Y1.getUnit() ? Y1.getNumber() * 0.01 : Y1.getNumber());
+ aEnd.setX(Unit_percent == X2.getUnit() ? X2.getNumber() * 0.01 : X2.getNumber());
+ aEnd.setY(Unit_percent == Y2.getUnit() ? Y2.getNumber() * 0.01 : Y2.getNumber());
+ }
+
+ if(!aGeoToUnit.isIdentity())
+ {
+ aStart *= aGeoToUnit;
+ aEnd *= aGeoToUnit;
+ }
+
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
+ rTarget,
+ new drawinglayer::primitive2d::SvgLinearGradientPrimitive2D(
+ rPath,
+ aSvgGradientEntryVector,
+ aStart,
+ aEnd,
+ rFillGradient.getSpreadMethod()));
+ }
+ else
+ {
+ basegfx::B2DPoint aStart(0.5, 0.5);
+ basegfx::B2DPoint aFocal;
+ double fRadius(0.5);
+ const SvgNumber* pFx = rFillGradient.getFx();
+ const SvgNumber* pFy = rFillGradient.getFy();
+ const bool bFocal(pFx || pFy);
+
+ if(userSpaceOnUse == rFillGradient.getGradientUnits())
+ {
+ // all possible units
+ aStart.setX(rFillGradient.getCx().solve(mrOwner, xcoordinate));
+ aStart.setY(rFillGradient.getCy().solve(mrOwner, ycoordinate));
+ fRadius = rFillGradient.getR().solve(mrOwner, length);
+
+ if(bFocal)
+ {
+ aFocal.setX(pFx ? pFx->solve(mrOwner, xcoordinate) : aStart.getX());
+ aFocal.setY(pFy ? pFy->solve(mrOwner, ycoordinate) : aStart.getY());
+ }
+ }
+ else
+ {
+ // fractions or percent relative to object bounds
+ const SvgNumber Cx(rFillGradient.getCx());
+ const SvgNumber Cy(rFillGradient.getCy());
+ const SvgNumber R(rFillGradient.getR());
+
+ aStart.setX(Unit_percent == Cx.getUnit() ? Cx.getNumber() * 0.01 : Cx.getNumber());
+ aStart.setY(Unit_percent == Cy.getUnit() ? Cy.getNumber() * 0.01 : Cy.getNumber());
+ fRadius = (Unit_percent == R.getUnit()) ? R.getNumber() * 0.01 : R.getNumber();
+
+ if(bFocal)
+ {
+ aFocal.setX(pFx ? (Unit_percent == pFx->getUnit() ? pFx->getNumber() * 0.01 : pFx->getNumber()) : aStart.getX());
+ aFocal.setY(pFy ? (Unit_percent == pFy->getUnit() ? pFy->getNumber() * 0.01 : pFy->getNumber()) : aStart.getY());
+ }
+ }
+
+ if(!aGeoToUnit.isIdentity())
+ {
+ aStart *= aGeoToUnit;
+ fRadius = (aGeoToUnit * basegfx::B2DVector(fRadius, 0.0)).getLength();
+
+ if(bFocal)
+ {
+ aFocal *= aGeoToUnit;
+ }
+ }
+
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
+ rTarget,
+ new drawinglayer::primitive2d::SvgRadialGradientPrimitive2D(
+ rPath,
+ aSvgGradientEntryVector,
+ aStart,
+ fRadius,
+ rFillGradient.getSpreadMethod(),
+ bFocal ? &aFocal : 0));
+ }
+ }
+ }
+
+ void SvgStyleAttributes::add_fillPatternTransform(
+ const basegfx::B2DPolyPolygon& rPath,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const SvgPatternNode& rFillPattern,
+ const basegfx::B2DRange& rGeoRange) const
+ {
+ // prepare fill polyPolygon with given pattern, check for patternTransform
+ if(rFillPattern.getPatternTransform() && !rFillPattern.getPatternTransform()->isIdentity())
+ {
+ // PatternTransform is active; Handle by filling the inverse transformed
+ // path and back-transforming the result
+ basegfx::B2DPolyPolygon aPath(rPath);
+ basegfx::B2DHomMatrix aInv(*rFillPattern.getPatternTransform());
+ drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
+
+ aInv.invert();
+ aPath.transform(aInv);
+ add_fillPattern(aPath, aNewTarget, rFillPattern, aPath.getB2DRange());
+
+ if(aNewTarget.hasElements())
+ {
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
+ rTarget,
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ *rFillPattern.getPatternTransform(),
+ aNewTarget));
+ }
+ }
+ else
+ {
+ // no patternTransform, create fillPattern directly
+ add_fillPattern(rPath, rTarget, rFillPattern, rGeoRange);
+ }
+ }
+
+ void SvgStyleAttributes::add_fillPattern(
+ const basegfx::B2DPolyPolygon& rPath,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const SvgPatternNode& rFillPattern,
+ const basegfx::B2DRange& rGeoRange) const
+ {
+ // fill polyPolygon with given pattern
+ const drawinglayer::primitive2d::Primitive2DSequence& rPrimitives = rFillPattern.getPatternPrimitives();
+
+ if(rPrimitives.hasElements())
+ {
+ double fTargetWidth(rGeoRange.getWidth());
+ double fTargetHeight(rGeoRange.getHeight());
+
+ if(fTargetWidth > 0.0 && fTargetHeight > 0.0)
+ {
+ // get relative values from pattern
+ double fX(0.0);
+ double fY(0.0);
+ double fW(0.0);
+ double fH(0.0);
+
+ rFillPattern.getValuesRelative(fX, fY, fW, fH, rGeoRange, mrOwner);
+
+ if(fW > 0.0 && fH > 0.0)
+ {
+ // build the reference range relative to the rGeoRange
+ const basegfx::B2DRange aReferenceRange(fX, fY, fX + fW, fY + fH);
+
+ // find out how the content is mapped to the reference range
+ basegfx::B2DHomMatrix aMapPrimitivesToUnitRange;
+ const basegfx::B2DRange* pViewBox = rFillPattern.getViewBox();
+
+ if(pViewBox)
+ {
+ // use viewBox/preserveAspectRatio
+ const SvgAspectRatio& rRatio = rFillPattern.getSvgAspectRatio();
+ const basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0);
+
+ if(rRatio.isSet())
+ {
+ // let mapping be created from SvgAspectRatio
+ aMapPrimitivesToUnitRange = rRatio.createMapping(aUnitRange, *pViewBox);
+ }
+ else
+ {
+ // choose default mapping
+ aMapPrimitivesToUnitRange = rRatio.createLinearMapping(aUnitRange, *pViewBox);
+ }
+ }
+ else
+ {
+ // use patternContentUnits
+ const SvgUnits aPatternContentUnits(rFillPattern.getPatternContentUnits() ? *rFillPattern.getPatternContentUnits() : userSpaceOnUse);
+
+ if(userSpaceOnUse == aPatternContentUnits)
+ {
+ // create relative mapping to unit coordinates
+ aMapPrimitivesToUnitRange.scale(1.0 / (fW * fTargetWidth), 1.0 / (fH * fTargetHeight));
+ }
+ else
+ {
+ aMapPrimitivesToUnitRange.scale(1.0 / fW, 1.0 / fH);
+ }
+ }
+
+ // apply aMapPrimitivesToUnitRange to content when used
+ drawinglayer::primitive2d::Primitive2DSequence aPrimitives(rPrimitives);
+
+ if(!aMapPrimitivesToUnitRange.isIdentity())
+ {
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ aMapPrimitivesToUnitRange,
+ aPrimitives));
+
+ aPrimitives = drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1);
+ }
+
+ // embed in PatternFillPrimitive2D
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
+ rTarget,
+ new drawinglayer::primitive2d::PatternFillPrimitive2D(
+ rPath,
+ aPrimitives,
+ aReferenceRange));
+ }
+ }
+ }
+ }
+
+ void SvgStyleAttributes::add_fill(
+ const basegfx::B2DPolyPolygon& rPath,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const basegfx::B2DRange& rGeoRange) const
+ {
+ const basegfx::BColor* pFill = getFill();
+ const SvgGradientNode* pFillGradient = getSvgGradientNodeFill();
+ const SvgPatternNode* pFillPattern = getSvgPatternNodeFill();
+
+ if(pFill || pFillGradient || pFillPattern)
+ {
+ const double fFillOpacity(getFillOpacity().solve(mrOwner, length));
+
+ if(basegfx::fTools::more(fFillOpacity, 0.0))
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aNewFill;
+
+ if(pFillGradient)
+ {
+ // create fill content with SVG gradient primitive
+ add_fillGradient(rPath, aNewFill, *pFillGradient, rGeoRange);
+ }
+ else if(pFillPattern)
+ {
+ // create fill content with SVG pattern primitive
+ add_fillPatternTransform(rPath, aNewFill, *pFillPattern, rGeoRange);
+ }
+ else // if(pFill)
+ {
+ // create fill content
+ aNewFill.realloc(1);
+ aNewFill[0] = new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
+ rPath,
+ *pFill);
+ }
+
+ if(aNewFill.hasElements())
+ {
+ if(basegfx::fTools::less(fFillOpacity, 1.0))
+ {
+ // embed in UnifiedTransparencePrimitive2D
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
+ rTarget,
+ new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
+ aNewFill,
+ 1.0 - fFillOpacity));
+ }
+ else
+ {
+ // append
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewFill);
+ }
+ }
+ }
+ }
+ }
+
+ void SvgStyleAttributes::add_stroke(
+ const basegfx::B2DPolyPolygon& rPath,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const basegfx::B2DRange& rGeoRange) const
+ {
+ const basegfx::BColor* pStroke = getStroke();
+ const SvgGradientNode* pStrokeGradient = getSvgGradientNodeStroke();
+ const SvgPatternNode* pStrokePattern = getSvgPatternNodeStroke();
+
+ if(pStroke || pStrokeGradient || pStrokePattern)
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aNewStroke;
+ const double fStrokeOpacity(getStrokeOpacity().solve(mrOwner, length));
+
+ if(basegfx::fTools::more(fStrokeOpacity, 0.0))
+ {
+ // get stroke width; SVG does not use 0.0 == hairline, so 0.0 is no line at all
+ const double fStrokeWidth(getStrokeWidth().isSet() ? getStrokeWidth().solve(mrOwner, length) : 1.0);
+
+ if(basegfx::fTools::more(fStrokeWidth, 0.0))
+ {
+ // get LineJoin and stroke array
+ const basegfx::B2DLineJoin aB2DLineJoin(StrokeLinejoinToB2DLineJoin(getStrokeLinejoin()));
+ ::std::vector< double > aDashArray;
+
+ if(!getStrokeDasharray().empty())
+ {
+ aDashArray = solveSvgNumberVector(getStrokeDasharray(), mrOwner, length);
+ }
+
+ // todo: Handle getStrokeDashOffset()
+ // todo: Handle getStrokeLinecap()
+
+ // prepare line attribute
+ drawinglayer::primitive2d::Primitive2DReference aNewLinePrimitive;
+ const drawinglayer::attribute::LineAttribute aLineAttribute(
+ pStroke ? *pStroke : basegfx::BColor(0.0, 0.0, 0.0),
+ fStrokeWidth,
+ aB2DLineJoin);
+
+ if(aDashArray.empty())
+ {
+ aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
+ rPath,
+ aLineAttribute);
+ }
+ else
+ {
+ const drawinglayer::attribute::StrokeAttribute aStrokeAttribute(aDashArray);
+
+ aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
+ rPath,
+ aLineAttribute,
+ aDashArray);
+ }
+
+ if(pStrokeGradient || pStrokePattern)
+ {
+ // put primitive into Primitive2DReference and Primitive2DSequence
+ const drawinglayer::primitive2d::Primitive2DSequence aSeq(&aNewLinePrimitive, 1);
+
+ // use neutral ViewInformation and create LineGeometryExtractor2D
+ const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
+ drawinglayer::processor2d::LineGeometryExtractor2D aExtractor(aViewInformation2D);
+
+ // proccess
+ aExtractor.process(aSeq);
+
+ // check for fill rsults
+ const basegfx::B2DPolyPolygonVector& rLineFillVector(aExtractor.getExtractedLineFills());
+
+ if(!aExtractor.getExtractedLineFills().empty())
+ {
+ const basegfx::B2DPolyPolygon aMergedArea(
+ basegfx::tools::mergeToSinglePolyPolygon(
+ aExtractor.getExtractedLineFills()));
+
+ if(aMergedArea.count())
+ {
+ if(pStrokeGradient)
+ {
+ // create fill content with SVG gradient primitive. Use original GeoRange,
+ // e.g. from circle without LineWidth
+ add_fillGradient(aMergedArea, aNewStroke, *pStrokeGradient, rGeoRange);
+ }
+ else // if(pStrokePattern)
+ {
+ // create fill content with SVG pattern primitive. Use GeoRange
+ // from the expanded data, e.g. circle with extended geo by half linewidth
+ add_fillPatternTransform(aMergedArea, aNewStroke, *pStrokePattern, aMergedArea.getB2DRange());
+ }
+ }
+ }
+ }
+ else // if(pStroke)
+ {
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aNewStroke, aNewLinePrimitive);
+ }
+
+ if(aNewStroke.hasElements())
+ {
+ if(basegfx::fTools::less(fStrokeOpacity, 1.0))
+ {
+ // embed in UnifiedTransparencePrimitive2D
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
+ rTarget,
+ new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
+ aNewStroke,
+ 1.0 - fStrokeOpacity));
+ }
+ else
+ {
+ // append
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewStroke);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ double get_markerRotation(
+ const SvgMarkerNode& rMarker,
+ const basegfx::B2DPolygon& rPolygon,
+ const sal_uInt32 nIndex)
+ {
+ double fAngle(0.0);
+ const sal_uInt32 nPointCount(rPolygon.count());
+
+ if(nPointCount)
+ {
+ if(rMarker.getOrientAuto())
+ {
+ const bool bPrev(rPolygon.isClosed() || nIndex > 0);
+ basegfx::B2DCubicBezier aSegment;
+ basegfx::B2DVector aPrev;
+ basegfx::B2DVector aNext;
+
+ if(bPrev)
+ {
+ rPolygon.getBezierSegment((nIndex - 1) % nPointCount, aSegment);
+ aPrev = aSegment.getTangent(1.0);
+ }
+
+ const bool bNext(rPolygon.isClosed() || nIndex + 1 < nPointCount);
+
+ if(bNext)
+ {
+ rPolygon.getBezierSegment(nIndex % nPointCount, aSegment);
+ aNext = aSegment.getTangent(0.0);
+ }
+
+ if(bPrev && bNext)
+ {
+ fAngle = atan2(aPrev.getY() + aNext.getY(), aPrev.getX() + aNext.getX());
+ }
+ else if(bPrev)
+ {
+ fAngle = atan2(aPrev.getY(), aPrev.getX());
+ }
+ else if(bNext)
+ {
+ fAngle = atan2(aNext.getY(), aNext.getX());
+ }
+ }
+ else
+ {
+ fAngle = rMarker.getAngle();
+ }
+ }
+
+ return fAngle;
+ }
+
+ bool SvgStyleAttributes::prepare_singleMarker(
+ drawinglayer::primitive2d::Primitive2DSequence& rMarkerPrimitives,
+ basegfx::B2DHomMatrix& rMarkerTransform,
+ basegfx::B2DRange& rClipRange,
+ const SvgMarkerNode& rMarker) const
+ {
+ // reset return values
+ rMarkerTransform.identity();
+ rClipRange.reset();
+
+ // get marker primitive representation
+ rMarkerPrimitives = rMarker.getMarkerPrimitives();
+
+ if(rMarkerPrimitives.hasElements())
+ {
+ basegfx::B2DRange aPrimitiveRange;
+
+ if(rMarker.getViewBox())
+ {
+ aPrimitiveRange = *rMarker.getViewBox();
+ }
+ else
+ {
+ aPrimitiveRange = drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(
+ rMarkerPrimitives,
+ drawinglayer::geometry::ViewInformation2D());
+ }
+
+ if(aPrimitiveRange.getWidth() > 0.0 && aPrimitiveRange.getHeight() > 0.0)
+ {
+ double fTargetWidth(rMarker.getMarkerWidth().isSet() ? rMarker.getMarkerWidth().solve(mrOwner, xcoordinate) : 0.0);
+ double fTargetHeight(rMarker.getMarkerHeight().isSet() ? rMarker.getMarkerHeight().solve(mrOwner, xcoordinate) : 0.0);
+
+ if(SvgMarkerNode::strokeWidth == rMarker.getMarkerUnits())
+ {
+ // relative to strokeWidth
+ const double fStrokeWidth(getStrokeWidth().isSet() ? getStrokeWidth().solve(mrOwner, length) : 1.0);
+
+ fTargetWidth *= fStrokeWidth;
+ fTargetHeight *= fStrokeWidth;
+ }
+
+ if(fTargetWidth > 0.0 && fTargetHeight > 0.0)
+ {
+ const basegfx::B2DRange aTargetRange(0.0, 0.0, fTargetWidth, fTargetHeight);
+
+ // subbstract refX, refY first, it's in marker local coordinates
+ rMarkerTransform.translate(
+ rMarker.getRefX().isSet() ? -rMarker.getRefX().solve(mrOwner, xcoordinate) : 0.0,
+ rMarker.getRefY().isSet() ? -rMarker.getRefY().solve(mrOwner, ycoordinate) : 0.0);
+
+ // create mapping
+ const SvgAspectRatio& rRatio = rMarker.getSvgAspectRatio();
+
+ if(rRatio.isSet())
+ {
+ // let mapping be created from SvgAspectRatio
+ rMarkerTransform = rRatio.createMapping(aTargetRange, aPrimitiveRange) * rMarkerTransform;
+
+ if(rRatio.isMeetOrSlice())
+ {
+ // need to clip
+ rClipRange = basegfx::B2DRange(0.0, 0.0, 1.0, 1.0);
+ }
+ }
+ else
+ {
+ // choose default mapping
+ rMarkerTransform = rRatio.createLinearMapping(aTargetRange, aPrimitiveRange) * rMarkerTransform;
+ }
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ void SvgStyleAttributes::add_singleMarker(
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const drawinglayer::primitive2d::Primitive2DSequence& rMarkerPrimitives,
+ const basegfx::B2DHomMatrix& rMarkerTransform,
+ const basegfx::B2DRange& rClipRange,
+ const SvgMarkerNode& rMarker,
+ const basegfx::B2DPolygon& rCandidate,
+ const sal_uInt32 nIndex) const
+ {
+ const sal_uInt32 nPointCount(rCandidate.count());
+
+ if(nPointCount)
+ {
+ // get and apply rotation
+ basegfx::B2DHomMatrix aCombinedTransform(rMarkerTransform);
+ aCombinedTransform.rotate(get_markerRotation(rMarker, rCandidate, nIndex));
+
+ // get and apply target position
+ const basegfx::B2DPoint aPoint(rCandidate.getB2DPoint(nIndex % nPointCount));
+ aCombinedTransform.translate(aPoint.getX(), aPoint.getY());
+
+ // add marker
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
+ rTarget,
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ aCombinedTransform,
+ rMarkerPrimitives));
+ }
+ }
+
+ void SvgStyleAttributes::add_markers(
+ const basegfx::B2DPolyPolygon& rPath,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget) const
+ {
+ // try to access linked markers
+ const SvgMarkerNode* pStart = accessMarkerStartXLink();
+ const SvgMarkerNode* pMid = accessMarkerMidXLink();
+ const SvgMarkerNode* pEnd = accessMarkerEndXLink();
+
+ if(pStart || pMid || pEnd)
+ {
+ const sal_uInt32 nCount(rPath.count());
+
+ for (sal_uInt32 a(0); a < nCount; a++)
+ {
+ const basegfx::B2DPolygon aCandidate(rPath.getB2DPolygon(a));
+ const sal_uInt32 nPointCount(aCandidate.count());
+
+ if(nPointCount)
+ {
+ const sal_uInt32 nMarkerCount(aCandidate.isClosed() ? nPointCount + 1 : nPointCount);
+ drawinglayer::primitive2d::Primitive2DSequence aMarkerPrimitives;
+ basegfx::B2DHomMatrix aMarkerTransform;
+ basegfx::B2DRange aClipRange;
+ const SvgMarkerNode* pPrepared = 0;
+
+ if(pStart)
+ {
+ if(prepare_singleMarker(aMarkerPrimitives, aMarkerTransform, aClipRange, *pStart))
+ {
+ pPrepared = pStart;
+ add_singleMarker(rTarget, aMarkerPrimitives, aMarkerTransform, aClipRange, *pPrepared, aCandidate, 0);
+ }
+ }
+
+ if(pMid && nMarkerCount > 2)
+ {
+ if(pMid == pPrepared || prepare_singleMarker(aMarkerPrimitives, aMarkerTransform, aClipRange, *pMid))
+ {
+ pPrepared = pMid;
+
+ for(sal_uInt32 a(1); a < nMarkerCount - 1; a++)
+ {
+ add_singleMarker(rTarget, aMarkerPrimitives, aMarkerTransform, aClipRange, *pPrepared, aCandidate, a);
+ }
+ }
+ }
+
+ if(pEnd)
+ {
+ if(pEnd == pPrepared || prepare_singleMarker(aMarkerPrimitives, aMarkerTransform, aClipRange, *pEnd))
+ {
+ pPrepared = pEnd;
+ add_singleMarker(rTarget, aMarkerPrimitives, aMarkerTransform, aClipRange, *pPrepared, aCandidate, nMarkerCount - 1);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ void SvgStyleAttributes::add_path(
+ const basegfx::B2DPolyPolygon& rPath,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget) const
+ {
+ const bool bIsLine(1 == rPath.count()
+ && !rPath.areControlPointsUsed()
+ && 2 == rPath.getB2DPolygon(0).count());
+
+ if(!rPath.count())
+ {
+ return;
+ }
+
+ const basegfx::B2DRange aGeoRange(rPath.getB2DRange());
+
+ if(aGeoRange.isEmpty())
+ {
+ return;
+ }
+
+ if(!bIsLine && // not for lines
+ (basegfx::fTools::equalZero(aGeoRange.getWidth())
+ || basegfx::fTools::equalZero(aGeoRange.getHeight())))
+ {
+ return;
+ }
+
+ const double fOpacity(getOpacity().getNumber());
+
+ if(basegfx::fTools::equalZero(fOpacity))
+ {
+ return;
+ }
+
+ if(!bIsLine)
+ {
+ basegfx::B2DPolyPolygon aPath(rPath);
+ const bool bNeedToCheckClipRule(SVGTokenPath == mrOwner.getType() || SVGTokenPolygon == mrOwner.getType());
+ const bool bClipPathIsNonzero(!bIsLine && bNeedToCheckClipRule && mbIsClipPathContent && mbClipRule);
+ const bool bFillRuleIsNonzero(!bIsLine && bNeedToCheckClipRule && !mbIsClipPathContent && getFillRule());
+
+ if(bClipPathIsNonzero || bFillRuleIsNonzero)
+ {
+ // nonzero is wanted, solve geometrically (see description on basegfx)
+ aPath = basegfx::tools::createNonzeroConform(aPath);
+ }
+
+ add_fill(aPath, rTarget, aGeoRange);
+ }
+
+ add_stroke(rPath, rTarget, aGeoRange);
+
+ // Svg supports markers for path, polygon, polyline and line
+ if(SVGTokenPath == mrOwner.getType() || // path
+ SVGTokenPolygon == mrOwner.getType() || // polygon, polyline
+ SVGTokenLine == mrOwner.getType()) // line
+ {
+ // try to add markers
+ add_markers(rPath, rTarget);
+ }
+ }
+
+ void SvgStyleAttributes::add_postProcess(
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const drawinglayer::primitive2d::Primitive2DSequence& rSource,
+ const basegfx::B2DHomMatrix* pTransform) const
+ {
+ if(rSource.hasElements())
+ {
+ const double fOpacity(getOpacity().getNumber());
+
+ if(basegfx::fTools::equalZero(fOpacity))
+ {
+ return;
+ }
+
+ drawinglayer::primitive2d::Primitive2DSequence aSource(rSource);
+
+ if(basegfx::fTools::less(fOpacity, 1.0))
+ {
+ // embed in UnifiedTransparencePrimitive2D
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
+ aSource,
+ 1.0 - fOpacity));
+
+ aSource = drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1);
+ }
+
+ if(getClipPathXLink().getLength())
+ {
+ // try to access linked ClipPath
+ const SvgClipPathNode* mpClip = dynamic_cast< const SvgClipPathNode* >(mrOwner.getDocument().findSvgNodeById(getClipPathXLink()));
+
+ if(mpClip)
+ {
+ mpClip->apply(aSource);
+ }
+ }
+
+ if(aSource.hasElements()) // test again, applied clipPath may have lead to empty geometry
+ {
+ if(getMaskXLink().getLength())
+ {
+ // try to access linked Mask
+ const SvgMaskNode* mpMask = dynamic_cast< const SvgMaskNode* >(mrOwner.getDocument().findSvgNodeById(getMaskXLink()));
+
+ if(mpMask)
+ {
+ mpMask->apply(aSource);
+ }
+ }
+
+ if(aSource.hasElements()) // test again, applied mask may have lead to empty geometry
+ {
+ if(pTransform)
+ {
+ // create embedding group element with transformation
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ *pTransform,
+ aSource));
+
+ aSource = drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1);
+ }
+
+ // append to current target
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aSource);
+ }
+ }
+ }
+ }
+
+ SvgStyleAttributes::SvgStyleAttributes(SvgNode& rOwner)
+ : mrOwner(rOwner),
+ mpCssStyleParent(0),
+ maFill(),
+ maStroke(),
+ maStopColor(basegfx::BColor(0.0, 0.0, 0.0), true),
+ maStrokeWidth(),
+ maStopOpacity(),
+ mpSvgGradientNodeFill(0),
+ mpSvgGradientNodeStroke(0),
+ mpSvgPatternNodeFill(0),
+ mpSvgPatternNodeStroke(0),
+ maFillOpacity(),
+ maStrokeDasharray(),
+ maStrokeDashOffset(),
+ maStrokeLinecap(StrokeLinecap_notset),
+ maStrokeLinejoin(StrokeLinejoin_notset),
+ maStrokeMiterLimit(),
+ maStrokeOpacity(),
+ maFontFamily(),
+ maFontSize(),
+ maFontStretch(FontStretch_notset),
+ maFontStyle(FontStyle_notset),
+ maFontVariant(FontVariant_notset),
+ maFontWeight(FontWeight_notset),
+ maTextAlign(TextAlign_notset),
+ maTextDecoration(TextDecoration_notset),
+ maTextAnchor(TextAnchor_notset),
+ maColor(),
+ maOpacity(1.0),
+ maClipPathXLink(),
+ maMaskXLink(),
+ maMarkerStartXLink(),
+ mpMarkerStartXLink(0),
+ maMarkerMidXLink(),
+ mpMarkerMidXLink(0),
+ maMarkerEndXLink(),
+ mpMarkerEndXLink(0),
+ maFillRule(true),
+ maFillRuleSet(false),
+ mbIsClipPathContent(SVGTokenClipPathNode == mrOwner.getType()),
+ mbClipRule(true)
+ {
+ if(!mbIsClipPathContent)
+ {
+ const SvgStyleAttributes* pParentStyle = getParentStyle();
+
+ if(pParentStyle)
+ {
+ mbIsClipPathContent = pParentStyle->mbIsClipPathContent;
+ }
+ }
+ }
+
+ SvgStyleAttributes::~SvgStyleAttributes()
+ {
+ }
+
+ void SvgStyleAttributes::parseStyleAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ switch(aSVGToken)
+ {
+ case SVGTokenFill:
+ {
+ SvgPaint aSvgPaint;
+ rtl::OUString aURL;
+ bool bUseCurrent(false);
+
+ if(readSvgPaint(aContent, aSvgPaint, aURL))
+ {
+ setFill(aSvgPaint);
+ }
+ else if(aURL.getLength())
+ {
+ const SvgNode* pNode = mrOwner.getDocument().findSvgNodeById(aURL);
+
+ if(pNode)
+ {
+ if(SVGTokenLinearGradient == pNode->getType() || SVGTokenRadialGradient == pNode->getType())
+ {
+ setSvgGradientNodeFill(static_cast< const SvgGradientNode* >(pNode));
+ }
+ else if(SVGTokenPattern == pNode->getType())
+ {
+ setSvgPatternNodeFill(static_cast< const SvgPatternNode* >(pNode));
+ }
+ }
+ }
+ break;
+ }
+ case SVGTokenFillOpacity:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setFillOpacity(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenFillRule:
+ {
+ if(aContent.getLength())
+ {
+ if(aContent.match(commonStrings::aStrNonzero))
+ {
+ maFillRule = true;
+ maFillRuleSet = true;
+ }
+ else if(aContent.match(commonStrings::aStrEvenOdd))
+ {
+ maFillRule = false;
+ maFillRuleSet = true;
+ }
+ }
+ break;
+ }
+ case SVGTokenStroke:
+ {
+ SvgPaint aSvgPaint;
+ rtl::OUString aURL;
+
+ if(readSvgPaint(aContent, aSvgPaint, aURL))
+ {
+ setStroke(aSvgPaint);
+ }
+ else if(aURL.getLength())
+ {
+ const SvgNode* pNode = mrOwner.getDocument().findSvgNodeById(aURL);
+
+ if(pNode)
+ {
+ if(SVGTokenLinearGradient == pNode->getType() || SVGTokenRadialGradient == pNode->getType())
+ {
+ setSvgGradientNodeStroke(static_cast< const SvgGradientNode* >(pNode));
+ }
+ else if(SVGTokenPattern == pNode->getType())
+ {
+ setSvgPatternNodeStroke(static_cast< const SvgPatternNode* >(pNode));
+ }
+ }
+ }
+ break;
+ }
+ case SVGTokenStrokeDasharray:
+ {
+ if(aContent.getLength())
+ {
+ SvgNumberVector aVector;
+
+ if(readSvgNumberVector(aContent, aVector))
+ {
+ setStrokeDasharray(aVector);
+ }
+ }
+ break;
+ }
+ case SVGTokenStrokeDashoffset:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setStrokeDashOffset(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenStrokeLinecap:
+ {
+ if(aContent.getLength())
+ {
+ static rtl::OUString aStrButt(rtl::OUString::createFromAscii("butt"));
+ static rtl::OUString aStrRound(rtl::OUString::createFromAscii("round"));
+ static rtl::OUString aStrSquare(rtl::OUString::createFromAscii("square"));
+
+ if(aContent.match(aStrButt))
+ {
+ setStrokeLinecap(StrokeLinecap_butt);
+ }
+ else if(aContent.match(aStrRound))
+ {
+ setStrokeLinecap(StrokeLinecap_round);
+ }
+ else if(aContent.match(aStrSquare))
+ {
+ setStrokeLinecap(StrokeLinecap_square);
+ }
+ }
+ break;
+ }
+ case SVGTokenStrokeLinejoin:
+ {
+ if(aContent.getLength())
+ {
+ static rtl::OUString aStrMiter(rtl::OUString::createFromAscii("miter"));
+ static rtl::OUString aStrRound(rtl::OUString::createFromAscii("round"));
+ static rtl::OUString aStrBevel(rtl::OUString::createFromAscii("bevel"));
+
+ if(aContent.match(aStrMiter))
+ {
+ setStrokeLinejoin(StrokeLinejoin_miter);
+ }
+ else if(aContent.match(aStrRound))
+ {
+ setStrokeLinejoin(StrokeLinejoin_round);
+ }
+ else if(aContent.match(aStrBevel))
+ {
+ setStrokeLinejoin(StrokeLinejoin_bevel);
+ }
+ }
+ break;
+ }
+ case SVGTokenStrokeMiterlimit:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setStrokeMiterLimit(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenStrokeOpacity:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setStrokeOpacity(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenStrokeWidth:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setStrokeWidth(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenStopColor:
+ {
+ SvgPaint aSvgPaint;
+ rtl::OUString aURL;
+
+ if(readSvgPaint(aContent, aSvgPaint, aURL))
+ {
+ setStopColor(aSvgPaint);
+ }
+ break;
+ }
+ case SVGTokenStopOpacity:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setStopOpacity(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenFont:
+ {
+ bool bBla = true;
+ break;
+ }
+ case SVGTokenFontFamily:
+ {
+ SvgStringVector aSvgStringVector;
+
+ if(readSvgStringVector(aContent, aSvgStringVector))
+ {
+ setFontFamily(aSvgStringVector);
+ }
+ break;
+ }
+ case SVGTokenFontSize:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setFontSize(aNum);
+ }
+ break;
+ }
+ case SVGTokenFontSizeAdjust:
+ {
+ bool bBla = true;
+ break;
+ }
+ case SVGTokenFontStretch:
+ {
+ if(aContent.getLength())
+ {
+ static rtl::OUString aStrNormal(rtl::OUString::createFromAscii("normal"));
+ static rtl::OUString aStrWider(rtl::OUString::createFromAscii("wider"));
+ static rtl::OUString aStrNarrower(rtl::OUString::createFromAscii("narrower"));
+ static rtl::OUString aStrUltra_condensed(rtl::OUString::createFromAscii("ultra-condensed"));
+ static rtl::OUString aStrExtra_condensed(rtl::OUString::createFromAscii("extra-condensed"));
+ static rtl::OUString aStrCondensed(rtl::OUString::createFromAscii("condensed"));
+ static rtl::OUString aStrSemi_condensed(rtl::OUString::createFromAscii("semi-condensed"));
+ static rtl::OUString aStrSemi_expanded(rtl::OUString::createFromAscii("semi-expanded"));
+ static rtl::OUString aStrExpanded(rtl::OUString::createFromAscii("expanded"));
+ static rtl::OUString aStrExtra_expanded(rtl::OUString::createFromAscii("extra-expanded"));
+ static rtl::OUString aStrUltra_expanded(rtl::OUString::createFromAscii("ultra-expanded"));
+
+ if(aContent.match(aStrNormal))
+ {
+ setFontStretch(FontStretch_normal);
+ }
+ else if(aContent.match(aStrWider))
+ {
+ setFontStretch(FontStretch_wider);
+ }
+ else if(aContent.match(aStrNarrower))
+ {
+ setFontStretch(FontStretch_narrower);
+ }
+ else if(aContent.match(aStrUltra_condensed))
+ {
+ setFontStretch(FontStretch_ultra_condensed);
+ }
+ else if(aContent.match(aStrExtra_condensed))
+ {
+ setFontStretch(FontStretch_extra_condensed);
+ }
+ else if(aContent.match(aStrCondensed))
+ {
+ setFontStretch(FontStretch_condensed);
+ }
+ else if(aContent.match(aStrSemi_condensed))
+ {
+ setFontStretch(FontStretch_semi_condensed);
+ }
+ else if(aContent.match(aStrSemi_expanded))
+ {
+ setFontStretch(FontStretch_semi_expanded);
+ }
+ else if(aContent.match(aStrExpanded))
+ {
+ setFontStretch(FontStretch_expanded);
+ }
+ else if(aContent.match(aStrExtra_expanded))
+ {
+ setFontStretch(FontStretch_extra_expanded);
+ }
+ else if(aContent.match(aStrUltra_expanded))
+ {
+ setFontStretch(FontStretch_ultra_expanded);
+ }
+ }
+ break;
+ }
+ case SVGTokenFontStyle:
+ {
+ if(aContent.getLength())
+ {
+ static rtl::OUString aStrNormal(rtl::OUString::createFromAscii("normal"));
+ static rtl::OUString aStrItalic(rtl::OUString::createFromAscii("italic"));
+ static rtl::OUString aStrOblique(rtl::OUString::createFromAscii("oblique"));
+
+ if(aContent.match(aStrNormal))
+ {
+ setFontStyle(FontStyle_normal);
+ }
+ else if(aContent.match(aStrItalic))
+ {
+ setFontStyle(FontStyle_italic);
+ }
+ else if(aContent.match(aStrOblique))
+ {
+ setFontStyle(FontStyle_oblique);
+ }
+ }
+ break;
+ }
+ case SVGTokenFontVariant:
+ {
+ if(aContent.getLength())
+ {
+ static rtl::OUString aStrNormal(rtl::OUString::createFromAscii("normal"));
+ static rtl::OUString aStrSmallCaps(rtl::OUString::createFromAscii("small-caps"));
+
+ if(aContent.match(aStrNormal))
+ {
+ setFontVariant(FontVariant_normal);
+ }
+ else if(aContent.match(aStrSmallCaps))
+ {
+ setFontVariant(FontVariant_small_caps);
+ }
+ }
+ break;
+ }
+ case SVGTokenFontWeight:
+ {
+ if(aContent.getLength())
+ {
+ static rtl::OUString aStrNormal(rtl::OUString::createFromAscii("normal"));
+ static rtl::OUString aStrBold(rtl::OUString::createFromAscii("bold"));
+ static rtl::OUString aStrBolder(rtl::OUString::createFromAscii("bolder"));
+ static rtl::OUString aStrLighter(rtl::OUString::createFromAscii("lighter"));
+ static rtl::OUString aStr100(rtl::OUString::createFromAscii("100"));
+ static rtl::OUString aStr200(rtl::OUString::createFromAscii("200"));
+ static rtl::OUString aStr300(rtl::OUString::createFromAscii("300"));
+ static rtl::OUString aStr400(rtl::OUString::createFromAscii("400"));
+ static rtl::OUString aStr500(rtl::OUString::createFromAscii("500"));
+ static rtl::OUString aStr600(rtl::OUString::createFromAscii("600"));
+ static rtl::OUString aStr700(rtl::OUString::createFromAscii("700"));
+ static rtl::OUString aStr800(rtl::OUString::createFromAscii("800"));
+ static rtl::OUString aStr900(rtl::OUString::createFromAscii("900"));
+
+ if(aContent.match(aStr100))
+ {
+ setFontWeight(FontWeight_100);
+ }
+ else if(aContent.match(aStr200))
+ {
+ setFontWeight(FontWeight_200);
+ }
+ else if(aContent.match(aStr300))
+ {
+ setFontWeight(FontWeight_300);
+ }
+ else if(aContent.match(aStr400) || aContent.match(aStrNormal))
+ {
+ setFontWeight(FontWeight_400);
+ }
+ else if(aContent.match(aStr500))
+ {
+ setFontWeight(FontWeight_500);
+ }
+ else if(aContent.match(aStr600))
+ {
+ setFontWeight(FontWeight_600);
+ }
+ else if(aContent.match(aStr700) || aContent.match(aStrBold))
+ {
+ setFontWeight(FontWeight_700);
+ }
+ else if(aContent.match(aStr800))
+ {
+ setFontWeight(FontWeight_800);
+ }
+ else if(aContent.match(aStr900))
+ {
+ setFontWeight(FontWeight_900);
+ }
+ else if(aContent.match(aStrBolder))
+ {
+ setFontWeight(FontWeight_bolder);
+ }
+ else if(aContent.match(aStrLighter))
+ {
+ setFontWeight(FontWeight_lighter);
+ }
+ }
+ break;
+ }
+ case SVGTokenDirection:
+ {
+ bool bBla = true;
+ break;
+ }
+ case SVGTokenLetterSpacing:
+ {
+ bool bBla = true;
+ break;
+ }
+ case SVGTokenTextDecoration:
+ {
+ if(aContent.getLength())
+ {
+ static rtl::OUString aStrNone(rtl::OUString::createFromAscii("none"));
+ static rtl::OUString aStrUnderline(rtl::OUString::createFromAscii("underline"));
+ static rtl::OUString aStrOverline(rtl::OUString::createFromAscii("overline"));
+ static rtl::OUString aStrLineThrough(rtl::OUString::createFromAscii("line-through"));
+ static rtl::OUString aStrBlink(rtl::OUString::createFromAscii("blink"));
+
+ if(aContent.match(aStrNone))
+ {
+ setTextDecoration(TextDecoration_none);
+ }
+ else if(aContent.match(aStrUnderline))
+ {
+ setTextDecoration(TextDecoration_underline);
+ }
+ else if(aContent.match(aStrOverline))
+ {
+ setTextDecoration(TextDecoration_overline);
+ }
+ else if(aContent.match(aStrLineThrough))
+ {
+ setTextDecoration(TextDecoration_line_through);
+ }
+ else if(aContent.match(aStrBlink))
+ {
+ setTextDecoration(TextDecoration_blink);
+ }
+ }
+ break;
+ }
+ case SVGTokenUnicodeBidi:
+ {
+ bool bBla = true;
+ break;
+ }
+ case SVGTokenWordSpacing:
+ {
+ bool bBla = true;
+ break;
+ }
+ case SVGTokenTextAnchor:
+ {
+ if(aContent.getLength())
+ {
+ static rtl::OUString aStrStart(rtl::OUString::createFromAscii("start"));
+ static rtl::OUString aStrMiddle(rtl::OUString::createFromAscii("middle"));
+ static rtl::OUString aStrEnd(rtl::OUString::createFromAscii("end"));
+
+ if(aContent.match(aStrStart))
+ {
+ setTextAnchor(TextAnchor_start);
+ }
+ else if(aContent.match(aStrMiddle))
+ {
+ setTextAnchor(TextAnchor_middle);
+ }
+ else if(aContent.match(aStrEnd))
+ {
+ setTextAnchor(TextAnchor_end);
+ }
+ }
+ break;
+ }
+ case SVGTokenTextAlign:
+ {
+ if(aContent.getLength())
+ {
+ static rtl::OUString aStrLeft(rtl::OUString::createFromAscii("left"));
+ static rtl::OUString aStrRight(rtl::OUString::createFromAscii("right"));
+ static rtl::OUString aStrCenter(rtl::OUString::createFromAscii("center"));
+ static rtl::OUString aStrJustify(rtl::OUString::createFromAscii("justify"));
+
+ if(aContent.match(aStrLeft))
+ {
+ setTextAlign(TextAlign_left);
+ }
+ else if(aContent.match(aStrRight))
+ {
+ setTextAlign(TextAlign_right);
+ }
+ else if(aContent.match(aStrCenter))
+ {
+ setTextAlign(TextAlign_center);
+ }
+ else if(aContent.match(aStrJustify))
+ {
+ setTextAlign(TextAlign_justify);
+ }
+ }
+ break;
+ }
+ case SVGTokenColor:
+ {
+ SvgPaint aSvgPaint;
+ rtl::OUString aURL;
+
+ if(readSvgPaint(aContent, aSvgPaint, aURL))
+ {
+ setColor(aSvgPaint);
+ }
+ break;
+ }
+ case SVGTokenOpacity:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setOpacity(SvgNumber(basegfx::clamp(aNum.getNumber(), 0.0, 1.0), aNum.getUnit(), aNum.isSet()));
+ }
+ break;
+ }
+ case SVGTokenClipPathProperty:
+ {
+ readLocalUrl(aContent, maClipPathXLink);
+ break;
+ }
+ case SVGTokenMask:
+ {
+ readLocalUrl(aContent, maMaskXLink);
+ break;
+ }
+ case SVGTokenClipRule:
+ {
+ if(aContent.getLength())
+ {
+ if(aContent.match(commonStrings::aStrNonzero))
+ {
+ mbClipRule = true;
+ }
+ else if(aContent.match(commonStrings::aStrEvenOdd))
+ {
+ mbClipRule = false;
+ }
+ }
+ break;
+ }
+ case SVGTokenMarker:
+ {
+ readLocalUrl(aContent, maMarkerEndXLink);
+ maMarkerStartXLink = maMarkerMidXLink = maMarkerEndXLink;
+ break;
+ }
+ case SVGTokenMarkerStart:
+ {
+ readLocalUrl(aContent, maMarkerStartXLink);
+ break;
+ }
+ case SVGTokenMarkerMid:
+ {
+ readLocalUrl(aContent, maMarkerMidXLink);
+ break;
+ }
+ case SVGTokenMarkerEnd:
+ {
+ readLocalUrl(aContent, maMarkerEndXLink);
+ break;
+ }
+ }
+ }
+
+ const basegfx::BColor* SvgStyleAttributes::getFill() const
+ {
+ if(mbIsClipPathContent)
+ {
+ static basegfx::BColor aBlack(0.0, 0.0, 0.0);
+
+ return &aBlack;
+ }
+ else if(maFill.isSet())
+ {
+ if(maFill.isCurrent())
+ {
+ return getColor();
+ }
+ else if(maFill.isOn())
+ {
+ return &maFill.getBColor();
+ }
+ }
+ else
+ {
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getFill();
+ }
+ }
+
+ return 0;
+ }
+
+ const basegfx::BColor* SvgStyleAttributes::getStroke() const
+ {
+ if(mbIsClipPathContent)
+ {
+ return 0;
+ }
+ else if(maStroke.isSet())
+ {
+ if(maStroke.isCurrent())
+ {
+ return getColor();
+ }
+ else if(maStroke.isOn())
+ {
+ return &maStroke.getBColor();
+ }
+ }
+ else
+ {
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getStroke();
+ }
+ }
+
+ return 0;
+ }
+
+ const basegfx::BColor& SvgStyleAttributes::getStopColor() const
+ {
+ if(maStopColor.isCurrent())
+ {
+ return *getColor();
+ }
+ else
+ {
+ return maStopColor.getBColor();
+ }
+ }
+
+ const SvgGradientNode* SvgStyleAttributes::getSvgGradientNodeFill() const
+ {
+ if(mbIsClipPathContent)
+ {
+ return 0;
+ }
+ else if(mpSvgGradientNodeFill)
+ {
+ return mpSvgGradientNodeFill;
+ }
+ else
+ {
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getSvgGradientNodeFill();
+ }
+ }
+
+ return 0;
+ }
+
+ const SvgGradientNode* SvgStyleAttributes::getSvgGradientNodeStroke() const
+ {
+ if(mbIsClipPathContent)
+ {
+ return 0;
+ }
+ else if(mpSvgGradientNodeStroke)
+ {
+ return mpSvgGradientNodeStroke;
+ }
+ else
+ {
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getSvgGradientNodeStroke();
+ }
+ }
+
+ return 0;
+ }
+
+ const SvgPatternNode* SvgStyleAttributes::getSvgPatternNodeFill() const
+ {
+ if(mbIsClipPathContent)
+ {
+ return 0;
+ }
+ else if(mpSvgPatternNodeFill)
+ {
+ return mpSvgPatternNodeFill;
+ }
+ else
+ {
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getSvgPatternNodeFill();
+ }
+ }
+
+ return 0;
+ }
+
+ const SvgPatternNode* SvgStyleAttributes::getSvgPatternNodeStroke() const
+ {
+ if(mbIsClipPathContent)
+ {
+ return 0;
+ }
+ else if(mpSvgPatternNodeStroke)
+ {
+ return mpSvgPatternNodeStroke;
+ }
+ else
+ {
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getSvgPatternNodeStroke();
+ }
+ }
+
+ return 0;
+ }
+
+ const SvgNumber SvgStyleAttributes::getStrokeWidth() const
+ {
+ if(mbIsClipPathContent)
+ {
+ return SvgNumber(0.0);
+ }
+ else if(maStrokeWidth.isSet())
+ {
+ return maStrokeWidth;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getStrokeWidth();
+ }
+
+ // default is 1
+ return SvgNumber(1.0);
+ }
+
+ const SvgNumber SvgStyleAttributes::getStopOpacity() const
+ {
+ if(maStopOpacity.isSet())
+ {
+ return maStopOpacity;
+ }
+
+ // default is 1
+ return SvgNumber(1.0);
+ }
+
+ const SvgNumber SvgStyleAttributes::getFillOpacity() const
+ {
+ if(mbIsClipPathContent)
+ {
+ return SvgNumber(1.0);
+ }
+ else if(maFillOpacity.isSet())
+ {
+ return maFillOpacity;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getFillOpacity();
+ }
+
+ // default is 1
+ return SvgNumber(1.0);
+ }
+
+ bool SvgStyleAttributes::getFillRule() const
+ {
+ if(maFillRuleSet)
+ {
+ return maFillRule;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getFillRule();
+ }
+
+ // default is NonZero
+ return true;
+ }
+
+ void SvgStyleAttributes::setFillRule(const bool* pFillRule)
+ {
+ if(pFillRule)
+ {
+ maFillRuleSet = true;
+ maFillRule = *pFillRule;
+ }
+ else
+ {
+ maFillRuleSet = false;
+ }
+ }
+
+ const SvgNumberVector& SvgStyleAttributes::getStrokeDasharray() const
+ {
+ if(!maStrokeDasharray.empty())
+ {
+ return maStrokeDasharray;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getStrokeDasharray();
+ }
+
+ // default empty
+ return maStrokeDasharray;
+ }
+
+ const SvgNumber SvgStyleAttributes::getStrokeDashOffset() const
+ {
+ if(maStrokeDashOffset.isSet())
+ {
+ return maStrokeDashOffset;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getStrokeDashOffset();
+ }
+
+ // default is 0
+ return SvgNumber(0.0);
+ }
+
+ const StrokeLinecap SvgStyleAttributes::getStrokeLinecap() const
+ {
+ if(maStrokeLinecap != StrokeLinecap_notset)
+ {
+ return maStrokeLinecap;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getStrokeLinecap();
+ }
+
+ // default is StrokeLinecap_butt
+ return StrokeLinecap_butt;
+ }
+
+ const StrokeLinejoin SvgStyleAttributes::getStrokeLinejoin() const
+ {
+ if(maStrokeLinejoin != StrokeLinejoin_notset)
+ {
+ return maStrokeLinejoin;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getStrokeLinejoin();
+ }
+
+ // default is StrokeLinejoin_butt
+ return StrokeLinejoin_miter;
+ }
+
+ const SvgNumber SvgStyleAttributes::getStrokeMiterLimit() const
+ {
+ if(maStrokeMiterLimit.isSet())
+ {
+ return maStrokeMiterLimit;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getStrokeMiterLimit();
+ }
+
+ // default is 4
+ return SvgNumber(4.0);
+ }
+
+ const SvgNumber SvgStyleAttributes::getStrokeOpacity() const
+ {
+ if(maStrokeOpacity.isSet())
+ {
+ return maStrokeOpacity;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getStrokeOpacity();
+ }
+
+ // default is 1
+ return SvgNumber(1.0);
+ }
+
+ const SvgStringVector& SvgStyleAttributes::getFontFamily() const
+ {
+ if(!maFontFamily.empty())
+ {
+ return maFontFamily;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getFontFamily();
+ }
+
+ // default is empty
+ return maFontFamily;
+ }
+
+ const SvgNumber SvgStyleAttributes::getFontSize() const
+ {
+ if(maFontSize.isSet())
+ {
+ return maFontSize;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getFontSize();
+ }
+
+ // default is 'medium'
+ return SvgNumber(12.0);
+ }
+
+ const FontStretch SvgStyleAttributes::getFontStretch() const
+ {
+ if(maFontStretch != FontStretch_notset)
+ {
+ if(FontStretch_wider != maFontStretch && FontStretch_narrower != maFontStretch)
+ {
+ return maFontStretch;
+ }
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ FontStretch aInherited = pSvgStyleAttributes->getFontStretch();
+
+ if(FontStretch_wider == maFontStretch)
+ {
+ aInherited = getWider(aInherited);
+ }
+ else if(FontStretch_narrower == maFontStretch)
+ {
+ aInherited = getNarrower(aInherited);
+ }
+
+ return aInherited;
+ }
+
+ // default is FontStretch_normal
+ return FontStretch_normal;
+ }
+
+ const FontStyle SvgStyleAttributes::getFontStyle() const
+ {
+ if(maFontStyle != FontStyle_notset)
+ {
+ return maFontStyle;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getFontStyle();
+ }
+
+ // default is FontStyle_normal
+ return FontStyle_normal;
+ }
+
+ const FontWeight SvgStyleAttributes::getFontWeight() const
+ {
+ if(maFontWeight != FontWeight_notset)
+ {
+ if(FontWeight_bolder != maFontWeight && FontWeight_lighter != maFontWeight)
+ {
+ return maFontWeight;
+ }
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ FontWeight aInherited = pSvgStyleAttributes->getFontWeight();
+
+ if(FontWeight_bolder == maFontWeight)
+ {
+ aInherited = getBolder(aInherited);
+ }
+ else if(FontWeight_lighter == maFontWeight)
+ {
+ aInherited = getLighter(aInherited);
+ }
+
+ return aInherited;
+ }
+
+ // default is FontWeight_400 (FontWeight_normal)
+ return FontWeight_400;
+ }
+
+ const TextAlign SvgStyleAttributes::getTextAlign() const
+ {
+ if(maTextAlign != TextAlign_notset)
+ {
+ return maTextAlign;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getTextAlign();
+ }
+
+ // default is TextAlign_left
+ return TextAlign_left;
+ }
+
+ const SvgStyleAttributes* SvgStyleAttributes::getTextDecorationDefiningSvgStyleAttributes() const
+ {
+ if(maTextDecoration != TextDecoration_notset)
+ {
+ return this;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getTextDecorationDefiningSvgStyleAttributes();
+ }
+
+ // default is 0
+ return 0;
+ }
+
+ const TextDecoration SvgStyleAttributes::getTextDecoration() const
+ {
+ const SvgStyleAttributes* pDefining = getTextDecorationDefiningSvgStyleAttributes();
+
+ if(pDefining)
+ {
+ return pDefining->maTextDecoration;
+ }
+ else
+ {
+ // default is TextDecoration_none
+ return TextDecoration_none;
+ }
+ }
+
+ const TextAnchor SvgStyleAttributes::getTextAnchor() const
+ {
+ if(maTextAnchor != TextAnchor_notset)
+ {
+ return maTextAnchor;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getTextAnchor();
+ }
+
+ // default is TextAnchor_start
+ return TextAnchor_start;
+ }
+
+ const basegfx::BColor* SvgStyleAttributes::getColor() const
+ {
+ if(maColor.isSet())
+ {
+ if(maColor.isCurrent())
+ {
+ OSL_ENSURE(false, "Svg error: current color uses current color (!)");
+ return 0;
+ }
+ else if(maColor.isOn())
+ {
+ return &maColor.getBColor();
+ }
+ }
+ else
+ {
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getColor();
+ }
+ }
+
+ return 0;
+ }
+
+ const rtl::OUString SvgStyleAttributes::getMarkerStartXLink() const
+ {
+ if(maMarkerStartXLink.getLength())
+ {
+ return maMarkerStartXLink;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getMarkerStartXLink();
+ }
+
+ return rtl::OUString();
+ }
+
+ const SvgMarkerNode* SvgStyleAttributes::accessMarkerStartXLink() const
+ {
+ if(!mpMarkerStartXLink)
+ {
+ const rtl::OUString aMarker(getMarkerStartXLink());
+
+ if(aMarker.getLength())
+ {
+ const_cast< SvgStyleAttributes* >(this)->mpMarkerStartXLink = dynamic_cast< const SvgMarkerNode* >(mrOwner.getDocument().findSvgNodeById(getMarkerStartXLink()));
+ }
+ }
+
+ return mpMarkerStartXLink;
+ }
+
+ const rtl::OUString SvgStyleAttributes::getMarkerMidXLink() const
+ {
+ if(maMarkerMidXLink.getLength())
+ {
+ return maMarkerMidXLink;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getMarkerMidXLink();
+ }
+
+ return rtl::OUString();
+ }
+
+ const SvgMarkerNode* SvgStyleAttributes::accessMarkerMidXLink() const
+ {
+ if(!mpMarkerMidXLink)
+ {
+ const rtl::OUString aMarker(getMarkerMidXLink());
+
+ if(aMarker.getLength())
+ {
+ const_cast< SvgStyleAttributes* >(this)->mpMarkerMidXLink = dynamic_cast< const SvgMarkerNode* >(mrOwner.getDocument().findSvgNodeById(getMarkerMidXLink()));
+ }
+ }
+
+ return mpMarkerMidXLink;
+ }
+
+ const rtl::OUString SvgStyleAttributes::getMarkerEndXLink() const
+ {
+ if(maMarkerEndXLink.getLength())
+ {
+ return maMarkerEndXLink;
+ }
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+
+ if(pSvgStyleAttributes)
+ {
+ return pSvgStyleAttributes->getMarkerEndXLink();
+ }
+
+ return rtl::OUString();
+ }
+
+ const SvgMarkerNode* SvgStyleAttributes::accessMarkerEndXLink() const
+ {
+ if(!mpMarkerEndXLink)
+ {
+ const rtl::OUString aMarker(getMarkerEndXLink());
+
+ if(aMarker.getLength())
+ {
+ const_cast< SvgStyleAttributes* >(this)->mpMarkerEndXLink = dynamic_cast< const SvgMarkerNode* >(mrOwner.getDocument().findSvgNodeById(getMarkerEndXLink()));
+ }
+ }
+
+ return mpMarkerEndXLink;
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgstylenode.cxx b/svgio/source/svgreader/svgstylenode.cxx
new file mode 100644
index 000000000000..e670f4137a8f
--- /dev/null
+++ b/svgio/source/svgreader/svgstylenode.cxx
@@ -0,0 +1,115 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgstylenode.hxx>
+#include <svgio/svgreader/svgdocument.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgStyleNode::SvgStyleNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenStyle, rDocument, pParent),
+ maSvgStyleAttributes(),
+ mbTextCss(false)
+ {
+ }
+
+ SvgStyleNode::~SvgStyleNode()
+ {
+ while(!maSvgStyleAttributes.empty())
+ {
+ delete *(maSvgStyleAttributes.end() - 1);
+ maSvgStyleAttributes.pop_back();
+ }
+ }
+
+ void SvgStyleNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenType:
+ {
+ if(aContent.getLength())
+ {
+ static rtl::OUString aStrTextCss(rtl::OUString::createFromAscii("text/css"));
+
+ if(aContent.match(aStrTextCss))
+ {
+ setTextCss(true);
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ void SvgStyleNode::addCssStyleSheet(const rtl::OUString& aContent)
+ {
+ const sal_Int32 nLen(aContent.getLength());
+
+ if(nLen)
+ {
+ sal_Int32 nPos(0);
+ rtl::OUStringBuffer aTokenValue;
+
+ skip_char(aContent, sal_Unicode(' '), sal_Unicode('#'), nPos, nLen);
+ copyToLimiter(aContent, sal_Unicode('{'), nPos, aTokenValue, nLen);
+ const rtl::OUString aStyleName = aTokenValue.makeStringAndClear().trim();
+
+ if(aStyleName.getLength())
+ {
+ skip_char(aContent, sal_Unicode(' '), sal_Unicode('{'), nPos, nLen);
+ copyToLimiter(aContent, sal_Unicode('}'), nPos, aTokenValue, nLen);
+ const rtl::OUString aStyleContent = aTokenValue.makeStringAndClear().trim();
+
+ if(aStyleContent.getLength())
+ {
+ // create new style
+ SvgStyleAttributes* pNewStyle = new SvgStyleAttributes(*this);
+ maSvgStyleAttributes.push_back(pNewStyle);
+
+ // fill with content
+ pNewStyle->readStyle(aStyleContent);
+
+ // register new style at document
+ const_cast< SvgDocument& >(getDocument()).addSvgStyleAttributesToMapper(aStyleName, *pNewStyle);
+ }
+ }
+ }
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgsvgnode.cxx b/svgio/source/svgreader/svgsvgnode.cxx
new file mode 100644
index 000000000000..eadbe7705772
--- /dev/null
+++ b/svgio/source/svgreader/svgsvgnode.cxx
@@ -0,0 +1,395 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgsvgnode.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgSvgNode::SvgSvgNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenSvg, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ mpViewBox(0),
+ maSvgAspectRatio(),
+ maX(),
+ maY(),
+ maWidth(),
+ maHeight(),
+ maVersion()
+ {
+ if(!getParent())
+ {
+ // initial fill is black
+ maSvgStyleAttributes.setFill(SvgPaint(basegfx::BColor(0.0, 0.0, 0.0), true, true));
+ }
+ }
+
+ SvgSvgNode::~SvgSvgNode()
+ {
+ if(mpViewBox) delete mpViewBox;
+ }
+
+ const SvgStyleAttributes* SvgSvgNode::getSvgStyleAttributes() const
+ {
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgSvgNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenViewBox:
+ {
+ const basegfx::B2DRange aRange(readViewBox(aContent, *this));
+
+ if(!aRange.isEmpty())
+ {
+ setViewBox(&aRange);
+ }
+ break;
+ }
+ case SVGTokenPreserveAspectRatio:
+ {
+ setSvgAspectRatio(readSvgAspectRatio(aContent));
+ break;
+ }
+ case SVGTokenX:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setX(aNum);
+ }
+ break;
+ }
+ case SVGTokenY:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setY(aNum);
+ }
+ break;
+ }
+ case SVGTokenWidth:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setWidth(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenHeight:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setHeight(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenVersion:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setVersion(aNum);
+ }
+ break;
+ }
+ }
+ }
+
+ void SvgSvgNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aSequence;
+
+ // decompose childs
+ SvgNode::decomposeSvgNode(aSequence, bReferenced);
+
+ if(aSequence.hasElements())
+ {
+ if(getParent())
+ {
+ if(getViewBox())
+ {
+ // Svg defines that with no width or no height the viewBox content is empty,
+ // so both need to exist
+ if(!basegfx::fTools::equalZero(getViewBox()->getWidth()) && !basegfx::fTools::equalZero(getViewBox()->getHeight()))
+ {
+ // create target range homing x,y, width and height as given
+ const double fX(getX().isSet() ? getX().solve(*this, xcoordinate) : 0.0);
+ const double fY(getY().isSet() ? getY().solve(*this, ycoordinate) : 0.0);
+ const double fW(getWidth().isSet() ? getWidth().solve(*this, xcoordinate) : getViewBox()->getWidth());
+ const double fH(getHeight().isSet() ? getHeight().solve(*this, ycoordinate) : getViewBox()->getHeight());
+ const basegfx::B2DRange aTarget(fX, fY, fX + fW, fY + fH);
+
+ if(aTarget.equal(*getViewBox()))
+ {
+ // no mapping needed, append
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aSequence);
+ }
+ else
+ {
+ // create mapping
+ const SvgAspectRatio& rRatio = getSvgAspectRatio();
+
+ if(rRatio.isSet())
+ {
+ // let mapping be created from SvgAspectRatio
+ const basegfx::B2DHomMatrix aEmbeddingTransform(
+ rRatio.createMapping(aTarget, *getViewBox()));
+
+ // prepare embedding in transformation
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ aEmbeddingTransform,
+ aSequence));
+
+ if(rRatio.isMeetOrSlice())
+ {
+ // embed in transformation
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(rTarget, xRef);
+ }
+ else
+ {
+ // need to embed in MaskPrimitive2D, too
+ const drawinglayer::primitive2d::Primitive2DReference xMask(
+ new drawinglayer::primitive2d::MaskPrimitive2D(
+ basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(aTarget)),
+ drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1)));
+
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(rTarget, xMask);
+ }
+ }
+ else
+ {
+ // choose default mapping
+ const basegfx::B2DHomMatrix aEmbeddingTransform(
+ rRatio.createLinearMapping(
+ aTarget, *getViewBox()));
+
+ // embed in transformation
+ const drawinglayer::primitive2d::Primitive2DReference xTransform(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ aEmbeddingTransform,
+ aSequence));
+
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(rTarget, xTransform);
+ }
+ }
+ }
+ }
+ else
+ {
+ // check if we have a size
+ const double fW(getWidth().isSet() ? getWidth().solve(*this, xcoordinate) : 0.0);
+ const double fH(getHeight().isSet() ? getHeight().solve(*this, ycoordinate) : 0.0);
+
+ // Svg defines that a negative value is an error and that 0.0 disables rendering
+ if(basegfx::fTools::more(fW, 0.0) && basegfx::fTools::more(fH, 0.0))
+ {
+ // check if we have a x,y position
+ const double fX(getX().isSet() ? getX().solve(*this, xcoordinate) : 0.0);
+ const double fY(getY().isSet() ? getY().solve(*this, ycoordinate) : 0.0);
+
+ if(!basegfx::fTools::equalZero(fX) || !basegfx::fTools::equalZero(fY))
+ {
+ // embed in transform
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ basegfx::tools::createTranslateB2DHomMatrix(fX, fY),
+ aSequence));
+
+ aSequence = drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1);
+ }
+
+ // embed in MaskPrimitive2D to clip
+ const drawinglayer::primitive2d::Primitive2DReference xMask(
+ new drawinglayer::primitive2d::MaskPrimitive2D(
+ basegfx::B2DPolyPolygon(
+ basegfx::tools::createPolygonFromRect(
+ basegfx::B2DRange(fX, fY, fX + fW, fY + fH))),
+ aSequence));
+
+ // append
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(rTarget, xMask);
+ }
+ }
+ }
+ else
+ {
+ // Outermost SVG element; create target range homing width and height as given.
+ // SVG defines that x,y has no meanig for the outermost SVG element. Use a fallback
+ // width and height of din A 4 (21 x 29,7 cm)
+ double fW(getWidth().isSet() ? getWidth().solve(*this, xcoordinate) : (210.0 * 3.543307));
+ double fH(getHeight().isSet() ? getHeight().solve(*this, ycoordinate) : (297.0 * 3.543307));
+
+ // Svg defines that a negative value is an error and that 0.0 disables rendering
+ if(basegfx::fTools::more(fW, 0.0) && basegfx::fTools::more(fH, 0.0))
+ {
+ const basegfx::B2DRange aSvgCanvasRange(0.0, 0.0, fW, fH);
+
+ if(getViewBox())
+ {
+ if(!basegfx::fTools::equalZero(getViewBox()->getWidth()) && !basegfx::fTools::equalZero(getViewBox()->getHeight()))
+ {
+ // create mapping
+ const SvgAspectRatio& rRatio = getSvgAspectRatio();
+ basegfx::B2DHomMatrix aViewBoxMapping;
+
+ if(rRatio.isSet())
+ {
+ // let mapping be created from SvgAspectRatio
+ aViewBoxMapping = rRatio.createMapping(aSvgCanvasRange, *getViewBox());
+
+ // no need to check ratio here for slice, the outermost Svg will
+ // be clipped anyways (see below)
+ }
+ else
+ {
+ // choose default mapping
+ aViewBoxMapping = rRatio.createLinearMapping(aSvgCanvasRange, *getViewBox());
+ }
+
+ // scale content to viewBox definitions
+ const drawinglayer::primitive2d::Primitive2DReference xTransform(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ aViewBoxMapping,
+ aSequence));
+
+ aSequence = drawinglayer::primitive2d::Primitive2DSequence(&xTransform, 1);
+ }
+ }
+
+ // to be completely correct in Svg sense it is necessary to clip
+ // the whole content to the given canvas. I choose here to do this
+ // initially despite I found various examples of Svg files out there
+ // which have no correct values for this clipping. It's correct
+ // due to the Svg spec.
+ bool bDoCorrectCanvasClipping(true);
+
+ if(bDoCorrectCanvasClipping)
+ {
+ // different from Svg we have the possibility with primitives to get
+ // a correct bounding box for the geometry, thhus I will allow to
+ // only clip if necessary. This will make Svg images evtl. smaller
+ // than wanted from Svg (the free space which may be around it is
+ // conform to the Svg spec), but avoids an expensive and unneccessary
+ // clip.
+ const basegfx::B2DRange aContentRange(
+ drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(
+ aSequence,
+ drawinglayer::geometry::ViewInformation2D()));
+
+ if(!aSvgCanvasRange.isInside(aContentRange))
+ {
+ const drawinglayer::primitive2d::Primitive2DReference xMask(
+ new drawinglayer::primitive2d::MaskPrimitive2D(
+ basegfx::B2DPolyPolygon(
+ basegfx::tools::createPolygonFromRect(
+ aSvgCanvasRange)),
+ aSequence));
+
+ aSequence = drawinglayer::primitive2d::Primitive2DSequence(&xMask, 1);
+ }
+ }
+
+ {
+ // embed in transform primitive to scale to 1/100th mm
+ // where 1 mm == 3.543307 px to get from Svg coordinates to
+ // drawinglayer ones
+ const double fScaleTo100thmm(100.0 / 3.543307);
+ const basegfx::B2DHomMatrix aTransform(
+ basegfx::tools::createScaleB2DHomMatrix(
+ fScaleTo100thmm,
+ fScaleTo100thmm));
+
+ const drawinglayer::primitive2d::Primitive2DReference xTransform(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ aTransform,
+ aSequence));
+
+ aSequence = drawinglayer::primitive2d::Primitive2DSequence(&xTransform, 1);
+ }
+
+ // append
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aSequence);
+ }
+ }
+ }
+ }
+
+ const basegfx::B2DRange* SvgSvgNode::getCurrentViewPort() const
+ {
+ if(getViewBox())
+ {
+ return getViewBox();
+ }
+ else
+ {
+ return SvgNode::getCurrentViewPort();
+ }
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgsymbolnode.cxx b/svgio/source/svgreader/svgsymbolnode.cxx
new file mode 100644
index 000000000000..39da059285f4
--- /dev/null
+++ b/svgio/source/svgreader/svgsymbolnode.cxx
@@ -0,0 +1,93 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgsymbolnode.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgSymbolNode::SvgSymbolNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenSvg, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ mpViewBox(0),
+ maSvgAspectRatio()
+ {
+ }
+
+ SvgSymbolNode::~SvgSymbolNode()
+ {
+ if(mpViewBox) delete mpViewBox;
+ }
+
+ const SvgStyleAttributes* SvgSymbolNode::getSvgStyleAttributes() const
+ {
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgSymbolNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenViewBox:
+ {
+ const basegfx::B2DRange aRange(readViewBox(aContent, *this));
+
+ if(!aRange.isEmpty())
+ {
+ setViewBox(&aRange);
+ }
+ break;
+ }
+ case SVGTokenPreserveAspectRatio:
+ {
+ setSvgAspectRatio(readSvgAspectRatio(aContent));
+ break;
+ }
+ }
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgtextnode.cxx b/svgio/source/svgreader/svgtextnode.cxx
new file mode 100644
index 000000000000..903a485016f5
--- /dev/null
+++ b/svgio/source/svgreader/svgtextnode.cxx
@@ -0,0 +1,273 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgtextnode.hxx>
+#include <svgio/svgreader/svgcharacternode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+#include <svgio/svgreader/svgtrefnode.hxx>
+#include <svgio/svgreader/svgtextpathnode.hxx>
+#include <svgio/svgreader/svgtspannode.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgTextNode::SvgTextNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenText, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ mpaTransform(0),
+ maSvgTextPositions()
+ {
+ }
+
+ SvgTextNode::~SvgTextNode()
+ {
+ if(mpaTransform) delete mpaTransform;
+ }
+
+ const SvgStyleAttributes* SvgTextNode::getSvgStyleAttributes() const
+ {
+ static rtl::OUString aClassStr(rtl::OUString::createFromAscii("text"));
+ maSvgStyleAttributes.checkForCssStyle(aClassStr);
+
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgTextNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // read text position attributes
+ maSvgTextPositions.parseTextPositionAttributes(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenTransform:
+ {
+ const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
+
+ if(!aMatrix.isIdentity())
+ {
+ setTransform(&aMatrix);
+ }
+ break;
+ }
+ }
+ }
+
+ void SvgTextNode::addTextPrimitives(
+ const SvgNode& rCandidate,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ drawinglayer::primitive2d::Primitive2DSequence& rSource) const
+ {
+ if(rSource.hasElements())
+ {
+ const SvgStyleAttributes* pAttributes = rCandidate.getSvgStyleAttributes();
+
+ if(pAttributes)
+ {
+ // add text with taking all Fill/Stroke attributes into account
+ pAttributes->add_text(rTarget, rSource);
+ }
+ else
+ {
+ // should not happen, every subnode from SvgTextNode will at least
+ // return the attributes from SvgTextNode. Nonetheless, add text
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, rSource);
+ }
+ }
+ }
+
+ void SvgTextNode::DecomposeChild(const SvgNode& rCandidate, drawinglayer::primitive2d::Primitive2DSequence& rTarget, SvgTextPosition& rSvgTextPosition) const
+ {
+ switch(rCandidate.getType())
+ {
+ case SVGTokenCharacter:
+ {
+ // direct SvgTextPathNode derivates, decompose them
+ const SvgCharacterNode& rSvgCharacterNode = static_cast< const SvgCharacterNode& >(rCandidate);
+ rSvgCharacterNode.decomposeText(rTarget, rSvgTextPosition);
+ break;
+ }
+ case SVGTokenTextPath:
+ {
+ // direct TextPath decompose
+ const SvgTextPathNode& rSvgTextPathNode = static_cast< const SvgTextPathNode& >(rCandidate);
+ const SvgNodeVector& rChildren = rSvgTextPathNode.getChildren();
+ const sal_uInt32 nCount(rChildren.size());
+
+ if(nCount && rSvgTextPathNode.isValid())
+ {
+ // remember original TextStart to later detect hor/ver offsets
+ const basegfx::B2DPoint aTextStart(rSvgTextPosition.getPosition());
+ drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
+
+ // decompose to regular TextPrimitives
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ DecomposeChild(*rChildren[a], aNewTarget, rSvgTextPosition);
+ }
+
+ if(aNewTarget.hasElements())
+ {
+ const drawinglayer::primitive2d::Primitive2DSequence aPathContent(aNewTarget);
+ aNewTarget.realloc(0);
+
+ // dismantle TextPrimitives and map them on curve/path
+ rSvgTextPathNode.decomposePathNode(aPathContent, aNewTarget, aTextStart);
+ }
+
+ if(aNewTarget.hasElements())
+ {
+ addTextPrimitives(rCandidate, rTarget, aNewTarget);
+ }
+ }
+
+ break;
+ }
+ case SVGTokenTspan:
+ {
+ // Tspan may have children, call recursively
+ const SvgTspanNode& rSvgTspanNode = static_cast< const SvgTspanNode& >(rCandidate);
+ const SvgNodeVector& rChildren = rSvgTspanNode.getChildren();
+ const sal_uInt32 nCount(rChildren.size());
+
+ if(nCount)
+ {
+ SvgTextPosition aSvgTextPosition(&rSvgTextPosition, rSvgTspanNode, rSvgTspanNode.getSvgTextPositions());
+ drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
+
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ DecomposeChild(*rChildren[a], aNewTarget, aSvgTextPosition);
+ }
+
+ rSvgTextPosition.setPosition(aSvgTextPosition.getPosition());
+
+ if(aNewTarget.hasElements())
+ {
+ addTextPrimitives(rCandidate, rTarget, aNewTarget);
+ }
+ }
+ break;
+ }
+ case SVGTokenTref:
+ {
+ const SvgTrefNode& rSvgTrefNode = static_cast< const SvgTrefNode& >(rCandidate);
+ const SvgTextNode* pRefText = rSvgTrefNode.getReferencedSvgTextNode();
+
+ if(pRefText)
+ {
+ const SvgNodeVector& rChildren = pRefText->getChildren();
+ const sal_uInt32 nCount(rChildren.size());
+ drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
+
+ if(nCount)
+ {
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ const SvgNode& rChildCandidate = *rChildren[a];
+ const_cast< SvgNode& >(rChildCandidate).setAlternativeParent(this);
+
+ DecomposeChild(rChildCandidate, aNewTarget, rSvgTextPosition);
+ const_cast< SvgNode& >(rChildCandidate).setAlternativeParent(0);
+ }
+
+ if(aNewTarget.hasElements())
+ {
+ addTextPrimitives(rCandidate, rTarget, aNewTarget);
+ }
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ OSL_ENSURE(false, "Unexpected node in text token (!)");
+ break;
+ }
+ }
+ }
+
+ void SvgTextNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
+ {
+ // text has a group of child nodes, allowed are SVGTokenCharacter, SVGTokenTspan,
+ // SVGTokenTref and SVGTokenTextPath. These increase a given current text position
+ const SvgStyleAttributes* pStyle = getSvgStyleAttributes();
+
+ if(pStyle && !getChildren().empty())
+ {
+ const double fOpacity(pStyle->getOpacity().getNumber());
+
+ if(fOpacity > 0.0)
+ {
+ SvgTextPosition aSvgTextPosition(0, *this, getSvgTextPositions());
+ drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
+ const SvgNodeVector& rChildren = getChildren();
+ const sal_uInt32 nCount(rChildren.size());
+
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ const SvgNode& rCandidate = *rChildren[a];
+
+ DecomposeChild(rCandidate, aNewTarget, aSvgTextPosition);
+ }
+
+ if(aNewTarget.hasElements())
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aNewTarget2;
+
+ addTextPrimitives(*this, aNewTarget2, aNewTarget);
+ aNewTarget = aNewTarget2;
+ }
+
+ if(aNewTarget.hasElements())
+ {
+ pStyle->add_postProcess(rTarget, aNewTarget, getTransform());
+ }
+ }
+ }
+ }
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgtextpathnode.cxx b/svgio/source/svgreader/svgtextpathnode.cxx
new file mode 100644
index 000000000000..b84ba940236e
--- /dev/null
+++ b/svgio/source/svgreader/svgtextpathnode.cxx
@@ -0,0 +1,510 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgtextpathnode.hxx>
+#include <svgio/svgreader/svgstyleattributes.hxx>
+#include <svgio/svgreader/svgpathnode.hxx>
+#include <svgio/svgreader/svgdocument.hxx>
+#include <svgio/svgreader/svgtrefnode.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <drawinglayer/primitive2d/textbreakuphelper.hxx>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
+#include <basegfx/curve/b2dcubicbezier.hxx>
+#include <basegfx/curve/b2dbeziertools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class pathTextBreakupHelper : public drawinglayer::primitive2d::TextBreakupHelper
+ {
+ private:
+ const basegfx::B2DPolygon& mrPolygon;
+ const double mfBasegfxPathLength;
+ const double mfUserToBasegfx;
+ double mfPosition;
+ const basegfx::B2DPoint& mrTextStart;
+
+ const sal_uInt32 mnMaxIndex;
+ sal_uInt32 mnIndex;
+ basegfx::B2DCubicBezier maCurrentSegment;
+ basegfx::B2DCubicBezierHelper* mpB2DCubicBezierHelper;
+ double mfCurrentSegmentLength;
+ double mfSegmentStartPosition;
+
+ protected:
+ /// allow user callback to allow changes to the new TextTransformation. Default
+ /// does nothing.
+ virtual bool allowChange(sal_uInt32 nCount, basegfx::B2DHomMatrix& rNewTransform, sal_uInt32 nIndex, sal_uInt32 nLength);
+
+ void freeB2DCubicBezierHelper();
+ basegfx::B2DCubicBezierHelper* getB2DCubicBezierHelper();
+ void advanceToPosition(double fNewPosition);
+
+ public:
+ pathTextBreakupHelper(
+ const drawinglayer::primitive2d::Primitive2DReference& rxSource,
+ const basegfx::B2DPolygon& rPolygon,
+ const double fBasegfxPathLength,
+ const double fUserToBasegfx,
+ double fPosition,
+ const basegfx::B2DPoint& rTextStart);
+ virtual ~pathTextBreakupHelper();
+
+ // read access to evtl. advanced position
+ double getPosition() const { return mfPosition; }
+
+ // get length of given text
+ double getLength(const rtl::OUString& rText) const;
+ };
+
+ double pathTextBreakupHelper::getLength(const rtl::OUString& rText) const
+ {
+ const sal_uInt32 nLength(rText.getLength());
+
+ if(nLength)
+ {
+ return getTextLayouter().getTextWidth(rText, 0, nLength);
+ }
+
+ return 0.0;
+ }
+
+ void pathTextBreakupHelper::freeB2DCubicBezierHelper()
+ {
+ if(mpB2DCubicBezierHelper)
+ {
+ delete mpB2DCubicBezierHelper;
+ mpB2DCubicBezierHelper = 0;
+ }
+ }
+
+ basegfx::B2DCubicBezierHelper* pathTextBreakupHelper::getB2DCubicBezierHelper()
+ {
+ if(!mpB2DCubicBezierHelper && maCurrentSegment.isBezier())
+ {
+ mpB2DCubicBezierHelper = new basegfx::B2DCubicBezierHelper(maCurrentSegment);
+ }
+
+ return mpB2DCubicBezierHelper;
+ }
+
+ void pathTextBreakupHelper::advanceToPosition(double fNewPosition)
+ {
+ while(mfSegmentStartPosition + mfCurrentSegmentLength < fNewPosition && mnIndex < mnMaxIndex)
+ {
+ mfSegmentStartPosition += mfCurrentSegmentLength;
+ mnIndex++;
+
+ if(mnIndex < mnMaxIndex)
+ {
+ freeB2DCubicBezierHelper();
+ mrPolygon.getBezierSegment(mnIndex % mrPolygon.count(), maCurrentSegment);
+ maCurrentSegment.testAndSolveTrivialBezier();
+ mfCurrentSegmentLength = getB2DCubicBezierHelper()
+ ? getB2DCubicBezierHelper()->getLength()
+ : maCurrentSegment.getLength();
+ }
+ }
+
+ mfPosition = fNewPosition;
+ }
+
+ pathTextBreakupHelper::pathTextBreakupHelper(
+ const drawinglayer::primitive2d::Primitive2DReference& rxSource,
+ const basegfx::B2DPolygon& rPolygon,
+ const double fBasegfxPathLength,
+ const double fUserToBasegfx,
+ double fPosition,
+ const basegfx::B2DPoint& rTextStart)
+ : drawinglayer::primitive2d::TextBreakupHelper(rxSource),
+ mrPolygon(rPolygon),
+ mfBasegfxPathLength(fBasegfxPathLength),
+ mfUserToBasegfx(fUserToBasegfx),
+ mfPosition(0.0),
+ mrTextStart(rTextStart),
+ mnMaxIndex(rPolygon.isClosed() ? rPolygon.count() : rPolygon.count() - 1),
+ mnIndex(0),
+ maCurrentSegment(),
+ mpB2DCubicBezierHelper(0),
+ mfCurrentSegmentLength(0.0),
+ mfSegmentStartPosition(0.0)
+ {
+ mrPolygon.getBezierSegment(mnIndex % mrPolygon.count(), maCurrentSegment);
+ mfCurrentSegmentLength = maCurrentSegment.getLength();
+
+ advanceToPosition(fPosition);
+ }
+
+ pathTextBreakupHelper::~pathTextBreakupHelper()
+ {
+ freeB2DCubicBezierHelper();
+ }
+
+ bool pathTextBreakupHelper::allowChange(sal_uInt32 nCount, basegfx::B2DHomMatrix& rNewTransform, sal_uInt32 nIndex, sal_uInt32 nLength)
+ {
+ bool bRetval(false);
+
+ if(mfPosition < mfBasegfxPathLength && nLength && getCastedSource() && mnIndex < mnMaxIndex)
+ {
+ const double fSnippetWidth(
+ getTextLayouter().getTextWidth(
+ getCastedSource()->getText(),
+ nIndex,
+ nLength));
+
+ if(basegfx::fTools::more(fSnippetWidth, 0.0))
+ {
+ const ::rtl::OUString aText(getCastedSource()->getText());
+ const ::rtl::OUString aTrimmedChars(aText.copy(nIndex, nLength).trim());
+ const double fEndPos(mfPosition + fSnippetWidth);
+
+ if(aTrimmedChars.getLength() && (mfPosition < mfBasegfxPathLength || fEndPos > 0.0))
+ {
+ const double fHalfSnippetWidth(fSnippetWidth * 0.5);
+
+ advanceToPosition(mfPosition + fHalfSnippetWidth);
+
+ // create representation for this snippet
+ bRetval = true;
+
+ // get target position and tangent in that pint
+ basegfx::B2DPoint aPosition(0.0, 0.0);
+ basegfx::B2DVector aTangent(0.0, 1.0);
+
+ if(mfPosition < 0.0)
+ {
+ // snippet center is left of first segment, but right edge is on it (SVG allows that)
+ aTangent = maCurrentSegment.getTangent(0.0);
+ aTangent.normalize();
+ aPosition = maCurrentSegment.getStartPoint() + (aTangent * (mfPosition - mfSegmentStartPosition));
+ }
+ else if(mfPosition > mfBasegfxPathLength)
+ {
+ // snippet center is right of last segment, but left edge is on it (SVG allows that)
+ aTangent = maCurrentSegment.getTangent(1.0);
+ aTangent.normalize();
+ aPosition = maCurrentSegment.getEndPoint() + (aTangent * (mfPosition - mfSegmentStartPosition));
+ }
+ else
+ {
+ // snippet center inside segment, interpolate
+ double fBezierDistance(mfPosition - mfSegmentStartPosition);
+
+ if(getB2DCubicBezierHelper())
+ {
+ // use B2DCubicBezierHelper to bridge the non-linear gap between
+ // length and bezier distances (if it's a bezier segment)
+ fBezierDistance = getB2DCubicBezierHelper()->distanceToRelative(fBezierDistance);
+ }
+ else
+ {
+ // linear relationship, make relative to segment length
+ fBezierDistance = fBezierDistance / mfCurrentSegmentLength;
+ }
+
+ aPosition = maCurrentSegment.interpolatePoint(fBezierDistance);
+ aTangent = maCurrentSegment.getTangent(fBezierDistance);
+ aTangent.normalize();
+ }
+
+ // detect evtl. hor/ver translations (depends on text direction)
+ const basegfx::B2DPoint aBasePoint(rNewTransform * basegfx::B2DPoint(0.0, 0.0));
+ const basegfx::B2DVector aOffset(aBasePoint - mrTextStart);
+
+ if(!basegfx::fTools::equalZero(aOffset.getY()))
+ {
+ // ...and apply
+ aPosition.setY(aPosition.getY() + aOffset.getY());
+ }
+
+ // move target position from snippet center to left text start
+ aPosition -= fHalfSnippetWidth * aTangent;
+
+ // remove current translation
+ rNewTransform.translate(-aBasePoint.getX(), -aBasePoint.getY());
+
+ // rotate due to tangent
+ rNewTransform.rotate(atan2(aTangent.getY(), aTangent.getX()));
+
+ // add new translation
+ rNewTransform.translate(aPosition.getX(), aPosition.getY());
+ }
+
+ // advance to end
+ advanceToPosition(fEndPos);
+ }
+ }
+
+ return bRetval;
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgTextPathNode::SvgTextPathNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenTextPath, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ maXLink(),
+ maStartOffset(),
+ mbMethod(true),
+ mbSpacing(false)
+ {
+ }
+
+ SvgTextPathNode::~SvgTextPathNode()
+ {
+ }
+
+ const SvgStyleAttributes* SvgTextPathNode::getSvgStyleAttributes() const
+ {
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgTextPathNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenStartOffset:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setStartOffset(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenMethod:
+ {
+ if(aContent.getLength())
+ {
+ static rtl::OUString aStrAlign(rtl::OUString::createFromAscii("align"));
+ static rtl::OUString aStrStretch(rtl::OUString::createFromAscii("stretch"));
+
+ if(aContent.match(aStrAlign))
+ {
+ setMethod(true);
+ }
+ else if(aContent.match(aStrStretch))
+ {
+ setMethod(false);
+ }
+ }
+ break;
+ }
+ case SVGTokenSpacing:
+ {
+ if(aContent.getLength())
+ {
+ static rtl::OUString aStrAuto(rtl::OUString::createFromAscii("auto"));
+ static rtl::OUString aStrExact(rtl::OUString::createFromAscii("exact"));
+
+ if(aContent.match(aStrAuto))
+ {
+ setSpacing(true);
+ }
+ else if(aContent.match(aStrExact))
+ {
+ setSpacing(false);
+ }
+ }
+ break;
+ }
+ case SVGTokenXlinkHref:
+ {
+ const sal_Int32 nLen(aContent.getLength());
+
+ if(nLen && sal_Unicode('#') == aContent[0])
+ {
+ maXLink = aContent.copy(1);
+ }
+ break;
+ }
+ }
+ }
+
+ bool SvgTextPathNode::isValid() const
+ {
+ const SvgPathNode* pSvgPathNode = dynamic_cast< const SvgPathNode* >(getDocument().findSvgNodeById(maXLink));
+
+ if(!pSvgPathNode)
+ {
+ return false;
+ }
+
+ const basegfx::B2DPolyPolygon* pPolyPolyPath = pSvgPathNode->getPath();
+
+ if(!pPolyPolyPath || !pPolyPolyPath->count())
+ {
+ return false;
+ }
+
+ const basegfx::B2DPolygon aPolygon(pPolyPolyPath->getB2DPolygon(0));
+
+ if(!aPolygon.count())
+ {
+ return false;
+ }
+
+ const double fBasegfxPathLength(basegfx::tools::getLength(aPolygon));
+
+ if(basegfx::fTools::equalZero(fBasegfxPathLength))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ void SvgTextPathNode::decomposePathNode(
+ const drawinglayer::primitive2d::Primitive2DSequence& rPathContent,
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const basegfx::B2DPoint& rTextStart) const
+ {
+ if(rPathContent.hasElements())
+ {
+ const SvgPathNode* pSvgPathNode = dynamic_cast< const SvgPathNode* >(getDocument().findSvgNodeById(maXLink));
+
+ if(pSvgPathNode)
+ {
+ const basegfx::B2DPolyPolygon* pPolyPolyPath = pSvgPathNode->getPath();
+
+ if(pPolyPolyPath && pPolyPolyPath->count())
+ {
+ basegfx::B2DPolygon aPolygon(pPolyPolyPath->getB2DPolygon(0));
+
+ if(pSvgPathNode->getTransform())
+ {
+ aPolygon.transform(*pSvgPathNode->getTransform());
+ }
+
+ const double fBasegfxPathLength(basegfx::tools::getLength(aPolygon));
+
+ if(!basegfx::fTools::equalZero(fBasegfxPathLength))
+ {
+ double fUserToBasegfx(1.0); // multiply: user->basegfx, divide: basegfx->user
+
+ if(pSvgPathNode->getPathLength().isSet())
+ {
+ const double fUserLength(pSvgPathNode->getPathLength().solve(*this, length));
+
+ if(fUserLength > 0.0 && !basegfx::fTools::equal(fUserLength, fBasegfxPathLength))
+ {
+ fUserToBasegfx = fUserLength / fBasegfxPathLength;
+ }
+ }
+
+ double fPosition(0.0);
+
+ if(getStartOffset().isSet())
+ {
+ if(Unit_percent == getStartOffset().getUnit())
+ {
+ // percent are relative to path length
+ fPosition = getStartOffset().getNumber() * 0.01 * fBasegfxPathLength;
+ }
+ else
+ {
+ fPosition = getStartOffset().solve(*this, length) * fUserToBasegfx;
+ }
+ }
+
+ if(fPosition >= 0.0)
+ {
+ const sal_Int32 nLength(rPathContent.getLength());
+ sal_Int32 nCurrent(0);
+
+ while(fPosition < fBasegfxPathLength && nCurrent < nLength)
+ {
+ const drawinglayer::primitive2d::TextSimplePortionPrimitive2D* pCandidate = 0;
+ const drawinglayer::primitive2d::Primitive2DReference xReference(rPathContent[nCurrent]);
+
+ if(xReference.is())
+ {
+ pCandidate = dynamic_cast< const drawinglayer::primitive2d::TextSimplePortionPrimitive2D* >(xReference.get());
+ }
+
+ if(pCandidate)
+ {
+ pathTextBreakupHelper aPathTextBreakupHelper(
+ xReference,
+ aPolygon,
+ fBasegfxPathLength,
+ fUserToBasegfx,
+ fPosition,
+ rTextStart);
+
+ const drawinglayer::primitive2d::Primitive2DSequence aResult(
+ aPathTextBreakupHelper.getResult(drawinglayer::primitive2d::BreakupUnit_character));
+
+ if(aResult.hasElements())
+ {
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aResult);
+ }
+
+ // advance position to consumed
+ fPosition = aPathTextBreakupHelper.getPosition();
+ }
+
+ nCurrent++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgtoken.cxx b/svgio/source/svgreader/svgtoken.cxx
new file mode 100644
index 000000000000..5e16ec1829b2
--- /dev/null
+++ b/svgio/source/svgreader/svgtoken.cxx
@@ -0,0 +1,321 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgtoken.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ static rtl::OUString aSVGStrWidth(rtl::OUString::createFromAscii("width"));
+ static rtl::OUString aSVGStrHeight(rtl::OUString::createFromAscii("height"));
+ static rtl::OUString aSVGStrViewBox(rtl::OUString::createFromAscii("viewBox"));
+ static rtl::OUString aSVGStrTransform(rtl::OUString::createFromAscii("transform"));
+ static rtl::OUString aSVGStrStyle(rtl::OUString::createFromAscii("style"));
+ static rtl::OUString aSVGStrD(rtl::OUString::createFromAscii("d"));
+ static rtl::OUString aSVGStrX(rtl::OUString::createFromAscii("x"));
+ static rtl::OUString aSVGStrY(rtl::OUString::createFromAscii("y"));
+ static rtl::OUString aSVGStrXmlns(rtl::OUString::createFromAscii("xmlns"));
+ static rtl::OUString aSVGStrVersion(rtl::OUString::createFromAscii("version"));
+ static rtl::OUString aSVGStrId(rtl::OUString::createFromAscii("id"));
+ static rtl::OUString aSVGStrRx(rtl::OUString::createFromAscii("rx"));
+ static rtl::OUString aSVGStrRy(rtl::OUString::createFromAscii("ry"));
+ static rtl::OUString aSVGStrPoints(rtl::OUString::createFromAscii("points"));
+ static rtl::OUString aSVGStrDx(rtl::OUString::createFromAscii("dx"));
+ static rtl::OUString aSVGStrDy(rtl::OUString::createFromAscii("dy"));
+ static rtl::OUString aSVGStrRotate(rtl::OUString::createFromAscii("rotate"));
+ static rtl::OUString aSVGStrTextLength(rtl::OUString::createFromAscii("textLength"));
+ static rtl::OUString aSVGStrLengthAdjust(rtl::OUString::createFromAscii("lengthAdjust"));
+ static rtl::OUString aSVGStrFont(rtl::OUString::createFromAscii("font"));
+ static rtl::OUString aSVGStrFontFamily(rtl::OUString::createFromAscii("font-family"));
+ static rtl::OUString aSVGStrFontSize(rtl::OUString::createFromAscii("font-size"));
+ static rtl::OUString aSVGStrFontSizeAdjust(rtl::OUString::createFromAscii("font-size-adjust"));
+ static rtl::OUString aSVGStrFontStretch(rtl::OUString::createFromAscii("font-stretch"));
+ static rtl::OUString aSVGStrFontStyle(rtl::OUString::createFromAscii("font-style"));
+ static rtl::OUString aSVGStrFontVariant(rtl::OUString::createFromAscii("font-variant"));
+ static rtl::OUString aSVGStrFontWeight(rtl::OUString::createFromAscii("font-weight"));
+ static rtl::OUString aSVGStrDirection(rtl::OUString::createFromAscii("direction"));
+ static rtl::OUString aSVGStrLetterSpacing(rtl::OUString::createFromAscii("letter-spacing"));
+ static rtl::OUString aSVGStrTextDecoration(rtl::OUString::createFromAscii("text-decoration"));
+ static rtl::OUString aSVGStrUnicodeBidi(rtl::OUString::createFromAscii("unicode-bidi"));
+ static rtl::OUString aSVGStrWordSpacing(rtl::OUString::createFromAscii("word-spacing"));
+ static rtl::OUString aSVGStrTspan(rtl::OUString::createFromAscii("tspan"));
+ static rtl::OUString aSVGStrTref(rtl::OUString::createFromAscii("tref"));
+ static rtl::OUString aSVGStrTextPath(rtl::OUString::createFromAscii("textPath"));
+ static rtl::OUString aSVGStrStartOffset(rtl::OUString::createFromAscii("startOffset"));
+ static rtl::OUString aSVGStrMethod(rtl::OUString::createFromAscii("method"));
+ static rtl::OUString aSVGStrSpacing(rtl::OUString::createFromAscii("spacing"));
+ static rtl::OUString aSVGStrTextAlign(rtl::OUString::createFromAscii("text-align"));
+ static rtl::OUString aSVGStrPathLength(rtl::OUString::createFromAscii("pathLength"));
+ static rtl::OUString aSVGStrType(rtl::OUString::createFromAscii("type"));
+ static rtl::OUString aSVGStrClass(rtl::OUString::createFromAscii("class"));
+ static rtl::OUString aSVGStrTextAnchor(rtl::OUString::createFromAscii("text-anchor"));
+ static rtl::OUString aSVGStrXmlSpace(rtl::OUString::createFromAscii("xml:space"));
+ static rtl::OUString aSVGStrColor(rtl::OUString::createFromAscii("color"));
+ static rtl::OUString aSVGStrClipPathNode(rtl::OUString::createFromAscii("clipPath"));
+ static rtl::OUString aSVGStrClipPathProperty(rtl::OUString::createFromAscii("clip-path"));
+ static rtl::OUString aSVGStrMask(rtl::OUString::createFromAscii("mask"));
+ static rtl::OUString aSVGStrClipPathUnits(rtl::OUString::createFromAscii("clipPathUnits"));
+ static rtl::OUString aSVGStrMaskUnits(rtl::OUString::createFromAscii("maskUnits"));
+ static rtl::OUString aSVGStrMaskContentUnits(rtl::OUString::createFromAscii("maskContentUnits"));
+ static rtl::OUString aSVGStrClipRule(rtl::OUString::createFromAscii("clip-rule"));
+ static rtl::OUString aSVGStrMarker(rtl::OUString::createFromAscii("marker"));
+ static rtl::OUString aSVGStrMarkerStart(rtl::OUString::createFromAscii("marker-start"));
+ static rtl::OUString aSVGStrMarkerMid(rtl::OUString::createFromAscii("marker-mid"));
+ static rtl::OUString aSVGStrMarkerEnd(rtl::OUString::createFromAscii("marker-end"));
+ static rtl::OUString aSVGStrRefX(rtl::OUString::createFromAscii("refX"));
+ static rtl::OUString aSVGStrRefY(rtl::OUString::createFromAscii("refY"));
+ static rtl::OUString aSVGStrMarkerUnits(rtl::OUString::createFromAscii("markerUnits"));
+ static rtl::OUString aSVGStrMarkerWidth(rtl::OUString::createFromAscii("markerWidth"));
+ static rtl::OUString aSVGStrMarkerHeight(rtl::OUString::createFromAscii("markerHeight"));
+ static rtl::OUString aSVGStrOrient(rtl::OUString::createFromAscii("orient"));
+ static rtl::OUString aSVGStrPattern(rtl::OUString::createFromAscii("pattern"));
+ static rtl::OUString aSVGStrPatternUnits(rtl::OUString::createFromAscii("patternUnits"));
+ static rtl::OUString aSVGStrPatternContentUnits(rtl::OUString::createFromAscii("patternContentUnits"));
+ static rtl::OUString aSVGStrPatternTransform(rtl::OUString::createFromAscii("patternTransform"));
+ static rtl::OUString aSVGStrOpacity(rtl::OUString::createFromAscii("opacity"));
+
+ static rtl::OUString aSVGStrPreserveAspectRatio(rtl::OUString::createFromAscii("preserveAspectRatio"));
+ static rtl::OUString aSVGStrDefer(rtl::OUString::createFromAscii("defer"));
+ static rtl::OUString aSVGStrNone(rtl::OUString::createFromAscii("none"));
+ static rtl::OUString aSVGStrXMinYMin(rtl::OUString::createFromAscii("xMinYMin"));
+ static rtl::OUString aSVGStrXMidYMin(rtl::OUString::createFromAscii("xMidYMin"));
+ static rtl::OUString aSVGStrXMaxYMin(rtl::OUString::createFromAscii("xMaxYMin"));
+ static rtl::OUString aSVGStrXMinYMid(rtl::OUString::createFromAscii("xMinYMid"));
+ static rtl::OUString aSVGStrXMidYMid(rtl::OUString::createFromAscii("xMidYMid"));
+ static rtl::OUString aSVGStrXMaxYMid(rtl::OUString::createFromAscii("xMaxYMid"));
+ static rtl::OUString aSVGStrXMinYMax(rtl::OUString::createFromAscii("xMinYMax"));
+ static rtl::OUString aSVGStrXMidYMax(rtl::OUString::createFromAscii("xMidYMax"));
+ static rtl::OUString aSVGStrXMaxYMax(rtl::OUString::createFromAscii("xMaxYMax"));
+ static rtl::OUString aSVGStrMeet(rtl::OUString::createFromAscii("meet"));
+ static rtl::OUString aSVGStrSlice(rtl::OUString::createFromAscii("slice"));
+
+ static rtl::OUString aSVGStrDefs(rtl::OUString::createFromAscii("defs"));
+ static rtl::OUString aSVGStrG(rtl::OUString::createFromAscii("g"));
+ static rtl::OUString aSVGStrSvg(rtl::OUString::createFromAscii("svg"));
+ static rtl::OUString aSVGStrSymbol(rtl::OUString::createFromAscii("symbol"));
+ static rtl::OUString aSVGStrUse(rtl::OUString::createFromAscii("use"));
+
+ static rtl::OUString aSVGStrCircle(rtl::OUString::createFromAscii("circle"));
+ static rtl::OUString aSVGStrEllipse(rtl::OUString::createFromAscii("ellipse"));
+ static rtl::OUString aSVGStrLine(rtl::OUString::createFromAscii("line"));
+ static rtl::OUString aSVGStrPath(rtl::OUString::createFromAscii("path"));
+ static rtl::OUString aSVGStrPolygon(rtl::OUString::createFromAscii("polygon"));
+ static rtl::OUString aSVGStrPolyline(rtl::OUString::createFromAscii("polyline"));
+ static rtl::OUString aSVGStrRect(rtl::OUString::createFromAscii("rect"));
+ static rtl::OUString aSVGStrImage(rtl::OUString::createFromAscii("image"));
+
+ static rtl::OUString aSVGStrLinearGradient(rtl::OUString::createFromAscii("linearGradient"));
+ static rtl::OUString aSVGStrRadialGradient(rtl::OUString::createFromAscii("radialGradient"));
+ static rtl::OUString aSVGStrStop(rtl::OUString::createFromAscii("stop"));
+ static rtl::OUString aSVGStrOffset(rtl::OUString::createFromAscii("offset"));
+ static rtl::OUString aSVGStrX1(rtl::OUString::createFromAscii("x1"));
+ static rtl::OUString aSVGStrY1(rtl::OUString::createFromAscii("y1"));
+ static rtl::OUString aSVGStrX2(rtl::OUString::createFromAscii("x2"));
+ static rtl::OUString aSVGStrY2(rtl::OUString::createFromAscii("y2"));
+ static rtl::OUString aSVGStrCx(rtl::OUString::createFromAscii("cx"));
+ static rtl::OUString aSVGStrCy(rtl::OUString::createFromAscii("cy"));
+ static rtl::OUString aSVGStrFx(rtl::OUString::createFromAscii("fx"));
+ static rtl::OUString aSVGStrFy(rtl::OUString::createFromAscii("fy"));
+ static rtl::OUString aSVGStrR(rtl::OUString::createFromAscii("r"));
+ static rtl::OUString aSVGStrGradientUnits(rtl::OUString::createFromAscii("gradientUnits"));
+ static rtl::OUString aSVGStrGradientTransform(rtl::OUString::createFromAscii("gradientTransform"));
+ static rtl::OUString aSVGStrSpreadMethod(rtl::OUString::createFromAscii("spreadMethod"));
+ static rtl::OUString aSVGStrXlinkHref(rtl::OUString::createFromAscii("xlink:href"));
+ static rtl::OUString aSVGStrStopColor(rtl::OUString::createFromAscii("stop-color"));
+ static rtl::OUString aSVGStrStopOpacity(rtl::OUString::createFromAscii("stop-opacity"));
+
+ static rtl::OUString aSVGStrFill(rtl::OUString::createFromAscii("fill"));
+ static rtl::OUString aSVGStrFillOpacity(rtl::OUString::createFromAscii("fill-opacity"));
+ static rtl::OUString aSVGStrFillRule(rtl::OUString::createFromAscii("fill-rule"));
+
+ static rtl::OUString aSVGStrStroke(rtl::OUString::createFromAscii("stroke"));
+ static rtl::OUString aSVGStrStrokeDasharray(rtl::OUString::createFromAscii("stroke-dasharray"));
+ static rtl::OUString aSVGStrStrokeDashoffset(rtl::OUString::createFromAscii("stroke-dashoffset"));
+ static rtl::OUString aSVGStrStrokeLinecap(rtl::OUString::createFromAscii("stroke-linecap"));
+ static rtl::OUString aSVGStrStrokeLinejoin(rtl::OUString::createFromAscii("stroke-linejoin"));
+ static rtl::OUString aSVGStrStrokeMiterlimit(rtl::OUString::createFromAscii("stroke-miterlimit"));
+ static rtl::OUString aSVGStrStrokeOpacity(rtl::OUString::createFromAscii("stroke-opacity"));
+ static rtl::OUString aSVGStrStrokeWidth(rtl::OUString::createFromAscii("stroke-width"));
+
+ static rtl::OUString aSVGStrText(rtl::OUString::createFromAscii("text"));
+
+ SVGToken StrToSVGToken(const rtl::OUString& rStr)
+ {
+ typedef std::hash_map< rtl::OUString, SVGToken, rtl::OUStringHash > SVGTokenMapper;
+ typedef std::pair< rtl::OUString, SVGToken > SVGTokenValueType;
+ static SVGTokenMapper aSVGTokenMapperList;
+
+ if(aSVGTokenMapperList.empty())
+ {
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrWidth, SVGTokenWidth));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrHeight, SVGTokenHeight));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrViewBox, SVGTokenViewBox));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrTransform, SVGTokenTransform));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStyle, SVGTokenStyle));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrD, SVGTokenD));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrX, SVGTokenX));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrY, SVGTokenY));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXmlns, SVGTokenXmlns));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrVersion, SVGTokenVersion));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrId, SVGTokenId));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrRx, SVGTokenRx));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrRy, SVGTokenRy));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPoints, SVGTokenPoints));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrDx, SVGTokenDx));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrDy, SVGTokenDy));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrRotate, SVGTokenRotate));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFont, SVGTokenFont));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFontFamily, SVGTokenFontFamily));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFontSize, SVGTokenFontSize));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFontSizeAdjust, SVGTokenFontSizeAdjust));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFontStretch, SVGTokenFontStretch));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFontStyle, SVGTokenFontStyle));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFontVariant, SVGTokenFontVariant));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFontWeight, SVGTokenFontWeight));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrDirection, SVGTokenDirection));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrLetterSpacing, SVGTokenLetterSpacing));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrTextDecoration, SVGTokenTextDecoration));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrUnicodeBidi, SVGTokenUnicodeBidi));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrWordSpacing, SVGTokenWordSpacing));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrTspan, SVGTokenTspan));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrTref, SVGTokenTref));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrTextPath, SVGTokenTextPath));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStartOffset, SVGTokenStartOffset));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMethod, SVGTokenMethod));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrSpacing, SVGTokenSpacing));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrTextAlign, SVGTokenTextAlign));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPathLength, SVGTokenPathLength));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrType, SVGTokenType));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrClass, SVGTokenClass));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrTextAnchor, SVGTokenTextAnchor));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXmlSpace, SVGTokenXmlSpace));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrColor, SVGTokenColor));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrClipPathNode, SVGTokenClipPathNode));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrClipPathProperty, SVGTokenClipPathProperty));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMask, SVGTokenMask));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrClipPathUnits, SVGTokenClipPathUnits));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMaskUnits, SVGTokenMaskUnits));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMaskContentUnits, SVGTokenMaskContentUnits));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrClipRule, SVGTokenClipRule));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMarker, SVGTokenMarker));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMarkerStart, SVGTokenMarkerStart));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMarkerMid, SVGTokenMarkerMid));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMarkerEnd, SVGTokenMarkerEnd));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrRefX, SVGTokenRefX));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrRefY, SVGTokenRefY));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMarkerUnits, SVGTokenMarkerUnits));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMarkerWidth, SVGTokenMarkerWidth));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMarkerHeight, SVGTokenMarkerHeight));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrOrient, SVGTokenOrient));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPattern, SVGTokenPattern));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPatternUnits, SVGTokenPatternUnits));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPatternContentUnits, SVGTokenPatternContentUnits));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPatternTransform, SVGTokenPatternTransform));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrOpacity, SVGTokenOpacity));
+
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPreserveAspectRatio, SVGTokenPreserveAspectRatio));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrDefer, SVGTokenDefer));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrNone, SVGTokenNone));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMinYMin, SVGTokenXMinYMin));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMidYMin, SVGTokenXMidYMin));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMaxYMin, SVGTokenXMaxYMin));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMinYMid, SVGTokenXMinYMid));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMidYMid, SVGTokenXMidYMid));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMaxYMid, SVGTokenXMaxYMid));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMinYMax, SVGTokenXMinYMax));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMidYMax, SVGTokenXMidYMax));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXMaxYMax, SVGTokenXMaxYMax));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrMeet, SVGTokenMeet));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrSlice, SVGTokenSlice));
+
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrDefs, SVGTokenDefs));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrG, SVGTokenG));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrSvg, SVGTokenSvg));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrSymbol, SVGTokenSymbol));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrUse, SVGTokenUse));
+
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrCircle, SVGTokenCircle));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrEllipse, SVGTokenEllipse));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrLine, SVGTokenLine));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPath, SVGTokenPath));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPolygon, SVGTokenPolygon));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrPolyline, SVGTokenPolyline));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrRect, SVGTokenRect));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrImage, SVGTokenImage));
+
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrLinearGradient, SVGTokenLinearGradient));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrRadialGradient, SVGTokenRadialGradient));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStop, SVGTokenStop));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrOffset, SVGTokenOffset));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrX1, SVGTokenX1));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrY1, SVGTokenY1));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrX2, SVGTokenX2));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrY2, SVGTokenY2));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrCx, SVGTokenCx));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrCy, SVGTokenCy));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFx, SVGTokenFx));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFy, SVGTokenFy));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrR, SVGTokenR));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrGradientUnits, SVGTokenGradientUnits));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrGradientTransform, SVGTokenGradientTransform));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrSpreadMethod, SVGTokenSpreadMethod));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrXlinkHref, SVGTokenXlinkHref));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStopColor, SVGTokenStopColor));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStopOpacity, SVGTokenStopOpacity));
+
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFill, SVGTokenFill));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFillOpacity, SVGTokenFillOpacity));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrFillRule, SVGTokenFillRule));
+
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStroke, SVGTokenStroke));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStrokeDasharray, SVGTokenStrokeDasharray));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStrokeDashoffset, SVGTokenStrokeDashoffset));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStrokeLinecap, SVGTokenStrokeLinecap));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStrokeLinejoin, SVGTokenStrokeLinejoin));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStrokeMiterlimit, SVGTokenStrokeMiterlimit));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStrokeOpacity, SVGTokenStrokeOpacity));
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrStrokeWidth, SVGTokenStrokeWidth));
+
+ aSVGTokenMapperList.insert(SVGTokenValueType(aSVGStrText, SVGTokenText));
+ }
+
+ const SVGTokenMapper::const_iterator aResult(aSVGTokenMapperList.find(rStr));
+
+ if(aResult == aSVGTokenMapperList.end())
+ {
+ return SVGTokenUnknown;
+ }
+ else
+ {
+ return aResult->second;
+ }
+ }
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgtools.cxx b/svgio/source/svgreader/svgtools.cxx
new file mode 100644
index 000000000000..597decfdee08
--- /dev/null
+++ b/svgio/source/svgreader/svgtools.cxx
@@ -0,0 +1,1581 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgtools.hxx>
+#include <osl/thread.h>
+#include <tools/color.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <svgio/svgreader/svgtoken.hxx>
+#include <hash_map>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+#ifdef DBG_UTIL
+ void myAssert(const rtl::OUString& rMessage)
+ {
+ rtl::OString aMessage2;
+
+ rMessage.convertToString(&aMessage2, osl_getThreadTextEncoding(), RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR|RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR);
+ OSL_ENSURE(false, aMessage2.getStr());
+ }
+#endif
+
+ // common non-token strings
+ const rtl::OUString commonStrings::aStrUserSpaceOnUse(rtl::OUString::createFromAscii("userSpaceOnUse"));
+ const rtl::OUString commonStrings::aStrObjectBoundingBox(rtl::OUString::createFromAscii("objectBoundingBox"));
+ const rtl::OUString commonStrings::aStrNonzero(rtl::OUString::createFromAscii("nonzero"));
+ const rtl::OUString commonStrings::aStrEvenOdd(rtl::OUString::createFromAscii("evenodd"));
+
+ basegfx::B2DHomMatrix SvgAspectRatio::createLinearMapping(const basegfx::B2DRange& rTarget, const basegfx::B2DRange& rSource)
+ {
+ basegfx::B2DHomMatrix aRetval;
+ const double fSWidth(rSource.getWidth());
+ const double fSHeight(rSource.getHeight());
+ const bool bNoSWidth(basegfx::fTools::equalZero(fSWidth));
+ const bool bNoSHeight(basegfx::fTools::equalZero(fSHeight));
+
+ // transform from source state to unit range
+ aRetval.translate(-rSource.getMinX(), -rSource.getMinY());
+ aRetval.scale(
+ (bNoSWidth ? 1.0 : 1.0 / fSWidth) * rTarget.getWidth(),
+ (bNoSHeight ? 1.0 : 1.0 / fSHeight) * rTarget.getHeight());
+
+ // transform from unit rage to target range
+ aRetval.translate(rTarget.getMinX(), rTarget.getMinY());
+
+ return aRetval;
+ }
+
+ basegfx::B2DHomMatrix SvgAspectRatio::createMapping(const basegfx::B2DRange& rTarget, const basegfx::B2DRange& rSource) const
+ {
+ if(!isSet() || Align_none == getSvgAlign())
+ {
+ // create linear mapping (default)
+ return createLinearMapping(rTarget, rSource);
+ }
+
+ basegfx::B2DHomMatrix aRetval;
+
+ const double fSWidth(rSource.getWidth());
+ const double fSHeight(rSource.getHeight());
+ const bool bNoSWidth(basegfx::fTools::equalZero(fSWidth));
+ const bool bNoSHeight(basegfx::fTools::equalZero(fSHeight));
+ const double fScaleX((bNoSWidth ? 1.0 : 1.0 / fSWidth) * rTarget.getWidth());
+ const double fScaleY((bNoSHeight ? 1.0 : 1.0 / fSHeight) * rTarget.getHeight());
+ const double fScale(isMeetOrSlice() ? std::min(fScaleX, fScaleY) : std::max(fScaleX, fScaleY));
+
+ // remove source translation, apply scale
+ aRetval.translate(-rSource.getMinX(), -rSource.getMinY());
+ aRetval.scale(fScale, fScale);
+
+ // evaluate horizontal alignment
+ const double fNewWidth(fSWidth * fScale);
+ double fTransX(0.0);
+
+ switch(getSvgAlign())
+ {
+ case Align_xMidYMin:
+ case Align_xMidYMid:
+ case Align_xMidYMax:
+ {
+ // centerX
+ const double fFreeSpace(rTarget.getWidth() - fNewWidth);
+ fTransX = fFreeSpace * 0.5;
+ break;
+ }
+ case Align_xMaxYMin:
+ case Align_xMaxYMid:
+ case Align_xMaxYMax:
+ {
+ // Right align
+ const double fFreeSpace(rTarget.getWidth() - fNewWidth);
+ fTransX = fFreeSpace;
+ break;
+ }
+ }
+
+ // evaluate vertical alignment
+ const double fNewHeight(fSHeight * fScale);
+ double fTransY(0.0);
+
+ switch(getSvgAlign())
+ {
+ case Align_xMinYMid:
+ case Align_xMidYMid:
+ case Align_xMaxYMid:
+ {
+ // centerY
+ const double fFreeSpace(rTarget.getHeight() - fNewHeight);
+ fTransY = fFreeSpace * 0.5;
+ break;
+ }
+ case Align_xMinYMax:
+ case Align_xMidYMax:
+ case Align_xMaxYMax:
+ {
+ // Bottom align
+ const double fFreeSpace(rTarget.getHeight() - fNewHeight);
+ fTransY = fFreeSpace;
+ break;
+ }
+ }
+
+ // add target translation
+ aRetval.translate(
+ rTarget.getMinX() + fTransX,
+ rTarget.getMinY() + fTransY);
+
+ return aRetval;
+ }
+
+ double SvgNumber::solve(const InfoProvider& rInfoProvider, NumberType aNumberType) const
+ {
+ if(isSet())
+ {
+ switch(meUnit)
+ {
+ case Unit_em:
+ {
+ return mfNumber * rInfoProvider.getCurrentFontSize();
+ break;
+ }
+ case Unit_ex:
+ {
+ return mfNumber * rInfoProvider.getCurrentXHeight() * 0.5;
+ break;
+ }
+ case Unit_px:
+ {
+ return mfNumber;
+ break;
+ }
+ case Unit_pt:
+ case Unit_pc:
+ case Unit_cm:
+ case Unit_mm:
+ case Unit_in:
+ {
+ double fRetval(mfNumber);
+
+ switch(meUnit)
+ {
+ case Unit_pt: fRetval *= 1.25; break;
+ case Unit_pc: fRetval *= 15.0; break;
+ case Unit_cm: fRetval *= 35.43307; break;
+ case Unit_mm: fRetval *= 3.543307; break;
+ case Unit_in: fRetval *= 90.0; break;
+ }
+
+ return fRetval;
+ break;
+ }
+ case Unit_percent:
+ {
+ double fRetval(mfNumber * 0.01);
+ const basegfx::B2DRange* pViewPort = rInfoProvider.getCurrentViewPort();
+
+ if(!pViewPort)
+ {
+ // no viewPort, assume a normal page size (A4)
+ static basegfx::B2DRange aDinA4Range(
+ 0.0,
+ 0.0,
+ 210.0 * 3.543307,
+ 297.0 * 3.543307);
+
+ pViewPort = &aDinA4Range;
+ }
+
+ if(pViewPort)
+ {
+ if(xcoordinate == aNumberType)
+ {
+ // it's a x-coordinate, relative to current width (w)
+ fRetval *= pViewPort->getWidth();
+ }
+ else if(ycoordinate == aNumberType)
+ {
+ // it's a y-coordinate, relative to current height (h)
+ fRetval *= pViewPort->getHeight();
+ }
+ else // length
+ {
+ // it's a length, relative to sqrt(w*w + h*h)/sqrt(2)
+ const double fCurrentWidth(pViewPort->getWidth());
+ const double fCurrentHeight(pViewPort->getHeight());
+ const double fCurrentLength(
+ sqrt(fCurrentWidth * fCurrentWidth + fCurrentHeight * fCurrentHeight)/sqrt(2.0));
+
+ fRetval *= fCurrentLength;
+ }
+ }
+
+ return fRetval;
+ break;
+ }
+ }
+ }
+
+ /// not set
+ OSL_ENSURE(false, "SvgNumber not set (!)");
+ return 0.0;
+ }
+
+ bool SvgNumber::isPositive() const
+ {
+ return basegfx::fTools::moreOrEqual(mfNumber, 0.0);
+ }
+
+ void skip_char(const rtl::OUString& rCandidate, const sal_Unicode& rChar, sal_Int32& nPos, const sal_Int32 nLen)
+ {
+ while(nPos < nLen && rChar == rCandidate[nPos])
+ {
+ nPos++;
+ }
+ }
+
+ void skip_char(const rtl::OUString& rCandidate, const sal_Unicode& rCharA, const sal_Unicode& rCharB, sal_Int32& nPos, const sal_Int32 nLen)
+ {
+ while(nPos < nLen && (rCharA == rCandidate[nPos] || rCharB == rCandidate[nPos]))
+ {
+ nPos++;
+ }
+ }
+
+ void copySign(const rtl::OUString& rCandidate, sal_Int32& nPos, rtl::OUStringBuffer& rTarget, const sal_Int32 nLen)
+ {
+ if(nPos < nLen)
+ {
+ const sal_Unicode aChar(rCandidate[nPos]);
+
+ if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
+ {
+ rTarget.append(aChar);
+ nPos++;
+ }
+ }
+ }
+
+ void copyNumber(const rtl::OUString& rCandidate, sal_Int32& nPos, rtl::OUStringBuffer& rTarget, const sal_Int32 nLen)
+ {
+ bool bOnNumber(true);
+
+ while(bOnNumber && nPos < nLen)
+ {
+ const sal_Unicode aChar(rCandidate[nPos]);
+
+ bOnNumber = (sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) || sal_Unicode('.') == aChar;
+
+ if(bOnNumber)
+ {
+ rTarget.append(aChar);
+ nPos++;
+ }
+ }
+ }
+
+ void copyHex(const rtl::OUString& rCandidate, sal_Int32& nPos, rtl::OUStringBuffer& rTarget, const sal_Int32 nLen)
+ {
+ bool bOnHex(true);
+
+ while(bOnHex && nPos < nLen)
+ {
+ const sal_Unicode aChar(rCandidate[nPos]);
+
+ bOnHex = (sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
+ || (sal_Unicode('A') <= aChar && sal_Unicode('F') >= aChar)
+ || (sal_Unicode('a') <= aChar && sal_Unicode('f') >= aChar);
+
+ if(bOnHex)
+ {
+ rTarget.append(aChar);
+ nPos++;
+ }
+ }
+ }
+
+ void copyString(const rtl::OUString& rCandidate, sal_Int32& nPos, rtl::OUStringBuffer& rTarget, const sal_Int32 nLen)
+ {
+ bool bOnChar(true);
+
+ while(bOnChar && nPos < nLen)
+ {
+ const sal_Unicode aChar(rCandidate[nPos]);
+
+ bOnChar = (sal_Unicode('a') <= aChar && sal_Unicode('z') >= aChar)
+ || (sal_Unicode('A') <= aChar && sal_Unicode('Z') >= aChar)
+ || sal_Unicode('-') == aChar;
+
+ if(bOnChar)
+ {
+ rTarget.append(aChar);
+ nPos++;
+ }
+ }
+ }
+
+ void copyToLimiter(const rtl::OUString& rCandidate, const sal_Unicode& rLimiter, sal_Int32& nPos, rtl::OUStringBuffer& rTarget, const sal_Int32 nLen)
+ {
+ while(nPos < nLen && rLimiter != rCandidate[nPos])
+ {
+ rTarget.append(rCandidate[nPos]);
+ nPos++;
+ }
+ }
+
+ bool readNumber(const rtl::OUString& rCandidate, sal_Int32& nPos, double& fNum, const sal_Int32 nLen)
+ {
+ if(nPos < nLen)
+ {
+ rtl::OUStringBuffer aNum;
+
+ copySign(rCandidate, nPos, aNum, nLen);
+ copyNumber(rCandidate, nPos, aNum, nLen);
+
+ if(nPos < nLen)
+ {
+ const sal_Unicode aChar(rCandidate[nPos]);
+
+ if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar)
+ {
+ // try to read exponential number, but be careful. I had
+ // a case where dx="2em" was used, thus the 'e' was consumed
+ // by error. First try if there are numbers after the 'e',
+ // safe current state
+ nPos++;
+ const rtl::OUStringBuffer aNum2(aNum);
+ const sal_Int32 nPosAfterE(nPos);
+
+ aNum.append(aChar);
+ copySign(rCandidate, nPos, aNum, nLen);
+ copyNumber(rCandidate, nPos, aNum, nLen);
+
+ if(nPosAfterE == nPos)
+ {
+ // no number after 'e', go back. Do not
+ // return false, it's still a valid integer number
+ aNum = aNum2;
+ nPos--;
+ }
+ }
+ }
+
+ if(aNum.getLength())
+ {
+ rtl_math_ConversionStatus eStatus;
+
+ fNum = rtl::math::stringToDouble(
+ aNum.makeStringAndClear(), (sal_Unicode)('.'), (sal_Unicode)(','),
+ &eStatus, 0);
+
+ return eStatus == rtl_math_ConversionStatus_Ok;
+ }
+ }
+
+ return false;
+ }
+
+ SvgUnit readUnit(const rtl::OUString& rCandidate, sal_Int32& nPos, const sal_Int32 nLen)
+ {
+ SvgUnit aRetval(Unit_px);
+
+ if(nPos < nLen)
+ {
+ const sal_Unicode aCharA(rCandidate[nPos]);
+
+ if(nPos + 1 < nLen)
+ {
+ const sal_Unicode aCharB(rCandidate[nPos + 1]);
+ bool bTwoCharValid(false);
+
+ switch(aCharA)
+ {
+ case sal_Unicode('e') :
+ {
+ if(sal_Unicode('m') == aCharB)
+ {
+ // 'em' Relative to current font size
+ aRetval = Unit_em;
+ bTwoCharValid = true;
+ }
+ else if(sal_Unicode('x') == aCharB)
+ {
+ // 'ex' Relative to current font x-height
+ aRetval = Unit_ex;
+ bTwoCharValid = true;
+ }
+ break;
+ }
+ case sal_Unicode('p') :
+ {
+ if(sal_Unicode('x') == aCharB)
+ {
+ // 'px' UserUnit (default)
+ bTwoCharValid = true;
+ }
+ else if(sal_Unicode('t') == aCharB)
+ {
+ // 'pt' == 1.25 px
+ aRetval = Unit_pt;
+ bTwoCharValid = true;
+ }
+ else if(sal_Unicode('c') == aCharB)
+ {
+ // 'pc' == 15 px
+ aRetval = Unit_pc;
+ bTwoCharValid = true;
+ }
+ break;
+ }
+ case sal_Unicode('i') :
+ {
+ if(sal_Unicode('n') == aCharB)
+ {
+ // 'in' == 90 px
+ aRetval = Unit_in;
+ bTwoCharValid = true;
+ }
+ break;
+ }
+ case sal_Unicode('c') :
+ {
+ if(sal_Unicode('m') == aCharB)
+ {
+ // 'cm' == 35.43307 px
+ aRetval = Unit_cm;
+ bTwoCharValid = true;
+ }
+ break;
+ }
+ case sal_Unicode('m') :
+ {
+ if(sal_Unicode('m') == aCharB)
+ {
+ // 'mm' == 3.543307 px
+ aRetval = Unit_mm;
+ bTwoCharValid = true;
+ }
+ break;
+ }
+ }
+
+ if(bTwoCharValid)
+ {
+ nPos += 2;
+ }
+ }
+ else
+ {
+ if(sal_Unicode('%') == aCharA)
+ {
+ // percent used, relative to current
+ nPos++;
+ aRetval = Unit_percent;
+ }
+ }
+ }
+
+ return aRetval;
+ }
+
+ bool readNumberAndUnit(const rtl::OUString& rCandidate, sal_Int32& nPos, SvgNumber& aNum, const sal_Int32 nLen)
+ {
+ double fNum(0.0);
+
+ if(readNumber(rCandidate, nPos, fNum, nLen))
+ {
+ skip_char(rCandidate, sal_Unicode(' '), nPos, nLen);
+ aNum = SvgNumber(fNum, readUnit(rCandidate, nPos, nLen));
+
+ return true;
+ }
+
+ return false;
+ }
+
+ bool readAngle(const rtl::OUString& rCandidate, sal_Int32& nPos, double& fAngle, const sal_Int32 nLen)
+ {
+ if(readNumber(rCandidate, nPos, fAngle, nLen))
+ {
+ skip_char(rCandidate, sal_Unicode(' '), nPos, nLen);
+
+ enum DegreeType
+ {
+ deg,
+ grad,
+ rad
+ } aType(deg); // degrees is default
+
+ if(nPos < nLen)
+ {
+ const sal_Unicode aChar(rCandidate[nPos]);
+ static rtl::OUString aStrGrad(rtl::OUString::createFromAscii("grad"));
+ static rtl::OUString aStrRad(rtl::OUString::createFromAscii("rad"));
+
+ switch(aChar)
+ {
+ case sal_Unicode('g') :
+ case sal_Unicode('G') :
+ {
+ if(rCandidate.matchIgnoreAsciiCase(aStrGrad, nPos))
+ {
+ // angle in grad
+ nPos += aStrGrad.getLength();
+ }
+ break;
+ }
+ case sal_Unicode('r') :
+ case sal_Unicode('R') :
+ {
+ if(rCandidate.matchIgnoreAsciiCase(aStrRad, nPos))
+ {
+ // angle in radians
+ nPos += aStrRad.getLength();
+ }
+ break;
+ }
+ }
+ }
+
+ // convert to radians
+ if(deg == aType)
+ {
+ fAngle *= F_PI / 180.0;
+ }
+ else if(grad == aType)
+ {
+ // looks like 100 grad is 90 degrees
+ fAngle *= F_PI / 200.0;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ sal_Int32 read_hex(const sal_Unicode& rChar)
+ {
+ if(rChar >= sal_Unicode('0') && rChar <=sal_Unicode('9'))
+ {
+ return sal_Int32(rChar - sal_Unicode('0'));
+ }
+ else if(rChar >= sal_Unicode('A') && rChar <=sal_Unicode('F'))
+ {
+ return 10 + sal_Int32(rChar - sal_Unicode('A'));
+ }
+ else if(rChar >= sal_Unicode('a') && rChar <=sal_Unicode('f'))
+ {
+ return 10 + sal_Int32(rChar - sal_Unicode('a'));
+ }
+ else
+ {
+ // error
+ return 0;
+ }
+ }
+
+ bool match_colorKeyword(basegfx::BColor& rColor, const rtl::OUString& rName)
+ {
+ typedef std::hash_map< rtl::OUString, Color, rtl::OUStringHash > ColorTokenMapper;
+ typedef std::pair< rtl::OUString, Color > ColorTokenValueType;
+ ColorTokenMapper aColorTokenMapperList;
+
+ if(aColorTokenMapperList.empty())
+ {
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("aliceblue"), Color(240, 248, 255)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("antiquewhite"), Color(250, 235, 215)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("aqua"), Color( 0, 255, 255)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("aquamarine"), Color(127, 255, 212)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("azure"), Color(240, 255, 255)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("beige"), Color(245, 245, 220)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("bisque"), Color(255, 228, 196)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("black"), Color( 0, 0, 0)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("blanchedalmond"), Color(255, 235, 205)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("blue"), Color( 0, 0, 255)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("blueviolet"), Color(138, 43, 226)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("brown"), Color(165, 42, 42)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("burlywood"), Color(222, 184, 135)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("cadetblue"), Color( 95, 158, 160)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("chartreuse"), Color(127, 255, 0)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("chocolate"), Color(210, 105, 30)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("coral"), Color(255, 127, 80)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("cornflowerblue"), Color(100, 149, 237)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("cornsilk"), Color(255, 248, 220)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("crimson"), Color(220, 20, 60)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("cyan"), Color( 0, 255, 255)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkblue"), Color( 0, 0, 139)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkcyan"), Color( 0, 139, 139)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkgoldenrod"), Color(184, 134, 11)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkgray"), Color(169, 169, 169)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkgreen"), Color( 0, 100, 0)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkgrey"), Color(169, 169, 169)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkkhaki"), Color(189, 183, 107)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkmagenta"), Color(139, 0, 139)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkolivegreen"), Color( 85, 107, 47)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkorange"), Color(255, 140, 0)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkorchid"), Color(153, 50, 204)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkred"), Color(139, 0, 0)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darksalmon"), Color(233, 150, 122)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkseagreen"), Color(143, 188, 143)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkslateblue"), Color( 72, 61, 139)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkslategray"), Color( 47, 79, 79)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkslategrey"), Color( 47, 79, 79)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkturquoise"), Color( 0, 206, 209)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkviolet"), Color(148, 0, 211)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("deeppink"), Color(255, 20, 147)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("deepskyblue"), Color( 0, 191, 255)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("dimgray"), Color(105, 105, 105)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("dimgrey"), Color(105, 105, 105)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("dodgerblue"), Color( 30, 144, 255)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("firebrick"), Color(178, 34, 34)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("floralwhite"), Color(255, 250, 240)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("forestgreen"), Color( 34, 139, 34)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("fuchsia"), Color(255, 0, 255)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("gainsboro"), Color(220, 220, 220)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("ghostwhite"), Color(248, 248, 255)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("gold"), Color(255, 215, 0)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("goldenrod"), Color(218, 165, 32)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("gray"), Color(128, 128, 128)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("grey"), Color(128, 128, 128)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("green"), Color(0, 128, 0)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("greenyellow"), Color(173, 255, 47)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("honeydew"), Color(240, 255, 240)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("hotpink"), Color(255, 105, 180)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("indianred"), Color(205, 92, 92)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("indigo"), Color( 75, 0, 130)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("ivory"), Color(255, 255, 240)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("khaki"), Color(240, 230, 140)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lavender"), Color(230, 230, 250)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lavenderblush"), Color(255, 240, 245)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lawngreen"), Color(124, 252, 0)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lemonchiffon"), Color(255, 250, 205)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightblue"), Color(173, 216, 230)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightcoral"), Color(240, 128, 128)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightcyan"), Color(224, 255, 255)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightgoldenrodyellow"), Color(250, 250, 210)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightgray"), Color(211, 211, 211)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightgreen"), Color(144, 238, 144)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightgrey"), Color(211, 211, 211)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightpink"), Color(255, 182, 193)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightsalmon"), Color(255, 160, 122)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightseagreen"), Color( 32, 178, 170)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightskyblue"), Color(135, 206, 250)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightslategray"), Color(119, 136, 153)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightslategrey"), Color(119, 136, 153)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightsteelblue"), Color(176, 196, 222)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightyellow"), Color(255, 255, 224)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lime"), Color( 0, 255, 0)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("limegreen"), Color( 50, 205, 50)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("linen"), Color(250, 240, 230)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("magenta"), Color(255, 0, 255)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("maroon"), Color(128, 0, 0)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumaquamarine"), Color(102, 205, 170)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumblue"), Color( 0, 0, 205)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumorchid"), Color(186, 85, 211)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumpurple"), Color(147, 112, 219)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumseagreen"), Color( 60, 179, 113)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumslateblue"), Color(123, 104, 238)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumspringgreen"), Color( 0, 250, 154)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumturquoise"), Color( 72, 209, 204)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumvioletred"), Color(199, 21, 133)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("midnightblue"), Color( 25, 25, 112)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mintcream"), Color(245, 255, 250)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mistyrose"), Color(255, 228, 225)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("moccasin"), Color(255, 228, 181)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("navajowhite"), Color(255, 222, 173)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("navy"), Color( 0, 0, 128)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("oldlace"), Color(253, 245, 230)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("olive"), Color(128, 128, 0)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("olivedrab"), Color(107, 142, 35)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("orange"), Color(255, 165, 0)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("orangered"), Color(255, 69, 0)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("orchid"), Color(218, 112, 214)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("palegoldenrod"), Color(238, 232, 170)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("palegreen"), Color(152, 251, 152)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("paleturquoise"), Color(175, 238, 238)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("palevioletred"), Color(219, 112, 147)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("papayawhip"), Color(255, 239, 213)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("peachpuff"), Color(255, 218, 185)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("peru"), Color(205, 133, 63)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("pink"), Color(255, 192, 203)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("plum"), Color(221, 160, 221)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("powderblue"), Color(176, 224, 230)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("purple"), Color(128, 0, 128)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("red"), Color(255, 0, 0)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("rosybrown"), Color(188, 143, 143)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("royalblue"), Color( 65, 105, 225)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("saddlebrown"), Color(139, 69, 19)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("salmon"), Color(250, 128, 114)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("sandybrown"), Color(244, 164, 96)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("seagreen"), Color( 46, 139, 87)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("seashell"), Color(255, 245, 238)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("sienna"), Color(160, 82, 45)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("silver"), Color(192, 192, 192)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("skyblue"), Color(135, 206, 235)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("slateblue"), Color(106, 90, 205)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("slategray"), Color(112, 128, 144)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("slategrey"), Color(112, 128, 144)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("snow"), Color(255, 250, 250)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("springgreen"), Color( 0, 255, 127)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("steelblue"), Color( 70, 130, 180)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("tan"), Color(210, 180, 140)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("teal"), Color( 0, 128, 128)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("thistle"), Color(216, 191, 216)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("tomato"), Color(255, 99, 71)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("turquoise"), Color( 64, 224, 208)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("violet"), Color(238, 130, 238)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("wheat"), Color(245, 222, 179)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("white"), Color(255, 255, 255)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("whitesmoke"), Color(245, 245, 245)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("yellow"), Color(255, 255, 0)));
+ aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("yellowgreen"), Color(154, 205, 50)));
+ }
+
+ const ColorTokenMapper::const_iterator aResult(aColorTokenMapperList.find(rName));
+
+ if(aResult == aColorTokenMapperList.end())
+ {
+ return false;
+ }
+ else
+ {
+ rColor = aResult->second.getBColor();
+ return true;
+ }
+ }
+
+ bool read_color(const rtl::OUString& rCandidate, basegfx::BColor& rColor)
+ {
+ const sal_Int32 nLen(rCandidate.getLength());
+
+ if(nLen)
+ {
+ const sal_Unicode aChar(rCandidate[0]);
+ const double fFactor(1.0 / 255.0);
+
+ if(aChar == sal_Unicode('#'))
+ {
+ // hex definition
+ rtl::OUStringBuffer aNum;
+ sal_Int32 nPos(1);
+
+ copyHex(rCandidate, nPos, aNum, nLen);
+ const sal_Int32 nLength(aNum.getLength());
+
+ if(3 == nLength)
+ {
+ const sal_Int32 nR(read_hex(aNum.charAt(0)));
+ const sal_Int32 nG(read_hex(aNum.charAt(1)));
+ const sal_Int32 nB(read_hex(aNum.charAt(2)));
+
+ rColor.setRed((nR | (nR << 4)) * fFactor);
+ rColor.setGreen((nG | (nG << 4)) * fFactor);
+ rColor.setBlue((nB | (nB << 4)) * fFactor);
+
+ return true;
+ }
+ else if(6 == nLength)
+ {
+ const sal_Int32 nR1(read_hex(aNum.charAt(0)));
+ const sal_Int32 nR2(read_hex(aNum.charAt(1)));
+ const sal_Int32 nG1(read_hex(aNum.charAt(2)));
+ const sal_Int32 nG2(read_hex(aNum.charAt(3)));
+ const sal_Int32 nB1(read_hex(aNum.charAt(4)));
+ const sal_Int32 nB2(read_hex(aNum.charAt(5)));
+
+ rColor.setRed((nR2 | (nR1 << 4)) * fFactor);
+ rColor.setGreen((nG2 | (nG1 << 4)) * fFactor);
+ rColor.setBlue((nB2 | (nB1 << 4)) * fFactor);
+
+ return true;
+ }
+ }
+ else
+ {
+ static rtl::OUString aStrRgb(rtl::OUString::createFromAscii("rgb"));
+
+ if(rCandidate.matchIgnoreAsciiCase(aStrRgb, 0))
+ {
+ // rgb definition
+ sal_Int32 nPos(aStrRgb.getLength());
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode('('), nPos, nLen);
+ double fR(0.0);
+
+ if(readNumber(rCandidate, nPos, fR, nLen))
+ {
+ skip_char(rCandidate, sal_Unicode(' '), nPos, nLen);
+
+ if(nPos < nLen)
+ {
+ const sal_Unicode aChar(rCandidate[nPos]);
+ const bool bIsPercent(sal_Unicode('%') == aChar);
+ double fG(0.0);
+
+ if(bIsPercent)
+ {
+ skip_char(rCandidate, sal_Unicode('%'), nPos, nLen);
+ }
+
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ if(readNumber(rCandidate, nPos, fG, nLen))
+ {
+ double fB(0.0);
+
+ if(bIsPercent)
+ {
+ skip_char(rCandidate, sal_Unicode('%'), nPos, nLen);
+ }
+
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ if(readNumber(rCandidate, nPos, fB, nLen))
+ {
+ const double fFac(bIsPercent ? 0.01 : fFactor);
+
+ rColor.setRed(fR * fFac);
+ rColor.setGreen(fG * fFac);
+ rColor.setBlue(fB * fFac);
+
+ if(bIsPercent)
+ {
+ skip_char(rCandidate, sal_Unicode('%'), nPos, nLen);
+ }
+
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(')'), nPos, nLen);
+ return true;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // color keyword
+ if(match_colorKeyword(rColor, rCandidate))
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange readViewBox(const rtl::OUString& rCandidate, InfoProvider& rInfoProvider)
+ {
+ const sal_Int32 nLen(rCandidate.getLength());
+
+ if(nLen)
+ {
+ sal_Int32 nPos(0);
+ SvgNumber aMinX;
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ if(readNumberAndUnit(rCandidate, nPos, aMinX, nLen))
+ {
+ SvgNumber aMinY;
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ if(readNumberAndUnit(rCandidate, nPos, aMinY, nLen))
+ {
+ SvgNumber aWidth;
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ if(readNumberAndUnit(rCandidate, nPos, aWidth, nLen))
+ {
+ SvgNumber aHeight;
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ if(readNumberAndUnit(rCandidate, nPos, aHeight, nLen))
+ {
+ return basegfx::B2DRange(
+ aMinX.solve(rInfoProvider, xcoordinate),
+ aMinY.solve(rInfoProvider, ycoordinate),
+ aWidth.solve(rInfoProvider, xcoordinate),
+ aHeight.solve(rInfoProvider, ycoordinate));
+ }
+ }
+ }
+ }
+ }
+
+ return basegfx::B2DRange();
+ }
+
+ basegfx::B2DHomMatrix readTransform(const rtl::OUString& rCandidate, InfoProvider& rInfoProvider)
+ {
+ basegfx::B2DHomMatrix aMatrix;
+ const sal_Int32 nLen(rCandidate.getLength());
+
+ if(nLen)
+ {
+ sal_Int32 nPos(0);
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ while(nPos < nLen)
+ {
+ const sal_Unicode aChar(rCandidate[nPos]);
+ const sal_Int32 nInitPos(nPos);
+ static rtl::OUString aStrMatrix(rtl::OUString::createFromAscii("matrix"));
+ static rtl::OUString aStrTranslate(rtl::OUString::createFromAscii("translate"));
+ static rtl::OUString aStrScale(rtl::OUString::createFromAscii("scale"));
+ static rtl::OUString aStrRotate(rtl::OUString::createFromAscii("rotate"));
+ static rtl::OUString aStrSkewX(rtl::OUString::createFromAscii("skewX"));
+ static rtl::OUString aStrSkewY(rtl::OUString::createFromAscii("skewY"));
+
+ switch(aChar)
+ {
+ case sal_Unicode('m') :
+ {
+ if(rCandidate.match(aStrMatrix, nPos))
+ {
+ // matrix element
+ nPos += aStrMatrix.getLength();
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode('('), nPos, nLen);
+ SvgNumber aVal;
+ basegfx::B2DHomMatrix aNew;
+
+ if(readNumberAndUnit(rCandidate, nPos, aVal, nLen))
+ {
+ aNew.set(0, 0, aVal.solve(rInfoProvider)); // Element A
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ if(readNumberAndUnit(rCandidate, nPos, aVal, nLen))
+ {
+ aNew.set(1, 0, aVal.solve(rInfoProvider)); // Element B
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ if(readNumberAndUnit(rCandidate, nPos, aVal, nLen))
+ {
+ aNew.set(0, 1, aVal.solve(rInfoProvider)); // Element C
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ if(readNumberAndUnit(rCandidate, nPos, aVal, nLen))
+ {
+ aNew.set(1, 1, aVal.solve(rInfoProvider)); // Element D
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ if(readNumberAndUnit(rCandidate, nPos, aVal, nLen))
+ {
+ aNew.set(0, 2, aVal.solve(rInfoProvider, xcoordinate)); // Element E
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ if(readNumberAndUnit(rCandidate, nPos, aVal, nLen))
+ {
+ aNew.set(1, 2, aVal.solve(rInfoProvider, ycoordinate)); // Element F
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(')'), nPos, nLen);
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ // caution: String is evaluated from left to right, but matrix multiplication
+ // in SVG is right to left, so put the new transformation before the current
+ // one by multiplicating from the right side
+ aMatrix = aMatrix * aNew;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ case sal_Unicode('t') :
+ {
+ if(rCandidate.match(aStrTranslate, nPos))
+ {
+ // translate element
+ nPos += aStrTranslate.getLength();
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode('('), nPos, nLen);
+ SvgNumber aTransX;
+
+ if(readNumberAndUnit(rCandidate, nPos, aTransX, nLen))
+ {
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+ SvgNumber aTransY;
+ readNumberAndUnit(rCandidate, nPos, aTransY, nLen);
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(')'), nPos, nLen);
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ aMatrix = aMatrix * basegfx::tools::createTranslateB2DHomMatrix(
+ aTransX.solve(rInfoProvider, xcoordinate),
+ aTransY.solve(rInfoProvider, ycoordinate));
+ }
+ }
+ break;
+ }
+ case sal_Unicode('s') :
+ {
+ if(rCandidate.match(aStrScale, nPos))
+ {
+ // scale element
+ nPos += aStrScale.getLength();
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode('('), nPos, nLen);
+ SvgNumber aScaleX;
+
+ if(readNumberAndUnit(rCandidate, nPos, aScaleX, nLen))
+ {
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+ SvgNumber aScaleY(aScaleX);
+ readNumberAndUnit(rCandidate, nPos, aScaleY, nLen);
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(')'), nPos, nLen);
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ aMatrix = aMatrix * basegfx::tools::createScaleB2DHomMatrix(
+ aScaleX.solve(rInfoProvider),
+ aScaleY.solve(rInfoProvider));
+ }
+ }
+ else if(rCandidate.match(aStrSkewX, nPos))
+ {
+ // skewx element
+ nPos += aStrSkewX.getLength();
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode('('), nPos, nLen);
+ double fSkewX(0.0);
+
+ if(readAngle(rCandidate, nPos, fSkewX, nLen))
+ {
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(')'), nPos, nLen);
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ aMatrix = aMatrix * basegfx::tools::createShearXB2DHomMatrix(tan(fSkewX));
+ }
+ }
+ else if(rCandidate.match(aStrSkewY, nPos))
+ {
+ // skewy element
+ nPos += aStrSkewY.getLength();
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode('('), nPos, nLen);
+ double fSkewY(0.0);
+
+ if(readAngle(rCandidate, nPos, fSkewY, nLen))
+ {
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(')'), nPos, nLen);
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ aMatrix = aMatrix * basegfx::tools::createShearYB2DHomMatrix(tan(fSkewY));
+ }
+ }
+ break;
+ }
+ case sal_Unicode('r') :
+ {
+ if(rCandidate.match(aStrRotate, nPos))
+ {
+ // rotate element
+ nPos += aStrRotate.getLength();
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode('('), nPos, nLen);
+ double fAngle(0.0);
+
+ if(readAngle(rCandidate, nPos, fAngle, nLen))
+ {
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+ SvgNumber aX;
+ readNumberAndUnit(rCandidate, nPos, aX, nLen);
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+ SvgNumber aY;
+ readNumberAndUnit(rCandidate, nPos, aY, nLen);
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(')'), nPos, nLen);
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ const double fX(aX.isSet() ? aX.solve(rInfoProvider, xcoordinate) : 0.0);
+ const double fY(aY.isSet() ? aY.solve(rInfoProvider, ycoordinate) : 0.0);
+
+ if(!basegfx::fTools::equalZero(fX) || !basegfx::fTools::equalZero(fY))
+ {
+ // rotate around point
+ aMatrix = aMatrix * basegfx::tools::createRotateAroundPoint(fX, fY, fAngle);
+ }
+ else
+ {
+ // rotate
+ aMatrix = aMatrix * basegfx::tools::createRotateB2DHomMatrix(fAngle);
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ if(nInitPos == nPos)
+ {
+ OSL_ENSURE(false, "Could not interpret on current position (!)");
+ nPos++;
+ }
+ }
+ }
+
+ return aMatrix;
+ }
+
+ bool readSingleNumber(const rtl::OUString& rCandidate, SvgNumber& aNum)
+ {
+ const sal_Int32 nLen(rCandidate.getLength());
+ sal_Int32 nPos(0);
+
+ return readNumberAndUnit(rCandidate, nPos, aNum, nLen);
+ }
+
+ bool readLocalUrl(const rtl::OUString& rCandidate, rtl::OUString& rURL)
+ {
+ static rtl::OUString aStrUrl(rtl::OUString::createFromAscii("url"));
+
+ if(rCandidate.match(aStrUrl, 0))
+ {
+ const sal_Int32 nLen(rCandidate.getLength());
+ sal_Int32 nPos(aStrUrl.getLength());
+
+ skip_char(rCandidate, sal_Unicode('('), sal_Unicode('#'), nPos, nLen);
+ rtl::OUStringBuffer aTokenValue;
+ copyToLimiter(rCandidate, sal_Unicode(')'), nPos, aTokenValue, nLen);
+ rURL = aTokenValue.makeStringAndClear();
+
+ return true;
+ }
+
+ return false;
+ }
+
+ bool readSvgPaint(const rtl::OUString& rCandidate, SvgPaint& rSvgPaint, rtl::OUString& rURL)
+ {
+ const sal_Int32 nLen(rCandidate.getLength());
+
+ if(nLen)
+ {
+ basegfx::BColor aColor;
+
+ if(read_color(rCandidate, aColor))
+ {
+ rSvgPaint = SvgPaint(aColor, true, true);
+ return true;
+ }
+ else
+ {
+ static rtl::OUString aStrNone(rtl::OUString::createFromAscii("none"));
+ static rtl::OUString aStrCurrentColor(rtl::OUString::createFromAscii("currentColor"));
+
+ if(rCandidate.match(aStrNone, 0))
+ {
+ rSvgPaint = SvgPaint(aColor, true, false, false);
+ return true;
+ }
+ else if(readLocalUrl(rCandidate, rURL))
+ {
+ /// Url is copied to rURL, but needs to be solved outside this helper
+ return false;
+ }
+ else if(rCandidate.match(aStrCurrentColor, 0))
+ {
+ rSvgPaint = SvgPaint(aColor, true, true, true);
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ bool readSvgNumberVector(const rtl::OUString& rCandidate, SvgNumberVector& rSvgNumberVector)
+ {
+ const sal_Int32 nLen(rCandidate.getLength());
+ rSvgNumberVector.clear();
+
+ if(nLen)
+ {
+ sal_Int32 nPos(0);
+ SvgNumber aNum;
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ while(readNumberAndUnit(rCandidate, nPos, aNum, nLen))
+ {
+ rSvgNumberVector.push_back(aNum);
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+ }
+
+ return !rSvgNumberVector.empty();
+ }
+
+ return false;
+ }
+
+ SvgAspectRatio readSvgAspectRatio(const rtl::OUString& rCandidate)
+ {
+ const sal_Int32 nLen(rCandidate.getLength());
+
+ if(nLen)
+ {
+ sal_Int32 nPos(0);
+ SvgAlign aSvgAlign(Align_xMidYMid);
+ bool bDefer(false);
+ bool bMeetOrSlice(true);
+ bool bChanged(false);
+
+ while(nPos < nLen)
+ {
+ const sal_Int32 nInitPos(nPos);
+ skip_char(rCandidate, sal_Unicode(' '), nPos, nLen);
+ rtl::OUStringBuffer aTokenName;
+ copyString(rCandidate, nPos, aTokenName, nLen);
+
+ if(aTokenName.getLength())
+ {
+ switch(StrToSVGToken(aTokenName.makeStringAndClear()))
+ {
+ case SVGTokenDefer:
+ {
+ bDefer = true;
+ bChanged = true;
+ break;
+ }
+ case SVGTokenNone:
+ {
+ aSvgAlign = Align_none;
+ bChanged = true;
+ break;
+ }
+ case SVGTokenXMinYMin:
+ {
+ aSvgAlign = Align_xMinYMin;
+ bChanged = true;
+ break;
+ }
+ case SVGTokenXMidYMin:
+ {
+ aSvgAlign = Align_xMidYMin;
+ bChanged = true;
+ break;
+ }
+ case SVGTokenXMaxYMin:
+ {
+ aSvgAlign = Align_xMaxYMin;
+ bChanged = true;
+ break;
+ }
+ case SVGTokenXMinYMid:
+ {
+ aSvgAlign = Align_xMinYMid;
+ bChanged = true;
+ break;
+ }
+ case SVGTokenXMidYMid:
+ {
+ aSvgAlign = Align_xMidYMid;
+ bChanged = true;
+ break;
+ }
+ case SVGTokenXMaxYMid:
+ {
+ aSvgAlign = Align_xMaxYMid;
+ bChanged = true;
+ break;
+ }
+ case SVGTokenXMinYMax:
+ {
+ aSvgAlign = Align_xMinYMax;
+ bChanged = true;
+ break;
+ }
+ case SVGTokenXMidYMax:
+ {
+ aSvgAlign = Align_xMidYMax;
+ bChanged = true;
+ break;
+ }
+ case SVGTokenXMaxYMax:
+ {
+ aSvgAlign = Align_xMaxYMax;
+ bChanged = true;
+ break;
+ }
+ case SVGTokenMeet:
+ {
+ bMeetOrSlice = true;
+ bChanged = true;
+ break;
+ }
+ case SVGTokenSlice:
+ {
+ bMeetOrSlice = false;
+ bChanged = true;
+ break;
+ }
+ }
+ }
+
+ if(nInitPos == nPos)
+ {
+ OSL_ENSURE(false, "Could not interpret on current position (!)");
+ nPos++;
+ }
+ }
+
+ if(bChanged)
+ {
+ return SvgAspectRatio(aSvgAlign, bDefer, bMeetOrSlice);
+ }
+ }
+
+ return SvgAspectRatio();
+ }
+
+ bool readSvgStringVector(const rtl::OUString& rCandidate, SvgStringVector& rSvgStringVector)
+ {
+ rSvgStringVector.clear();
+ const sal_Int32 nLen(rCandidate.getLength());
+
+ if(nLen)
+ {
+ sal_Int32 nPos(0);
+ rtl::OUStringBuffer aTokenValue;
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ while(nPos < nLen)
+ {
+ copyToLimiter(rCandidate, sal_Unicode(','), nPos, aTokenValue, nLen);
+ skip_char(rCandidate, sal_Unicode(','), sal_Unicode(' '), nPos, nLen);
+ const rtl::OUString aString = aTokenValue.makeStringAndClear();
+
+ if(aString.getLength())
+ {
+ rSvgStringVector.push_back(aString);
+ }
+ }
+ }
+
+ return !rSvgStringVector.empty();
+ }
+
+ void readImageLink(const rtl::OUString& rCandidate, rtl::OUString& rXLink, rtl::OUString& rUrl, rtl::OUString& rMimeType, rtl::OUString& rData)
+ {
+ rXLink = rUrl = rMimeType = rData = rtl::OUString();
+
+ if(sal_Unicode('#') == rCandidate[0])
+ {
+ // local link
+ rXLink = rCandidate.copy(1);
+ }
+ else
+ {
+ static rtl::OUString aStrData(rtl::OUString::createFromAscii("data:"));
+
+ if(rCandidate.match(aStrData, 0))
+ {
+ // embedded data
+ sal_Int32 nPos(aStrData.getLength());
+ sal_Int32 nLen(rCandidate.getLength());
+ rtl::OUStringBuffer aBuffer;
+
+ // read mime type
+ skip_char(rCandidate, sal_Unicode(' '), nPos, nLen);
+ copyToLimiter(rCandidate, sal_Unicode(';'), nPos, aBuffer, nLen);
+ skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(';'), nPos, nLen);
+ rMimeType = aBuffer.makeStringAndClear();
+
+ if(rMimeType.getLength() && nPos < nLen)
+ {
+ static rtl::OUString aStrImage(rtl::OUString::createFromAscii("image"));
+
+ if(rMimeType.match(aStrImage, 0))
+ {
+ // image data
+ rtl::OUString aData(rCandidate.copy(nPos));
+ static rtl::OUString aStrBase64(rtl::OUString::createFromAscii("base64"));
+
+ if(aData.match(aStrBase64, 0))
+ {
+ // base64 encoded
+ nPos = aStrBase64.getLength();
+ nLen = aData.getLength();
+
+ skip_char(aData, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
+
+ if(nPos < nLen)
+ {
+ rData = aData.copy(nPos);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // Url (path and filename)
+ rUrl = rCandidate;
+ }
+ }
+ }
+
+ rtl::OUString convert(const rtl::OUString& rCandidate, const sal_Unicode& rPattern, const sal_Unicode& rNew, bool bRemove)
+ {
+ const sal_Int32 nLen(rCandidate.getLength());
+
+ if(nLen)
+ {
+ sal_Int32 nPos(0);
+ rtl::OUStringBuffer aBuffer;
+ bool bChanged(false);
+
+ while(nPos < nLen)
+ {
+ const sal_Unicode aChar(rCandidate[nPos]);
+
+ if(rPattern == aChar)
+ {
+ bChanged = true;
+
+ if(!bRemove)
+ {
+ aBuffer.append(rNew);
+ }
+ }
+ else
+ {
+ aBuffer.append(aChar);
+ }
+
+ nPos++;
+ }
+
+ if(bChanged)
+ {
+ return aBuffer.makeStringAndClear();
+ }
+ }
+
+ return rCandidate;
+ }
+
+ rtl::OUString consolidateContiguosSpace(const rtl::OUString& rCandidate)
+ {
+ const sal_Int32 nLen(rCandidate.getLength());
+
+ if(nLen)
+ {
+ sal_Int32 nPos(0);
+ rtl::OUStringBuffer aBuffer;
+ bool bInsideSpace(false);
+ const sal_Unicode aSpace(' ');
+
+ while(nPos < nLen)
+ {
+ const sal_Unicode aChar(rCandidate[nPos]);
+
+ if(aSpace == aChar)
+ {
+ bInsideSpace = true;
+ }
+ else
+ {
+ if(bInsideSpace)
+ {
+ bInsideSpace = false;
+ aBuffer.append(aSpace);
+ }
+
+ aBuffer.append(aChar);
+ }
+
+ nPos++;
+ }
+
+ if(bInsideSpace)
+ {
+ aBuffer.append(aSpace);
+ }
+
+ if(aBuffer.getLength() != nLen)
+ {
+ return aBuffer.makeStringAndClear();
+ }
+ }
+
+ return rCandidate;
+ }
+
+ rtl::OUString whiteSpaceHandlingDefault(const rtl::OUString& rCandidate)
+ {
+ const sal_Unicode aNewline('\n');
+ const sal_Unicode aTab('\t');
+ const sal_Unicode aSpace(' ');
+
+ // remove all newline characters
+ rtl::OUString aRetval(convert(rCandidate, aNewline, aNewline, true));
+
+ // convert tab to space
+ aRetval = convert(aRetval, aTab, aSpace, false);
+
+ // strip of all leading and trailing spaces
+ aRetval = aRetval.trim();
+
+ // consolidate contiguos space
+ aRetval = consolidateContiguosSpace(aRetval);
+
+ return aRetval;
+ }
+
+ rtl::OUString whiteSpaceHandlingPreserve(const rtl::OUString& rCandidate)
+ {
+ const sal_Unicode aNewline('\n');
+ const sal_Unicode aTab('\t');
+ const sal_Unicode aSpace(' ');
+
+ // convert newline to space
+ rtl::OUString aRetval(convert(rCandidate, aNewline, aSpace, false));
+
+ // convert tab to space
+ aRetval = convert(rCandidate, aTab, aSpace, false);
+
+ return rCandidate;
+ }
+
+ ::std::vector< double > solveSvgNumberVector(const SvgNumberVector& rInput, const InfoProvider& rInfoProvider, NumberType aNumberType)
+ {
+ ::std::vector< double > aRetval;
+
+ if(!rInput.empty())
+ {
+ const double nCount(rInput.size());
+ aRetval.reserve(nCount);
+
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ aRetval.push_back(rInput[a].solve(rInfoProvider, aNumberType));
+ }
+ }
+
+ return aRetval;
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgtrefnode.cxx b/svgio/source/svgreader/svgtrefnode.cxx
new file mode 100644
index 000000000000..fb0d04143e8f
--- /dev/null
+++ b/svgio/source/svgreader/svgtrefnode.cxx
@@ -0,0 +1,90 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgtrefnode.hxx>
+#include <svgio/svgreader/svgdocument.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgTrefNode::SvgTrefNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenTref, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ maXLink()
+ {
+ }
+
+ SvgTrefNode::~SvgTrefNode()
+ {
+ }
+
+ const SvgStyleAttributes* SvgTrefNode::getSvgStyleAttributes() const
+ {
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgTrefNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenXlinkHref:
+ {
+ const sal_Int32 nLen(aContent.getLength());
+
+ if(nLen && sal_Unicode('#') == aContent[0])
+ {
+ maXLink = aContent.copy(1);
+ }
+ break;
+ }
+ }
+ }
+
+ const SvgTextNode* SvgTrefNode::getReferencedSvgTextNode() const
+ {
+ return dynamic_cast< const SvgTextNode* >(getDocument().findSvgNodeById(maXLink));
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgtspannode.cxx b/svgio/source/svgreader/svgtspannode.cxx
new file mode 100644
index 000000000000..8c66a9eecd99
--- /dev/null
+++ b/svgio/source/svgreader/svgtspannode.cxx
@@ -0,0 +1,77 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgtspannode.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgTspanNode::SvgTspanNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenTspan, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ maSvgTextPositions()
+ {
+ }
+
+ SvgTspanNode::~SvgTspanNode()
+ {
+ }
+
+ const SvgStyleAttributes* SvgTspanNode::getSvgStyleAttributes() const
+ {
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgTspanNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // read text position attributes
+ maSvgTextPositions.parseTextPositionAttributes(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ }
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svgreader/svgusenode.cxx b/svgio/source/svgreader/svgusenode.cxx
new file mode 100644
index 000000000000..c697f93b3b5e
--- /dev/null
+++ b/svgio/source/svgreader/svgusenode.cxx
@@ -0,0 +1,197 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgreader/svgusenode.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <svgio/svgreader/svgdocument.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ SvgUseNode::SvgUseNode(
+ SvgDocument& rDocument,
+ SvgNode* pParent)
+ : SvgNode(SVGTokenG, rDocument, pParent),
+ maSvgStyleAttributes(*this),
+ mpaTransform(0),
+ maX(),
+ maY(),
+ maWidth(),
+ maHeight(),
+ maXLink()
+ {
+ }
+
+ SvgUseNode::~SvgUseNode()
+ {
+ if(mpaTransform) delete mpaTransform;
+ }
+
+ const SvgStyleAttributes* SvgUseNode::getSvgStyleAttributes() const
+ {
+ return &maSvgStyleAttributes;
+ }
+
+ void SvgUseNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
+ {
+ // call parent
+ SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
+
+ // read style attributes
+ maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
+
+ // parse own
+ switch(aSVGToken)
+ {
+ case SVGTokenStyle:
+ {
+ maSvgStyleAttributes.readStyle(aContent);
+ break;
+ }
+ case SVGTokenTransform:
+ {
+ const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
+
+ if(!aMatrix.isIdentity())
+ {
+ setTransform(&aMatrix);
+ }
+ break;
+ }
+ case SVGTokenX:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setX(aNum);
+ }
+ break;
+ }
+ case SVGTokenY:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ setY(aNum);
+ }
+ break;
+ }
+ case SVGTokenWidth:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setWidth(aNum);
+ }
+ }
+ break;
+ }
+ case SVGTokenHeight:
+ {
+ SvgNumber aNum;
+
+ if(readSingleNumber(aContent, aNum))
+ {
+ if(aNum.isPositive())
+ {
+ setHeight(aNum);
+ }
+ }
+ }
+ case SVGTokenXlinkHref:
+ {
+ const sal_Int32 nLen(aContent.getLength());
+
+ if(nLen && sal_Unicode('#') == aContent[0])
+ {
+ maXLink = aContent.copy(1);
+ }
+ break;
+ }
+ }
+ }
+
+ void SvgUseNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
+ {
+ // try to access link to content
+ const SvgNode* mpXLink = getDocument().findSvgNodeById(maXLink);
+
+ if(mpXLink)
+ {
+ // decompose childs
+ drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
+
+ // todo: in case mpXLink is a SVGTokenSvg or SVGTokenSymbol the
+ // SVG docs want the getWidth() and getHeight() from this node
+ // to be valid for the subtree.
+ const_cast< SvgNode* >(mpXLink)->setAlternativeParent(this);
+ mpXLink->decomposeSvgNode(aNewTarget, true);
+ const_cast< SvgNode* >(mpXLink)->setAlternativeParent(0);
+
+ if(aNewTarget.hasElements())
+ {
+ basegfx::B2DHomMatrix aTransform;
+
+ if(getX().isSet() || getY().isSet())
+ {
+ aTransform.translate(
+ getX().solve(*this, xcoordinate),
+ getY().solve(*this, ycoordinate));
+ }
+
+ if(getTransform())
+ {
+ aTransform = *getTransform() * aTransform;
+ }
+
+ if(!aTransform.isIdentity())
+ {
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ aTransform,
+ aNewTarget));
+
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(rTarget, xRef);
+ }
+ else
+ {
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewTarget);
+ }
+ }
+ }
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svguno/svguno.cxx b/svgio/source/svguno/svguno.cxx
new file mode 100644
index 000000000000..eec9c86e3796
--- /dev/null
+++ b/svgio/source/svguno/svguno.cxx
@@ -0,0 +1,95 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <svgio/svgiodllapi.h>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <uno/environment.h>
+#include <cppuhelper/factory.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace ::com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+// predefines
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ extern uno::Sequence< rtl::OUString > SAL_CALL XSvgParser_getSupportedServiceNames();
+ extern rtl::OUString SAL_CALL XSvgParser_getImplementationName();
+ extern uno::Reference< uno::XInterface > SAL_CALL XSvgParser_createInstance( const uno::Reference< lang::XMultiServiceFactory > & );
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// component_getImplementationEnvironment
+
+extern "C"
+{
+ SVGIO_DLLPUBLIC void SAL_CALL component_getImplementationEnvironment( const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */ )
+ {
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// component_getFactory
+
+extern "C"
+{
+ SVGIO_DLLPUBLIC void* SAL_CALL component_getFactory( const sal_Char* pImplName, void* pServiceManager, void* /* pRegistryKey */ )
+ {
+ uno::Reference< lang::XSingleServiceFactory > xFactory;
+ void* pRet = 0;
+
+ if(svgio::svgreader::XSvgParser_getImplementationName().equalsAscii(pImplName))
+ {
+ xFactory = ::cppu::createSingleFactory(
+ reinterpret_cast< lang::XMultiServiceFactory * >(pServiceManager),
+ svgio::svgreader::XSvgParser_getImplementationName(),
+ svgio::svgreader::XSvgParser_createInstance,
+ svgio::svgreader::XSvgParser_getSupportedServiceNames());
+ }
+
+ if(xFactory.is())
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/source/svguno/xsvgparser.cxx b/svgio/source/svguno/xsvgparser.cxx
new file mode 100644
index 000000000000..92459a6a7632
--- /dev/null
+++ b/svgio/source/svguno/xsvgparser.cxx
@@ -0,0 +1,194 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svgio.hxx"
+
+#include <com/sun/star/graphic/XSvgParser.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/implbase2.hxx>
+#include <svgio/svgreader/svgdocumenthandler.hxx>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <comphelper/processfactory.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace ::com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ class XSvgParser : public ::cppu::WeakAggImplHelper2< graphic::XSvgParser, lang::XServiceInfo >
+ {
+ private:
+ XSvgParser(const XSvgParser&);
+ XSvgParser& operator=(const XSvgParser&);
+
+ protected:
+ public:
+ XSvgParser();
+ virtual ~XSvgParser();
+
+ // XSvgParser
+ virtual uno::Sequence< uno::Reference< ::graphic::XPrimitive2D > > SAL_CALL getDecomposition(
+ const uno::Reference< ::io::XInputStream >& xSVGStream,
+ const ::rtl::OUString& aAbsolutePath) throw (uno::RuntimeException);
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL getImplementationName() throw(uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL supportsService(const rtl::OUString&) throw(uno::RuntimeException);
+ virtual uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames() throw(uno::RuntimeException);
+ };
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// uno functions
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ uno::Sequence< rtl::OUString > XSvgParser_getSupportedServiceNames()
+ {
+ static rtl::OUString aServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.graphic.SvgTools" ) );
+ static uno::Sequence< rtl::OUString > aServiceNames( &aServiceName, 1 );
+
+ return( aServiceNames );
+ }
+
+ rtl::OUString XSvgParser_getImplementationName()
+ {
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "svgio::svgreader::XSvgParser" ) );
+ }
+
+ uno::Reference< uno::XInterface > SAL_CALL XSvgParser_createInstance(const uno::Reference< lang::XMultiServiceFactory >&)
+ {
+ return static_cast< ::cppu::OWeakObject* >(new XSvgParser);
+ }
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace svgio
+{
+ namespace svgreader
+ {
+ XSvgParser::XSvgParser()
+ {
+ }
+
+ XSvgParser::~XSvgParser()
+ {
+ }
+
+ uno::Sequence< uno::Reference< ::graphic::XPrimitive2D > > XSvgParser::getDecomposition(
+ const uno::Reference< ::io::XInputStream >& xSVGStream,
+ const ::rtl::OUString& aAbsolutePath ) throw (uno::RuntimeException)
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aRetval;
+
+ if(xSVGStream.is())
+ {
+ // local document handler
+ SvgDocHdl* pSvgDocHdl = new SvgDocHdl(aAbsolutePath);
+ uno::Reference< xml::sax::XDocumentHandler > xSvgDocHdl(pSvgDocHdl);
+
+ try
+ {
+ // prepare ParserInputSrouce
+ xml::sax::InputSource myInputSource;
+ myInputSource.aInputStream = xSVGStream;
+
+ // get parser
+ uno::Reference< xml::sax::XParser > xParser(
+ comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString::createFromAscii("com.sun.star.xml.sax.Parser") ),
+ uno::UNO_QUERY_THROW );
+
+ // connect parser and filter
+ xParser->setDocumentHandler(xSvgDocHdl);
+
+ // finally, parse the stream to a hierarchy of
+ // SVGGraphicPrimitive2D which will be embedded to the
+ // primitive sequence. Their decompositions will in the
+ // end create local low-level primitives, thus SVG will
+ // be processable from all our processors
+ xParser->parseStream(myInputSource);
+ }
+ catch(uno::Exception&)
+ {
+ OSL_ENSURE(false, "Parse error (!)");
+ }
+
+ // decompose to primitives
+ const SvgNodeVector& rResults = pSvgDocHdl->getSvgDocument().getSvgNodeVector();
+ const sal_uInt32 nCount(rResults.size());
+
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ rResults[a]->decomposeSvgNode(aRetval, false);
+ }
+ }
+ else
+ {
+ OSL_ENSURE(false, "Invalid stream (!)");
+ }
+
+ return aRetval;
+ }
+
+ rtl::OUString SAL_CALL XSvgParser::getImplementationName() throw(uno::RuntimeException)
+ {
+ return(XSvgParser_getImplementationName());
+ }
+
+ sal_Bool SAL_CALL XSvgParser::supportsService(const rtl::OUString& rServiceName) throw(uno::RuntimeException)
+ {
+ const uno::Sequence< rtl::OUString > aServices(XSvgParser_getSupportedServiceNames());
+
+ for(sal_Int32 nService(0); nService < aServices.getLength(); nService++)
+ {
+ if(rServiceName == aServices[nService])
+ {
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+ }
+
+ uno::Sequence< rtl::OUString > SAL_CALL XSvgParser::getSupportedServiceNames() throw(uno::RuntimeException)
+ {
+ return XSvgParser_getSupportedServiceNames();
+ }
+
+ } // end of namespace svgreader
+} // end of namespace svgio
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svgio/svgio.component b/svgio/svgio.component
new file mode 100644
index 000000000000..24ff62613029
--- /dev/null
+++ b/svgio/svgio.component
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="svgio::svgreader::XSvgParser">
+ <service name="com.sun.star.graphic.SvgTools"/>
+ </implementation>
+</component>
diff --git a/svtools/inc/svtools/grfmgr.hxx b/svtools/inc/svtools/grfmgr.hxx
index 4dde3c57494b..1155820e85a8 100644
--- a/svtools/inc/svtools/grfmgr.hxx
+++ b/svtools/inc/svtools/grfmgr.hxx
@@ -217,8 +217,6 @@ private:
sal_Bool mbIsInSwapOut : 1;
sal_Bool mbAlpha : 1;
sal_Bool mbDummyFlag8 : 1;
- sal_Bool mbIsRenderGraphic : 1;
- sal_Bool mbHasRenderGraphic : 1;
void SVT_DLLPRIVATE ImplConstruct();
void SVT_DLLPRIVATE ImplAssignGraphicData();
@@ -400,8 +398,6 @@ public:
sal_Bool IsAlpha() const { return mbAlpha; }
sal_Bool IsAnimated() const { return mbAnimated; }
sal_Bool IsEPS() const { return mbEPS; }
- sal_Bool IsRenderGraphic() const { return mbIsRenderGraphic; }
- sal_Bool HasRenderGraphic() const { return mbHasRenderGraphic; }
void ResetAnimationLoopCount();
List* GetAnimationInfoList() const;
diff --git a/svtools/source/filter/filter.cxx b/svtools/source/filter/filter.cxx
index 4e5cc6a72451..2942ef925f19 100644
--- a/svtools/source/filter/filter.cxx
+++ b/svtools/source/filter/filter.cxx
@@ -35,7 +35,7 @@
#include <vcl/salctype.hxx>
#include <vcl/pngread.hxx>
#include <vcl/pngwrite.hxx>
-#include <vcl/svgread.hxx>
+#include <vcl/svgdata.hxx>
#include <vcl/virdev.hxx>
#include <vcl/svapp.hxx>
#include <osl/file.hxx>
@@ -71,6 +71,7 @@
#include <comphelper/processfactory.hxx>
#include <rtl/bootstrap.hxx>
#include <rtl/instance.hxx>
+#include <vcl/metaact.hxx>
#include "SvFilterOptionsDialog.hxx"
@@ -675,13 +676,19 @@ static sal_Bool ImpPeekGraphicFormat( SvStream& rStream, String& rFormatExtensio
}
//--------------------------- SVG ------------------------------------
- if( !bTest || ( rFormatExtension.CompareToAscii( "SVG", 3 ) == COMPARE_EQUAL ) )
+ if( !bTest )
{
- bSomethingTested=sal_True;
-
- // just a simple test for the extension
- if( rFormatExtension.CompareToAscii( "SVG", 3 ) == COMPARE_EQUAL )
+ if( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"DOCTYPE", 256, 7 )
+ && ImplSearchEntry( sFirstBytes, (sal_uInt8*)"svg", 256, 3 ) )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "SVG", 3 );
return sal_True;
+ }
+ }
+ else if( rFormatExtension.CompareToAscii( "SVG", 3 ) == COMPARE_EQUAL )
+ {
+ bSomethingTested = sal_True;
+ return sal_True;
}
//--------------------------- TGA ------------------------------------
@@ -1500,21 +1507,38 @@ sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath,
if( rGraphic.GetContext() == (GraphicReader*) 1 )
rGraphic.SetContext( NULL );
- vcl::SVGReader aSVGReader( rIStream );
- GDIMetaFile aSVGMtf;
+ const sal_uInt32 nStmPos(rIStream.Tell());
+ const sal_uInt32 nStmLen(rIStream.Seek(STREAM_SEEK_TO_END) - nStmPos);
+ bool bOkay(false);
- if( 0 == aSVGReader.Read( aSVGMtf ).GetActionCount() )
- nStatus = GRFILTER_FILTERERROR;
+ if(nStmLen)
+ {
+ SvgDataArray aNewData(new sal_uInt8[nStmLen]);
+
+ rIStream.Seek(nStmPos);
+ rIStream.Read(aNewData.get(), nStmLen);
+
+ if(!rIStream.GetError())
+ {
+ SvgDataPtr aSvgDataPtr(
+ new SvgData(
+ aNewData,
+ nStmLen,
+ rPath));
+
+ rGraphic = Graphic(aSvgDataPtr);
+ bOkay = true;
+ }
+ }
+
+ if(bOkay)
+ {
+ eLinkType = GFX_LINK_TYPE_NATIVE_SVG;
+ }
else
- rGraphic = Graphic( aSVGMtf );
-
- // Dont set any GfxLink here, since the MetaRenderGraphicAction
- // inside the just read MetaFile contains excatly this native data;
- // setting a ǴfxLink would also affect other program parts, since
- // GfxLinks are preferably written to the file format in general,
- // which would be a bad idea in case of SVG files, since earlier
- // implementations are not able to handle native SVG data in any
- // case. (KA 01/19/2011)
+ {
+ nStatus = GRFILTER_FILTERERROR;
+ }
}
else if( aFilterName.EqualsIgnoreCaseAscii( IMP_XBM ) )
{
@@ -1856,7 +1880,7 @@ sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const String&
aMTF.SetPrefSize( aGraphic.GetPrefSize() );
aMTF.SetPrefMapMode( aGraphic.GetPrefMapMode() );
}
- aMTF.Write( rOStm, GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC );
+ aMTF.Write( rOStm );
if( rOStm.GetError() )
nStatus = GRFILTER_IOERROR;
}
@@ -1973,24 +1997,22 @@ sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const String&
}
else if( aFilterName.EqualsIgnoreCaseAscii( EXP_SVG ) )
{
- sal_Bool bDone = sal_False;
+ bool bDone(false);
// do we have a native SVG RenderGraphic, whose data can be written directly?
- if( ( GRAPHIC_GDIMETAFILE == eType ) && aGraphic.IsRenderGraphic() )
+ const SvgDataPtr aSvgDataPtr(rGraphic.getSvgData());
+
+ if(aSvgDataPtr.get() && aSvgDataPtr->getSvgDataArrayLength())
{
- const ::vcl::RenderGraphic aRenderGraphic( aGraphic.GetRenderGraphic() );
+ rOStm.Write(aSvgDataPtr->getSvgDataArray().get(), aSvgDataPtr->getSvgDataArrayLength());
- if( aRenderGraphic.GetGraphicDataLength() &&
- aRenderGraphic.GetGraphicDataMimeType().equalsIgnoreAsciiCase(
- ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/svg+xml" ) ) ) )
+ if( rOStm.GetError() )
{
- rOStm.Write( aRenderGraphic.GetGraphicData().get(),
- aRenderGraphic.GetGraphicDataLength() );
-
- if( rOStm.GetError() )
- {
- nStatus = GRFILTER_IOERROR;
- }
+ nStatus = GRFILTER_IOERROR;
+ }
+ else
+ {
+ bDone = true;
}
}
diff --git a/svtools/source/filter/wmf/emfwr.cxx b/svtools/source/filter/wmf/emfwr.cxx
index 99ca92c76abb..2d5e5c4170ad 100644
--- a/svtools/source/filter/wmf/emfwr.cxx
+++ b/svtools/source/filter/wmf/emfwr.cxx
@@ -33,7 +33,6 @@
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <vcl/lineinfo.hxx>
-#include <vcl/rendergraphicrasterizer.hxx>
// -----------
// - Defines -
@@ -1408,26 +1407,6 @@ void EMFWriter::ImplWrite( const GDIMetaFile& rMtf )
}
break;
- case( META_RENDERGRAPHIC_ACTION ):
- {
- const MetaRenderGraphicAction* pA = (const MetaRenderGraphicAction*) pAction;
- const ::vcl::RenderGraphicRasterizer aRasterizer( pA->GetRenderGraphic() );
- const BitmapEx aBmpEx( aRasterizer.Rasterize( maVDev.LogicToPixel( pA->GetSize() ) ) );
- Bitmap aBmp( aBmpEx.GetBitmap() );
- Bitmap aMsk( aBmpEx.GetMask() );
-
- if( !!aMsk )
- {
- aBmp.Replace( aMsk, COL_WHITE );
- aMsk.Invert();
- ImplWriteBmpRecord( aMsk, pA->GetPoint(), pA->GetSize(), WIN_SRCPAINT );
- ImplWriteBmpRecord( aBmp, pA->GetPoint(), pA->GetSize(), WIN_SRCAND );
- }
- else
- ImplWriteBmpRecord( aBmp, pA->GetPoint(), pA->GetSize(), WIN_SRCCOPY );
- }
- break;
-
default:
DBG_ERROR( ( ByteString( "EMFWriter::ImplWriteActions: unsupported MetaAction #" ) += ByteString::CreateFromInt32( nType ) ).GetBuffer() );
break;
diff --git a/svtools/source/filter/wmf/wmfwr.cxx b/svtools/source/filter/wmf/wmfwr.cxx
index 26bda76a11d9..8067c0966ac5 100644
--- a/svtools/source/filter/wmf/wmfwr.cxx
+++ b/svtools/source/filter/wmf/wmfwr.cxx
@@ -29,7 +29,6 @@
#include "precompiled_svtools.hxx"
#include <vcl/salbtype.hxx>
-#include <vcl/rendergraphicrasterizer.hxx>
#include "wmfwr.hxx"
#include <unotools/fontcvt.hxx>
#include "emfwr.hxx"
@@ -319,7 +318,6 @@ void WMFWriter::CountActionsAndBitmaps( const GDIMetaFile & rMTF )
case META_BMPEX_ACTION:
case META_BMPEXSCALE_ACTION:
case META_BMPEXSCALEPART_ACTION:
- case META_RENDERGRAPHIC_ACTION:
nNumberOfBitmaps++;
break;
}
@@ -1799,26 +1797,6 @@ void WMFWriter::WriteRecords( const GDIMetaFile & rMTF )
}
break;
- case( META_RENDERGRAPHIC_ACTION ):
- {
- const MetaRenderGraphicAction* pA = (const MetaRenderGraphicAction*) pMA;
- const ::vcl::RenderGraphicRasterizer aRasterizer( pA->GetRenderGraphic() );
- const BitmapEx aBmpEx( aRasterizer.Rasterize( pVirDev->LogicToPixel( pA->GetSize(), aSrcMapMode ) ) );
- Bitmap aBmp( aBmpEx.GetBitmap() );
- Bitmap aMsk( aBmpEx.GetMask() );
-
- if( !!aMsk )
- {
- aBmp.Replace( aMsk, COL_WHITE );
- aMsk.Invert();
- WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aMsk, W_SRCPAINT );
- WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aBmp, W_SRCAND );
- }
- else
- WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aBmp );
- }
- break;
-
default:
{
DBG_ERROR( "Unsupported meta action!" );
diff --git a/svtools/source/graphic/descriptor.cxx b/svtools/source/graphic/descriptor.cxx
index 2c1053857593..7ad32926d155 100644
--- a/svtools/source/graphic/descriptor.cxx
+++ b/svtools/source/graphic/descriptor.cxx
@@ -393,7 +393,10 @@ void GraphicDescriptor::_getPropertyValues( const comphelper::PropertyMapEntry**
case( GFX_LINK_TYPE_NATIVE_PNG ): pMimeType = MIMETYPE_PNG; break;
case( GFX_LINK_TYPE_NATIVE_WMF ): pMimeType = MIMETYPE_WMF; break;
case( GFX_LINK_TYPE_NATIVE_MET ): pMimeType = MIMETYPE_MET; break;
- case( GFX_LINK_TYPE_NATIVE_PCT ): pMimeType = MIMETYPE_PCT ; break;
+ case( GFX_LINK_TYPE_NATIVE_PCT ): pMimeType = MIMETYPE_PCT; break;
+
+ // added Svg mimetype support
+ case( GFX_LINK_TYPE_NATIVE_SVG ): pMimeType = MIMETYPE_SVG; break;
default:
pMimeType = NULL;
diff --git a/svtools/source/graphic/grfcache.cxx b/svtools/source/graphic/grfcache.cxx
index 39ff71280b5a..4f5c85762c14 100644
--- a/svtools/source/graphic/grfcache.cxx
+++ b/svtools/source/graphic/grfcache.cxx
@@ -29,7 +29,7 @@
#include <vcl/outdev.hxx>
#include <tools/poly.hxx>
#include "grfcache.hxx"
-
+#include <rtl/crc.h>
#include <memory>
// -----------
@@ -88,7 +88,17 @@ GraphicID::GraphicID( const GraphicObject& rObj )
{
case( GRAPHIC_BITMAP ):
{
- if( rGraphic.IsAnimated() )
+ if(rGraphic.getSvgData().get())
+ {
+ const SvgDataPtr& rSvgDataPtr = rGraphic.getSvgData();
+ const basegfx::B2DRange& rRange = rSvgDataPtr->getRange();
+
+ mnID1 |= rSvgDataPtr->getSvgDataArrayLength();
+ mnID2 = basegfx::fround(rRange.getWidth());
+ mnID3 = basegfx::fround(rRange.getHeight());
+ mnID4 = rtl_crc32(0, rSvgDataPtr->getSvgDataArray().get(), rSvgDataPtr->getSvgDataArrayLength());
+ }
+ else if( rGraphic.IsAnimated() )
{
const Animation aAnimation( rGraphic.GetAnimation() );
@@ -163,10 +173,13 @@ private:
BitmapEx* mpBmpEx;
GDIMetaFile* mpMtf;
Animation* mpAnimation;
- sal_Bool mbSwappedAll;
+ sal_Bool mbSwappedAll;
- sal_Bool ImplInit( const GraphicObject& rObj );
- sal_Bool ImplMatches( const GraphicObject& rObj ) const { return( GraphicID( rObj ) == maID ); }
+ // SvgData support
+ SvgDataPtr maSvgData;
+
+ sal_Bool ImplInit( const GraphicObject& rObj );
+ sal_Bool ImplMatches( const GraphicObject& rObj ) const { return( GraphicID( rObj ) == maID ); }
void ImplFillSubstitute( Graphic& rSubstitute );
public:
@@ -194,8 +207,9 @@ GraphicCacheEntry::GraphicCacheEntry( const GraphicObject& rObj ) :
mpBmpEx ( NULL ),
mpMtf ( NULL ),
mpAnimation ( NULL ),
- mbSwappedAll ( !ImplInit( rObj ) )
+ mbSwappedAll ( true )
{
+ mbSwappedAll = !ImplInit(rObj);
maGraphicObjectList.Insert( (void*) &rObj, LIST_APPEND );
}
@@ -233,10 +247,18 @@ sal_Bool GraphicCacheEntry::ImplInit( const GraphicObject& rObj )
{
case( GRAPHIC_BITMAP ):
{
- if( rGraphic.IsAnimated() )
+ if(rGraphic.getSvgData().get())
+ {
+ maSvgData = rGraphic.getSvgData();
+ }
+ else if( rGraphic.IsAnimated() )
+ {
mpAnimation = new Animation( rGraphic.GetAnimation() );
+ }
else
+ {
mpBmpEx = new BitmapEx( rGraphic.GetBitmapEx() );
+ }
}
break;
@@ -280,14 +302,26 @@ void GraphicCacheEntry::ImplFillSubstitute( Graphic& rSubstitute )
if( rSubstitute.IsLink() && ( GFX_LINK_TYPE_NONE == maGfxLink.GetType() ) )
maGfxLink = rSubstitute.GetLink();
- if( mpBmpEx )
+ if(maSvgData.get())
+ {
+ rSubstitute = maSvgData;
+ }
+ else if( mpBmpEx )
+ {
rSubstitute = *mpBmpEx;
+ }
else if( mpAnimation )
+ {
rSubstitute = *mpAnimation;
+ }
else if( mpMtf )
+ {
rSubstitute = *mpMtf;
+ }
else
+ {
rSubstitute.Clear();
+ }
if( eOldType != GRAPHIC_NONE )
{
@@ -298,10 +332,14 @@ void GraphicCacheEntry::ImplFillSubstitute( Graphic& rSubstitute )
}
if( GFX_LINK_TYPE_NONE != maGfxLink.GetType() )
+ {
rSubstitute.SetLink( maGfxLink );
+ }
if( bDefaultType )
+ {
rSubstitute.SetDefaultType();
+ }
}
// -----------------------------------------------------------------------------
diff --git a/svtools/source/graphic/grfmgr.cxx b/svtools/source/graphic/grfmgr.cxx
index 3ae232ac2b7e..795afab7c0b6 100644
--- a/svtools/source/graphic/grfmgr.cxx
+++ b/svtools/source/graphic/grfmgr.cxx
@@ -187,8 +187,6 @@ void GraphicObject::ImplAssignGraphicData()
mbAlpha = maGraphic.IsAlpha();
mbAnimated = maGraphic.IsAnimated();
mbEPS = maGraphic.IsEPS();
- mbIsRenderGraphic = maGraphic.IsRenderGraphic();
- mbHasRenderGraphic = maGraphic.HasRenderGraphic();
mnAnimationLoopCount = ( mbAnimated ? maGraphic.GetAnimationLoopCount() : 0 );
}
@@ -438,7 +436,7 @@ void GraphicObject::Assign( const SvDataCopyStream& rCopyStream )
ByteString GraphicObject::GetUniqueID() const
{
- if ( !IsInSwapIn() && ( IsEPS() || IsRenderGraphic() ) )
+ if ( !IsInSwapIn() && IsEPS() )
const_cast<GraphicObject*>(this)->FireSwapInRequest();
ByteString aRet;
diff --git a/svtools/source/graphic/grfmgr2.cxx b/svtools/source/graphic/grfmgr2.cxx
index 57b09f5a90e7..61bc4b310038 100644
--- a/svtools/source/graphic/grfmgr2.cxx
+++ b/svtools/source/graphic/grfmgr2.cxx
@@ -865,8 +865,6 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
// FALLTHROUGH intended
case META_GRADIENTEX_ACTION:
// FALLTHROUGH intended
- case META_RENDERGRAPHIC_ACTION:
- // FALLTHROUGH intended
// OutDev state changes that _do_ affect bitmap
// output
diff --git a/svtools/source/graphic/provider.cxx b/svtools/source/graphic/provider.cxx
index 06e19c7fc26f..9ea46f5e2f29 100644
--- a/svtools/source/graphic/provider.cxx
+++ b/svtools/source/graphic/provider.cxx
@@ -628,17 +628,24 @@ void ImplApplyFilterData( ::Graphic& rGraphic, uno::Sequence< beans::PropertyVal
}
if ( rGraphic.GetType() == GRAPHIC_BITMAP )
{
- Rectangle aCropPixel( Point( 0, 0 ), rGraphic.GetSizePixel() );
- ImplCalculateCropRect( rGraphic, aCropLogic, aCropPixel );
- if ( bRemoveCropArea )
+ if(rGraphic.getSvgData().get())
{
- BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
- aBmpEx.Crop( aCropPixel );
- rGraphic = aBmpEx;
+ // embedded Svg, no need to scale. Also no method to apply crop data currently
+ }
+ else
+ {
+ Rectangle aCropPixel( Point( 0, 0 ), rGraphic.GetSizePixel() );
+ ImplCalculateCropRect( rGraphic, aCropLogic, aCropPixel );
+ if ( bRemoveCropArea )
+ {
+ BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+ aBmpEx.Crop( aCropPixel );
+ rGraphic = aBmpEx;
+ }
+ Size aVisiblePixelSize( bRemoveCropArea ? rGraphic.GetSizePixel() : aCropPixel.GetSize() );
+ ImplApplyBitmapResolution( rGraphic, nImageResolution, aVisiblePixelSize, aLogicalSize );
+ ImplApplyBitmapScaling( rGraphic, nPixelWidth, nPixelHeight );
}
- Size aVisiblePixelSize( bRemoveCropArea ? rGraphic.GetSizePixel() : aCropPixel.GetSize() );
- ImplApplyBitmapResolution( rGraphic, nImageResolution, aVisiblePixelSize, aLogicalSize );
- ImplApplyBitmapScaling( rGraphic, nPixelWidth, nPixelHeight );
}
else if ( ( rGraphic.GetType() == GRAPHIC_GDIMETAFILE ) && nImageResolution )
{
diff --git a/svx/inc/svx/sdr/contact/objectcontacttools.hxx b/svx/inc/svx/sdr/contact/objectcontacttools.hxx
index bbae70cf9b6e..bdd919d5b8f0 100644
--- a/svx/inc/svx/sdr/contact/objectcontacttools.hxx
+++ b/svx/inc/svx/sdr/contact/objectcontacttools.hxx
@@ -25,6 +25,7 @@
#define _SDR_CONTACT_OBJECTCONTACTTOOLS_HXX
#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <svx/svxdllapi.h>
//////////////////////////////////////////////////////////////////////////////
// predeclarations
@@ -44,7 +45,7 @@ namespace sdr
// create a mating VCL-Provessor for given OutputDevice. This includes
// looking for MetaFile-recording. The returned renderer changes owner,
// deletion is duty of the caller
- drawinglayer::processor2d::BaseProcessor2D* createBaseProcessor2DFromOutputDevice(
+ SVX_DLLPUBLIC drawinglayer::processor2d::BaseProcessor2D* createBaseProcessor2DFromOutputDevice(
OutputDevice& rTargetOutDev,
const drawinglayer::geometry::ViewInformation2D& rViewInformation2D);
diff --git a/svx/inc/svx/svdograf.hxx b/svx/inc/svx/svdograf.hxx
index 0607ee235225..b8437b7320c0 100644
--- a/svx/inc/svx/svdograf.hxx
+++ b/svx/inc/svx/svdograf.hxx
@@ -101,6 +101,7 @@ protected:
String aFileName; // Wenn es sich um einen Link handelt, steht hier der Dateiname drin.
String aFilterName;
GraphicObject* pGraphic; // Zur Beschleunigung von Bitmapausgaben, besonders von gedrehten.
+ GraphicObject* mpReplacementGraphic;
SdrGraphicLink* pGraphicLink; // Und hier noch ein Pointer fuer gelinkte Grafiken
bool bMirrored; // True bedeutet, die Grafik ist horizontal, d.h. ueber die Y-Achse gespiegelt auszugeben.
@@ -131,6 +132,7 @@ public:
void SetGraphicObject( const GraphicObject& rGrfObj );
const GraphicObject& GetGraphicObject( bool bForceSwapIn = false) const;
+ const GraphicObject* GetReplacementGraphicObject() const;
void NbcSetGraphic(const Graphic& rGrf);
void SetGraphic(const Graphic& rGrf);
@@ -144,8 +146,6 @@ public:
// Keep ATM for SD.
sal_Bool IsAnimated() const;
sal_Bool IsEPS() const;
- sal_Bool IsRenderGraphic() const;
- sal_Bool HasRenderGraphic() const;
sal_Bool IsSwappedOut() const;
const MapMode& GetGrafPrefMapMode() const;
@@ -199,6 +199,9 @@ public:
virtual void SetPage(SdrPage* pNewPage);
virtual void SetModel(SdrModel* pNewModel);
+ bool isEmbeddedSvg() const;
+ GDIMetaFile getMetafileFromEmbeddedSvg() const;
+
virtual SdrObject* DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const;
virtual void AdjustToMaxRect( const Rectangle& rMaxRect, bool bShrinkOnly = false );
diff --git a/svx/inc/svx/svdstr.hrc b/svx/inc/svx/svdstr.hrc
index c21a564f54a0..1c9a34901a33 100644
--- a/svx/inc/svx/svdstr.hrc
+++ b/svx/inc/svx/svdstr.hrc
@@ -181,11 +181,16 @@
#define STR_ObjNameSingulMEDIA (STR_ObjNameBegin + 143)
#define STR_ObjNamePluralMEDIA (STR_ObjNameBegin + 144)
-//#define STR_ObjNameEnd (STR_ObjNamePluralMEDIA)
//IAccessibility2 Implementation 2009-----
#define STR_ObjNameSingulFONTWORK (STR_ObjNameBegin+145)
#define STR_ObjNamePluralFONTWORK (STR_ObjNameBegin+146)
-#define STR_ObjNameEnd (STR_ObjNamePluralFONTWORK)
+
+// Svg support
+#define STR_ObjNameSingulGRAFSVG (STR_ObjNameBegin + 147)
+#define STR_ObjNamePluralGRAFSVG (STR_ObjNameBegin + 148)
+
+#define STR_ObjNameEnd (STR_ObjNamePluralGRAFSVG)
+
//-----IAccessibility2 Implementation 2009
#define STR_EditBegin (STR_ObjNameEnd+1)
#define STR_EditWithCopy (STR_EditBegin + 0)
diff --git a/svx/inc/svx/svdxcgv.hxx b/svx/inc/svx/svdxcgv.hxx
index 0942016b860a..8c08174f21f9 100644
--- a/svx/inc/svx/svdxcgv.hxx
+++ b/svx/inc/svx/svdxcgv.hxx
@@ -75,7 +75,7 @@ public:
// Alle markierten Objekte auf eine Bitmap malen. Diese hat die Farbtiefe
// und Aufloesung des Bildschirms.
- virtual Bitmap GetMarkedObjBitmap(sal_Bool bNoVDevIfOneBmpMarked=sal_False) const;
+ BitmapEx GetMarkedObjBitmap(bool bNoVDevIfOneBmpMarked = false) const;
// Alle markierten Objekte in ein neues Model kopieren. Dieses neue Model
// hat dann genau eine Page. Das Flag PageNotValid an diesem Model ist
@@ -90,7 +90,7 @@ public:
virtual SdrModel* GetMarkedObjModel() const;
GDIMetaFile GetAllMarkedMetaFile(sal_Bool bNoVDevIfOneMtfMarked=sal_False) const { return GetMarkedObjMetaFile(bNoVDevIfOneMtfMarked); }
- Bitmap GetAllMarkedBitmap(sal_Bool bNoVDevIfOneBmpMarked=sal_False) const { return GetMarkedObjBitmap(bNoVDevIfOneBmpMarked); }
+ Bitmap GetAllMarkedBitmap(sal_Bool bNoVDevIfOneBmpMarked=sal_False) const { return GetMarkedObjBitmap(bNoVDevIfOneBmpMarked).GetBitmap(); }
Graphic GetAllMarkedGraphic() const;
SdrModel* GetAllMarkedModel() const { return GetMarkedObjModel(); }
diff --git a/svx/inc/svx/unoshprp.hxx b/svx/inc/svx/unoshprp.hxx
index 2e6ac3c1106c..13c265a29365 100644
--- a/svx/inc/svx/unoshprp.hxx
+++ b/svx/inc/svx/unoshprp.hxx
@@ -125,6 +125,9 @@
#define OWN_ATTR_TRANSFORMATION (OWN_ATTR_VALUE_START+46)
#define OWN_ATTR_BASE_GEOMETRY (OWN_ATTR_VALUE_START+47)
+/// reuse attr slots for GraphicObject which will never be used together with graphic object
+#define OWN_ATTR_REPLACEMENTGRAFURL (OWN_ATTR_VALUE_START+14)
+
#define OWN_ATTR_APPLET_DOCBASE (OWN_ATTR_VALUE_START+48)
#define OWN_ATTR_APPLET_CODEBASE (OWN_ATTR_VALUE_START+49)
#define OWN_ATTR_APPLET_NAME (OWN_ATTR_VALUE_START+50)
@@ -415,11 +418,12 @@
#define SPECIAL_GRAPHOBJ_PROPERTIES \
SPECIAL_GRAPHOBJ_PROPERTIES_DEFAULTS \
- { MAP_CHAR_LEN(UNO_NAME_GRAPHIC_GRAPHICCROP), SDRATTR_GRAFCROP , &::getCppuType((const ::com::sun::star::text::GraphicCrop*)0), 0, 0 }, \
- { MAP_CHAR_LEN(UNO_NAME_GRAPHOBJ_GRAFURL), OWN_ATTR_GRAFURL , &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, \
- { MAP_CHAR_LEN(UNO_NAME_GRAPHOBJ_GRAFSTREAMURL),OWN_ATTR_GRAFSTREAMURL , &::getCppuType((const ::rtl::OUString*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, \
- { MAP_CHAR_LEN(UNO_NAME_GRAPHOBJ_FILLBITMAP), OWN_ATTR_VALUE_FILLBITMAP , &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap>*)0) , 0, 0}, \
- { MAP_CHAR_LEN(UNO_NAME_GRAPHOBJ_GRAPHIC), OWN_ATTR_VALUE_GRAPHIC , &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic>*)0) , 0, 0},
+ { MAP_CHAR_LEN(UNO_NAME_GRAPHIC_GRAPHICCROP), SDRATTR_GRAFCROP , &::getCppuType((const ::com::sun::star::text::GraphicCrop*)0), 0, 0 }, \
+ { MAP_CHAR_LEN(UNO_NAME_GRAPHOBJ_GRAFURL), OWN_ATTR_GRAFURL , &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, \
+ { MAP_CHAR_LEN(UNO_NAME_GRAPHOBJ_REPLACEMENTGRAFURL), OWN_ATTR_REPLACEMENTGRAFURL , &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, \
+ { MAP_CHAR_LEN(UNO_NAME_GRAPHOBJ_GRAFSTREAMURL), OWN_ATTR_GRAFSTREAMURL , &::getCppuType((const ::rtl::OUString*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, \
+ { MAP_CHAR_LEN(UNO_NAME_GRAPHOBJ_FILLBITMAP), OWN_ATTR_VALUE_FILLBITMAP , &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap>*)0) , 0, 0}, \
+ { MAP_CHAR_LEN(UNO_NAME_GRAPHOBJ_GRAPHIC), OWN_ATTR_VALUE_GRAPHIC , &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic>*)0) , 0, 0},
#define SPECIAL_3DSCENEOBJECT_PROPERTIES_DEFAULTS \
diff --git a/svx/source/dialog/_bmpmask.cxx b/svx/source/dialog/_bmpmask.cxx
index 91438ee278ad..73484ed512d6 100644
--- a/svx/source/dialog/_bmpmask.cxx
+++ b/svx/source/dialog/_bmpmask.cxx
@@ -1034,9 +1034,6 @@ GDIMetaFile SvxBmpMask::ImpMask( const GDIMetaFile& rMtf )
default:
{
- OSL_ENSURE( pAction->GetType() != META_RENDERGRAPHIC_ACTION,
- "META_RENDERGRAPHIC_ACTION currently not supported at masking" );
-
pAction->Duplicate();
aMtf.AddAction( pAction );
}
diff --git a/svx/source/sdr/contact/viewcontactofgraphic.cxx b/svx/source/sdr/contact/viewcontactofgraphic.cxx
index f8941f09b57b..f6c50e1a52df 100644
--- a/svx/source/sdr/contact/viewcontactofgraphic.cxx
+++ b/svx/source/sdr/contact/viewcontactofgraphic.cxx
@@ -410,11 +410,12 @@ namespace sdr
{
// create primitive. Info: Calling the copy-constructor of GraphicObject in this
// SdrGrafPrimitive2D constructor will force a full swap-in of the graphic
- const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::SdrGrafPrimitive2D(
- aObjectMatrix,
- aAttribute,
- rGraphicObject,
- aLocalGrafInfo));
+ const drawinglayer::primitive2d::Primitive2DReference xReference(
+ new drawinglayer::primitive2d::SdrGrafPrimitive2D(
+ aObjectMatrix,
+ aAttribute,
+ rGraphicObject,
+ aLocalGrafInfo));
xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
}
diff --git a/svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx
index 8178a6c88054..2630ddab7e48 100644
--- a/svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx
+++ b/svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx
@@ -19,8 +19,6 @@
*
*************************************************************/
-
-
#include "precompiled_svx.hxx"
#include <svx/sdr/primitive2d/sdrgrafprimitive2d.hxx>
#include <drawinglayer/primitive2d/graphicprimitive2d.hxx>
@@ -30,6 +28,8 @@
#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx>
#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
//////////////////////////////////////////////////////////////////////////////
@@ -94,6 +94,7 @@ namespace drawinglayer
// add graphic content
if(255L != getGraphicAttr().GetTransparency())
{
+ // standard graphic fill
const Primitive2DReference xGraphicContentPrimitive(
new GraphicPrimitive2D(
getTransform(),
@@ -160,7 +161,8 @@ namespace drawinglayer
bool SdrGrafPrimitive2D::isTransparent() const
{
- return ((0L != getGraphicAttr().GetTransparency()) || (getGraphicObject().IsTransparent()));
+ return ((0L != getGraphicAttr().GetTransparency())
+ || (getGraphicObject().IsTransparent()));
}
// provide unique ID
diff --git a/svx/source/svdraw/svddrgmt.cxx b/svx/source/svdraw/svddrgmt.cxx
index 668ef6fc7877..7047117c1a75 100644
--- a/svx/source/svdraw/svddrgmt.cxx
+++ b/svx/source/svdraw/svddrgmt.cxx
@@ -3628,6 +3628,19 @@ bool SdrDragCrop::EndSdrDrag(bool bCopy)
double fScaleX = ( aGraphicSize.Width() - rOldCrop.GetLeft() - rOldCrop.GetRight() ) / (double)aOldRect.GetWidth();
double fScaleY = ( aGraphicSize.Height() - rOldCrop.GetTop() - rOldCrop.GetBottom() ) / (double)aOldRect.GetHeight();
+ // to correct the never working combination of cropped images and mirroring
+ // I have to correct the rectangles the calculation is based on here. In the current
+ // core geometry stuff a vertical mirror is expressed as 180 degree rotation. All
+ // this can be removed again when aw080 will have cleaned up the old
+ // (non-)transformation mess in the core.
+ if(18000 == pObj->GetGeoStat().nDrehWink)
+ {
+ // old notation of vertical mirror, need to correct diffs since both rects
+ // are rotated by 180 degrees
+ aOldRect = Rectangle(aOldRect.TopLeft() - (aOldRect.BottomRight() - aOldRect.TopLeft()), aOldRect.TopLeft());
+ aNewRect = Rectangle(aNewRect.TopLeft() - (aNewRect.BottomRight() - aNewRect.TopLeft()), aNewRect.TopLeft());
+ }
+
sal_Int32 nDiffLeft = aNewRect.nLeft - aOldRect.nLeft;
sal_Int32 nDiffTop = aNewRect.nTop - aOldRect.nTop;
sal_Int32 nDiffRight = aNewRect.nRight - aOldRect.nRight;
diff --git a/svx/source/svdraw/svdedtv.cxx b/svx/source/svdraw/svdedtv.cxx
index d8921e50da18..5656cf02b34e 100644
--- a/svx/source/svdraw/svdedtv.cxx
+++ b/svx/source/svdraw/svdedtv.cxx
@@ -636,19 +636,20 @@ void SdrEditView::CheckPossibilities()
if (!bOrthoDesiredOnMarked && !aInfo.bNoOrthoDesired) bOrthoDesiredOnMarked=sal_True;
// ImportMtf checken
- if (!bImportMtfPossible) {
- sal_Bool bGraf=HAS_BASE(SdrGrafObj,pObj);
- sal_Bool bOle2=HAS_BASE(SdrOle2Obj,pObj);
+ if (!bImportMtfPossible)
+ {
+ const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pObj);
+ const SdrOle2Obj* pSdrOle2Obj = dynamic_cast< const SdrOle2Obj* >(pObj);
- if( bGraf &&
- ((SdrGrafObj*)pObj)->HasGDIMetaFile() &&
- !( ((SdrGrafObj*)pObj)->IsEPS() || ((SdrGrafObj*)pObj)->IsRenderGraphic() ) )
+ if(pSdrGrafObj && ((pSdrGrafObj->HasGDIMetaFile() && !pSdrGrafObj->IsEPS()) || pSdrGrafObj->isEmbeddedSvg()))
{
bImportMtfPossible = sal_True;
}
- if (bOle2)
- bImportMtfPossible=((SdrOle2Obj*)pObj)->GetObjRef().is();
+ if(pSdrOle2Obj)
+ {
+ bImportMtfPossible = pSdrOle2Obj->GetObjRef().is();
+ }
}
}
diff --git a/svx/source/svdraw/svdedtv2.cxx b/svx/source/svdraw/svdedtv2.cxx
index 3b003c8c54c4..d9e97abc54a2 100644
--- a/svx/source/svdraw/svdedtv2.cxx
+++ b/svx/source/svdraw/svdedtv2.cxx
@@ -2073,17 +2073,30 @@ void SdrEditView::DoImportMarkedMtf(SvdProgressInfo *pProgrInfo)
sal_uIntPtr nInsAnz=0;
Rectangle aLogicRect;
- if (pGraf!=NULL && pGraf->HasGDIMetaFile())
+ if(pGraf && (pGraf->HasGDIMetaFile() || pGraf->isEmbeddedSvg()))
{
- ImpSdrGDIMetaFileImport aFilter(*pMod);
+ GDIMetaFile aMetaFile;
- aLogicRect = pGraf->GetLogicRect();
- aFilter.SetScaleRect(aLogicRect);
- aFilter.SetLayer(pObj->GetLayer());
+ if(pGraf->HasGDIMetaFile())
+ {
+ aMetaFile = pGraf->GetTransformedGraphic(
+ SDRGRAFOBJ_TRANSFORMATTR_COLOR|SDRGRAFOBJ_TRANSFORMATTR_MIRROR).GetGDIMetaFile();
+ }
+ else if(pGraf->isEmbeddedSvg())
+ {
+ aMetaFile = pGraf->getMetafileFromEmbeddedSvg();
+ }
+
+ if(aMetaFile.GetActionCount())
+ {
+ ImpSdrGDIMetaFileImport aFilter(*pMod);
- nInsAnz=aFilter.DoImport(pGraf->GetTransformedGraphic(
- SDRGRAFOBJ_TRANSFORMATTR_COLOR|SDRGRAFOBJ_TRANSFORMATTR_MIRROR).GetGDIMetaFile(),
- *pOL,nInsPos,pProgrInfo);
+ aLogicRect = pGraf->GetLogicRect();
+ aFilter.SetScaleRect(aLogicRect);
+ aFilter.SetLayer(pObj->GetLayer());
+
+ nInsAnz = aFilter.DoImport(aMetaFile, *pOL, nInsPos, pProgrInfo);
+ }
}
if ( pOle2!=NULL && pOle2->GetGraphic() )
{
diff --git a/svx/source/svdraw/svdfmtf.cxx b/svx/source/svdraw/svdfmtf.cxx
index de8d53e31c20..5519973e0c88 100644
--- a/svx/source/svdraw/svdfmtf.cxx
+++ b/svx/source/svdraw/svdfmtf.cxx
@@ -191,7 +191,6 @@ sal_uIntPtr ImpSdrGDIMetaFileImport::DoImport(const GDIMetaFile& rMtf,
case META_POP_ACTION : DoAction((MetaPopAction &)*pAct); break;
case META_HATCH_ACTION : DoAction((MetaHatchAction &)*pAct); break;
case META_COMMENT_ACTION : DoAction((MetaCommentAction &)*pAct, pMtf); break;
- case META_RENDERGRAPHIC_ACTION : DoAction((MetaRenderGraphicAction &)*pAct); break;
}
if(pProgrInfo != NULL)
@@ -1025,24 +1024,4 @@ void ImpSdrGDIMetaFileImport::DoAction( MetaCommentAction& rAct, GDIMetaFile* pM
}
////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void ImpSdrGDIMetaFileImport::DoAction(MetaRenderGraphicAction& rAct)
-{
- GDIMetaFile aMtf;
- const ::vcl::RenderGraphic& rRenderGraphic = rAct.GetRenderGraphic();
- Rectangle aRect( rAct.GetPoint(), rAct.GetSize() );
- const Point aPos;
- const Size aPrefSize( rRenderGraphic.GetPrefSize() );
-
- aRect.Right()++; aRect.Bottom()++;
-
- aMtf.SetPrefMapMode( rRenderGraphic.GetPrefMapMode() );
- aMtf.SetPrefSize( aPrefSize );
- aMtf.AddAction( new MetaRenderGraphicAction( aPos, aPrefSize, rRenderGraphic ) );
- aMtf.WindStart();
-
- SdrGrafObj* pGraf=new SdrGrafObj( aMtf, aRect );
- InsertObj( pGraf );
-}
-
// eof
diff --git a/svx/source/svdraw/svdfmtf.hxx b/svx/source/svdraw/svdfmtf.hxx
index 23ac97524210..c311a8d5dc2f 100644
--- a/svx/source/svdraw/svdfmtf.hxx
+++ b/svx/source/svdraw/svdfmtf.hxx
@@ -136,7 +136,6 @@ protected:
void DoAction(MetaISectRectClipRegionAction& rAct) { rAct.Execute(&aVD); }
void DoAction(MetaISectRegionClipRegionAction& rAct) { rAct.Execute(&aVD); }
void DoAction(MetaCommentAction& rAct, GDIMetaFile* pMtf);
- void DoAction(MetaRenderGraphicAction& rAct);
void ImportText( const Point& rPos, const XubString& rStr, const MetaAction& rAct );
void SetAttributes(SdrObject* pObj, FASTBOOL bForceTextAttr=sal_False);
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx
index 0639220da7b1..15ea175155fa 100644
--- a/svx/source/svdraw/svdobj.cxx
+++ b/svx/source/svdraw/svdobj.cxx
@@ -1203,7 +1203,7 @@ basegfx::B2DPolyPolygon SdrObject::TakeContour() const
// create extractor, process and get result
drawinglayer::processor2d::ContourExtractor2D aExtractor(aViewInformation2D);
aExtractor.process(xSequence);
- const std::vector< basegfx::B2DPolyPolygon >& rResult(aExtractor.getExtractedContour());
+ const basegfx::B2DPolyPolygonVector& rResult(aExtractor.getExtractedContour());
const sal_uInt32 nSize(rResult.size());
// when count is one, it is implied that the object has only it's normal
@@ -2434,7 +2434,7 @@ SdrObject* SdrObject::ImpConvertToContourObj(SdrObject* pRet, sal_Bool bForceLin
aExtractor.process(xSequence);
// #i102241# check for line results
- const std::vector< basegfx::B2DPolygon >& rHairlineVector = aExtractor.getExtractedHairlines();
+ const basegfx::B2DPolygonVector& rHairlineVector = aExtractor.getExtractedHairlines();
if(!rHairlineVector.empty())
{
@@ -2446,7 +2446,7 @@ SdrObject* SdrObject::ImpConvertToContourObj(SdrObject* pRet, sal_Bool bForceLin
}
// #i102241# check for fill rsults
- const std::vector< basegfx::B2DPolyPolygon >& rLineFillVector(aExtractor.getExtractedLineFills());
+ const basegfx::B2DPolyPolygonVector& rLineFillVector(aExtractor.getExtractedLineFills());
if(!rLineFillVector.empty())
{
diff --git a/svx/source/svdraw/svdograf.cxx b/svx/source/svdraw/svdograf.cxx
index 5b710281f672..df03d56f06e9 100644
--- a/svx/source/svdraw/svdograf.cxx
+++ b/svx/source/svdraw/svdograf.cxx
@@ -321,6 +321,7 @@ SdrGrafObj::SdrGrafObj()
bMirrored ( sal_False )
{
pGraphic = new GraphicObject;
+ mpReplacementGraphic = 0;
pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
// #i118485# Shear allowed and possible now
@@ -346,6 +347,7 @@ SdrGrafObj::SdrGrafObj(const Graphic& rGrf, const Rectangle& rRect)
bMirrored ( sal_False )
{
pGraphic = new GraphicObject( rGrf );
+ mpReplacementGraphic = 0;
pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
// #i118485# Shear allowed and possible now
@@ -371,6 +373,7 @@ SdrGrafObj::SdrGrafObj( const Graphic& rGrf )
bMirrored ( sal_False )
{
pGraphic = new GraphicObject( rGrf );
+ mpReplacementGraphic = 0;
pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
// #i118485# Shear allowed and possible now
@@ -393,6 +396,7 @@ SdrGrafObj::SdrGrafObj( const Graphic& rGrf )
SdrGrafObj::~SdrGrafObj()
{
delete pGraphic;
+ delete mpReplacementGraphic;
ImpLinkAbmeldung();
}
@@ -401,6 +405,8 @@ SdrGrafObj::~SdrGrafObj()
void SdrGrafObj::SetGraphicObject( const GraphicObject& rGrfObj )
{
*pGraphic = rGrfObj;
+ delete mpReplacementGraphic;
+ mpReplacementGraphic = 0;
pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
pGraphic->SetUserData();
mbIsPreview = sal_False;
@@ -420,11 +426,28 @@ const GraphicObject& SdrGrafObj::GetGraphicObject(bool bForceSwapIn) const
return *pGraphic;
}
+const GraphicObject* SdrGrafObj::GetReplacementGraphicObject() const
+{
+ if(!mpReplacementGraphic && pGraphic)
+ {
+ const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
+
+ if(rSvgDataPtr.get())
+ {
+ const_cast< SdrGrafObj* >(this)->mpReplacementGraphic = new GraphicObject(rSvgDataPtr->getReplacement());
+ }
+ }
+
+ return mpReplacementGraphic;
+}
+
// -----------------------------------------------------------------------------
void SdrGrafObj::NbcSetGraphic( const Graphic& rGrf )
{
pGraphic->SetGraphic( rGrf );
+ delete mpReplacementGraphic;
+ mpReplacementGraphic = 0;
pGraphic->SetUserData();
mbIsPreview = sal_False;
}
@@ -503,16 +526,6 @@ sal_Bool SdrGrafObj::IsEPS() const
return pGraphic->IsEPS();
}
-sal_Bool SdrGrafObj::IsRenderGraphic() const
-{
- return pGraphic->IsRenderGraphic();
-}
-
-sal_Bool SdrGrafObj::HasRenderGraphic() const
-{
- return pGraphic->HasRenderGraphic();
-}
-
sal_Bool SdrGrafObj::IsSwappedOut() const
{
return mbIsPreview ? sal_True : pGraphic->IsSwappedOut();
@@ -667,7 +680,6 @@ void SdrGrafObj::ReleaseGraphicLink()
void SdrGrafObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
{
FASTBOOL bAnim = pGraphic->IsAnimated();
- FASTBOOL bRenderGraphic = pGraphic->HasRenderGraphic();
FASTBOOL bNoPresGrf = ( pGraphic->GetType() != GRAPHIC_NONE ) && !bEmptyPresObj;
rInfo.bResizeFreeAllowed = aGeo.nDrehWink % 9000 == 0 ||
@@ -675,11 +687,11 @@ void SdrGrafObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
aGeo.nDrehWink % 27000 == 0;
rInfo.bResizePropAllowed = sal_True;
- rInfo.bRotateFreeAllowed = bNoPresGrf && !bAnim && !bRenderGraphic;
- rInfo.bRotate90Allowed = bNoPresGrf && !bAnim && !bRenderGraphic;
- rInfo.bMirrorFreeAllowed = bNoPresGrf && !bAnim && !bRenderGraphic;
- rInfo.bMirror45Allowed = bNoPresGrf && !bAnim && !bRenderGraphic;
- rInfo.bMirror90Allowed = !bEmptyPresObj && !bRenderGraphic;
+ rInfo.bRotateFreeAllowed = bNoPresGrf && !bAnim;
+ rInfo.bRotate90Allowed = bNoPresGrf && !bAnim;
+ rInfo.bMirrorFreeAllowed = bNoPresGrf && !bAnim;
+ rInfo.bMirror45Allowed = bNoPresGrf && !bAnim;
+ rInfo.bMirror90Allowed = !bEmptyPresObj;
rInfo.bTransparenceAllowed = sal_False;
rInfo.bGradientAllowed = sal_False;
@@ -687,10 +699,10 @@ void SdrGrafObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
rInfo.bShearAllowed = true;
rInfo.bEdgeRadiusAllowed=sal_False;
- rInfo.bCanConvToPath = !IsEPS() && !bRenderGraphic;
+ rInfo.bCanConvToPath = !IsEPS();
rInfo.bCanConvToPathLineToArea = sal_False;
rInfo.bCanConvToPolyLineToArea = sal_False;
- rInfo.bCanConvToPoly = !IsEPS() && !bRenderGraphic;
+ rInfo.bCanConvToPoly = !IsEPS();
rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
}
@@ -735,38 +747,50 @@ void SdrGrafObj::ImpSetLinkedGraphic( const Graphic& rGraphic )
void SdrGrafObj::TakeObjNameSingul(XubString& rName) const
{
- switch( pGraphic->GetType() )
+ if(pGraphic)
{
- case GRAPHIC_BITMAP:
- {
- const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || ( (const SdrGrafTransparenceItem&) GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
- ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPTRANSLNK : STR_ObjNameSingulGRAFBMPTRANS ) :
- ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPLNK : STR_ObjNameSingulGRAFBMP ) );
+ const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
- rName=ImpGetResStr( nId );
+ if(rSvgDataPtr.get())
+ {
+ rName = ImpGetResStr(STR_ObjNameSingulGRAFSVG);
}
- break;
+ else
+ {
+ switch( pGraphic->GetType() )
+ {
+ case GRAPHIC_BITMAP:
+ {
+ const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || ( (const SdrGrafTransparenceItem&) GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
+ ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPTRANSLNK : STR_ObjNameSingulGRAFBMPTRANS ) :
+ ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPLNK : STR_ObjNameSingulGRAFBMP ) );
- case GRAPHIC_GDIMETAFILE:
- rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFMTFLNK : STR_ObjNameSingulGRAFMTF );
- break;
+ rName=ImpGetResStr( nId );
+ }
+ break;
- case GRAPHIC_NONE:
- rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFNONELNK : STR_ObjNameSingulGRAFNONE );
- break;
+ case GRAPHIC_GDIMETAFILE:
+ rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFMTFLNK : STR_ObjNameSingulGRAFMTF );
+ break;
- default:
- rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFLNK : STR_ObjNameSingulGRAF );
- break;
- }
+ case GRAPHIC_NONE:
+ rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFNONELNK : STR_ObjNameSingulGRAFNONE );
+ break;
- const String aName(GetName());
+ default:
+ rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFLNK : STR_ObjNameSingulGRAF );
+ break;
+ }
+ }
- if( aName.Len() )
- {
- rName.AppendAscii( " '" );
- rName += aName;
- rName += sal_Unicode( '\'' );
+ const String aName(GetName());
+
+ if( aName.Len() )
+ {
+ rName.AppendAscii( " '" );
+ rName += aName;
+ rName += sal_Unicode( '\'' );
+ }
}
}
@@ -774,38 +798,50 @@ void SdrGrafObj::TakeObjNameSingul(XubString& rName) const
void SdrGrafObj::TakeObjNamePlural( XubString& rName ) const
{
- switch( pGraphic->GetType() )
+ if(pGraphic)
{
- case GRAPHIC_BITMAP:
- {
- const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || ( (const SdrGrafTransparenceItem&) GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
- ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPTRANSLNK : STR_ObjNamePluralGRAFBMPTRANS ) :
- ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPLNK : STR_ObjNamePluralGRAFBMP ) );
+ const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
- rName=ImpGetResStr( nId );
+ if(rSvgDataPtr.get())
+ {
+ rName = ImpGetResStr(STR_ObjNamePluralGRAFSVG);
}
- break;
+ else
+ {
+ switch( pGraphic->GetType() )
+ {
+ case GRAPHIC_BITMAP:
+ {
+ const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || ( (const SdrGrafTransparenceItem&) GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
+ ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPTRANSLNK : STR_ObjNamePluralGRAFBMPTRANS ) :
+ ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPLNK : STR_ObjNamePluralGRAFBMP ) );
- case GRAPHIC_GDIMETAFILE:
- rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFMTFLNK : STR_ObjNamePluralGRAFMTF );
- break;
+ rName=ImpGetResStr( nId );
+ }
+ break;
- case GRAPHIC_NONE:
- rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFNONELNK : STR_ObjNamePluralGRAFNONE );
- break;
+ case GRAPHIC_GDIMETAFILE:
+ rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFMTFLNK : STR_ObjNamePluralGRAFMTF );
+ break;
- default:
- rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFLNK : STR_ObjNamePluralGRAF );
- break;
- }
+ case GRAPHIC_NONE:
+ rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFNONELNK : STR_ObjNamePluralGRAFNONE );
+ break;
+
+ default:
+ rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFLNK : STR_ObjNamePluralGRAF );
+ break;
+ }
+ }
- const String aName(GetName());
+ const String aName(GetName());
- if( aName.Len() )
- {
- rName.AppendAscii( " '" );
- rName += aName;
- rName += sal_Unicode( '\'' );
+ if( aName.Len() )
+ {
+ rName.AppendAscii( " '" );
+ rName += aName;
+ rName += sal_Unicode( '\'' );
+ }
}
}
@@ -1055,11 +1091,57 @@ const GDIMetaFile* SdrGrafObj::GetGDIMetaFile() const
// -----------------------------------------------------------------------------
+bool SdrGrafObj::isEmbeddedSvg() const
+{
+ return GRAPHIC_BITMAP == GetGraphicType() && GetGraphic().getSvgData().get();
+}
+
+GDIMetaFile SdrGrafObj::getMetafileFromEmbeddedSvg() const
+{
+ GDIMetaFile aRetval;
+
+ if(isEmbeddedSvg() && GetModel())
+ {
+ VirtualDevice aOut;
+ const Rectangle aBoundRect(GetCurrentBoundRect());
+ const MapMode aMap(GetModel()->GetScaleUnit(), Point(), GetModel()->GetScaleFraction(), GetModel()->GetScaleFraction());
+
+ aOut.EnableOutput(false);
+ aOut.SetMapMode(aMap);
+ aRetval.Record(&aOut);
+ SingleObjectPainter(aOut);
+ aRetval.Stop();
+ aRetval.WindStart();
+ aRetval.Move(-aBoundRect.Left(), -aBoundRect.Top());
+ aRetval.SetPrefMapMode(aMap);
+ aRetval.SetPrefSize(aBoundRect.GetSize());
+ }
+
+ return aRetval;
+}
+
SdrObject* SdrGrafObj::DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const
{
SdrObject* pRetval = NULL;
+ GraphicType aGraphicType(GetGraphicType());
+ GDIMetaFile aMtf;
+
+ if(isEmbeddedSvg())
+ {
+ // Embedded Svg
+ // There is currently no helper to create SdrObjects from primitives (even if I'm thinking
+ // about writing one for some time). To get the roundtrip to SdrObjects it is necessary to
+ // use the old converter path over the MetaFile mechanism. Create Metafile from Svg
+ // primitives here pretty directly
+ aMtf = getMetafileFromEmbeddedSvg();
+ aGraphicType = GRAPHIC_GDIMETAFILE;
+ }
+ else if(GRAPHIC_GDIMETAFILE == aGraphicType)
+ {
+ aMtf = GetTransformedGraphic(SDRGRAFOBJ_TRANSFORMATTR_COLOR|SDRGRAFOBJ_TRANSFORMATTR_MIRROR).GetGDIMetaFile();
+ }
- switch( GetGraphicType() )
+ switch(aGraphicType)
{
case GRAPHIC_GDIMETAFILE:
{
@@ -1069,14 +1151,12 @@ SdrObject* SdrGrafObj::DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const
aFilter.SetLayer(GetLayer());
SdrObjGroup* pGrp = new SdrObjGroup();
- sal_uInt32 nInsAnz = aFilter.DoImport(GetTransformedGraphic(
- SDRGRAFOBJ_TRANSFORMATTR_COLOR|SDRGRAFOBJ_TRANSFORMATTR_MIRROR).GetGDIMetaFile(),
- *pGrp->GetSubList(), 0);
+ sal_uInt32 nInsAnz = aFilter.DoImport(aMtf, *pGrp->GetSubList(), 0);
if(nInsAnz)
{
{
- // copy transformation
+ // copy transformation
GeoStat aGeoStat(GetGeoStat());
if(aGeoStat.nShearWink)
@@ -1343,9 +1423,6 @@ IMPL_LINK( SdrGrafObj, ImpSwapHdl, GraphicObject*, pO )
if(mbInsidePaint && !GetViewContact().HasViewObjectContacts(true))
{
-// Rectangle aSnapRect(GetSnapRect());
-// const Rectangle aSnapRectPixel(pOutDev->LogicToPixel(aSnapRect));
-
pFilterData = new com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >( 3 );
com::sun::star::awt::Size aPreviewSizeHint( 64, 64 );
@@ -1361,8 +1438,9 @@ IMPL_LINK( SdrGrafObj, ImpSwapHdl, GraphicObject*, pO )
mbIsPreview = sal_True;
}
- if( !GraphicFilter::GetGraphicFilter()->ImportGraphic( aGraphic, String(), *pStream,
- GRFILTER_FORMAT_DONTKNOW, NULL, 0, pFilterData ) )
+ if(!GraphicFilter::GetGraphicFilter()->ImportGraphic(
+ aGraphic, aStreamInfo.maUserData, *pStream,
+ GRFILTER_FORMAT_DONTKNOW, NULL, 0, pFilterData))
{
const String aUserData( pGraphic->GetUserData() );
diff --git a/svx/source/svdraw/svdorect.cxx b/svx/source/svdraw/svdorect.cxx
index a987ce22cf13..8d21289d593c 100644
--- a/svx/source/svdraw/svdorect.cxx
+++ b/svx/source/svdraw/svdorect.cxx
@@ -591,7 +591,10 @@ SdrObject* SdrRectObj::DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const
aPolyPolygon.removeDoublePoints();
SdrObject* pRet = 0L;
- if(!IsTextFrame() || HasFill() || HasLine())
+ // small correction: Do not create something when no fill and no line. To
+ // be sure to not damage something with non-text frames, do this only
+ // when used with bAddText==false from other converters
+ if((bAddText && !IsTextFrame()) || HasFill() || HasLine())
{
pRet = ImpConvertMakeObj(aPolyPolygon, sal_True, bBezier);
}
diff --git a/svx/source/svdraw/svdstr.src b/svx/source/svdraw/svdstr.src
index a39e8f7b686d..368fa4082520 100644
--- a/svx/source/svdraw/svdstr.src
+++ b/svx/source/svdraw/svdstr.src
@@ -474,7 +474,21 @@ String STR_ObjNamePluralGRAFMACLNK
{
Text [ en-US ] = "Linked Mac graphics" ;
};
- ////////////////////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Svg support
+
+String STR_ObjNameSingulGRAFSVG
+{
+ Text [ en-US ] = "SVG" ;
+};
+String STR_ObjNamePluralGRAFSVG
+{
+ Text [ en-US ] = "SVGs" ;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
String STR_ObjNameSingulOLE2
{
Text [ en-US ] = "embedded object (OLE)" ;
diff --git a/svx/source/svdraw/svdxcgv.cxx b/svx/source/svdraw/svdxcgv.cxx
index a43a9dc870e9..e9d4297d0104 100644
--- a/svx/source/svdraw/svdxcgv.cxx
+++ b/svx/source/svdraw/svdxcgv.cxx
@@ -529,19 +529,33 @@ void SdrExchangeView::ImpPasteObject(SdrObject* pObj, SdrObjList& rLst, const Po
////////////////////////////////////////////////////////////////////////////////////////////////////
-Bitmap SdrExchangeView::GetMarkedObjBitmap( sal_Bool bNoVDevIfOneBmpMarked ) const
+BitmapEx SdrExchangeView::GetMarkedObjBitmap( bool bNoVDevIfOneBmpMarked ) const
{
- Bitmap aBmp;
+ BitmapEx aBmp;
if( AreObjectsMarked() )
{
- if( bNoVDevIfOneBmpMarked )
+ if(1 == GetMarkedObjectCount())
{
- SdrObject* pGrafObjTmp = GetMarkedObjectByIndex( 0 );
- SdrGrafObj* pGrafObj = ( GetMarkedObjectCount() == 1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL;
+ if(bNoVDevIfOneBmpMarked)
+ {
+ SdrObject* pGrafObjTmp = GetMarkedObjectByIndex( 0 );
+ SdrGrafObj* pGrafObj = ( GetMarkedObjectCount() == 1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL;
+
+ if( pGrafObj && ( pGrafObj->GetGraphicType() == GRAPHIC_BITMAP ) )
+ {
+ aBmp = pGrafObj->GetTransformedGraphic().GetBitmapEx();
+ }
+ }
+ else
+ {
+ const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(GetMarkedObjectByIndex(0));
- if( pGrafObj && ( pGrafObj->GetGraphicType() == GRAPHIC_BITMAP ) )
- aBmp = pGrafObj->GetTransformedGraphic().GetBitmap();
+ if(pSdrGrafObj && pSdrGrafObj->isEmbeddedSvg())
+ {
+ aBmp = pSdrGrafObj->GetGraphic().getSvgData()->getReplacement();
+ }
+ }
}
if( !aBmp )
@@ -557,7 +571,7 @@ Bitmap SdrExchangeView::GetMarkedObjBitmap( sal_Bool bNoVDevIfOneBmpMarked ) con
aDrawinglayerOpt.IsAntiAliasing(),
aDrawinglayerOpt.IsSnapHorVerLinesToDiscrete());
- aBmp = aGraphic.GetBitmap(aParameters);
+ aBmp = aGraphic.GetBitmapEx(aParameters);
}
}
@@ -665,10 +679,18 @@ Graphic SdrExchangeView::GetObjGraphic( const SdrModel* pModel, const SdrObject*
if(pSdrGrafObj)
{
- // #110981# Make behaviour coherent with metafile
- // recording below (which of course also takes
- // view-transformed objects)
- aRet = pSdrGrafObj->GetTransformedGraphic();
+ if(pSdrGrafObj->isEmbeddedSvg())
+ {
+ // get Metafile for Svg content
+ aRet = pSdrGrafObj->getMetafileFromEmbeddedSvg();
+ }
+ else
+ {
+ // #110981# Make behaviour coherent with metafile
+ // recording below (which of course also takes
+ // view-transformed objects)
+ aRet = pSdrGrafObj->GetTransformedGraphic();
+ }
}
else if(pSdrOle2Obj)
{
diff --git a/svx/source/tbxctrls/grafctrl.cxx b/svx/source/tbxctrls/grafctrl.cxx
index 5077d3e8f830..af026ef86bb6 100644
--- a/svx/source/tbxctrls/grafctrl.cxx
+++ b/svx/source/tbxctrls/grafctrl.cxx
@@ -1145,8 +1145,7 @@ void SvxGrafAttrHelper::GetGrafAttrState( SfxItemSet& rSet, SdrView& rView )
if( !pGrafObj ||
( pGrafObj->GetGraphicType() == GRAPHIC_NONE ) ||
- ( pGrafObj->GetGraphicType() == GRAPHIC_DEFAULT ) ||
- pGrafObj->HasRenderGraphic() )
+ ( pGrafObj->GetGraphicType() == GRAPHIC_DEFAULT ))
{
bEnableColors = bEnableTransparency = bEnableCrop = false;
break;
diff --git a/svx/source/unodraw/unoshap2.cxx b/svx/source/unodraw/unoshap2.cxx
index c6ab5315a32d..5e9794570475 100644
--- a/svx/source/unodraw/unoshap2.cxx
+++ b/svx/source/unodraw/unoshap2.cxx
@@ -1843,6 +1843,20 @@ bool SvxGraphicObject::getPropertyValueImpl( const ::rtl::OUString& rName, const
break;
}
+ case OWN_ATTR_REPLACEMENTGRAFURL:
+ {
+ const GraphicObject* pGrafObj = static_cast< SdrGrafObj* >(mpObj.get())->GetReplacementGraphicObject();
+
+ if(pGrafObj)
+ {
+ OUString aURL(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_GRAPHOBJ_URLPREFIX));
+ aURL += OUString::createFromAscii(pGrafObj->GetUniqueID().GetBuffer());
+ rValue <<= aURL;
+ }
+
+ break;
+ }
+
case OWN_ATTR_GRAFSTREAMURL:
{
const OUString aStreamURL( ( (SdrGrafObj*) mpObj.get() )->GetGrafStreamURL() );
diff --git a/svx/source/xml/xmlgrhlp.cxx b/svx/source/xml/xmlgrhlp.cxx
index de941670b624..5ff20b338559 100644
--- a/svx/source/xml/xmlgrhlp.cxx
+++ b/svx/source/xml/xmlgrhlp.cxx
@@ -149,7 +149,7 @@ SvXMLGraphicInputStream::SvXMLGraphicInputStream( const ::rtl::OUString& rGraphi
{
pStm->SetVersion( SOFFICE_FILEFORMAT_8 );
pStm->SetCompressMode( COMPRESSMODE_ZBITMAP );
- ( (GDIMetaFile&) aGraphic.GetGDIMetaFile() ).Write( *pStm, GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC );
+ ( (GDIMetaFile&) aGraphic.GetGDIMetaFile() ).Write( *pStm );
bRet = ( pStm->GetError() == 0 );
}
}
@@ -645,7 +645,7 @@ sal_Bool SvXMLGraphicHelper::ImplWriteGraphic( const ::rtl::OUString& rPictureSt
pStream->Write( rLink.GetData(), rLink.GetDataSize() );
}
else
- rMtf.Write( *pStream, GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC );
+ rMtf.Write( *pStream );
bRet = ( pStream->GetError() == 0 );
}
diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h
index 9ec153757f35..f11f2116bc48 100644
--- a/sw/inc/cmdid.h
+++ b/sw/inc/cmdid.h
@@ -910,6 +910,8 @@ Achtung: Ab sofort sind in diesem File keine C++-Kommentare (//) mehr
#define FN_EMBEDDED_OBJECT (FN_EXTRA2 + 116)
+#define FN_UNO_REPLACEMENT_GRAPHIC_U_R_L (FN_EXTRA2 + 117)
+
/*--------------------------------------------------------------------
Bereich: Hilfe
--------------------------------------------------------------------*/
diff --git a/sw/inc/ndgrf.hxx b/sw/inc/ndgrf.hxx
index 0211ea79848a..e6a0cd5d544f 100644
--- a/sw/inc/ndgrf.hxx
+++ b/sw/inc/ndgrf.hxx
@@ -46,6 +46,7 @@ class SW_DLLPUBLIC SwGrfNode: public SwNoTxtNode
friend class SwNodes;
GraphicObject aGrfObj;
+ GraphicObject* mpReplacementGraphic;
::sfx2::SvBaseLinkRef refLink; // falls Grafik nur als Link, dann Pointer gesetzt
Size nGrfSize;
// String aStrmName; // SW3: Name des Storage-Streams fuer Embedded
@@ -146,6 +147,7 @@ public:
const Graphic& GetGrf() const { return aGrfObj.GetGraphic(); }
const GraphicObject& GetGrfObj() const { return aGrfObj; }
GraphicObject& GetGrfObj() { return aGrfObj; }
+ const GraphicObject* GetReplacementGrfObj() const;
virtual SwCntntNode *SplitCntntNode( const SwPosition & );
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index 802635083104..12a2eb930bb1 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -803,7 +803,10 @@ enum SwPropNameIds
/* 0738 */ UNO_NAME_META, // #i91565#
/* 0739 */ UNO_NAME_NESTED_TEXT_CONTENT, // #i109601#
/* 0740 */ UNO_NAME_EMBEDDED_OBJECT,
-/* 0741 */ SW_PROPNAME_END
+
+/* 0741 */ UNO_NAME_REPLACEMENT_GRAPHIC_URL,
+
+/* 0742 */ SW_PROPNAME_END
};
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index 7a9d733f9592..01bdd1a04cfa 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -78,6 +78,11 @@
#include <dview.hxx>
// <--
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <svx/sdr/contact/objectcontacttools.hxx>
+#include <drawinglayer/processor2d/baseprocessor2d.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+
using namespace com::sun::star;
#define DEFTEXTSIZE 12
@@ -941,9 +946,101 @@ void SwNoTxtFrm::PaintPicture( OutputDevice* pOut, const SwRect &rGrfArea ) cons
0, GRFMGR_DRAW_STANDARD, pVout );
}
else
- rGrfObj.DrawWithPDFHandling( *pOut,
- aAlignedGrfArea.Pos(), aAlignedGrfArea.SSize(),
- &aGrfAttr );
+ {
+ const SvgDataPtr& rSvgDataPtr = rGrfObj.GetGraphic().getSvgData();
+ bool bDone(false);
+
+ if(rSvgDataPtr.get())
+ {
+ // Graphic is Svg and can be painted as primitives (vector graphic)
+ const basegfx::B2DRange& rRange = rSvgDataPtr->getRange();
+ const double fWidth(rRange.getWidth());
+ const double fHeight(rRange.getHeight());
+ const drawinglayer::primitive2d::Primitive2DSequence& rSequence = rSvgDataPtr->getPrimitive2DSequence();
+
+ if(rSequence.hasElements() && !basegfx::fTools::equalZero(fWidth) && !basegfx::fTools::equalZero(fHeight))
+ {
+ // get target range
+ const basegfx::B2DRange aTargetRange(
+ aAlignedGrfArea.Left(), aAlignedGrfArea.Top(),
+ aAlignedGrfArea.Right(), aAlignedGrfArea.Bottom());
+
+ // prepare evtl. cropped range
+ basegfx::B2DRange aCroppedTargetRange(aTargetRange);
+
+ if(aGrfAttr.IsCropped())
+ {
+ // calculate original TargetRange
+ const double fFactor100thmmToTwips(72.0 / 127.0);
+
+ aCroppedTargetRange = basegfx::B2DRange(
+ aTargetRange.getMinX() - (aGrfAttr.GetLeftCrop() * fFactor100thmmToTwips),
+ aTargetRange.getMinY() - (aGrfAttr.GetTopCrop() * fFactor100thmmToTwips),
+ aTargetRange.getMaxX() + (aGrfAttr.GetRightCrop() * fFactor100thmmToTwips),
+ aTargetRange.getMaxY() + (aGrfAttr.GetBottomCrop() * fFactor100thmmToTwips));
+ }
+
+ const double fTargetWidth(aCroppedTargetRange.getWidth());
+ const double fTargetHeight(aCroppedTargetRange.getHeight());
+
+ if(!basegfx::fTools::equalZero(fTargetWidth) && !basegfx::fTools::equalZero(fTargetHeight))
+ {
+ // map graphic range to target range. This will automatically include
+ // tme mapping from Svg 1/100th mm content to twips since the target
+ // range is twips already
+ basegfx::B2DHomMatrix aMappingTransform(
+ basegfx::tools::createTranslateB2DHomMatrix(
+ -rRange.getMinX(),
+ -rRange.getMinY()));
+
+ aMappingTransform.scale(fTargetWidth / fWidth, fTargetHeight / fHeight);
+ aMappingTransform.translate(aCroppedTargetRange.getMinX(), aCroppedTargetRange.getMinY());
+
+ // check for and apply mirrorings
+ const bool bMirrorHor(aGrfAttr.GetMirrorFlags() & BMP_MIRROR_HORZ);
+ const bool bMirrorVer(aGrfAttr.GetMirrorFlags() & BMP_MIRROR_VERT);
+
+ if(bMirrorHor || bMirrorVer)
+ {
+ aMappingTransform.translate(-aCroppedTargetRange.getCenterX(), -aCroppedTargetRange.getCenterY());
+ aMappingTransform.scale(bMirrorHor ? -1.0 : 1.0, bMirrorVer ? -1.0 : 1.0);
+ aMappingTransform.translate(aCroppedTargetRange.getCenterX(), aCroppedTargetRange.getCenterY());
+ }
+
+ // Fill ViewInformation. Use MappingTransform here, so there is no need to
+ // embed the primitives to it. Use original TargetRange here so there is also
+ // no need to embed the primitives to a MaskPrimitive for cropping. This works
+ // only in this case where the graphic object cannot be rotated, though.
+ const drawinglayer::geometry::ViewInformation2D aViewInformation2D(
+ aMappingTransform,
+ pOut->GetViewTransformation(),
+ aTargetRange,
+ 0,
+ 0.0,
+ com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >());
+
+ // get a primitive processor for rendering
+ drawinglayer::processor2d::BaseProcessor2D* pProcessor2D = sdr::contact::createBaseProcessor2DFromOutputDevice(
+ *pOut,
+ aViewInformation2D);
+
+ if(pProcessor2D)
+ {
+ // render and cleanup
+ pProcessor2D->process(rSequence);
+ delete pProcessor2D;
+ bDone = true;
+ }
+ }
+ }
+ }
+
+ if(!bDone)
+ {
+ // fallback paint, uses replacement image
+ rGrfObj.DrawWithPDFHandling(*pOut, aAlignedGrfArea.Pos(), aAlignedGrfArea.SSize(), &aGrfAttr);
+ }
+ }
}
else
{
diff --git a/sw/source/core/graphic/ndgrf.cxx b/sw/source/core/graphic/ndgrf.cxx
index c6d792690413..cd68a0df3e3e 100755
--- a/sw/source/core/graphic/ndgrf.cxx
+++ b/sw/source/core/graphic/ndgrf.cxx
@@ -73,6 +73,8 @@ SwGrfNode::SwGrfNode(
SwGrfFmtColl *pGrfColl,
SwAttrSet* pAutoAttr ) :
SwNoTxtNode( rWhere, ND_GRFNODE, pGrfColl, pAutoAttr ),
+ aGrfObj(),
+ mpReplacementGraphic(0),
// --> OD 2007-01-23 #i73788#
mbLinkedInputStreamReady( false ),
mbIsStreamReadOnly( sal_False )
@@ -90,6 +92,8 @@ SwGrfNode::SwGrfNode( const SwNodeIndex & rWhere,
const GraphicObject& rGrfObj,
SwGrfFmtColl *pGrfColl, SwAttrSet* pAutoAttr ) :
SwNoTxtNode( rWhere, ND_GRFNODE, pGrfColl, pAutoAttr ),
+ aGrfObj(rGrfObj),
+ mpReplacementGraphic(0),
// --> OD 2007-01-23 #i73788#
mbLinkedInputStreamReady( false ),
mbIsStreamReadOnly( sal_False )
@@ -113,6 +117,8 @@ SwGrfNode::SwGrfNode( const SwNodeIndex & rWhere,
SwGrfFmtColl *pGrfColl,
SwAttrSet* pAutoAttr ) :
SwNoTxtNode( rWhere, ND_GRFNODE, pGrfColl, pAutoAttr ),
+ aGrfObj(),
+ mpReplacementGraphic(0),
// --> OD 2007-01-23 #i73788#
mbLinkedInputStreamReady( false ),
mbIsStreamReadOnly( sal_False )
@@ -146,6 +152,8 @@ sal_Bool SwGrfNode::ReRead(
sal_Bool bNewGrf )
{
sal_Bool bReadGrf = sal_False, bSetTwipSize = sal_True;
+ delete mpReplacementGraphic;
+ mpReplacementGraphic = 0;
ASSERT( pGraphic || pGrfObj || rGrfName.Len(),
"GraphicNode without a name, Graphic or GraphicObject" );
@@ -315,6 +323,9 @@ sal_Bool SwGrfNode::ReRead(
SwGrfNode::~SwGrfNode()
{
+ delete mpReplacementGraphic;
+ mpReplacementGraphic = 0;
+
// --> OD 2007-03-30 #i73788#
mpThreadConsumer.reset();
// <--
@@ -348,6 +359,21 @@ SwGrfNode::~SwGrfNode()
}
+const GraphicObject* SwGrfNode::GetReplacementGrfObj() const
+{
+ if(!mpReplacementGraphic)
+ {
+ const SvgDataPtr& rSvgDataPtr = GetGrfObj().GetGraphic().getSvgData();
+
+ if(rSvgDataPtr.get())
+ {
+ const_cast< SwGrfNode* >(this)->mpReplacementGraphic = new GraphicObject(rSvgDataPtr->getReplacement());
+ }
+ }
+
+ return mpReplacementGraphic;
+}
+
SwCntntNode *SwGrfNode::SplitCntntNode( const SwPosition & )
{
return this;
@@ -394,12 +420,15 @@ Size SwGrfNode::GetTwipSize() const
sal_Bool SwGrfNode::ImportGraphic( SvStream& rStrm )
{
Graphic aGraphic;
- if( !GraphicFilter::GetGraphicFilter()->ImportGraphic( aGraphic, String(), rStrm ) )
+ const String aURL(aGrfObj.GetUserData());
+
+ if(!GraphicFilter::GetGraphicFilter()->ImportGraphic(aGraphic, aURL, rStrm))
{
- const String aUserData( aGrfObj.GetUserData() );
+ delete mpReplacementGraphic;
+ mpReplacementGraphic = 0;
aGrfObj.SetGraphic( aGraphic );
- aGrfObj.SetUserData( aUserData );
+ aGrfObj.SetUserData( aURL );
return sal_True;
}
@@ -432,6 +461,9 @@ short SwGrfNode::SwapIn( sal_Bool bWaitForData )
else if( GRAPHIC_DEFAULT == aGrfObj.GetType() )
{
// keine default Bitmap mehr, also neu Painten!
+ delete mpReplacementGraphic;
+ mpReplacementGraphic = 0;
+
aGrfObj.SetGraphic( Graphic() );
SwMsgPoolItem aMsgHint( RES_GRAPHIC_PIECE_ARRIVED );
ModifyNotification( &aMsgHint, &aMsgHint );
@@ -904,7 +936,8 @@ SwCntntNode* SwGrfNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
SvStream* pStrm = _GetStreamForEmbedGrf( refPics, aStrmName );
if ( pStrm )
{
- GraphicFilter::GetGraphicFilter()->ImportGraphic( aTmpGrf, String(), *pStrm );
+ const String aURL(aGrfObj.GetUserData());
+ GraphicFilter::GetGraphicFilter()->ImportGraphic(aTmpGrf, aURL, *pStrm);
delete pStrm;
}
// <--
diff --git a/sw/source/core/unocore/unoframe.cxx b/sw/source/core/unocore/unoframe.cxx
index 629e8454fff5..69320b30f7ee 100755
--- a/sw/source/core/unocore/unoframe.cxx
+++ b/sw/source/core/unocore/unoframe.cxx
@@ -1499,6 +1499,30 @@ uno::Any SwXFrame::getPropertyValue(const OUString& rPropertyName)
}
aAny <<= OUString(sGrfName);
}
+ else if( FN_UNO_REPLACEMENT_GRAPHIC_U_R_L == pEntry->nWID)
+ {
+ String sGrfName;
+ const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx();
+
+ if(pIdx)
+ {
+ SwNodeIndex aIdx(*pIdx, 1);
+ SwGrfNode* pGrfNode = aIdx.GetNode().GetGrfNode();
+ if(!pGrfNode)
+ throw uno::RuntimeException();
+
+ const GraphicObject* pGraphicObject = pGrfNode->GetReplacementGrfObj();
+
+ if(pGraphicObject)
+ {
+ String sPrefix( RTL_CONSTASCII_STRINGPARAM(sGraphicObjectProtocol) );
+ String sId( pGraphicObject->GetUniqueID(), RTL_TEXTENCODING_ASCII_US );
+ (sGrfName = sPrefix) += sId;
+ }
+ }
+
+ aAny <<= OUString(sGrfName);
+ }
else if( FN_UNO_GRAPHIC_FILTER == pEntry->nWID )
{
String sFltName;
diff --git a/sw/source/core/unocore/unomap.cxx b/sw/source/core/unocore/unomap.cxx
index ca5def979e25..81ac8375c19a 100644
--- a/sw/source/core/unocore/unomap.cxx
+++ b/sw/source/core/unocore/unomap.cxx
@@ -1108,6 +1108,7 @@ const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetPropertyMapEntries(s
{ SW_PROP_NMID(UNO_NAME_HORI_MIRRORED_ON_ODD_PAGES), RES_GRFATR_MIRRORGRF, CPPU_E2T(CPPUTYPE_BOOLEAN), PROPERTY_NONE, MID_MIRROR_HORZ_ODD_PAGES },
{ SW_PROP_NMID(UNO_NAME_VERT_MIRRORED), RES_GRFATR_MIRRORGRF, CPPU_E2T(CPPUTYPE_BOOLEAN), PROPERTY_NONE, MID_MIRROR_VERT },
{ SW_PROP_NMID(UNO_NAME_GRAPHIC_URL), FN_UNO_GRAPHIC_U_R_L, CPPU_E2T(CPPUTYPE_OUSTRING), 0, 0 },
+ { SW_PROP_NMID(UNO_NAME_REPLACEMENT_GRAPHIC_URL), FN_UNO_REPLACEMENT_GRAPHIC_U_R_L, CPPU_E2T(CPPUTYPE_OUSTRING), 0, 0 },
{ SW_PROP_NMID(UNO_NAME_GRAPHIC_FILTER), FN_UNO_GRAPHIC_FILTER, CPPU_E2T(CPPUTYPE_OUSTRING), 0, 0 },
{ SW_PROP_NMID(UNO_NAME_GRAPHIC), FN_UNO_GRAPHIC, CPPU_E2T(CPPUTYPE_REFXGRAPHIC), 0, 0 },
{ SW_PROP_NMID(UNO_NAME_ACTUAL_SIZE), FN_UNO_ACTUAL_SIZE, CPPU_E2T(CPPUTYPE_AWTSIZE), PropertyAttribute::READONLY, CONVERT_TWIPS},
diff --git a/sw/source/core/unocore/unoprnms.cxx b/sw/source/core/unocore/unoprnms.cxx
index 12330e831c3e..de157ad95dd0 100644
--- a/sw/source/core/unocore/unoprnms.cxx
+++ b/sw/source/core/unocore/unoprnms.cxx
@@ -776,6 +776,7 @@ const SwPropNameTab aPropNameTab = {
/* 0738 UNO_NAME_META */ {MAP_CHAR_LEN("InContentMetadata")},
/* 0739 UNO_NAME_NESTED_TEXT_CONTENT */ {MAP_CHAR_LEN("NestedTextContent")},
/* 0740 UNO_NAME_EMBEDDED_OBJECT */ {MAP_CHAR_LEN("EmbeddedObject")},
+/* 0741 UNO_NAME_REPLACEMENT_GRAPHIC_URL */ {MAP_CHAR_LEN("ReplacementGraphicURL")},
};
const SwPropNameLen& SwGetPropName( sal_uInt16 nId )
diff --git a/sw/source/ui/shells/grfsh.cxx b/sw/source/ui/shells/grfsh.cxx
index 23e4799c52e6..7c869c6f3024 100644
--- a/sw/source/ui/shells/grfsh.cxx
+++ b/sw/source/ui/shells/grfsh.cxx
@@ -515,13 +515,6 @@ void SwGrfShell::GetAttrState(SfxItemSet &rSet)
rSh.GetCurAttr( aCoreSet );
sal_Bool bParentCntProt = 0 != rSh.IsSelObjProtected( FLYPROTECT_CONTENT|FLYPROTECT_PARENT );
sal_Bool bIsGrfCntnt = CNT_GRF == GetShell().GetCntType();
-// const GraphicObject* pGrfObj = ( bIsGrfCntnt ? rSh.GetGraphicObj() : NULL );
-// sal_Bool bIsRenderGraphicGrfCntnt = ( pGrfObj && pGrfObj->IsRenderGraphic() );
-
- // --> OD 2006-11-03 #i59688#
-// sal_Bool bSwappedOut = rSh.IsGrfSwapOut( sal_True );
-// sal_Bool bBitmapType = !bSwappedOut && GRAPHIC_BITMAP == rSh.GetGraphicType();
- // <--
SetGetStateSet( &rSet );
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 02f3b1d3d6c7..8df615880ea8 100755
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -379,13 +379,11 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/gdi/print \
vcl/source/gdi/regband \
vcl/source/gdi/region \
- vcl/source/gdi/rendergraphic \
- vcl/source/gdi/rendergraphicrasterizer \
vcl/source/gdi/salgdilayout \
vcl/source/gdi/sallayout \
vcl/source/gdi/salmisc \
vcl/source/gdi/salnativewidgets-none \
- vcl/source/gdi/svgread \
+ vcl/source/gdi/svgdata \
vcl/source/gdi/textlayout \
vcl/source/gdi/virdev \
vcl/source/gdi/wall \
diff --git a/vcl/Package_inc.mk b/vcl/Package_inc.mk
index f45f2b9c3917..15c322381ddf 100644
--- a/vcl/Package_inc.mk
+++ b/vcl/Package_inc.mk
@@ -119,8 +119,6 @@ $(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/ptrstyle.hxx,vcl/ptrstyle.hxx)
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/quickselectionengine.hxx,vcl/quickselectionengine.hxx))
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/regband.hxx,vcl/regband.hxx))
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/region.hxx,vcl/region.hxx))
-$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/rendergraphicrasterizer.hxx,vcl/rendergraphicrasterizer.hxx))
-$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/rendergraphic.hxx,vcl/rendergraphic.hxx))
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/salbtype.hxx,vcl/salbtype.hxx))
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/salctype.hxx,vcl/salctype.hxx))
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/salgtype.hxx,vcl/salgtype.hxx))
@@ -141,7 +139,7 @@ $(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/stdtext.hxx,vcl/stdtext.hxx))
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/strhelper.hxx,vcl/strhelper.hxx))
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/svapp.hxx,vcl/svapp.hxx))
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/sv.h,vcl/sv.h))
-$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/svgread.hxx,vcl/svgread.hxx))
+$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/svgdata.hxx,vcl/svgdata.hxx))
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/symbol.hxx,vcl/symbol.hxx))
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/syschild.hxx,vcl/syschild.hxx))
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/sysdata.hxx,vcl/sysdata.hxx))
diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx
index e136fcc06ade..d432b347ce75 100644
--- a/vcl/inc/impgraph.hxx
+++ b/vcl/inc/impgraph.hxx
@@ -33,8 +33,8 @@
#include <vcl/bitmapex.hxx>
#include <vcl/animate.hxx>
#include <vcl/gdimtf.hxx>
-#include <vcl/rendergraphic.hxx>
#include <vcl/graph.h>
+#include <vcl/svgdata.hxx>
// ---------------
// - ImpSwapInfo -
@@ -70,11 +70,14 @@ private:
GfxLink* mpGfxLink;
GraphicType meType;
String maDocFileURLStr;
- sal_uLong mnDocFilePos;
- mutable sal_uLong mnSizeBytes;
- sal_uLong mnRefCount;
- sal_Bool mbSwapOut;
- sal_Bool mbSwapUnderway;
+ sal_uLong mnDocFilePos;
+ mutable sal_uLong mnSizeBytes;
+ sal_uLong mnRefCount;
+ sal_Bool mbSwapOut;
+ sal_Bool mbSwapUnderway;
+
+ // SvgData support
+ SvgDataPtr maSvgData;
private:
@@ -82,6 +85,7 @@ private:
ImpGraphic( const ImpGraphic& rImpGraphic );
ImpGraphic( const Bitmap& rBmp );
ImpGraphic( const BitmapEx& rBmpEx );
+ ImpGraphic(const SvgDataPtr& rSvgDataPtr);
ImpGraphic( const Animation& rAnimation );
ImpGraphic( const GDIMetaFile& rMtf );
virtual ~ImpGraphic();
@@ -101,14 +105,11 @@ private:
sal_Bool ImplIsAlpha() const;
sal_Bool ImplIsAnimated() const;
sal_Bool ImplIsEPS() const;
- sal_Bool ImplIsRenderGraphic() const;
- sal_Bool ImplHasRenderGraphic() const;
Bitmap ImplGetBitmap(const GraphicConversionParameters& rParameters) const;
BitmapEx ImplGetBitmapEx(const GraphicConversionParameters& rParameters) const;
Animation ImplGetAnimation() const;
const GDIMetaFile& ImplGetGDIMetaFile() const;
- ::vcl::RenderGraphic ImplGetRenderGraphic() const;
Size ImplGetPrefSize() const;
@@ -177,6 +178,9 @@ private:
friend SvStream& operator<<( SvStream& rOStm, const ImpGraphic& rImpGraphic );
friend SvStream& operator>>( SvStream& rIStm, ImpGraphic& rImpGraphic );
+
+ // SvgData support
+ const SvgDataPtr& getSvgData() const;
};
#endif // _SV_IMPGRAPH_HXX
diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx
index bb5c6e829a70..6e3719b60694 100755
--- a/vcl/inc/sallayout.hxx
+++ b/vcl/inc/sallayout.hxx
@@ -29,12 +29,8 @@
#define _SV_SALLAYOUT_HXX
#include <tools/gen.hxx>
-
#include <vector>
-namespace basegfx {
- class B2DPolyPolygon;
- typedef std::vector<B2DPolyPolygon> B2DPolyPolygonVector;
-}
+#include <basegfx/polygon/b2dpolypolygon.hxx>
#ifndef _TOOLS_LANG_HXX
typedef unsigned short LanguageType;
diff --git a/vcl/inc/vcl/gdimtf.hxx b/vcl/inc/vcl/gdimtf.hxx
index 9a0a16246130..790c410fe12b 100644
--- a/vcl/inc/vcl/gdimtf.hxx
+++ b/vcl/inc/vcl/gdimtf.hxx
@@ -64,15 +64,6 @@ class Gradient;
#define MTF_MIRROR_HORZ 0x00000001UL
#define MTF_MIRROR_VERT 0x00000002UL
-// -----------------------------
-// - Write flags for streaming -
-// -----------------------------
-
-#define GDIMETAFILE_WRITE_DEFAULT 0x00000000
-#define GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC 0x00000001
-
-typedef sal_uInt32 GDIMetaFileWriteFlags;
-
// ---------
// - Enums -
// ---------
@@ -242,7 +233,7 @@ public:
// Methoden zum Lesen und Schreiben des neuen Formats;
// die Read-Methode kann auch das alte Format lesen
SvStream& Read( SvStream& rIStm );
- SvStream& Write( SvStream& rOStm, GDIMetaFileWriteFlags = GDIMETAFILE_WRITE_DEFAULT );
+ SvStream& Write( SvStream& rOStm );
// Stream-Operatoren schreiben das alte Format (noch)
// und lesen sowohl das alte wie auch das neue Format
diff --git a/vcl/inc/vcl/graph.hxx b/vcl/inc/vcl/graph.hxx
index 4d70970008a7..cd30c305a7ae 100644
--- a/vcl/inc/vcl/graph.hxx
+++ b/vcl/inc/vcl/graph.hxx
@@ -31,10 +31,10 @@
#include <vcl/bitmapex.hxx>
#include <vcl/animate.hxx>
#include <vcl/gdimtf.hxx>
-#include <vcl/rendergraphic.hxx>
#include <vcl/graph.h>
#include <vcl/gfxlink.hxx>
#include <com/sun/star/uno/Reference.hxx>
+#include <vcl/svgdata.hxx>
namespace com { namespace sun { namespace star { namespace graphic { class XGraphic;} } } }
@@ -100,6 +100,7 @@ public:
Graphic( const Graphic& rGraphic );
Graphic( const Bitmap& rBmp );
Graphic( const BitmapEx& rBmpEx );
+ Graphic(const SvgDataPtr& rSvgDataPtr);
Graphic( const Animation& rAnimation );
Graphic( const GDIMetaFile& rMtf );
Graphic( const ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >& rxGraphic );
@@ -120,8 +121,6 @@ public:
sal_Bool IsAlpha() const;
sal_Bool IsAnimated() const;
sal_Bool IsEPS() const;
- sal_Bool IsRenderGraphic() const;
- sal_Bool HasRenderGraphic() const;
// #i102089# Access of Bitmap potentially will have to rasterconvert the Graphic
// if it is a MetaFile. To be able to control this conversion it is necessary to
@@ -133,7 +132,6 @@ public:
Animation GetAnimation() const;
const GDIMetaFile& GetGDIMetaFile() const;
- ::vcl::RenderGraphic GetRenderGraphic() const;
::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > GetXGraphic() const;
@@ -217,6 +215,9 @@ public:
virtual void Load( SvStream& );
virtual void Save( SvStream& );
virtual void Assign( const SvDataCopyStream& );
+
+ // SvgData support
+ const SvgDataPtr& getSvgData() const;
};
#endif // _SV_GRAPH_HXX
diff --git a/vcl/inc/vcl/metaact.hxx b/vcl/inc/vcl/metaact.hxx
index d50e097ca50e..af1a55a3f519 100644
--- a/vcl/inc/vcl/metaact.hxx
+++ b/vcl/inc/vcl/metaact.hxx
@@ -38,7 +38,6 @@
#include <vcl/gdimtf.hxx>
#include <vcl/gfxlink.hxx>
#include <vcl/lineinfo.hxx>
-#include <vcl/rendergraphic.hxx>
class SvStream;
@@ -99,7 +98,6 @@ class SvStream;
#define META_LAYOUTMODE_ACTION (149)
#define META_TEXTLANGUAGE_ACTION (150)
#define META_OVERLINECOLOR_ACTION (151)
-#define META_RENDERGRAPHIC_ACTION (152)
#define META_COMMENT_ACTION (512)
@@ -120,11 +118,9 @@ struct ImplMetaReadData
struct ImplMetaWriteData
{
rtl_TextEncoding meActualCharSet;
- GDIMetaFileWriteFlags mnWriteFlags;
ImplMetaWriteData() :
- meActualCharSet( RTL_TEXTENCODING_ASCII_US ),
- mnWriteFlags( GDIMETAFILE_WRITE_DEFAULT )
+ meActualCharSet( RTL_TEXTENCODING_ASCII_US )
{
}
};
@@ -1553,41 +1549,4 @@ public:
LanguageType GetTextLanguage() const { return meTextLanguage; }
};
-// ---------------------------
-// - MetaRenderGraphicAction -
-// ---------------------------
-
-class VCL_DLLPUBLIC MetaRenderGraphicAction : public MetaAction
-{
-private:
-
- ::vcl::RenderGraphic maRenderGraphic;
- Point maPoint;
- Size maSize;
- double mfRotateAngle;
- double mfShearAngleX;
- double mfShearAngleY;
-
- virtual sal_Bool Compare( const MetaAction& ) const;
-
-public:
- DECL_META_ACTION( RenderGraphic, META_RENDERGRAPHIC_ACTION )
-
- MetaRenderGraphicAction( const Point& rPoint, const Size& rSize,
- const vcl::RenderGraphic& rRenderData,
- double fRotateAngle = 0.0,
- double fShearAngleX = 0.0,
- double fShearAngleY = 0.0 );
-
- virtual void Move( long nHorzMove, long nVertMove );
- virtual void Scale( double fScaleX, double fScaleY );
-
- const ::vcl::RenderGraphic& GetRenderGraphic() const { return maRenderGraphic; }
- const Point& GetPoint() const { return maPoint; }
- const Size& GetSize() const { return maSize; }
- double GetRotateAngle() const { return mfRotateAngle; }
- double GetShearAngleX() const { return mfShearAngleX; }
- double GetShearAngleY() const { return mfShearAngleY; }
-};
-
#endif // _SV_METAACT_HXX
diff --git a/vcl/inc/vcl/outdev.hxx b/vcl/inc/vcl/outdev.hxx
index 08a07b1238f7..30d8c0f3eaa0 100644
--- a/vcl/inc/vcl/outdev.hxx
+++ b/vcl/inc/vcl/outdev.hxx
@@ -40,6 +40,7 @@
#include <basegfx/vector/b2enums.hxx>
#include <com/sun/star/uno/Reference.h>
#include <unotools/fontdefs.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <vector>
@@ -87,7 +88,6 @@ namespace basegfx {
class B2DHomMatrix;
class B2DPolygon;
class B2DPolyPolygon;
- typedef ::std::vector< B2DPolyPolygon > B2DPolyPolygonVector;
}
namespace com {
@@ -104,7 +104,6 @@ namespace vcl
class PDFWriterImpl;
class ExtOutDevData;
class ITextLayout;
- class RenderGraphic;
}
#define OUTDEV_BUFFER_SIZE 128
@@ -813,9 +812,6 @@ public:
bool DrawEPS( const Point& rPt, const Size& rSz,
const GfxLink& rGfxLink, GDIMetaFile* pSubst = NULL );
- void DrawRenderGraphic( const Point& rPt, const Size& rSz,
- const ::vcl::RenderGraphic& rRenderGraphic );
-
Color GetPixel( const Point& rPt ) const;
Color* GetPixel( const Polygon& rPts ) const;
diff --git a/vcl/inc/vcl/rendergraphic.hxx b/vcl/inc/vcl/rendergraphic.hxx
deleted file mode 100644
index 0a0f475decd6..000000000000
--- a/vcl/inc/vcl/rendergraphic.hxx
+++ /dev/null
@@ -1,124 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-#ifndef _SV_RENDERGRAPHIC_HXX
-#define _SV_RENDERGRAPHIC_HXX
-
-#include <vcl/dllapi.h>
-#include <rtl/ustring.hxx>
-#include <boost/shared_array.hpp>
-#include <memory>
-
-class SvStream;
-class MapMode;
-class Size;
-class BitmapEx;
-
-namespace vcl
-{
- // -----------------
- // - RenderGraphic -
- // -----------------
- class VCL_DLLPUBLIC RenderGraphic
- {
- public:
-
- typedef boost::shared_array< sal_uInt8 > GraphicData;
-
- friend VCL_DLLPUBLIC ::SvStream& operator>>( ::SvStream& rIStm, RenderGraphic& rRenderGraphic );
- friend VCL_DLLPUBLIC ::SvStream& operator<<( ::SvStream& rOStm, const RenderGraphic& rRenderGraphic );
-
- public:
-
- RenderGraphic( );
-
- RenderGraphic( const RenderGraphic& rRenderGraphic );
-
- RenderGraphic( const GraphicData& rGraphicData,
- sal_uInt32 nGraphicDataLength,
- const rtl::OUString& rGraphicDataMimeType );
-
- RenderGraphic( const rtl::OUString& rGraphicDataMimeType,
- sal_uInt32 nGraphicDataLength,
- const sal_uInt8* pGraphicData = NULL );
-
- virtual ~RenderGraphic();
-
- RenderGraphic& operator=(const RenderGraphic& rRenderGraphic );
-
- bool operator==(const RenderGraphic& rRenderGraphic ) const;
-
- inline bool operator!=(const RenderGraphic& rRenderGraphic ) const
- {
- return( !( rRenderGraphic == *this ) );
- }
-
- bool IsEqual( const RenderGraphic& rRenderGraphic ) const;
-
- bool operator!() const;
-
- inline bool IsEmpty( ) const
- {
- return( !( *this ) );
- }
-
- inline const GraphicData& GetGraphicData( ) const
- {
- return( maGraphicData );
- }
-
- inline sal_uInt32 GetGraphicDataLength( ) const
- {
- return( mnGraphicDataLength );
- }
-
- inline const rtl::OUString& GetGraphicDataMimeType( ) const
- {
- return( maGraphicDataMimeType );
- }
-
- const MapMode& GetPrefMapMode() const;
- const Size& GetPrefSize() const;
-
- BitmapEx GetReplacement() const;
-
- private:
-
- void ImplCheckData();
- void ImplGetDefaults() const;
-
- private:
-
- GraphicData maGraphicData;
- sal_uInt32 mnGraphicDataLength;
- rtl::OUString maGraphicDataMimeType;
- mutable ::std::auto_ptr< MapMode > mapPrefMapMode;
- mutable ::std::auto_ptr< Size > mapPrefSize;
- };
-}
-
-#endif // _SV_RENDERHRAPHIC_HXX
diff --git a/vcl/inc/vcl/rendergraphicrasterizer.hxx b/vcl/inc/vcl/rendergraphicrasterizer.hxx
deleted file mode 100644
index f2166b03ffb3..000000000000
--- a/vcl/inc/vcl/rendergraphicrasterizer.hxx
+++ /dev/null
@@ -1,111 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-#ifndef _SV_RENDERGRAPHICRASTERIZER_HXX
-#define _SV_RENDERGRAPHICRASTERIZER_HXX
-
-#include <vcl/rendergraphic.hxx>
-#include <vcl/bitmapex.hxx>
-
-#include <com/sun/star/graphic/XGraphicRasterizer.hpp>
-
-#include <memory>
-#include <deque>
-
-#define VCL_RASTERIZER_UNLIMITED_EXTENT 0x00000000
-#define VCL_RASTERIZER_DEFAULT_EXTENT 0xffffffff
-
-namespace vcl
-{
- // ---------------------------
- // - RenderGraphicRasterizer -
- // ---------------------------
-
- class VCL_DLLPUBLIC RenderGraphicRasterizer
- {
- public:
-
- RenderGraphicRasterizer( const RenderGraphic& rData );
-
-
- RenderGraphicRasterizer( const RenderGraphicRasterizer& rRenderGraphicRasterizer );
-
- virtual ~RenderGraphicRasterizer();
-
- RenderGraphicRasterizer& operator=( const RenderGraphicRasterizer& rRenderGraphicRasterizer );
-
- inline const RenderGraphic& GetRenderGraphic() const
- {
- return( maRenderGraphic );
- }
-
- const Size& GetDefaultSizePixel() const;
-
- BitmapEx GetReplacement() const;
-
- virtual Size GetPrefSize() const;
-
- virtual MapMode GetPrefMapMode() const;
-
- virtual const BitmapEx& Rasterize( const Size& rSizePixel_UnrotatedUnsheared,
- double fRotateAngle = 0.0,
- double fShearAngleX = 0.0,
- double fShearAngleY = 0.0,
- sal_uInt32 nMaxExtent = VCL_RASTERIZER_DEFAULT_EXTENT ) const;
-
- protected:
-
- RenderGraphic maRenderGraphic;
- mutable com::sun::star::uno::Reference< com::sun::star::graphic::XGraphicRasterizer > mxRasterizer;
-
- virtual void InitializeRasterizer();
-
- private:
-
- RenderGraphicRasterizer();
-
- mutable BitmapEx maBitmapEx;
- mutable Size maDefaultSizePixel;
- mutable double mfRotateAngle;
- mutable double mfShearAngleX;
- mutable double mfShearAngleY;
-
- private:
-
- typedef ::std::deque< RenderGraphicRasterizer > RenderGraphicRasterizerCache;
-
- static RenderGraphicRasterizerCache& ImplGetCache();
-
- static bool ImplInitializeFromCache( RenderGraphicRasterizer& rRasterizer );
- static bool ImplRasterizeFromCache( RenderGraphicRasterizer& rRasterizer,
- const Size& rSizePixel, double fRotateAngle,
- double fShearAngleX, double fShearAngleY );
- static void ImplUpdateCache( const RenderGraphicRasterizer& rRasterizer );
-};
-}
-
-#endif // _SV_RENDERGRAPHICRASTERIZER_HXX
diff --git a/vcl/inc/vcl/svgdata.hxx b/vcl/inc/vcl/svgdata.hxx
new file mode 100644
index 000000000000..e7b208e8b739
--- /dev/null
+++ b/vcl/inc/vcl/svgdata.hxx
@@ -0,0 +1,82 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+#ifndef _SV_SVGDATA_HXX
+#define _SV_SVGDATA_HXX
+
+#include <basegfx/range/b2drange.hxx>
+#include <boost/shared_array.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include <com/sun/star/graphic/XPrimitive2D.hpp>
+#include <vcl/bitmapex.hxx>
+#include <rtl/ustring.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+typedef boost::shared_array< sal_uInt8 > SvgDataArray;
+typedef ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XPrimitive2D > Primitive2DReference;
+typedef ::com::sun::star::uno::Sequence< Primitive2DReference > Primitive2DSequence;
+
+//////////////////////////////////////////////////////////////////////////////
+
+class VCL_DLLPUBLIC SvgData : private boost::noncopyable
+{
+private:
+ // the file and length
+ SvgDataArray maSvgDataArray;
+ sal_uInt32 mnSvgDataArrayLength;
+
+ // The absolute Path if available
+ rtl::OUString maPath;
+
+ // on demand created content
+ basegfx::B2DRange maRange;
+ Primitive2DSequence maSequence;
+ BitmapEx maReplacement;
+
+ // on demand creators
+ void ensureReplacement();
+ void ensureSequenceAndRange();
+
+public:
+ SvgData(const SvgDataArray& rSvgDataArray, sal_uInt32 nSvgDataArrayLength, const rtl::OUString& rPath);
+
+ /// data read
+ const SvgDataArray& getSvgDataArray() const { return maSvgDataArray; }
+ sal_uInt32 getSvgDataArrayLength() const { return mnSvgDataArrayLength; }
+ const rtl::OUString& getPath() const { return maPath; }
+
+ /// data read and evtl. on demand creation
+ const basegfx::B2DRange& getRange() const;
+ const Primitive2DSequence& getPrimitive2DSequence() const;
+ const BitmapEx& getReplacement() const;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+typedef boost::shared_ptr< SvgData > SvgDataPtr;
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif // _SV_SVGDATA_HXX
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/vcl/inc/vcl/svgread.hxx b/vcl/inc/vcl/svgread.hxx
deleted file mode 100644
index ea4388767d02..000000000000
--- a/vcl/inc/vcl/svgread.hxx
+++ /dev/null
@@ -1,80 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-#ifndef _SV_SVGREAD_HXX
-#define _SV_SVGREAD_HXX
-
-#include <vcl/dllapi.h>
-#include <memory>
-
-// -------------
-// - SVGReader -
-// -------------
-
-class SvStream;
-class GDIMetaFile;
-
-namespace vcl
-{
- class SVGReaderImpl;
-
- class VCL_DLLPUBLIC SVGReader
- {
- public:
-
- SVGReader( SvStream& rStm );
- ~SVGReader();
-
- /* rSVGMtf is an output parameter, that is also returned
- by the method as well.
-
- In case of a failure, the GDIMetaFile will not contain
- any actions at all and thus GDIMetaFile::GetActionCount
- will return 0.
-
- In case of success, the GDIMetaFile will contain a
- META_RENDERGRAPHIC_ACTION, containing the SVG raw data. The
- data can be rendered by using the standard ways to output a
- GDIMetaFile, e.g. calling GDIMetaFile::Play
-
- */
- GDIMetaFile& Read( GDIMetaFile& rSVGMtf );
-
- private:
-
- SVGReader();
- SVGReader( const SVGReader& rReader );
-
- inline SVGReader& operator=( const SVGReader& /* rReader */ ) { return( *this ); }
-
- private:
-
- std::auto_ptr< SVGReaderImpl > mapImpl;
- };
-}
-
-#endif // _SV_SVGREAD_HXX
diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx
index c02adbee322c..54a4edfc3c9c 100644
--- a/vcl/source/gdi/gdimtf.cxx
+++ b/vcl/source/gdi/gdimtf.cxx
@@ -37,6 +37,7 @@
#include <vcl/virdev.hxx>
#include <vcl/gdimtf.hxx>
#include <vcl/graphictools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
// -----------
// - Defines -
@@ -1445,15 +1446,6 @@ void GDIMetaFile::Rotate( long nAngle10 )
}
break;
- case( META_RENDERGRAPHIC_ACTION ):
- {
- OSL_TRACE( "Rotate not supported for RenderGraphic MetaActions yet" );
-
- pAction->Duplicate();
- aMtf.AddAction( pAction );
- }
- break;
-
default:
{
pAction->Execute( &aMapVDev );
@@ -1876,14 +1868,6 @@ Rectangle GDIMetaFile::GetBoundRect( OutputDevice& i_rReference )
}
break;
- case( META_RENDERGRAPHIC_ACTION ):
- {
- MetaRenderGraphicAction* pAct = (MetaRenderGraphicAction*) pAction;
- Rectangle aRect( pAct->GetPoint(), pAct->GetSize() );
- ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
- }
- break;
-
default:
{
pAction->Execute( &aMapVDev );
@@ -2282,15 +2266,6 @@ void GDIMetaFile::ImplExchangeColors( ColorExchangeFnc pFncCol, const void* pCol
}
break;
- case( META_RENDERGRAPHIC_ACTION ):
- {
- OSL_TRACE( "ExchangeColors not supported for RenderGraphic MetaActions yet" );
-
- pAction->Duplicate();
- aMtf.Insert( pAction, LIST_APPEND );
- }
- break;
-
default:
{
pAction->Duplicate();
@@ -2739,27 +2714,70 @@ sal_uLong GDIMetaFile::GetChecksum() const
}
break;
- case( META_RENDERGRAPHIC_ACTION ):
+ case META_CLIPREGION_ACTION :
{
- MetaRenderGraphicAction* pAct = (MetaRenderGraphicAction*) pAction;
- const ::vcl::RenderGraphic& rRenderGraphic = pAct->GetRenderGraphic();
+ MetaClipRegionAction* pAct = dynamic_cast< MetaClipRegionAction* >(pAction);
+ const Region& rRegion = pAct->GetRegion();
- ShortToSVBT16( pAct->GetType(), aBT16 );
- nCrc = rtl_crc32( nCrc, aBT16, 2 );
+ if(rRegion.HasPolyPolygon())
+ {
+ // It has shown that this is a possible bottleneck for checksum calculation.
+ // In worst case a very expensive RegionHandle representation gets created.
+ // In this case it's cheaper to use the PolyPolygon
+ const basegfx::B2DPolyPolygon aPolyPolygon(rRegion.GetB2DPolyPolygon());
+ const sal_uInt32 nPolyCount(aPolyPolygon.count());
+ SVBT64 aSVBT64;
+
+ for(sal_uInt32 a(0); a < nPolyCount; a++)
+ {
+ const basegfx::B2DPolygon aPolygon(aPolyPolygon.getB2DPolygon(a));
+ const sal_uInt32 nPointCount(aPolygon.count());
+ const bool bControl(aPolygon.areControlPointsUsed());
- nCrc = rtl_crc32( nCrc, rRenderGraphic.GetGraphicData().get(), rRenderGraphic.GetGraphicDataLength() );
+ for(sal_uInt32 b(0); b < nPointCount; b++)
+ {
+ const basegfx::B2DPoint aPoint(aPolygon.getB2DPoint(b));
- UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 );
- nCrc = rtl_crc32( nCrc, aBT32, 4 );
+ DoubleToSVBT64(aPoint.getX(), aSVBT64);
+ nCrc = rtl_crc32(nCrc, aSVBT64, 8);
+ DoubleToSVBT64(aPoint.getY(), aSVBT64);
+ nCrc = rtl_crc32(nCrc, aSVBT64, 8);
- UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 );
- nCrc = rtl_crc32( nCrc, aBT32, 4 );
+ if(bControl)
+ {
+ if(aPolygon.isPrevControlPointUsed(b))
+ {
+ const basegfx::B2DPoint aCtrl(aPolygon.getPrevControlPoint(b));
- UInt32ToSVBT32( pAct->GetSize().Width(), aBT32 );
- nCrc = rtl_crc32( nCrc, aBT32, 4 );
+ DoubleToSVBT64(aCtrl.getX(), aSVBT64);
+ nCrc = rtl_crc32(nCrc, aSVBT64, 8);
+ DoubleToSVBT64(aCtrl.getY(), aSVBT64);
+ nCrc = rtl_crc32(nCrc, aSVBT64, 8);
+ }
- UInt32ToSVBT32( pAct->GetSize().Height(), aBT32 );
- nCrc = rtl_crc32( nCrc, aBT32, 4 );
+ if(aPolygon.isNextControlPointUsed(b))
+ {
+ const basegfx::B2DPoint aCtrl(aPolygon.getNextControlPoint(b));
+
+ DoubleToSVBT64(aCtrl.getX(), aSVBT64);
+ nCrc = rtl_crc32(nCrc, aSVBT64, 8);
+ DoubleToSVBT64(aCtrl.getY(), aSVBT64);
+ nCrc = rtl_crc32(nCrc, aSVBT64, 8);
+ }
+ }
+ }
+ }
+
+ SVBT8 aSVBT8;
+ ByteToSVBT8((sal_uInt8)pAct->IsClipping(), aSVBT8);
+ nCrc = rtl_crc32(nCrc, aSVBT8, 1);
+ }
+ else
+ {
+ pAction->Write( aMemStm, &aWriteData );
+ nCrc = rtl_crc32( nCrc, aMemStm.GetData(), aMemStm.Tell() );
+ aMemStm.Seek( 0 );
+ }
}
break;
@@ -2828,8 +2846,6 @@ sal_uLong GDIMetaFile::GetSizeBytes() const
nSizeBytes += ( pTextArrayAction->GetLen() << 2 );
}
break;
-
- case( META_RENDERGRAPHIC_ACTION ): nSizeBytes += ( ( (MetaRenderGraphicAction*) pAction )->GetRenderGraphic() ).GetGraphicDataLength(); break;
}
}
@@ -2857,63 +2873,27 @@ SvStream& operator>>( SvStream& rIStm, GDIMetaFile& rGDIMetaFile )
// new format
VersionCompat* pCompat;
MetaAction* pAction;
- sal_uInt32 nStmCompressMode = 0;
- sal_uInt32 nCount = 0;
- sal_uInt8 bRenderGraphicReplacements = 0;
+ sal_uInt32 nStmCompressMode = 0;
+ sal_uInt32 nCount = 0;
pCompat = new VersionCompat( rIStm, STREAM_READ );
- {
- // version 1
- rIStm >> nStmCompressMode;
- rIStm >> rGDIMetaFile.aPrefMapMode;
- rIStm >> rGDIMetaFile.aPrefSize;
- rIStm >> nCount;
- if( pCompat->GetVersion() >= 2 )
- {
- // version 2
- // =========
- // contains an additional flag to indicate that RenderGraphic
- // actions are immediately followed by a replacement image, that
- // needs to be skipped in case the flag is set (KA 01/2011)
+ rIStm >> nStmCompressMode;
+ rIStm >> rGDIMetaFile.aPrefMapMode;
+ rIStm >> rGDIMetaFile.aPrefSize;
+ rIStm >> nCount;
- rIStm >> bRenderGraphicReplacements;
- }
- }
delete pCompat;
ImplMetaReadData aReadData;
aReadData.meActualCharSet = rIStm.GetStreamCharSet();
- for( sal_uInt32 nAction = 0UL; ( nAction < nCount ) && !rIStm.IsEof(); ++nAction )
+ for( sal_uInt32 nAction = 0UL; ( nAction < nCount ) && !rIStm.IsEof(); nAction++ )
{
pAction = MetaAction::ReadMetaAction( rIStm, &aReadData );
if( pAction )
- {
rGDIMetaFile.AddAction( pAction );
-
- // if the MetaFile was written in RenderGraphics replacement mode
- // and we just read a RenderGraphic action, skip the following
- // META_BMPEXSCALE_ACTION, since this is the replacement image,
- // just needed for old implementations; don't forget to increment
- // the action read counter! (KA 01/2011)
- if( bRenderGraphicReplacements &&
- ( META_RENDERGRAPHIC_ACTION == pAction->GetType() ) &&
- ( ++nAction < nCount ) && !rIStm.IsEof() )
- {
- sal_uInt16 nFollowingType;
-
- // dummy read of the next following META_BMPEXSCALE_ACTION
- // RenderGraphic replacement action (KA 01/2011)
- rIStm >> nFollowingType;
- delete ( new VersionCompat( rIStm, STREAM_READ ) );
-
- OSL_ENSURE( META_BMPEXSCALE_ACTION == nFollowingType, \
-"META_RENDERGRAPHIC_ACTION read in RenderGraphic replacement mode \
-without following META_BMPEXSCALE_ACTION replacement" );
- }
- }
}
}
else
@@ -2980,90 +2960,32 @@ SvStream& GDIMetaFile::Read( SvStream& rIStm )
// ------------------------------------------------------------------------
-SvStream& GDIMetaFile::Write( SvStream& rOStm, GDIMetaFileWriteFlags nWriteFlags )
+SvStream& GDIMetaFile::Write( SvStream& rOStm )
{
VersionCompat* pCompat;
const sal_uInt32 nStmCompressMode = rOStm.GetCompressMode();
sal_uInt16 nOldFormat = rOStm.GetNumberFormatInt();
- const sal_uInt8 bRenderGraphicReplacements =
- ( ( ( GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC & nWriteFlags ) != 0 ) ? 1 : 0 );
-
- // With the introduction of the META_RENDERGRAPHIC_ACTION, it is neccessary
- // to provide some kind of document backward compatibility:
- //
- // If the flag GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC is set in
- // parameter nWriteFlags, each META_RENDERGRAPHIC_ACTION is followed by
- // an additional META_BMPEXSCALE_ACTION, that contains a replacement
- // image for the new RenderGraphic action.
- //
- // Old implementations, not knowing anything about META_RENDERGRAPHIC_ACTION,
- // will skip this new action and read the META_BMPEXSCALE_ACTION instead
- //
- // Since the current implementation is able to handle the new action, the
- // then following image replacement action needs to be skipped by this
- // implementation, if the metafile was written in the RenderGraphic
- // replacement mode.
- //
- // To be able to detect this compatibility mode, the header needs to
- // be extended by a corresponding flag, resulting in version 2 of
- // the header. The surrounding VersionCompat of the header
- // allows to add such new data without any problems (KA 01/2011)
rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
rOStm.Write( "VCLMTF", 6 );
- pCompat = new VersionCompat( rOStm, STREAM_WRITE, 2 );
-
- {
- // version 1
- sal_uInt32 nActionCount = 0;
-
- // calculate correct action count and watch for
- // additional RenderGraphic replacement actions, if the
- // GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC is set
- // and META_RENDERGRAPHIC_ACTION are encountered (KA 01/2011)
- for( MetaAction* pAct = static_cast< MetaAction* >( First() ); pAct; pAct = static_cast< MetaAction* >( Next() ) )
- {
- nActionCount += ( bRenderGraphicReplacements && ( META_RENDERGRAPHIC_ACTION == pAct->GetType() ) ? 2 : 1 );
- }
-
- rOStm << nStmCompressMode << aPrefMapMode << aPrefSize << nActionCount;
+ pCompat = new VersionCompat( rOStm, STREAM_WRITE, 1 );
- {
- // version 2
- // =========
- // since version 2, a GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC flag
- // is written, to indicate that each META_BMPEXSCALE_ACTION following
- // a META_RENDERGRAPHIC_ACTION needs to be skipped, in case the flag is
- // set (KA 01/2011)
- rOStm << bRenderGraphicReplacements;
- }
- }
+ rOStm << nStmCompressMode;
+ rOStm << aPrefMapMode;
+ rOStm << aPrefSize;
+ rOStm << (sal_uInt32) GetActionCount();
delete pCompat;
ImplMetaWriteData aWriteData;
-
aWriteData.meActualCharSet = rOStm.GetStreamCharSet();
- aWriteData.mnWriteFlags = nWriteFlags;
- for( MetaAction* pAct = static_cast< MetaAction* >( First() ); pAct; pAct = static_cast< MetaAction* >( Next() ) )
+ MetaAction* pAct = (MetaAction*)First();
+ while ( pAct )
{
pAct->Write( rOStm, &aWriteData );
-
- // write the RenderGraphic replacement image, if the
- // GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC flag is set
- // and if a META_RENDERGRAPHIC_ACTION is encountered (KA 01/2011)
- if( bRenderGraphicReplacements && ( META_RENDERGRAPHIC_ACTION == pAct->GetType() ) )
- {
- MetaRenderGraphicAction* pRenderAction = static_cast< MetaRenderGraphicAction* >( pAct );
- MetaBmpExScaleAction* pBmpExScaleAction = new MetaBmpExScaleAction(
- pRenderAction->GetPoint(), pRenderAction->GetSize(),
- pRenderAction->GetRenderGraphic().GetReplacement() );
-
- pBmpExScaleAction->Write( rOStm, &aWriteData );
- pBmpExScaleAction->Delete();
- }
+ pAct = (MetaAction*)Next();
}
rOStm.SetNumberFormatInt( nOldFormat );
diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx
index 9b4154740d0b..55477d3b4b89 100644
--- a/vcl/source/gdi/graph.cxx
+++ b/vcl/source/gdi/graph.cxx
@@ -27,11 +27,9 @@
#include <vcl/outdev.hxx>
#include <vcl/svapp.hxx>
#include <vcl/graph.hxx>
-
+#include <vcl/metaact.hxx>
#include <impgraph.hxx>
-
#include <comphelper/processfactory.hxx>
-
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/graphic/XGraphicProvider.hpp>
#include <com/sun/star/lang/XUnoTunnel.hpp>
@@ -244,6 +242,13 @@ Graphic::Graphic( const BitmapEx& rBmpEx )
// ------------------------------------------------------------------------
+Graphic::Graphic(const SvgDataPtr& rSvgDataPtr)
+{
+ mpImpGraphic = new ImpGraphic(rSvgDataPtr);
+}
+
+// ------------------------------------------------------------------------
+
Graphic::Graphic( const Animation& rAnimation )
{
mpImpGraphic = new ImpGraphic( rAnimation );
@@ -434,20 +439,6 @@ sal_Bool Graphic::IsEPS() const
// ------------------------------------------------------------------------
-sal_Bool Graphic::IsRenderGraphic() const
-{
- return mpImpGraphic->ImplIsRenderGraphic();
-}
-
-// ------------------------------------------------------------------------
-
-sal_Bool Graphic::HasRenderGraphic() const
-{
- return mpImpGraphic->ImplHasRenderGraphic();
-}
-
-// ------------------------------------------------------------------------
-
Bitmap Graphic::GetBitmap(const GraphicConversionParameters& rParameters) const
{
return mpImpGraphic->ImplGetBitmap(rParameters);
@@ -476,13 +467,6 @@ const GDIMetaFile& Graphic::GetGDIMetaFile() const
// ------------------------------------------------------------------------
-::vcl::RenderGraphic Graphic::GetRenderGraphic() const
-{
- return mpImpGraphic->ImplGetRenderGraphic();
-}
-
-// ------------------------------------------------------------------------
-
uno::Reference< graphic::XGraphic > Graphic::GetXGraphic() const
{
uno::Reference< graphic::XGraphic > xRet;
@@ -840,3 +824,8 @@ SvStream& operator<<( SvStream& rOStream, const Graphic& rGraphic )
{
return rOStream << *rGraphic.mpImpGraphic;
}
+
+const SvgDataPtr& Graphic::getSvgData() const
+{
+ return mpImpGraphic->getSvgData();
+}
diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx
index 5f4c310747fc..140f62c841c0 100644
--- a/vcl/source/gdi/impgraph.cxx
+++ b/vcl/source/gdi/impgraph.cxx
@@ -175,6 +175,8 @@ ImpGraphic::ImpGraphic( const ImpGraphic& rImpGraphic ) :
}
else
mpAnimation = NULL;
+
+ maSvgData = rImpGraphic.maSvgData;
}
// ------------------------------------------------------------------------
@@ -213,6 +215,23 @@ ImpGraphic::ImpGraphic( const BitmapEx& rBitmapEx ) :
// ------------------------------------------------------------------------
+ImpGraphic::ImpGraphic(const SvgDataPtr& rSvgDataPtr)
+: mpAnimation( NULL ),
+ mpContext( NULL ),
+ mpSwapFile( NULL ),
+ mpGfxLink( NULL ),
+ meType( rSvgDataPtr.get() ? GRAPHIC_BITMAP : GRAPHIC_NONE ),
+ mnDocFilePos( 0UL ),
+ mnSizeBytes( 0UL ),
+ mnRefCount( 1UL ),
+ mbSwapOut( sal_False ),
+ mbSwapUnderway( sal_False ),
+ maSvgData(rSvgDataPtr)
+{
+}
+
+// ------------------------------------------------------------------------
+
ImpGraphic::ImpGraphic( const Animation& rAnimation ) :
maEx ( rAnimation.GetBitmapEx() ),
mpAnimation ( new Animation( rAnimation ) ),
@@ -298,6 +317,8 @@ ImpGraphic& ImpGraphic::operator=( const ImpGraphic& rImpGraphic )
mpGfxLink = new GfxLink( *rImpGraphic.mpGfxLink );
else
mpGfxLink = NULL;
+
+ maSvgData = rImpGraphic.maSvgData;
}
return *this;
@@ -328,13 +349,35 @@ sal_Bool ImpGraphic::operator==( const ImpGraphic& rImpGraphic ) const
case( GRAPHIC_BITMAP ):
{
- if( mpAnimation )
+ if(maSvgData.get())
+ {
+ if(maSvgData == rImpGraphic.maSvgData)
+ {
+ bRet = sal_True;
+ }
+ else if(rImpGraphic.maSvgData)
+ {
+ if(maSvgData->getSvgDataArrayLength() == rImpGraphic.maSvgData->getSvgDataArrayLength())
+ {
+ if(0 == memcmp(
+ maSvgData->getSvgDataArray().get(),
+ rImpGraphic.maSvgData->getSvgDataArray().get(),
+ maSvgData->getSvgDataArrayLength()))
+ {
+ bRet = sal_True;
+ }
+ }
+ }
+ }
+ else if( mpAnimation )
{
if( rImpGraphic.mpAnimation && ( *rImpGraphic.mpAnimation == *mpAnimation ) )
bRet = sal_True;
}
else if( !rImpGraphic.mpAnimation && ( rImpGraphic.maEx == maEx ) )
+ {
bRet = sal_True;
+ }
}
break;
@@ -371,6 +414,8 @@ void ImpGraphic::ImplClearGraphics( sal_Bool bCreateSwapInfo )
delete mpGfxLink;
mpGfxLink = NULL;
}
+
+ maSvgData.reset();
}
// ------------------------------------------------------------------------
@@ -446,12 +491,12 @@ sal_Bool ImpGraphic::ImplIsSupportedGraphic() const
sal_Bool ImpGraphic::ImplIsTransparent() const
{
- sal_Bool bRet;
+ sal_Bool bRet(sal_True);
- if( meType == GRAPHIC_BITMAP )
+ if( meType == GRAPHIC_BITMAP && !maSvgData.get())
+ {
bRet = ( mpAnimation ? mpAnimation->IsTransparent() : maEx.IsTransparent() );
- else
- bRet = sal_True;
+ }
return bRet;
}
@@ -460,12 +505,16 @@ sal_Bool ImpGraphic::ImplIsTransparent() const
sal_Bool ImpGraphic::ImplIsAlpha() const
{
- sal_Bool bRet;
+ sal_Bool bRet(sal_False);
- if( meType == GRAPHIC_BITMAP )
+ if(maSvgData.get())
+ {
+ bRet = sal_True;
+ }
+ else if( meType == GRAPHIC_BITMAP )
+ {
bRet = ( NULL == mpAnimation ) && maEx.IsAlpha();
- else
- bRet = sal_False;
+ }
return bRet;
}
@@ -488,45 +537,18 @@ sal_Bool ImpGraphic::ImplIsEPS() const
// ------------------------------------------------------------------------
-sal_Bool ImpGraphic::ImplIsRenderGraphic() const
-{
- return( ( GRAPHIC_GDIMETAFILE == meType ) &&
- ( 1 == maMetaFile.GetActionCount() ) &&
- ( META_RENDERGRAPHIC_ACTION == maMetaFile.GetAction( 0 )->GetType() ) );
-}
-
-// ------------------------------------------------------------------------
-
-sal_Bool ImpGraphic::ImplHasRenderGraphic() const
-{
- sal_Bool bRet = sal_False;
-
- if( GRAPHIC_GDIMETAFILE == meType )
- {
- GDIMetaFile& rMtf = const_cast< ImpGraphic* >( this )->maMetaFile;
-
- for( MetaAction* pAct = rMtf.FirstAction(); pAct && !bRet; pAct = rMtf.NextAction() )
- {
- if( META_RENDERGRAPHIC_ACTION == pAct->GetType() )
- {
- bRet = sal_True;
- }
- }
-
- rMtf.WindStart();
- }
-
- return( bRet );
-}
-
-// ------------------------------------------------------------------------
-
Bitmap ImpGraphic::ImplGetBitmap(const GraphicConversionParameters& rParameters) const
{
Bitmap aRetBmp;
if( meType == GRAPHIC_BITMAP )
{
+ if(maSvgData.get() && maEx.IsEmpty())
+ {
+ // use maEx as local buffer for rendered svg
+ const_cast< ImpGraphic* >(this)->maEx = maSvgData->getReplacement();
+ }
+
const BitmapEx& rRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx );
const Color aReplaceColor( COL_WHITE );
@@ -605,6 +627,12 @@ BitmapEx ImpGraphic::ImplGetBitmapEx(const GraphicConversionParameters& rParamet
if( meType == GRAPHIC_BITMAP )
{
+ if(maSvgData.get() && maEx.IsEmpty())
+ {
+ // use maEx as local buffer for rendered svg
+ const_cast< ImpGraphic* >(this)->maEx = maSvgData->getReplacement();
+ }
+
aRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx );
if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height())
@@ -633,18 +661,6 @@ Animation ImpGraphic::ImplGetAnimation() const
// ------------------------------------------------------------------------
-::vcl::RenderGraphic ImpGraphic::ImplGetRenderGraphic() const
-{
- ::vcl::RenderGraphic aRet;
-
- if( ImplIsRenderGraphic() )
- aRet = static_cast< MetaRenderGraphicAction* >( maMetaFile.GetAction( 0 ) )->GetRenderGraphic();
-
- return( aRet );
-}
-
-// ------------------------------------------------------------------------
-
const GDIMetaFile& ImpGraphic::ImplGetGDIMetaFile() const
{
return maMetaFile;
@@ -668,10 +684,22 @@ Size ImpGraphic::ImplGetPrefSize() const
case( GRAPHIC_BITMAP ):
{
- aSize = maEx.GetPrefSize();
+ if(maSvgData.get() && maEx.IsEmpty())
+ {
+ // svg not yet buffered in maEx, return size derived from range
+ const basegfx::B2DRange& rRange = maSvgData->getRange();
- if( !aSize.Width() || !aSize.Height() )
- aSize = maEx.GetSizePixel();
+ aSize = Size(basegfx::fround(rRange.getWidth()), basegfx::fround(rRange.getHeight()));
+ }
+ else
+ {
+ aSize = maEx.GetPrefSize();
+
+ if( !aSize.Width() || !aSize.Height() )
+ {
+ aSize = maEx.GetSizePixel();
+ }
+ }
}
break;
@@ -698,12 +726,24 @@ void ImpGraphic::ImplSetPrefSize( const Size& rPrefSize )
break;
case( GRAPHIC_BITMAP ):
+ {
// #108077# Push through pref size to animation object,
// will be lost on copy otherwise
- if( ImplIsAnimated() )
- const_cast< BitmapEx& >(mpAnimation->GetBitmapEx()).SetPrefSize( rPrefSize );
+ if(maSvgData.get())
+ {
+ // ignore for Svg. If this is really used (except the grfcache)
+ // it can be extended by using maEx as buffer for maSvgData->getReplacement()
+ }
+ else
+ {
+ if( ImplIsAnimated() )
+ {
+ const_cast< BitmapEx& >(mpAnimation->GetBitmapEx()).SetPrefSize( rPrefSize );
+ }
- maEx.SetPrefSize( rPrefSize );
+ maEx.SetPrefSize( rPrefSize );
+ }
+ }
break;
default:
@@ -733,10 +773,18 @@ MapMode ImpGraphic::ImplGetPrefMapMode() const
case( GRAPHIC_BITMAP ):
{
- const Size aSize( maEx.GetPrefSize() );
+ if(maSvgData.get() && maEx.IsEmpty())
+ {
+ // svg not yet buffered in maEx, return default PrefMapMode
+ aMapMode = MapMode(MAP_100TH_MM);
+ }
+ else
+ {
+ const Size aSize( maEx.GetPrefSize() );
- if ( aSize.Width() && aSize.Height() )
- aMapMode = maEx.GetPrefMapMode();
+ if ( aSize.Width() && aSize.Height() )
+ aMapMode = maEx.GetPrefMapMode();
+ }
}
break;
@@ -763,12 +811,24 @@ void ImpGraphic::ImplSetPrefMapMode( const MapMode& rPrefMapMode )
break;
case( GRAPHIC_BITMAP ):
- // #108077# Push through pref mapmode to animation object,
- // will be lost on copy otherwise
- if( ImplIsAnimated() )
- const_cast< BitmapEx& >(mpAnimation->GetBitmapEx()).SetPrefMapMode( rPrefMapMode );
+ {
+ if(maSvgData.get())
+ {
+ // ignore for Svg. If this is really used (except the grfcache)
+ // it can be extended by using maEx as buffer for maSvgData->getReplacement()
+ }
+ else
+ {
+ // #108077# Push through pref mapmode to animation object,
+ // will be lost on copy otherwise
+ if( ImplIsAnimated() )
+ {
+ const_cast< BitmapEx& >(mpAnimation->GetBitmapEx()).SetPrefMapMode( rPrefMapMode );
+ }
- maEx.SetPrefMapMode( rPrefMapMode );
+ maEx.SetPrefMapMode( rPrefMapMode );
+ }
+ }
break;
default:
@@ -788,7 +848,14 @@ sal_uLong ImpGraphic::ImplGetSizeBytes() const
{
if( meType == GRAPHIC_BITMAP )
{
- mnSizeBytes = mpAnimation ? mpAnimation->GetSizeBytes() : maEx.GetSizeBytes();
+ if(maSvgData.get())
+ {
+ mnSizeBytes = maSvgData->getSvgDataArrayLength();
+ }
+ else
+ {
+ mnSizeBytes = mpAnimation ? mpAnimation->GetSizeBytes() : maEx.GetSizeBytes();
+ }
}
else if( meType == GRAPHIC_GDIMETAFILE )
{
@@ -812,10 +879,20 @@ void ImpGraphic::ImplDraw( OutputDevice* pOutDev, const Point& rDestPt ) const
case( GRAPHIC_BITMAP ):
{
+ if(maSvgData.get() && !maEx)
+ {
+ // use maEx as local buffer for rendered svg
+ const_cast< ImpGraphic* >(this)->maEx = maSvgData->getReplacement();
+ }
+
if ( mpAnimation )
+ {
mpAnimation->Draw( pOutDev, rDestPt );
+ }
else
+ {
maEx.Draw( pOutDev, rDestPt );
+ }
}
break;
@@ -840,10 +917,20 @@ void ImpGraphic::ImplDraw( OutputDevice* pOutDev,
case( GRAPHIC_BITMAP ):
{
+ if(maSvgData.get() && maEx.IsEmpty())
+ {
+ // use maEx as local buffer for rendered svg
+ const_cast< ImpGraphic* >(this)->maEx = maSvgData->getReplacement();
+ }
+
if( mpAnimation )
+ {
mpAnimation->Draw( pOutDev, rDestPt, rDestSize );
+ }
else
+ {
maEx.Draw( pOutDev, rDestPt, rDestSize );
+ }
}
break;
@@ -1052,6 +1139,12 @@ sal_Bool ImpGraphic::ImplReadEmbedded( SvStream& rIStm, sal_Bool bSwap )
{
if( meType == GRAPHIC_BITMAP )
{
+ if(maSvgData.get() && maEx.IsEmpty())
+ {
+ // use maEx as local buffer for rendered svg
+ maEx = maSvgData->getReplacement();
+ }
+
maEx.aBitmapSize = aSize;
if( aMapMode != MapMode() )
@@ -1510,10 +1603,20 @@ sal_uLong ImpGraphic::ImplGetChecksum() const
case( GRAPHIC_BITMAP ):
{
+ if(maSvgData.get() && maEx.IsEmpty())
+ {
+ // use maEx as local buffer for rendered svg
+ const_cast< ImpGraphic* >(this)->maEx = maSvgData->getReplacement();
+ }
+
if( mpAnimation )
+ {
nRet = mpAnimation->GetChecksum();
+ }
else
+ {
nRet = maEx.GetChecksum();
+ }
}
break;
@@ -1553,6 +1656,13 @@ sal_Bool ImpGraphic::ImplExportNative( SvStream& rOStm ) const
// ------------------------------------------------------------------------
+const SvgDataPtr& ImpGraphic::getSvgData() const
+{
+ return maSvgData;
+}
+
+// ------------------------------------------------------------------------
+
SvStream& operator>>( SvStream& rIStm, ImpGraphic& rImpGraphic )
{
if( !rIStm.GetError() )
@@ -1704,10 +1814,18 @@ SvStream& operator<<( SvStream& rOStm, const ImpGraphic& rImpGraphic )
case GRAPHIC_BITMAP:
{
- if ( rImpGraphic.ImplIsAnimated() )
+ if(rImpGraphic.getSvgData().get())
+ {
+ rOStm << rImpGraphic.getSvgData()->getReplacement();
+ }
+ else if( rImpGraphic.ImplIsAnimated())
+ {
rOStm << *rImpGraphic.mpAnimation;
+ }
else
+ {
rOStm << rImpGraphic.maEx;
+ }
}
break;
diff --git a/vcl/source/gdi/makefile.mk b/vcl/source/gdi/makefile.mk
index ec664cf648a6..f3f5ebd87680 100755
--- a/vcl/source/gdi/makefile.mk
+++ b/vcl/source/gdi/makefile.mk
@@ -76,9 +76,7 @@ EXCEPTIONSFILES= $(SLO)$/salmisc.obj \
$(SLO)$/graphictools.obj \
$(SLO)$/textlayout.obj \
$(SLO)$/lineinfo.obj \
- $(SLO)$/svgread.obj \
- $(SLO)$/rendergraphic.obj \
- $(SLO)$/rendergraphicrasterizer.obj
+ $(SLO)$/svgdata.obj
SLOFILES= $(EXCEPTIONSFILES) \
$(SLO)$/animate.obj \
diff --git a/vcl/source/gdi/metaact.cxx b/vcl/source/gdi/metaact.cxx
index f15527feaf2a..df8967fd683d 100644
--- a/vcl/source/gdi/metaact.cxx
+++ b/vcl/source/gdi/metaact.cxx
@@ -34,7 +34,8 @@
#include <vcl/salbtype.hxx>
#include <vcl/metaact.hxx>
#include <vcl/graphictools.hxx>
-#include <vcl/rendergraphicrasterizer.hxx>
+//#include <svgio/svgreader/svgreader.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
// ========================================================================
@@ -232,7 +233,6 @@ MetaAction* MetaAction::ReadMetaAction( SvStream& rIStm, ImplMetaReadData* pData
case( META_COMMENT_ACTION ): pAction = new MetaCommentAction; break;
case( META_LAYOUTMODE_ACTION ): pAction = new MetaLayoutModeAction; break;
case( META_TEXTLANGUAGE_ACTION ): pAction = new MetaTextLanguageAction; break;
- case( META_RENDERGRAPHIC_ACTION ): pAction = new MetaRenderGraphicAction; break;
default:
{
@@ -2025,7 +2025,7 @@ void MetaBmpExAction::Execute( OutputDevice* pOut )
MetaAction* MetaBmpExAction::Clone()
{
- MetaAction* pClone = (MetaAction*) new MetaBmpExAction( *this );
+ MetaBmpExAction* pClone = new MetaBmpExAction( *this );
pClone->ResetRefCount();
return pClone;
}
@@ -4297,82 +4297,4 @@ void MetaTextLanguageAction::Read( SvStream& rIStm, ImplMetaReadData* )
rIStm >> meTextLanguage;
}
-// ========================================================================
-
-IMPL_META_ACTION( RenderGraphic, META_RENDERGRAPHIC_ACTION )
-
-// ------------------------------------------------------------------------
-
-MetaRenderGraphicAction::MetaRenderGraphicAction( const Point& rPoint, const Size& rSize,
- const vcl::RenderGraphic& rRenderGraphic,
- double fRotateAngle, double fShearAngleX, double fShearAngleY ) :
- MetaAction( META_RENDERGRAPHIC_ACTION ),
- maRenderGraphic( rRenderGraphic ),
- maPoint( rPoint ),
- maSize( rSize ),
- mfRotateAngle( fRotateAngle ),
- mfShearAngleX( fShearAngleX ),
- mfShearAngleY( fShearAngleY )
-{
-}
-
-// ------------------------------------------------------------------------
-
-void MetaRenderGraphicAction::Execute( OutputDevice* pOut )
-{
- pOut->DrawRenderGraphic( maPoint, maSize, maRenderGraphic );
-}
-
-// ------------------------------------------------------------------------
-
-MetaAction* MetaRenderGraphicAction::Clone()
-{
- MetaAction* pClone = (MetaAction*) new MetaRenderGraphicAction( *this );
- pClone->ResetRefCount();
- return pClone;
-}
-
-// ------------------------------------------------------------------------
-
-void MetaRenderGraphicAction::Move( long nHorzMove, long nVertMove )
-{
- maPoint.Move( nHorzMove, nVertMove );
-}
-
-// ------------------------------------------------------------------------
-
-void MetaRenderGraphicAction::Scale( double fScaleX, double fScaleY )
-{
- Rectangle aRectangle( maPoint, maSize );
- ImplScaleRect( aRectangle, fScaleX, fScaleY );
- maPoint = aRectangle.TopLeft();
- maSize = aRectangle.GetSize();
-}
-
-// ------------------------------------------------------------------------
-
-sal_Bool MetaRenderGraphicAction::Compare( const MetaAction& rMetaAction ) const
-{
- return ( maRenderGraphic.IsEqual( ( (MetaRenderGraphicAction&) rMetaAction).maRenderGraphic ) &&
- ( maPoint == ( (MetaRenderGraphicAction&) rMetaAction).maPoint ) &&
- ( maSize == ( (MetaRenderGraphicAction&) rMetaAction).maSize ) &&
- ( mfRotateAngle == ( (MetaRenderGraphicAction&) rMetaAction).mfRotateAngle ) &&
- ( mfShearAngleX == ( (MetaRenderGraphicAction&) rMetaAction).mfShearAngleX ) &&
- ( mfShearAngleY == ( (MetaRenderGraphicAction&) rMetaAction).mfShearAngleY ) );
-}
-
-// ------------------------------------------------------------------------
-
-void MetaRenderGraphicAction::Write( SvStream& rOStm, ImplMetaWriteData* pData )
-{
- WRITE_BASE_COMPAT( rOStm, 1, pData );
- rOStm << maRenderGraphic << maPoint << maSize << mfRotateAngle << mfShearAngleX << mfShearAngleY;
-}
-
-// ------------------------------------------------------------------------
-
-void MetaRenderGraphicAction::Read( SvStream& rIStm, ImplMetaReadData* )
-{
- COMPAT( rIStm );
- rIStm >> maRenderGraphic >> maPoint >> maSize >> mfRotateAngle >> mfShearAngleX >> mfShearAngleY;
-}
+// eof
diff --git a/vcl/source/gdi/outdev6.cxx b/vcl/source/gdi/outdev6.cxx
index 96d7d3793c5c..f4b4dee908c6 100644
--- a/vcl/source/gdi/outdev6.cxx
+++ b/vcl/source/gdi/outdev6.cxx
@@ -33,7 +33,6 @@
#include <vcl/svapp.hxx>
#include <vcl/wrkwin.hxx>
#include <vcl/graph.hxx>
-#include <vcl/rendergraphicrasterizer.hxx>
#include <wall2.hxx>
#include <salgdi.hxx>
@@ -1246,25 +1245,3 @@ bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize,
return bDrawn;
}
-// ------------------------------------------------------------------
-
-void OutputDevice::DrawRenderGraphic( const Point& rPoint, const Size& rSize,
- const ::vcl::RenderGraphic& rRenderGraphic )
-{
- DBG_TRACE( "OutputDevice::DrawRenderGraphic()" );
-
- if( mpMetaFile )
- mpMetaFile->AddAction( new MetaRenderGraphicAction( rPoint, rSize, rRenderGraphic ) );
-
- if( !rRenderGraphic.IsEmpty() )
- {
- ::vcl::RenderGraphicRasterizer aRasterizer( rRenderGraphic );
- BitmapEx aBmpEx;
- const Size aSizePixel( LogicToPixel( rSize ) );
- GDIMetaFile* pOldMetaFile = mpMetaFile;
-
- mpMetaFile = NULL;
- DrawBitmapEx( rPoint, rSize, aRasterizer.Rasterize( aSizePixel ) );
- mpMetaFile = pOldMetaFile;
- }
-}
diff --git a/vcl/source/gdi/pdfwriter_impl2.cxx b/vcl/source/gdi/pdfwriter_impl2.cxx
index fe91a07e8ad4..488460ac873d 100644
--- a/vcl/source/gdi/pdfwriter_impl2.cxx
+++ b/vcl/source/gdi/pdfwriter_impl2.cxx
@@ -31,7 +31,6 @@
#include "vcl/metaact.hxx"
#include "vcl/bmpacc.hxx"
#include "vcl/graph.hxx"
-#include "vcl/rendergraphicrasterizer.hxx"
#include "svdata.hxx"
@@ -1044,17 +1043,6 @@ void PDFWriterImpl::playMetafile( const GDIMetaFile& i_rMtf, vcl::PDFExtOutDevDa
}
break;
- case( META_RENDERGRAPHIC_ACTION ):
- {
- const MetaRenderGraphicAction* pA = static_cast< const MetaRenderGraphicAction* >( pAction );
- const ::vcl::RenderGraphicRasterizer aRasterizer( pA->GetRenderGraphic() );
-
- implWriteBitmapEx( pA->GetPoint(), pA->GetSize(),
- aRasterizer.Rasterize( pDummyVDev->LogicToPixel( pA->GetSize() ) ),
- pDummyVDev, i_rContext );
- }
- break;
-
default:
// #i24604# Made assertion fire only once per
// metafile. The asserted actions here are all
diff --git a/vcl/source/gdi/print2.cxx b/vcl/source/gdi/print2.cxx
index daced96c9778..5b3b04102577 100644
--- a/vcl/source/gdi/print2.cxx
+++ b/vcl/source/gdi/print2.cxx
@@ -42,7 +42,6 @@
#include <vcl/print.hxx>
#include <vcl/svapp.hxx>
#include <vcl/bmpacc.hxx>
-#include <vcl/rendergraphicrasterizer.hxx>
#include <print.h>
@@ -111,9 +110,6 @@ static bool ImplIsActionSpecial( const MetaAction& rAct )
case META_BMPEXSCALEPART_ACTION:
return static_cast<const MetaBmpExScalePartAction&>(rAct).GetBitmapEx().IsTransparent();
- case META_RENDERGRAPHIC_ACTION:
- return true;
-
default:
return false;
}
@@ -201,16 +197,6 @@ static void ImplConvertTransparentAction( GDIMetaFile& o_rMtf,
aBmpEx = static_cast<const MetaBmpExScaleAction&>(rAct).GetBitmapEx();
break;
- case META_RENDERGRAPHIC_ACTION:
- {
- const ::vcl::RenderGraphicRasterizer aRasterizer( static_cast<const MetaRenderGraphicAction&>(rAct).
- GetRenderGraphic() );
-
- aBmpEx = aRasterizer.Rasterize( rStateOutDev.LogicToPixel(
- static_cast<const MetaRenderGraphicAction&>(rAct).GetSize() ) );
- break;
- }
-
case META_TRANSPARENT_ACTION:
default:
@@ -278,11 +264,6 @@ static void ImplConvertTransparentAction( GDIMetaFile& o_rMtf,
static_cast<const MetaBmpExScalePartAction&>(rAct).GetSrcSize(),
aBmp ));
break;
- case META_RENDERGRAPHIC_ACTION:
- o_rMtf.AddAction( new MetaBmpScaleAction(
- static_cast<const MetaRenderGraphicAction&>(rAct).GetPoint(),
- static_cast<const MetaRenderGraphicAction&>(rAct).GetSize(),
- aBmp ));
default:
DBG_ERROR("Unexpected case");
break;
@@ -395,7 +376,6 @@ static bool ImplIsNotTransparent( const MetaAction& rAct, const OutputDevice& rO
case META_TEXTRECT_ACTION:
case META_STRETCHTEXT_ACTION:
case META_TEXTLINE_ACTION:
- case META_RENDERGRAPHIC_ACTION:
// all other actions: generate non-transparent output
bRet = true;
break;
@@ -650,13 +630,6 @@ static Rectangle ImplCalcActionBounds( const MetaAction& rAct, const OutputDevic
DBG_ERROR("META_TEXTLINE_ACTION not supported");
break;
- case( META_RENDERGRAPHIC_ACTION ):
- {
- const MetaRenderGraphicAction& rRenderAct = static_cast<const MetaRenderGraphicAction&>(rAct);
- aActionBounds = Rectangle( rRenderAct.GetPoint(), rRenderAct.GetSize() );
- }
- break;
-
default:
break;
}
@@ -682,7 +655,6 @@ static bool ImplIsActionHandlingTransparency( const MetaAction& rAct )
case META_BMPEX_ACTION:
case META_BMPEXSCALE_ACTION:
case META_BMPEXSCALEPART_ACTION:
- case META_RENDERGRAPHIC_ACTION:
return true;
default:
diff --git a/vcl/source/gdi/rendergraphic.cxx b/vcl/source/gdi/rendergraphic.cxx
deleted file mode 100644
index 10b6064cc57c..000000000000
--- a/vcl/source/gdi/rendergraphic.cxx
+++ /dev/null
@@ -1,240 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-#include <vcl/rendergraphic.hxx>
-#include <vcl/rendergraphicrasterizer.hxx>
-#include <vcl/mapmod.hxx>
-#include <tools/stream.hxx>
-#include <tools/vcompat.hxx>
-
-#include <cstring>
-#include <cstdio>
-
-namespace vcl
-{
-
-// -----------------
-// - RenderGraphic -
-// -----------------
-RenderGraphic::RenderGraphic( ) :
- mnGraphicDataLength( 0 )
-{
-}
-
-// -------------------------------------------------------------------------
-
-RenderGraphic::RenderGraphic( const RenderGraphic& rRenderGraphic ) :
- maGraphicData( rRenderGraphic.maGraphicData ),
- mnGraphicDataLength( rRenderGraphic.mnGraphicDataLength ),
- maGraphicDataMimeType( rRenderGraphic.maGraphicDataMimeType ),
- mapPrefMapMode( rRenderGraphic.mapPrefMapMode.get() ? new MapMode( *rRenderGraphic.mapPrefMapMode ) : NULL ),
- mapPrefSize( rRenderGraphic.mapPrefSize.get() ? new Size( *rRenderGraphic.mapPrefSize ) : NULL )
-{
-}
-
-// -------------------------------------------------------------------------
-
-RenderGraphic::RenderGraphic( const GraphicData& rGraphicData,
- sal_uInt32 nGraphicDataLength,
- const rtl::OUString& rGraphicDataMimeType ) :
- maGraphicData( rGraphicData ),
- mnGraphicDataLength( nGraphicDataLength ),
- maGraphicDataMimeType( rGraphicDataMimeType )
-{
- ImplCheckData( );
-}
-
-// -------------------------------------------------------------------------
-
-RenderGraphic::RenderGraphic( const rtl::OUString& rGraphicDataMimeType,
- sal_uInt32 nGraphicDataLength,
- const sal_uInt8* pGraphicData ) :
- maGraphicData(),
- mnGraphicDataLength( nGraphicDataLength ),
- maGraphicDataMimeType( rGraphicDataMimeType )
-{
- if( rGraphicDataMimeType.getLength( ) && nGraphicDataLength )
- {
- maGraphicData.reset( new sal_uInt8[ nGraphicDataLength ] );
-
- if( pGraphicData )
- {
- memcpy( maGraphicData.get(), pGraphicData, nGraphicDataLength );
- }
- }
- else
- {
- ImplCheckData( );
- }
-}
-
-// -------------------------------------------------------------------------
-
-RenderGraphic::~RenderGraphic( )
-{
-}
-
-// -------------------------------------------------------------------------
-
-RenderGraphic& RenderGraphic::operator=(const RenderGraphic& rRenderGraphic )
-{
- maGraphicData = rRenderGraphic.maGraphicData;
- mnGraphicDataLength = rRenderGraphic.mnGraphicDataLength;
- maGraphicDataMimeType = rRenderGraphic.maGraphicDataMimeType;
- mapPrefMapMode.reset( rRenderGraphic.mapPrefMapMode.get() ? new MapMode( *rRenderGraphic.mapPrefMapMode ) : NULL );
- mapPrefSize.reset( rRenderGraphic.mapPrefSize.get() ? new Size( *rRenderGraphic.mapPrefSize ) : NULL );
-
- return( *this );
-}
-
-// -------------------------------------------------------------------------
-
-bool RenderGraphic::operator==(const RenderGraphic& rRenderGraphic ) const
-{
- return( ( rRenderGraphic.mnGraphicDataLength == mnGraphicDataLength ) &&
- ( rRenderGraphic.maGraphicData == maGraphicData ) &&
- ( rRenderGraphic.maGraphicDataMimeType.equalsIgnoreAsciiCase( maGraphicDataMimeType ) ) );
-}
-
-// -------------------------------------------------------------------------
-
-bool RenderGraphic::operator!() const
-{
- return( ( 0 == maGraphicDataMimeType.getLength( ) ) ||
- ( 0 == mnGraphicDataLength ) ||
- !maGraphicData.get( ) );
-}
-
-// -------------------------------------------------------------------------
-
-bool RenderGraphic::IsEqual( const RenderGraphic& rRenderGraphic ) const
-{
- bool bRet = ( rRenderGraphic.mnGraphicDataLength == mnGraphicDataLength ) &&
- ( rRenderGraphic.maGraphicDataMimeType.equalsIgnoreAsciiCase( maGraphicDataMimeType ) );
-
- if( bRet && mnGraphicDataLength && ( rRenderGraphic.maGraphicData != maGraphicData ) )
- {
- bRet = ( 0 == memcmp( rRenderGraphic.maGraphicData.get( ),
- maGraphicData.get( ),
- mnGraphicDataLength ) );
- }
-
- return( bRet );
-}
-
-// -------------------------------------------------------------------------
-
-const MapMode& RenderGraphic::GetPrefMapMode() const
-{
- ImplGetDefaults();
- return( *mapPrefMapMode );
-}
-
-// -------------------------------------------------------------------------
-
-const Size& RenderGraphic::GetPrefSize() const
-{
- ImplGetDefaults();
- return( *mapPrefSize );
-}
-
-// -------------------------------------------------------------------------
-
-BitmapEx RenderGraphic::GetReplacement() const
-{
- const RenderGraphicRasterizer aRasterizer( *this );
-
- return( aRasterizer.GetReplacement() );
-}
-
-// -------------------------------------------------------------------------
-
-void RenderGraphic::ImplCheckData( )
-{
- if( !( *this ) )
- {
- maGraphicData.reset( );
- mnGraphicDataLength = 0;
- maGraphicDataMimeType = ::rtl::OUString();
- mapPrefMapMode.reset();
- mapPrefSize.reset();
- }
-}
-
-// -------------------------------------------------------------------------
-
-void RenderGraphic::ImplGetDefaults() const
-{
- if( !mapPrefMapMode.get() || !mapPrefSize.get() )
- {
- const RenderGraphicRasterizer aRasterizer( *this );
-
- mapPrefMapMode.reset( new MapMode( aRasterizer.GetPrefMapMode() ) );
- mapPrefSize.reset( new Size( aRasterizer.GetPrefSize() ) );
- }
-}
-
-// -------------------------------------------------------------------------
-
-::SvStream& operator>>( ::SvStream& rIStm, RenderGraphic& rRenderGraphic )
-{
- ::VersionCompat aVCompat( rIStm, STREAM_READ );
- String aGraphicDataMimeType;
- sal_uInt32 nGraphicDataLength = 0;
-
- rIStm.ReadByteString( aGraphicDataMimeType, RTL_TEXTENCODING_ASCII_US );
- rIStm >> nGraphicDataLength;
-
- rRenderGraphic = RenderGraphic( aGraphicDataMimeType, nGraphicDataLength );
-
- if( !rRenderGraphic.IsEmpty() )
- {
- rIStm.Read( rRenderGraphic.GetGraphicData().get(), nGraphicDataLength );
- }
-
- return rIStm;
-}
-
-// ------------------------------------------------------------------
-
-::SvStream& operator<<( ::SvStream& rOStm, const RenderGraphic& rRenderGraphic )
-{
- ::VersionCompat aVCompat( rOStm, STREAM_WRITE, 1 );
- const sal_uInt32 nGraphicDataLength = rRenderGraphic.GetGraphicDataLength();
-
- rOStm.WriteByteString( rRenderGraphic.GetGraphicDataMimeType(), RTL_TEXTENCODING_ASCII_US );
- rOStm << nGraphicDataLength;
-
- if( nGraphicDataLength )
- {
- rOStm.Write( rRenderGraphic.GetGraphicData().get(), nGraphicDataLength );
- }
-
- return rOStm;
-}
-
-} // VCL
diff --git a/vcl/source/gdi/rendergraphicrasterizer.cxx b/vcl/source/gdi/rendergraphicrasterizer.cxx
deleted file mode 100644
index dd1704cf02c2..000000000000
--- a/vcl/source/gdi/rendergraphicrasterizer.cxx
+++ /dev/null
@@ -1,401 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-#include <vcl/rendergraphicrasterizer.hxx>
-#include <vcl/svapp.hxx>
-#include <vcl/wrkwin.hxx>
-#include <vcl/virdev.hxx>
-#include <vcl/unohelp.hxx>
-#include <vcl/bmpacc.hxx>
-#include <vcl/graph.hxx>
-#include <tools/diagnose_ex.h>
-#include <tools/stream.hxx>
-#include <comphelper/processfactory.hxx>
-#include <unotools/streamwrap.hxx>
-
-#include <com/sun/star/lang/XMultiServiceFactory.hpp>
-
-#define VCL_SERVICENAME_RASTERIZER_SVG "com.sun.star.graphic.GraphicRasterizer_RSVG"
-
-using namespace com::sun::star;
-
-namespace vcl
-{
-// ---------------------------------------------------------
-// - maximum extent in pixel for graphics to be rasterized -
-// ---------------------------------------------------------
-
-static const sal_uInt32 nRasterizerDefaultExtent = 4096;
-
-// ---------------------------
-// - RenderGraphicRasterizer -
-// ---------------------------
-
-RenderGraphicRasterizer::RenderGraphicRasterizer( const RenderGraphic& rRenderGraphic ) :
- maRenderGraphic( rRenderGraphic ),
- mfRotateAngle( 0.0 ),
- mfShearAngleX( 0.0 ),
- mfShearAngleY( 0.0 )
-{
-}
-
-// -------------------------------------------------------------------------
-
-RenderGraphicRasterizer::RenderGraphicRasterizer( const RenderGraphicRasterizer& rRenderGraphicRasterizer ) :
- maRenderGraphic( rRenderGraphicRasterizer.maRenderGraphic ),
- mxRasterizer( rRenderGraphicRasterizer.mxRasterizer ),
- maBitmapEx( rRenderGraphicRasterizer.maBitmapEx ),
- maDefaultSizePixel( rRenderGraphicRasterizer.maDefaultSizePixel ),
- mfRotateAngle( rRenderGraphicRasterizer.mfRotateAngle ),
- mfShearAngleX( rRenderGraphicRasterizer.mfShearAngleX ),
- mfShearAngleY( rRenderGraphicRasterizer.mfShearAngleY )
-{
-}
-
-// -------------------------------------------------------------------------
-
-RenderGraphicRasterizer::~RenderGraphicRasterizer()
-{
-}
-
-// -------------------------------------------------------------------------
-
-RenderGraphicRasterizer& RenderGraphicRasterizer::operator=(
- const RenderGraphicRasterizer& rRenderGraphicRasterizer )
-{
- maRenderGraphic = rRenderGraphicRasterizer.maRenderGraphic;
- maBitmapEx = rRenderGraphicRasterizer.maBitmapEx;
- maDefaultSizePixel = rRenderGraphicRasterizer.maDefaultSizePixel;
- mfRotateAngle = rRenderGraphicRasterizer.mfRotateAngle;
- mfShearAngleX = rRenderGraphicRasterizer.mfShearAngleX;
- mfShearAngleY = rRenderGraphicRasterizer.mfShearAngleY;
- mxRasterizer = rRenderGraphicRasterizer.mxRasterizer;
-
- return( *this );
-}
-
-// -------------------------------------------------------------------------
-
-const Size& RenderGraphicRasterizer::GetDefaultSizePixel() const
-{
- const_cast< RenderGraphicRasterizer* >( this )->InitializeRasterizer();
-
- return( maDefaultSizePixel );
-}
-
-// -------------------------------------------------------------------------
-
-BitmapEx RenderGraphicRasterizer::GetReplacement() const
-{
- BitmapEx aRet( Rasterize( GetDefaultSizePixel() ) );
-
- aRet.SetPrefSize( GetPrefSize() );
- aRet.SetPrefMapMode( GetPrefMapMode() );
-
- return( aRet );
-}
-
-// -------------------------------------------------------------------------
-
-Size RenderGraphicRasterizer::GetPrefSize() const
-{
- const Size aSizePixel( GetDefaultSizePixel() );
- std::auto_ptr< VirtualDevice > apCompVDev;
- OutputDevice* pCompDev = NULL;
-
-#ifndef NO_GETAPPWINDOW
- pCompDev = Application::GetAppWindow();
-#endif
-
- if( !pCompDev )
- {
- apCompVDev.reset( new VirtualDevice );
- pCompDev = apCompVDev.get();
- }
-
- return( pCompDev->PixelToLogic( aSizePixel, GetPrefMapMode() ) );
-}
-
-// -------------------------------------------------------------------------
-
-MapMode RenderGraphicRasterizer::GetPrefMapMode() const
-{
- return( MapMode( MAP_100TH_MM ) );
-}
-
-// -------------------------------------------------------------------------
-
-const BitmapEx& RenderGraphicRasterizer::Rasterize( const Size& rSizePixel,
- double fRotateAngle,
- double fShearAngleX,
- double fShearAngleY,
- sal_uInt32 nMaxExtent ) const
-{
- const bool bRasterize = !maRenderGraphic.IsEmpty() &&
- rSizePixel.Width() && rSizePixel.Height() &&
- ( maBitmapEx.IsEmpty() ||
- ( rSizePixel != maBitmapEx.GetSizePixel() ) ||
- ( fRotateAngle != mfRotateAngle ) ||
- ( fShearAngleX != mfShearAngleX ) ||
- ( fShearAngleY != mfShearAngleY ) );
-
- if( bRasterize )
- {
- const_cast< RenderGraphicRasterizer* >( this )->InitializeRasterizer();
-
- if( mxRasterizer.is() )
- {
- sal_uInt32 nWidth = labs( rSizePixel.Width() );
- sal_uInt32 nHeight = labs( rSizePixel.Height() );
-
- // limiting the extent of the rastered bitmap
- if( VCL_RASTERIZER_UNLIMITED_EXTENT != nMaxExtent )
- {
- if( VCL_RASTERIZER_DEFAULT_EXTENT == nMaxExtent )
- {
- nMaxExtent = nRasterizerDefaultExtent;
- }
-
- if( ( nWidth > nMaxExtent ) || ( nHeight > nMaxExtent ) )
- {
- const double fScale = static_cast< double >( nMaxExtent ) / ::std::max( nWidth, nHeight );
-
- nWidth = FRound( nWidth * fScale );
- nHeight = FRound( nHeight * fScale );
- }
- }
-
- if( !ImplRasterizeFromCache( const_cast< RenderGraphicRasterizer& >( *this ),
- Size( nWidth, nHeight ), fRotateAngle, fShearAngleX, fShearAngleY ) )
- {
- try
- {
- const uno::Sequence< beans::PropertyValue > aPropertySeq;
- const Graphic aRasteredGraphic( mxRasterizer->rasterize( nWidth,
- nHeight,
- fRotateAngle,
- fShearAngleX,
- fShearAngleY,
- aPropertySeq ) );
-
- maBitmapEx = aRasteredGraphic.GetBitmapEx();
- mfRotateAngle = fRotateAngle;
- mfShearAngleX = fShearAngleX;
- mfShearAngleY = fShearAngleY;
-
- ImplUpdateCache( *this );
-
-// OSL_TRACE( "Wanted: %d x %d / Got: %d x %d", rSizePixel.Width(), rSizePixel.Height(), maBitmapEx.GetSizePixel().Width(), maBitmapEx.GetSizePixel().Height() );
- }
- catch( ... )
- {
- OSL_TRACE( "caught exception during rasterization" );
- }
- }
- }
- }
-
- return( maBitmapEx );
-}
-
-// -------------------------------------------------------------------------
-
-void RenderGraphicRasterizer::InitializeRasterizer()
-{
- if( !mxRasterizer.is() && !ImplInitializeFromCache( *this ) )
- {
- uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
-
- maDefaultSizePixel.Width() = maDefaultSizePixel.Height() = 0;
-
- if ( !maRenderGraphic.IsEmpty() )
- {
- rtl::OUString aServiceName;
-
- if ( 0 == maRenderGraphic.GetGraphicDataMimeType().compareToAscii( RTL_CONSTASCII_STRINGPARAM( "image/svg+xml" ) ) )
- {
- aServiceName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VCL_SERVICENAME_RASTERIZER_SVG ) );
- }
-
- if( aServiceName.getLength() )
- {
- try
- {
- mxRasterizer.set( xFactory->createInstance( aServiceName ), uno::UNO_QUERY );
-
- if( mxRasterizer.is() )
- {
- std::auto_ptr< VirtualDevice > apCompVDev;
- OutputDevice* pCompDev = NULL;
-
-#ifndef NO_GETAPPWINDOW
- pCompDev = Application::GetAppWindow();
-#endif
-
- if( !pCompDev )
- {
- apCompVDev.reset( new VirtualDevice );
- pCompDev = apCompVDev.get();
- }
-
- const Size aDPI( pCompDev->LogicToPixel( Size( 1, 1 ), MAP_INCH ) );
- awt::Size aSizePixel;
- SvMemoryStream aMemStm( maRenderGraphic.GetGraphicData().get(),
- maRenderGraphic.GetGraphicDataLength(),
- STREAM_READ );
-
- uno::Reference< io::XInputStream > xIStm( new utl::OSeekableInputStreamWrapper( aMemStm ) );
-
- if( !xIStm.is() || !mxRasterizer->initializeData( xIStm, aDPI.Width(), aDPI.Height(), aSizePixel ) )
- {
- mxRasterizer.clear();
- }
- else
- {
- maDefaultSizePixel.Width() = aSizePixel.Width;
- maDefaultSizePixel.Height() = aSizePixel.Height;
- }
- }
- }
- catch( ... )
- {
- DBG_UNHANDLED_EXCEPTION();
- mxRasterizer.clear();
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------
-
-RenderGraphicRasterizer::RenderGraphicRasterizerCache& RenderGraphicRasterizer::ImplGetCache()
-{
- static RenderGraphicRasterizerCache* pCache = NULL;
-
- if( !pCache )
- {
- pCache = new RenderGraphicRasterizerCache;
- }
-
- return( *pCache );
-}
-
-// ------------------------------------------------------------------------------
-
-bool RenderGraphicRasterizer::ImplInitializeFromCache( RenderGraphicRasterizer& rRasterizer )
-{
- RenderGraphicRasterizerCache& rCache = ImplGetCache();
- bool bRet = false;
-
- for( sal_uInt32 i = 0; i < rCache.size(); ++i )
- {
- const RenderGraphicRasterizer* pCheck = &rCache[ i ];
-
- if( pCheck && pCheck->mxRasterizer.is() && ( pCheck->maRenderGraphic == rRasterizer.maRenderGraphic ) )
- {
-// OSL_TRACE( "Hit RenderGraphicRasterizer cache for initialization" );
-
- rRasterizer.mxRasterizer = pCheck->mxRasterizer;
- rRasterizer.maDefaultSizePixel = pCheck->maDefaultSizePixel;
-
- // put found Rasterizer at begin of deque
- const RenderGraphicRasterizer aFound( rCache[ i ] );
-
- rCache.erase( rCache.begin() + i );
- rCache.push_front( aFound );
-
-
- bRet = true;
- }
- }
-
- return( bRet );
-}
-
-// ------------------------------------------------------------------------------
-
-bool RenderGraphicRasterizer::ImplRasterizeFromCache( RenderGraphicRasterizer& rRasterizer,
- const Size& rSizePixel,
- double fRotateAngle,
- double fShearAngleX,
- double fShearAngleY )
-{
- RenderGraphicRasterizerCache& rCache = ImplGetCache();
- bool bRet = false;
-
- for( sal_uInt32 i = 0; i < rCache.size(); ++i )
- {
- const RenderGraphicRasterizer& rCheck = rCache[ i ];
-
- if( rCheck.mxRasterizer.is() && rRasterizer.mxRasterizer.is() &&
- ( ( rCheck.mxRasterizer == rRasterizer.mxRasterizer ) ||
- ( rRasterizer.maRenderGraphic == rCheck.maRenderGraphic ) ) &&
- ( rCheck.maBitmapEx.GetSizePixel() == rSizePixel ) &&
- ( rCheck.mfRotateAngle == fRotateAngle ) &&
- ( rCheck.mfShearAngleX == fShearAngleX ) &&
- ( rCheck.mfShearAngleY == fShearAngleY ) )
- {
-// OSL_TRACE( "Hit RenderGraphicRasterizer cache for rasterizing" );
-
- rRasterizer.maBitmapEx = rCheck.maBitmapEx;
- rRasterizer.mfRotateAngle = fRotateAngle;
- rRasterizer.mfShearAngleX = fShearAngleX;
- rRasterizer.mfShearAngleY = fShearAngleY;
-
- // put found Rasterizer at begin of deque
- const RenderGraphicRasterizer aFound( rCache[ i ] );
-
- rCache.erase( rCache.begin() + i );
- rCache.push_front( aFound );
-
- bRet = true;
- }
- }
-
- return( bRet );
-}
-
-// ------------------------------------------------------------------------------
-
-void RenderGraphicRasterizer::ImplUpdateCache( const RenderGraphicRasterizer& rRasterizer )
-{
- RenderGraphicRasterizerCache& rCache = ImplGetCache();
- const sal_uInt32 nMaxCacheSize = 8;
-
- if( rCache.size() < nMaxCacheSize )
- {
- rCache.push_front( rRasterizer );
- }
- else
- {
- rCache.pop_back();
- rCache.push_front( rRasterizer );
- }
-}
-
-} // VCL
diff --git a/vcl/source/gdi/svgdata.cxx b/vcl/source/gdi/svgdata.cxx
new file mode 100644
index 000000000000..884d3fd1cbee
--- /dev/null
+++ b/vcl/source/gdi/svgdata.cxx
@@ -0,0 +1,194 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http:\\www.apache.org\licenses\LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_vcl.hxx"
+
+#include <vcl/svgdata.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/graphic/XSvgParser.hpp>
+#include <com/sun/star/graphic/XPrimitive2DRenderer.hpp>
+#include <com/sun/star/rendering/XIntegerReadOnlyBitmap.hpp>
+#include <vcl/canvastools.hxx>
+#include <comphelper/seqstream.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace ::com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+void SvgData::ensureReplacement()
+{
+ ensureSequenceAndRange();
+
+ if(maReplacement.IsEmpty() && maSequence.hasElements())
+ {
+ // create replacement graphic from maSequence
+ // create XPrimitive2DRenderer
+ uno::Reference< lang::XMultiServiceFactory > xFactory(::comphelper::getProcessServiceFactory());
+ const rtl::OUString aServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.graphic.Primitive2DTools"));
+
+ try
+ {
+ const uno::Reference< graphic::XPrimitive2DRenderer > xPrimitive2DRenderer(xFactory->createInstance(aServiceName), uno::UNO_QUERY_THROW);
+
+ if(xPrimitive2DRenderer.is())
+ {
+ uno::Sequence< beans::PropertyValue > aViewParameters;
+ const basegfx::B2DRange& rRange(getRange());
+ geometry::RealRectangle2D aRealRect;
+
+ aRealRect.X1 = rRange.getMinX();
+ aRealRect.Y1 = rRange.getMinY();
+ aRealRect.X2 = rRange.getMaxX();
+ aRealRect.Y2 = rRange.getMaxY();
+
+ const uno::Reference< rendering::XBitmap > xBitmap(
+ xPrimitive2DRenderer->rasterize(
+ maSequence,
+ aViewParameters,
+ 72,
+ 72,
+ aRealRect,
+ 500000));
+
+ if(xBitmap.is())
+ {
+ const uno::Reference< rendering::XIntegerReadOnlyBitmap> xIntBmp(xBitmap, uno::UNO_QUERY_THROW);
+
+ if(xIntBmp.is())
+ {
+ maReplacement = vcl::unotools::bitmapExFromXBitmap(xIntBmp);
+ }
+ }
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ OSL_ENSURE(sal_False, "Got no graphic::XPrimitive2DRenderer (!)" );
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+void SvgData::ensureSequenceAndRange()
+{
+ if(!maSequence.hasElements() && mnSvgDataArrayLength)
+ {
+ // import SVG to maSequence, also set maRange
+ maRange.reset();
+
+ // create stream
+ const uno::Sequence< sal_Int8 > aPostData((sal_Int8*)maSvgDataArray.get(), mnSvgDataArrayLength);
+ const uno::Reference< io::XInputStream > myInputStream(new comphelper::SequenceInputStream(aPostData));
+
+ if(myInputStream.is())
+ {
+ // create SVG interpreter
+ uno::Reference< lang::XMultiServiceFactory > xFactory(::comphelper::getProcessServiceFactory());
+ const rtl::OUString aServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.graphic.SvgTools"));
+
+ try
+ {
+ const uno::Reference< graphic::XSvgParser > xSvgParser(xFactory->createInstance(aServiceName), uno::UNO_QUERY_THROW);
+
+ if(xSvgParser.is())
+ {
+ maSequence = xSvgParser->getDecomposition(myInputStream, maPath);
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ OSL_ENSURE(sal_False, "Got no graphic::XSvgParser (!)" );
+ }
+ }
+
+ if(maSequence.hasElements())
+ {
+ const sal_Int32 nCount(maSequence.getLength());
+ geometry::RealRectangle2D aRealRect;
+ uno::Sequence< beans::PropertyValue > aViewParameters;
+
+ for(sal_Int32 a(0L); a < nCount; a++)
+ {
+ // get reference
+ const Primitive2DReference xReference(maSequence[a]);
+
+ if(xReference.is())
+ {
+ aRealRect = xReference->getRange(aViewParameters);
+
+ maRange.expand(
+ basegfx::B2DRange(
+ aRealRect.X1,
+ aRealRect.Y1,
+ aRealRect.X2,
+ aRealRect.Y2));
+ }
+ }
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+SvgData::SvgData(const SvgDataArray& rSvgDataArray, sal_uInt32 nSvgDataArrayLength, const rtl::OUString& rPath)
+: maSvgDataArray(rSvgDataArray),
+ mnSvgDataArrayLength(nSvgDataArrayLength),
+ maPath(rPath),
+ maRange(),
+ maSequence(),
+ maReplacement()
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+const basegfx::B2DRange& SvgData::getRange() const
+{
+ const_cast< SvgData* >(this)->ensureSequenceAndRange();
+
+ return maRange;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+const Primitive2DSequence& SvgData::getPrimitive2DSequence() const
+{
+ const_cast< SvgData* >(this)->ensureSequenceAndRange();
+
+ return maSequence;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+const BitmapEx& SvgData::getReplacement() const
+{
+ const_cast< SvgData* >(this)->ensureReplacement();
+
+ return maReplacement;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/vcl/source/gdi/svgread.cxx b/vcl/source/gdi/svgread.cxx
deleted file mode 100644
index 2c4855de0a8c..000000000000
--- a/vcl/source/gdi/svgread.cxx
+++ /dev/null
@@ -1,127 +0,0 @@
-/**************************************************************
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- *************************************************************/
-
-
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include <tools/stream.hxx>
-#include <vcl/svgread.hxx>
-#include <vcl/gdimtf.hxx>
-#include <vcl/metaact.hxx>
-#include <vcl/rendergraphicrasterizer.hxx>
-
-// -----------
-// - Defines -
-// -----------
-
-namespace vcl
-{
- // -----------------
- // - SVGReaderImpl -
- // -----------------
-
- class SVGReaderImpl
- {
- public:
-
- SVGReaderImpl( SvStream& rStm );
- ~SVGReaderImpl();
-
- GDIMetaFile& ImplRead( GDIMetaFile& rSVGMtf );
-
- private:
-
- SvStream& mrStm;
- };
-
- // ------------------------------------------------------------------------------
-
- SVGReaderImpl::SVGReaderImpl( SvStream& rStm ) :
- mrStm( rStm )
- {
- }
-
- // ------------------------------------------------------------------------
-
- SVGReaderImpl::~SVGReaderImpl()
- {
- }
-
- // ------------------------------------------------------------------------
-
- GDIMetaFile& SVGReaderImpl::ImplRead( GDIMetaFile& rSVGMtf )
- {
- const sal_uInt32 nStmPos = mrStm.Tell();
- const sal_uInt32 nStmLen = mrStm.Seek( STREAM_SEEK_TO_END ) - nStmPos;
-
- if( nStmLen )
- {
- const vcl::RenderGraphic aSVGGraphic( ::rtl::OUString::createFromAscii( "image/svg+xml" ), nStmLen );
-
- mrStm.Seek( nStmPos );
- mrStm.Read( aSVGGraphic.GetGraphicData().get(), nStmLen );
-
- if( !mrStm.GetError() )
- {
- const vcl::RenderGraphicRasterizer aRasterizer( aSVGGraphic );
- const Size aDefaultSizePixel( aRasterizer.GetDefaultSizePixel() );
-
- if( aDefaultSizePixel.Width() && aDefaultSizePixel.Height() )
- {
- const Point aPos;
- const Size aPrefSize( aRasterizer.GetPrefSize() );
-
- rSVGMtf.SetPrefMapMode( aRasterizer.GetPrefMapMode() );
- rSVGMtf.SetPrefSize( aPrefSize );
- rSVGMtf.AddAction( new MetaRenderGraphicAction( aPos, aPrefSize, aSVGGraphic ) );
- rSVGMtf.WindStart();
- }
- }
- }
-
- return( rSVGMtf );
- }
-
- // -------------
- // - SVGReader -
- // -------------
-
- SVGReader::SVGReader( SvStream& rIStm ) :
- mapImpl( new ::vcl::SVGReaderImpl( rIStm ) )
- {
- }
-
- // ------------------------------------------------------------------------
-
- SVGReader::~SVGReader()
- {
- }
-
- // ------------------------------------------------------------------------
-
- GDIMetaFile& SVGReader::Read( GDIMetaFile& rSVGMtf )
- {
- rSVGMtf = GDIMetaFile();
-
- return( mapImpl.get() ? mapImpl->ImplRead( rSVGMtf ) : rSVGMtf );
- }
-
-} // namespace vcl
diff --git a/vcl/util/makefile.mk b/vcl/util/makefile.mk
index 75b3f9f527c1..8d1de2ed30f0 100644
--- a/vcl/util/makefile.mk
+++ b/vcl/util/makefile.mk
@@ -99,8 +99,6 @@ HXXDEPNLST= $(INC)$/vcl$/accel.hxx \
$(INC)$/vcl$/print.hxx \
$(INC)$/vcl$/prndlg.hxx \
$(INC)$/vcl$/region.hxx \
- $(INC)$/vcl$/rendergraphic.hxx \
- $(INC)$/vcl$/rendergraphicrasterizer.hxx \
$(INC)$/vcl$/salbtype.hxx \
$(INC)$/vcl$/scrbar.hxx \
$(INC)$/vcl$/slider.hxx \
diff --git a/xmloff/Library_xo.mk b/xmloff/Library_xo.mk
index 0544171dbfbd..0e23b7dea241 100644
--- a/xmloff/Library_xo.mk
+++ b/xmloff/Library_xo.mk
@@ -119,6 +119,7 @@ $(eval $(call gb_Library_add_exception_objects,xo,\
xmloff/source/core/xmltkmap \
xmloff/source/core/xmltoken \
xmloff/source/core/xmluconv \
+ xmloff/source/core/xmlmultiimagehelper \
xmloff/source/draw/EnhancedCustomShapeToken \
xmloff/source/draw/XMLGraphicsDefaultStyle \
xmloff/source/draw/XMLImageMapContext \
diff --git a/xmloff/Package_inc.mk b/xmloff/Package_inc.mk
index 4e11c2b4b5d9..a71da5fe617e 100644
--- a/xmloff/Package_inc.mk
+++ b/xmloff/Package_inc.mk
@@ -129,3 +129,4 @@ $(eval $(call gb_Package_add_file,xmloff_inc,inc/xmloff/xmltkmap.hxx,xmloff/xmlt
$(eval $(call gb_Package_add_file,xmloff_inc,inc/xmloff/xmltoken.hxx,xmloff/xmltoken.hxx))
$(eval $(call gb_Package_add_file,xmloff_inc,inc/xmloff/xmltypes.hxx,xmloff/xmltypes.hxx))
$(eval $(call gb_Package_add_file,xmloff_inc,inc/xmloff/xmluconv.hxx,xmloff/xmluconv.hxx))
+$(eval $(call gb_Package_add_file,xmloff_inc,inc/xmloff/xmlmultiimagehelper.hxx,xmloff/xmlmultiimagehelper.hxx))
diff --git a/xmloff/inc/xmloff/txtparae.hxx b/xmloff/inc/xmloff/txtparae.hxx
index a83d24d15d0c..01e1ba9cbff9 100644
--- a/xmloff/inc/xmloff/txtparae.hxx
+++ b/xmloff/inc/xmloff/txtparae.hxx
@@ -146,6 +146,7 @@ protected:
const ::rtl::OUString sGraphicFilter;
const ::rtl::OUString sGraphicRotation;
const ::rtl::OUString sGraphicURL;
+ const ::rtl::OUString sReplacementGraphicURL;
const ::rtl::OUString sHeight;
const ::rtl::OUString sHoriOrient;
const ::rtl::OUString sHoriOrientPosition;
diff --git a/xmloff/inc/xmloff/xmlmultiimagehelper.hxx b/xmloff/inc/xmloff/xmlmultiimagehelper.hxx
new file mode 100644
index 000000000000..c7ce4bae7570
--- /dev/null
+++ b/xmloff/inc/xmloff/xmlmultiimagehelper.hxx
@@ -0,0 +1,62 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#ifndef _XMLOFF_XMLMULTIIMAGEHELPER_HXX
+#define _XMLOFF_XMLMULTIIMAGEHELPER_HXX
+
+#include <sal/types.h>
+#include <xmloff/xmlimp.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+class multiImageImportHelper
+{
+private:
+ std::vector< SvXMLImportContextRef* > maImplContextVector;
+ bool mbSupportsMultipleContents;
+
+protected:
+ /// helper to get the created xShape instance, needs to be overloaded
+ virtual rtl::OUString getGraphicURLFromImportContext(const SvXMLImportContext& rContext) const = 0;
+ virtual void removeGraphicFromImportContext(const SvXMLImportContext& rContext) const = 0;
+
+public:
+ multiImageImportHelper();
+ ~multiImageImportHelper();
+
+ /// solve multiple imported images. The most valuable one is choosen,
+ /// see imlementation for evtl. changing weights and/or adding filetypes
+ void solveMultipleImages();
+
+ /// add a content to the remembered image import contexts
+ void addContent(const SvXMLImportContext& rSvXMLImportContext);
+
+ /// read/write access to boolean switch
+ bool getSupportsMultipleContents() const { return mbSupportsMultipleContents; }
+ void setSupportsMultipleContents(bool bNew) { mbSupportsMultipleContents = bNew; }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif // _XMLOFF_XMLMULTIIMAGEHELPER_HXX
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/xmloff/source/core/xmlmultiimagehelper.cxx b/xmloff/source/core/xmlmultiimagehelper.cxx
new file mode 100644
index 000000000000..9047ac9d125c
--- /dev/null
+++ b/xmloff/source/core/xmlmultiimagehelper.cxx
@@ -0,0 +1,146 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_xmloff.hxx"
+
+#include <xmloff/xmlmultiimagehelper.hxx>
+#include <rtl/ustring.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace ::com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace
+{
+ sal_uInt32 getQualityIndex(const rtl::OUString& rString)
+ {
+ sal_uInt32 nRetval(0);
+
+ // pixel formats first
+ if(rString.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM(".bmp")))
+ {
+ return 10;
+ }
+ if(rString.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM(".gif")))
+ {
+ return 20;
+ }
+ if(rString.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM(".jpg")))
+ {
+ return 30;
+ }
+ if(rString.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM(".png")))
+ {
+ return 40;
+ }
+
+ // vector formats, prefer always
+ if(rString.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM(".svm")))
+ {
+ return 1000;
+ }
+ if(rString.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM(".wmf")))
+ {
+ return 1010;
+ }
+ if(rString.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM(".emf")))
+ {
+ return 1020;
+ }
+ else if(rString.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM(".svg")))
+ {
+ return 1030;
+ }
+
+ return nRetval;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+multiImageImportHelper::multiImageImportHelper()
+: maImplContextVector(),
+ mbSupportsMultipleContents(false)
+{
+}
+
+multiImageImportHelper::~multiImageImportHelper()
+{
+ while(!maImplContextVector.empty())
+ {
+ delete *(maImplContextVector.end() - 1);
+ maImplContextVector.pop_back();
+ }
+}
+
+void multiImageImportHelper::solveMultipleImages()
+{
+ if(maImplContextVector.size() > 1)
+ {
+ // multiple child contexts were imported, decide which is the most valuable one
+ // and remove the rest
+ sal_uInt32 nIndexOfPreferred(maImplContextVector.size());
+ sal_uInt32 nBestQuality(0), a(0);
+
+ for(a = 0; a < maImplContextVector.size(); a++)
+ {
+ const rtl::OUString aStreamURL(getGraphicURLFromImportContext(**maImplContextVector[a]));
+ const sal_uInt32 nNewQuality(getQualityIndex(aStreamURL));
+
+ if(nNewQuality > nBestQuality)
+ {
+ nBestQuality = nNewQuality;
+ nIndexOfPreferred = a;
+ }
+ }
+
+ // correct if needed, default is to use the last entry
+ if(nIndexOfPreferred >= maImplContextVector.size())
+ {
+ nIndexOfPreferred = maImplContextVector.size() - 1;
+ }
+
+ // Take out the most valuable one
+ const std::vector< SvXMLImportContextRef* >::iterator aRemove(maImplContextVector.begin() + nIndexOfPreferred);
+ delete *aRemove;
+ maImplContextVector.erase(aRemove);
+
+ // remove the rest from parent
+ for(a = 0; a < maImplContextVector.size(); a++)
+ {
+ removeGraphicFromImportContext(**maImplContextVector[a]);
+ }
+ }
+}
+
+void multiImageImportHelper::addContent(const SvXMLImportContext& rSvXMLImportContext)
+{
+ if(dynamic_cast< const SvXMLImportContext* >(&rSvXMLImportContext))
+ {
+ maImplContextVector.push_back(new SvXMLImportContextRef(const_cast< SvXMLImportContext* >(&rSvXMLImportContext)));
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//eof
diff --git a/xmloff/source/draw/shapeexport2.cxx b/xmloff/source/draw/shapeexport2.cxx
index f9b0989825fa..ded603f7801c 100644
--- a/xmloff/source/draw/shapeexport2.cxx
+++ b/xmloff/source/draw/shapeexport2.cxx
@@ -1156,6 +1156,29 @@ void XMLShapeExport::ImpExportGraphicObjectShape(
{
if( !bIsEmptyPresObj )
{
+ OUString aReplacementUrl;
+ xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("ReplacementGraphicURL"))) >>= aReplacementUrl;
+
+ // If there is no url, then then graphic is empty
+ if(aReplacementUrl.getLength())
+ {
+ const OUString aStr = mrExport.AddEmbeddedGraphicObject(aReplacementUrl);
+
+ if(aStr.getLength())
+ {
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aStr);
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
+
+ // xlink:href for replacement, only written for Svg content
+ SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_IMAGE, sal_True, sal_True);
+
+ // optional office:binary-data
+ mrExport.AddEmbeddedGraphicObjectAsBase64(aReplacementUrl);
+ }
+ }
+
OUString aStreamURL;
OUString aStr;
@@ -1189,7 +1212,7 @@ void XMLShapeExport::ImpExportGraphicObjectShape(
{
if( aStr[ 0 ] == '#' )
{
- aStreamURL = OUString::createFromAscii( "vnd.sun.star.Package:" );
+ aStreamURL = sPackageURL;
aStreamURL = aStreamURL.concat( aStr.copy( 1, aStr.getLength() - 1 ) );
}
diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx
index 11c399ff3ec6..79bcbe026c51 100644
--- a/xmloff/source/draw/ximpshap.cxx
+++ b/xmloff/source/draw/ximpshap.cxx
@@ -82,6 +82,7 @@
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <tools/string.hxx>
#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
+#include <com/sun/star/container/XChild.hpp>
// --> OD 2006-02-22 #b6382898#
#include <com/sun/star/text/XTextDocument.hpp>
@@ -3328,7 +3329,10 @@ SdXMLFrameShapeContext::SdXMLFrameShapeContext( SvXMLImport& rImport, sal_uInt16
com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& rShapes,
sal_Bool bTemporaryShape)
: SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
- mbSupportsReplacement( sal_False )
+ multiImageImportHelper(),
+ mbSupportsReplacement( sal_False ),
+ mxImplContext(),
+ mxReplImplContext()
{
uno::Reference < util::XCloneable > xClone( xAttrList, uno::UNO_QUERY );
if( xClone.is() )
@@ -3342,6 +3346,67 @@ SdXMLFrameShapeContext::~SdXMLFrameShapeContext()
{
}
+void SdXMLFrameShapeContext::removeGraphicFromImportContext(const SvXMLImportContext& rContext) const
+{
+ const SdXMLGraphicObjectShapeContext* pSdXMLGraphicObjectShapeContext = dynamic_cast< const SdXMLGraphicObjectShapeContext* >(&rContext);
+
+ if(pSdXMLGraphicObjectShapeContext)
+ {
+ try
+ {
+ uno::Reference< container::XChild > xChild(pSdXMLGraphicObjectShapeContext->getShape(), uno::UNO_QUERY_THROW);
+
+ if(xChild.is())
+ {
+ uno::Reference< drawing::XShapes > xParent(xChild->getParent(), uno::UNO_QUERY_THROW);
+
+ if(xParent.is())
+ {
+ // remove from parent
+ xParent->remove(pSdXMLGraphicObjectShapeContext->getShape());
+
+ // dispose
+ uno::Reference< lang::XComponent > xComp(pSdXMLGraphicObjectShapeContext->getShape(), UNO_QUERY);
+
+ if(xComp.is())
+ {
+ xComp->dispose();
+ }
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ DBG_ERROR( "Error in cleanup of multiple graphic object import (!)" );
+ }
+ }
+}
+
+rtl::OUString SdXMLFrameShapeContext::getGraphicURLFromImportContext(const SvXMLImportContext& rContext) const
+{
+ rtl::OUString aRetval;
+ const SdXMLGraphicObjectShapeContext* pSdXMLGraphicObjectShapeContext = dynamic_cast< const SdXMLGraphicObjectShapeContext* >(&rContext);
+
+ if(pSdXMLGraphicObjectShapeContext)
+ {
+ try
+ {
+ const uno::Reference< beans::XPropertySet > xPropSet(pSdXMLGraphicObjectShapeContext->getShape(), uno::UNO_QUERY_THROW);
+
+ if(xPropSet.is())
+ {
+ xPropSet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicStreamURL"))) >>= aRetval;
+ }
+ }
+ catch( uno::Exception& )
+ {
+ DBG_ERROR( "Error in cleanup of multiple graphic object import (!)" );
+ }
+ }
+
+ return aRetval;
+}
+
SvXMLImportContext *SdXMLFrameShapeContext::CreateChildContext( sal_uInt16 nPrefix,
const OUString& rLocalName,
const uno::Reference< xml::sax::XAttributeList>& xAttrList )
@@ -3351,11 +3416,28 @@ SvXMLImportContext *SdXMLFrameShapeContext::CreateChildContext( sal_uInt16 nPref
if( !mxImplContext.Is() )
{
pContext = GetImport().GetShapeImport()->CreateFrameChildContext(
- GetImport(), nPrefix, rLocalName, xAttrList, mxShapes, mxAttrList );
+ GetImport(), nPrefix, rLocalName, xAttrList, mxShapes, mxAttrList);
+
+ mxImplContext = pContext;
+ mbSupportsReplacement = IsXMLToken(rLocalName, XML_OBJECT ) || IsXMLToken(rLocalName, XML_OBJECT_OLE);
+ setSupportsMultipleContents(IsXMLToken(rLocalName, XML_IMAGE));
+ if(getSupportsMultipleContents() && dynamic_cast< SdXMLGraphicObjectShapeContext* >(pContext))
+ {
+ addContent(*mxImplContext);
+ }
+ }
+ else if(getSupportsMultipleContents() && XML_NAMESPACE_DRAW == nPrefix && IsXMLToken(rLocalName, XML_IMAGE))
+ {
+ // read another image
+ pContext = GetImport().GetShapeImport()->CreateFrameChildContext(
+ GetImport(), nPrefix, rLocalName, xAttrList, mxShapes, mxAttrList);
mxImplContext = pContext;
- mbSupportsReplacement = IsXMLToken( rLocalName, XML_OBJECT ) ||
- IsXMLToken( rLocalName, XML_OBJECT_OLE );
+
+ if(dynamic_cast< SdXMLGraphicObjectShapeContext* >(pContext))
+ {
+ addContent(*mxImplContext);
+ }
}
else if( mbSupportsReplacement && !mxReplImplContext &&
XML_NAMESPACE_DRAW == nPrefix &&
@@ -3415,6 +3497,9 @@ void SdXMLFrameShapeContext::StartElement(const uno::Reference< xml::sax::XAttri
void SdXMLFrameShapeContext::EndElement()
{
+ /// solve if multiple image child contexts were imported
+ solveMultipleImages();
+
if( !mxImplContext.Is() )
{
// now check if this is an empty presentation object
diff --git a/xmloff/source/draw/ximpshap.hxx b/xmloff/source/draw/ximpshap.hxx
index 1423f7a4b5d7..e8fe3725312f 100644
--- a/xmloff/source/draw/ximpshap.hxx
+++ b/xmloff/source/draw/ximpshap.hxx
@@ -38,6 +38,7 @@
#include <vector>
#include <xmloff/shapeimport.hxx>
+#include <xmloff/xmlmultiimagehelper.hxx>
//////////////////////////////////////////////////////////////////////////////
// common shape context
@@ -573,13 +574,18 @@ public:
//////////////////////////////////////////////////////////////////////////////
// draw:-frame
-class SdXMLFrameShapeContext : public SdXMLShapeContext
+class SdXMLFrameShapeContext : public SdXMLShapeContext, public multiImageImportHelper
{
private:
sal_Bool mbSupportsReplacement;
SvXMLImportContextRef mxImplContext;
SvXMLImportContextRef mxReplImplContext;
+protected:
+ /// helper to get the created xShape instance, needs to be overloaded
+ virtual rtl::OUString getGraphicURLFromImportContext(const SvXMLImportContext& rContext) const;
+ virtual void removeGraphicFromImportContext(const SvXMLImportContext& rContext) const;
+
public:
TYPEINFO();
diff --git a/xmloff/source/text/XMLTextFrameContext.cxx b/xmloff/source/text/XMLTextFrameContext.cxx
index 1548387ffc04..3e741e2f65f9 100644
--- a/xmloff/source/text/XMLTextFrameContext.cxx
+++ b/xmloff/source/text/XMLTextFrameContext.cxx
@@ -433,6 +433,7 @@ public:
TYPEINFO();
sal_Bool CreateIfNotThere();
+ const OUString& GetHRef() const { return sHRef; }
XMLTextFrameContext_Impl( SvXMLImport& rImport,
sal_uInt16 nPrfx,
@@ -466,7 +467,7 @@ public:
::com::sun::star::text::TextContentAnchorType GetAnchorType() const { return eAnchorType; }
const ::com::sun::star::uno::Reference <
- ::com::sun::star::beans::XPropertySet >& GetPropSet() { return xPropSet; }
+ ::com::sun::star::beans::XPropertySet >& GetPropSet() const { return xPropSet; }
};
TYPEINIT1( XMLTextFrameContext_Impl, SvXMLImportContext );
@@ -759,8 +760,6 @@ void XMLTextFrameContext_Impl::Create( sal_Bool /*bHRefOrBase64*/ )
xTextImportHelper->InsertTextContent( xTxtCntnt );
}
- Reference < XShape > xShape( xPropSet, UNO_QUERY );
-
// #107848#
// Make adding the shepe to Z-Ordering dependent from if we are
// inside a inside_deleted_section (redlining). That is necessary
@@ -770,6 +769,8 @@ void XMLTextFrameContext_Impl::Create( sal_Bool /*bHRefOrBase64*/ )
if(!GetImport().HasTextImport()
|| !GetImport().GetTextImport()->IsInsideDeleteContext())
{
+ Reference < XShape > xShape( xPropSet, UNO_QUERY );
+
GetImport().GetShapeImport()->shapeWithZIndexAdded( xShape, nZIndex );
}
@@ -1308,6 +1309,42 @@ void XMLTextFrameContext_Impl::SetDesc( const OUString& rDesc )
TYPEINIT1( XMLTextFrameContext, SvXMLImportContext );
+void XMLTextFrameContext::removeGraphicFromImportContext(const SvXMLImportContext& rContext) const
+{
+ const XMLTextFrameContext_Impl* pXMLTextFrameContext_Impl = dynamic_cast< const XMLTextFrameContext_Impl* >(&rContext);
+
+ if(pXMLTextFrameContext_Impl)
+ {
+ try
+ {
+ // just dispose to delete
+ uno::Reference< lang::XComponent > xComp(pXMLTextFrameContext_Impl->GetPropSet(), UNO_QUERY);
+
+ if(xComp.is())
+ {
+ xComp->dispose();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ DBG_ERROR( "Error in cleanup of multiple graphic object import (!)" );
+ }
+ }
+}
+
+rtl::OUString XMLTextFrameContext::getGraphicURLFromImportContext(const SvXMLImportContext& rContext) const
+{
+ rtl::OUString aRetval;
+ const XMLTextFrameContext_Impl* pXMLTextFrameContext_Impl = dynamic_cast< const XMLTextFrameContext_Impl* >(&rContext);
+
+ if(pXMLTextFrameContext_Impl)
+ {
+ return pXMLTextFrameContext_Impl->GetHRef();
+ }
+
+ return aRetval;
+}
+
sal_Bool XMLTextFrameContext::CreateIfNotThere()
{
sal_Bool bRet = sal_False;
@@ -1339,6 +1376,7 @@ XMLTextFrameContext::XMLTextFrameContext(
const Reference< XAttributeList > & xAttrList,
TextContentAnchorType eATyp )
: SvXMLImportContext( rImport, nPrfx, rLName )
+, multiImageImportHelper()
, m_xAttrList( new SvXMLAttributeList( xAttrList ) )
, m_pHyperlink( 0 )
// --> OD 2009-07-22 #i73249#
@@ -1401,6 +1439,9 @@ XMLTextFrameContext::~XMLTextFrameContext()
void XMLTextFrameContext::EndElement()
{
+ /// solve if multiple image child contexts were imported
+ solveMultipleImages();
+
SvXMLImportContext *pContext = &m_xImplContext;
XMLTextFrameContext_Impl *pImpl = PTR_CAST( XMLTextFrameContext_Impl, pContext );
if( pImpl )
@@ -1505,6 +1546,10 @@ SvXMLImportContext *XMLTextFrameContext::CreateChildContext(
{
m_bSupportsReplacement = sal_True;
}
+ else if(XML_TEXT_FRAME_GRAPHIC == nFrameType)
+ {
+ setSupportsMultipleContents(IsXMLToken(rLocalName, XML_IMAGE));
+ }
if( !pContext )
{
@@ -1517,9 +1562,24 @@ SvXMLImportContext *XMLTextFrameContext::CreateChildContext(
}
m_xImplContext = pContext;
+
+ if(getSupportsMultipleContents() && XML_TEXT_FRAME_GRAPHIC == nFrameType)
+ {
+ addContent(*m_xImplContext);
+ }
}
}
}
+ else if(getSupportsMultipleContents() && XML_NAMESPACE_DRAW == p_nPrefix && IsXMLToken(rLocalName, XML_IMAGE))
+ {
+ // read another image
+ pContext = new XMLTextFrameContext_Impl(
+ GetImport(), p_nPrefix, rLocalName, xAttrList,
+ m_eDefaultAnchorType, XML_TEXT_FRAME_GRAPHIC, m_xAttrList);
+
+ m_xImplContext = pContext;
+ addContent(*m_xImplContext);
+ }
else if( m_bSupportsReplacement && !m_xReplImplContext &&
XML_NAMESPACE_DRAW == p_nPrefix &&
IsXMLToken( rLocalName, XML_IMAGE ) )
diff --git a/xmloff/source/text/XMLTextFrameContext.hxx b/xmloff/source/text/XMLTextFrameContext.hxx
index e8d660ced4a8..0cac2a59e23b 100644
--- a/xmloff/source/text/XMLTextFrameContext.hxx
+++ b/xmloff/source/text/XMLTextFrameContext.hxx
@@ -28,6 +28,7 @@
#include <com/sun/star/text/TextContentAnchorType.hpp>
#endif
#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlmultiimagehelper.hxx>
namespace com { namespace sun { namespace star {
namespace text { class XTextCursor; class XTextContent; }
@@ -36,7 +37,7 @@ namespace com { namespace sun { namespace star {
class SvXMLAttributeList;
class XMLTextFrameContextHyperlink_Impl;
-class XMLTextFrameContext : public SvXMLImportContext
+class XMLTextFrameContext : public SvXMLImportContext, public multiImageImportHelper
{
::com::sun::star::uno::Reference<
::com::sun::star::xml::sax::XAttributeList > m_xAttrList;
@@ -66,6 +67,11 @@ class XMLTextFrameContext : public SvXMLImportContext
sal_Bool CreateIfNotThere( ::com::sun::star::uno::Reference <
::com::sun::star::beans::XPropertySet >& rPropSet );
+protected:
+ /// helper to get the created xShape instance, needs to be overloaded
+ virtual rtl::OUString getGraphicURLFromImportContext(const SvXMLImportContext& rContext) const;
+ virtual void removeGraphicFromImportContext(const SvXMLImportContext& rContext) const;
+
public:
TYPEINFO();
diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx
index 290b5099ed3c..ecc672b257ee 100644
--- a/xmloff/source/text/txtparae.cxx
+++ b/xmloff/source/text/txtparae.cxx
@@ -1223,6 +1223,7 @@ XMLTextParagraphExport::XMLTextParagraphExport(
sGraphicFilter(RTL_CONSTASCII_USTRINGPARAM("GraphicFilter")),
sGraphicRotation(RTL_CONSTASCII_USTRINGPARAM("GraphicRotation")),
sGraphicURL(RTL_CONSTASCII_USTRINGPARAM("GraphicURL")),
+ sReplacementGraphicURL(RTL_CONSTASCII_USTRINGPARAM("ReplacementGraphicURL")),
sHeight(RTL_CONSTASCII_USTRINGPARAM("Height")),
sHoriOrient(RTL_CONSTASCII_USTRINGPARAM("HoriOrient")),
sHoriOrientPosition(RTL_CONSTASCII_USTRINGPARAM("HoriOrientPosition")),
@@ -3018,9 +3019,33 @@ void XMLTextParagraphExport::_exportTextGraphic(
sRet.makeStringAndClear() );
}
+ // original content
+ SvXMLElementExport aElem(GetExport(), XML_NAMESPACE_DRAW, XML_FRAME, sal_False, sal_True);
- SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_DRAW,
- XML_FRAME, sal_False, sal_True );
+ // replacement graphic for backwards compatibility, but
+ // only for SVG currently
+ OUString sReplacementOrigURL;
+ rPropSet->getPropertyValue( sReplacementGraphicURL ) >>= sReplacementOrigURL;
+
+ if(sReplacementOrigURL.getLength())
+ {
+ const OUString sReplacementURL(GetExport().AddEmbeddedGraphicObject( sReplacementOrigURL ));
+
+ // If there is no url, then then graphic is empty
+ if(sReplacementURL.getLength())
+ {
+ GetExport().AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, sReplacementURL);
+ GetExport().AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE);
+ GetExport().AddAttribute(XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED);
+ GetExport().AddAttribute(XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD);
+
+ // xlink:href for replacement, only written for Svg content
+ SvXMLElementExport aElement(GetExport(), XML_NAMESPACE_DRAW, XML_IMAGE, sal_False, sal_True);
+
+ // optional office:binary-data
+ GetExport().AddEmbeddedGraphicObjectAsBase64(sReplacementURL);
+ }
+ }
// xlink:href
OUString sOrigURL;