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/implbase1.hxx>
24 #include <rtl/ustring.hxx>
25 #include <tools/stream.hxx>
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>
62 #include <unordered_map>
64 using namespace ::com::sun::star::uno
;
65 using namespace ::com::sun::star::container
;
66 using namespace ::com::sun::star::lang
;
67 using namespace ::com::sun::star::text
;
68 using namespace ::com::sun::star::drawing
;
69 using namespace ::com::sun::star::style
;
70 using namespace ::com::sun::star::svg
;
71 using namespace ::com::sun::star::xml::sax
;
75 #define SVG_DTD_STRING "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">"
77 #define SVGWRITER_WRITE_FILL 0x00000001
78 #define SVGWRITER_WRITE_TEXT 0x00000002
79 #define SVGWRITER_NO_SHAPE_COMMENTS 0x01000000
82 // - SVGAttributeWriter -
85 class SVGActionWriter
;
89 class SVGAttributeWriter
97 SVGFontExport
& mrFontExport
;
98 SvXMLElementExport
* mpElemFont
;
99 SvXMLElementExport
* mpElemPaint
;
101 basegfx::B2DLineJoin maLineJoin
;
102 com::sun::star::drawing::LineCap maLineCap
;
104 SVGAttributeWriter();
106 static double ImplRound( double fVal
, sal_Int32 nDecs
= 3 );
110 SVGAttributeWriter( SVGExport
& rExport
, SVGFontExport
& rFontExport
);
111 virtual ~SVGAttributeWriter();
113 void AddColorAttr( const char* pColorAttrName
, const char* pColorOpacityAttrName
, const Color
& rColor
);
114 void AddGradientDef( const Rectangle
& rObjRect
,const Gradient
& rGradient
, OUString
& rGradientId
);
115 void AddPaintAttr( const Color
& rLineColor
, const Color
& rFillColor
,
116 const Rectangle
* pObjBoundRect
= NULL
, const Gradient
* pFillGradient
= NULL
);
118 void SetFontAttr( const vcl::Font
& rFont
);
119 void startFontSettings();
120 void endFontSettings();
121 void setFontFamily();
123 static void ImplGetColorStr( const Color
& rColor
, OUString
& rColorStr
);
126 struct SVGShapeDescriptor
128 tools::PolyPolygon maShapePolyPoly
;
129 Color maShapeFillColor
;
130 Color maShapeLineColor
;
131 sal_Int32 mnStrokeWidth
;
132 SvtGraphicStroke::DashArray maDashArray
;
133 ::std::unique_ptr
< Gradient
> mapShapeGradient
;
136 basegfx::B2DLineJoin maLineJoin
;
137 com::sun::star::drawing::LineCap maLineCap
;
141 SVGShapeDescriptor() :
142 maShapeFillColor( Color( COL_TRANSPARENT
) ),
143 maShapeLineColor( Color( COL_TRANSPARENT
) ),
145 maLineJoin(basegfx::B2DLINEJOIN_MITER
), // miter is Svg 'stroke-linejoin' default
146 maLineCap(com::sun::star::drawing::LineCap_BUTT
) // butt is Svg 'stroke-linecap' default
153 class SVGAttributeWriter
;
159 // - BulletListItemInfo -
161 struct BulletListItemInfo
166 sal_Unicode cBulletChar
;
176 typedef std::unordered_map
< OUString
, BulletListItemInfo
, OUStringHash
> BulletListItemInfoMap
;
180 SVGAttributeWriter
* mpContext
;
181 VclPtr
<VirtualDevice
> mpVDev
;
182 bool mbIsTextShapeStarted
;
183 Reference
<XText
> mrTextShape
;
185 Reference
<XEnumeration
> mrParagraphEnumeration
;
186 Reference
<XTextContent
> mrCurrentTextParagraph
;
187 Reference
<XEnumeration
> mrTextPortionEnumeration
;
188 Reference
<XTextRange
> mrCurrentTextPortion
;
189 const GDIMetaFile
* mpTextEmbeddedBitmapMtf
;
190 MapMode
* mpTargetMapMode
;
191 SvXMLElementExport
* mpTextShapeElem
;
192 SvXMLElementExport
* mpTextParagraphElem
;
193 SvXMLElementExport
* mpTextPositionElem
;
194 sal_Int32 mnLeftTextPortionLength
;
196 long int mnTextWidth
;
197 bool mbPositioningNeeded
;
198 bool mbIsNewListItem
;
199 sal_Int16 meNumberingType
;
200 sal_Unicode mcBulletChar
;
201 BulletListItemInfoMap maBulletListItemMap
;
202 bool mbIsListLevelStyleImage
;
206 OUString msHyperlinkIdList
;
207 bool mbIsPlaceholderShape
;
209 vcl::Font maCurrentFont
;
210 vcl::Font maParentFont
;
213 SVGTextWriter( SVGExport
& rExport
);
214 virtual ~SVGTextWriter();
216 sal_Int32
setTextPosition( const GDIMetaFile
& rMtf
, sal_uLong
& nCurAction
);
217 void setTextProperties( const GDIMetaFile
& rMtf
, sal_uLong nCurAction
);
218 void addFontAttributes( bool bIsTextContainer
);
220 bool createParagraphEnumeration();
221 bool nextParagraph();
222 bool nextTextPortion();
224 bool isTextShapeStarted() { return mbIsTextShapeStarted
; }
225 void startTextShape();
227 void startTextParagraph();
228 void endTextParagraph();
229 void startTextPosition( bool bExportX
= true, bool bExportY
= true);
230 void endTextPosition();
231 void implExportHyperlinkIds();
232 void implWriteBulletChars();
233 template< typename MetaBitmapActionType
>
234 void writeBitmapPlaceholder( const MetaBitmapActionType
* pAction
);
235 void implWriteEmbeddedBitmaps();
236 void writeTextPortion( const Point
& rPos
, const OUString
& rText
,
237 bool bApplyMapping
= true );
238 void implWriteTextPortion( const Point
& rPos
, const OUString
& rText
,
239 Color aTextColor
, bool bApplyMapping
);
241 void setVirtualDevice( VirtualDevice
* pVDev
, MapMode
& rTargetMapMode
)
244 OSL_FAIL( "SVGTextWriter::setVirtualDevice: invalid virtual device." );
246 mpTargetMapMode
= &rTargetMapMode
;
249 void setContext( SVGAttributeWriter
* pContext
)
251 mpContext
= pContext
;
254 void setTextShape( const Reference
<XText
>& rxText
,
255 const GDIMetaFile
* pTextEmbeddedBitmapMtf
)
257 mrTextShape
.set( rxText
);
258 mpTextEmbeddedBitmapMtf
= pTextEmbeddedBitmapMtf
;
261 const Reference
<XText
>& getTextShape() const
267 void setPlaceholderShapeFlag( bool bState
)
269 mbIsPlaceholderShape
= bState
;
273 void implMap( const Size
& rSz
, Size
& rDstSz
) const;
274 void implMap( const Point
& rPt
, Point
& rDstPt
) const;
275 void implSetCurrentFont();
276 void implSetFontFamily();
278 template< typename SubType
>
279 bool implGetTextPosition( const MetaAction
* pAction
, Point
& raPos
, bool& bEmpty
);
280 template< typename SubType
>
281 bool implGetTextPositionFromBitmap( const MetaAction
* pAction
, Point
& raPos
, bool& rbEmpty
);
283 void implRegisterInterface( const Reference
< XInterface
>& rxIf
);
284 const OUString
& implGetValidIDFromInterface( const Reference
< XInterface
>& rxIf
);
290 // - SVGActionWriter -
293 class SVGActionWriter
297 sal_Int32 mnCurGradientId
;
298 sal_Int32 mnCurMaskId
;
299 sal_Int32 mnCurPatternId
;
300 ::std::stack
< SVGAttributeWriter
* > maContextStack
;
301 ::std::unique_ptr
< SVGShapeDescriptor
> mapCurShape
;
303 SVGFontExport
& mrFontExport
;
304 SVGAttributeWriter
* mpContext
;
305 SVGTextWriter maTextWriter
;
306 VclPtr
<VirtualDevice
> mpVDev
;
307 MapMode maTargetMapMode
;
308 sal_uInt32 mnInnerMtfCount
;
309 bool mbClipAttrChanged
;
310 bool mbIsPlaceholderShape
;
313 SVGAttributeWriter
* ImplAcquireContext()
315 maContextStack
.push( mpContext
= new SVGAttributeWriter( mrExport
, mrFontExport
) );
316 maTextWriter
.setContext( mpContext
);
319 void ImplReleaseContext()
321 if (!maContextStack
.empty())
323 delete maContextStack
.top();
324 maContextStack
.pop();
326 mpContext
= (maContextStack
.empty() ? NULL
: maContextStack
.top());
327 maTextWriter
.setContext( mpContext
);
330 long ImplMap( sal_Int32 nVal
) const;
331 Point
& ImplMap( const Point
& rPt
, Point
& rDstPt
) const;
332 Size
& ImplMap( const Size
& rSz
, Size
& rDstSz
) const;
333 Rectangle
& ImplMap( const Rectangle
& rRect
, Rectangle
& rDstRect
) const;
334 Polygon
& ImplMap( const Polygon
& rPoly
, Polygon
& rDstPoly
) const;
335 tools::PolyPolygon
& ImplMap( const tools::PolyPolygon
& rPolyPoly
, tools::PolyPolygon
& rDstPolyPoly
) const;
337 void ImplWriteLine( const Point
& rPt1
, const Point
& rPt2
, const Color
* pLineColor
= NULL
,
338 bool bApplyMapping
= true );
339 void ImplWriteRect( const Rectangle
& rRect
, long nRadX
= 0, long nRadY
= 0,
340 bool bApplyMapping
= true );
341 void ImplWriteEllipse( const Point
& rCenter
, long nRadX
, long nRadY
,
342 bool bApplyMapping
= true );
343 void ImplWritePattern( const tools::PolyPolygon
& rPolyPoly
, const Hatch
* pHatch
, const Gradient
* pGradient
, sal_uInt32 nWriteFlags
);
344 void ImplAddLineAttr( const LineInfo
&rAttrs
,
345 bool bApplyMapping
= true );
346 void ImplWritePolyPolygon( const tools::PolyPolygon
& rPolyPoly
, bool bLineOnly
,
347 bool bApplyMapping
= true );
348 void ImplWriteShape( const SVGShapeDescriptor
& rShape
, bool bApplyMapping
= true );
349 void ImplWriteGradientEx( const tools::PolyPolygon
& rPolyPoly
, const Gradient
& rGradient
, sal_uInt32 nWriteFlags
);
350 void ImplWriteGradientLinear( const tools::PolyPolygon
& rPolyPoly
, const Gradient
& rGradient
);
351 void ImplWriteGradientStop( const Color
& rColor
, double fOffset
);
352 static Color
ImplGetColorWithIntensity( const Color
& rColor
, sal_uInt16 nIntensity
);
353 static Color
ImplGetGradientColor( const Color
& rStartColor
, const Color
& rEndColor
, double fOffset
);
354 void ImplWriteMask( GDIMetaFile
& rMtf
, const Point
& rDestPt
, const Size
& rDestSize
, const Gradient
& rGradient
, sal_uInt32 nWriteFlags
);
355 void ImplWriteText( const Point
& rPos
, const OUString
& rText
, const long* pDXArray
, long nWidth
, bool bApplyMapping
= true );
356 void ImplWriteText( const Point
& rPos
, const OUString
& rText
, const long* pDXArray
, long nWidth
, Color aTextColor
, bool bApplyMapping
);
357 void ImplWriteBmp( const BitmapEx
& rBmpEx
, const Point
& rPt
, const Size
& rSz
, const Point
& rSrcPt
, const Size
& rSrcSz
,
358 bool bApplyMapping
= true );
360 void ImplCheckFontAttributes();
361 void ImplCheckPaintAttributes();
363 void ImplWriteActions( const GDIMetaFile
& rMtf
,
364 sal_uInt32 nWriteFlags
,
365 const OUString
* pElementId
,
366 const Reference
< XShape
>* pXShape
= NULL
,
367 const GDIMetaFile
* pTextEmbeddedBitmapMtf
= NULL
);
369 vcl::Font
ImplSetCorrectFontHeight() const;
373 static OUString
GetPathString( const tools::PolyPolygon
& rPolyPoly
, bool bLine
);
374 static BitmapChecksum
GetChecksum( const MetaAction
* pAction
);
378 SVGActionWriter( SVGExport
& rExport
, SVGFontExport
& rFontExport
);
379 virtual ~SVGActionWriter();
381 void WriteMetaFile( const Point
& rPos100thmm
,
382 const Size
& rSize100thmm
,
383 const GDIMetaFile
& rMtf
,
384 sal_uInt32 nWriteFlags
,
385 const OUString
* pElementId
= NULL
,
386 const Reference
< XShape
>* pXShape
= NULL
,
387 const GDIMetaFile
* pTextEmbeddedBitmapMtf
= NULL
);
390 class SVGWriter
: public cppu::WeakImplHelper1
< XSVGWriter
>
393 Reference
< XComponentContext
> mxContext
;
394 Sequence
< com::sun::star::beans::PropertyValue
> maFilterData
;
398 explicit SVGWriter( const Sequence
<Any
>& args
,
399 const Reference
< XComponentContext
>& rxCtx
);
400 virtual ~SVGWriter();
403 virtual void SAL_CALL
write( const Reference
<XDocumentHandler
>& rxDocHandler
,
404 const Sequence
<sal_Int8
>& rMtfSeq
) throw( RuntimeException
, std::exception
) SAL_OVERRIDE
;
409 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */