1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svgaction.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
34 #include "svgaction.hxx"
35 #include <vcl/virdev.hxx>
36 #include <vcl/cvtgrf.hxx>
37 #include <vcl/metric.hxx>
39 #undef _SVG_USE_NATIVE_TEXTDECORATION
40 #undef _SVG_USE_TSPANS
46 static const char aXMLElemSVG
[] = "svg";
47 static const char aXMLElemG
[] = "g";
48 static const char aXMLElemDefs
[] = "defs";
49 static const char aXMLElemClipPath
[] = "clipPath";
50 static const char aXMLElemLine
[] = "line";
51 static const char aXMLElemRect
[] = "rect";
52 static const char aXMLElemEllipse
[] = "ellipse";
53 static const char aXMLElemPath
[] = "path";
54 static const char aXMLElemPolygon
[] = "polygon";
55 static const char aXMLElemPolyLine
[] = "polyline";
56 static const char aXMLElemText
[] = "text";
57 static const char aXMLElemTSpan
[] = "tspan";
58 static const char aXMLElemImage
[] = "image";
60 static const char aXMLAttrTransform
[] = "transform";
61 static const char aXMLAttrStyle
[] = "style";
62 static const char aXMLAttrId
[] = "id";
64 static const char aXMLAttrD
[] = "d";
65 static const char aXMLAttrX
[] = "x";
66 static const char aXMLAttrY
[] = "y";
67 static const char aXMLAttrX1
[] = "x1";
68 static const char aXMLAttrY1
[] = "y1";
69 static const char aXMLAttrX2
[] = "x2";
70 static const char aXMLAttrY2
[] = "y2";
71 static const char aXMLAttrCX
[] = "cx";
72 static const char aXMLAttrCY
[] = "cy";
73 static const char aXMLAttrRX
[] = "rx";
74 static const char aXMLAttrRY
[] = "ry";
75 static const char aXMLAttrWidth
[] = "width";
76 static const char aXMLAttrHeight
[] = "height";
77 static const char aXMLAttrPoints
[] = "points";
78 static const char aXMLAttrXLinkHRef
[] = "xlink:href";
80 static const sal_Unicode pBase64
[] =
83 'A','B','C','D','E','F','G','H', // 0
84 'I','J','K','L','M','N','O','P', // 1
85 'Q','R','S','T','U','V','W','X', // 2
86 'Y','Z','a','b','c','d','e','f', // 3
87 'g','h','i','j','k','l','m','n', // 4
88 'o','p','q','r','s','t','u','v', // 5
89 'w','x','y','z','0','1','2','3', // 6
90 '4','5','6','7','8','9','+','/' // 7
97 FastString::FastString( sal_uInt32 nInitLen
, sal_uInt32 nIncrement
) :
98 mpBuffer( new sal_Unicode
[ nInitLen
* sizeof( sal_Unicode
) ] ),
101 mnBufInc( nIncrement
),
104 DBG_ASSERT( nInitLen
, "invalid initial length" );
105 DBG_ASSERT( nIncrement
, "invalid increment" );
108 // -----------------------------------------------------------------------------
110 FastString::FastString( sal_Char
* pBufferForBase64Encoding
, sal_uInt32 nBufLen
) :
114 DBG_ASSERT( pBufferForBase64Encoding
&& nBufLen
, "invalid arguments" );
116 const sal_uInt32 nQuadCount
= nBufLen
/ 3;
117 const sal_uInt32 nRest
= nBufLen
% 3;
119 if( nQuadCount
|| nRest
)
121 mnBufLen
= mnCurLen
= ( ( nQuadCount
+ ( nRest
? 1 : 0 ) ) << 2 );
122 mpBuffer
= new sal_Unicode
[ mnBufLen
* sizeof( sal_Unicode
) ];
124 sal_Char
* pTmpSrc
= pBufferForBase64Encoding
;
125 sal_Unicode
* pTmpDst
= mpBuffer
;
127 for( sal_uInt32 i
= 0; i
< nQuadCount
; i
++ )
129 const sal_Int32 nA
= *pTmpSrc
++;
130 const sal_Int32 nB
= *pTmpSrc
++;
131 const sal_Int32 nC
= *pTmpSrc
++;
133 *pTmpDst
++ = pBase64
[ ( nA
>> 2 ) & 0x3f ];
134 *pTmpDst
++ = pBase64
[ ( ( nA
<< 4 ) & 0x30 ) + ( ( nB
>> 4 ) & 0xf ) ];
135 *pTmpDst
++ = pBase64
[ ( ( nB
<< 2 ) & 0x3c ) + ( ( nC
>> 6 ) & 0x3 ) ];
136 *pTmpDst
++ = pBase64
[ nC
& 0x3f ];
141 const sal_Int32 nA
= *pTmpSrc
;
143 *pTmpDst
++ = pBase64
[ ( nA
>> 2 ) & 0x3f ];
144 *pTmpDst
++ = pBase64
[ ( nA
<< 4 ) & 0x30 ];
148 else if( 2 == nRest
)
150 const sal_Int32 nA
= *pTmpSrc
++;
151 const sal_Int32 nB
= *pTmpSrc
;
153 *pTmpDst
++ = pBase64
[ ( nA
>> 2 ) & 0x3f ];
154 *pTmpDst
++ = pBase64
[ ( ( nA
<< 4 ) & 0x30 ) + ( ( nB
>> 4 ) & 0xf ) ];
155 *pTmpDst
++ = pBase64
[ ( nB
<< 2 ) & 0x3c ];
161 mpBuffer
= new sal_Unicode
[ ( mnBufLen
= 1 ) * sizeof( sal_Unicode
) ];
166 // -----------------------------------------------------------------------------
168 FastString::~FastString()
173 // -----------------------------------------------------------------------------
175 FastString
& FastString::operator+=( const NMSP_RTL::OUString
& rStr
)
177 if( rStr
.getLength() )
179 if( ( mnCurLen
+ rStr
.getLength() ) > mnBufLen
)
181 const sal_uInt32 nNewBufLen
= ( mnBufLen
+ ( ( ( mnCurLen
+ rStr
.getLength() ) - mnBufLen
) / mnBufInc
+ 1 ) * mnBufInc
);
182 sal_Unicode
* pNewBuffer
= new sal_Unicode
[ nNewBufLen
* sizeof( sal_Unicode
) ];
184 memcpy( pNewBuffer
, mpBuffer
, mnBufLen
* sizeof( sal_Unicode
) );
186 mpBuffer
= pNewBuffer
;
187 mnBufLen
= nNewBufLen
;
190 memcpy( mpBuffer
+ mnCurLen
, rStr
.getStr(), rStr
.getLength() * sizeof( sal_Unicode
) );
191 mnCurLen
+= rStr
.getLength();
193 if( maString
.getLength() )
194 maString
= NMSP_RTL::OUString();
200 // -----------------------------------------------------------------------------
202 const NMSP_RTL::OUString
& FastString::GetString() const
204 if( !maString
.getLength() && mnCurLen
)
205 ( (FastString
*) this )->maString
= NMSP_RTL::OUString( mpBuffer
, mnCurLen
);
210 // -----------------------------------------------------------------------------
212 sal_Bool
FastString::GetFirstPartString( const sal_uInt32 nPartLen
, NMSP_RTL::OUString
& rPartString
)
214 const sal_uInt32 nLength
= Min( mnCurLen
, nPartLen
);
220 rPartString
= NMSP_RTL::OUString( mpBuffer
, nLength
);
224 return( rPartString
.getLength() > 0 );
227 // -----------------------------------------------------------------------------
229 sal_Bool
FastString::GetNextPartString( const sal_uInt32 nPartLen
, NMSP_RTL::OUString
& rPartString
)
231 if( mnPartPos
< mnCurLen
)
233 const sal_uInt32 nLength
= Min( mnCurLen
- mnPartPos
, nPartLen
);
234 rPartString
= NMSP_RTL::OUString( mpBuffer
+ mnPartPos
, nLength
);
235 mnPartPos
+= nLength
;
238 rPartString
= NMSP_RTL::OUString();
240 return( rPartString
.getLength() > 0 );
243 // ----------------------
244 // - SVGAttributeWriter -
245 // ----------------------
247 SVGAttributeWriter::SVGAttributeWriter( SVGActionWriter
& rParent
, SvXMLExport
& rExport
) :
255 // -----------------------------------------------------------------------------
257 SVGAttributeWriter::~SVGAttributeWriter()
263 // -----------------------------------------------------------------------------
265 NMSP_RTL::OUString
SVGAttributeWriter::GetFontStyle( const Font
& rFont
)
270 aStyle
+= B2UCONST( "font-family:" );
271 aStyle
+= NMSP_RTL::OUString( rFont
.GetName().GetToken( 0, ';' ) );
274 aStyle
+= B2UCONST( ";" );
275 aStyle
+= B2UCONST( "font-size:" );
276 aStyle
+= mrParent
.GetValueString( mrParent
.ImplMap( Size( 0, rFont
.GetHeight() ) ).Height(), mrParent
.HasDoublePoints() );
279 if( rFont
.GetItalic() != ITALIC_NONE
)
281 aStyle
+= B2UCONST( ";" );
282 aStyle
+= B2UCONST( "font-style:" );
284 if( rFont
.GetItalic() == ITALIC_OBLIQUE
)
285 aStyle
+= B2UCONST( "oblique" );
287 aStyle
+= B2UCONST( "italic" );
291 sal_Int32 nFontWeight
;
293 switch( rFont
.GetWeight() )
295 case WEIGHT_THIN
: nFontWeight
= 100; break;
296 case WEIGHT_ULTRALIGHT
: nFontWeight
= 200; break;
297 case WEIGHT_LIGHT
: nFontWeight
= 300; break;
298 case WEIGHT_SEMILIGHT
: nFontWeight
= 400; break;
299 case WEIGHT_NORMAL
: nFontWeight
= 400; break;
300 case WEIGHT_MEDIUM
: nFontWeight
= 500; break;
301 case WEIGHT_SEMIBOLD
: nFontWeight
= 600; break;
302 case WEIGHT_BOLD
: nFontWeight
= 700; break;
303 case WEIGHT_ULTRABOLD
: nFontWeight
= 800; break;
304 case WEIGHT_BLACK
: nFontWeight
= 900; break;
305 default: nFontWeight
= 400; break;
308 aStyle
+= B2UCONST( ";" );
309 aStyle
+= B2UCONST( "font-weight:" );
310 aStyle
+= NMSP_RTL::OUString::valueOf( nFontWeight
);
317 #ifdef _SVG_USE_NATIVE_TEXTDECORATION
319 if( rFont
.GetUnderline() != UNDERLINE_NONE
|| rFont
.GetStrikeout() != STRIKEOUT_NONE
)
321 aStyle
+= B2UCONST( ";" );
322 aStyle
+= B2UCONST( "text-decoration:" );
324 if( rFont
.GetUnderline() != UNDERLINE_NONE
)
325 aStyle
+= B2UCONST( " underline" );
327 if( rFont
.GetStrikeout() != STRIKEOUT_NONE
)
328 aStyle
+= B2UCONST( " line-through" );
331 #endif // _SVG_USE_NATIVE_TEXTDECORATION
333 return aStyle
.GetString();
336 // -----------------------------------------------------------------------------
338 NMSP_RTL::OUString
SVGAttributeWriter::GetPaintStyle( const Color
& rLineColor
, const Color
& rFillColor
)
343 aStyle
+= B2UCONST( "stroke:" );
345 if( rLineColor
.GetTransparency() == 255 )
346 aStyle
+= B2UCONST( "none" );
349 // line color value in rgb
350 aStyle
+= B2UCONST( "rgb(" );
351 aStyle
+= NMSP_RTL::OUString::valueOf( (sal_Int32
) rLineColor
.GetRed() );
352 aStyle
+= B2UCONST( "," );
353 aStyle
+= NMSP_RTL::OUString::valueOf( (sal_Int32
) rLineColor
.GetGreen() );
354 aStyle
+= B2UCONST( "," );
355 aStyle
+= NMSP_RTL::OUString::valueOf( (sal_Int32
) rLineColor
.GetBlue() );
356 aStyle
+= B2UCONST( ")" );
358 // line color opacity in percent if neccessary
359 if( rLineColor
.GetTransparency() )
361 aStyle
+= B2UCONST( ";" );
362 aStyle
+= B2UCONST( "stroke-opacity:" );
363 aStyle
+= NMSP_RTL::OUString::valueOf( (sal_Int32
) ( ( 255 - (double) rLineColor
.GetTransparency() ) / 2.55 ) );
364 aStyle
+= B2UCONST( "%" );
369 aStyle
+= B2UCONST( ";" );
370 aStyle
+= B2UCONST( "fill:" );
372 if( rFillColor
.GetTransparency() == 255 )
373 aStyle
+= B2UCONST( "none" );
376 // fill color value in rgb
377 aStyle
+= B2UCONST( "rgb(" );
378 aStyle
+= NMSP_RTL::OUString::valueOf( (sal_Int32
) rFillColor
.GetRed() );
379 aStyle
+= B2UCONST( "," );
380 aStyle
+= NMSP_RTL::OUString::valueOf( (sal_Int32
) rFillColor
.GetGreen() );
381 aStyle
+= B2UCONST( "," );
382 aStyle
+= NMSP_RTL::OUString::valueOf( (sal_Int32
) rFillColor
.GetBlue() );
383 aStyle
+= B2UCONST( ")" );
385 // fill color opacity in percent if neccessary
386 if( rFillColor
.GetTransparency() )
388 aStyle
+= B2UCONST( ";" );
389 aStyle
+= B2UCONST( "fill-opacity:" );
390 aStyle
+= NMSP_RTL::OUString::valueOf( (sal_Int32
) ( ( 255 - (double) rFillColor
.GetTransparency() ) / 2.55 ) );
391 aStyle
+= B2UCONST( "%" );
395 return aStyle
.GetString();
398 // -----------------------------------------------------------------------------
400 void SVGAttributeWriter::SetFontAttr( const Font
& rFont
)
402 if( !mpElemFont
|| ( rFont
!= maCurFont
) )
404 delete mpElemPaint
, mpElemPaint
= NULL
;
406 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, GetFontStyle( maCurFont
= rFont
) );
407 mpElemFont
= new SvXMLElementExport( mrExport
, XML_NAMESPACE_NONE
, aXMLElemG
, TRUE
, TRUE
);
411 // -----------------------------------------------------------------------------
413 void SVGAttributeWriter::SetPaintAttr( const Color
& rLineColor
, const Color
& rFillColor
)
415 if( !mpElemPaint
|| ( rLineColor
!= maCurLineColor
) || ( rFillColor
!= maCurFillColor
) )
418 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, GetPaintStyle( maCurLineColor
= rLineColor
, maCurFillColor
= rFillColor
) );
419 mpElemPaint
= new SvXMLElementExport( mrExport
, XML_NAMESPACE_NONE
, aXMLElemG
, TRUE
, TRUE
);
423 // -------------------
424 // - SVGActionWriter -
425 // -------------------
427 SVGActionWriter::SVGActionWriter( SvXMLExport
& rExport
, const GDIMetaFile
& rMtf
,
428 VirtualDevice
* pParentVDev
, sal_Bool bWriteDoublePoints
) :
433 mbClipAttrChanged( sal_False
),
434 mbDoublePoints( bWriteDoublePoints
)
438 mpVDev
= pParentVDev
;
439 mbDestroyVDev
= sal_False
;
440 maTargetMapMode
= mpVDev
->GetMapMode();
444 mpVDev
= new VirtualDevice
;
445 mpVDev
->EnableOutput( sal_False
);
446 mbDestroyVDev
= sal_True
;
447 maTargetMapMode
= MAP_100TH_MM
;
451 mpVDev
->SetMapMode( mrMtf
.GetPrefMapMode() );
452 ImplWriteActions( mrMtf
);
456 // -----------------------------------------------------------------------------
458 SVGActionWriter::~SVGActionWriter()
460 DBG_ASSERT( !mpContext
, "Not all contexts are closed" );
466 // -----------------------------------------------------------------------------
468 long SVGActionWriter::ImplMap( sal_Int32 nVal
) const
470 return ImplMap( Size( nVal
, nVal
) ).Width();
473 // -----------------------------------------------------------------------------
475 Point
SVGActionWriter::ImplMap( const Point
& rPt
) const
477 return mpVDev
->LogicToLogic( rPt
, mpVDev
->GetMapMode(), maTargetMapMode
);
480 // -----------------------------------------------------------------------------
482 Size
SVGActionWriter::ImplMap( const Size
& rSz
) const
484 return mpVDev
->LogicToLogic( rSz
, mpVDev
->GetMapMode(), maTargetMapMode
);
487 // -----------------------------------------------------------------------------
489 NMSP_RTL::OUString
SVGActionWriter::GetValueString( sal_Int32 nVal
, sal_Bool bDoublePoints
)
492 return NMSP_RTL::OUString::valueOf( nVal
);
495 const double fPoints
= nVal
* 72.0 / 2540.0;
496 const sal_Int32 nInt
= (sal_Int32
) fPoints
;
498 return( ( NMSP_RTL::OUString::valueOf( nInt
) +=
499 NMSP_RTL::OUString::valueOf( (sal_Unicode
) '.' ) ) +=
500 NMSP_RTL::OUString::valueOf( labs( (sal_Int32
) ( ( fPoints
- nInt
) * 100.0 ) ) ) );
504 // -----------------------------------------------------------------------------
506 void SVGActionWriter::ImplWriteLine( const Point
& rPt1
, const Point
& rPt2
, const Color
* pLineColor
,
507 const NMSP_RTL::OUString
* pStyle
)
509 const Point
aPt1( ImplMap( rPt1
) );
510 const Point
aPt2( ImplMap( rPt2
) );
512 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrX1
, GetValueString( aPt1
.X(), mbDoublePoints
) );
513 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrY1
, GetValueString( aPt1
.Y(), mbDoublePoints
) );
514 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrX2
, GetValueString( aPt2
.X(), mbDoublePoints
) );
515 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrY2
, GetValueString( aPt2
.Y(), mbDoublePoints
) );
517 // add additional style if requested
519 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, *pStyle
);
523 // !!! mrExport.AddAttribute( XML_NAMESPACE_NONE, ... )
524 DBG_ERROR( "SVGActionWriter::ImplWriteLine: Line color not implemented" );
528 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_NONE
, aXMLElemLine
, TRUE
, TRUE
);
532 // -----------------------------------------------------------------------------
534 void SVGActionWriter::ImplWriteRect( const Rectangle
& rRect
, long nRadX
, long nRadY
,
535 const NMSP_RTL::OUString
* pStyle
)
537 const Rectangle
aRect( ImplMap( rRect
) );
539 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrX
, GetValueString( aRect
.Left(), mbDoublePoints
) );
540 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrY
, GetValueString( aRect
.Top(), mbDoublePoints
) );
541 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrWidth
, GetValueString( aRect
.GetWidth(), mbDoublePoints
) );
542 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrHeight
, GetValueString( aRect
.GetHeight(), mbDoublePoints
) );
545 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrRX
, GetValueString( ImplMap( nRadX
), mbDoublePoints
) );
548 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrRY
, GetValueString( ImplMap( nRadY
), mbDoublePoints
) );
550 // add additional style if requested
552 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, *pStyle
);
555 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_NONE
, aXMLElemRect
, TRUE
, TRUE
);
559 // -----------------------------------------------------------------------------
561 void SVGActionWriter::ImplWriteEllipse( const Point
& rCenter
, long nRadX
, long nRadY
,
562 const NMSP_RTL::OUString
* pStyle
)
564 const Point
aCenter( ImplMap( rCenter
) );
566 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrCX
, GetValueString( aCenter
.X(), mbDoublePoints
) );
567 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrCY
, GetValueString( aCenter
.Y(), mbDoublePoints
) );
568 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrRX
, GetValueString( ImplMap( nRadX
), mbDoublePoints
) );
569 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrRY
, GetValueString( ImplMap( nRadY
), mbDoublePoints
) );
571 // add additional style if requested
573 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, *pStyle
);
576 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_NONE
, aXMLElemEllipse
, TRUE
, TRUE
);
580 // -----------------------------------------------------------------------------
582 void SVGActionWriter::ImplWritePolygon( const Polygon
& rPoly
, sal_Bool bLineOnly
,
583 const NMSP_RTL::OUString
* pStyle
)
585 if( rPoly
.GetSize() )
587 if( rPoly
.HasFlags() )
588 ImplWritePolyPolygon( rPoly
, bLineOnly
, pStyle
);
593 USHORT i
= 0, nSize
= rPoly
.GetSize();
594 const NMSP_RTL::OUString
aBlank( B2UCONST( " " ) );
599 const Point
aPolyPoint( ImplMap( rPoly
[ i
] ) );
601 aPoints
+= GetValueString( aPolyPoint
.X(), mbDoublePoints
);
602 aPoints
+= B2UCONST( "," );
603 aPoints
+= GetValueString( aPolyPoint
.Y(), mbDoublePoints
);
612 aStyle
+= B2UCONST( "fill:none" );
616 aStyle
+= B2UCONST( ";" );
623 // add point attribute
624 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrPoints
, aPoints
.GetString() );
626 // add style attribute
627 if( aStyle
.GetLength() )
628 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, aStyle
.GetString() );
631 // write polyline/polygon element
632 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_NONE
, bLineOnly
? aXMLElemPolyLine
: aXMLElemPolygon
, TRUE
, TRUE
);
638 // -----------------------------------------------------------------------------
640 void SVGActionWriter::ImplWritePolyPolygon( const PolyPolygon
& rPolyPoly
, sal_Bool bLineOnly
,
641 const NMSP_RTL::OUString
* pStyle
)
643 if( rPolyPoly
.Count() )
645 if( ( rPolyPoly
.Count() == 1 ) && ( rPolyPoly
[ 0 ].HasFlags() == sal_False
) )
646 ImplWritePolygon( rPolyPoly
[ 0 ], bLineOnly
, pStyle
);
650 FastString aPathData
;
651 const NMSP_RTL::OUString
aBlank( B2UCONST( " " ) );
652 const NMSP_RTL::OUString
aComma( B2UCONST( "," ) );
655 for( long i
= 0, nCount
= rPolyPoly
.Count(); i
< nCount
; i
++ )
657 const Polygon
& rPoly
= rPolyPoly
[ (USHORT
) i
];
658 USHORT n
= 1, nSize
= rPoly
.GetSize();
662 aPathData
+= B2UCONST( "M " );
663 aPathData
+= GetValueString( ( aPolyPoint
= ImplMap( rPoly
[ 0 ] ) ).X(), mbDoublePoints
);
665 aPathData
+= GetValueString( aPolyPoint
.Y(), mbDoublePoints
);
666 sal_Char nCurrentMode
= 0;
671 if ( ( rPoly
.GetFlags( n
) == POLY_CONTROL
) && ( ( n
+ 2 ) < nSize
) )
673 if ( nCurrentMode
!= 'C' )
676 aPathData
+= B2UCONST( "C " );
678 for ( int j
= 0; j
< 3; j
++ )
682 aPathData
+= GetValueString( ( aPolyPoint
= ImplMap( rPoly
[ n
++ ] ) ).X(), mbDoublePoints
);
684 aPathData
+= GetValueString( aPolyPoint
.Y(), mbDoublePoints
);
689 if ( nCurrentMode
!= 'L' )
692 aPathData
+= B2UCONST( "L " );
694 aPathData
+= GetValueString( ( aPolyPoint
= ImplMap( rPoly
[ n
++ ] ) ).X(), mbDoublePoints
);
696 aPathData
+= GetValueString( aPolyPoint
.Y(), mbDoublePoints
);
699 aPathData
+= B2UCONST( " Z" );
701 if( i
< ( nCount
- 1 ) )
707 aStyle
+= B2UCONST( "fill:none" );
709 aStyle
+= B2UCONST( ";" );
714 // add style attribute
715 if( aStyle
.GetLength() )
716 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, aStyle
.GetString() );
718 // add path data attribute
719 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrD
, aPathData
.GetString() );
721 // write polyline/polygon element
722 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_NONE
, aXMLElemPath
, TRUE
, TRUE
);
728 // -----------------------------------------------------------------------------
730 void SVGActionWriter::ImplWriteGradientEx( const PolyPolygon
& rPolyPoly
, const Gradient
& rGradient
,
731 const NMSP_RTL::OUString
* pStyle
)
733 if( rPolyPoly
.Count() )
735 SvXMLElementExport
aElemG( mrExport
, XML_NAMESPACE_NONE
, aXMLElemG
, TRUE
, TRUE
);
737 FastString aClipStyle
;
739 aClipId
+= B2UCONST( "clip" );
740 aClipId
+= NMSP_RTL::OUString::valueOf( ImplGetNextClipId() );
743 SvXMLElementExport
aElemDefs( mrExport
, XML_NAMESPACE_NONE
, aXMLElemDefs
, TRUE
, TRUE
);
745 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrId
, aClipId
.GetString() );
748 SvXMLElementExport
aElemClipPath( mrExport
, XML_NAMESPACE_NONE
, aXMLElemClipPath
, TRUE
, TRUE
);
749 ImplWritePolyPolygon( rPolyPoly
, sal_False
);
753 // create new context with clippath set
754 aClipStyle
+= B2UCONST( "clip-path:URL(#" );
755 aClipStyle
+= aClipId
.GetString();
756 aClipStyle
+= B2UCONST( ")" );
758 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, aClipStyle
.GetString() );
762 SvXMLElementExport
aElemG2( mrExport
, XML_NAMESPACE_NONE
, aXMLElemG
, TRUE
, TRUE
);
764 mpVDev
->AddGradientActions( rPolyPoly
.GetBoundRect(), rGradient
, aTmpMtf
);
765 ImplWriteActions( aTmpMtf
, pStyle
);
770 // -----------------------------------------------------------------------------
772 void SVGActionWriter::ImplWriteText( const Point
& rPos
, const String
& rText
,
773 const sal_Int32
* pDXArray
, long nWidth
,
774 const NMSP_RTL::OUString
* pStyle
)
776 String
aText( rText
); aText
.EraseLeadingChars( ' ' );
777 UINT32 nLen
= aText
.Len(), i
;
782 sal_Int32
* pOwnArray
;
789 aNormSize
= Size( mpVDev
->GetTextWidth( aText
), 0 );
790 pDX
= const_cast< sal_Int32
* >( pDXArray
);
794 pOwnArray
= new sal_Int32
[ nLen
];
795 aNormSize
= Size( mpVDev
->GetTextArray( aText
, pOwnArray
), 0 );
801 aNormSize
.Width() = pDX
[ nLen
- 2 ] + mpVDev
->GetTextWidth( aText
.GetChar( (USHORT
) nLen
- 1 ) );
803 if( nWidth
&& aNormSize
.Width() && ( nWidth
!= aNormSize
.Width() ) )
805 const double fFactor
= (double) nWidth
/ aNormSize
.Width();
807 for( i
= 0; i
< ( nLen
- 1 ); i
++ )
808 pDX
[ i
] = FRound( pDX
[ i
] * fFactor
);
813 const Font
& rFont
= mpVDev
->GetFont();
814 const FontMetric
aMetric( mpVDev
->GetFontMetric() );
815 Point
aBaseLinePos( rPos
);
816 SvXMLElementExport
* pTransform
= NULL
;
818 // leading whitespaces erased? => adjust position
819 if( nLen
< rText
.Len() )
821 aBaseLinePos
.X() += mpVDev
->GetTextWidth( ' ' ) * ( rText
.Len() - nLen
);
824 // always adjust text position to match baseline alignment
825 switch( rFont
.GetAlign() )
828 aBaseLinePos
.Y() += aMetric
.GetAscent();
831 case( ALIGN_BOTTOM
):
832 aBaseLinePos
.Y() -= aMetric
.GetDescent();
839 // get mapped text position
840 const Point
aPt( ImplMap( aBaseLinePos
) );
842 // if text is rotated, set transform at new g element
843 if( rFont
.GetOrientation() )
847 aTransform
= NMSP_RTL::OUString::createFromAscii( "translate" );
849 aTransform
+= String( GetValueString( aPt
.X(), mbDoublePoints
) );
851 aTransform
+= String( GetValueString( aPt
.Y(), mbDoublePoints
) );
854 aTransform
+= String( NMSP_RTL::OUString::createFromAscii( " rotate" ) );
856 aTransform
+= String( NMSP_RTL::OUString::valueOf( rFont
.GetOrientation() * -0.1 ) );
859 aTransform
+= String( NMSP_RTL::OUString::createFromAscii( " translate" ) );
861 aTransform
+= String( GetValueString( -aPt
.X(), mbDoublePoints
) );
863 aTransform
+= String( GetValueString( -aPt
.Y(), mbDoublePoints
) );
866 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrTransform
, aTransform
);
867 pTransform
= new SvXMLElementExport( mrExport
, XML_NAMESPACE_NONE
, aXMLElemG
, TRUE
, TRUE
);
870 // add additional style if requested
871 if( pStyle
&& pStyle
->getLength() )
872 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrStyle
, *pStyle
);
874 // write text element
875 #ifdef _SVG_USE_TSPANS
878 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_NONE
, aXMLElemText
, TRUE
, TRUE
);
880 const NMSP_RTL::OUString
aSpace( ' ' );
883 aTSpanX
+= GetValueString( aPt
.X(), mbDoublePoints
);
886 for( i
= 0, nX
= aPt
.X(), nCount
= ( nLen
- 1 ); i
< nCount
; )
888 aTSpanX
+= GetValueString( aPt
.X() + pDX
[ i
++ ], mbDoublePoints
);
892 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrX
, aTSpanX
.GetString() );
893 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrY
, GetValueString( aPt
.Y(), mbDoublePoints
) );
900 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_NONE
, aXMLElemTSpan
, TRUE
, TRUE
);
901 mrExport
.GetDocHandler()->characters( NMSP_RTL::OUString( UniString( aText
) ) );
903 catch( ::com::sun::star::xml::sax::SAXException
& )
905 // string seems to contain invalid characters
913 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrX
, GetValueString( aPt
.X(), mbDoublePoints
) );
914 mrExport
.AddAttribute( XML_NAMESPACE_NONE
, aXMLAttrY
, GetValueString( aPt
.Y(), mbDoublePoints
) );
918 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_NONE
, aXMLElemText
, TRUE
, TRUE
);
919 mrExport
.GetDocHandler()->characters( NMSP_RTL::OUString( UniString( aText
) ) );
921 catch( ::com::sun::star::xml::sax::SAXException
& )
923 // string seems to contain invalid characters
927 #ifndef _SVG_USE_NATIVE_TEXTDECORATION
929 // write strikeout if neccessary
930 if( ( rFont
.GetStrikeout() != STRIKEOUT_NONE
) || ( rFont
.GetUnderline() != UNDERLINE_NONE
) )
933 const long nLineHeight
= Max( (long) FRound( aMetric
.GetLineHeight() * 0.05 ), (long) 1 );
935 if( rFont
.GetStrikeout() )
937 const long nYLinePos
= aBaseLinePos
.Y() - FRound( aMetric
.GetAscent() * 0.26 );
939 aPoly
[ 0 ].X() = aBaseLinePos
.X(); aPoly
[ 0 ].Y() = nYLinePos
- ( nLineHeight
>> 1 );
940 aPoly
[ 1 ].X() = aBaseLinePos
.X() + aNormSize
.Width() - 1; aPoly
[ 1 ].Y() = aPoly
[ 0 ].Y();
941 aPoly
[ 2 ].X() = aPoly
[ 1 ].X(); aPoly
[ 2 ].Y() = aPoly
[ 0 ].Y() + nLineHeight
- 1;
942 aPoly
[ 3 ].X() = aPoly
[ 0 ].X(); aPoly
[ 3 ].Y() = aPoly
[ 2 ].Y();
944 ImplWritePolygon( aPoly
, FALSE
);
947 if( rFont
.GetUnderline() )
949 const long nYLinePos
= aBaseLinePos
.Y() + ( nLineHeight
<< 1 );
951 aPoly
[ 0 ].X() = aBaseLinePos
.X(); aPoly
[ 0 ].Y() = nYLinePos
- ( nLineHeight
>> 1 );
952 aPoly
[ 1 ].X() = aBaseLinePos
.X() + aNormSize
.Width() - 1; aPoly
[ 1 ].Y() = aPoly
[ 0 ].Y();
953 aPoly
[ 2 ].X() = aPoly
[ 1 ].X(); aPoly
[ 2 ].Y() = aPoly
[ 0 ].Y() + nLineHeight
- 1;
954 aPoly
[ 3 ].X() = aPoly
[ 0 ].X(); aPoly
[ 3 ].Y() = aPoly
[ 2 ].Y();
956 ImplWritePolygon( aPoly
, FALSE
);
960 #endif // _SVG_USE_NATIVE_TEXTDECORATION
967 // -----------------------------------------------------------------------------
969 void SVGActionWriter::ImplWriteBmp( const BitmapEx
& rBmpEx
,
970 const Point
& rPt
, const Size
& rSz
,
971 const Point
& rSrcPt
, const Size
& rSrcSz
,
972 const NMSP_RTL::OUString
* /*pStyle*/ )
976 BitmapEx
aBmpEx( rBmpEx
);
977 Point aPoint
= Point();
978 const Rectangle
aBmpRect( aPoint
, rBmpEx
.GetSizePixel() );
979 const Rectangle
aSrcRect( rSrcPt
, rSrcSz
);
981 if( aSrcRect
!= aBmpRect
)
982 aBmpEx
.Crop( aSrcRect
);
986 SvMemoryStream
aOStm( 65535, 65535 );
988 if( GraphicConverter::Export( aOStm
, rBmpEx
, CVT_PNG
) == ERRCODE_NONE
)
990 const Point
aPt( ImplMap( rPt
) );
991 const Size
aSz( ImplMap( rSz
) );
992 FastString
aImageData( (sal_Char
*) aOStm
.GetData(), aOStm
.Tell() );
993 REF( NMSP_SAX::XExtendedDocumentHandler
) xExtDocHandler( mrExport
.GetDocHandler(), NMSP_UNO::UNO_QUERY
);
995 if( xExtDocHandler
.is() )
997 static const sal_uInt32 nPartLen
= 64;
998 const NMSP_RTL::OUString
aSpace( ' ' );
999 const NMSP_RTL::OUString
aLineFeed( NMSP_RTL::OUString::valueOf( (sal_Unicode
) 0x0a ) );
1000 NMSP_RTL::OUString aString
;
1001 NMSP_RTL::OUString aImageString
;
1003 aString
= aLineFeed
;
1004 aString
+= B2UCONST( "<" );
1005 aString
+= NMSP_RTL::OUString::createFromAscii( aXMLElemImage
);
1008 aString
+= NMSP_RTL::OUString::createFromAscii( aXMLAttrX
);
1009 aString
+= B2UCONST( "=\"" );
1010 aString
+= GetValueString( aPt
.X(), mbDoublePoints
);
1011 aString
+= B2UCONST( "\" " );
1013 aString
+= NMSP_RTL::OUString::createFromAscii( aXMLAttrY
);
1014 aString
+= B2UCONST( "=\"" );
1015 aString
+= GetValueString( aPt
.Y(), mbDoublePoints
);
1016 aString
+= B2UCONST( "\" " );
1018 aString
+= NMSP_RTL::OUString::createFromAscii( aXMLAttrWidth
);
1019 aString
+= B2UCONST( "=\"" );
1020 aString
+= GetValueString( aSz
.Width(), mbDoublePoints
);
1021 aString
+= B2UCONST( "\" " );
1023 aString
+= NMSP_RTL::OUString::createFromAscii( aXMLAttrHeight
);
1024 aString
+= B2UCONST( "=\"" );
1025 aString
+= GetValueString( aSz
.Height(), mbDoublePoints
);
1026 aString
+= B2UCONST( "\" " );
1028 aString
+= NMSP_RTL::OUString::createFromAscii( aXMLAttrXLinkHRef
);
1029 aString
+= B2UCONST( "=\"data:image/png;base64," );
1031 if( aImageData
.GetFirstPartString( nPartLen
, aImageString
) )
1033 xExtDocHandler
->unknown( aString
+= aImageString
);
1035 while( aImageData
.GetNextPartString( nPartLen
, aImageString
) )
1037 xExtDocHandler
->unknown( aLineFeed
);
1038 xExtDocHandler
->unknown( aImageString
);
1042 xExtDocHandler
->unknown( B2UCONST( "\"/>" ) );
1049 // -----------------------------------------------------------------------------
1051 void SVGActionWriter::ImplWriteActions( const GDIMetaFile
& rMtf
, const NMSP_RTL::OUString
* pStyle
)
1053 ImplAcquireContext();
1055 for( ULONG i
= 0, nCount
= rMtf
.GetActionCount(); i
< nCount
; i
++ )
1057 const MetaAction
* pAction
= rMtf
.GetAction( i
);
1058 const USHORT nType
= pAction
->GetType();
1062 case( META_PIXEL_ACTION
):
1064 const MetaPixelAction
* pA
= (const MetaPixelAction
*) pAction
;
1066 mpContext
->SetPaintAttr( pA
->GetColor(), pA
->GetColor() );
1067 ImplWriteLine( pA
->GetPoint(), pA
->GetPoint(), &pA
->GetColor(), pStyle
);
1071 case( META_POINT_ACTION
):
1073 const MetaPointAction
* pA
= (const MetaPointAction
*) pAction
;
1075 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetLineColor() );
1076 ImplWriteLine( pA
->GetPoint(), pA
->GetPoint(), NULL
, pStyle
);
1080 case( META_LINE_ACTION
):
1082 const MetaLineAction
* pA
= (const MetaLineAction
*) pAction
;
1084 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetLineColor() );
1085 ImplWriteLine( pA
->GetStartPoint(), pA
->GetEndPoint(), NULL
, pStyle
);
1089 case( META_RECT_ACTION
):
1091 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1092 ImplWriteRect( ( (const MetaRectAction
*) pAction
)->GetRect(), 0, 0, pStyle
);
1096 case( META_ROUNDRECT_ACTION
):
1098 const MetaRoundRectAction
* pA
= (const MetaRoundRectAction
*) pAction
;
1100 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1101 ImplWriteRect( pA
->GetRect(), pA
->GetHorzRound(), pA
->GetVertRound(), pStyle
);
1105 case( META_ELLIPSE_ACTION
):
1107 const MetaEllipseAction
* pA
= (const MetaEllipseAction
*) pAction
;
1108 const Rectangle
& rRect
= pA
->GetRect();
1110 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1111 ImplWriteEllipse( rRect
.Center(), rRect
.GetWidth() >> 1, rRect
.GetHeight() >> 1, pStyle
);
1115 case( META_ARC_ACTION
):
1116 case( META_PIE_ACTION
):
1117 case( META_CHORD_ACTION
):
1118 case( META_POLYGON_ACTION
):
1124 case( META_ARC_ACTION
):
1126 const MetaArcAction
* pA
= (const MetaArcAction
*) pAction
;
1127 aPoly
= Polygon( pA
->GetRect(), pA
->GetStartPoint(), pA
->GetEndPoint(), POLY_ARC
);
1131 case( META_PIE_ACTION
):
1133 const MetaPieAction
* pA
= (const MetaPieAction
*) pAction
;
1134 aPoly
= Polygon( pA
->GetRect(), pA
->GetStartPoint(), pA
->GetEndPoint(), POLY_PIE
);
1138 case( META_CHORD_ACTION
):
1140 const MetaChordAction
* pA
= (const MetaChordAction
*) pAction
;
1141 aPoly
= Polygon( pA
->GetRect(), pA
->GetStartPoint(), pA
->GetEndPoint(), POLY_CHORD
);
1145 case( META_POLYGON_ACTION
):
1146 aPoly
= ( (const MetaPolygonAction
*) pAction
)->GetPolygon();
1150 if( aPoly
.GetSize() )
1152 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1153 ImplWritePolygon( aPoly
, sal_False
, pStyle
);
1158 case( META_POLYLINE_ACTION
):
1160 const MetaPolyLineAction
* pA
= (const MetaPolyLineAction
*) pAction
;
1161 const Polygon
& rPoly
= pA
->GetPolygon();
1163 if( rPoly
.GetSize() )
1165 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1166 ImplWritePolygon( rPoly
, sal_True
, pStyle
);
1171 case( META_POLYPOLYGON_ACTION
):
1173 const MetaPolyPolygonAction
* pA
= (const MetaPolyPolygonAction
*) pAction
;
1174 const PolyPolygon
& rPolyPoly
= pA
->GetPolyPolygon();
1176 if( rPolyPoly
.Count() )
1178 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1179 ImplWritePolyPolygon( rPolyPoly
, sal_False
, pStyle
);
1184 case( META_GRADIENT_ACTION
):
1186 const MetaGradientAction
* pA
= (const MetaGradientAction
*) pAction
;
1187 GDIMetaFile aTmpMtf
;
1189 mpVDev
->AddGradientActions( pA
->GetRect(), pA
->GetGradient(), aTmpMtf
);
1190 ImplWriteActions( aTmpMtf
, pStyle
);
1194 case( META_GRADIENTEX_ACTION
):
1196 const MetaGradientExAction
* pA
= (const MetaGradientExAction
*) pAction
;
1197 ImplWriteGradientEx( pA
->GetPolyPolygon(), pA
->GetGradient(), pStyle
);
1201 case META_HATCH_ACTION
:
1203 const MetaHatchAction
* pA
= (const MetaHatchAction
*) pAction
;
1204 GDIMetaFile aTmpMtf
;
1206 mpVDev
->AddHatchActions( pA
->GetPolyPolygon(), pA
->GetHatch(), aTmpMtf
);
1207 ImplWriteActions( aTmpMtf
, pStyle
);
1211 case( META_TRANSPARENT_ACTION
):
1213 const MetaTransparentAction
* pA
= (const MetaTransparentAction
*) pAction
;
1214 const PolyPolygon
& rPolyPoly
= pA
->GetPolyPolygon();
1216 if( rPolyPoly
.Count() )
1218 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1219 ImplWritePolyPolygon( rPolyPoly
, sal_False
, pStyle
);
1224 case( META_FLOATTRANSPARENT_ACTION
):
1226 const MetaFloatTransparentAction
* pA
= (const MetaFloatTransparentAction
*) pAction
;
1227 GDIMetaFile
aTmpMtf( pA
->GetGDIMetaFile() );
1228 Point
aSrcPt( aTmpMtf
.GetPrefMapMode().GetOrigin() );
1229 const Size
aSrcSize( aTmpMtf
.GetPrefSize() );
1230 const Point
aDestPt( pA
->GetPoint() );
1231 const Size
aDestSize( pA
->GetSize() );
1232 const double fScaleX
= aSrcSize
.Width() ? (double) aDestSize
.Width() / aSrcSize
.Width() : 1.0;
1233 const double fScaleY
= aSrcSize
.Height() ? (double) aDestSize
.Height() / aSrcSize
.Height() : 1.0;
1234 long nMoveX
, nMoveY
;
1236 if( fScaleX
!= 1.0 || fScaleY
!= 1.0 )
1238 aTmpMtf
.Scale( fScaleX
, fScaleY
);
1239 aSrcPt
.X() = FRound( aSrcPt
.X() * fScaleX
), aSrcPt
.Y() = FRound( aSrcPt
.Y() * fScaleY
);
1242 nMoveX
= aDestPt
.X() - aSrcPt
.X(), nMoveY
= aDestPt
.Y() - aSrcPt
.Y();
1244 if( nMoveX
|| nMoveY
)
1245 aTmpMtf
.Move( nMoveX
, nMoveY
);
1248 ImplWriteActions( aTmpMtf
, pStyle
);
1253 case( META_EPS_ACTION
):
1255 const MetaEPSAction
* pA
= (const MetaEPSAction
*) pAction
;
1256 const GDIMetaFile
aGDIMetaFile( pA
->GetSubstitute() );
1257 sal_Bool bFound
= sal_False
;
1259 for( ULONG j
= 0, nCount2
= aGDIMetaFile
.GetActionCount(); ( j
< nCount2
) && !bFound
; j
++ )
1261 const MetaAction
* pSubstAct
= aGDIMetaFile
.GetAction( j
);
1263 if( pSubstAct
->GetType() == META_BMPSCALE_ACTION
)
1266 const MetaBmpScaleAction
* pBmpScaleAction
= (const MetaBmpScaleAction
*) pSubstAct
;
1267 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1268 ImplWriteBmp( pBmpScaleAction
->GetBitmap(),
1269 pA
->GetPoint(), pA
->GetSize(),
1270 Point(), pBmpScaleAction
->GetBitmap().GetSizePixel(), pStyle
);
1276 case( META_COMMENT_ACTION
):
1278 const MetaCommentAction
* pA
= (const MetaCommentAction
*) pAction
;
1279 String aSkipComment
;
1281 if( pA
->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_BEGIN" ) == COMPARE_EQUAL
)
1283 const MetaGradientExAction
* pGradAction
= NULL
;
1284 sal_Bool bDone
= sal_False
;
1286 while( !bDone
&& ( ++i
< nCount
) )
1288 pAction
= rMtf
.GetAction( i
);
1290 if( pAction
->GetType() == META_GRADIENTEX_ACTION
)
1291 pGradAction
= (const MetaGradientExAction
*) pAction
;
1292 else if( ( pAction
->GetType() == META_COMMENT_ACTION
) &&
1293 ( ( (const MetaCommentAction
*) pAction
)->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_END" ) == COMPARE_EQUAL
) )
1300 ImplWriteGradientEx( pGradAction
->GetPolyPolygon(), pGradAction
->GetGradient(), pStyle
);
1305 case( META_BMP_ACTION
):
1307 const MetaBmpAction
* pA
= (const MetaBmpAction
*) pAction
;
1309 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1310 ImplWriteBmp( pA
->GetBitmap(),
1311 pA
->GetPoint(), mpVDev
->PixelToLogic( pA
->GetBitmap().GetSizePixel() ),
1312 Point(), pA
->GetBitmap().GetSizePixel(), pStyle
);
1316 case( META_BMPSCALE_ACTION
):
1318 const MetaBmpScaleAction
* pA
= (const MetaBmpScaleAction
*) pAction
;
1320 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1321 ImplWriteBmp( pA
->GetBitmap(),
1322 pA
->GetPoint(), pA
->GetSize(),
1323 Point(), pA
->GetBitmap().GetSizePixel(), pStyle
);
1327 case( META_BMPSCALEPART_ACTION
):
1329 const MetaBmpScalePartAction
* pA
= (const MetaBmpScalePartAction
*) pAction
;
1331 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1332 ImplWriteBmp( pA
->GetBitmap(),
1333 pA
->GetDestPoint(), pA
->GetDestSize(),
1334 pA
->GetSrcPoint(), pA
->GetSrcSize(), pStyle
);
1338 case( META_BMPEX_ACTION
):
1340 const MetaBmpExAction
* pA
= (const MetaBmpExAction
*) pAction
;
1342 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1343 ImplWriteBmp( pA
->GetBitmapEx(),
1344 pA
->GetPoint(), mpVDev
->PixelToLogic( pA
->GetBitmapEx().GetSizePixel() ),
1345 Point(), pA
->GetBitmapEx().GetSizePixel(), pStyle
);
1349 case( META_BMPEXSCALE_ACTION
):
1351 const MetaBmpExScaleAction
* pA
= (const MetaBmpExScaleAction
*) pAction
;
1353 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1354 ImplWriteBmp( pA
->GetBitmapEx(),
1355 pA
->GetPoint(), pA
->GetSize(),
1356 Point(), pA
->GetBitmapEx().GetSizePixel(), pStyle
);
1360 case( META_BMPEXSCALEPART_ACTION
):
1362 const MetaBmpExScalePartAction
* pA
= (const MetaBmpExScalePartAction
*) pAction
;
1364 mpContext
->SetPaintAttr( mpVDev
->GetLineColor(), mpVDev
->GetFillColor() );
1365 ImplWriteBmp( pA
->GetBitmapEx(),
1366 pA
->GetDestPoint(), pA
->GetDestSize(),
1367 pA
->GetSrcPoint(), pA
->GetSrcSize(), pStyle
);
1371 case( META_TEXT_ACTION
):
1373 const MetaTextAction
* pA
= (const MetaTextAction
*) pAction
;
1375 mpContext
->SetFontAttr( mpVDev
->GetFont() );
1376 mpContext
->SetPaintAttr( COL_TRANSPARENT
, mpVDev
->GetFont().GetColor() );
1377 ImplWriteText( pA
->GetPoint(), String( pA
->GetText(), pA
->GetIndex(), pA
->GetLen() ), NULL
, 0, pStyle
);
1381 case( META_TEXTRECT_ACTION
):
1383 const MetaTextRectAction
* pA
= (const MetaTextRectAction
*) pAction
;
1385 mpContext
->SetFontAttr( mpVDev
->GetFont() );
1386 mpContext
->SetPaintAttr( COL_TRANSPARENT
, mpVDev
->GetFont().GetColor() );
1387 ImplWriteText( pA
->GetRect().TopLeft(), pA
->GetText(), NULL
, 0, pStyle
);
1391 case( META_TEXTARRAY_ACTION
):
1393 const MetaTextArrayAction
* pA
= (const MetaTextArrayAction
*) pAction
;
1394 const Point
aPos( ImplMap( pA
->GetPoint() ) );
1396 mpContext
->SetFontAttr( mpVDev
->GetFont() );
1397 mpContext
->SetPaintAttr( COL_TRANSPARENT
, mpVDev
->GetFont().GetColor() );
1398 ImplWriteText( pA
->GetPoint(), String( pA
->GetText(), pA
->GetIndex(), pA
->GetLen() ), pA
->GetDXArray(), 0, pStyle
);
1402 case( META_STRETCHTEXT_ACTION
):
1404 const MetaStretchTextAction
* pA
= (const MetaStretchTextAction
*) pAction
;
1406 mpContext
->SetFontAttr( mpVDev
->GetFont() );
1407 mpContext
->SetPaintAttr( COL_TRANSPARENT
, mpVDev
->GetFont().GetColor() );
1408 ImplWriteText( pA
->GetPoint(), String( pA
->GetText(), pA
->GetIndex(), pA
->GetLen() ), NULL
, pA
->GetWidth(), pStyle
);
1412 case( META_CLIPREGION_ACTION
):
1413 case( META_ISECTRECTCLIPREGION_ACTION
):
1414 case( META_ISECTREGIONCLIPREGION_ACTION
):
1415 case( META_MOVECLIPREGION_ACTION
):
1417 ( (MetaAction
*) pAction
)->Execute( mpVDev
);
1418 mbClipAttrChanged
= sal_True
;
1422 case( META_REFPOINT_ACTION
):
1423 case( META_MAPMODE_ACTION
):
1424 case( META_LINECOLOR_ACTION
):
1425 case( META_FILLCOLOR_ACTION
):
1426 case( META_TEXTLINECOLOR_ACTION
):
1427 case( META_TEXTFILLCOLOR_ACTION
):
1428 case( META_TEXTCOLOR_ACTION
):
1429 case( META_TEXTALIGN_ACTION
):
1430 case( META_FONT_ACTION
):
1431 case( META_PUSH_ACTION
):
1432 case( META_POP_ACTION
):
1434 ( (MetaAction
*) pAction
)->Execute( mpVDev
);
1438 case( META_RASTEROP_ACTION
):
1439 case( META_MASK_ACTION
):
1440 case( META_MASKSCALE_ACTION
):
1441 case( META_MASKSCALEPART_ACTION
):
1442 case( META_WALLPAPER_ACTION
):
1443 case( META_TEXTLINE_ACTION
):
1444 case( META_LAYOUTMODE_ACTION
):
1446 // !!! >>> we don't want to support these actions
1452 ByteString
aDbgOut( "SVGActionWriter::ImplWriteActions: unsupported MetaAction #" );
1453 aDbgOut
.Append( ByteString::CreateFromInt32( nType
) );
1454 DBG_ERROR( aDbgOut
.GetBuffer() );
1460 ImplReleaseContext();