Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / filter / source / svg / svgwriter.hxx
blobf0271ed4090b451bfbc74079f53cd7d114a70e95
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
61 #include <memory>
62 #include <stack>
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
81 struct SVGState
83 vcl::Font aFont;
84 // Color aLineColor;
85 // Color aFillColor;
86 // basegfx::B2DLineJoin aLineJoin;
87 // com::sun::star::drawing::LineCap aLineCap;
88 sal_Int32 nRegionClipPathId;
90 SVGState()
91 : aFont()
92 , nRegionClipPathId( 0 )
95 // - PartialState -
97 struct PartialState
99 PushFlags meFlags;
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) ); }
109 PartialState()
110 : meFlags( PushFlags::NONE )
111 , mupFont()
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
130 private:
131 ::std::stack<PartialState> maStateStack;
132 SVGState maCurrentState;
134 public:
135 PushFlags getPushFlags() const;
136 SVGState& getCurrentState();
137 void pushState( PushFlags eFlags );
138 void popState();
142 // - SVGAttributeWriter -
144 class SVGActionWriter;
145 class SVGExport;
146 class SVGFontExport;
149 class SVGAttributeWriter final
151 private:
153 SVGExport& mrExport;
154 SVGFontExport& mrFontExport;
155 SVGState& mrCurrentState;
156 std::unique_ptr<SvXMLElementExport> mpElemFont;
159 static double ImplRound( double fVal );
161 public:
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;
187 OUString maId;
188 basegfx::B2DLineJoin maLineJoin;
189 css::drawing::LineCap maLineCap;
192 SVGShapeDescriptor() :
193 maShapeFillColor( COL_TRANSPARENT ),
194 maShapeLineColor( COL_TRANSPARENT ),
195 mnStrokeWidth( 0 ),
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;
204 class SVGExport;
205 class GDIMetaFile;
208 struct BulletListItemInfo
210 long nFontSize;
211 Color aColor;
212 Point aPos;
213 sal_Unicode cBulletChar;
217 class SVGTextWriter final
219 public:
220 typedef std::unordered_map< OUString, BulletListItemInfo > BulletListItemInfoMap;
222 private:
223 SVGExport& mrExport;
224 SVGAttributeWriter& mrAttributeWriter;
225 VclPtr<VirtualDevice> mpVDev;
226 bool mbIsTextShapeStarted;
227 Reference<XText> mrTextShape;
228 OUString msShapeId;
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;
239 Point maTextPos;
240 long int mnTextWidth;
241 bool mbPositioningNeeded;
242 bool mbIsNewListItem;
243 sal_Int16 meNumberingType;
244 sal_Unicode mcBulletChar;
245 BulletListItemInfoMap maBulletListItemMap;
246 bool mbIsListLevelStyleImage;
247 bool mbLineBreak;
248 bool mbIsURLField;
249 OUString msUrl;
250 OUString msHyperlinkIdList;
251 bool mbIsPlaceholderShape;
252 static const bool mbIWS = false;
253 vcl::Font maCurrentFont;
254 vcl::Font maParentFont;
256 public:
257 explicit SVGTextWriter( SVGExport& rExport, SVGAttributeWriter& rAttributeWriter );
258 ~SVGTextWriter();
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();
270 void endTextShape();
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,
282 Color aTextColor );
284 void setVirtualDevice( VirtualDevice* pVDev, MapMode& rTargetMapMode )
286 if( !pVDev )
287 OSL_FAIL( "SVGTextWriter::setVirtualDevice: invalid virtual device." );
288 mpVDev = pVDev;
289 mpTargetMapMode = &rTargetMapMode;
292 void setTextShape( const Reference<XText>& rxText,
293 const GDIMetaFile* pTextEmbeddedBitmapMtf )
295 mrTextShape.set( rxText );
296 mpTextEmbeddedBitmapMtf = pTextEmbeddedBitmapMtf;
299 private:
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
317 private:
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;
325 SVGExport& mrExport;
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;
373 public:
375 static OUString GetPathString( const tools::PolyPolygon& rPolyPoly, bool bLine );
376 static BitmapChecksum GetChecksum( const MetaAction* pAction );
378 public:
379 SVGActionWriter( SVGExport& rExport, SVGFontExport& rFontExport );
380 ~SVGActionWriter();
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 >
394 private:
395 Reference< XComponentContext > mxContext;
396 Sequence< css::beans::PropertyValue > maFilterData;
398 public:
399 explicit SVGWriter( const Sequence<Any>& args,
400 const Reference< XComponentContext >& rxCtx );
401 virtual ~SVGWriter() override;
403 // XSVGWriter
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: */