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 SVGWRITER_HXX
21 : #define SVGWRITER_HXX
22 :
23 : #include <stack>
24 : #include <cppuhelper/weak.hxx>
25 : #include <rtl/ustring.hxx>
26 : #include <tools/stream.hxx>
27 : #include <tools/string.hxx>
28 : #include <vcl/gdimtf.hxx>
29 : #include <vcl/metaact.hxx>
30 : #include <vcl/metric.hxx>
31 : #include <vcl/virdev.hxx>
32 : #include <vcl/cvtgrf.hxx>
33 : #include <vcl/graphictools.hxx>
34 : #include <xmloff/xmlexp.hxx>
35 : #include <xmloff/nmspmap.hxx>
36 :
37 : #include <com/sun/star/uno/Reference.h>
38 : #include <com/sun/star/container/XEnumerationAccess.hpp>
39 : #include <com/sun/star/container/XContentEnumerationAccess.hpp>
40 : #include <com/sun/star/container/XEnumeration.hpp>
41 : #include <com/sun/star/container/XIndexReplace.hpp>
42 : #include <com/sun/star/lang/XServiceInfo.hpp>
43 : #include <com/sun/star/beans/XPropertySet.hpp>
44 : #include <com/sun/star/beans/XPropertySetInfo.hpp>
45 : #include <com/sun/star/uno/RuntimeException.hpp>
46 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 : #include <com/sun/star/lang/XComponent.hpp>
48 : #include <com/sun/star/registry/XRegistryKey.hpp>
49 : #include <com/sun/star/io/XInputStream.hpp>
50 : #include <com/sun/star/io/XOutputStream.hpp>
51 : #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
52 : #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
53 : #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
54 : #include <com/sun/star/i18n/XBreakIterator.hpp>
55 : #include <com/sun/star/drawing/XShape.hpp>
56 : #include <com/sun/star/text/XText.hpp>
57 : #include <com/sun/star/text/XTextContent.hpp>
58 : #include <com/sun/star/text/XTextRange.hpp>
59 : #include <com/sun/star/text/XTextField.hpp>
60 : #include <com/sun/star/style/NumberingType.hpp>
61 :
62 :
63 : // -----------------------------------------------------------------------------
64 :
65 : using namespace ::com::sun::star::uno;
66 : using namespace ::com::sun::star::container;
67 : using namespace ::com::sun::star::lang;
68 : using namespace ::com::sun::star::text;
69 : using namespace ::com::sun::star::drawing;
70 : using namespace ::com::sun::star::style;
71 :
72 : // -----------------------------------------------------------------------------
73 :
74 : #define NMSP_CPPU cppu
75 : #define NMSP_UNO com::sun::star::uno
76 : #define NMSP_LANG com::sun::star::lang
77 : #define NMSP_SAX com::sun::star::xml::sax
78 : #define NMSP_REGISTRY com::sun::star::registry
79 :
80 :
81 : #define REF( _def_Obj ) NMSP_UNO::Reference< _def_Obj >
82 : #define SEQ( _def_Obj ) NMSP_UNO::Sequence< _def_Obj >
83 : #define B2UCONST( _def_pChar ) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(_def_pChar )))
84 : #define SVG_DTD_STRING B2UCONST( "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">" )
85 : #define SVG_TINY_DTD_STRING B2UCONST( "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG Tiny 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd\">" )
86 :
87 : #define SVGWRITER_WRITE_NONE 0x00000000
88 : #define SVGWRITER_WRITE_FILL 0x00000001
89 : #define SVGWRITER_WRITE_TEXT 0x00000002
90 : #define SVGWRITER_NO_SHAPE_COMMENTS 0x01000000
91 :
92 : // ----------------------
93 : // - SVGAttributeWriter -
94 : // ----------------------
95 :
96 : class SVGActionWriter;
97 : class SVGExport;
98 : class SVGFontExport;
99 :
100 : class SVGAttributeWriter
101 : {
102 : private:
103 :
104 : Font maCurFont;
105 : Color maCurLineColor;
106 : Color maCurFillColor;
107 : SVGExport& mrExport;
108 : SVGFontExport& mrFontExport;
109 : SvXMLElementExport* mpElemFont;
110 : SvXMLElementExport* mpElemPaint;
111 :
112 : basegfx::B2DLineJoin maLineJoin;
113 : com::sun::star::drawing::LineCap maLineCap;
114 :
115 : SVGAttributeWriter();
116 :
117 : double ImplRound( double fVal, sal_Int32 nDecs = 3 );
118 :
119 : public:
120 :
121 : SVGAttributeWriter( SVGExport& rExport, SVGFontExport& rFontExport );
122 : virtual ~SVGAttributeWriter();
123 :
124 : void AddColorAttr( const char* pColorAttrName, const char* pColorOpacityAttrName, const Color& rColor );
125 : void AddGradientDef( const Rectangle& rObjRect,const Gradient& rGradient, ::rtl::OUString& rGradientId );
126 : void AddPaintAttr( const Color& rLineColor, const Color& rFillColor,
127 : const Rectangle* pObjBoundRect = NULL, const Gradient* pFillGradient = NULL );
128 :
129 : void SetFontAttr( const Font& rFont );
130 : void startFontSettings();
131 : void endFontSettings();
132 : void setFontFamily();
133 :
134 : static void ImplGetColorStr( const Color& rColor, ::rtl::OUString& rColorStr );
135 : };
136 :
137 0 : struct SVGShapeDescriptor
138 : {
139 : PolyPolygon maShapePolyPoly;
140 : Color maShapeFillColor;
141 : Color maShapeLineColor;
142 : sal_Int32 mnStrokeWidth;
143 : SvtGraphicStroke::DashArray maDashArray;
144 : ::std::auto_ptr< Gradient > mapShapeGradient;
145 : ::rtl::OUString maId;
146 :
147 : basegfx::B2DLineJoin maLineJoin;
148 : com::sun::star::drawing::LineCap maLineCap;
149 :
150 : // -------------------------------------------------------------------------
151 :
152 0 : SVGShapeDescriptor() :
153 : maShapeFillColor( Color( COL_TRANSPARENT ) ),
154 : maShapeLineColor( Color( COL_TRANSPARENT ) ),
155 : mnStrokeWidth( 0 ),
156 : maLineJoin(basegfx::B2DLINEJOIN_MITER), // miter is Svg 'stroke-linejoin' default
157 0 : maLineCap(com::sun::star::drawing::LineCap_BUTT) // butt is Svg 'stroke-linecap' default
158 : {
159 0 : }
160 : };
161 :
162 :
163 :
164 : class SVGAttributeWriter;
165 : class GDIMetaFile;
166 :
167 :
168 : // ---------------------------
169 : // - BulletListItemInfo -
170 : // ---------------------------
171 0 : struct BulletListItemInfo
172 : {
173 : long nFontSize;
174 : Color aColor;
175 : Point aPos;
176 : sal_Unicode cBulletChar;
177 : };
178 :
179 : // ---------------------------
180 : // - OUStringHasher -
181 : // ---------------------------
182 :
183 : struct OUStringHasher
184 : {
185 0 : size_t operator()( const ::rtl::OUString& oustr ) const { return static_cast< size_t >( oustr.hashCode() ); }
186 : };
187 :
188 :
189 : // -------------------
190 : // - SVGTextWriter -
191 : // -------------------
192 : class SVGTextWriter
193 : {
194 : public:
195 : typedef ::boost::unordered_map< ::rtl::OUString, BulletListItemInfo, OUStringHasher > BulletListItemInfoMap;
196 :
197 : private:
198 : SVGExport& mrExport;
199 : SVGAttributeWriter* mpContext;
200 : VirtualDevice* mpVDev;
201 : sal_Bool mbIsTextShapeStarted;
202 : Reference<XText> mrTextShape;
203 : ::rtl::OUString msShapeId;
204 : Reference<XEnumeration> mrParagraphEnumeration;
205 : Reference<XTextContent> mrCurrentTextParagraph;
206 : Reference<XEnumeration> mrTextPortionEnumeration;
207 : Reference<XTextRange> mrCurrentTextPortion;
208 : const GDIMetaFile* mpTextEmbeddedBitmapMtf;
209 : MapMode* mpTargetMapMode;
210 : SvXMLElementExport* mpTextShapeElem;
211 : SvXMLElementExport* mpTextParagraphElem;
212 : SvXMLElementExport* mpTextPositionElem;
213 : sal_Int32 mnLeftTextPortionLength;
214 : Point maTextPos;
215 : long int mnTextWidth;
216 : sal_Bool mbPositioningNeeded;
217 : sal_Bool mbIsNewListItem;
218 : sal_Int16 meNumberingType;
219 : sal_Unicode mcBulletChar;
220 : BulletListItemInfoMap maBulletListItemMap;
221 : sal_Bool mbIsListLevelStyleImage;
222 : sal_Bool mbLineBreak;
223 : sal_Bool mbIsURLField;
224 : ::rtl::OUString msUrl;
225 : ::rtl::OUString msHyperlinkIdList;
226 : sal_Bool mbIsPlacehlolderShape;
227 : sal_Bool mbIWS;
228 : Font maCurrentFont;
229 : Font maParentFont;
230 :
231 : public:
232 : SVGTextWriter( SVGExport& rExport );
233 : virtual ~SVGTextWriter();
234 :
235 : sal_Int32 setTextPosition( const GDIMetaFile& rMtf, sal_uLong& nCurAction );
236 : void setTextProperties( const GDIMetaFile& rMtf, sal_uLong nCurAction );
237 : void addFontAttributes( sal_Bool bIsTextContainer );
238 :
239 : sal_Bool createParagraphEnumeration();
240 : sal_Bool nextParagraph();
241 : sal_Bool nextTextPortion();
242 :
243 0 : sal_Bool isTextShapeStarted() { return mbIsTextShapeStarted; }
244 : void startTextShape();
245 : void endTextShape();
246 : void startTextParagraph();
247 : void endTextParagraph();
248 : void startTextPosition( sal_Bool bExportX = sal_True, sal_Bool bExportY = sal_True);
249 : void endTextPosition();
250 : void implExportHyperlinkIds();
251 : void implWriteBulletChars();
252 : template< typename MetaBitmapActionType >
253 : void writeBitmapPlaceholder( const MetaBitmapActionType* pAction );
254 : void implWriteEmbeddedBitmaps();
255 : void writeTextPortion( const Point& rPos, const String& rText,
256 : sal_Bool bApplyMapping = sal_True );
257 : void implWriteTextPortion( const Point& rPos, const String& rText,
258 : Color aTextColor, sal_Bool bApplyMapping );
259 :
260 0 : void setVirtualDevice( VirtualDevice* pVDev, MapMode& rTargetMapMode )
261 : {
262 : if( !pVDev )
263 : OSL_FAIL( "SVGTextWriter::setVirtualDevice: invalid virtual device." );
264 0 : mpVDev = pVDev;
265 0 : mpTargetMapMode = &rTargetMapMode;
266 0 : }
267 :
268 0 : void setContext( SVGAttributeWriter* pContext )
269 : {
270 0 : mpContext = pContext;
271 0 : }
272 :
273 0 : void setTextShape( const Reference<XText>& rxText,
274 : const GDIMetaFile* pTextEmbeddedBitmapMtf )
275 : {
276 0 : mrTextShape.set( rxText );
277 0 : mpTextEmbeddedBitmapMtf = pTextEmbeddedBitmapMtf;
278 0 : }
279 :
280 : const Reference<XText>& getTextShape() const
281 : {
282 : return mrTextShape;
283 : }
284 :
285 :
286 : void setPlaceholderShapeFlag( sal_Bool bState )
287 : {
288 : mbIsPlacehlolderShape = bState;
289 : }
290 :
291 : private:
292 : void implMap( const Size& rSz, Size& rDstSz ) const;
293 : void implMap( const Point& rPt, Point& rDstPt ) const;
294 : void implSetCurrentFont();
295 : void implSetFontFamily();
296 :
297 : template< typename SubType >
298 : sal_Bool implGetTextPosition( const MetaAction* pAction, Point& raPos, sal_Bool& bEmpty );
299 : template< typename SubType >
300 : sal_Bool implGetTextPositionFromBitmap( const MetaAction* pAction, Point& raPos, sal_Bool& rbEmpty );
301 :
302 : void implRegisterInterface( const Reference< XInterface >& rxIf );
303 : const ::rtl::OUString & implGetValidIDFromInterface( const Reference< XInterface >& rxIf );
304 :
305 :
306 : };
307 :
308 : // -------------------
309 : // - SVGActionWriter -
310 : // -------------------
311 :
312 : class SVGActionWriter
313 : {
314 : private:
315 :
316 : sal_Int32 mnCurGradientId;
317 : sal_Int32 mnCurMaskId;
318 : sal_Int32 mnCurPatternId;
319 : ::std::stack< SVGAttributeWriter* > maContextStack;
320 : ::std::auto_ptr< SVGShapeDescriptor > mapCurShape;
321 : SVGExport& mrExport;
322 : SVGFontExport& mrFontExport;
323 : SVGAttributeWriter* mpContext;
324 : SVGTextWriter maTextWriter;
325 : VirtualDevice* mpVDev;
326 : MapMode maTargetMapMode;
327 : sal_uInt32 mnInnerMtfCount;
328 : sal_Bool mbDestroyVDev;
329 : sal_Bool mbPaintAttrChanged;
330 : sal_Bool mbFontAttrChanged;
331 : sal_Bool mbClipAttrChanged;
332 : sal_Bool mbIsPlacehlolderShape;
333 :
334 :
335 0 : SVGAttributeWriter* ImplAcquireContext()
336 : {
337 0 : maContextStack.push( mpContext = new SVGAttributeWriter( mrExport, mrFontExport ) );
338 0 : maTextWriter.setContext( mpContext );
339 0 : return mpContext;
340 : }
341 0 : void ImplReleaseContext()
342 : {
343 0 : if (!maContextStack.empty())
344 : {
345 0 : delete maContextStack.top();
346 0 : maContextStack.pop();
347 : }
348 0 : mpContext = (maContextStack.empty() ? NULL : maContextStack.top());
349 0 : maTextWriter.setContext( mpContext );
350 0 : }
351 :
352 : long ImplMap( sal_Int32 nVal ) const;
353 : Point& ImplMap( const Point& rPt, Point& rDstPt ) const;
354 : Size& ImplMap( const Size& rSz, Size& rDstSz ) const;
355 : Rectangle& ImplMap( const Rectangle& rRect, Rectangle& rDstRect ) const;
356 : Polygon& ImplMap( const Polygon& rPoly, Polygon& rDstPoly ) const;
357 : PolyPolygon& ImplMap( const PolyPolygon& rPolyPoly, PolyPolygon& rDstPolyPoly ) const;
358 :
359 : void ImplWriteLine( const Point& rPt1, const Point& rPt2, const Color* pLineColor = NULL,
360 : sal_Bool bApplyMapping = sal_True );
361 : void ImplWriteRect( const Rectangle& rRect, long nRadX = 0, long nRadY = 0,
362 : sal_Bool bApplyMapping = sal_True );
363 : void ImplWriteEllipse( const Point& rCenter, long nRadX, long nRadY,
364 : sal_Bool bApplyMapping = sal_True );
365 : void ImplWritePattern( const PolyPolygon& rPolyPoly, const Hatch* pHatch, const Gradient* pGradient, sal_uInt32 nWriteFlags );
366 : void ImplWritePolyPolygon( const PolyPolygon& rPolyPoly, sal_Bool bLineOnly,
367 : sal_Bool bApplyMapping = sal_True );
368 : void ImplWriteShape( const SVGShapeDescriptor& rShape, sal_Bool bApplyMapping = sal_True );
369 : void ImplWriteGradientEx( const PolyPolygon& rPolyPoly, const Gradient& rGradient, sal_uInt32 nWriteFlags,
370 : sal_Bool bApplyMapping = sal_True );
371 : void ImplWriteGradientLinear( const PolyPolygon& rPolyPoly, const Gradient& rGradient );
372 : void ImplWriteGradientStop( const Color& rColor, double fOffset );
373 : Color ImplGetColorWithIntensity( const Color& rColor, sal_uInt16 nIntensity );
374 : Color ImplGetGradientColor( const Color& rStartColor, const Color& rEndColor, double fOffset );
375 : void ImplWriteMask( GDIMetaFile& rMtf, const Point& rDestPt, const Size& rDestSize, const Gradient& rGradient, sal_uInt32 nWriteFlags );
376 : void ImplWriteText( const Point& rPos, const String& rText, const sal_Int32* pDXArray, long nWidth, sal_Bool bApplyMapping = sal_True );
377 : void ImplWriteText( const Point& rPos, const String& rText, const sal_Int32* pDXArray, long nWidth, Color aTextColor, sal_Bool bApplyMapping );
378 : void ImplWriteBmp( const BitmapEx& rBmpEx, const Point& rPt, const Size& rSz, const Point& rSrcPt, const Size& rSrcSz,
379 : sal_Bool bApplyMapping = sal_True );
380 :
381 : void ImplCheckFontAttributes();
382 : void ImplCheckPaintAttributes();
383 :
384 : void ImplWriteActions( const GDIMetaFile& rMtf,
385 : sal_uInt32 nWriteFlags,
386 : const ::rtl::OUString* pElementId,
387 : const Reference< XShape >* pXShape = NULL,
388 : const GDIMetaFile* pTextEmbeddedBitmapMtf = NULL );
389 :
390 : Font ImplSetCorrectFontHeight() const;
391 :
392 : public:
393 :
394 : static ::rtl::OUString GetPathString( const PolyPolygon& rPolyPoly, sal_Bool bLine );
395 : static sal_uLong GetChecksum( const MetaAction* pAction );
396 :
397 : public:
398 :
399 : SVGActionWriter( SVGExport& rExport, SVGFontExport& rFontExport );
400 : virtual ~SVGActionWriter();
401 :
402 : void WriteMetaFile( const Point& rPos100thmm,
403 : const Size& rSize100thmm,
404 : const GDIMetaFile& rMtf,
405 : sal_uInt32 nWriteFlags,
406 : const ::rtl::OUString* pElementId = NULL,
407 : const Reference< XShape >* pXShape = NULL,
408 : const GDIMetaFile* pTextEmbeddedBitmapMtf = NULL );
409 : };
410 :
411 : #endif
412 :
413 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|