1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_FILTER_SOURCE_SVG_SVGWRITER_HXX
21 #define INCLUDED_FILTER_SOURCE_SVG_SVGWRITER_HXX
23 #include <cppuhelper/implbase.hxx>
24 #include <rtl/ustring.hxx>
25 #include <osl/diagnose.h>
26 #include <vcl/gdimtf.hxx>
27 #include <vcl/metaact.hxx>
28 #include <vcl/metric.hxx>
29 #include <vcl/virdev.hxx>
30 #include <vcl/cvtgrf.hxx>
31 #include <vcl/graphictools.hxx>
32 #include <xmloff/xmlexp.hxx>
33 #include <xmloff/nmspmap.hxx>
35 #include <com/sun/star/uno/Reference.h>
36 #include <com/sun/star/container/XEnumerationAccess.hpp>
37 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
38 #include <com/sun/star/container/XEnumeration.hpp>
39 #include <com/sun/star/container/XIndexReplace.hpp>
40 #include <com/sun/star/lang/XServiceInfo.hpp>
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <com/sun/star/beans/XPropertySetInfo.hpp>
43 #include <com/sun/star/uno/RuntimeException.hpp>
44 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
45 #include <com/sun/star/lang/XComponent.hpp>
46 #include <com/sun/star/registry/XRegistryKey.hpp>
47 #include <com/sun/star/io/XInputStream.hpp>
48 #include <com/sun/star/io/XOutputStream.hpp>
49 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
50 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
51 #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
52 #include <com/sun/star/i18n/XBreakIterator.hpp>
53 #include <com/sun/star/drawing/XShape.hpp>
54 #include <com/sun/star/text/XText.hpp>
55 #include <com/sun/star/text/XTextContent.hpp>
56 #include <com/sun/star/text/XTextRange.hpp>
57 #include <com/sun/star/text/XTextField.hpp>
58 #include <com/sun/star/style/NumberingType.hpp>
59 #include <com/sun/star/svg/XSVGWriter.hpp>
63 #include <unordered_map>
66 using namespace ::com::sun::star::uno
;
67 using namespace ::com::sun::star::container
;
68 using namespace ::com::sun::star::lang
;
69 using namespace ::com::sun::star::text
;
70 using namespace ::com::sun::star::style
;
71 using namespace ::com::sun::star::svg
;
72 using namespace ::com::sun::star::xml::sax
;
74 #define SVG_DTD_STRING "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">"
76 #define SVGWRITER_WRITE_FILL 0x00000001
77 #define SVGWRITER_WRITE_TEXT 0x00000002
78 #define SVGWRITER_NO_SHAPE_COMMENTS 0x01000000
86 // basegfx::B2DLineJoin aLineJoin;
87 // com::sun::star::drawing::LineCap aLineCap;
88 sal_Int32 nRegionClipPathId
;
92 , nRegionClipPathId( 0 )
100 ::std::unique_ptr
<vcl::Font
> mupFont
;
101 sal_Int32 mnRegionClipPathId
;
103 const vcl::Font
& getFont( const vcl::Font
& rDefaultFont
) const
104 { return mupFont
? *mupFont
: rDefaultFont
; }
106 void setFont( const vcl::Font
& rFont
)
107 { mupFont
.reset( new vcl::Font(rFont
) ); }
110 : meFlags( PushFlags::NONE
)
112 , mnRegionClipPathId( 0 )
115 PartialState(PartialState
&& aPartialState
) noexcept
116 : meFlags( aPartialState
.meFlags
)
117 , mupFont( std::move( aPartialState
.mupFont
) )
118 , mnRegionClipPathId( aPartialState
.mnRegionClipPathId
)
120 aPartialState
.meFlags
= PushFlags::NONE
;
121 aPartialState
.mnRegionClipPathId
= 0;
126 // - SVGContextHandler -
128 class SVGContextHandler
131 ::std::stack
<PartialState
> maStateStack
;
132 SVGState maCurrentState
;
135 PushFlags
getPushFlags() const;
136 SVGState
& getCurrentState();
137 void pushState( PushFlags eFlags
);
142 // - SVGAttributeWriter -
144 class SVGActionWriter
;
149 class SVGAttributeWriter final
154 SVGFontExport
& mrFontExport
;
155 SVGState
& mrCurrentState
;
156 std::unique_ptr
<SvXMLElementExport
> mpElemFont
;
159 static double ImplRound( double fVal
);
163 SVGAttributeWriter( SVGExport
& rExport
, SVGFontExport
& rFontExport
, SVGState
& rCurState
);
164 ~SVGAttributeWriter();
166 void AddColorAttr( const char* pColorAttrName
, const char* pColorOpacityAttrName
, const Color
& rColor
);
167 void AddGradientDef( const tools::Rectangle
& rObjRect
,const Gradient
& rGradient
, OUString
& rGradientId
);
168 void AddPaintAttr( const Color
& rLineColor
, const Color
& rFillColor
,
169 const tools::Rectangle
* pObjBoundRect
= nullptr, const Gradient
* pFillGradient
= nullptr );
171 void SetFontAttr( const vcl::Font
& rFont
);
172 void startFontSettings();
173 void endFontSettings();
174 void setFontFamily();
176 static void ImplGetColorStr( const Color
& rColor
, OUString
& rColorStr
);
179 struct SVGShapeDescriptor
181 tools::PolyPolygon maShapePolyPoly
;
182 Color maShapeFillColor
;
183 Color maShapeLineColor
;
184 sal_Int32 mnStrokeWidth
;
185 SvtGraphicStroke::DashArray maDashArray
;
186 ::std::unique_ptr
< Gradient
> mapShapeGradient
;
188 basegfx::B2DLineJoin maLineJoin
;
189 css::drawing::LineCap maLineCap
;
192 SVGShapeDescriptor() :
193 maShapeFillColor( COL_TRANSPARENT
),
194 maShapeLineColor( COL_TRANSPARENT
),
196 maLineJoin(basegfx::B2DLineJoin::Miter
), // miter is Svg 'stroke-linejoin' default
197 maLineCap(css::drawing::LineCap_BUTT
) // butt is Svg 'stroke-linecap' default
203 class SVGAttributeWriter
;
208 struct BulletListItemInfo
213 sal_Unicode cBulletChar
;
217 class SVGTextWriter final
220 typedef std::unordered_map
< OUString
, BulletListItemInfo
> BulletListItemInfoMap
;
224 SVGAttributeWriter
& mrAttributeWriter
;
225 VclPtr
<VirtualDevice
> mpVDev
;
226 bool mbIsTextShapeStarted
;
227 Reference
<XText
> mrTextShape
;
229 Reference
<XEnumeration
> mrParagraphEnumeration
;
230 Reference
<XTextContent
> mrCurrentTextParagraph
;
231 Reference
<XEnumeration
> mrTextPortionEnumeration
;
232 Reference
<XTextRange
> mrCurrentTextPortion
;
233 const GDIMetaFile
* mpTextEmbeddedBitmapMtf
;
234 MapMode
* mpTargetMapMode
;
235 std::unique_ptr
<SvXMLElementExport
> mpTextShapeElem
;
236 std::unique_ptr
<SvXMLElementExport
> mpTextParagraphElem
;
237 std::unique_ptr
<SvXMLElementExport
> mpTextPositionElem
;
238 sal_Int32 mnLeftTextPortionLength
;
240 long int mnTextWidth
;
241 bool mbPositioningNeeded
;
242 bool mbIsNewListItem
;
243 sal_Int16 meNumberingType
;
244 sal_Unicode mcBulletChar
;
245 BulletListItemInfoMap maBulletListItemMap
;
246 bool mbIsListLevelStyleImage
;
250 OUString msHyperlinkIdList
;
251 bool mbIsPlaceholderShape
;
252 static const bool mbIWS
= false;
253 vcl::Font maCurrentFont
;
254 vcl::Font maParentFont
;
257 explicit SVGTextWriter( SVGExport
& rExport
, SVGAttributeWriter
& rAttributeWriter
);
260 sal_Int32
setTextPosition( const GDIMetaFile
& rMtf
, sal_uLong
& nCurAction
);
261 void setTextProperties( const GDIMetaFile
& rMtf
, sal_uLong nCurAction
);
262 void addFontAttributes( bool bIsTextContainer
);
264 void createParagraphEnumeration();
265 bool nextParagraph();
266 bool nextTextPortion();
268 bool isTextShapeStarted() const { return mbIsTextShapeStarted
; }
269 void startTextShape();
271 void startTextParagraph();
272 void endTextParagraph();
273 void startTextPosition( bool bExportX
= true, bool bExportY
= true);
274 void endTextPosition();
275 void implExportHyperlinkIds();
276 void implWriteBulletChars();
277 template< typename MetaBitmapActionType
>
278 void writeBitmapPlaceholder( const MetaBitmapActionType
* pAction
);
279 void implWriteEmbeddedBitmaps();
280 void writeTextPortion( const Point
& rPos
, const OUString
& rText
);
281 void implWriteTextPortion( const Point
& rPos
, const OUString
& rText
,
284 void setVirtualDevice( VirtualDevice
* pVDev
, MapMode
& rTargetMapMode
)
287 OSL_FAIL( "SVGTextWriter::setVirtualDevice: invalid virtual device." );
289 mpTargetMapMode
= &rTargetMapMode
;
292 void setTextShape( const Reference
<XText
>& rxText
,
293 const GDIMetaFile
* pTextEmbeddedBitmapMtf
)
295 mrTextShape
.set( rxText
);
296 mpTextEmbeddedBitmapMtf
= pTextEmbeddedBitmapMtf
;
300 void implMap( const Size
& rSz
, Size
& rDstSz
) const;
301 void implMap( const Point
& rPt
, Point
& rDstPt
) const;
302 void implSetCurrentFont();
303 void implSetFontFamily();
305 template< typename SubType
>
306 bool implGetTextPosition( const MetaAction
* pAction
, Point
& raPos
, bool& bEmpty
);
307 template< typename SubType
>
308 bool implGetTextPositionFromBitmap( const MetaAction
* pAction
, Point
& raPos
, bool& rbEmpty
);
310 void implRegisterInterface( const Reference
< XInterface
>& rxIf
);
311 const OUString
& implGetValidIDFromInterface( const Reference
< XInterface
>& rxIf
);
315 class SVGActionWriter final
319 sal_Int32 mnCurGradientId
;
320 sal_Int32 mnCurMaskId
;
321 sal_Int32 mnCurPatternId
;
322 sal_Int32 mnCurClipPathId
;
323 ::std::unique_ptr
< SvXMLElementExport
> mpCurrentClipRegionElem
;
324 ::std::unique_ptr
< SVGShapeDescriptor
> mapCurShape
;
326 SVGContextHandler maContextHandler
;
327 SVGState
& mrCurrentState
;
328 SVGAttributeWriter maAttributeWriter
;
329 SVGTextWriter maTextWriter
;
330 VclPtr
<VirtualDevice
> mpVDev
;
331 MapMode maTargetMapMode
;
332 bool mbClipAttrChanged
;
333 bool mbIsPlaceholderShape
;
336 long ImplMap( sal_Int32 nVal
) const;
337 Point
& ImplMap( const Point
& rPt
, Point
& rDstPt
) const;
338 Size
& ImplMap( const Size
& rSz
, Size
& rDstSz
) const;
339 void ImplMap( const tools::Rectangle
& rRect
, tools::Rectangle
& rDstRect
) const;
340 tools::Polygon
& ImplMap( const tools::Polygon
& rPoly
, tools::Polygon
& rDstPoly
) const;
341 tools::PolyPolygon
& ImplMap( const tools::PolyPolygon
& rPolyPoly
, tools::PolyPolygon
& rDstPolyPoly
) const;
343 void ImplWriteLine( const Point
& rPt1
, const Point
& rPt2
, const Color
* pLineColor
= nullptr );
344 void ImplWriteRect( const tools::Rectangle
& rRect
, long nRadX
= 0, long nRadY
= 0 );
345 void ImplWriteEllipse( const Point
& rCenter
, long nRadX
, long nRadY
);
346 void ImplWritePattern( const tools::PolyPolygon
& rPolyPoly
, const Hatch
* pHatch
, const Gradient
* pGradient
, sal_uInt32 nWriteFlags
);
347 void ImplAddLineAttr( const LineInfo
&rAttrs
);
348 void ImplWritePolyPolygon( const tools::PolyPolygon
& rPolyPoly
, bool bLineOnly
,
349 bool bApplyMapping
= true );
350 void ImplWriteShape( const SVGShapeDescriptor
& rShape
);
351 void ImplCreateClipPathDef( const tools::PolyPolygon
& rPolyPoly
);
352 void ImplStartClipRegion(sal_Int32 nClipPathId
);
353 void ImplEndClipRegion();
354 void ImplWriteClipPath( const tools::PolyPolygon
& rPolyPoly
);
355 void ImplWriteGradientEx( const tools::PolyPolygon
& rPolyPoly
, const Gradient
& rGradient
, sal_uInt32 nWriteFlags
);
356 void ImplWriteGradientLinear( const tools::PolyPolygon
& rPolyPoly
, const Gradient
& rGradient
);
357 void ImplWriteGradientStop( const Color
& rColor
, double fOffset
);
358 static Color
ImplGetColorWithIntensity( const Color
& rColor
, sal_uInt16 nIntensity
);
359 static Color
ImplGetGradientColor( const Color
& rStartColor
, const Color
& rEndColor
, double fOffset
);
360 void ImplWriteMask( GDIMetaFile
& rMtf
, const Point
& rDestPt
, const Size
& rDestSize
, const Gradient
& rGradient
, sal_uInt32 nWriteFlags
);
361 void ImplWriteText( const Point
& rPos
, const OUString
& rText
, const long* pDXArray
, long nWidth
);
362 void ImplWriteText( const Point
& rPos
, const OUString
& rText
, const long* pDXArray
, long nWidth
, Color aTextColor
);
363 void ImplWriteBmp( const BitmapEx
& rBmpEx
, const Point
& rPt
, const Size
& rSz
, const Point
& rSrcPt
, const Size
& rSrcSz
);
365 void ImplWriteActions( const GDIMetaFile
& rMtf
,
366 sal_uInt32 nWriteFlags
,
367 const OUString
* pElementId
,
368 const Reference
< css::drawing::XShape
>* pXShape
= nullptr,
369 const GDIMetaFile
* pTextEmbeddedBitmapMtf
= nullptr );
371 vcl::Font
ImplSetCorrectFontHeight() const;
375 static OUString
GetPathString( const tools::PolyPolygon
& rPolyPoly
, bool bLine
);
376 static BitmapChecksum
GetChecksum( const MetaAction
* pAction
);
379 SVGActionWriter( SVGExport
& rExport
, SVGFontExport
& rFontExport
);
382 void WriteMetaFile( const Point
& rPos100thmm
,
383 const Size
& rSize100thmm
,
384 const GDIMetaFile
& rMtf
,
385 sal_uInt32 nWriteFlags
,
386 const OUString
* pElementId
= nullptr,
387 const Reference
< css::drawing::XShape
>* pXShape
= nullptr,
388 const GDIMetaFile
* pTextEmbeddedBitmapMtf
= nullptr );
392 class SVGWriter
: public cppu::WeakImplHelper
< XSVGWriter
>
395 Reference
< XComponentContext
> mxContext
;
396 Sequence
< css::beans::PropertyValue
> maFilterData
;
399 explicit SVGWriter( const Sequence
<Any
>& args
,
400 const Reference
< XComponentContext
>& rxCtx
);
401 virtual ~SVGWriter() override
;
404 virtual void SAL_CALL
write( const Reference
<XDocumentHandler
>& rxDocHandler
,
405 const Sequence
<sal_Int8
>& rMtfSeq
) override
;
408 #endif // INCLUDED_FILTER_SOURCE_SVG_SVGWRITER_HXX
410 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */