Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #ifndef INCLUDED_FILTER_SOURCE_SVG_SVGWRITER_HXX
21 : #define INCLUDED_FILTER_SOURCE_SVG_SVGWRITER_HXX
22 :
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>
34 :
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>
60 :
61 : #include <stack>
62 : #include <unordered_map>
63 :
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;
72 :
73 :
74 :
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\">"
76 :
77 : #define SVGWRITER_WRITE_FILL 0x00000001
78 : #define SVGWRITER_WRITE_TEXT 0x00000002
79 : #define SVGWRITER_NO_SHAPE_COMMENTS 0x01000000
80 :
81 :
82 : // - SVGAttributeWriter -
83 :
84 :
85 : class SVGActionWriter;
86 : class SVGExport;
87 : class SVGFontExport;
88 :
89 : class SVGAttributeWriter
90 : {
91 : private:
92 :
93 : vcl::Font maCurFont;
94 : Color maCurLineColor;
95 : Color maCurFillColor;
96 : SVGExport& mrExport;
97 : SVGFontExport& mrFontExport;
98 : SvXMLElementExport* mpElemFont;
99 : SvXMLElementExport* mpElemPaint;
100 :
101 : basegfx::B2DLineJoin maLineJoin;
102 : com::sun::star::drawing::LineCap maLineCap;
103 :
104 : SVGAttributeWriter();
105 :
106 : static double ImplRound( double fVal, sal_Int32 nDecs = 3 );
107 :
108 : public:
109 :
110 : SVGAttributeWriter( SVGExport& rExport, SVGFontExport& rFontExport );
111 : virtual ~SVGAttributeWriter();
112 :
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 );
117 :
118 : void SetFontAttr( const vcl::Font& rFont );
119 : void startFontSettings();
120 : void endFontSettings();
121 : void setFontFamily();
122 :
123 : static void ImplGetColorStr( const Color& rColor, OUString& rColorStr );
124 : };
125 :
126 0 : struct SVGShapeDescriptor
127 : {
128 : tools::PolyPolygon maShapePolyPoly;
129 : Color maShapeFillColor;
130 : Color maShapeLineColor;
131 : sal_Int32 mnStrokeWidth;
132 : SvtGraphicStroke::DashArray maDashArray;
133 : ::std::unique_ptr< Gradient > mapShapeGradient;
134 : OUString maId;
135 :
136 : basegfx::B2DLineJoin maLineJoin;
137 : com::sun::star::drawing::LineCap maLineCap;
138 :
139 :
140 :
141 0 : SVGShapeDescriptor() :
142 : maShapeFillColor( Color( COL_TRANSPARENT ) ),
143 : maShapeLineColor( Color( COL_TRANSPARENT ) ),
144 : mnStrokeWidth( 0 ),
145 : maLineJoin(basegfx::B2DLineJoin::Miter), // miter is Svg 'stroke-linejoin' default
146 0 : maLineCap(com::sun::star::drawing::LineCap_BUTT) // butt is Svg 'stroke-linecap' default
147 : {
148 0 : }
149 : };
150 :
151 :
152 :
153 : class SVGAttributeWriter;
154 : class SVGExport;
155 : class GDIMetaFile;
156 :
157 :
158 :
159 : // - BulletListItemInfo -
160 :
161 0 : struct BulletListItemInfo
162 : {
163 : long nFontSize;
164 : Color aColor;
165 : Point aPos;
166 : sal_Unicode cBulletChar;
167 : };
168 :
169 :
170 :
171 : // - SVGTextWriter -
172 :
173 : class SVGTextWriter
174 : {
175 : public:
176 : typedef std::unordered_map< OUString, BulletListItemInfo, OUStringHash > BulletListItemInfoMap;
177 :
178 : private:
179 : SVGExport& mrExport;
180 : SVGAttributeWriter* mpContext;
181 : VclPtr<VirtualDevice> mpVDev;
182 : bool mbIsTextShapeStarted;
183 : Reference<XText> mrTextShape;
184 : OUString msShapeId;
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;
195 : Point maTextPos;
196 : long int mnTextWidth;
197 : bool mbPositioningNeeded;
198 : bool mbIsNewListItem;
199 : sal_Int16 meNumberingType;
200 : sal_Unicode mcBulletChar;
201 : BulletListItemInfoMap maBulletListItemMap;
202 : bool mbIsListLevelStyleImage;
203 : bool mbLineBreak;
204 : bool mbIsURLField;
205 : OUString msUrl;
206 : OUString msHyperlinkIdList;
207 : bool mbIsPlaceholderShape;
208 : bool mbIWS;
209 : vcl::Font maCurrentFont;
210 : vcl::Font maParentFont;
211 :
212 : public:
213 : SVGTextWriter( SVGExport& rExport );
214 : virtual ~SVGTextWriter();
215 :
216 : sal_Int32 setTextPosition( const GDIMetaFile& rMtf, sal_uLong& nCurAction );
217 : void setTextProperties( const GDIMetaFile& rMtf, sal_uLong nCurAction );
218 : void addFontAttributes( bool bIsTextContainer );
219 :
220 : bool createParagraphEnumeration();
221 : bool nextParagraph();
222 : bool nextTextPortion();
223 :
224 0 : bool isTextShapeStarted() { return mbIsTextShapeStarted; }
225 : void startTextShape();
226 : void endTextShape();
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 );
240 :
241 0 : void setVirtualDevice( VirtualDevice* pVDev, MapMode& rTargetMapMode )
242 : {
243 : if( !pVDev )
244 : OSL_FAIL( "SVGTextWriter::setVirtualDevice: invalid virtual device." );
245 0 : mpVDev = pVDev;
246 0 : mpTargetMapMode = &rTargetMapMode;
247 0 : }
248 :
249 0 : void setContext( SVGAttributeWriter* pContext )
250 : {
251 0 : mpContext = pContext;
252 0 : }
253 :
254 0 : void setTextShape( const Reference<XText>& rxText,
255 : const GDIMetaFile* pTextEmbeddedBitmapMtf )
256 : {
257 0 : mrTextShape.set( rxText );
258 0 : mpTextEmbeddedBitmapMtf = pTextEmbeddedBitmapMtf;
259 0 : }
260 :
261 : const Reference<XText>& getTextShape() const
262 : {
263 : return mrTextShape;
264 : }
265 :
266 :
267 : void setPlaceholderShapeFlag( bool bState )
268 : {
269 : mbIsPlaceholderShape = bState;
270 : }
271 :
272 : private:
273 : void implMap( const Size& rSz, Size& rDstSz ) const;
274 : void implMap( const Point& rPt, Point& rDstPt ) const;
275 : void implSetCurrentFont();
276 : void implSetFontFamily();
277 :
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 );
282 :
283 : void implRegisterInterface( const Reference< XInterface >& rxIf );
284 : const OUString & implGetValidIDFromInterface( const Reference< XInterface >& rxIf );
285 :
286 :
287 : };
288 :
289 :
290 : // - SVGActionWriter -
291 :
292 :
293 : class SVGActionWriter
294 : {
295 : private:
296 :
297 : sal_Int32 mnCurGradientId;
298 : sal_Int32 mnCurMaskId;
299 : sal_Int32 mnCurPatternId;
300 : ::std::stack< SVGAttributeWriter* > maContextStack;
301 : ::std::unique_ptr< SVGShapeDescriptor > mapCurShape;
302 : SVGExport& mrExport;
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;
311 :
312 :
313 0 : SVGAttributeWriter* ImplAcquireContext()
314 : {
315 0 : maContextStack.push( mpContext = new SVGAttributeWriter( mrExport, mrFontExport ) );
316 0 : maTextWriter.setContext( mpContext );
317 0 : return mpContext;
318 : }
319 0 : void ImplReleaseContext()
320 : {
321 0 : if (!maContextStack.empty())
322 : {
323 0 : delete maContextStack.top();
324 0 : maContextStack.pop();
325 : }
326 0 : mpContext = (maContextStack.empty() ? NULL : maContextStack.top());
327 0 : maTextWriter.setContext( mpContext );
328 0 : }
329 :
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;
336 :
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 );
359 :
360 : void ImplCheckFontAttributes();
361 : void ImplCheckPaintAttributes();
362 :
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 );
368 :
369 : vcl::Font ImplSetCorrectFontHeight() const;
370 :
371 : public:
372 :
373 : static OUString GetPathString( const tools::PolyPolygon& rPolyPoly, bool bLine );
374 : static sal_uLong GetChecksum( const MetaAction* pAction );
375 :
376 : public:
377 :
378 : SVGActionWriter( SVGExport& rExport, SVGFontExport& rFontExport );
379 : virtual ~SVGActionWriter();
380 :
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 );
388 : };
389 :
390 : class SVGWriter : public cppu::WeakImplHelper1< XSVGWriter >
391 : {
392 : private:
393 : Reference< XComponentContext > mxContext;
394 : Sequence< com::sun::star::beans::PropertyValue > maFilterData;
395 : SVGWriter();
396 :
397 : public:
398 : explicit SVGWriter( const Sequence<Any>& args,
399 : const Reference< XComponentContext >& rxCtx );
400 : virtual ~SVGWriter();
401 :
402 : // XSVGWriter
403 : virtual void SAL_CALL write( const Reference<XDocumentHandler>& rxDocHandler,
404 : const Sequence<sal_Int8>& rMtfSeq ) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
405 : };
406 :
407 : #endif
408 :
409 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|