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 : #include "winmtf.hxx"
21 : #include <basegfx/matrix/b2dhommatrix.hxx>
22 : #include <basegfx/polygon/b2dpolypolygontools.hxx>
23 : #include <vcl/metaact.hxx>
24 : #include <vcl/graphictools.hxx>
25 : #include <vcl/canvastools.hxx>
26 : #include <vcl/metric.hxx>
27 : #include <vcl/svapp.hxx>
28 : #include <rtl/strbuf.hxx>
29 : #include <rtl/tencinfo.h>
30 :
31 : // ------------------------------------------------------------------------
32 :
33 : #if OSL_DEBUG_LEVEL > 1
34 : #define EMFP_DEBUG(x) x
35 : #else
36 : #define EMFP_DEBUG(x)
37 : #endif
38 :
39 3 : void WinMtfClipPath::intersectClipRect( const Rectangle& rRect )
40 : {
41 : maClip.intersectRange(
42 3 : vcl::unotools::b2DRectangleFromRectangle(rRect));
43 3 : }
44 :
45 0 : void WinMtfClipPath::excludeClipRect( const Rectangle& rRect )
46 : {
47 : maClip.subtractRange(
48 0 : vcl::unotools::b2DRectangleFromRectangle(rRect));
49 0 : }
50 :
51 8 : void WinMtfClipPath::setClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode )
52 : {
53 8 : const basegfx::B2DPolyPolygon& rB2DPoly=rPolyPolygon.getB2DPolyPolygon();
54 8 : switch ( nClippingMode )
55 : {
56 : case RGN_OR :
57 0 : maClip.unionPolyPolygon(rB2DPoly);
58 0 : break;
59 : case RGN_XOR :
60 0 : maClip.xorPolyPolygon(rB2DPoly);
61 0 : break;
62 : case RGN_DIFF :
63 0 : maClip.subtractPolyPolygon(rB2DPoly);
64 0 : break;
65 : case RGN_AND :
66 5 : maClip.intersectPolyPolygon(rB2DPoly);
67 5 : break;
68 : case RGN_COPY :
69 3 : maClip = basegfx::tools::B2DClipState(rB2DPoly);
70 3 : break;
71 8 : }
72 8 : }
73 :
74 0 : void WinMtfClipPath::moveClipRegion( const Size& rSize )
75 : {
76 : // what a weird concept. emulate, don't want this in B2DClipState
77 : // API
78 0 : basegfx::B2DPolyPolygon aCurrClip=maClip.getClipPoly();
79 0 : basegfx::B2DHomMatrix aTranslate;
80 0 : aTranslate.translate(rSize.Width(), rSize.Height());
81 :
82 0 : aCurrClip.transform(aTranslate);
83 0 : maClip = basegfx::tools::B2DClipState( aCurrClip );
84 0 : }
85 :
86 8 : basegfx::B2DPolyPolygon WinMtfClipPath::getClipPath() const
87 : {
88 8 : return maClip.getClipPoly();
89 : }
90 :
91 : // ------------------------------------------------------------------------
92 :
93 21 : void WinMtfPathObj::AddPoint( const Point& rPoint )
94 : {
95 21 : if ( bClosed )
96 19 : Insert( Polygon(), POLYPOLY_APPEND );
97 21 : Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
98 21 : rPoly.Insert( rPoly.GetSize(), rPoint, POLY_NORMAL );
99 21 : bClosed = sal_False;
100 21 : }
101 :
102 21 : void WinMtfPathObj::AddPolyLine( const Polygon& rPolyLine )
103 : {
104 21 : if ( bClosed )
105 0 : Insert( Polygon(), POLYPOLY_APPEND );
106 21 : Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
107 21 : rPoly.Insert( rPoly.GetSize(), rPolyLine );
108 21 : bClosed = sal_False;
109 21 : }
110 :
111 0 : void WinMtfPathObj::AddPolygon( const Polygon& rPoly )
112 : {
113 0 : Insert( rPoly, POLYPOLY_APPEND );
114 0 : bClosed = sal_True;
115 0 : }
116 :
117 0 : void WinMtfPathObj::AddPolyPolygon( const PolyPolygon& rPolyPoly )
118 : {
119 0 : sal_uInt16 i, nCount = rPolyPoly.Count();
120 0 : for ( i = 0; i < nCount; i++ )
121 0 : Insert( rPolyPoly[ i ], POLYPOLY_APPEND );
122 0 : bClosed = sal_True;
123 0 : }
124 :
125 13 : void WinMtfPathObj::ClosePath()
126 : {
127 13 : if ( Count() )
128 : {
129 13 : Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
130 13 : if ( rPoly.GetSize() > 2 )
131 : {
132 13 : Point aFirst( rPoly[ 0 ] );
133 13 : if ( aFirst != rPoly[ rPoly.GetSize() - 1 ] )
134 13 : rPoly.Insert( rPoly.GetSize(), aFirst, POLY_NORMAL );
135 : }
136 : }
137 13 : bClosed = sal_True;
138 13 : }
139 :
140 : // ------------------------------------------------------------------------
141 :
142 65 : WinMtfFontStyle::WinMtfFontStyle( LOGFONTW& rFont )
143 : {
144 : CharSet eCharSet;
145 65 : if ( ( rFont.lfCharSet == OEM_CHARSET ) || ( rFont.lfCharSet == DEFAULT_CHARSET ) )
146 1 : eCharSet = RTL_TEXTENCODING_MS_1252;
147 : else
148 64 : eCharSet = rtl_getTextEncodingFromWindowsCharset( rFont.lfCharSet );
149 65 : if ( eCharSet == RTL_TEXTENCODING_DONTKNOW )
150 0 : eCharSet = RTL_TEXTENCODING_MS_1252;
151 65 : aFont.SetCharSet( eCharSet );
152 65 : aFont.SetName( rFont.alfFaceName );
153 : FontFamily eFamily;
154 65 : switch ( rFont.lfPitchAndFamily & 0xf0 )
155 : {
156 : case FF_ROMAN:
157 0 : eFamily = FAMILY_ROMAN;
158 0 : break;
159 :
160 : case FF_SWISS:
161 61 : eFamily = FAMILY_SWISS;
162 61 : break;
163 :
164 : case FF_MODERN:
165 0 : eFamily = FAMILY_MODERN;
166 0 : break;
167 :
168 : case FF_SCRIPT:
169 0 : eFamily = FAMILY_SCRIPT;
170 0 : break;
171 :
172 : case FF_DECORATIVE:
173 0 : eFamily = FAMILY_DECORATIVE;
174 0 : break;
175 :
176 : default:
177 4 : eFamily = FAMILY_DONTKNOW;
178 4 : break;
179 : }
180 65 : aFont.SetFamily( eFamily );
181 :
182 : FontPitch ePitch;
183 65 : switch ( rFont.lfPitchAndFamily & 0x0f )
184 : {
185 : case FIXED_PITCH:
186 0 : ePitch = PITCH_FIXED;
187 0 : break;
188 :
189 : case DEFAULT_PITCH:
190 : case VARIABLE_PITCH:
191 : default:
192 65 : ePitch = PITCH_VARIABLE;
193 65 : break;
194 : }
195 65 : aFont.SetPitch( ePitch );
196 :
197 : FontWeight eWeight;
198 65 : if( rFont.lfWeight <= FW_THIN )
199 0 : eWeight = WEIGHT_THIN;
200 65 : else if( rFont.lfWeight <= FW_ULTRALIGHT )
201 0 : eWeight = WEIGHT_ULTRALIGHT;
202 65 : else if( rFont.lfWeight <= FW_LIGHT )
203 0 : eWeight = WEIGHT_LIGHT;
204 65 : else if( rFont.lfWeight < FW_MEDIUM )
205 64 : eWeight = WEIGHT_NORMAL;
206 1 : else if( rFont.lfWeight == FW_MEDIUM )
207 0 : eWeight = WEIGHT_MEDIUM;
208 1 : else if( rFont.lfWeight <= FW_SEMIBOLD )
209 0 : eWeight = WEIGHT_SEMIBOLD;
210 1 : else if( rFont.lfWeight <= FW_BOLD )
211 1 : eWeight = WEIGHT_BOLD;
212 0 : else if( rFont.lfWeight <= FW_ULTRABOLD )
213 0 : eWeight = WEIGHT_ULTRABOLD;
214 : else
215 0 : eWeight = WEIGHT_BLACK;
216 65 : aFont.SetWeight( eWeight );
217 :
218 65 : if( rFont.lfItalic )
219 0 : aFont.SetItalic( ITALIC_NORMAL );
220 :
221 65 : if( rFont.lfUnderline )
222 0 : aFont.SetUnderline( UNDERLINE_SINGLE );
223 :
224 65 : if( rFont.lfStrikeOut )
225 0 : aFont.SetStrikeout( STRIKEOUT_SINGLE );
226 :
227 65 : if ( rFont.lfOrientation )
228 0 : aFont.SetOrientation( (short)rFont.lfOrientation );
229 : else
230 65 : aFont.SetOrientation( (short)rFont.lfEscapement );
231 :
232 65 : Size aFontSize( Size( rFont.lfWidth, rFont.lfHeight ) );
233 65 : if ( rFont.lfHeight > 0 )
234 : {
235 : // converting the cell height into a font height
236 0 : VirtualDevice aVDev;
237 0 : aFont.SetSize( aFontSize );
238 0 : aVDev.SetFont( aFont );
239 0 : FontMetric aMetric( aVDev.GetFontMetric() );
240 0 : long nHeight = aMetric.GetAscent() + aMetric.GetDescent();
241 0 : if ( nHeight )
242 : {
243 0 : double fHeight = ((double)aFontSize.Height() * rFont.lfHeight ) / nHeight;
244 0 : aFontSize.Height() = (sal_Int32)( fHeight + 0.5 );
245 0 : }
246 : }
247 65 : else if ( aFontSize.Height() < 0 )
248 65 : aFontSize.Height() *= -1;
249 :
250 65 : if ( !rFont.lfWidth )
251 : {
252 63 : VirtualDevice aVDev;
253 63 : aFont.SetSize( aFontSize );
254 63 : aVDev.SetFont( aFont );
255 63 : FontMetric aMetric( aVDev.GetFontMetric() );
256 63 : aFontSize.Width() = aMetric.GetWidth();
257 : }
258 :
259 65 : aFont.SetSize( aFontSize );
260 65 : };
261 :
262 : // ------------------------------------------------------------------------
263 :
264 : #ifdef WIN_MTF_ASSERT
265 : void WinMtfAssertHandler( const sal_Char* pAction, sal_uInt32 nFlags )
266 : {
267 : static sal_Bool bOnlyOnce;
268 : static sal_Int32 nAssertCount;
269 :
270 : if ( nFlags & WIN_MTF_ASSERT_INIT )
271 : nAssertCount = 0;
272 : if ( nFlags & WIN_MTF_ASSERT_ONCE )
273 : bOnlyOnce = sal_True;
274 : if ( nFlags & WIN_MTF_ASSERT_MIFE )
275 : {
276 : if ( ( nAssertCount == 0 ) || ( bOnlyOnce == sal_False ) )
277 : {
278 : rtl::OStringBuffer aText(RTL_CONSTASCII_STRINGPARAM(
279 : "WMF/EMF Import: "));
280 : if (pAction)
281 : aText.append(pAction);
282 : aText.append(RTL_CONSTASCII_STRINGPARAM(
283 : " needs to be implemented"));
284 : DBG_ASSERT( 0, aText.getStr() );
285 : }
286 : nAssertCount++;
287 : }
288 : }
289 : #endif
290 :
291 : // ------------------------------------------------------------------------
292 :
293 28 : WinMtf::WinMtf( WinMtfOutput* pWinMtfOutput, SvStream& rStreamWMF, FilterConfigItem* pConfigItem ) :
294 : pOut ( pWinMtfOutput ),
295 : pWMF ( &rStreamWMF ),
296 28 : pFilterConfigItem ( pConfigItem )
297 : {
298 : #ifdef WIN_MTF_ASSERT
299 : // we want to assert not implemented features, but we do this
300 : // only once, so that nobody is handicaped by getting too much assertions
301 : // I hope this will bring more testdocuments, without support of these
302 : // testdocuments the implementation of missing features won't be possible. (SJ)
303 : WinMtfAssertHandler( NULL, WIN_MTF_ASSERT_INIT | WIN_MTF_ASSERT_ONCE );
304 : #endif
305 :
306 28 : SvLockBytes *pLB = pWMF->GetLockBytes();
307 28 : if ( pLB )
308 3 : pLB->SetSynchronMode( sal_True );
309 :
310 28 : nStartPos = pWMF->Tell();
311 :
312 28 : pOut->SetDevOrg( Point() );
313 28 : if ( pFilterConfigItem )
314 : {
315 0 : xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
316 0 : if ( xStatusIndicator.is() )
317 : {
318 0 : rtl::OUString aMsg;
319 0 : xStatusIndicator->start( aMsg, 100 );
320 : }
321 : }
322 28 : }
323 :
324 : // ------------------------------------------------------------------------
325 :
326 56 : WinMtf::~WinMtf()
327 : {
328 28 : delete pOut;
329 :
330 28 : if ( xStatusIndicator.is() )
331 0 : xStatusIndicator->end();
332 28 : }
333 :
334 : // ------------------------------------------------------------------------
335 :
336 86 : void WinMtf::Callback( sal_uInt16 nPercent )
337 : {
338 86 : if ( xStatusIndicator.is() )
339 0 : xStatusIndicator->setValue( nPercent );
340 86 : }
341 :
342 : // ------------------------------------------------------------------------
343 :
344 353 : Color WinMtf::ReadColor()
345 : {
346 : sal_uInt32 nColor;
347 353 : *pWMF >> nColor;
348 353 : return Color( (sal_uInt8)nColor, (sal_uInt8)( nColor >> 8 ), (sal_uInt8)( nColor >> 16 ) );
349 : };
350 :
351 : //-----------------------------------------------------------------------------------
352 : //-----------------------------------------------------------------------------------
353 : //-----------------------------------------------------------------------------------
354 :
355 5572 : Point WinMtfOutput::ImplMap( const Point& rPt )
356 : {
357 5572 : if ( mnWinExtX && mnWinExtY )
358 : {
359 5572 : double fX = rPt.X();
360 5572 : double fY = rPt.Y();
361 :
362 5572 : double fX2 = fX * maXForm.eM11 + fY * maXForm.eM21 + maXForm.eDx;
363 5572 : double fY2 = fX * maXForm.eM12 + fY * maXForm.eM22 + maXForm.eDy;
364 :
365 5572 : if ( mnGfxMode == GM_COMPATIBLE )
366 : {
367 5572 : switch( mnMapMode )
368 : {
369 : case MM_TEXT:
370 777 : fX2 -= mnWinOrgX;
371 777 : fY2 -= mnWinOrgY;
372 777 : if( mnDevWidth != 1 || mnDevHeight != 1 ) {
373 0 : fX2 *= 2540.0/mnUnitsPerInch;
374 0 : fY2 *= 2540.0/mnUnitsPerInch;
375 : }
376 777 : fX2 += mnDevOrgX;
377 777 : fY2 += mnDevOrgY;
378 777 : fX2 *= (double)mnMillX * 100.0 / (double)mnPixX;
379 777 : fY2 *= (double)mnMillY * 100.0 / (double)mnPixY;
380 :
381 777 : break;
382 : case MM_LOENGLISH :
383 : {
384 0 : fX2 -= mnWinOrgX;
385 0 : fY2 = mnWinOrgY-fY2;
386 0 : fX2 *= 25.40;
387 0 : fY2 *= 25.40;
388 0 : fX2 += mnDevOrgX;
389 0 : fY2 += mnDevOrgY;
390 : }
391 0 : break;
392 : case MM_HIENGLISH :
393 : {
394 0 : fX2 -= mnWinOrgX;
395 0 : fY2 = mnWinOrgY-fY2;
396 0 : fX2 *= 2.540;
397 0 : fY2 *= 2.540;
398 0 : fX2 += mnDevOrgX;
399 0 : fY2 += mnDevOrgY;
400 : }
401 0 : break;
402 : case MM_LOMETRIC :
403 : {
404 0 : fX2 -= mnWinOrgX;
405 0 : fY2 = mnWinOrgY-fY2;
406 0 : fX2 *= 10;
407 0 : fY2 *= 10;
408 0 : fX2 += mnDevOrgX;
409 0 : fY2 += mnDevOrgY;
410 : }
411 0 : break;
412 : case MM_HIMETRIC :
413 : {
414 0 : fX2 -= mnWinOrgX;
415 0 : fY2 = mnWinOrgY-fY2;
416 0 : fX2 += mnDevOrgX;
417 0 : fY2 += mnDevOrgY;
418 : }
419 0 : break;
420 : default :
421 : {
422 4795 : fX2 -= mnWinOrgX;
423 4795 : fY2 -= mnWinOrgY;
424 4795 : fX2 /= mnWinExtX;
425 4795 : fY2 /= mnWinExtY;
426 4795 : fX2 *= mnDevWidth;
427 4795 : fY2 *= mnDevHeight;
428 4795 : fX2 += mnDevOrgX;
429 4795 : fY2 += mnDevOrgY; // fX2, fY2 now in device units
430 4795 : fX2 *= (double)mnMillX * 100.0 / (double)mnPixX;
431 4795 : fY2 *= (double)mnMillY * 100.0 / (double)mnPixY;
432 : }
433 4795 : break;
434 : }
435 5572 : fX2 -= mrclFrame.Left();
436 5572 : fY2 -= mrclFrame.Top();
437 : }
438 5572 : return Point( FRound( fX2 ), FRound( fY2 ) );
439 : }
440 : else
441 0 : return Point();
442 : };
443 :
444 : // ------------------------------------------------------------------------
445 :
446 543 : Size WinMtfOutput::ImplMap( const Size& rSz )
447 : {
448 543 : if ( mnWinExtX && mnWinExtY )
449 : {
450 543 : double fWidth = rSz.Width() * maXForm.eM11;
451 543 : double fHeight = rSz.Height() * maXForm.eM22;
452 :
453 543 : if ( mnGfxMode == GM_COMPATIBLE )
454 : {
455 543 : switch( mnMapMode )
456 : {
457 : case MM_TEXT:
458 414 : if( mnDevWidth != 1 && mnDevHeight != 1 ) {
459 0 : fWidth *= 2540.0/mnUnitsPerInch;
460 0 : fHeight*= 2540.0/mnUnitsPerInch;
461 : } else {
462 414 : fWidth *= (double)mnMillX * 100 / (double)mnPixX;
463 414 : fHeight *= (double)mnMillY * 100 / (double)mnPixY;
464 : }
465 414 : break;
466 : case MM_LOENGLISH :
467 : {
468 0 : fWidth *= 25.40;
469 0 : fHeight*=-25.40;
470 : }
471 0 : break;
472 : case MM_HIENGLISH :
473 : {
474 0 : fWidth *= 2.540;
475 0 : fHeight*=-2.540;
476 : }
477 0 : break;
478 : case MM_LOMETRIC :
479 : {
480 0 : fWidth *= 10;
481 0 : fHeight*=-10;
482 : }
483 0 : break;
484 : case MM_HIMETRIC :
485 : {
486 0 : fHeight *= -1;
487 : }
488 0 : break;
489 : default :
490 : {
491 129 : fWidth /= mnWinExtX;
492 129 : fHeight /= mnWinExtY;
493 129 : fWidth *= mnDevWidth;
494 129 : fHeight *= mnDevHeight;
495 129 : fWidth *= (double)mnMillX * 100 / (double)mnPixX;
496 129 : fHeight *= (double)mnMillY * 100 / (double)mnPixY;
497 : }
498 129 : break;
499 : }
500 : }
501 543 : return Size( FRound( fWidth ), FRound( fHeight ) );
502 : }
503 : else
504 0 : return Size();
505 : }
506 :
507 : //-----------------------------------------------------------------------------------
508 :
509 42 : Rectangle WinMtfOutput::ImplMap( const Rectangle& rRect )
510 : {
511 42 : return Rectangle( ImplMap( rRect.TopLeft() ), ImplMap( rRect.GetSize() ) );
512 : }
513 :
514 : //-----------------------------------------------------------------------------------
515 :
516 65 : void WinMtfOutput::ImplMap( Font& rFont )
517 : {
518 : // !!! HACK: Wir setzen die Breite jetzt immer auf Null,
519 : // da OS die Breite unterschiedlich interpretieren;
520 : // muss spaeter in SV portabel gemacht werden ( KA 08.02.96 )
521 65 : Size aFontSize = ImplMap ( rFont.GetSize() );
522 :
523 65 : if( aFontSize.Height() < 0 )
524 1 : aFontSize.Height() *= -1;
525 :
526 65 : rFont.SetSize( aFontSize );
527 :
528 65 : if( ( mnWinExtX * mnWinExtY ) < 0 )
529 0 : rFont.SetOrientation( 3600 - rFont.GetOrientation() );
530 65 : }
531 :
532 : //-----------------------------------------------------------------------------------
533 :
534 222 : Polygon& WinMtfOutput::ImplMap( Polygon& rPolygon )
535 : {
536 222 : sal_uInt16 nPoints = rPolygon.GetSize();
537 5635 : for ( sal_uInt16 i = 0; i < nPoints; i++ )
538 : {
539 5413 : rPolygon[ i ] = ImplMap( rPolygon[ i ] );
540 : }
541 222 : return rPolygon;
542 : }
543 :
544 : //-----------------------------------------------------------------------------------
545 :
546 9 : PolyPolygon& WinMtfOutput::ImplMap( PolyPolygon& rPolyPolygon )
547 : {
548 9 : sal_uInt16 nPolys = rPolyPolygon.Count();
549 9 : for ( sal_uInt16 i = 0; i < nPolys; ImplMap( rPolyPolygon[ i++ ] ) ) ;
550 9 : return rPolyPolygon;
551 : }
552 :
553 : //-----------------------------------------------------------------------------------
554 :
555 684 : void WinMtfOutput::SelectObject( sal_Int32 nIndex )
556 : {
557 684 : GDIObj* pGDIObj = NULL;
558 :
559 684 : if ( nIndex & ENHMETA_STOCK_OBJECT )
560 319 : pGDIObj = new GDIObj();
561 : else
562 : {
563 365 : nIndex &= 0xffff; // zur Sicherheit: mehr als 65535 nicht zulassen
564 :
565 365 : if ( (sal_uInt32)nIndex < vGDIObj.size() )
566 365 : pGDIObj = vGDIObj[ nIndex ];
567 : }
568 :
569 684 : if( pGDIObj == NULL )
570 689 : return;
571 :
572 679 : if ( nIndex & ENHMETA_STOCK_OBJECT )
573 : {
574 319 : sal_uInt16 nStockId = (sal_uInt8)nIndex;
575 319 : switch( nStockId )
576 : {
577 : case WHITE_BRUSH :
578 : {
579 3 : pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_WHITE ) ) );
580 : }
581 3 : break;
582 : case LTGRAY_BRUSH :
583 : {
584 63 : pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_LIGHTGRAY ) ) );
585 : }
586 63 : break;
587 : case GRAY_BRUSH :
588 : case DKGRAY_BRUSH :
589 : {
590 3 : pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_GRAY ) ) );
591 : }
592 3 : break;
593 : case BLACK_BRUSH :
594 : {
595 3 : pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_BLACK ) ) );
596 : }
597 3 : break;
598 : case NULL_BRUSH :
599 : {
600 0 : pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_TRANSPARENT ), sal_True ) );
601 : }
602 0 : break;
603 : case WHITE_PEN :
604 : {
605 0 : pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_WHITE ) ) );
606 : }
607 0 : break;
608 : case BLACK_PEN :
609 : {
610 192 : pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_BLACK ) ) );
611 : }
612 192 : break;
613 : case NULL_PEN :
614 : {
615 0 : pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_TRANSPARENT ), sal_True ) );
616 : }
617 0 : break;
618 : default:
619 55 : break;
620 : }
621 : }
622 679 : if ( pGDIObj->pStyle )
623 : {
624 624 : switch( pGDIObj->eType )
625 : {
626 : case GDI_PEN :
627 406 : maLineStyle = (WinMtfLineStyle*)pGDIObj->pStyle;
628 406 : break;
629 : case GDI_BRUSH :
630 : {
631 153 : maFillStyle = (WinMtfFillStyle*)pGDIObj->pStyle;
632 153 : mbFillStyleSelected = sal_True;
633 : }
634 153 : break;
635 : case GDI_FONT :
636 65 : maFont = ((WinMtfFontStyle*)pGDIObj->pStyle)->aFont;
637 65 : break;
638 : default:
639 0 : break; // -Wall many options not handled.
640 : }
641 : }
642 679 : if ( nIndex & ENHMETA_STOCK_OBJECT )
643 319 : delete pGDIObj;
644 : }
645 :
646 : //-----------------------------------------------------------------------------------
647 :
648 0 : const Font& WinMtfOutput::GetFont() const
649 : {
650 0 : return maFont;
651 : }
652 :
653 : //-----------------------------------------------------------------------------------
654 :
655 65 : void WinMtfOutput::SetTextLayoutMode( const sal_uInt32 nTextLayoutMode )
656 : {
657 65 : mnTextLayoutMode = nTextLayoutMode;
658 65 : }
659 :
660 : //-----------------------------------------------------------------------------------
661 :
662 11 : void WinMtfOutput::SetBkMode( sal_uInt32 nMode )
663 : {
664 11 : mnBkMode = nMode;
665 11 : }
666 :
667 : //-----------------------------------------------------------------------------------
668 :
669 6 : void WinMtfOutput::SetBkColor( const Color& rColor )
670 : {
671 6 : maBkColor = rColor;
672 6 : }
673 :
674 : //-----------------------------------------------------------------------------------
675 :
676 62 : void WinMtfOutput::SetTextColor( const Color& rColor )
677 : {
678 62 : maTextColor = rColor;
679 62 : }
680 :
681 : //-----------------------------------------------------------------------------------
682 :
683 59 : void WinMtfOutput::SetTextAlign( sal_uInt32 nAlign )
684 : {
685 59 : mnTextAlign = nAlign;
686 59 : }
687 :
688 : //-----------------------------------------------------------------------------------
689 :
690 17 : void WinMtfOutput::ImplResizeObjectArry( sal_uInt32 nNewEntrys )
691 : {
692 17 : sal_uInt32 i = vGDIObj.size();
693 17 : vGDIObj.resize( nNewEntrys );
694 299 : for ( ; i < nNewEntrys ; i++ )
695 282 : vGDIObj[ i ] = NULL;
696 17 : }
697 :
698 : //-----------------------------------------------------------------------------------
699 :
700 0 : void WinMtfOutput::ImplDrawClippedPolyPolygon( const PolyPolygon& rPolyPoly )
701 : {
702 0 : if ( rPolyPoly.Count() )
703 : {
704 0 : ImplSetNonPersistentLineColorTransparenz();
705 0 : if ( rPolyPoly.Count() == 1 )
706 : {
707 0 : if ( rPolyPoly.IsRect() )
708 0 : mpGDIMetaFile->AddAction( new MetaRectAction( rPolyPoly.GetBoundRect() ) );
709 : else
710 : {
711 0 : Polygon aPoly( rPolyPoly[ 0 ] );
712 0 : sal_uInt16 nCount = aPoly.GetSize();
713 0 : if ( nCount )
714 : {
715 0 : if ( aPoly[ nCount - 1 ] != aPoly[ 0 ] )
716 : {
717 0 : Point aPoint( aPoly[ 0 ] );
718 0 : aPoly.Insert( nCount, aPoint );
719 : }
720 0 : mpGDIMetaFile->AddAction( new MetaPolygonAction( aPoly ) );
721 0 : }
722 : }
723 : }
724 : else
725 0 : mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPoly ) );
726 : }
727 0 : }
728 :
729 :
730 : //-----------------------------------------------------------------------------------
731 :
732 25 : void WinMtfOutput::CreateObject( GDIObjectType eType, void* pStyle )
733 : {
734 25 : if ( pStyle )
735 : {
736 25 : if ( eType == GDI_FONT )
737 : {
738 2 : ImplMap( ((WinMtfFontStyle*)pStyle)->aFont );
739 2 : if (!((WinMtfFontStyle*)pStyle)->aFont.GetHeight() )
740 0 : ((WinMtfFontStyle*)pStyle)->aFont.SetHeight( 423 ); // defaulting to 12pt
741 : }
742 23 : else if ( eType == GDI_PEN )
743 : {
744 8 : Size aSize( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetWidth(), 0 );
745 8 : ((WinMtfLineStyle*)pStyle)->aLineInfo.SetWidth( ImplMap( aSize ).Width() );
746 8 : if ( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetStyle() == LINE_DASH )
747 : {
748 0 : aSize.Width() += 1;
749 0 : long nDotLen = ImplMap( aSize ).Width();
750 0 : ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDistance( nDotLen );
751 0 : ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDotLen( nDotLen );
752 0 : ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDashLen( nDotLen * 4 );
753 : }
754 : }
755 : }
756 : sal_uInt32 nIndex;
757 47 : for ( nIndex = 0; nIndex < vGDIObj.size(); nIndex++ )
758 : {
759 40 : if ( vGDIObj[ nIndex ] == NULL )
760 18 : break;
761 : }
762 25 : if ( nIndex == vGDIObj.size() )
763 7 : ImplResizeObjectArry( vGDIObj.size() + 16 );
764 :
765 25 : vGDIObj[ nIndex ] = new GDIObj( eType, pStyle );
766 25 : }
767 :
768 : //-----------------------------------------------------------------------------------
769 :
770 326 : void WinMtfOutput::CreateObject( sal_Int32 nIndex, GDIObjectType eType, void* pStyle )
771 : {
772 326 : if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
773 : {
774 326 : nIndex &= 0xffff; // zur Sicherheit: mehr als 65535 nicht zulassen
775 326 : if ( pStyle )
776 : {
777 326 : if ( eType == GDI_FONT )
778 63 : ImplMap( ((WinMtfFontStyle*)pStyle)->aFont );
779 263 : else if ( eType == GDI_PEN )
780 : {
781 198 : Size aSize( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetWidth(), 0 );
782 198 : ((WinMtfLineStyle*)pStyle)->aLineInfo.SetWidth( ImplMap( aSize ).Width() );
783 198 : if ( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetStyle() == LINE_DASH )
784 : {
785 0 : aSize.Width() += 1;
786 0 : long nDotLen = ImplMap( aSize ).Width();
787 0 : ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDistance( nDotLen );
788 0 : ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDotLen( nDotLen );
789 0 : ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDashLen( nDotLen * 4 );
790 : }
791 : }
792 : }
793 326 : if ( (sal_uInt32)nIndex >= vGDIObj.size() )
794 10 : ImplResizeObjectArry( nIndex + 16 );
795 :
796 326 : if ( vGDIObj[ nIndex ] != NULL )
797 0 : delete vGDIObj[ nIndex ];
798 :
799 326 : vGDIObj[ nIndex ] = new GDIObj( eType, pStyle );
800 : }
801 : else
802 : {
803 0 : switch ( eType )
804 : {
805 : case GDI_PEN :
806 0 : delete (WinMtfLineStyle*)pStyle;
807 0 : break;
808 : case GDI_BRUSH :
809 0 : delete (WinMtfFillStyle*)pStyle;
810 0 : break;
811 : case GDI_FONT :
812 0 : delete (WinMtfFontStyle*)pStyle;
813 0 : break;
814 :
815 : default:
816 : OSL_FAIL( "unsupported style not deleted" );
817 0 : break;
818 : }
819 : }
820 326 : }
821 :
822 : //-----------------------------------------------------------------------------------
823 :
824 323 : void WinMtfOutput::DeleteObject( sal_Int32 nIndex )
825 : {
826 323 : if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
827 : {
828 323 : if ( (sal_uInt32)nIndex < vGDIObj.size() )
829 : {
830 323 : delete vGDIObj[ nIndex ];
831 323 : vGDIObj[ nIndex ] = NULL;
832 : }
833 : }
834 323 : }
835 :
836 : //-----------------------------------------------------------------------------------
837 :
838 3 : void WinMtfOutput::IntersectClipRect( const Rectangle& rRect )
839 : {
840 3 : mbClipNeedsUpdate=true;
841 3 : aClipPath.intersectClipRect( ImplMap( rRect ) );
842 3 : }
843 :
844 : //-----------------------------------------------------------------------------------
845 :
846 0 : void WinMtfOutput::ExcludeClipRect( const Rectangle& rRect )
847 : {
848 0 : mbClipNeedsUpdate=true;
849 0 : aClipPath.excludeClipRect( ImplMap( rRect ) );
850 0 : }
851 :
852 : //-----------------------------------------------------------------------------------
853 :
854 0 : void WinMtfOutput::MoveClipRegion( const Size& rSize )
855 : {
856 0 : mbClipNeedsUpdate=true;
857 0 : aClipPath.moveClipRegion( ImplMap( rSize ) );
858 0 : }
859 :
860 8 : void WinMtfOutput::SetClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode, sal_Bool bIsMapped )
861 : {
862 8 : mbClipNeedsUpdate=true;
863 8 : if ( bIsMapped )
864 5 : aClipPath.setClipPath( rPolyPolygon, nClippingMode );
865 : else
866 : {
867 3 : PolyPolygon aPP( rPolyPolygon );
868 3 : aClipPath.setClipPath( ImplMap( aPP ), nClippingMode );
869 : }
870 8 : }
871 :
872 : //-----------------------------------------------------------------------------------
873 : //-----------------------------------------------------------------------------------
874 : //-----------------------------------------------------------------------------------
875 :
876 28 : WinMtfOutput::WinMtfOutput( GDIMetaFile& rGDIMetaFile ) :
877 : mnLatestTextAlign ( 0 ),
878 : mnTextAlign ( TA_LEFT | TA_TOP | TA_NOUPDATECP ),
879 : maLatestBkColor ( 0x12345678 ),
880 : maBkColor ( COL_WHITE ),
881 : mnLatestTextLayoutMode( TEXT_LAYOUT_DEFAULT ),
882 : mnTextLayoutMode ( TEXT_LAYOUT_DEFAULT ),
883 : mnLatestBkMode ( 0 ),
884 : mnBkMode ( OPAQUE ),
885 : meLatestRasterOp ( ROP_INVERT ),
886 : meRasterOp ( ROP_OVERPAINT ),
887 : maActPos ( Point() ),
888 : mbNopMode ( sal_False ),
889 : mbFillStyleSelected ( sal_False ),
890 : mbClipNeedsUpdate ( true ),
891 : mbComplexClip ( false ),
892 : mnGfxMode ( GM_COMPATIBLE ),
893 : mnMapMode ( MM_TEXT ),
894 : mnUnitsPerInch ( 96 ),
895 : mnDevOrgX ( 0 ),
896 : mnDevOrgY ( 0 ),
897 : mnDevWidth ( 1 ),
898 : mnDevHeight ( 1 ),
899 : mnWinOrgX ( 0 ),
900 : mnWinOrgY ( 0 ),
901 : mnWinExtX ( 1 ),
902 : mnWinExtY ( 1 ),
903 : mnPixX ( 100 ),
904 : mnPixY ( 100 ),
905 : mnMillX ( 1 ),
906 : mnMillY ( 1 ),
907 28 : mpGDIMetaFile ( &rGDIMetaFile )
908 : {
909 28 : mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_CLIPREGION ) ); // The original clipregion has to be on top
910 : // of the stack so it can always be restored
911 : // this is necessary to be able to support
912 : // SetClipRgn( NULL ) and similar ClipRgn actions (SJ)
913 :
914 28 : maFont.SetName( String( RTL_CONSTASCII_USTRINGPARAM( "Arial" )) ); // sj: #i57205#, we do have some scaling problems if using
915 28 : maFont.SetCharSet( RTL_TEXTENCODING_MS_1252 ); // the default font then most times a x11 font is used, we
916 28 : maFont.SetHeight( 423 ); // will prevent this defining a font
917 :
918 28 : maLatestLineStyle.aLineColor = Color( 0x12, 0x34, 0x56 );
919 28 : maLatestFillStyle.aFillColor = Color( 0x12, 0x34, 0x56 );
920 :
921 28 : mnRop = R2_BLACK + 1;
922 28 : SetRasterOp( R2_BLACK );
923 28 : };
924 :
925 : //-----------------------------------------------------------------------------------
926 :
927 84 : WinMtfOutput::~WinMtfOutput()
928 : {
929 28 : mpGDIMetaFile->AddAction( new MetaPopAction() );
930 28 : mpGDIMetaFile->SetPrefMapMode( MAP_100TH_MM );
931 28 : if ( mrclFrame.IsEmpty() )
932 13 : mpGDIMetaFile->SetPrefSize( Size( mnDevWidth, mnDevHeight ) );
933 : else
934 15 : mpGDIMetaFile->SetPrefSize( mrclFrame.GetSize() );
935 :
936 310 : for ( sal_uInt32 i = 0; i < vGDIObj.size(); i++ )
937 282 : delete vGDIObj[ i ];
938 56 : };
939 :
940 : //-----------------------------------------------------------------------------------
941 :
942 448 : void WinMtfOutput::UpdateClipRegion()
943 : {
944 448 : if ( mbClipNeedsUpdate )
945 : {
946 24 : mbClipNeedsUpdate = false;
947 24 : mbComplexClip = false;
948 :
949 24 : mpGDIMetaFile->AddAction( new MetaPopAction() ); // taking the orignal clipregion
950 24 : mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_CLIPREGION ) ); //
951 :
952 : // skip for 'no clipping at all' case
953 24 : if( !aClipPath.isEmpty() )
954 : {
955 8 : const basegfx::B2DPolyPolygon& rClipPoly( aClipPath.getClipPath() );
956 : mpGDIMetaFile->AddAction(
957 : new MetaISectRectClipRegionAction(
958 : vcl::unotools::rectangleFromB2DRectangle(
959 8 : rClipPoly.getB2DRange())));
960 :
961 8 : mbComplexClip = rClipPoly.count() > 1
962 8 : || !basegfx::tools::isRectangle(rClipPoly);
963 : }
964 : }
965 448 : }
966 :
967 : //-----------------------------------------------------------------------------------
968 :
969 31 : void WinMtfOutput::ImplSetNonPersistentLineColorTransparenz()
970 : {
971 31 : Color aColor( COL_TRANSPARENT);
972 31 : WinMtfLineStyle aTransparentLine( aColor, sal_True );
973 31 : if ( ! ( maLatestLineStyle == aTransparentLine ) )
974 : {
975 4 : maLatestLineStyle = aTransparentLine;
976 4 : mpGDIMetaFile->AddAction( new MetaLineColorAction( aTransparentLine.aLineColor, !aTransparentLine.bTransparent ) );
977 31 : }
978 31 : }
979 :
980 : //-----------------------------------------------------------------------------------
981 :
982 221 : void WinMtfOutput::UpdateLineStyle()
983 : {
984 221 : if (!( maLatestLineStyle == maLineStyle ) )
985 : {
986 113 : maLatestLineStyle = maLineStyle;
987 113 : mpGDIMetaFile->AddAction( new MetaLineColorAction( maLineStyle.aLineColor, !maLineStyle.bTransparent ) );
988 : }
989 221 : }
990 :
991 : //-----------------------------------------------------------------------------------
992 :
993 143 : void WinMtfOutput::UpdateFillStyle()
994 : {
995 143 : if ( !mbFillStyleSelected ) // SJ: #i57205# taking care of bkcolor if no brush is selected
996 1 : maFillStyle = WinMtfFillStyle( maBkColor, mnBkMode == TRANSPARENT );
997 143 : if (!( maLatestFillStyle == maFillStyle ) )
998 : {
999 57 : maLatestFillStyle = maFillStyle;
1000 57 : if (maFillStyle.aType == FillStyleSolid)
1001 57 : mpGDIMetaFile->AddAction( new MetaFillColorAction( maFillStyle.aFillColor, !maFillStyle.bTransparent ) );
1002 : }
1003 143 : }
1004 :
1005 : //-----------------------------------------------------------------------------------
1006 :
1007 165 : sal_uInt32 WinMtfOutput::SetRasterOp( sal_uInt32 nRasterOp )
1008 : {
1009 165 : sal_uInt32 nRetROP = mnRop;
1010 165 : if ( nRasterOp != mnRop )
1011 : {
1012 94 : mnRop = nRasterOp;
1013 94 : static WinMtfFillStyle aNopFillStyle;
1014 94 : static WinMtfLineStyle aNopLineStyle;
1015 :
1016 94 : if ( mbNopMode && ( nRasterOp != R2_NOP ) )
1017 : { // beim uebergang von R2_NOP auf anderen Modus
1018 : // gesetzten Pen und Brush aktivieren
1019 0 : maFillStyle = aNopFillStyle;
1020 0 : maLineStyle = aNopLineStyle;
1021 0 : mbNopMode = sal_False;
1022 : }
1023 94 : switch( nRasterOp )
1024 : {
1025 : case R2_NOT:
1026 0 : meRasterOp = ROP_INVERT;
1027 0 : break;
1028 :
1029 : case R2_XORPEN:
1030 0 : meRasterOp = ROP_XOR;
1031 0 : break;
1032 :
1033 : case R2_NOP:
1034 : {
1035 0 : meRasterOp = ROP_OVERPAINT;
1036 0 : if( mbNopMode == sal_False )
1037 : {
1038 0 : aNopFillStyle = maFillStyle;
1039 0 : aNopLineStyle = maLineStyle;
1040 0 : maFillStyle = WinMtfFillStyle( Color( COL_TRANSPARENT ), sal_True );
1041 0 : maLineStyle = WinMtfLineStyle( Color( COL_TRANSPARENT ), sal_True );
1042 0 : mbNopMode = sal_True;
1043 : }
1044 : }
1045 0 : break;
1046 :
1047 : default:
1048 94 : meRasterOp = ROP_OVERPAINT;
1049 94 : break;
1050 : }
1051 : }
1052 165 : if ( nRetROP != nRasterOp )
1053 94 : mpGDIMetaFile->AddAction( new MetaRasterOpAction( meRasterOp ) );
1054 165 : return nRetROP;
1055 : };
1056 :
1057 : //-----------------------------------------------------------------------------------
1058 :
1059 11 : void WinMtfOutput::StrokeAndFillPath( sal_Bool bStroke, sal_Bool bFill )
1060 : {
1061 11 : if ( aPathObj.Count() )
1062 : {
1063 11 : UpdateClipRegion();
1064 11 : UpdateLineStyle();
1065 11 : UpdateFillStyle();
1066 11 : if ( bFill )
1067 : {
1068 11 : if ( !bStroke )
1069 : {
1070 11 : mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
1071 11 : mpGDIMetaFile->AddAction( new MetaLineColorAction( Color(), sal_False ) );
1072 : }
1073 11 : if ( aPathObj.Count() == 1 )
1074 6 : mpGDIMetaFile->AddAction( new MetaPolygonAction( aPathObj.GetObject( 0 ) ) );
1075 : else
1076 5 : mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( aPathObj ) );
1077 :
1078 11 : if ( !bStroke )
1079 11 : mpGDIMetaFile->AddAction( new MetaPopAction() );
1080 : }
1081 : else
1082 : {
1083 0 : sal_uInt16 i, nCount = aPathObj.Count();
1084 0 : for ( i = 0; i < nCount; i++ )
1085 0 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( aPathObj[ i ], maLineStyle.aLineInfo ) );
1086 : }
1087 11 : ClearPath();
1088 : }
1089 11 : }
1090 :
1091 : //-----------------------------------------------------------------------------------
1092 :
1093 0 : void WinMtfOutput::DrawPixel( const Point& rSource, const Color& rColor )
1094 : {
1095 0 : mpGDIMetaFile->AddAction( new MetaPixelAction( ImplMap( rSource), rColor ) );
1096 0 : }
1097 :
1098 : //-----------------------------------------------------------------------------------
1099 :
1100 21 : void WinMtfOutput::MoveTo( const Point& rPoint, sal_Bool bRecordPath )
1101 : {
1102 21 : Point aDest( ImplMap( rPoint ) );
1103 21 : if ( bRecordPath )
1104 : {
1105 : // fdo#57353 create new subpath for subsequent moves
1106 21 : if ( aPathObj.Count() )
1107 5 : if ( aPathObj[ aPathObj.Count() - 1 ].GetSize() )
1108 5 : aPathObj.Insert( Polygon(), POLYPOLY_APPEND );
1109 21 : aPathObj.AddPoint( aDest );
1110 : }
1111 21 : maActPos = aDest;
1112 21 : }
1113 :
1114 : //-----------------------------------------------------------------------------------
1115 :
1116 0 : void WinMtfOutput::LineTo( const Point& rPoint, sal_Bool bRecordPath )
1117 : {
1118 0 : UpdateClipRegion();
1119 :
1120 0 : Point aDest( ImplMap( rPoint ) );
1121 0 : if ( bRecordPath )
1122 0 : aPathObj.AddPoint( aDest );
1123 : else
1124 : {
1125 0 : UpdateLineStyle();
1126 0 : mpGDIMetaFile->AddAction( new MetaLineAction( maActPos, aDest, maLineStyle.aLineInfo ) );
1127 : }
1128 0 : maActPos = aDest;
1129 0 : }
1130 :
1131 : //-----------------------------------------------------------------------------------
1132 :
1133 39 : void WinMtfOutput::DrawRect( const Rectangle& rRect, sal_Bool bEdge )
1134 : {
1135 39 : UpdateClipRegion();
1136 39 : UpdateFillStyle();
1137 :
1138 39 : if ( mbComplexClip )
1139 : {
1140 0 : Polygon aPoly( ImplMap( rRect ) );
1141 0 : PolyPolygon aPolyPolyRect( aPoly );
1142 0 : PolyPolygon aDest;
1143 0 : PolyPolygon(aClipPath.getClipPath()).GetIntersection( aPolyPolyRect, aDest );
1144 0 : ImplDrawClippedPolyPolygon( aDest );
1145 : }
1146 : else
1147 : {
1148 39 : if ( bEdge )
1149 : {
1150 9 : if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
1151 : {
1152 0 : ImplSetNonPersistentLineColorTransparenz();
1153 0 : mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
1154 0 : UpdateLineStyle();
1155 0 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( ImplMap( rRect ) ),maLineStyle.aLineInfo ) );
1156 : }
1157 : else
1158 : {
1159 9 : UpdateLineStyle();
1160 9 : mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
1161 : }
1162 : }
1163 : else
1164 : {
1165 30 : ImplSetNonPersistentLineColorTransparenz();
1166 30 : mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
1167 : }
1168 : }
1169 39 : }
1170 :
1171 : //-----------------------------------------------------------------------------------
1172 :
1173 0 : void WinMtfOutput::DrawRoundRect( const Rectangle& rRect, const Size& rSize )
1174 : {
1175 0 : UpdateClipRegion();
1176 0 : UpdateLineStyle();
1177 0 : UpdateFillStyle();
1178 0 : mpGDIMetaFile->AddAction( new MetaRoundRectAction( ImplMap( rRect ), labs( ImplMap( rSize ).Width() ), labs( ImplMap( rSize ).Height() ) ) );
1179 0 : }
1180 :
1181 : //-----------------------------------------------------------------------------------
1182 :
1183 0 : void WinMtfOutput::DrawEllipse( const Rectangle& rRect )
1184 : {
1185 0 : UpdateClipRegion();
1186 0 : UpdateFillStyle();
1187 :
1188 0 : if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
1189 : {
1190 0 : Point aCenter( ImplMap( rRect.Center() ) );
1191 0 : Size aRad( ImplMap( Size( rRect.GetWidth() / 2, rRect.GetHeight() / 2 ) ) );
1192 :
1193 0 : ImplSetNonPersistentLineColorTransparenz();
1194 0 : mpGDIMetaFile->AddAction( new MetaEllipseAction( ImplMap( rRect ) ) );
1195 0 : UpdateLineStyle();
1196 0 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aCenter, aRad.Width(), aRad.Height() ), maLineStyle.aLineInfo ) );
1197 : }
1198 : else
1199 : {
1200 0 : UpdateLineStyle();
1201 0 : mpGDIMetaFile->AddAction( new MetaEllipseAction( ImplMap( rRect ) ) );
1202 : }
1203 0 : }
1204 :
1205 : //-----------------------------------------------------------------------------------
1206 :
1207 0 : void WinMtfOutput::DrawArc( const Rectangle& rRect, const Point& rStart, const Point& rEnd, sal_Bool bTo )
1208 : {
1209 0 : UpdateClipRegion();
1210 0 : UpdateLineStyle();
1211 0 : UpdateFillStyle();
1212 :
1213 0 : Rectangle aRect( ImplMap( rRect ) );
1214 0 : Point aStart( ImplMap( rStart ) );
1215 0 : Point aEnd( ImplMap( rEnd ) );
1216 :
1217 0 : if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
1218 : {
1219 0 : if ( aStart == aEnd )
1220 : { // SJ: #i53768# if start & end is identical, then we have to draw a full ellipse
1221 0 : Point aCenter( aRect.Center() );
1222 0 : Size aRad( aRect.GetWidth() / 2, aRect.GetHeight() / 2 );
1223 :
1224 0 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aCenter, aRad.Width(), aRad.Height() ), maLineStyle.aLineInfo ) );
1225 : }
1226 : else
1227 0 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_ARC ), maLineStyle.aLineInfo ) );
1228 : }
1229 : else
1230 0 : mpGDIMetaFile->AddAction( new MetaArcAction( aRect, aStart, aEnd ) );
1231 :
1232 0 : if ( bTo )
1233 0 : maActPos = aEnd;
1234 0 : }
1235 :
1236 : //-----------------------------------------------------------------------------------
1237 :
1238 0 : void WinMtfOutput::DrawPie( const Rectangle& rRect, const Point& rStart, const Point& rEnd )
1239 : {
1240 0 : UpdateClipRegion();
1241 0 : UpdateFillStyle();
1242 :
1243 0 : Rectangle aRect( ImplMap( rRect ) );
1244 0 : Point aStart( ImplMap( rStart ) );
1245 0 : Point aEnd( ImplMap( rEnd ) );
1246 :
1247 0 : if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
1248 : {
1249 0 : ImplSetNonPersistentLineColorTransparenz();
1250 0 : mpGDIMetaFile->AddAction( new MetaPieAction( aRect, aStart, aEnd ) );
1251 0 : UpdateLineStyle();
1252 0 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_PIE ), maLineStyle.aLineInfo ) );
1253 : }
1254 : else
1255 : {
1256 0 : UpdateLineStyle();
1257 0 : mpGDIMetaFile->AddAction( new MetaPieAction( aRect, aStart, aEnd ) );
1258 : }
1259 0 : }
1260 :
1261 : //-----------------------------------------------------------------------------------
1262 :
1263 0 : void WinMtfOutput::DrawChord( const Rectangle& rRect, const Point& rStart, const Point& rEnd )
1264 : {
1265 0 : UpdateClipRegion();
1266 0 : UpdateFillStyle();
1267 :
1268 0 : Rectangle aRect( ImplMap( rRect ) );
1269 0 : Point aStart( ImplMap( rStart ) );
1270 0 : Point aEnd( ImplMap( rEnd ) );
1271 :
1272 0 : if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
1273 : {
1274 0 : ImplSetNonPersistentLineColorTransparenz();
1275 0 : mpGDIMetaFile->AddAction( new MetaChordAction( aRect, aStart, aEnd ) );
1276 0 : UpdateLineStyle();
1277 0 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_CHORD ), maLineStyle.aLineInfo ) );
1278 : }
1279 : else
1280 : {
1281 0 : UpdateLineStyle();
1282 0 : mpGDIMetaFile->AddAction( new MetaChordAction( aRect, aStart, aEnd ) );
1283 : }
1284 0 : }
1285 :
1286 : //-----------------------------------------------------------------------------------
1287 :
1288 57 : void WinMtfOutput::DrawPolygon( Polygon& rPolygon, sal_Bool bRecordPath )
1289 : {
1290 57 : UpdateClipRegion();
1291 57 : ImplMap( rPolygon );
1292 57 : if ( bRecordPath )
1293 0 : aPathObj.AddPolygon( rPolygon );
1294 : else
1295 : {
1296 57 : UpdateFillStyle();
1297 :
1298 57 : if ( mbComplexClip )
1299 : {
1300 0 : PolyPolygon aPolyPoly( rPolygon );
1301 0 : PolyPolygon aDest;
1302 0 : PolyPolygon(aClipPath.getClipPath()).GetIntersection( aPolyPoly, aDest );
1303 0 : ImplDrawClippedPolyPolygon( aDest );
1304 : }
1305 : else
1306 : {
1307 57 : if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
1308 : {
1309 1 : sal_uInt16 nCount = rPolygon.GetSize();
1310 1 : if ( nCount )
1311 : {
1312 1 : if ( rPolygon[ nCount - 1 ] != rPolygon[ 0 ] )
1313 : {
1314 0 : Point aPoint( rPolygon[ 0 ] );
1315 0 : rPolygon.Insert( nCount, aPoint );
1316 : }
1317 : }
1318 1 : ImplSetNonPersistentLineColorTransparenz();
1319 1 : mpGDIMetaFile->AddAction( new MetaPolygonAction( rPolygon ) );
1320 1 : UpdateLineStyle();
1321 1 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
1322 : }
1323 : else
1324 : {
1325 56 : UpdateLineStyle();
1326 :
1327 56 : if (maLatestFillStyle.aType != FillStylePattern)
1328 56 : mpGDIMetaFile->AddAction( new MetaPolygonAction( rPolygon ) );
1329 : else {
1330 : SvtGraphicFill aFill = SvtGraphicFill( PolyPolygon( rPolygon ),
1331 : Color(),
1332 : 0.0,
1333 : SvtGraphicFill::fillNonZero,
1334 : SvtGraphicFill::fillTexture,
1335 : SvtGraphicFill::Transform(),
1336 : true,
1337 : SvtGraphicFill::hatchSingle,
1338 : Color(),
1339 : SvtGraphicFill::gradientLinear,
1340 : Color(),
1341 : Color(),
1342 : 0,
1343 0 : Graphic (maLatestFillStyle.aBmp) );
1344 :
1345 0 : SvMemoryStream aMemStm;
1346 :
1347 0 : aMemStm << aFill;
1348 :
1349 : mpGDIMetaFile->AddAction( new MetaCommentAction( "XPATHFILL_SEQ_BEGIN", 0,
1350 : static_cast<const sal_uInt8*>(aMemStm.GetData()),
1351 0 : aMemStm.Seek( STREAM_SEEK_TO_END ) ) );
1352 0 : mpGDIMetaFile->AddAction( new MetaCommentAction( "XPATHFILL_SEQ_END" ) );
1353 : }
1354 :
1355 : }
1356 : }
1357 : }
1358 57 : }
1359 :
1360 : //-----------------------------------------------------------------------------------
1361 :
1362 6 : void WinMtfOutput::DrawPolyPolygon( PolyPolygon& rPolyPolygon, sal_Bool bRecordPath )
1363 : {
1364 6 : UpdateClipRegion();
1365 :
1366 6 : ImplMap( rPolyPolygon );
1367 :
1368 6 : if ( bRecordPath )
1369 0 : aPathObj.AddPolyPolygon( rPolyPolygon );
1370 : else
1371 : {
1372 6 : UpdateFillStyle();
1373 :
1374 6 : if ( mbComplexClip )
1375 : {
1376 0 : PolyPolygon aDest;
1377 0 : PolyPolygon(aClipPath.getClipPath()).GetIntersection( rPolyPolygon, aDest );
1378 0 : ImplDrawClippedPolyPolygon( aDest );
1379 : }
1380 : else
1381 : {
1382 6 : UpdateLineStyle();
1383 6 : mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPolygon ) );
1384 : }
1385 : }
1386 6 : }
1387 :
1388 : //-----------------------------------------------------------------------------------
1389 :
1390 143 : void WinMtfOutput::DrawPolyLine( Polygon& rPolygon, sal_Bool bTo, sal_Bool bRecordPath )
1391 : {
1392 143 : UpdateClipRegion();
1393 :
1394 143 : ImplMap( rPolygon );
1395 143 : if ( bTo )
1396 : {
1397 5 : rPolygon[ 0 ] = maActPos;
1398 5 : maActPos = rPolygon[ rPolygon.GetSize() - 1 ];
1399 : }
1400 143 : if ( bRecordPath )
1401 5 : aPathObj.AddPolyLine( rPolygon );
1402 : else
1403 : {
1404 138 : UpdateLineStyle();
1405 138 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
1406 : }
1407 143 : }
1408 :
1409 : //-----------------------------------------------------------------------------------
1410 :
1411 16 : void WinMtfOutput::DrawPolyBezier( Polygon& rPolygon, sal_Bool bTo, sal_Bool bRecordPath )
1412 : {
1413 16 : UpdateClipRegion();
1414 :
1415 16 : sal_uInt16 nPoints = rPolygon.GetSize();
1416 16 : if ( ( nPoints >= 4 ) && ( ( ( nPoints - 4 ) % 3 ) == 0 ) )
1417 : {
1418 16 : ImplMap( rPolygon );
1419 16 : if ( bTo )
1420 : {
1421 16 : rPolygon[ 0 ] = maActPos;
1422 16 : maActPos = rPolygon[ nPoints - 1 ];
1423 : }
1424 : sal_uInt16 i;
1425 188 : for ( i = 0; ( i + 2 ) < nPoints; )
1426 : {
1427 156 : rPolygon.SetFlags( i++, POLY_NORMAL );
1428 156 : rPolygon.SetFlags( i++, POLY_CONTROL );
1429 156 : rPolygon.SetFlags( i++, POLY_CONTROL );
1430 : }
1431 16 : if ( bRecordPath )
1432 16 : aPathObj.AddPolyLine( rPolygon );
1433 : else
1434 : {
1435 0 : UpdateLineStyle();
1436 0 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
1437 : }
1438 : }
1439 16 : }
1440 :
1441 : //-----------------------------------------------------------------------------------
1442 :
1443 65 : void WinMtfOutput::DrawText( Point& rPosition, String& rText, sal_Int32* pDXArry, sal_Bool bRecordPath, sal_Int32 nGfxMode )
1444 : {
1445 65 : UpdateClipRegion();
1446 :
1447 65 : VirtualDevice* pVDev = NULL;
1448 :
1449 65 : rPosition = ImplMap( rPosition );
1450 :
1451 65 : sal_Int32 nOldGfxMode = GetGfxMode();
1452 65 : SetGfxMode( GM_COMPATIBLE );
1453 65 : if ( pDXArry )
1454 : {
1455 65 : sal_Int32 i, nSum, nLen = rText.Len();
1456 :
1457 329 : for( i = 0, nSum = 0; i < nLen; i++ )
1458 : {
1459 264 : if ( i ) {
1460 199 : pDXArry[ i - 1 ] = ImplMap( Size( nSum, 0 ) ).Width();
1461 : }
1462 264 : nSum += pDXArry[ i ];
1463 : }
1464 : }
1465 65 : if ( mnLatestTextLayoutMode != mnTextLayoutMode )
1466 : {
1467 0 : mnLatestTextLayoutMode = mnTextLayoutMode;
1468 0 : mpGDIMetaFile->AddAction( new MetaLayoutModeAction( mnTextLayoutMode ) );
1469 : }
1470 65 : SetGfxMode( nGfxMode );
1471 65 : sal_Bool bChangeFont = sal_False;
1472 65 : if ( mnLatestTextAlign != mnTextAlign )
1473 : {
1474 4 : bChangeFont = sal_True;
1475 4 : mnLatestTextAlign = mnTextAlign;
1476 : TextAlign eTextAlign;
1477 4 : if ( ( mnTextAlign & TA_BASELINE) == TA_BASELINE )
1478 4 : eTextAlign = ALIGN_BASELINE;
1479 0 : else if( ( mnTextAlign & TA_BOTTOM) == TA_BOTTOM )
1480 0 : eTextAlign = ALIGN_BOTTOM;
1481 : else
1482 0 : eTextAlign = ALIGN_TOP;
1483 4 : mpGDIMetaFile->AddAction( new MetaTextAlignAction( eTextAlign ) );
1484 : }
1485 65 : if ( maLatestTextColor != maTextColor )
1486 : {
1487 0 : bChangeFont = sal_True;
1488 0 : maLatestTextColor = maTextColor;
1489 0 : mpGDIMetaFile->AddAction( new MetaTextColorAction( maTextColor ) );
1490 : }
1491 65 : sal_Bool bChangeFillColor = sal_False;
1492 65 : if ( maLatestBkColor != maBkColor )
1493 : {
1494 8 : bChangeFillColor = sal_True;
1495 8 : maLatestBkColor = maBkColor;
1496 : }
1497 65 : if ( mnLatestBkMode != mnBkMode )
1498 : {
1499 8 : bChangeFillColor = sal_True;
1500 8 : mnLatestBkMode = mnBkMode;
1501 : }
1502 65 : if ( bChangeFillColor )
1503 : {
1504 8 : bChangeFont = sal_True;
1505 8 : mpGDIMetaFile->AddAction( new MetaTextFillColorAction( maFont.GetFillColor(), !maFont.IsTransparent() ) );
1506 : }
1507 65 : Font aTmp( maFont );
1508 65 : aTmp.SetColor( maTextColor );
1509 65 : aTmp.SetFillColor( maBkColor );
1510 :
1511 65 : if( mnBkMode == TRANSPARENT )
1512 65 : aTmp.SetTransparent( sal_True );
1513 : else
1514 0 : aTmp.SetTransparent( sal_False );
1515 :
1516 65 : if ( ( mnTextAlign & TA_BASELINE) == TA_BASELINE )
1517 59 : aTmp.SetAlign( ALIGN_BASELINE );
1518 6 : else if( ( mnTextAlign & TA_BOTTOM) == TA_BOTTOM )
1519 0 : aTmp.SetAlign( ALIGN_BOTTOM );
1520 : else
1521 6 : aTmp.SetAlign( ALIGN_TOP );
1522 :
1523 65 : if ( nGfxMode == GM_ADVANCED )
1524 : {
1525 : // check whether there is a font rotation applied via transformation
1526 0 : Point aP1( ImplMap( Point() ) );
1527 0 : Point aP2( ImplMap( Point( 0, 100 ) ) );
1528 0 : aP2.X() -= aP1.X();
1529 0 : aP2.Y() -= aP1.Y();
1530 0 : double fX = aP2.X();
1531 0 : double fY = aP2.Y();
1532 0 : if ( fX )
1533 : {
1534 0 : double fOrientation = acos( fX / sqrt( fX * fX + fY * fY ) ) * 57.29577951308;
1535 0 : if ( fY > 0 )
1536 0 : fOrientation = 360 - fOrientation;
1537 0 : fOrientation += 90;
1538 0 : fOrientation *= 10;
1539 0 : fOrientation += aTmp.GetOrientation();
1540 0 : aTmp.SetOrientation( sal_Int16( fOrientation ) );
1541 : }
1542 : }
1543 :
1544 65 : if( mnTextAlign & ( TA_UPDATECP | TA_RIGHT_CENTER ) )
1545 : {
1546 0 : if ( !pVDev )
1547 0 : pVDev = new VirtualDevice;
1548 : sal_Int32 nTextWidth;
1549 0 : pVDev->SetMapMode( MapMode( MAP_100TH_MM ) );
1550 0 : pVDev->SetFont( maFont );
1551 0 : if( pDXArry )
1552 : {
1553 0 : sal_uInt32 nLen = rText.Len();
1554 0 : nTextWidth = pVDev->GetTextWidth( rtl::OUString(rText.GetChar( (sal_uInt16)( nLen - 1 ) )) );
1555 0 : if( nLen > 1 )
1556 0 : nTextWidth += pDXArry[ nLen - 2 ];
1557 : }
1558 : else
1559 0 : nTextWidth = pVDev->GetTextWidth( rText );
1560 :
1561 0 : if( mnTextAlign & TA_UPDATECP )
1562 0 : rPosition = maActPos;
1563 :
1564 0 : if ( mnTextAlign & TA_RIGHT_CENTER )
1565 : {
1566 0 : double fLenght = ( ( mnTextAlign & TA_RIGHT_CENTER ) == TA_RIGHT ) ? nTextWidth : nTextWidth >> 1;
1567 0 : rPosition.X() -= (sal_Int32)( fLenght * cos( maFont.GetOrientation() * F_PI1800 ) );
1568 0 : rPosition.Y() -= (sal_Int32)(-( fLenght * sin( maFont.GetOrientation() * F_PI1800 ) ) );
1569 : }
1570 :
1571 0 : if( mnTextAlign & TA_UPDATECP )
1572 0 : maActPos.X() = rPosition.X() + nTextWidth;
1573 : }
1574 65 : if ( bChangeFont || ( maLatestFont != aTmp ) )
1575 : {
1576 14 : maLatestFont = aTmp;
1577 14 : mpGDIMetaFile->AddAction( new MetaFontAction( aTmp ) );
1578 14 : mpGDIMetaFile->AddAction( new MetaTextAlignAction( aTmp.GetAlign() ) );
1579 14 : mpGDIMetaFile->AddAction( new MetaTextColorAction( aTmp.GetColor() ) );
1580 14 : mpGDIMetaFile->AddAction( new MetaTextFillColorAction( aTmp.GetFillColor(), !aTmp.IsTransparent() ) );
1581 : }
1582 65 : if ( bRecordPath )
1583 : {
1584 : // ToDo
1585 : }
1586 : else
1587 : {
1588 : /* because text without dx array is badly scaled, we
1589 : will create such an array if necessary */
1590 65 : sal_Int32* pDX = pDXArry;
1591 65 : if ( !pDXArry )
1592 : {
1593 0 : SolarMutexGuard aGuard;
1594 :
1595 0 : pDX = new sal_Int32[ rText.Len() ];
1596 0 : if ( !pVDev )
1597 0 : pVDev = new VirtualDevice;
1598 0 : pVDev->SetMapMode( MAP_100TH_MM );
1599 0 : pVDev->SetFont( maLatestFont );
1600 0 : pVDev->GetTextArray( rText, pDX, 0, STRING_LEN );
1601 : }
1602 65 : mpGDIMetaFile->AddAction( new MetaTextArrayAction( rPosition, rText, pDX, 0, STRING_LEN ) );
1603 65 : if ( !pDXArry ) // this means we have created our own array
1604 0 : delete[] pDX; // which must be deleted
1605 : }
1606 65 : SetGfxMode( nOldGfxMode );
1607 65 : delete pVDev;
1608 65 : }
1609 :
1610 : //-----------------------------------------------------------------------------------
1611 :
1612 1 : void WinMtfOutput::ImplDrawBitmap( const Point& rPos, const Size& rSize, const BitmapEx rBitmap )
1613 : {
1614 1 : BitmapEx aBmpEx( rBitmap );
1615 1 : if ( mbComplexClip )
1616 : {
1617 0 : VirtualDevice aVDev;
1618 0 : MapMode aMapMode( MAP_100TH_MM );
1619 0 : aMapMode.SetOrigin( Point( -rPos.X(), -rPos.Y() ) );
1620 0 : const Size aOutputSizePixel( aVDev.LogicToPixel( rSize, aMapMode ) );
1621 0 : const Size aSizePixel( rBitmap.GetSizePixel() );
1622 0 : if ( aOutputSizePixel.Width() && aOutputSizePixel.Height() )
1623 : {
1624 0 : aMapMode.SetScaleX( Fraction( aSizePixel.Width(), aOutputSizePixel.Width() ) );
1625 0 : aMapMode.SetScaleY( Fraction( aSizePixel.Height(), aOutputSizePixel.Height() ) );
1626 : }
1627 0 : aVDev.SetMapMode( aMapMode );
1628 0 : aVDev.SetOutputSizePixel( aSizePixel );
1629 0 : aVDev.SetFillColor( Color( COL_BLACK ) );
1630 0 : const PolyPolygon aClip( aClipPath.getClipPath() );
1631 0 : aVDev.DrawPolyPolygon( aClip );
1632 0 : const Point aEmptyPoint;
1633 :
1634 : // #i50672# Extract whole VDev content (to match size of rBitmap)
1635 0 : aVDev.EnableMapMode( sal_False );
1636 0 : Bitmap aMask( aVDev.GetBitmap( aEmptyPoint, aSizePixel ).CreateMask( Color( COL_WHITE ) ) );
1637 :
1638 0 : if ( aBmpEx.IsTransparent() )
1639 : {
1640 0 : if ( rBitmap.GetTransparentColor() == Color( COL_WHITE ) )
1641 0 : aMask.CombineSimple( rBitmap.GetMask(), BMP_COMBINE_OR );
1642 : else
1643 0 : aMask.CombineSimple( rBitmap.GetMask(), BMP_COMBINE_AND );
1644 0 : aBmpEx = BitmapEx( rBitmap.GetBitmap(), aMask );
1645 : }
1646 : else
1647 0 : aBmpEx = BitmapEx( rBitmap.GetBitmap(), aMask );
1648 : }
1649 1 : if ( aBmpEx.IsTransparent() )
1650 0 : mpGDIMetaFile->AddAction( new MetaBmpExScaleAction( rPos, rSize, aBmpEx ) );
1651 : else
1652 1 : mpGDIMetaFile->AddAction( new MetaBmpScaleAction( rPos, rSize, aBmpEx.GetBitmap() ) );
1653 1 : }
1654 :
1655 : //-----------------------------------------------------------------------------------
1656 :
1657 19 : void WinMtfOutput::ResolveBitmapActions( BSaveStructList_impl& rSaveList )
1658 : {
1659 19 : UpdateClipRegion();
1660 :
1661 19 : size_t nObjects = rSaveList.size();
1662 19 : size_t nObjectsLeft = nObjects;
1663 :
1664 69 : while ( nObjectsLeft )
1665 : {
1666 : size_t i;
1667 31 : size_t nObjectsOfSameSize = 0;
1668 31 : size_t nObjectStartIndex = nObjects - nObjectsLeft;
1669 :
1670 31 : BSaveStruct* pSave = rSaveList[ nObjectStartIndex ];
1671 31 : Rectangle aRect( pSave->aOutRect );
1672 :
1673 81 : for ( i = nObjectStartIndex; i < nObjects; )
1674 : {
1675 31 : nObjectsOfSameSize++;
1676 31 : if ( ++i < nObjects )
1677 : {
1678 12 : pSave = rSaveList[ i ];
1679 12 : if ( pSave->aOutRect != aRect )
1680 12 : break;
1681 : }
1682 : }
1683 31 : Point aPos( ImplMap( aRect.TopLeft() ) );
1684 31 : Size aSize( ImplMap( aRect.GetSize() ) );
1685 :
1686 62 : for ( i = nObjectStartIndex; i < ( nObjectStartIndex + nObjectsOfSameSize ); i++ )
1687 : {
1688 31 : pSave = rSaveList[ i ];
1689 :
1690 31 : sal_uInt32 nWinRop = pSave->nWinRop;
1691 31 : sal_uInt8 nRasterOperation = (sal_uInt8)( nWinRop >> 16 );
1692 :
1693 31 : sal_uInt32 nUsed = 0;
1694 31 : if ( ( nRasterOperation & 0xf ) != ( nRasterOperation >> 4 ) )
1695 30 : nUsed |= 1; // pattern is used
1696 31 : if ( ( nRasterOperation & 0x33 ) != ( ( nRasterOperation & 0xcc ) >> 2 ) )
1697 1 : nUsed |= 2; // source is used
1698 31 : if ( ( nRasterOperation & 0xaa ) != ( ( nRasterOperation & 0x55 ) << 1 ) )
1699 0 : nUsed |= 4; // destination is used
1700 :
1701 31 : if ( (nUsed & 1) && (( nUsed & 2 ) == 0) && nWinRop != PATINVERT )
1702 : { // patterns aren't well supported yet
1703 30 : sal_uInt32 nOldRop = SetRasterOp( ROP_OVERPAINT ); // in this case nRasterOperation is either 0 or 0xff
1704 30 : UpdateFillStyle();
1705 30 : DrawRect( aRect, sal_False );
1706 30 : SetRasterOp( nOldRop );
1707 : }
1708 : else
1709 : {
1710 1 : sal_Bool bDrawn = sal_False;
1711 :
1712 1 : if ( i == nObjectStartIndex ) // optimizing, sometimes it is possible to create just one transparent bitmap
1713 : {
1714 1 : if ( nObjectsOfSameSize == 2 )
1715 : {
1716 0 : BSaveStruct* pSave2 = rSaveList[ i + 1 ];
1717 0 : if ( ( pSave->aBmp.GetPrefSize() == pSave2->aBmp.GetPrefSize() ) &&
1718 0 : ( pSave->aBmp.GetPrefMapMode() == pSave2->aBmp.GetPrefMapMode() ) )
1719 : {
1720 : // TODO: Strictly speaking, we should
1721 : // check whether mask is monochrome, and
1722 : // whether image is black (upper branch)
1723 : // or white (lower branch). Otherwise, the
1724 : // effect is not the same as a masked
1725 : // bitmap.
1726 0 : if ( ( nWinRop == SRCPAINT ) && ( pSave2->nWinRop == SRCAND ) )
1727 : {
1728 0 : Bitmap aMask( pSave->aBmp ); aMask.Invert();
1729 0 : BitmapEx aBmpEx( pSave2->aBmp, aMask );
1730 0 : ImplDrawBitmap( aPos, aSize, aBmpEx );
1731 0 : bDrawn = sal_True;
1732 0 : i++;
1733 : }
1734 : // #i20085# This is just the other way
1735 : // around as above. Only difference: mask
1736 : // is inverted
1737 0 : else if ( ( nWinRop == SRCAND ) && ( pSave2->nWinRop == SRCPAINT ) )
1738 : {
1739 0 : Bitmap aMask( pSave->aBmp );
1740 0 : BitmapEx aBmpEx( pSave2->aBmp, aMask );
1741 0 : ImplDrawBitmap( aPos, aSize, aBmpEx );
1742 0 : bDrawn = sal_True;
1743 0 : i++;
1744 : }
1745 : }
1746 : }
1747 : }
1748 :
1749 1 : if ( !bDrawn )
1750 : {
1751 1 : Push();
1752 1 : sal_uInt32 nOldRop = SetRasterOp( R2_COPYPEN );
1753 1 : Bitmap aBitmap( pSave->aBmp );
1754 1 : sal_uInt32 nOperation = ( nRasterOperation & 0xf );
1755 1 : switch( nOperation )
1756 : {
1757 : case 0x1 :
1758 : case 0xe :
1759 : {
1760 0 : SetRasterOp( R2_XORPEN );
1761 0 : ImplDrawBitmap( aPos, aSize, aBitmap );
1762 0 : SetRasterOp( R2_COPYPEN );
1763 0 : Bitmap aMask( aBitmap );
1764 0 : aMask.Invert();
1765 0 : BitmapEx aBmpEx( aBitmap, aMask );
1766 0 : ImplDrawBitmap( aPos, aSize, aBmpEx );
1767 0 : if ( nOperation == 0x1 )
1768 : {
1769 0 : SetRasterOp( R2_NOT );
1770 0 : DrawRect( aRect, sal_False );
1771 0 : }
1772 : }
1773 0 : break;
1774 : case 0x7 :
1775 : case 0x8 :
1776 : {
1777 0 : Bitmap aMask( aBitmap );
1778 0 : if ( ( nUsed & 1 ) && ( nRasterOperation & 0xb0 ) == 0xb0 ) // pattern used
1779 : {
1780 0 : aBitmap.Convert( BMP_CONVERSION_24BIT );
1781 0 : aBitmap.Erase( maFillStyle.aFillColor );
1782 : }
1783 0 : BitmapEx aBmpEx( aBitmap, aMask );
1784 0 : ImplDrawBitmap( aPos, aSize, aBmpEx );
1785 0 : if ( nOperation == 0x7 )
1786 : {
1787 0 : SetRasterOp( R2_NOT );
1788 0 : DrawRect( aRect, sal_False );
1789 0 : }
1790 : }
1791 0 : break;
1792 :
1793 : case 0x4 :
1794 : case 0xb :
1795 : {
1796 0 : SetRasterOp( R2_NOT );
1797 0 : DrawRect( aRect, sal_False );
1798 0 : SetRasterOp( R2_COPYPEN );
1799 0 : Bitmap aMask( aBitmap );
1800 0 : aBitmap.Invert();
1801 0 : BitmapEx aBmpEx( aBitmap, aMask );
1802 0 : ImplDrawBitmap( aPos, aSize, aBmpEx );
1803 0 : SetRasterOp( R2_XORPEN );
1804 0 : ImplDrawBitmap( aPos, aSize, aBitmap );
1805 0 : if ( nOperation == 0xb )
1806 : {
1807 0 : SetRasterOp( R2_NOT );
1808 0 : DrawRect( aRect, sal_False );
1809 0 : }
1810 : }
1811 0 : break;
1812 :
1813 : case 0x2 :
1814 : case 0xd :
1815 : {
1816 0 : Bitmap aMask( aBitmap );
1817 0 : aMask.Invert();
1818 0 : BitmapEx aBmpEx( aBitmap, aMask );
1819 0 : ImplDrawBitmap( aPos, aSize, aBmpEx );
1820 0 : SetRasterOp( R2_XORPEN );
1821 0 : ImplDrawBitmap( aPos, aSize, aBitmap );
1822 0 : if ( nOperation == 0xd )
1823 : {
1824 0 : SetRasterOp( R2_NOT );
1825 0 : DrawRect( aRect, sal_False );
1826 0 : }
1827 : }
1828 0 : break;
1829 : case 0x6 :
1830 : case 0x9 :
1831 : {
1832 0 : SetRasterOp( R2_XORPEN );
1833 0 : ImplDrawBitmap( aPos, aSize, aBitmap );
1834 0 : if ( nOperation == 0x9 )
1835 : {
1836 0 : SetRasterOp( R2_NOT );
1837 0 : DrawRect( aRect, sal_False );
1838 : }
1839 : }
1840 0 : break;
1841 :
1842 : case 0x0 : // WHITENESS
1843 : case 0xf : // BLACKNESS
1844 : { // in this case nRasterOperation is either 0 or 0xff
1845 0 : maFillStyle = WinMtfFillStyle( Color( nRasterOperation, nRasterOperation, nRasterOperation ) );
1846 0 : UpdateFillStyle();
1847 0 : DrawRect( aRect, sal_False );
1848 : }
1849 0 : break;
1850 :
1851 : case 0x3 : // only source is used
1852 : case 0xc :
1853 : {
1854 1 : if ( nRasterOperation == 0x33 )
1855 0 : aBitmap.Invert();
1856 1 : ImplDrawBitmap( aPos, aSize, aBitmap );
1857 : }
1858 1 : break;
1859 :
1860 : case 0x5 : // only destination is used
1861 : {
1862 0 : SetRasterOp( R2_NOT );
1863 0 : DrawRect( aRect, sal_False );
1864 : }
1865 : case 0xa : // no operation
1866 0 : break;
1867 : }
1868 1 : SetRasterOp( nOldRop );
1869 1 : Pop();
1870 : }
1871 : }
1872 : }
1873 31 : nObjectsLeft -= nObjectsOfSameSize;
1874 : }
1875 :
1876 50 : for( size_t i = 0, n = rSaveList.size(); i < n; ++i )
1877 31 : delete rSaveList[ i ];
1878 19 : rSaveList.clear();
1879 19 : }
1880 :
1881 : //-----------------------------------------------------------------------------------
1882 :
1883 39 : void WinMtfOutput::SetDevOrg( const Point& rPoint )
1884 : {
1885 39 : mnDevOrgX = rPoint.X();
1886 39 : mnDevOrgY = rPoint.Y();
1887 39 : }
1888 :
1889 : //-----------------------------------------------------------------------------------
1890 :
1891 0 : void WinMtfOutput::SetDevOrgOffset( sal_Int32 nXAdd, sal_Int32 nYAdd )
1892 : {
1893 0 : mnDevOrgX += nXAdd;
1894 0 : mnDevOrgY += nYAdd;
1895 0 : }
1896 :
1897 : //-----------------------------------------------------------------------------------
1898 :
1899 34 : void WinMtfOutput::SetDevExt( const Size& rSize )
1900 : {
1901 34 : if ( rSize.Width() && rSize.Height() )
1902 : {
1903 34 : switch( mnMapMode )
1904 : {
1905 : case MM_ISOTROPIC :
1906 : case MM_ANISOTROPIC :
1907 : {
1908 34 : mnDevWidth = rSize.Width();
1909 34 : mnDevHeight = rSize.Height();
1910 : }
1911 : }
1912 : }
1913 34 : }
1914 :
1915 : //-----------------------------------------------------------------------------------
1916 :
1917 3 : void WinMtfOutput::ScaleDevExt( double fX, double fY )
1918 : {
1919 3 : mnDevWidth = FRound( mnDevWidth * fX );
1920 3 : mnDevHeight = FRound( mnDevHeight * fY );
1921 3 : }
1922 :
1923 : //-----------------------------------------------------------------------------------
1924 :
1925 55 : void WinMtfOutput::SetWinOrg( const Point& rPoint )
1926 : {
1927 55 : mnWinOrgX = rPoint.X();
1928 55 : mnWinOrgY = rPoint.Y();
1929 55 : }
1930 :
1931 : //-----------------------------------------------------------------------------------
1932 :
1933 0 : void WinMtfOutput::SetWinOrgOffset( sal_Int32 nXAdd, sal_Int32 nYAdd )
1934 : {
1935 0 : mnWinOrgX += nXAdd;
1936 0 : mnWinOrgY += nYAdd;
1937 0 : }
1938 :
1939 : //-----------------------------------------------------------------------------------
1940 :
1941 57 : void WinMtfOutput::SetWinExt( const Size& rSize )
1942 : {
1943 :
1944 57 : if( rSize.Width() && rSize.Height() )
1945 : {
1946 57 : switch( mnMapMode )
1947 : {
1948 : case MM_ISOTROPIC :
1949 : case MM_ANISOTROPIC :
1950 : {
1951 54 : mnWinExtX = rSize.Width();
1952 54 : mnWinExtY = rSize.Height();
1953 : }
1954 : }
1955 : }
1956 57 : }
1957 :
1958 : //-----------------------------------------------------------------------------------
1959 :
1960 0 : void WinMtfOutput::ScaleWinExt( double fX, double fY )
1961 : {
1962 0 : mnWinExtX = FRound( mnWinExtX * fX );
1963 0 : mnWinExtY = FRound( mnWinExtY * fY );
1964 0 : }
1965 :
1966 : //-----------------------------------------------------------------------------------
1967 :
1968 15 : void WinMtfOutput::SetrclBounds( const Rectangle& rRect )
1969 : {
1970 15 : mrclBounds = rRect;
1971 15 : }
1972 :
1973 : //-----------------------------------------------------------------------------------
1974 :
1975 15 : void WinMtfOutput::SetrclFrame( const Rectangle& rRect )
1976 : {
1977 15 : mrclFrame = rRect;
1978 15 : }
1979 :
1980 : //-----------------------------------------------------------------------------------
1981 :
1982 15 : void WinMtfOutput::SetRefPix( const Size& rSize )
1983 : {
1984 15 : mnPixX = rSize.Width();
1985 15 : mnPixY = rSize.Height();
1986 15 : }
1987 :
1988 : //-----------------------------------------------------------------------------------
1989 :
1990 15 : void WinMtfOutput::SetRefMill( const Size& rSize )
1991 : {
1992 15 : mnMillX = rSize.Width();
1993 15 : mnMillY = rSize.Height();
1994 15 : }
1995 :
1996 : //-----------------------------------------------------------------------------------
1997 :
1998 32 : void WinMtfOutput::SetMapMode( sal_uInt32 nMapMode )
1999 : {
2000 32 : mnMapMode = nMapMode;
2001 32 : if ( nMapMode == MM_TEXT )
2002 : {
2003 2 : mnWinExtX = mnDevWidth;
2004 2 : mnWinExtY = mnDevHeight;
2005 : }
2006 30 : else if ( mnMapMode == MM_HIMETRIC )
2007 : {
2008 0 : mnWinExtX = mnMillX * 100;
2009 0 : mnWinExtY = mnMillY * 100;
2010 : }
2011 32 : }
2012 :
2013 : //-----------------------------------------------------------------------------------
2014 :
2015 13 : void WinMtfOutput::SetUnitsPerInch( sal_uInt16 nUnitsPerInch )
2016 : {
2017 13 : if( nUnitsPerInch != 0 )
2018 13 : mnUnitsPerInch = nUnitsPerInch;
2019 13 : }
2020 :
2021 : //-----------------------------------------------------------------------------------
2022 :
2023 1 : void WinMtfOutput::SetWorldTransform( const XForm& rXForm )
2024 : {
2025 1 : maXForm.eM11 = rXForm.eM11;
2026 1 : maXForm.eM12 = rXForm.eM12;
2027 1 : maXForm.eM21 = rXForm.eM21;
2028 1 : maXForm.eM22 = rXForm.eM22;
2029 1 : maXForm.eDx = rXForm.eDx;
2030 1 : maXForm.eDy = rXForm.eDy;
2031 1 : }
2032 :
2033 : //-----------------------------------------------------------------------------------
2034 :
2035 1 : void WinMtfOutput::ModifyWorldTransform( const XForm& rXForm, sal_uInt32 nMode )
2036 : {
2037 1 : switch( nMode )
2038 : {
2039 : case MWT_IDENTITY :
2040 : {
2041 0 : maXForm.eM11 = maXForm.eM12 = maXForm.eM21 = maXForm.eM22 = 1.0f;
2042 0 : maXForm.eDx = maXForm.eDy = 0.0f;
2043 : }
2044 0 : break;
2045 :
2046 : case MWT_RIGHTMULTIPLY :
2047 : case MWT_LEFTMULTIPLY :
2048 : {
2049 : const XForm* pLeft;
2050 : const XForm* pRight;
2051 :
2052 1 : if ( nMode == MWT_LEFTMULTIPLY )
2053 : {
2054 1 : pLeft = &rXForm;
2055 1 : pRight = &maXForm;
2056 : }
2057 : else
2058 : {
2059 0 : pLeft = &maXForm;
2060 0 : pRight = &rXForm;
2061 : }
2062 :
2063 : float aF[3][3];
2064 : float bF[3][3];
2065 : float cF[3][3];
2066 :
2067 1 : aF[0][0] = pLeft->eM11;
2068 1 : aF[0][1] = pLeft->eM12;
2069 1 : aF[0][2] = 0;
2070 1 : aF[1][0] = pLeft->eM21;
2071 1 : aF[1][1] = pLeft->eM22;
2072 1 : aF[1][2] = 0;
2073 1 : aF[2][0] = pLeft->eDx;
2074 1 : aF[2][1] = pLeft->eDy;
2075 1 : aF[2][2] = 1;
2076 :
2077 1 : bF[0][0] = pRight->eM11;
2078 1 : bF[0][1] = pRight->eM12;
2079 1 : bF[0][2] = 0;
2080 1 : bF[1][0] = pRight->eM21;
2081 1 : bF[1][1] = pRight->eM22;
2082 1 : bF[1][2] = 0;
2083 1 : bF[2][0] = pRight->eDx;
2084 1 : bF[2][1] = pRight->eDy;
2085 1 : bF[2][2] = 1;
2086 :
2087 : int i, j, k;
2088 4 : for ( i = 0; i < 3; i++ )
2089 : {
2090 12 : for ( j = 0; j < 3; j++ )
2091 : {
2092 9 : cF[i][j] = 0;
2093 36 : for ( k = 0; k < 3; k++ )
2094 27 : cF[i][j] += aF[i][k] * bF[k][j];
2095 : }
2096 : }
2097 1 : maXForm.eM11 = cF[0][0];
2098 1 : maXForm.eM12 = cF[0][1];
2099 1 : maXForm.eM21 = cF[1][0];
2100 1 : maXForm.eM22 = cF[1][1];
2101 1 : maXForm.eDx = cF[2][0];
2102 1 : maXForm.eDy = cF[2][1];
2103 : }
2104 1 : break;
2105 : }
2106 1 : }
2107 :
2108 : //-----------------------------------------------------------------------------------
2109 :
2110 92 : void WinMtfOutput::Push() // !! to be able to access the original ClipRegion it
2111 : { // is not allowed to use the MetaPushAction()
2112 92 : UpdateClipRegion(); // (the original clip region is on top of the stack) (SJ)
2113 92 : SaveStructPtr pSave( new SaveStruct );
2114 :
2115 92 : pSave->aLineStyle = maLineStyle;
2116 92 : pSave->aFillStyle = maFillStyle;
2117 :
2118 92 : pSave->aFont = maFont;
2119 92 : pSave->aTextColor = maTextColor;
2120 92 : pSave->nTextAlign = mnTextAlign;
2121 92 : pSave->nTextLayoutMode = mnTextLayoutMode;
2122 92 : pSave->nMapMode = mnMapMode;
2123 92 : pSave->nGfxMode = mnGfxMode;
2124 92 : pSave->nBkMode = mnBkMode;
2125 92 : pSave->aBkColor = maBkColor;
2126 92 : pSave->bFillStyleSelected = mbFillStyleSelected;
2127 :
2128 92 : pSave->aActPos = maActPos;
2129 92 : pSave->aXForm = maXForm;
2130 92 : pSave->eRasterOp = meRasterOp;
2131 :
2132 92 : pSave->nWinOrgX = mnWinOrgX;
2133 92 : pSave->nWinOrgY = mnWinOrgY;
2134 92 : pSave->nWinExtX = mnWinExtX;
2135 92 : pSave->nWinExtY = mnWinExtY;
2136 92 : pSave->nDevOrgX = mnDevOrgX;
2137 92 : pSave->nDevOrgY = mnDevOrgY;
2138 92 : pSave->nDevWidth = mnDevWidth;
2139 92 : pSave->nDevHeight = mnDevHeight;
2140 :
2141 92 : pSave->aPathObj = aPathObj;
2142 92 : pSave->aClipPath = aClipPath;
2143 :
2144 92 : vSaveStack.push_back( pSave );
2145 92 : }
2146 :
2147 : //-----------------------------------------------------------------------------------
2148 :
2149 80 : void WinMtfOutput::Pop()
2150 : {
2151 : // Die aktuellen Daten vom Stack holen
2152 80 : if( !vSaveStack.empty() )
2153 : {
2154 : // Die aktuelle Daten auf dem Stack sichern
2155 80 : SaveStructPtr pSave( vSaveStack.back() );
2156 :
2157 80 : maLineStyle = pSave->aLineStyle;
2158 80 : maFillStyle = pSave->aFillStyle;
2159 :
2160 80 : maFont = pSave->aFont;
2161 80 : maTextColor = pSave->aTextColor;
2162 80 : mnTextAlign = pSave->nTextAlign;
2163 80 : mnTextLayoutMode = pSave->nTextLayoutMode;
2164 80 : mnBkMode = pSave->nBkMode;
2165 80 : mnGfxMode = pSave->nGfxMode;
2166 80 : mnMapMode = pSave->nMapMode;
2167 80 : maBkColor = pSave->aBkColor;
2168 80 : mbFillStyleSelected = pSave->bFillStyleSelected;
2169 :
2170 80 : maActPos = pSave->aActPos;
2171 80 : maXForm = pSave->aXForm;
2172 80 : meRasterOp = pSave->eRasterOp;
2173 :
2174 80 : mnWinOrgX = pSave->nWinOrgX;
2175 80 : mnWinOrgY = pSave->nWinOrgY;
2176 80 : mnWinExtX = pSave->nWinExtX;
2177 80 : mnWinExtY = pSave->nWinExtY;
2178 80 : mnDevOrgX = pSave->nDevOrgX;
2179 80 : mnDevOrgY = pSave->nDevOrgY;
2180 80 : mnDevWidth = pSave->nDevWidth;
2181 80 : mnDevHeight = pSave->nDevHeight;
2182 :
2183 80 : aPathObj = pSave->aPathObj;
2184 80 : if ( ! ( aClipPath == pSave->aClipPath ) )
2185 : {
2186 5 : aClipPath = pSave->aClipPath;
2187 5 : mbClipNeedsUpdate = true;
2188 : }
2189 80 : if ( meLatestRasterOp != meRasterOp )
2190 80 : mpGDIMetaFile->AddAction( new MetaRasterOpAction( meRasterOp ) );
2191 80 : vSaveStack.pop_back();
2192 : }
2193 80 : }
2194 :
2195 0 : void WinMtfOutput::AddFromGDIMetaFile( GDIMetaFile& rGDIMetaFile )
2196 : {
2197 0 : rGDIMetaFile.Play( *mpGDIMetaFile, 0xFFFFFFFF );
2198 0 : }
2199 :
2200 4 : void WinMtfOutput::PassEMFPlusHeaderInfo()
2201 : {
2202 : EMFP_DEBUG(printf ("\t\t\tadd EMF_PLUS header info\n"));
2203 :
2204 4 : SvMemoryStream mem;
2205 : sal_Int32 nLeft, nRight, nTop, nBottom;
2206 :
2207 4 : nLeft = mrclFrame.Left();
2208 4 : nTop = mrclFrame.Top();
2209 4 : nRight = mrclFrame.Right();
2210 4 : nBottom = mrclFrame.Bottom();
2211 :
2212 : // emf header info
2213 4 : mem << nLeft << nTop << nRight << nBottom;
2214 4 : mem << mnPixX << mnPixY << mnMillX << mnMillY;
2215 :
2216 : float one, zero;
2217 :
2218 4 : one = 1;
2219 4 : zero = 0;
2220 :
2221 : // add transformation matrix to be used in vcl's metaact.cxx for
2222 : // rotate and scale operations
2223 4 : mem << one << zero << zero << one << zero << zero;
2224 :
2225 : // need to flush the stream, otherwise GetEndOfData will return 0
2226 : // on windows where the function parameters are probably resolved in reverse order
2227 4 : mem.Flush();
2228 :
2229 4 : mpGDIMetaFile->AddAction( new MetaCommentAction( "EMF_PLUS_HEADER_INFO", 0, (const sal_uInt8*) mem.GetData(), mem.GetEndOfData() ) );
2230 4 : mpGDIMetaFile->UseCanvas( sal_True );
2231 4 : }
2232 :
2233 70 : void WinMtfOutput::PassEMFPlus( void* pBuffer, sal_uInt32 nLength )
2234 : {
2235 : EMFP_DEBUG(printf ("\t\t\tadd EMF_PLUS comment length %04x\n",(unsigned int) nLength));
2236 70 : mpGDIMetaFile->AddAction( new MetaCommentAction( "EMF_PLUS", 0, static_cast<const sal_uInt8*>(pBuffer), nLength ) );
2237 70 : }
2238 :
2239 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|