1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
31 #include "svgaction.hxx"
32 #include <vcl/virdev.hxx>
33 #include <vcl/cvtgrf.hxx>
34 #include <vcl/metric.hxx>
36 #undef _SVG_USE_NATIVE_TEXTDECORATION
37 #undef _SVG_USE_TSPANS
43 static const char aXMLElemSVG
[] = "svg";
44 static const char aXMLElemG
[] = "g";
45 static const char aXMLElemDefs
[] = "defs";
46 static const char aXMLElemClipPath
[] = "clipPath";
47 static const char aXMLElemLine
[] = "line";
48 static const char aXMLElemRect
[] = "rect";
49 static const char aXMLElemEllipse
[] = "ellipse";
50 static const char aXMLElemPath
[] = "path";
51 static const char aXMLElemPolygon
[] = "polygon";
52 static const char aXMLElemPolyLine
[] = "polyline";
53 static const char aXMLElemText
[] = "text";
54 static const char aXMLElemTSpan
[] = "tspan";
55 static const char aXMLElemImage
[] = "image";
57 static const char aXMLAttrTransform
[] = "transform";
58 static const char aXMLAttrStyle
[] = "style";
59 static const char aXMLAttrId
[] = "id";
61 static const char aXMLAttrD
[] = "d";
62 static const char aXMLAttrX
[] = "x";
63 static const char aXMLAttrY
[] = "y";
64 static const char aXMLAttrX1
[] = "x1";
65 static const char aXMLAttrY1
[] = "y1";
66 static const char aXMLAttrX2
[] = "x2";
67 static const char aXMLAttrY2
[] = "y2";
68 static const char aXMLAttrCX
[] = "cx";
69 static const char aXMLAttrCY
[] = "cy";
70 static const char aXMLAttrRX
[] = "rx";
71 static const char aXMLAttrRY
[] = "ry";
72 static const char aXMLAttrWidth
[] = "width";
73 static const char aXMLAttrHeight
[] = "height";
74 static const char aXMLAttrPoints
[] = "points";
75 static const char aXMLAttrXLinkHRef
[] = "xlink:href";
77 static const sal_Unicode pBase64
[] =
80 'A','B','C','D','E','F','G','H', // 0
81 'I','J','K','L','M','N','O','P', // 1
82 'Q','R','S','T','U','V','W','X', // 2
83 'Y','Z','a','b','c','d','e','f', // 3
84 'g','h','i','j','k','l','m','n', // 4
85 'o','p','q','r','s','t','u','v', // 5
86 'w','x','y','z','0','1','2','3', // 6
87 '4','5','6','7','8','9','+','/' // 7
94 FastString::FastString( sal_uInt32 nInitLen
, sal_uInt32 nIncrement
) :
95 mpBuffer( new sal_Unicode
[ nInitLen
* sizeof( sal_Unicode
) ] ),
98 mnBufInc( nIncrement
),
101 DBG_ASSERT( nInitLen
, "invalid initial length" );
102 DBG_ASSERT( nIncrement
, "invalid increment" );
105 // -----------------------------------------------------------------------------
107 FastString::FastString( sal_Char
* pBufferForBase64Encoding
, sal_uInt32 nBufLen
) :
111 DBG_ASSERT( pBufferForBase64Encoding
&& nBufLen
, "invalid arguments" );
113 const sal_uInt32 nQuadCount
= nBufLen
/ 3;
114 const sal_uInt32 nRest
= nBufLen
% 3;
116 if( nQuadCount
|| nRest
)
118 mnBufLen
= mnCurLen
= ( ( nQuadCount
+ ( nRest
? 1 : 0 ) ) << 2 );
119 mpBuffer
= new sal_Unicode
[ mnBufLen
* sizeof( sal_Unicode
) ];
121 sal_Char
* pTmpSrc
= pBufferForBase64Encoding
;
122 sal_Unicode
* pTmpDst
= mpBuffer
;
124 for( sal_uInt32 i
= 0; i
< nQuadCount
; i
++ )
126 const sal_Int32 nA
= *pTmpSrc
++;
127 const sal_Int32 nB
= *pTmpSrc
++;
128 const sal_Int32 nC
= *pTmpSrc
++;
130 *pTmpDst
++ = pBase64
[ ( nA
>> 2 ) & 0x3f ];
131 *pTmpDst
++ = pBase64
[ ( ( nA
<< 4 ) & 0x30 ) + ( ( nB
>> 4 ) & 0xf ) ];
132 *pTmpDst
++ = pBase64
[ ( ( nB
<< 2 ) & 0x3c ) + ( ( nC
>> 6 ) & 0x3 ) ];
133 *pTmpDst
++ = pBase64
[ nC
& 0x3f ];
138 const sal_Int32 nA
= *pTmpSrc
;
140 *pTmpDst
++ = pBase64
[ ( nA
>> 2 ) & 0x3f ];
141 *pTmpDst
++ = pBase64
[ ( nA
<< 4 ) & 0x30 ];
145 else if( 2 == nRest
)
147 const sal_Int32 nA
= *pTmpSrc
++;
148 const sal_Int32 nB
= *pTmpSrc
;
150 *pTmpDst
++ = pBase64
[ ( nA
>> 2 ) & 0x3f ];
151 *pTmpDst
++ = pBase64
[ ( ( nA
<< 4 ) & 0x30 ) + ( ( nB
>> 4 ) & 0xf ) ];
152 *pTmpDst
++ = pBase64
[ ( nB
<< 2 ) & 0x3c ];
158 mpBuffer
= new sal_Unicode
[ ( mnBufLen
= 1 ) * sizeof( sal_Unicode
) ];
163 // -----------------------------------------------------------------------------
165 FastString::~FastString()
170 // -----------------------------------------------------------------------------
172 FastString
& FastString::operator+=( const NMSP_RTL::OUString
& rStr
)
174 if( rStr
.getLength() )
176 if( ( mnCurLen
+ rStr
.getLength() ) > mnBufLen
)
178 const sal_uInt32 nNewBufLen
= ( mnBufLen
+ ( ( ( mnCurLen
+ rStr
.getLength() ) - mnBufLen
) / mnBufInc
+ 1 ) * mnBufInc
);
179 sal_Unicode
* pNewBuffer
= new sal_Unicode
[ nNewBufLen
* sizeof( sal_Unicode
) ];
181 memcpy( pNewBuffer
, mpBuffer
, mnBufLen
* sizeof( sal_Unicode
) );
183 mpBuffer
= pNewBuffer
;
184 mnBufLen
= nNewBufLen
;
187 memcpy( mpBuffer
+ mnCurLen
, rStr
.getStr(), rStr
.getLength() * sizeof( sal_Unicode
) );
188 mnCurLen
+= rStr
.getLength();
190 if( maString
.getLength() )
191 maString
= NMSP_RTL::OUString();
197 // -----------------------------------------------------------------------------
199 const NMSP_RTL::OUString
& FastString::GetString() const
201 if( !maString
.getLength() && mnCurLen
)
202 ( (FastString
*) this )->maString
= NMSP_RTL::OUString( mpBuffer
, mnCurLen
);
207 // -----------------------------------------------------------------------------
209 sal_Bool
FastString::GetFirstPartString( const sal_uInt32 nPartLen
, NMSP_RTL::OUString
& rPartString
)
211 const sal_uInt32 nLength
= Min( mnCurLen
, nPartLen
);
217 rPartString
= NMSP_RTL::OUString( mpBuffer
, nLength
);
221 return( rPartString
.getLength() > 0 );
224 // -----------------------------------------------------------------------------
226 sal_Bool
FastString::GetNextPartString( const sal_uInt32 nPartLen
, NMSP_RTL::OUString
& rPartString
)
228 if( mnPartPos
< mnCurLen
)
230 const sal_uInt32 nLength
= Min( mnCurLen
- mnPartPos
, nPartLen
);
231 rPartString
= NMSP_RTL::OUString( mpBuffer
+ mnPartPos
, nLength
);
232 mnPartPos
+= nLength
;
235 rPartString
= NMSP_RTL::OUString();
237 return( rPartString
.getLength() > 0 );
240 // ----------------------
241 // - SVGAttributeWriter -
242 // ----------------------
244 SVGAttributeWriter::SVGAttributeWriter( SVGActionWriter
& rParent
, SvXMLExport
& rExport
) :
252 // -----------------------------------------------------------------------------
254 SVGAttributeWriter::~SVGAttributeWriter()
260 // -----------------------------------------------------------------------------
262 NMSP_RTL::OUString
SVGAttributeWriter::GetFontStyle( const Font
& rFont
)
267 aStyle
+= B2UCONST( "font-family:" );
268 aStyle
+= NMSP_RTL::OUString( rFont
.GetName().GetToken( 0, ';' ) );
271 aStyle
+= B2UCONST( ";" );
272 aStyle
+= B2UCONST( "font-size:" );
273 aStyle
+= mrParent
.GetValueString( mrParent
.ImplMap( Size( 0, rFont
.GetHeight() ) ).Height(), mrParent
.HasDoublePoints() );
276 if( rFont
.GetItalic() != ITALIC_NONE
)
278 aStyle
+= B2UCONST( ";" );
279 aStyle
+= B2UCONST( "font-style:" );
281 if( rFont
.GetItalic() == ITALIC_OBLIQUE
)
282 aStyle
+= B2UCONST( "oblique" );
284 aStyle
+= B2UCONST( "italic" );
288 sal_Int32 nFontWeight
;
290 switch( rFont
.GetWeight() )
292 case WEIGHT_THIN
: nFontWeight
= 100; break;
293 case WEIGHT_ULTRALIGHT
: nFontWeight
= 200; break;
294 case WEIGHT_LIGHT
: nFontWeight
= 300; break;
295 case WEIGHT_SEMILIGHT
: nFontWeight
= 400; break;
296 case WEIGHT_NORMAL
: nFontWeight
= 400; break;
297 case WEIGHT_MEDIUM
: nFontWeight
= 500; break;
298 case WEIGHT_SEMIBOLD
: nFontWeight
= 600; break;
299 case WEIGHT_BOLD
: nFontWeight
= 700; break;
300 case WEIGHT_ULTRABOLD
: nFontWeight
= 800; break;
301 case WEIGHT_BLACK
: nFontWeight
= 900; break;
302 default: nFontWeight
= 400; break;
305 aStyle
+= B2UCONST( ";" );
306 aStyle
+= B2UCONST( "font-weight:" );
307 aStyle
+= NMSP_RTL::OUString::valueOf( nFontWeight
);
314 #ifdef _SVG_USE_NATIVE_TEXTDECORATION
316 if( rFont
.GetUnderline() != UNDERLINE_NONE
|| rFont
.GetStrikeout() != STRIKEOUT_NONE
)
318 aStyle
+= B2UCONST( ";" );
319 aStyle
+= B2UCONST( "text-decoration:" );
321 if( rFont
.GetUnderline() != UNDERLINE_NONE
)
322 aStyle
+= B2UCONST( " underline" );
324 if( rFont
.GetStrikeout() != STRIKEOUT_NONE
)
325 aStyle
+= B2UCONST( " line-through" );
328 #endif // _SVG_USE_NATIVE_TEXTDECORATION
330 return aStyle
.GetString();
333 // -----------------------------------------------------------------------------
335 NMSP_RTL::OUString
SVGAttributeWriter::GetPaintStyle( const Color
& rLineColor
, const Color
& rFillColor
)
340 aStyle
+= B2UCONST( "stroke:" );
342 if( rLineColor
.GetTransparency() == 255 )
343 aStyle
+= B2UCONST( "none" );
346 // line color value in rgb
347 aStyle
+= B2UCONST( "rgb(" );
348 aStyle
+= NMSP_RTL::OUString::valueOf( (sal_Int32
) rLineColor
.GetRed() );
349 aStyle
+= B2UCONST( "," );
350 aStyle
+= NMSP_RTL::OUString::valueOf( (sal_Int32
) rLineColor
.GetGreen() );
351 aStyle
+= B2UCONST( "," );
352 aStyle
+= NMSP_RTL::OUString::valueOf( (sal_Int32
) rLineColor
.GetBlue() );
353 aStyle
+= B2UCONST( ")" );
355 // line color opacity in percent if neccessary
356 if( rLineColor
.GetTransparency() )
358 aStyle
+= B2UCONST( ";" );
359 aStyle
+= B2UCONST( "stroke-opacity:" );
360 aStyle
+= NMSP_RTL::OUString::valueOf( (sal_Int32
) ( ( 255 - (double) rLineColor
.GetTransparency() ) / 2.55 ) );
361 aStyle
+= B2UCONST( "%" );
366 aStyle
+= B2UCONST( ";" );
367 aStyle
+= B2UCONST( "fill:" );
369 if( rFillColor
.GetTransparency() == 255 )
370 aStyle
+= B2UCONST( "none" );
373 // fill color value in rgb
374 aStyle
+= B2UCONST( "rgb(" );
375 aStyle
+= NMSP_RTL::OUString::valueOf( (sal_Int32
) rFillColor
.GetRed() );
376 aStyle
+= B2UCONST( "," );
377 aStyle
+= NMSP_RTL::OUString::valueOf( (sal_Int32
) rFillColor
.GetGreen() );
378 aStyle
+= B2UCONST( "," );
379 aStyle
+= NMSP_RTL::OUString::valueOf( (sal_Int32
) rFillColor
.GetBlue() );
380 aStyle
+= B2UCONST( ")" );
382 // fill color opacity in percent if neccessary
383 if( rFillColor
.GetTransparency() )
385 aStyle
+= B2UCONST( ";" );
386 aStyle
+= B2UCONST( "fill-opacity:" );
387 aStyle
+= NMSP_RTL::OUString::valueOf( (sal_Int32
) ( ( 255 - (double) rFillColor
.GetTransparency() ) / 2.55 ) );
388 aStyle
+= B2UCONST( "%" );
392 return aStyle
.GetString();
395 // -----------------------------------------------------------------------------
397 void SVGAttributeWriter::SetFontAttr( const Font
& rFont
)
399 if( !mpElemFont
|| ( rFont
!= maCurFont
) )
401 delete mpElemPaint
, mpElemPaint
= NULL
;
403 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, GetFontStyle( maCurFont
= rFont
) );
404 mpElemFont
= new SvXMLElementExport( mrExport
, XML_NAMESPACE_NONE
, aXMLElemG
, TRUE
, TRUE
);
408 // -----------------------------------------------------------------------------
410 void SVGAttributeWriter::SetPaintAttr( const Color
& rLineColor
, const Color
& rFillColor
)
412 if( !mpElemPaint
|| ( rLineColor
!= maCurLineColor
) || ( rFillColor
!= maCurFillColor
) )
415 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, GetPaintStyle( maCurLineColor
= rLineColor
, maCurFillColor
= rFillColor
) );
416 mpElemPaint
= new SvXMLElementExport( mrExport
, XML_NAMESPACE_NONE
, aXMLElemG
, TRUE
, TRUE
);
420 // -------------------
421 // - SVGActionWriter -
422 // -------------------
424 SVGActionWriter::SVGActionWriter( SvXMLExport
& rExport
, const GDIMetaFile
& rMtf
,
425 VirtualDevice
* pParentVDev
, sal_Bool bWriteDoublePoints
) :
430 mbClipAttrChanged( sal_False
),
431 mbDoublePoints( bWriteDoublePoints
)
435 mpVDev
= pParentVDev
;
436 mbDestroyVDev
= sal_False
;
437 maTargetMapMode
= mpVDev
->GetMapMode();
441 mpVDev
= new VirtualDevice
;
442 mpVDev
->EnableOutput( sal_False
);
443 mbDestroyVDev
= sal_True
;
444 maTargetMapMode
= MAP_100TH_MM
;
448 mpVDev
->SetMapMode( mrMtf
.GetPrefMapMode() );
449 ImplWriteActions( mrMtf
);
453 // -----------------------------------------------------------------------------
455 SVGActionWriter::~SVGActionWriter()
457 DBG_ASSERT( !mpContext
, "Not all contexts are closed" );
463 // -----------------------------------------------------------------------------
465 long SVGActionWriter::ImplMap( sal_Int32 nVal
) const
467 return ImplMap( Size( nVal
, nVal
) ).Width();
470 // -----------------------------------------------------------------------------
472 Point
SVGActionWriter::ImplMap( const Point
& rPt
) const
474 return mpVDev
->LogicToLogic( rPt
, mpVDev
->GetMapMode(), maTargetMapMode
);
477 // -----------------------------------------------------------------------------
479 Size
SVGActionWriter::ImplMap( const Size
& rSz
) const
481 return mpVDev
->LogicToLogic( rSz
, mpVDev
->GetMapMode(), maTargetMapMode
);
484 // -----------------------------------------------------------------------------
486 NMSP_RTL::OUString
SVGActionWriter::GetValueString( sal_Int32 nVal
, sal_Bool bDoublePoints
)
489 return NMSP_RTL::OUString::valueOf( nVal
);
492 const double fPoints
= nVal
* 72.0 / 2540.0;
493 const sal_Int32 nInt
= (sal_Int32
) fPoints
;
495 return( ( NMSP_RTL::OUString::valueOf( nInt
) +=
496 NMSP_RTL::OUString::valueOf( (sal_Unicode
) '.' ) ) +=
497 NMSP_RTL::OUString::valueOf( labs( (sal_Int32
) ( ( fPoints
- nInt
) * 100.0 ) ) ) );
501 // -----------------------------------------------------------------------------
503 void SVGActionWriter::ImplWriteLine( const Point
& rPt1
, const Point
& rPt2
, const Color
* pLineColor
,
504 const NMSP_RTL::OUString
* pStyle
)
506 const Point
aPt1( ImplMap( rPt1
) );
507 const Point
aPt2( ImplMap( rPt2
) );
509 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrX1
, GetValueString( aPt1
.X(), mbDoublePoints
) );
510 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrY1
, GetValueString( aPt1
.Y(), mbDoublePoints
) );
511 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrX2
, GetValueString( aPt2
.X(), mbDoublePoints
) );
512 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrY2
, GetValueString( aPt2
.Y(), mbDoublePoints
) );
514 // add additional style if requested
516 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, *pStyle
);
520 // !!! mrExport.AddAttribute( XML_NAMESPACE_NONE, ... )
521 DBG_ERROR( "SVGActionWriter::ImplWriteLine: Line color not implemented" );
525 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_NONE
, aXMLElemLine
, TRUE
, TRUE
);
529 // -----------------------------------------------------------------------------
531 void SVGActionWriter::ImplWriteRect( const Rectangle
& rRect
, long nRadX
, long nRadY
,
532 const NMSP_RTL::OUString
* pStyle
)
534 const Rectangle
aRect( ImplMap( rRect
) );
536 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrX
, GetValueString( aRect
.Left(), mbDoublePoints
) );
537 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrY
, GetValueString( aRect
.Top(), mbDoublePoints
) );
538 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrWidth
, GetValueString( aRect
.GetWidth(), mbDoublePoints
) );
539 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrHeight
, GetValueString( aRect
.GetHeight(), mbDoublePoints
) );
542 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrRX
, GetValueString( ImplMap( nRadX
), mbDoublePoints
) );
545 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrRY
, GetValueString( ImplMap( nRadY
), mbDoublePoints
) );
547 // add additional style if requested
549 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, *pStyle
);
552 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_NONE
, aXMLElemRect
, TRUE
, TRUE
);
556 // -----------------------------------------------------------------------------
558 void SVGActionWriter::ImplWriteEllipse( const Point
& rCenter
, long nRadX
, long nRadY
,
559 const NMSP_RTL::OUString
* pStyle
)
561 const Point
aCenter( ImplMap( rCenter
) );
563 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrCX
, GetValueString( aCenter
.X(), mbDoublePoints
) );
564 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrCY
, GetValueString( aCenter
.Y(), mbDoublePoints
) );
565 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrRX
, GetValueString( ImplMap( nRadX
), mbDoublePoints
) );
566 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrRY
, GetValueString( ImplMap( nRadY
), mbDoublePoints
) );
568 // add additional style if requested
570 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, *pStyle
);
573 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_NONE
, aXMLElemEllipse
, TRUE
, TRUE
);
577 // -----------------------------------------------------------------------------
579 void SVGActionWriter::ImplWritePolygon( const Polygon
& rPoly
, sal_Bool bLineOnly
,
580 const NMSP_RTL::OUString
* pStyle
)
582 if( rPoly
.GetSize() )
584 if( rPoly
.HasFlags() )
585 ImplWritePolyPolygon( rPoly
, bLineOnly
, pStyle
);
590 USHORT i
= 0, nSize
= rPoly
.GetSize();
591 const NMSP_RTL::OUString
aBlank( B2UCONST( " " ) );
596 const Point
aPolyPoint( ImplMap( rPoly
[ i
] ) );
598 aPoints
+= GetValueString( aPolyPoint
.X(), mbDoublePoints
);
599 aPoints
+= B2UCONST( "," );
600 aPoints
+= GetValueString( aPolyPoint
.Y(), mbDoublePoints
);
609 aStyle
+= B2UCONST( "fill:none" );
613 aStyle
+= B2UCONST( ";" );
620 // add point attribute
621 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrPoints
, aPoints
.GetString() );
623 // add style attribute
624 if( aStyle
.GetLength() )
625 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, aStyle
.GetString() );
628 // write polyline/polygon element
629 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_NONE
, bLineOnly
? aXMLElemPolyLine
: aXMLElemPolygon
, TRUE
, TRUE
);
635 // -----------------------------------------------------------------------------
637 void SVGActionWriter::ImplWritePolyPolygon( const PolyPolygon
& rPolyPoly
, sal_Bool bLineOnly
,
638 const NMSP_RTL::OUString
* pStyle
)
640 if( rPolyPoly
.Count() )
642 if( ( rPolyPoly
.Count() == 1 ) && ( rPolyPoly
[ 0 ].HasFlags() == sal_False
) )
643 ImplWritePolygon( rPolyPoly
[ 0 ], bLineOnly
, pStyle
);
647 FastString aPathData
;
648 const NMSP_RTL::OUString
aBlank( B2UCONST( " " ) );
649 const NMSP_RTL::OUString
aComma( B2UCONST( "," ) );
652 for( long i
= 0, nCount
= rPolyPoly
.Count(); i
< nCount
; i
++ )
654 const Polygon
& rPoly
= rPolyPoly
[ (USHORT
) i
];
655 USHORT n
= 1, nSize
= rPoly
.GetSize();
659 aPathData
+= B2UCONST( "M " );
660 aPathData
+= GetValueString( ( aPolyPoint
= ImplMap( rPoly
[ 0 ] ) ).X(), mbDoublePoints
);
662 aPathData
+= GetValueString( aPolyPoint
.Y(), mbDoublePoints
);
663 sal_Char nCurrentMode
= 0;
668 if ( ( rPoly
.GetFlags( n
) == POLY_CONTROL
) && ( ( n
+ 2 ) < nSize
) )
670 if ( nCurrentMode
!= 'C' )
673 aPathData
+= B2UCONST( "C " );
675 for ( int j
= 0; j
< 3; j
++ )
679 aPathData
+= GetValueString( ( aPolyPoint
= ImplMap( rPoly
[ n
++ ] ) ).X(), mbDoublePoints
);
681 aPathData
+= GetValueString( aPolyPoint
.Y(), mbDoublePoints
);
686 if ( nCurrentMode
!= 'L' )
689 aPathData
+= B2UCONST( "L " );
691 aPathData
+= GetValueString( ( aPolyPoint
= ImplMap( rPoly
[ n
++ ] ) ).X(), mbDoublePoints
);
693 aPathData
+= GetValueString( aPolyPoint
.Y(), mbDoublePoints
);
696 aPathData
+= B2UCONST( " Z" );
698 if( i
< ( nCount
- 1 ) )
704 aStyle
+= B2UCONST( "fill:none" );
706 aStyle
+= B2UCONST( ";" );
711 // add style attribute
712 if( aStyle
.GetLength() )
713 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, aStyle
.GetString() );
715 // add path data attribute
716 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrD
, aPathData
.GetString() );
718 // write polyline/polygon element
719 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_NONE
, aXMLElemPath
, TRUE
, TRUE
);
725 // -----------------------------------------------------------------------------
727 void SVGActionWriter::ImplWriteGradientEx( const PolyPolygon
& rPolyPoly
, const Gradient
& rGradient
,
728 const NMSP_RTL::OUString
* pStyle
)
730 if( rPolyPoly
.Count() )
732 SvXMLElementExport
aElemG( mrExport
, XML_NAMESPACE_NONE
, aXMLElemG
, TRUE
, TRUE
);
734 FastString aClipStyle
;
736 aClipId
+= B2UCONST( "clip" );
737 aClipId
+= NMSP_RTL::OUString::valueOf( ImplGetNextClipId() );
740 SvXMLElementExport
aElemDefs( mrExport
, XML_NAMESPACE_NONE
, aXMLElemDefs
, TRUE
, TRUE
);
742 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrId
, aClipId
.GetString() );
745 SvXMLElementExport
aElemClipPath( mrExport
, XML_NAMESPACE_NONE
, aXMLElemClipPath
, TRUE
, TRUE
);
746 ImplWritePolyPolygon( rPolyPoly
, sal_False
);
750 // create new context with clippath set
751 aClipStyle
+= B2UCONST( "clip-path:URL(#" );
752 aClipStyle
+= aClipId
.GetString();
753 aClipStyle
+= B2UCONST( ")" );
755 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, aClipStyle
.GetString() );
759 SvXMLElementExport
aElemG2( mrExport
, XML_NAMESPACE_NONE
, aXMLElemG
, TRUE
, TRUE
);
761 mpVDev
->AddGradientActions( rPolyPoly
.GetBoundRect(), rGradient
, aTmpMtf
);
762 ImplWriteActions( aTmpMtf
, pStyle
);
767 // -----------------------------------------------------------------------------
769 void SVGActionWriter::ImplWriteText( const Point
& rPos
, const String
& rText
,
770 const sal_Int32
* pDXArray
, long nWidth
,
771 const NMSP_RTL::OUString
* pStyle
)
773 String
aText( rText
); aText
.EraseLeadingChars( ' ' );
774 UINT32 nLen
= aText
.Len(), i
;
779 sal_Int32
* pOwnArray
;
786 aNormSize
= Size( mpVDev
->GetTextWidth( aText
), 0 );
787 pDX
= const_cast< sal_Int32
* >( pDXArray
);
791 pOwnArray
= new sal_Int32
[ nLen
];
792 aNormSize
= Size( mpVDev
->GetTextArray( aText
, pOwnArray
), 0 );
798 aNormSize
.Width() = pDX
[ nLen
- 2 ] + mpVDev
->GetTextWidth( aText
.GetChar( (USHORT
) nLen
- 1 ) );
800 if( nWidth
&& aNormSize
.Width() && ( nWidth
!= aNormSize
.Width() ) )
802 const double fFactor
= (double) nWidth
/ aNormSize
.Width();
804 for( i
= 0; i
< ( nLen
- 1 ); i
++ )
805 pDX
[ i
] = FRound( pDX
[ i
] * fFactor
);
810 const Font
& rFont
= mpVDev
->GetFont();
811 const FontMetric
aMetric( mpVDev
->GetFontMetric() );
812 Point
aBaseLinePos( rPos
);
813 SvXMLElementExport
* pTransform
= NULL
;
815 // leading whitespaces erased? => adjust position
816 if( nLen
< rText
.Len() )
818 aBaseLinePos
.X() += mpVDev
->GetTextWidth( ' ' ) * ( rText
.Len() - nLen
);
821 // always adjust text position to match baseline alignment
822 switch( rFont
.GetAlign() )
825 aBaseLinePos
.Y() += aMetric
.GetAscent();
828 case( ALIGN_BOTTOM
):
829 aBaseLinePos
.Y() -= aMetric
.GetDescent();
836 // get mapped text position
837 const Point
aPt( ImplMap( aBaseLinePos
) );
839 // if text is rotated, set transform at new g element
840 if( rFont
.GetOrientation() )
844 aTransform
= NMSP_RTL::OUString::createFromAscii( "translate" );
846 aTransform
+= String( GetValueString( aPt
.X(), mbDoublePoints
) );
848 aTransform
+= String( GetValueString( aPt
.Y(), mbDoublePoints
) );
851 aTransform
+= String( NMSP_RTL::OUString::createFromAscii( " rotate" ) );
853 aTransform
+= String( NMSP_RTL::OUString::valueOf( rFont
.GetOrientation() * -0.1 ) );
856 aTransform
+= String( NMSP_RTL::OUString::createFromAscii( " translate" ) );
858 aTransform
+= String( GetValueString( -aPt
.X(), mbDoublePoints
) );
860 aTransform
+= String( GetValueString( -aPt
.Y(), mbDoublePoints
) );
863 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrTransform
, aTransform
);
864 pTransform
= new SvXMLElementExport( mrExport
, XML_NAMESPACE_NONE
, aXMLElemG
, TRUE
, TRUE
);
867 // add additional style if requested
868 if( pStyle
&& pStyle
->getLength() )
869 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, *pStyle
);
871 // write text element
872 #ifdef _SVG_USE_TSPANS
875 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_NONE
, aXMLElemText
, TRUE
, TRUE
);
877 const NMSP_RTL::OUString
aSpace( ' ' );
880 aTSpanX
+= GetValueString( aPt
.X(), mbDoublePoints
);
883 for( i
= 0, nX
= aPt
.X(), nCount
= ( nLen
- 1 ); i
< nCount
; )
885 aTSpanX
+= GetValueString( aPt
.X() + pDX
[ i
++ ], mbDoublePoints
);
889 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrX
, aTSpanX
.GetString() );
890 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrY
, GetValueString( aPt
.Y(), mbDoublePoints
) );
897 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_NONE
, aXMLElemTSpan
, TRUE
, TRUE
);
898 mrExport
.GetDocHandler()->characters( NMSP_RTL::OUString( UniString( aText
) ) );
900 catch( ::com::sun::star::xml::sax::SAXException
& )
902 // string seems to contain invalid characters
910 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrX
, GetValueString( aPt
.X(), mbDoublePoints
) );
911 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrY
, GetValueString( aPt
.Y(), mbDoublePoints
) );
915 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_NONE
, aXMLElemText
, TRUE
, TRUE
);
916 mrExport
.GetDocHandler()->characters( NMSP_RTL::OUString( UniString( aText
) ) );
918 catch( ::com::sun::star::xml::sax::SAXException
& )
920 // string seems to contain invalid characters
924 #ifndef _SVG_USE_NATIVE_TEXTDECORATION
926 // write strikeout if neccessary
927 if( ( rFont
.GetStrikeout() != STRIKEOUT_NONE
) || ( rFont
.GetUnderline() != UNDERLINE_NONE
) )
930 const long nLineHeight
= Max( (long) FRound( aMetric
.GetLineHeight() * 0.05 ), (long) 1 );
932 if( rFont
.GetStrikeout() )
934 const long nYLinePos
= aBaseLinePos
.Y() - FRound( aMetric
.GetAscent() * 0.26 );
936 aPoly
[ 0 ].X() = aBaseLinePos
.X(); aPoly
[ 0 ].Y() = nYLinePos
- ( nLineHeight
>> 1 );
937 aPoly
[ 1 ].X() = aBaseLinePos
.X() + aNormSize
.Width() - 1; aPoly
[ 1 ].Y() = aPoly
[ 0 ].Y();
938 aPoly
[ 2 ].X() = aPoly
[ 1 ].X(); aPoly
[ 2 ].Y() = aPoly
[ 0 ].Y() + nLineHeight
- 1;
939 aPoly
[ 3 ].X() = aPoly
[ 0 ].X(); aPoly
[ 3 ].Y() = aPoly
[ 2 ].Y();
941 ImplWritePolygon( aPoly
, FALSE
);
944 if( rFont
.GetUnderline() )
946 const long nYLinePos
= aBaseLinePos
.Y() + ( nLineHeight
<< 1 );
948 aPoly
[ 0 ].X() = aBaseLinePos
.X(); aPoly
[ 0 ].Y() = nYLinePos
- ( nLineHeight
>> 1 );
949 aPoly
[ 1 ].X() = aBaseLinePos
.X() + aNormSize
.Width() - 1; aPoly
[ 1 ].Y() = aPoly
[ 0 ].Y();
950 aPoly
[ 2 ].X() = aPoly
[ 1 ].X(); aPoly
[ 2 ].Y() = aPoly
[ 0 ].Y() + nLineHeight
- 1;
951 aPoly
[ 3 ].X() = aPoly
[ 0 ].X(); aPoly
[ 3 ].Y() = aPoly
[ 2 ].Y();
953 ImplWritePolygon( aPoly
, FALSE
);
957 #endif // _SVG_USE_NATIVE_TEXTDECORATION
964 // -----------------------------------------------------------------------------
966 void SVGActionWriter::ImplWriteBmp( const BitmapEx
& rBmpEx
,
967 const Point
& rPt
, const Size
& rSz
,
968 const Point
& rSrcPt
, const Size
& rSrcSz
,
969 const NMSP_RTL::OUString
* /*pStyle*/ )
973 BitmapEx
aBmpEx( rBmpEx
);
974 Point aPoint
= Point();
975 const Rectangle
aBmpRect( aPoint
, rBmpEx
.GetSizePixel() );
976 const Rectangle
aSrcRect( rSrcPt
, rSrcSz
);
978 if( aSrcRect
!= aBmpRect
)
979 aBmpEx
.Crop( aSrcRect
);
983 SvMemoryStream
aOStm( 65535, 65535 );
985 if( GraphicConverter::Export( aOStm
, rBmpEx
, CVT_PNG
) == ERRCODE_NONE
)
987 const Point
aPt( ImplMap( rPt
) );
988 const Size
aSz( ImplMap( rSz
) );
989 FastString
aImageData( (sal_Char
*) aOStm
.GetData(), aOStm
.Tell() );
990 REF( NMSP_SAX::XExtendedDocumentHandler
) xExtDocHandler( mrExport
.GetDocHandler(), NMSP_UNO::UNO_QUERY
);
992 if( xExtDocHandler
.is() )
994 static const sal_uInt32 nPartLen
= 64;
995 const NMSP_RTL::OUString
aSpace( ' ' );
996 const NMSP_RTL::OUString
aLineFeed( NMSP_RTL::OUString::valueOf( (sal_Unicode
) 0x0a ) );
997 NMSP_RTL::OUString aString
;
998 NMSP_RTL::OUString aImageString
;
1000 aString
= aLineFeed
;
1001 aString
+= B2UCONST( "<" );
1002 aString
+= NMSP_RTL::OUString::createFromAscii( aXMLElemImage
);
1005 aString
+= NMSP_RTL::OUString::createFromAscii( aXMLAttrX
);
1006 aString
+= B2UCONST( "=\"" );
1007 aString
+= GetValueString( aPt
.X(), mbDoublePoints
);
1008 aString
+= B2UCONST( "\" " );
1010 aString
+= NMSP_RTL::OUString::createFromAscii( aXMLAttrY
);
1011 aString
+= B2UCONST( "=\"" );
1012 aString
+= GetValueString( aPt
.Y(), mbDoublePoints
);
1013 aString
+= B2UCONST( "\" " );
1015 aString
+= NMSP_RTL::OUString::createFromAscii( aXMLAttrWidth
);
1016 aString
+= B2UCONST( "=\"" );
1017 aString
+= GetValueString( aSz
.Width(), mbDoublePoints
);
1018 aString
+= B2UCONST( "\" " );
1020 aString
+= NMSP_RTL::OUString::createFromAscii( aXMLAttrHeight
);
1021 aString
+= B2UCONST( "=\"" );
1022 aString
+= GetValueString( aSz
.Height(), mbDoublePoints
);
1023 aString
+= B2UCONST( "\" " );
1025 aString
+= NMSP_RTL::OUString::createFromAscii( aXMLAttrXLinkHRef
);
1026 aString
+= B2UCONST( "=\"data:image/png;base64," );
1028 if( aImageData
.GetFirstPartString( nPartLen
, aImageString
) )
1030 xExtDocHandler
->unknown( aString
+= aImageString
);
1032 while( aImageData
.GetNextPartString( nPartLen
, aImageString
) )
1034 xExtDocHandler
->unknown( aLineFeed
);
1035 xExtDocHandler
->unknown( aImageString
);
1039 xExtDocHandler
->unknown( B2UCONST( "\"/>" ) );
1046 // -----------------------------------------------------------------------------
1048 void SVGActionWriter::ImplWriteActions( const GDIMetaFile
& rMtf
, const NMSP_RTL::OUString
* pStyle
)
1050 ImplAcquireContext();
1052 for( ULONG i
= 0, nCount
= rMtf
.GetActionCount(); i
< nCount
; i
++ )
1054 const MetaAction
* pAction
= rMtf
.GetAction( i
);
1055 const USHORT nType
= pAction
->GetType();
1059 case( META_PIXEL_ACTION
):
1061 const MetaPixelAction
* pA
= (const MetaPixelAction
*) pAction
;
1063 mpContext
->SetPaintAttr( pA
->GetColor(), pA
->GetColor() );
1064 ImplWriteLine( pA
->GetPoint(), pA
->GetPoint(), &pA
->GetColor(), pStyle
);
1068 case( META_POINT_ACTION
):
1070 const MetaPointAction
* pA
= (const MetaPointAction
*) pAction
;
1072 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetLineColor() );
1073 ImplWriteLine( pA
->GetPoint(), pA
->GetPoint(), NULL
, pStyle
);
1077 case( META_LINE_ACTION
):
1079 const MetaLineAction
* pA
= (const MetaLineAction
*) pAction
;
1081 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetLineColor() );
1082 ImplWriteLine( pA
->GetStartPoint(), pA
->GetEndPoint(), NULL
, pStyle
);
1086 case( META_RECT_ACTION
):
1088 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1089 ImplWriteRect( ( (const MetaRectAction
*) pAction
)->GetRect(), 0, 0, pStyle
);
1093 case( META_ROUNDRECT_ACTION
):
1095 const MetaRoundRectAction
* pA
= (const MetaRoundRectAction
*) pAction
;
1097 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1098 ImplWriteRect( pA
->GetRect(), pA
->GetHorzRound(), pA
->GetVertRound(), pStyle
);
1102 case( META_ELLIPSE_ACTION
):
1104 const MetaEllipseAction
* pA
= (const MetaEllipseAction
*) pAction
;
1105 const Rectangle
& rRect
= pA
->GetRect();
1107 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1108 ImplWriteEllipse( rRect
.Center(), rRect
.GetWidth() >> 1, rRect
.GetHeight() >> 1, pStyle
);
1112 case( META_ARC_ACTION
):
1113 case( META_PIE_ACTION
):
1114 case( META_CHORD_ACTION
):
1115 case( META_POLYGON_ACTION
):
1121 case( META_ARC_ACTION
):
1123 const MetaArcAction
* pA
= (const MetaArcAction
*) pAction
;
1124 aPoly
= Polygon( pA
->GetRect(), pA
->GetStartPoint(), pA
->GetEndPoint(), POLY_ARC
);
1128 case( META_PIE_ACTION
):
1130 const MetaPieAction
* pA
= (const MetaPieAction
*) pAction
;
1131 aPoly
= Polygon( pA
->GetRect(), pA
->GetStartPoint(), pA
->GetEndPoint(), POLY_PIE
);
1135 case( META_CHORD_ACTION
):
1137 const MetaChordAction
* pA
= (const MetaChordAction
*) pAction
;
1138 aPoly
= Polygon( pA
->GetRect(), pA
->GetStartPoint(), pA
->GetEndPoint(), POLY_CHORD
);
1142 case( META_POLYGON_ACTION
):
1143 aPoly
= ( (const MetaPolygonAction
*) pAction
)->GetPolygon();
1147 if( aPoly
.GetSize() )
1149 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1150 ImplWritePolygon( aPoly
, sal_False
, pStyle
);
1155 case( META_POLYLINE_ACTION
):
1157 const MetaPolyLineAction
* pA
= (const MetaPolyLineAction
*) pAction
;
1158 const Polygon
& rPoly
= pA
->GetPolygon();
1160 if( rPoly
.GetSize() )
1162 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1163 ImplWritePolygon( rPoly
, sal_True
, pStyle
);
1168 case( META_POLYPOLYGON_ACTION
):
1170 const MetaPolyPolygonAction
* pA
= (const MetaPolyPolygonAction
*) pAction
;
1171 const PolyPolygon
& rPolyPoly
= pA
->GetPolyPolygon();
1173 if( rPolyPoly
.Count() )
1175 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1176 ImplWritePolyPolygon( rPolyPoly
, sal_False
, pStyle
);
1181 case( META_GRADIENT_ACTION
):
1183 const MetaGradientAction
* pA
= (const MetaGradientAction
*) pAction
;
1184 GDIMetaFile aTmpMtf
;
1186 mpVDev
->AddGradientActions( pA
->GetRect(), pA
->GetGradient(), aTmpMtf
);
1187 ImplWriteActions( aTmpMtf
, pStyle
);
1191 case( META_GRADIENTEX_ACTION
):
1193 const MetaGradientExAction
* pA
= (const MetaGradientExAction
*) pAction
;
1194 ImplWriteGradientEx( pA
->GetPolyPolygon(), pA
->GetGradient(), pStyle
);
1198 case META_HATCH_ACTION
:
1200 const MetaHatchAction
* pA
= (const MetaHatchAction
*) pAction
;
1201 GDIMetaFile aTmpMtf
;
1203 mpVDev
->AddHatchActions( pA
->GetPolyPolygon(), pA
->GetHatch(), aTmpMtf
);
1204 ImplWriteActions( aTmpMtf
, pStyle
);
1208 case( META_TRANSPARENT_ACTION
):
1210 const MetaTransparentAction
* pA
= (const MetaTransparentAction
*) pAction
;
1211 const PolyPolygon
& rPolyPoly
= pA
->GetPolyPolygon();
1213 if( rPolyPoly
.Count() )
1215 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1216 ImplWritePolyPolygon( rPolyPoly
, sal_False
, pStyle
);
1221 case( META_FLOATTRANSPARENT_ACTION
):
1223 const MetaFloatTransparentAction
* pA
= (const MetaFloatTransparentAction
*) pAction
;
1224 GDIMetaFile
aTmpMtf( pA
->GetGDIMetaFile() );
1225 Point
aSrcPt( aTmpMtf
.GetPrefMapMode().GetOrigin() );
1226 const Size
aSrcSize( aTmpMtf
.GetPrefSize() );
1227 const Point
aDestPt( pA
->GetPoint() );
1228 const Size
aDestSize( pA
->GetSize() );
1229 const double fScaleX
= aSrcSize
.Width() ? (double) aDestSize
.Width() / aSrcSize
.Width() : 1.0;
1230 const double fScaleY
= aSrcSize
.Height() ? (double) aDestSize
.Height() / aSrcSize
.Height() : 1.0;
1231 long nMoveX
, nMoveY
;
1233 if( fScaleX
!= 1.0 || fScaleY
!= 1.0 )
1235 aTmpMtf
.Scale( fScaleX
, fScaleY
);
1236 aSrcPt
.X() = FRound( aSrcPt
.X() * fScaleX
), aSrcPt
.Y() = FRound( aSrcPt
.Y() * fScaleY
);
1239 nMoveX
= aDestPt
.X() - aSrcPt
.X(), nMoveY
= aDestPt
.Y() - aSrcPt
.Y();
1241 if( nMoveX
|| nMoveY
)
1242 aTmpMtf
.Move( nMoveX
, nMoveY
);
1245 ImplWriteActions( aTmpMtf
, pStyle
);
1250 case( META_EPS_ACTION
):
1252 const MetaEPSAction
* pA
= (const MetaEPSAction
*) pAction
;
1253 const GDIMetaFile
aGDIMetaFile( pA
->GetSubstitute() );
1254 sal_Bool bFound
= sal_False
;
1256 for( ULONG j
= 0, nCount2
= aGDIMetaFile
.GetActionCount(); ( j
< nCount2
) && !bFound
; j
++ )
1258 const MetaAction
* pSubstAct
= aGDIMetaFile
.GetAction( j
);
1260 if( pSubstAct
->GetType() == META_BMPSCALE_ACTION
)
1263 const MetaBmpScaleAction
* pBmpScaleAction
= (const MetaBmpScaleAction
*) pSubstAct
;
1264 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1265 ImplWriteBmp( pBmpScaleAction
->GetBitmap(),
1266 pA
->GetPoint(), pA
->GetSize(),
1267 Point(), pBmpScaleAction
->GetBitmap().GetSizePixel(), pStyle
);
1273 case( META_COMMENT_ACTION
):
1275 const MetaCommentAction
* pA
= (const MetaCommentAction
*) pAction
;
1276 String aSkipComment
;
1278 if( pA
->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_BEGIN" ) == COMPARE_EQUAL
)
1280 const MetaGradientExAction
* pGradAction
= NULL
;
1281 sal_Bool bDone
= sal_False
;
1283 while( !bDone
&& ( ++i
< nCount
) )
1285 pAction
= rMtf
.GetAction( i
);
1287 if( pAction
->GetType() == META_GRADIENTEX_ACTION
)
1288 pGradAction
= (const MetaGradientExAction
*) pAction
;
1289 else if( ( pAction
->GetType() == META_COMMENT_ACTION
) &&
1290 ( ( (const MetaCommentAction
*) pAction
)->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_END" ) == COMPARE_EQUAL
) )
1297 ImplWriteGradientEx( pGradAction
->GetPolyPolygon(), pGradAction
->GetGradient(), pStyle
);
1302 case( META_BMP_ACTION
):
1304 const MetaBmpAction
* pA
= (const MetaBmpAction
*) pAction
;
1306 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1307 ImplWriteBmp( pA
->GetBitmap(),
1308 pA
->GetPoint(), mpVDev
->PixelToLogic( pA
->GetBitmap().GetSizePixel() ),
1309 Point(), pA
->GetBitmap().GetSizePixel(), pStyle
);
1313 case( META_BMPSCALE_ACTION
):
1315 const MetaBmpScaleAction
* pA
= (const MetaBmpScaleAction
*) pAction
;
1317 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1318 ImplWriteBmp( pA
->GetBitmap(),
1319 pA
->GetPoint(), pA
->GetSize(),
1320 Point(), pA
->GetBitmap().GetSizePixel(), pStyle
);
1324 case( META_BMPSCALEPART_ACTION
):
1326 const MetaBmpScalePartAction
* pA
= (const MetaBmpScalePartAction
*) pAction
;
1328 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1329 ImplWriteBmp( pA
->GetBitmap(),
1330 pA
->GetDestPoint(), pA
->GetDestSize(),
1331 pA
->GetSrcPoint(), pA
->GetSrcSize(), pStyle
);
1335 case( META_BMPEX_ACTION
):
1337 const MetaBmpExAction
* pA
= (const MetaBmpExAction
*) pAction
;
1339 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1340 ImplWriteBmp( pA
->GetBitmapEx(),
1341 pA
->GetPoint(), mpVDev
->PixelToLogic( pA
->GetBitmapEx().GetSizePixel() ),
1342 Point(), pA
->GetBitmapEx().GetSizePixel(), pStyle
);
1346 case( META_BMPEXSCALE_ACTION
):
1348 const MetaBmpExScaleAction
* pA
= (const MetaBmpExScaleAction
*) pAction
;
1350 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1351 ImplWriteBmp( pA
->GetBitmapEx(),
1352 pA
->GetPoint(), pA
->GetSize(),
1353 Point(), pA
->GetBitmapEx().GetSizePixel(), pStyle
);
1357 case( META_BMPEXSCALEPART_ACTION
):
1359 const MetaBmpExScalePartAction
* pA
= (const MetaBmpExScalePartAction
*) pAction
;
1361 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1362 ImplWriteBmp( pA
->GetBitmapEx(),
1363 pA
->GetDestPoint(), pA
->GetDestSize(),
1364 pA
->GetSrcPoint(), pA
->GetSrcSize(), pStyle
);
1368 case( META_TEXT_ACTION
):
1370 const MetaTextAction
* pA
= (const MetaTextAction
*) pAction
;
1372 mpContext
->SetFontAttr( mpVDev
->GetFont() );
1373 mpContext
->SetPaintAttr( COL_TRANSPARENT
, mpVDev
->GetFont().GetColor() );
1374 ImplWriteText( pA
->GetPoint(), String( pA
->GetText(), pA
->GetIndex(), pA
->GetLen() ), NULL
, 0, pStyle
);
1378 case( META_TEXTRECT_ACTION
):
1380 const MetaTextRectAction
* pA
= (const MetaTextRectAction
*) pAction
;
1382 mpContext
->SetFontAttr( mpVDev
->GetFont() );
1383 mpContext
->SetPaintAttr( COL_TRANSPARENT
, mpVDev
->GetFont().GetColor() );
1384 ImplWriteText( pA
->GetRect().TopLeft(), pA
->GetText(), NULL
, 0, pStyle
);
1388 case( META_TEXTARRAY_ACTION
):
1390 const MetaTextArrayAction
* pA
= (const MetaTextArrayAction
*) pAction
;
1391 const Point
aPos( ImplMap( pA
->GetPoint() ) );
1393 mpContext
->SetFontAttr( mpVDev
->GetFont() );
1394 mpContext
->SetPaintAttr( COL_TRANSPARENT
, mpVDev
->GetFont().GetColor() );
1395 ImplWriteText( pA
->GetPoint(), String( pA
->GetText(), pA
->GetIndex(), pA
->GetLen() ), pA
->GetDXArray(), 0, pStyle
);
1399 case( META_STRETCHTEXT_ACTION
):
1401 const MetaStretchTextAction
* pA
= (const MetaStretchTextAction
*) pAction
;
1403 mpContext
->SetFontAttr( mpVDev
->GetFont() );
1404 mpContext
->SetPaintAttr( COL_TRANSPARENT
, mpVDev
->GetFont().GetColor() );
1405 ImplWriteText( pA
->GetPoint(), String( pA
->GetText(), pA
->GetIndex(), pA
->GetLen() ), NULL
, pA
->GetWidth(), pStyle
);
1409 case( META_CLIPREGION_ACTION
):
1410 case( META_ISECTRECTCLIPREGION_ACTION
):
1411 case( META_ISECTREGIONCLIPREGION_ACTION
):
1412 case( META_MOVECLIPREGION_ACTION
):
1414 ( (MetaAction
*) pAction
)->Execute( mpVDev
);
1415 mbClipAttrChanged
= sal_True
;
1419 case( META_REFPOINT_ACTION
):
1420 case( META_MAPMODE_ACTION
):
1421 case( META_LINECOLOR_ACTION
):
1422 case( META_FILLCOLOR_ACTION
):
1423 case( META_TEXTLINECOLOR_ACTION
):
1424 case( META_TEXTFILLCOLOR_ACTION
):
1425 case( META_TEXTCOLOR_ACTION
):
1426 case( META_TEXTALIGN_ACTION
):
1427 case( META_FONT_ACTION
):
1428 case( META_PUSH_ACTION
):
1429 case( META_POP_ACTION
):
1431 ( (MetaAction
*) pAction
)->Execute( mpVDev
);
1435 case( META_RASTEROP_ACTION
):
1436 case( META_MASK_ACTION
):
1437 case( META_MASKSCALE_ACTION
):
1438 case( META_MASKSCALEPART_ACTION
):
1439 case( META_WALLPAPER_ACTION
):
1440 case( META_TEXTLINE_ACTION
):
1441 case( META_LAYOUTMODE_ACTION
):
1443 // !!! >>> we don't want to support these actions
1449 ByteString
aDbgOut( "SVGActionWriter::ImplWriteActions: unsupported MetaAction #" );
1450 aDbgOut
.Append( ByteString::CreateFromInt32( nType
) );
1451 DBG_ERROR( aDbgOut
.GetBuffer() );
1457 ImplReleaseContext();