LibreOffice Module vcl (master)  1
wmfwr.cxx
Go to the documentation of this file.
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 <sal/config.h>
21 #include <osl/diagnose.h>
22 
23 #include <algorithm>
24 
25 #include "wmfwr.hxx"
26 #include "emfwr.hxx"
27 #include <rtl/crc.h>
28 #include <rtl/tencinfo.h>
29 #include <tools/bigint.hxx>
30 #include <tools/helpers.hxx>
31 #include <tools/tenccvt.hxx>
32 #include <tools/fract.hxx>
33 #include <tools/stream.hxx>
34 #include <vcl/dibtools.hxx>
35 #include <vcl/metaact.hxx>
36 #include <vcl/FilterConfigItem.hxx>
39 #include <memory>
40 #include <vcl/fontcharmap.hxx>
41 
42 // MS Windows defines
43 
44 #define W_META_SETBKMODE 0x0102
45 #define W_META_SETROP2 0x0104
46 #define W_META_SETSTRETCHBLTMODE 0x0107
47 #define W_META_SETTEXTCOLOR 0x0209
48 #define W_META_SETWINDOWORG 0x020B
49 #define W_META_SETWINDOWEXT 0x020C
50 #define W_META_LINETO 0x0213
51 #define W_META_MOVETO 0x0214
52 #define W_META_INTERSECTCLIPRECT 0x0416
53 #define W_META_ARC 0x0817
54 #define W_META_ELLIPSE 0x0418
55 #define W_META_PIE 0x081A
56 #define W_META_RECTANGLE 0x041B
57 #define W_META_ROUNDRECT 0x061C
58 #define W_META_SAVEDC 0x001E
59 #define W_META_SETPIXEL 0x041F
60 #define W_META_TEXTOUT 0x0521
61 #define W_META_POLYGON 0x0324
62 #define W_META_POLYLINE 0x0325
63 #define W_META_ESCAPE 0x0626
64 #define W_META_RESTOREDC 0x0127
65 #define W_META_SELECTOBJECT 0x012D
66 #define W_META_SETTEXTALIGN 0x012E
67 #define W_META_CHORD 0x0830
68 #define W_META_EXTTEXTOUT 0x0a32
69 #define W_META_POLYPOLYGON 0x0538
70 #define W_META_STRETCHDIB 0x0f43
71 #define W_META_DELETEOBJECT 0x01f0
72 #define W_META_CREATEPENINDIRECT 0x02FA
73 #define W_META_CREATEFONTINDIRECT 0x02FB
74 #define W_META_CREATEBRUSHINDIRECT 0x02FC
75 
76 #define W_TRANSPARENT 1
77 #define W_OPAQUE 2
78 
79 #define W_R2_NOT 6
80 #define W_R2_XORPEN 7
81 #define W_R2_COPYPEN 13
82 
83 #define W_TA_NOUPDATECP 0x0000
84 #define W_TA_LEFT 0x0000
85 #define W_TA_RIGHT 0x0002
86 #define W_TA_TOP 0x0000
87 #define W_TA_BOTTOM 0x0008
88 #define W_TA_BASELINE 0x0018
89 #define W_TA_RTLREADING 0x0100
90 
91 #define W_SRCCOPY 0x00CC0020L
92 #define W_SRCPAINT 0x00EE0086L
93 #define W_SRCAND 0x008800C6L
94 #define W_SRCINVERT 0x00660046L
95 #define W_DSTINVERT 0x00550009L
96 
97 #define W_PS_SOLID 0
98 #define W_PS_DASH 1
99 #define W_PS_DOT 2
100 #define W_PS_DASHDOT 3
101 #define W_PS_DASHDOTDOT 4
102 #define W_PS_NULL 5
103 
104 #define W_LF_FACESIZE 32
105 
106 #define W_ANSI_CHARSET 0
107 
108 #define W_DEFAULT_PITCH 0x00
109 #define W_FIXED_PITCH 0x01
110 #define W_VARIABLE_PITCH 0x02
111 
112 #define W_FF_DONTCARE 0x00
113 #define W_FF_ROMAN 0x10
114 #define W_FF_SWISS 0x20
115 #define W_FF_MODERN 0x30
116 #define W_FF_SCRIPT 0x40
117 #define W_FF_DECORATIVE 0x50
118 
119 #define W_FW_DONTCARE 0
120 #define W_FW_THIN 100
121 #define W_FW_LIGHT 300
122 #define W_FW_NORMAL 400
123 #define W_FW_MEDIUM 500
124 #define W_FW_SEMIBOLD 600
125 #define W_FW_BOLD 700
126 #define W_FW_ULTRALIGHT 200
127 #define W_FW_ULTRABOLD 800
128 #define W_FW_BLACK 900
129 
130 #define W_BS_SOLID 0
131 #define W_BS_HOLLOW 1
132 
133 #define W_MFCOMMENT 15
134 
135 #define PRIVATE_ESCAPE_UNICODE 2
136 
138  : bStatus(false)
139  , nLastPercent(0)
140  , pWMF(nullptr)
141  , pVirDev(nullptr)
142  , nMetafileHeaderPos(0)
143  , nMaxRecordSize(0)
144  , nActRecordPos(0)
145  , eSrcRasterOp(RasterOp::OverPaint)
146  , eSrcTextAlign(ALIGN_BASELINE)
147  , pAttrStack(nullptr)
148  , eSrcHorTextAlign(W_TA_LEFT)
149  , eDstROP2(RasterOp::OverPaint)
150  , eDstTextAlign(ALIGN_BASELINE)
151  , eDstHorTextAlign(W_TA_LEFT)
152  , bHandleAllocated{}
153  , nDstPenHandle(0)
154  , nDstFontHandle(0)
155  , nDstBrushHandle(0)
156  , nNumberOfActions(0)
157  , nNumberOfBitmaps(0)
158  , nWrittenActions(0)
159  , nWrittenBitmaps(0)
160  , nActBitmapPercent(0)
161  , bEmbedEMF(false)
162 {
163 }
164 
166 {
167  if ( !xStatusIndicator.is() )
168  return;
169 
170  sal_uLong nPercent;
171 
172  // we simply assume that 16386 actions match to a bitmap
173  // (normally a metafile either contains only actions or some bitmaps and
174  // almost no actions. In which case the ratio is less important)
175 
176  nPercent=((nWrittenBitmaps<<14)+(nActBitmapPercent<<14)/100+nWrittenActions)
177  *100
179 
180  if ( nPercent >= nLastPercent + 3 )
181  {
182  nLastPercent = nPercent;
183  if( nPercent <= 100 )
184  xStatusIndicator->setValue( nPercent );
185  }
186 }
187 
189 {
190  size_t nAction, nActionCount;
191 
192  nActionCount = rMTF.GetActionSize();
193 
194  for ( nAction=0; nAction < nActionCount; nAction++ )
195  {
196  MetaAction* pMA = rMTF.GetAction( nAction );
197 
198  switch( pMA->GetType() )
199  {
200  case MetaActionType::BMP:
207  break;
208  default: break;
209  }
211  }
212 }
213 
214 void WMFWriter::WritePointXY(const Point & rPoint)
215 {
217  pWMF->WriteInt16( aPt.X() ).WriteInt16( aPt.Y() );
218 }
219 
220 void WMFWriter::WritePointYX(const Point & rPoint)
221 {
223  pWMF->WriteInt16( aPt.Y() ).WriteInt16( aPt.X() );
224 }
225 
226 sal_Int32 WMFWriter::ScaleWidth( sal_Int32 nDX )
227 {
229  return aSz.Width();
230 }
231 
232 void WMFWriter::WriteSize(const Size & rSize)
233 {
235  pWMF->WriteInt16( aSz.Width() ).WriteInt16( aSz.Height() );
236 }
237 
239 {
241  pWMF->WriteInt16( aSz.Height() ).WriteInt16( aSz.Width() );
242 }
243 
245 {
246  WritePointYX(Point(rRect.Right()+1,rRect.Bottom()+1));
247  WritePointYX(rRect.TopLeft());
248 }
249 
250 void WMFWriter::WriteColor(const Color & rColor)
251 {
252  pWMF->WriteUChar( rColor.GetRed() ).WriteUChar( rColor.GetGreen() ).WriteUChar( rColor.GetBlue() ).WriteUChar( 0 );
253 }
254 
255 void WMFWriter::WriteRecordHeader(sal_uInt32 nSizeWords, sal_uInt16 nType)
256 {
258  if (nSizeWords>nMaxRecordSize) nMaxRecordSize=nSizeWords;
259  pWMF->WriteUInt32( nSizeWords ).WriteUInt16( nType );
260 }
261 
263 {
264  sal_uLong nPos;
265  sal_uInt32 nSize;
266 
267  nPos=pWMF->Tell(); nSize=nPos-nActRecordPos;
268  if ((nSize & 1)!=0) {
269  pWMF->WriteUChar( 0 );
270  nPos++; nSize++;
271  }
272  nSize/=2;
273  if (nSize>nMaxRecordSize) nMaxRecordSize=nSize;
274  pWMF->Seek(nActRecordPos);
275  pWMF->WriteUInt32( nSize );
276  pWMF->Seek(nPos);
277 }
278 
279 void WMFWriter::WMFRecord_Arc(const tools::Rectangle & rRect, const Point & rStartPt, const Point & rEndPt)
280 {
281  WriteRecordHeader(0x0000000b,W_META_ARC);
282  WritePointYX(rEndPt);
283  WritePointYX(rStartPt);
284  WriteRectangle(rRect);
285 }
286 
287 void WMFWriter::WMFRecord_Chord(const tools::Rectangle & rRect, const Point & rStartPt, const Point & rEndPt)
288 {
289  WriteRecordHeader(0x0000000b,W_META_CHORD);
290  WritePointYX(rEndPt);
291  WritePointYX(rStartPt);
292  WriteRectangle(rRect);
293 }
294 
296 {
298 
299  if( rColor==COL_TRANSPARENT )
301  else
303 
304  WriteColor( rColor );
305  pWMF->WriteUInt16( 0 );
306 }
307 
309 {
310  sal_uInt16 nWeight,i;
311  sal_uInt8 nPitchFamily;
312 
314  WriteHeightWidth(Size(rFont.GetFontSize().Width(),-rFont.GetFontSize().Height()));
315  pWMF->WriteInt16( rFont.GetOrientation() ).WriteInt16( rFont.GetOrientation() );
316 
317  switch (rFont.GetWeight()) {
318  case WEIGHT_THIN: nWeight=W_FW_THIN; break;
319  case WEIGHT_ULTRALIGHT: nWeight=W_FW_ULTRALIGHT; break;
320  case WEIGHT_LIGHT: nWeight=W_FW_LIGHT; break;
321  case WEIGHT_SEMILIGHT: nWeight=W_FW_LIGHT; break;
322  case WEIGHT_NORMAL: nWeight=W_FW_NORMAL; break;
323  case WEIGHT_MEDIUM: nWeight=W_FW_MEDIUM; break;
324  case WEIGHT_SEMIBOLD: nWeight=W_FW_SEMIBOLD; break;
325  case WEIGHT_BOLD: nWeight=W_FW_BOLD; break;
326  case WEIGHT_ULTRABOLD: nWeight=W_FW_ULTRABOLD; break;
327  case WEIGHT_BLACK: nWeight=W_FW_BLACK; break;
328  default: nWeight=W_FW_DONTCARE;
329  }
330  pWMF->WriteUInt16( nWeight );
331 
332  if (rFont.GetItalic()==ITALIC_NONE) pWMF->WriteUChar( 0 ); else pWMF->WriteUChar( 1 );
333  if (rFont.GetUnderline()==LINESTYLE_NONE) pWMF->WriteUChar( 0 ); else pWMF->WriteUChar( 1 );
334  if (rFont.GetStrikeout()==STRIKEOUT_NONE) pWMF->WriteUChar( 0 ); else pWMF->WriteUChar( 1 );
335 
336  rtl_TextEncoding eFontNameEncoding = rFont.GetCharSet();
337  sal_uInt8 nCharSet = rtl_getBestWindowsCharsetFromTextEncoding( eFontNameEncoding );
338  if ( eFontNameEncoding == RTL_TEXTENCODING_SYMBOL )
339  eFontNameEncoding = RTL_TEXTENCODING_MS_1252;
340  if ( nCharSet == 1 )
341  nCharSet = W_ANSI_CHARSET;
342  pWMF->WriteUChar( nCharSet );
343 
344  pWMF->WriteUChar( 0 ).WriteUChar( 0 ).WriteUChar( 0 );
345 
346  switch (rFont.GetPitch()) {
347  case PITCH_FIXED: nPitchFamily=W_FIXED_PITCH; break;
348  case PITCH_VARIABLE: nPitchFamily=W_VARIABLE_PITCH; break;
349  default: nPitchFamily=W_DEFAULT_PITCH;
350  }
351  switch (rFont.GetFamilyType()) {
352  case FAMILY_DECORATIVE: nPitchFamily|=W_FF_DECORATIVE; break;
353  case FAMILY_MODERN: nPitchFamily|=W_FF_MODERN; break;
354  case FAMILY_ROMAN: nPitchFamily|=W_FF_ROMAN; break;
355  case FAMILY_SCRIPT: nPitchFamily|=W_FF_SCRIPT; break;
356  case FAMILY_SWISS: nPitchFamily|=W_FF_SWISS; break;
357  default: nPitchFamily|=W_FF_DONTCARE;
358  }
359  pWMF->WriteUChar( nPitchFamily );
360 
361  OString aFontName(OUStringToOString(rFont.GetFamilyName(), eFontNameEncoding));
362  for ( i = 0; i < W_LF_FACESIZE; i++ )
363  {
364  char nChar = ( i < aFontName.getLength() ) ? aFontName[i] : 0;
365  pWMF->WriteChar( nChar );
366  }
368 }
369 
370 void WMFWriter::WMFRecord_CreatePenIndirect(const Color& rColor, const LineInfo& rLineInfo )
371 {
373  sal_uInt16 nStyle = rColor == COL_TRANSPARENT ? W_PS_NULL : W_PS_SOLID;
374  switch( rLineInfo.GetStyle() )
375  {
376  case LineStyle::Dash :
377  {
378  if ( rLineInfo.GetDotCount() )
379  {
380  if ( !rLineInfo.GetDashCount() )
381  nStyle = W_PS_DOT;
382  else
383  {
384  if ( rLineInfo.GetDotCount() == 1 )
385  nStyle = W_PS_DASHDOT;
386  else
387  nStyle = W_PS_DASHDOTDOT;
388  }
389  }
390  else
391  nStyle = W_PS_DASH;
392  }
393  break;
394  case LineStyle::NONE :
395  nStyle = W_PS_NULL;
396  break;
397  default:
398  break;
399  }
400  pWMF->WriteUInt16( nStyle );
401 
402  WriteSize( Size( rLineInfo.GetWidth(), 0 ) );
403  WriteColor( rColor );
404 }
405 
406 void WMFWriter::WMFRecord_DeleteObject(sal_uInt16 nObjectHandle)
407 {
409  pWMF->WriteUInt16( nObjectHandle );
410 }
411 
413 {
414  WriteRecordHeader(0x00000007,W_META_ELLIPSE);
415  WriteRectangle(rRect);
416 }
417 
418 void WMFWriter::WMFRecord_Escape( sal_uInt32 nEsc, sal_uInt32 nLen, const sal_Int8* pData )
419 {
420 #ifdef OSL_BIGENDIAN
421  sal_uInt32 nTmp = OSL_SWAPDWORD( nEsc );
422  sal_uInt32 nCheckSum = rtl_crc32( 0, &nTmp, 4 );
423 #else
424  sal_uInt32 nCheckSum = rtl_crc32( 0, &nEsc, 4 );
425 #endif
426  if ( nLen )
427  nCheckSum = rtl_crc32( nCheckSum, pData, nLen );
428 
429  WriteRecordHeader( 3 + 9 + ( ( nLen + 1 ) >> 1 ), W_META_ESCAPE );
431  .WriteUInt16( nLen + 14 ) // we will always have a fourteen byte escape header:
432  .WriteUInt16( 0x4f4f ) // OO
433  .WriteUInt32( 0xa2c2a ) // evil magic number
434  .WriteUInt32( nCheckSum ) // crc32 checksum about nEsc & pData
435  .WriteUInt32( nEsc ); // escape number
436  pWMF->WriteBytes( pData, nLen );
437  if ( nLen & 1 )
438  pWMF->WriteUChar( 0 ); // pad byte
439 }
440 
441 /* if return value is true, then a complete unicode string and also a polygon replacement has been written,
442  so there is no more action necessary
443 */
444 bool WMFWriter::WMFRecord_Escape_Unicode( const Point& rPoint, const OUString& rUniStr, const long* pDXAry )
445 {
446  bool bEscapeUsed = false;
447 
448  sal_uInt32 i, nStringLen = rUniStr.getLength();
449  if ( nStringLen )
450  {
451  // first we will check if a comment is necessary
452  if ( aSrcFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL ) // symbol is always byte character, so there is no unicode loss
453  {
454  const sal_Unicode* pBuf = rUniStr.getStr();
455  const rtl_TextEncoding aTextEncodingOrg = aSrcFont.GetCharSet();
456  OString aByteStr(OUStringToOString(rUniStr, aTextEncodingOrg));
457  OUString aUniStr2(OStringToOUString(aByteStr, aTextEncodingOrg));
458  const sal_Unicode* pConversion = aUniStr2.getStr(); // this is the unicode array after bytestring <-> unistring conversion
459  for ( i = 0; i < nStringLen; i++ )
460  {
461  if ( *pBuf++ != *pConversion++ )
462  break;
463  }
464 
465  if ( i != nStringLen ) // after conversion the characters are not original,
466  { // try again, with determining a better charset from unicode char
467  pBuf = rUniStr.getStr();
468  const sal_Unicode* pCheckChar = pBuf;
469  rtl_TextEncoding aTextEncoding = getBestMSEncodingByChar(*pCheckChar); // try the first character
470  if (aTextEncoding == RTL_TEXTENCODING_DONTKNOW) {
471  aTextEncoding = aTextEncodingOrg;
472  }
473  for ( i = 1; i < nStringLen; i++)
474  {
475  if (aTextEncoding != aTextEncodingOrg) // found something
476  break;
477  pCheckChar++;
478  aTextEncoding = getBestMSEncodingByChar(*pCheckChar); // try the next character
479  if (aTextEncoding == RTL_TEXTENCODING_DONTKNOW) {
480  aTextEncoding = aTextEncodingOrg;
481  }
482  }
483 
484  aByteStr = OUStringToOString(rUniStr, aTextEncoding);
485  aUniStr2 = OStringToOUString(aByteStr, aTextEncoding);
486  pConversion = aUniStr2.getStr(); // this is the unicode array after bytestring <-> unistring conversion
487  for ( i = 0; i < nStringLen; i++ )
488  {
489  if ( *pBuf++ != *pConversion++ )
490  break;
491  }
492  if (i == nStringLen)
493  {
494  aSrcFont.SetCharSet (aTextEncoding);
495  SetAllAttr();
496  }
497  }
498 
499  if ( ( i != nStringLen ) || IsStarSymbol( aSrcFont.GetFamilyName() ) ) // after conversion the characters are not original, so we
500  { // will store the unicode string and a polypoly replacement
501  Color aOldFillColor( aSrcFillColor );
502  Color aOldLineColor( aSrcLineColor );
508  std::vector<tools::PolyPolygon> aPolyPolyVec;
509  if ( pVirDev->GetTextOutlines( aPolyPolyVec, rUniStr ) )
510  {
511  sal_uInt32 nDXCount = pDXAry ? nStringLen : 0;
512  sal_uInt32 nSkipActions = aPolyPolyVec.size();
513  sal_Int32 nStrmLen = 8 +
514  + sizeof( nStringLen ) + ( nStringLen * 2 )
515  + sizeof( nDXCount ) + ( nDXCount * 4 )
516  + sizeof( nSkipActions );
517 
518  SvMemoryStream aMemoryStream( nStrmLen );
520  aMemoryStream.WriteInt32( aPt.X() )
521  .WriteInt32( aPt.Y() )
522  .WriteUInt32( nStringLen );
523  for ( i = 0; i < nStringLen; i++ )
524  aMemoryStream.WriteUInt16( rUniStr[ i ] );
525  aMemoryStream.WriteUInt32( nDXCount );
526  for ( i = 0; i < nDXCount; i++ )
527  aMemoryStream.WriteInt32( pDXAry[ i ] );
528  aMemoryStream.WriteUInt32( nSkipActions );
529  WMFRecord_Escape( PRIVATE_ESCAPE_UNICODE, nStrmLen, static_cast<const sal_Int8*>(aMemoryStream.GetData()) );
530 
531  for ( const auto& rPolyPoly : aPolyPolyVec )
532  {
533  tools::PolyPolygon aPolyPoly( rPolyPoly );
534  aPolyPoly.Move( rPoint.X(), rPoint.Y() );
535  WMFRecord_PolyPolygon( aPolyPoly );
536  }
537  aSrcFillColor = aOldFillColor;
538  aSrcLineColor = aOldLineColor;
539  bEscapeUsed = true;
540  }
541  }
542  }
543  }
544  return bEscapeUsed;
545 }
546 
547 void WMFWriter::WMFRecord_ExtTextOut( const Point& rPoint,
548  const OUString& rString,
549  const long* pDXAry )
550 {
551  sal_Int32 nOriginalTextLen = rString.getLength();
552 
553  if ( (nOriginalTextLen <= 1) || (pDXAry == nullptr) )
554  {
555  WMFRecord_TextOut(rPoint, rString);
556  return;
557  }
558  rtl_TextEncoding eChrSet = aSrcFont.GetCharSet();
559  OString aByteString(OUStringToOString(rString, eChrSet));
560  TrueExtTextOut(rPoint, rString, aByteString, pDXAry);
561 }
562 
563 void WMFWriter::TrueExtTextOut( const Point& rPoint, const OUString& rString,
564  const OString& rByteString, const long* pDXAry )
565 {
567  WritePointYX( rPoint );
568  sal_uInt16 nNewTextLen = static_cast<sal_uInt16>(rByteString.getLength());
569  pWMF->WriteUInt16( nNewTextLen ).WriteUInt16( 0 );
570  write_uInt8s_FromOString(*pWMF, rByteString, nNewTextLen);
571  if ( nNewTextLen & 1 )
572  pWMF->WriteUChar( 0 );
573 
574  sal_Int32 nOriginalTextLen = rString.getLength();
575  std::unique_ptr<sal_Int16[]> pConvertedDXAry(new sal_Int16[ nOriginalTextLen ]);
576  sal_Int32 j = 0;
577  pConvertedDXAry[ j++ ] = static_cast<sal_Int16>(ScaleWidth( pDXAry[ 0 ] ));
578  for (sal_Int32 i = 1; i < ( nOriginalTextLen - 1 ); ++i)
579  pConvertedDXAry[ j++ ] = static_cast<sal_Int16>(ScaleWidth( pDXAry[ i ] - pDXAry[ i - 1 ] ));
580  pConvertedDXAry[ j ] = static_cast<sal_Int16>(ScaleWidth( pDXAry[ nOriginalTextLen - 2 ] / ( nOriginalTextLen - 1 ) ));
581 
582  for (sal_Int32 i = 0; i < nOriginalTextLen; ++i)
583  {
584  sal_Int16 nDx = pConvertedDXAry[ i ];
585  pWMF->WriteInt16( nDx );
586  if ( nOriginalTextLen < nNewTextLen )
587  {
588  sal_Unicode nUniChar = rString[i];
589  OString aTemp(&nUniChar, 1, aSrcFont.GetCharSet());
590  j = aTemp.getLength();
591  while ( --j > 0 )
592  pWMF->WriteUInt16( 0 );
593  }
594  }
595  pConvertedDXAry.reset();
597 }
598 
599 void WMFWriter::WMFRecord_LineTo(const Point & rPoint)
600 {
601  WriteRecordHeader(0x00000005,W_META_LINETO);
602  WritePointYX(rPoint);
603 }
604 
605 void WMFWriter::WMFRecord_MoveTo(const Point & rPoint)
606 {
607  WriteRecordHeader(0x00000005,W_META_MOVETO);
608  WritePointYX(rPoint);
609 }
610 
611 void WMFWriter::WMFRecord_Pie(const tools::Rectangle & rRect, const Point & rStartPt, const Point & rEndPt)
612 {
613  WriteRecordHeader(0x0000000b,W_META_PIE);
614  WritePointYX(rEndPt);
615  WritePointYX(rStartPt);
616  WriteRectangle(rRect);
617 }
618 
620 {
621  tools::Polygon aSimplePoly;
622  if ( rPoly.HasFlags() )
623  rPoly.AdaptiveSubdivide( aSimplePoly );
624  else
625  aSimplePoly = rPoly;
626  const sal_uInt16 nSize = aSimplePoly.GetSize();
627  WriteRecordHeader(static_cast<sal_uInt32>(nSize)*2+4,W_META_POLYGON);
628  pWMF->WriteUInt16( nSize );
629  for (sal_uInt16 i=0; i<nSize; ++i)
630  WritePointXY(aSimplePoly.GetPoint(i));
631 }
632 
634 {
635  tools::Polygon aSimplePoly;
636  if ( rPoly.HasFlags() )
637  rPoly.AdaptiveSubdivide( aSimplePoly );
638  else
639  aSimplePoly = rPoly;
640  const sal_uInt16 nSize = aSimplePoly.GetSize();
641  WriteRecordHeader(static_cast<sal_uInt32>(nSize)*2+4,W_META_POLYLINE);
642  pWMF->WriteUInt16( nSize );
643  for (sal_uInt16 i=0; i<nSize; ++i)
644  WritePointXY(aSimplePoly.GetPoint(i));
645 }
646 
648 {
649  const tools::Polygon * pPoly;
650  sal_uInt16 nCount,nSize,i,j;
651 
652  nCount=rPolyPoly.Count();
653  tools::PolyPolygon aSimplePolyPoly( rPolyPoly );
654  for ( i = 0; i < nCount; i++ )
655  {
656  if ( aSimplePolyPoly[ i ].HasFlags() )
657  {
658  tools::Polygon aSimplePoly;
659  aSimplePolyPoly[ i ].AdaptiveSubdivide( aSimplePoly );
660  aSimplePolyPoly[ i ] = aSimplePoly;
661  }
662  }
664  pWMF->WriteUInt16( nCount );
665  for (i=0; i<nCount; i++) pWMF->WriteUInt16( aSimplePolyPoly.GetObject(i).GetSize() );
666  for (i=0; i<nCount; i++) {
667  pPoly=&(aSimplePolyPoly.GetObject(i));
668  nSize=pPoly->GetSize();
669  for (j=0; j<nSize; j++) WritePointXY(pPoly->GetPoint(j));
670  }
672 }
673 
675 {
676  WriteRecordHeader( 0x00000007,W_META_RECTANGLE );
677  WriteRectangle( rRect );
678 }
679 
681 {
683  pWMF->WriteInt16( -1 );
684 }
685 
686 void WMFWriter::WMFRecord_RoundRect(const tools::Rectangle & rRect, long nHorzRound, long nVertRound)
687 {
689  WriteHeightWidth(Size(nHorzRound,nVertRound));
690  WriteRectangle(rRect);
691 }
692 
694 {
695  WriteRecordHeader(0x00000003,W_META_SAVEDC);
696 }
697 
698 void WMFWriter::WMFRecord_SelectObject(sal_uInt16 nObjectHandle)
699 {
701  pWMF->WriteUInt16( nObjectHandle );
702 }
703 
704 void WMFWriter::WMFRecord_SetBkMode(bool bTransparent)
705 {
707  if (bTransparent) pWMF->WriteUInt16( W_TRANSPARENT );
708  else pWMF->WriteUInt16( W_OPAQUE );
709 }
710 
712 {
714  pWMF->WriteUInt16( 3 ); // STRETCH_DELETESCANS
715 }
716 
717 void WMFWriter::WMFRecord_SetPixel(const Point & rPoint, const Color & rColor)
718 {
720  WriteColor(rColor);
721  WritePointYX(rPoint);
722 }
723 
725 {
726  sal_uInt16 nROP2;
727 
728  switch (eROP) {
729  case RasterOp::Invert: nROP2=W_R2_NOT; break;
730  case RasterOp::Xor: nROP2=W_R2_XORPEN; break;
731  default: nROP2=W_R2_COPYPEN;
732  }
733  WriteRecordHeader(0x00000004,W_META_SETROP2);
734  pWMF->WriteUInt16( nROP2 );
735 }
736 
737 void WMFWriter::WMFRecord_SetTextAlign(FontAlign eFontAlign, sal_uInt16 eHorTextAlign)
738 {
739  sal_uInt16 nAlign;
740 
741  switch (eFontAlign) {
742  case ALIGN_TOP: nAlign=W_TA_TOP; break;
743  case ALIGN_BOTTOM: nAlign=W_TA_BOTTOM; break;
744  default: nAlign=W_TA_BASELINE;
745  }
746  nAlign|=eHorTextAlign;
747  nAlign|=W_TA_NOUPDATECP;
748 
750  pWMF->WriteUInt16( nAlign );
751 }
752 
754 {
756  WriteColor(rColor);
757 }
758 
760 {
762  WriteHeightWidth(rSize);
763 }
764 
765 void WMFWriter::WMFRecord_SetWindowOrg(const Point & rPoint)
766 {
768  WritePointYX(rPoint);
769 }
770 
771 void WMFWriter::WMFRecord_StretchDIB( const Point & rPoint, const Size & rSize,
772  const Bitmap & rBitmap, sal_uInt32 nROP )
773 {
774  sal_uLong nPosAnf,nPosEnd;
775 
777  MayCallback();
778 
780 
781  // The sequence in the metafile should be:
782  // some parameters (length 22), then the bitmap without FILEHEADER.
783  // As *pWMF << rBitmap generates a FILEHEADER of size 14,
784  // we first write the bitmap at the right position
785  // and overwrite later the FILEHEADER with the parameters.
786  nPosAnf=pWMF->Tell(); // remember position, where parameters should be stored
787  pWMF->WriteInt32( 0 ).WriteInt32( 0 ); // replenish 8 bytes (these 8 bytes +
788  // 14 bytes superfluous FILEHEADER
789  // = 22 bytes parameter)
790 
791  // write bitmap
792  WriteDIB(rBitmap, *pWMF, false, true);
793 
794  // write the parameters:
795  nPosEnd=pWMF->Tell();
796  pWMF->Seek(nPosAnf);
797 
798  // determine raster-op, if nothing was passed
799  if( !nROP )
800  {
801  switch( eSrcRasterOp )
802  {
803  case RasterOp::Invert: nROP = W_DSTINVERT; break;
804  case RasterOp::Xor: nROP = W_SRCINVERT; break;
805  default: nROP = W_SRCCOPY;
806  }
807  }
808 
809  pWMF->WriteUInt32( nROP ).
810  WriteInt16( 0 ).
811  WriteInt16( rBitmap.GetSizePixel().Height() ).
812  WriteInt16( rBitmap.GetSizePixel().Width() ).
813  WriteInt16( 0 ).
814  WriteInt16( 0 );
815 
816  WriteHeightWidth(rSize);
817  WritePointYX(rPoint);
818  pWMF->Seek(nPosEnd);
819 
821 
822  nWrittenBitmaps++;
824 }
825 
826 void WMFWriter::WMFRecord_TextOut(const Point & rPoint, const OUString & rStr)
827 {
828  rtl_TextEncoding eChrSet = aSrcFont.GetCharSet();
829  OString aString(OUStringToOString(rStr, eChrSet));
830  TrueTextOut(rPoint, aString);
831 }
832 
833 void WMFWriter::TrueTextOut(const Point & rPoint, const OString& rString)
834 {
836 
838  sal_Int32 nLen = rString.getLength();
839  if ((nLen&1)!=0) pWMF->WriteUChar( 0 );
840  WritePointYX(rPoint);
842 }
843 
845 {
847  WriteRectangle(rRect);
848 }
849 
851 {
852  sal_uInt16 i;
853 
854  for (i=0; i<MAXOBJECTHANDLES; i++) {
855  if (!bHandleAllocated[i]) {
856  bHandleAllocated[i]=true;
857  return i;
858  }
859  }
860  bStatus=false;
861  return 0xffff;
862 }
863 
864 void WMFWriter::FreeHandle(sal_uInt16 nObjectHandle)
865 {
866  if (nObjectHandle<MAXOBJECTHANDLES) bHandleAllocated[nObjectHandle]=false;
867 }
868 
869 void WMFWriter::CreateSelectDeletePen( const Color& rColor, const LineInfo& rLineInfo )
870 {
871  sal_uInt16 nOldHandle;
872 
873  nOldHandle=nDstPenHandle;
875  WMFRecord_CreatePenIndirect( rColor, rLineInfo );
877  if (nOldHandle<MAXOBJECTHANDLES) {
878  WMFRecord_DeleteObject(nOldHandle);
879  FreeHandle(nOldHandle);
880  }
881 }
882 
884 {
885  sal_uInt16 nOldHandle;
886 
887  nOldHandle=nDstFontHandle;
891  if (nOldHandle<MAXOBJECTHANDLES) {
892  WMFRecord_DeleteObject(nOldHandle);
893  FreeHandle(nOldHandle);
894  }
895 }
896 
898 {
899  sal_uInt16 nOldHandle;
900 
901  nOldHandle=nDstBrushHandle;
905  if (nOldHandle<MAXOBJECTHANDLES) {
906  WMFRecord_DeleteObject(nOldHandle);
907  FreeHandle(nOldHandle);
908  }
909 }
910 
912 {
913  if ( eDstROP2 != eSrcRasterOp )
914  {
917  }
918  if ( ( aDstLineColor != aSrcLineColor ) || ( aDstLineInfo != aSrcLineInfo ) )
919  {
923  }
924  if ( aDstFillColor != aSrcFillColor )
925  {
928  }
929 }
930 
932 {
934  if ( aDstTextColor != aSrcTextColor )
935  {
938  }
940  {
944  }
945  if ( aDstFont == aSrcFont )
946  return;
947 
950  {
951  FontCharMapRef xFontCharMap;
952  if ( pVirDev->GetFontCharMap( xFontCharMap ) )
953  {
954  if ( ( xFontCharMap->GetFirstChar() & 0xff00 ) == 0xf000 )
955  aSrcFont.SetCharSet( RTL_TEXTENCODING_SYMBOL );
956  else if ( aSrcFont.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
957  aSrcFont.SetCharSet( RTL_TEXTENCODING_MS_1252 );
958  }
959  }
960 
961  aDstFont = aSrcFont;
963 }
964 
966 {
967  if(!rLinePolygon.count())
968  return;
969 
970  basegfx::B2DPolyPolygon aLinePolyPolygon(rLinePolygon);
971  basegfx::B2DPolyPolygon aFillPolyPolygon;
972 
973  rInfo.applyToB2DPolyPolygon(aLinePolyPolygon, aFillPolyPolygon);
974 
975  if(aLinePolyPolygon.count())
976  {
977  aSrcLineInfo = rInfo;
979 
980  for(auto const& rB2DPolygon : aLinePolyPolygon)
981  {
982  WMFRecord_PolyLine( tools::Polygon(rB2DPolygon) );
983  }
984  }
985 
986  if(!aFillPolyPolygon.count())
987  return;
988 
989  const Color aOldLineColor(aSrcLineColor);
990  const Color aOldFillColor(aSrcFillColor);
991 
993  aSrcFillColor = aOldLineColor;
995 
996  for(auto const& rB2DPolygon : aFillPolyPolygon)
997  {
998  WMFRecord_Polygon( tools::Polygon(rB2DPolygon) );
999  }
1000 
1001  aSrcLineColor = aOldLineColor;
1002  aSrcFillColor = aOldFillColor;
1004 }
1005 
1007 {
1008  if( !bStatus )
1009  return;
1010 
1011  size_t nACount = rMTF.GetActionSize();
1012 
1014 
1015  for( size_t nA = 0; nA < nACount; nA++ )
1016  {
1017  MetaAction* pMA = rMTF.GetAction( nA );
1018 
1019  switch( pMA->GetType() )
1020  {
1021  case MetaActionType::PIXEL:
1022  {
1023  const MetaPixelAction* pA = static_cast<const MetaPixelAction *>(pMA);
1024  aSrcLineInfo = LineInfo();
1026  WMFRecord_SetPixel( pA->GetPoint(), pA->GetColor() );
1027  }
1028  break;
1029 
1030  case MetaActionType::POINT:
1031  {
1032  const MetaPointAction* pA = static_cast<const MetaPointAction*>(pMA);
1033  const Point& rPt = pA->GetPoint();
1034  aSrcLineInfo = LineInfo();
1036  WMFRecord_MoveTo( rPt);
1037  WMFRecord_LineTo( rPt );
1038  }
1039  break;
1040 
1041  case MetaActionType::LINE:
1042  {
1043  const MetaLineAction* pA = static_cast<const MetaLineAction *>(pMA);
1044  if(pA->GetLineInfo().IsDefault())
1045  {
1046  aSrcLineInfo = pA->GetLineInfo();
1049  WMFRecord_LineTo( pA->GetEndPoint() );
1050  }
1051  else
1052  {
1053  // LineInfo used; handle Dash/Dot and fat lines
1054  basegfx::B2DPolygon aPolygon;
1055  aPolygon.append(basegfx::B2DPoint(pA->GetStartPoint().X(), pA->GetStartPoint().Y()));
1056  aPolygon.append(basegfx::B2DPoint(pA->GetEndPoint().X(), pA->GetEndPoint().Y()));
1057  HandleLineInfoPolyPolygons(pA->GetLineInfo(), aPolygon);
1058  }
1059  }
1060  break;
1061 
1062  case MetaActionType::RECT:
1063  {
1064  const MetaRectAction* pA = static_cast<const MetaRectAction*>(pMA);
1065  aSrcLineInfo = LineInfo();
1067  WMFRecord_Rectangle( pA->GetRect() );
1068  }
1069  break;
1070 
1072  {
1073  const MetaRoundRectAction* pA = static_cast<const MetaRoundRectAction*>(pMA);
1074  aSrcLineInfo = LineInfo();
1076  WMFRecord_RoundRect( pA->GetRect(), pA->GetHorzRound(), pA->GetVertRound() );
1077  }
1078  break;
1079 
1081  {
1082  const MetaEllipseAction* pA = static_cast<const MetaEllipseAction*>(pMA);
1083  aSrcLineInfo = LineInfo();
1085  WMFRecord_Ellipse( pA->GetRect() );
1086  }
1087  break;
1088 
1089  case MetaActionType::ARC:
1090  {
1091  const MetaArcAction* pA = static_cast<const MetaArcAction*>(pMA);
1092  aSrcLineInfo = LineInfo();
1094  WMFRecord_Arc( pA->GetRect(),pA->GetStartPoint(),pA->GetEndPoint() );
1095  }
1096  break;
1097 
1098  case MetaActionType::PIE:
1099  {
1100  const MetaPieAction* pA = static_cast<const MetaPieAction*>(pMA);
1101  aSrcLineInfo = LineInfo();
1103  WMFRecord_Pie( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() );
1104  }
1105  break;
1106 
1107  case MetaActionType::CHORD:
1108  {
1109  const MetaChordAction* pA = static_cast<const MetaChordAction*>(pMA);
1110  aSrcLineInfo = LineInfo();
1112  WMFRecord_Chord( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() );
1113  }
1114  break;
1115 
1117  {
1118  const MetaPolyLineAction* pA = static_cast<const MetaPolyLineAction*>(pMA);
1119  const tools::Polygon& rPoly = pA->GetPolygon();
1120 
1121  if( rPoly.GetSize() )
1122  {
1123  if(pA->GetLineInfo().IsDefault())
1124  {
1125  aSrcLineInfo = pA->GetLineInfo();
1127  WMFRecord_PolyLine( rPoly );
1128  }
1129  else
1130  {
1131  // LineInfo used; handle Dash/Dot and fat lines
1132  HandleLineInfoPolyPolygons(pA->GetLineInfo(), rPoly.getB2DPolygon());
1133  }
1134  }
1135  }
1136  break;
1137 
1139  {
1140  const MetaPolygonAction* pA = static_cast<const MetaPolygonAction*>(pMA);
1141  aSrcLineInfo = LineInfo();
1143  WMFRecord_Polygon( pA->GetPolygon() );
1144  }
1145  break;
1146 
1148  {
1149  const MetaPolyPolygonAction* pA = static_cast<const MetaPolyPolygonAction*>(pMA);
1150  aSrcLineInfo = LineInfo();
1152  WMFRecord_PolyPolygon( pA->GetPolyPolygon() );
1153  }
1154  break;
1155 
1157  {
1158  const MetaTextRectAction * pA = static_cast<const MetaTextRectAction*>(pMA);
1159  OUString aTemp( pA->GetText() );
1160  aSrcLineInfo = LineInfo();
1161  SetAllAttr();
1162 
1163  Point aPos( pA->GetRect().TopLeft() );
1164  if ( !WMFRecord_Escape_Unicode( aPos, aTemp, nullptr ) )
1165  WMFRecord_TextOut( aPos, aTemp );
1166  }
1167  break;
1168 
1169  case MetaActionType::TEXT:
1170  {
1171  const MetaTextAction * pA = static_cast<const MetaTextAction*>(pMA);
1172  OUString aTemp = pA->GetText().copy( pA->GetIndex(), std::min<sal_Int32>(pA->GetText().getLength() - pA->GetIndex(), pA->GetLen()) );
1173  aSrcLineInfo = LineInfo();
1174  SetAllAttr();
1175  if ( !WMFRecord_Escape_Unicode( pA->GetPoint(), aTemp, nullptr ) )
1176  WMFRecord_TextOut( pA->GetPoint(), aTemp );
1177  }
1178  break;
1179 
1181  {
1182  const MetaTextArrayAction* pA = static_cast<const MetaTextArrayAction*>(pMA);
1183 
1184  OUString aTemp = pA->GetText().copy( pA->GetIndex(), std::min<sal_Int32>(pA->GetText().getLength() - pA->GetIndex(), pA->GetLen()) );
1185  aSrcLineInfo = LineInfo();
1186  SetAllAttr();
1187  if ( !WMFRecord_Escape_Unicode( pA->GetPoint(), aTemp, pA->GetDXArray() ) )
1188  WMFRecord_ExtTextOut( pA->GetPoint(), aTemp, pA->GetDXArray() );
1189  }
1190  break;
1191 
1193  {
1194  const MetaStretchTextAction* pA = static_cast<const MetaStretchTextAction *>(pMA);
1195  OUString aTemp = pA->GetText().copy( pA->GetIndex(), std::min<sal_Int32>(pA->GetText().getLength() - pA->GetIndex(), pA->GetLen()) );
1196 
1197  pVirDev->SetFont( aSrcFont );
1198  const sal_Int32 nLen = aTemp.getLength();
1199  std::unique_ptr<long[]> pDXAry(nLen ? new long[ nLen ] : nullptr);
1200  const sal_Int32 nNormSize = pVirDev->GetTextArray( aTemp, pDXAry.get() );
1201  if (nLen && nNormSize == 0)
1202  {
1203  OSL_FAIL("Impossible div by 0 action: MetaStretchTextAction!");
1204  }
1205  else
1206  {
1207  for ( sal_Int32 i = 0; i < ( nLen - 1 ); i++ )
1208  pDXAry[ i ] = pDXAry[ i ] * static_cast<sal_Int32>(pA->GetWidth()) / nNormSize;
1209  if ( ( nLen <= 1 ) || ( static_cast<sal_Int32>(pA->GetWidth()) == nNormSize ) )
1210  pDXAry.reset();
1211  aSrcLineInfo = LineInfo();
1212  SetAllAttr();
1213  if ( !WMFRecord_Escape_Unicode( pA->GetPoint(), aTemp, pDXAry.get() ) )
1214  WMFRecord_ExtTextOut( pA->GetPoint(), aTemp, pDXAry.get() );
1215  }
1216  }
1217  break;
1218 
1219  case MetaActionType::BMP:
1220  {
1221  const MetaBmpAction* pA = static_cast<const MetaBmpAction *>(pMA);
1223  }
1224  break;
1225 
1227  {
1228  const MetaBmpScaleAction* pA = static_cast<const MetaBmpScaleAction*>(pMA);
1229  WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), pA->GetBitmap() );
1230  }
1231  break;
1232 
1234  {
1235  const MetaBmpScalePartAction* pA = static_cast<const MetaBmpScalePartAction*>(pMA);
1236  Bitmap aTmp( pA->GetBitmap() );
1237 
1238  if( aTmp.Crop( tools::Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) ) )
1239  WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aTmp );
1240  }
1241  break;
1242 
1243  case MetaActionType::BMPEX:
1244  {
1245  const MetaBmpExAction* pA = static_cast<const MetaBmpExAction *>(pMA);
1246  Bitmap aBmp( pA->GetBitmapEx().GetBitmap() );
1247  Bitmap aMsk( pA->GetBitmapEx().GetMask() );
1248 
1249  if( !!aMsk )
1250  {
1251  aBmp.Replace( aMsk, COL_WHITE );
1252  aMsk.Invert();
1253  WMFRecord_StretchDIB( pA->GetPoint(), aMsk.GetSizePixel(), aBmp, W_SRCPAINT );
1254  WMFRecord_StretchDIB( pA->GetPoint(), aBmp.GetSizePixel(), aBmp, W_SRCAND );
1255  }
1256  else
1257  WMFRecord_StretchDIB( pA->GetPoint(), aBmp.GetSizePixel(), aBmp );
1258  }
1259  break;
1260 
1262  {
1263  const MetaBmpExScaleAction* pA = static_cast<const MetaBmpExScaleAction*>(pMA);
1264  Bitmap aBmp( pA->GetBitmapEx().GetBitmap() );
1265  Bitmap aMsk( pA->GetBitmapEx().GetMask() );
1266 
1267  if( !!aMsk )
1268  {
1269  aBmp.Replace( aMsk, COL_WHITE );
1270  aMsk.Invert();
1271  WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aMsk, W_SRCPAINT );
1272  WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aBmp, W_SRCAND );
1273  }
1274  else
1275  WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aBmp );
1276  }
1277  break;
1278 
1280  {
1281  const MetaBmpExScalePartAction* pA = static_cast<const MetaBmpExScalePartAction*>(pMA);
1282  BitmapEx aBmpEx( pA->GetBitmapEx() );
1283  aBmpEx.Crop( tools::Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
1284  Bitmap aBmp( aBmpEx.GetBitmap() );
1285  Bitmap aMsk( aBmpEx.GetMask() );
1286 
1287  if( !!aMsk )
1288  {
1289  aBmp.Replace( aMsk, COL_WHITE );
1290  aMsk.Invert();
1291  WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aMsk, W_SRCPAINT );
1292  WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aBmp, W_SRCAND );
1293  }
1294  else
1295  WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aBmp );
1296  }
1297  break;
1298 
1300  {
1301  const MetaGradientAction* pA = static_cast<const MetaGradientAction*>(pMA);
1302  GDIMetaFile aTmpMtf;
1303 
1304  pVirDev->AddGradientActions( pA->GetRect(), pA->GetGradient(), aTmpMtf );
1305  WriteRecords( aTmpMtf );
1306  }
1307  break;
1308 
1309  case MetaActionType::HATCH:
1310  {
1311  const MetaHatchAction* pA = static_cast<const MetaHatchAction*>(pMA);
1312  GDIMetaFile aTmpMtf;
1313 
1314  pVirDev->AddHatchActions( pA->GetPolyPolygon(), pA->GetHatch(), aTmpMtf );
1315  WriteRecords( aTmpMtf );
1316  }
1317  break;
1318 
1320  {
1321  const MetaWallpaperAction* pA = static_cast<const MetaWallpaperAction*>(pMA);
1322  const Color& rColor = pA->GetWallpaper().GetColor();
1323  const Color aOldLineColor( aSrcLineColor );
1324  const Color aOldFillColor( aSrcFillColor );
1325 
1326  aSrcLineColor = rColor;
1327  aSrcFillColor = rColor;
1328  aSrcLineInfo = LineInfo();
1330  WMFRecord_Rectangle( pA->GetRect() );
1331  aSrcLineColor = aOldLineColor;
1332  aSrcFillColor = aOldFillColor;
1333  }
1334  break;
1335 
1337  {
1338  const MetaISectRectClipRegionAction* pA = static_cast<const MetaISectRectClipRegionAction*>(pMA);
1339  WMFRecord_IntersectClipRect( pA->GetRect() );
1340  }
1341  break;
1342 
1344  {
1345  const MetaLineColorAction* pA = static_cast<const MetaLineColorAction*>(pMA);
1346 
1347  if( pA->IsSetting() )
1348  aSrcLineColor = pA->GetColor();
1349  else
1351  }
1352  break;
1353 
1355  {
1356  const MetaFillColorAction* pA = static_cast<const MetaFillColorAction*>(pMA);
1357 
1358  if( pA->IsSetting() )
1359  aSrcFillColor = pA->GetColor();
1360  else
1362  }
1363  break;
1364 
1366  {
1367  const MetaTextColorAction* pA = static_cast<const MetaTextColorAction*>(pMA);
1368  aSrcTextColor = pA->GetColor();
1369  }
1370  break;
1371 
1373  {
1374  const MetaTextFillColorAction* pA = static_cast<const MetaTextFillColorAction*>(pMA);
1375  if( pA->IsSetting() )
1376  aSrcFont.SetFillColor( pA->GetColor() );
1377  else
1379  }
1380  break;
1381 
1383  {
1384  const MetaTextAlignAction* pA = static_cast<const MetaTextAlignAction*>(pMA);
1385  eSrcTextAlign = pA->GetTextAlign();
1386  }
1387  break;
1388 
1390  {
1391  const MetaMapModeAction* pA = static_cast<const MetaMapModeAction*>(pMA);
1392 
1393  if (aSrcMapMode!=pA->GetMapMode())
1394  {
1395  if( pA->GetMapMode().GetMapUnit() == MapUnit::MapRelative )
1396  {
1397  const MapMode& aMM = pA->GetMapMode();
1398  Fraction aScaleX = aMM.GetScaleX();
1399  Fraction aScaleY = aMM.GetScaleY();
1400 
1401  Point aOrigin = aSrcMapMode.GetOrigin();
1402  BigInt aX( aOrigin.X() );
1403  aX *= BigInt( aScaleX.GetDenominator() );
1404  if( aOrigin.X() >= 0 )
1405  if( aScaleX.GetNumerator() >= 0 )
1406  aX += BigInt( aScaleX.GetNumerator()/2 );
1407  else
1408  aX -= BigInt( (aScaleX.GetNumerator()+1)/2 );
1409  else
1410  if( aScaleX.GetNumerator() >= 0 )
1411  aX -= BigInt( (aScaleX.GetNumerator()-1)/2 );
1412  else
1413  aX += BigInt( aScaleX.GetNumerator()/2 );
1414  aX /= BigInt( aScaleX.GetNumerator() );
1415  aOrigin.setX( static_cast<long>(aX) + aMM.GetOrigin().X() );
1416  BigInt aY( aOrigin.Y() );
1417  aY *= BigInt( aScaleY.GetDenominator() );
1418  if( aOrigin.Y() >= 0 )
1419  if( aScaleY.GetNumerator() >= 0 )
1420  aY += BigInt( aScaleY.GetNumerator()/2 );
1421  else
1422  aY -= BigInt( (aScaleY.GetNumerator()+1)/2 );
1423  else
1424  if( aScaleY.GetNumerator() >= 0 )
1425  aY -= BigInt( (aScaleY.GetNumerator()-1)/2 );
1426  else
1427  aY += BigInt( aScaleY.GetNumerator()/2 );
1428  aY /= BigInt( aScaleY.GetNumerator() );
1429  aOrigin.setY( static_cast<long>(aY) + aMM.GetOrigin().Y() );
1430  aSrcMapMode.SetOrigin( aOrigin );
1431 
1432  aScaleX *= aSrcMapMode.GetScaleX();
1433  aScaleY *= aSrcMapMode.GetScaleY();
1434  aSrcMapMode.SetScaleX( aScaleX );
1435  aSrcMapMode.SetScaleY( aScaleY );
1436  }
1437  else
1438  aSrcMapMode=pA->GetMapMode();
1439  }
1440  }
1441  break;
1442 
1443  case MetaActionType::FONT:
1444  {
1445  const MetaFontAction* pA = static_cast<const MetaFontAction*>(pMA);
1446  aSrcFont = pA->GetFont();
1447 
1448  if ( (aSrcFont.GetCharSet() == RTL_TEXTENCODING_DONTKNOW)
1449  || (aSrcFont.GetCharSet() == RTL_TEXTENCODING_UNICODE) )
1450  {
1451  aSrcFont.SetCharSet( RTL_TEXTENCODING_MS_1252 );
1452  }
1457  }
1458  break;
1459 
1460  case MetaActionType::PUSH:
1461  {
1462  const MetaPushAction* pA = static_cast<const MetaPushAction*>(pMA);
1463 
1465  pAt->nFlags = pA->GetFlags();
1466  pAt->aClipRegion = aSrcClipRegion;
1469  pAt->eRasterOp=eSrcRasterOp;
1470  pAt->aFont=aSrcFont;
1473  pAt->aMapMode=aSrcMapMode;
1474  pAt->aLineInfo=aDstLineInfo;
1475  pAt->pSucc=pAttrStack;
1476  pAttrStack=pAt;
1477 
1478  SetAllAttr(); // update ( now all source attributes are equal to the destination attributes )
1479  WMFRecord_SaveDC();
1480 
1481  }
1482  break;
1483 
1484  case MetaActionType::POP:
1485  {
1487 
1488  if( pAt )
1489  {
1490  aDstLineInfo = pAt->aLineInfo;
1491  aDstLineColor = pAt->aLineColor;
1492  if ( pAt->nFlags & PushFlags::LINECOLOR )
1493  aSrcLineColor = pAt->aLineColor;
1494  aDstFillColor = pAt->aFillColor;
1495  if ( pAt->nFlags & PushFlags::FILLCOLOR )
1496  aSrcFillColor = pAt->aFillColor;
1497  eDstROP2 = pAt->eRasterOp;
1498  if ( pAt->nFlags & PushFlags::RASTEROP )
1499  eSrcRasterOp = pAt->eRasterOp;
1500  aDstFont = pAt->aFont;
1501  if ( pAt->nFlags & PushFlags::FONT )
1502  aSrcFont = pAt->aFont;
1503  eDstTextAlign = pAt->eTextAlign;
1504  if ( pAt->nFlags & ( PushFlags::FONT | PushFlags::TEXTALIGN ) )
1505  eSrcTextAlign = pAt->eTextAlign;
1506  aDstTextColor = pAt->aTextColor;
1507  if ( pAt->nFlags & ( PushFlags::FONT | PushFlags::TEXTCOLOR ) )
1508  aSrcTextColor = pAt->aTextColor;
1509  if ( pAt->nFlags & PushFlags::MAPMODE )
1510  aSrcMapMode = pAt->aMapMode;
1511  aDstClipRegion = pAt->aClipRegion;
1512  if ( pAt->nFlags & PushFlags::CLIPREGION )
1513  aSrcClipRegion = pAt->aClipRegion;
1514 
1516  pAttrStack = pAt->pSucc;
1517  delete pAt;
1518  }
1519  }
1520  break;
1521 
1522  case MetaActionType::EPS :
1523  {
1524  const MetaEPSAction* pA = static_cast<const MetaEPSAction*>(pMA);
1525  const GDIMetaFile& aGDIMetaFile( pA->GetSubstitute() );
1526 
1527  size_t nCount = aGDIMetaFile.GetActionSize();
1528  for ( size_t i = 0; i < nCount; i++ )
1529  {
1530  const MetaAction* pMetaAct = aGDIMetaFile.GetAction( i );
1531  if ( pMetaAct->GetType() == MetaActionType::BMPSCALE )
1532  {
1533  const MetaBmpScaleAction* pBmpScaleAction = static_cast<const MetaBmpScaleAction*>(pMetaAct);
1534  WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), pBmpScaleAction->GetBitmap() );
1535  break;
1536  }
1537  }
1538  }
1539  break;
1540 
1542  {
1543  const MetaRasterOpAction* pA = static_cast<const MetaRasterOpAction*>(pMA);
1544  eSrcRasterOp=pA->GetRasterOp();
1545  }
1546  break;
1547 
1549  {
1550  aSrcLineInfo = LineInfo();
1552  WMFRecord_PolyPolygon( static_cast<const MetaTransparentAction*>(pMA)->GetPolyPolygon() );
1553  }
1554  break;
1555 
1557  {
1558  const MetaFloatTransparentAction* pA = static_cast<const MetaFloatTransparentAction*>(pMA);
1559 
1560  GDIMetaFile aTmpMtf( pA->GetGDIMetaFile() );
1561  Point aSrcPt( aTmpMtf.GetPrefMapMode().GetOrigin() );
1562  const Size aSrcSize( aTmpMtf.GetPrefSize() );
1563  const Point aDestPt( pA->GetPoint() );
1564  const Size aDestSize( pA->GetSize() );
1565  const double fScaleX = aSrcSize.Width() ? static_cast<double>(aDestSize.Width()) / aSrcSize.Width() : 1.0;
1566  const double fScaleY = aSrcSize.Height() ? static_cast<double>(aDestSize.Height()) / aSrcSize.Height() : 1.0;
1567  long nMoveX, nMoveY;
1568 
1569  aSrcLineInfo = LineInfo();
1570  SetAllAttr();
1571 
1572  if( fScaleX != 1.0 || fScaleY != 1.0 )
1573  {
1574  aTmpMtf.Scale( fScaleX, fScaleY );
1575  aSrcPt.setX( FRound( aSrcPt.X() * fScaleX ) );
1576  aSrcPt.setY( FRound( aSrcPt.Y() * fScaleY ) );
1577  }
1578 
1579  nMoveX = aDestPt.X() - aSrcPt.X();
1580  nMoveY = aDestPt.Y() - aSrcPt.Y();
1581 
1582  if( nMoveX || nMoveY )
1583  aTmpMtf.Move( nMoveX, nMoveY );
1584 
1585  WriteRecords( aTmpMtf );
1586  }
1587  break;
1588 
1590  {
1591  ComplexTextLayoutFlags nLayoutMode = static_cast<const MetaLayoutModeAction*>(pMA)->GetLayoutMode();
1592  eSrcHorTextAlign = 0; // TA_LEFT
1594  {
1596  }
1601  break;
1602  }
1603 
1607  // Explicitly ignored cases
1608  break;
1609 
1610  default:
1611  // TODO: Implement more cases as necessary. Let's not bother with a warning.
1612  break;
1613  }
1614 
1615  nWrittenActions++;
1616  MayCallback();
1617 
1618  if (pWMF->GetError())
1619  bStatus=false;
1620 
1621  if(!bStatus)
1622  break;
1623  }
1624 }
1625 
1626 void WMFWriter::WriteHeader( bool bPlaceable )
1627 {
1628  if( bPlaceable )
1629  {
1630  sal_uInt16 nCheckSum, nValue;
1631  Size aSize( OutputDevice::LogicToLogic(Size(1,1),MapMode(MapUnit::MapInch), aTargetMapMode) );
1632  sal_uInt16 nUnitsPerInch = static_cast<sal_uInt16>( ( aSize.Width() + aSize.Height() ) >> 1 );
1633 
1634  nCheckSum=0;
1635  nValue=0xcdd7; nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
1636  nValue=0x9ac6; nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
1637  nValue=0x0000; nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
1638  nValue=0x0000; nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
1639  nValue=0x0000; nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
1640  nValue=static_cast<sal_uInt16>(aTargetSize.Width()); nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
1641  nValue=static_cast<sal_uInt16>(aTargetSize.Height()); nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
1642  nValue=nUnitsPerInch; nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
1643  nValue=0x0000; nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
1644  nValue=0x0000; nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
1645  pWMF->WriteUInt16( nCheckSum );
1646  }
1647 
1649  pWMF->WriteUInt16( 0x0001 ) // type: file
1650  .WriteUInt16( 0x0009 ) // header length in words
1651  .WriteUInt16( 0x0300 ) // Version as BCD number
1652  .WriteUInt32( 0x00000000 ) // file length (without 1st header), is later corrected by UpdateHeader()
1653  .WriteUInt16( MAXOBJECTHANDLES ) // maximum number of simultaneous objects
1654  .WriteUInt32( 0x00000000 ) // maximum record length, is later corrected by UpdateHeader()
1655  .WriteUInt16( 0x0000 ); // reserved
1656 }
1657 
1659 {
1660  sal_uLong nPos;
1661  sal_uInt32 nFileSize;
1662 
1663  nPos=pWMF->Tell(); // endposition = total size of file
1664  nFileSize=nPos-nMetafileHeaderPos; // subtract size of 1st header
1665  if ((nFileSize&1)!=0) { // if needed round to words
1666  pWMF->WriteUChar( 0 );
1667  nPos++;
1668  nFileSize++;
1669  }
1670  nFileSize>>=1; // convert to number of words
1671  pWMF->Seek(nMetafileHeaderPos+6); // to filesize entry in second header
1672  pWMF->WriteUInt32( nFileSize ); // rectify file size
1673  pWMF->SeekRel(2); // to max-record-length-entry in second header
1674  pWMF->WriteUInt32( nMaxRecordSize ); // and rectify
1675  pWMF->Seek(nPos);
1676 }
1677 
1678 bool WMFWriter::WriteWMF( const GDIMetaFile& rMTF, SvStream& rTargetStream,
1679  FilterConfigItem const * pFConfigItem, bool bPlaceable )
1680 {
1682 
1683  bEmbedEMF = true;
1684  bStatus=true;
1686 
1687  if (pFConfigItem)
1688  {
1689  xStatusIndicator = pFConfigItem->GetStatusIndicator();
1690  if ( xStatusIndicator.is() )
1691  {
1692  xStatusIndicator->start( OUString(), 100 );
1693  }
1694  }
1695  nLastPercent=0;
1696 
1697  pWMF=&rTargetStream;
1698  pWMF->SetEndian(SvStreamEndian::LITTLE);
1699 
1700  nMaxRecordSize=0;
1701 
1702  aSrcMapMode=rMTF.GetPrefMapMode();
1703 
1704  if( bPlaceable )
1705  {
1707  aTargetSize = rMTF.GetPrefSize();
1708  sal_uInt16 nTargetDivisor = CalcSaveTargetMapMode(aTargetMapMode, aTargetSize);
1709  aTargetSize.setWidth( aTargetSize.Width() / nTargetDivisor );
1710  aTargetSize.setHeight( aTargetSize.Height() / nTargetDivisor );
1711  }
1712  else
1713  {
1714  aTargetMapMode = MapMode( MapUnit::MapInch );
1715 
1716  const long nUnit = pVirDev->LogicToPixel( Size( 1, 1 ), aTargetMapMode ).Width();
1717  const Fraction aFrac( 1, nUnit );
1718 
1719  aTargetMapMode.SetScaleX( aFrac );
1720  aTargetMapMode.SetScaleY( aFrac );
1722  }
1723 
1725 
1726  pAttrStack=nullptr;
1727 
1728  for (bool & rn : bHandleAllocated)
1729  rn=false;
1730 
1731  nDstPenHandle=0xffff;
1732  nDstFontHandle=0xffff;
1733  nDstBrushHandle=0xffff;
1734 
1735  nNumberOfActions=0;
1736  nNumberOfBitmaps=0;
1737  nWrittenActions=0;
1738  nWrittenBitmaps=0;
1740 
1741  CountActionsAndBitmaps(rMTF);
1742 
1743  WriteHeader(bPlaceable);
1744  if( bEmbedEMF )
1745  WriteEmbeddedEMF( rMTF );
1748  WMFRecord_SetBkMode( true );
1749 
1752 
1753  aDstLineInfo = LineInfo();
1756 
1759 
1761 
1762  vcl::Font aFont;
1763  aFont.SetCharSet( GetExtendedTextEncoding( RTL_TEXTENCODING_MS_1252 ) );
1764  aFont.SetColor( COL_WHITE );
1765  aFont.SetAlignment( ALIGN_BASELINE );
1766  aDstFont = aSrcFont = aFont;
1768 
1772 
1775 
1776  // Write records
1777  WriteRecords(rMTF);
1778 
1779  WriteRecordHeader(0x00000003,0x0000); // end of file
1780  UpdateHeader();
1781 
1782  while(pAttrStack)
1783  {
1784  pAt=pAttrStack;
1785  pAttrStack=pAt->pSucc;
1786  delete pAt;
1787  }
1788 
1790 
1791  if ( xStatusIndicator.is() )
1792  xStatusIndicator->end();
1793 
1794  return bStatus;
1795 }
1796 
1798  const Size& rPrefSize)
1799 {
1800  Fraction aDivFrac(2, 1);
1801  sal_uInt16 nDivisor = 1;
1802 
1803  Size aSize = OutputDevice::LogicToLogic( rPrefSize, aSrcMapMode, rMapMode );
1804 
1805  while( nDivisor <= 64 && (aSize.Width() > 32767 || aSize.Height() > 32767) )
1806  {
1807  Fraction aFrac = rMapMode.GetScaleX();
1808 
1809  aFrac *= aDivFrac;
1810  rMapMode.SetScaleX(aFrac);
1811  aFrac = rMapMode.GetScaleY();
1812  aFrac *= aDivFrac;
1813  rMapMode.SetScaleY(aFrac);
1814  nDivisor <<= 1;
1815  aSize = OutputDevice::LogicToLogic( rPrefSize, aSrcMapMode, rMapMode );
1816  }
1817 
1818  return nDivisor;
1819 }
1820 
1822 {
1823  SvMemoryStream aStream;
1824  EMFWriter aEMFWriter(aStream);
1825 
1826  if( !aEMFWriter.WriteEMF( rMTF ) )
1827  return;
1828 
1829  sal_uInt64 const nTotalSize = aStream.Tell();
1830  if( nTotalSize > SAL_MAX_UINT32 )
1831  return;
1832  aStream.Seek( 0 );
1833  sal_uInt32 nRemainingSize = static_cast< sal_uInt32 >( nTotalSize );
1834  sal_uInt32 nRecCounts = ( (nTotalSize - 1) / 0x2000 ) + 1;
1835  sal_uInt16 nCheckSum = 0, nWord;
1836 
1837  sal_uInt32 nPos = 0;
1838 
1839  while( nPos + 1 < nTotalSize )
1840  {
1841  aStream.ReadUInt16( nWord );
1842  nCheckSum ^= nWord;
1843  nPos += 2;
1844  }
1845 
1846  nCheckSum = static_cast< sal_uInt16 >( nCheckSum * -1 );
1847 
1848  aStream.Seek( 0 );
1849  while( nRemainingSize > 0 )
1850  {
1851  sal_uInt32 nCurSize;
1852  if( nRemainingSize > 0x2000 )
1853  {
1854  nCurSize = 0x2000;
1855  nRemainingSize -= 0x2000;
1856  }
1857  else
1858  {
1859  nCurSize = nRemainingSize;
1860  nRemainingSize = 0;
1861  }
1862  WriteEMFRecord( aStream,
1863  nCurSize,
1864  nRemainingSize,
1865  nTotalSize,
1866  nRecCounts,
1867  nCheckSum );
1868  nCheckSum = 0;
1869  }
1870 
1871 }
1872 
1873 void WMFWriter::WriteEMFRecord( SvMemoryStream& rStream, sal_uInt32 nCurSize, sal_uInt32 nRemainingSize,
1874  sal_uInt32 nTotalSize, sal_uInt32 nRecCounts, sal_uInt16 nCheckSum )
1875 {
1876  // according to http://msdn.microsoft.com/en-us/library/dd366152%28PROT.13%29.aspx
1878  pWMF->WriteUInt16( W_MFCOMMENT ) // same as META_ESCAPE_ENHANCED_METAFILE
1879  .WriteUInt16( nCurSize + 34 ) // we will always have a 34 byte escape header:
1880  .WriteUInt32( 0x43464D57 ) // WMFC
1881  .WriteUInt32( 0x00000001 ) // Comment type
1882  .WriteUInt32( 0x00010000 ) // version
1883  .WriteUInt16( nCheckSum ) // check sum
1884  .WriteUInt32( 0 ) // flags = 0
1885  .WriteUInt32( nRecCounts ) // total number of records
1886  .WriteUInt32( nCurSize ) // size of this record's data
1887  .WriteUInt32( nRemainingSize ) // remaining size of data in following records, missing in MSDN documentation
1888  .WriteUInt32( nTotalSize ); // total size of EMF stream
1889 
1890  pWMF->WriteBytes(static_cast<const char*>(rStream.GetData()) + rStream.Tell(), nCurSize);
1891  rStream.SeekRel( nCurSize );
1893 }
1894 
1895 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define W_META_SETPIXEL
Definition: wmfwr.cxx:59
sal_uInt16 Count() const
Point TopLeft() const
const Fraction & GetScaleX() const
Definition: mapmod.cxx:172
long Width() const
const LineInfo & GetLineInfo() const
Definition: metaact.hxx:187
#define W_TA_BASELINE
Definition: wmfwr.cxx:88
void WMFRecord_Rectangle(const tools::Rectangle &rRect)
Definition: wmfwr.cxx:674
#define FontAlign
Definition: font.hxx:35
void CreateSelectDeletePen(const Color &rColor, const LineInfo &rLineInfo)
Definition: wmfwr.cxx:869
Bitmap GetMask() const
Definition: bitmapex.cxx:254
void SetFillColor(const Color &)
Definition: font/font.cxx:88
bool GetFontCharMap(FontCharMapRef &rxFontCharMap) const
void WMFRecord_SetROP2(RasterOp eROP)
Definition: wmfwr.cxx:724
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
const tools::Polygon & GetObject(sal_uInt16 nPos) const
#define W_R2_COPYPEN
Definition: wmfwr.cxx:81
bool WriteWMF(const GDIMetaFile &rMTF, SvStream &rTargetStream, FilterConfigItem const *pFilterConfigItem, bool bPlaceable)
Definition: wmfwr.cxx:1678
sal_Int32 GetLen() const
Definition: metaact.hxx:497
const Point & GetPoint() const
Definition: metaact.hxx:705
sal_uInt8 GetRed() const
#define W_BS_SOLID
Definition: wmfwr.cxx:130
void WriteRecordHeader(sal_uInt32 nSizeWords, sal_uInt16 nType)
Definition: wmfwr.cxx:255
const OUString & GetFamilyName() const
Definition: font/font.cxx:670
FAMILY_SCRIPT
FontAlign eSrcTextAlign
Definition: wmfwr.hxx:76
void WMFRecord_SetBkMode(bool bTransparent)
Definition: wmfwr.cxx:704
SvStream & WriteUInt16(sal_uInt16 nUInt16)
void MayCallback()
Definition: wmfwr.cxx:165
long FRound(double fVal)
const GDIMetaFile & GetGDIMetaFile() const
Definition: metaact.hxx:1566
void WMFRecord_SetStretchBltMode()
Definition: wmfwr.cxx:711
#define W_META_CREATEPENINDIRECT
Definition: wmfwr.cxx:72
SvStream & WriteInt32(sal_Int32 nInt32)
FAMILY_MODERN
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
#define W_LF_FACESIZE
Definition: wmfwr.cxx:104
Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
Definition: map.cxx:1675
long Height() const
signed char sal_Int8
void WMFRecord_SelectObject(sal_uInt16 nObjectHandle)
Definition: wmfwr.cxx:698
#define W_FF_ROMAN
Definition: wmfwr.cxx:113
#define W_META_EXTTEXTOUT
Definition: wmfwr.cxx:68
const MapMode & GetPrefMapMode() const
Definition: gdimtf.hxx:178
#define W_BS_HOLLOW
Definition: wmfwr.cxx:131
Color aDstLineColor
Definition: wmfwr.hxx:85
#define W_META_RESTOREDC
Definition: wmfwr.cxx:64
void WMFRecord_PolyPolygon(const tools::PolyPolygon &rPolyPoly)
Definition: wmfwr.cxx:647
sal_uIntPtr sal_uLong
void disposeAndClear()
Definition: vclptr.hxx:200
const Point & GetPoint() const
Definition: metaact.hxx:1604
#define W_R2_XORPEN
Definition: wmfwr.cxx:80
WEIGHT_THIN
void WMFRecord_Arc(const tools::Rectangle &rRect, const Point &rStartPt, const Point &rEndPt)
Definition: wmfwr.cxx:279
const Point & GetPoint() const
Definition: metaact.hxx:1567
WEIGHT_BLACK
#define W_PS_SOLID
Definition: wmfwr.cxx:97
#define W_META_SELECTOBJECT
Definition: wmfwr.cxx:65
sal_uInt64 Seek(sal_uInt64 nPos)
const Size & GetSize() const
Definition: metaact.hxx:706
RasterOp eDstROP2
Definition: wmfwr.hxx:89
WEIGHT_SEMIBOLD
#define W_FW_ULTRABOLD
Definition: wmfwr.cxx:127
sal_uInt16 eSrcHorTextAlign
Definition: wmfwr.hxx:82
const Point & GetEndPoint() const
Definition: metaact.hxx:186
sal_uInt16 nDstPenHandle
Definition: wmfwr.hxx:97
sal_uLong nNumberOfActions
Definition: wmfwr.hxx:103
void SetCharSet(rtl_TextEncoding)
Definition: font/font.cxx:129
const OUString & GetText() const
Definition: metaact.hxx:569
#define W_FW_ULTRALIGHT
Definition: wmfwr.cxx:126
FAMILY_ROMAN
Size GetSizePixel() const
void UpdateHeader()
Definition: wmfwr.cxx:1658
TOOLS_DLLPUBLIC rtl_TextEncoding getBestMSEncodingByChar(sal_Unicode c)
void WriteHeader(bool bPlaceable)
Definition: wmfwr.cxx:1626
sal_uLong nMetafileHeaderPos
Definition: wmfwr.hxx:66
sal_uInt32 nMaxRecordSize
Definition: wmfwr.hxx:67
WEIGHT_LIGHT
void SetMapMode()
Definition: map.cxx:654
sal_uLong nLastPercent
Definition: wmfwr.hxx:57
sal_uInt64 SeekRel(sal_Int64 nPos)
FontFamily GetFamilyType()
Definition: font/font.cxx:694
FontAlign GetAlignment() const
Definition: font/font.cxx:668
void WriteSize(const Size &rSize)
Definition: wmfwr.cxx:232
WEIGHT_BOLD
#define W_FW_SEMIBOLD
Definition: wmfwr.cxx:124
#define SAL_MAX_UINT32
#define W_META_DELETEOBJECT
Definition: wmfwr.cxx:71
#define W_FF_SWISS
Definition: wmfwr.cxx:114
sal_uLong nNumberOfBitmaps
Definition: wmfwr.hxx:104
#define W_META_ROUNDRECT
Definition: wmfwr.cxx:57
#define W_TA_TOP
Definition: wmfwr.cxx:86
sal_uInt16 sal_Unicode
FontItalic GetItalic()
Definition: font/font.cxx:693
constexpr::Color COL_TRANSPARENT(0xFF, 0xFF, 0xFF, 0xFF)
#define W_META_SAVEDC
Definition: wmfwr.cxx:58
long Right() const
ErrCode GetError() const
const Point & GetPoint() const
Definition: metaact.hxx:807
#define W_META_SETWINDOWEXT
Definition: wmfwr.cxx:49
#define W_PS_DASH
Definition: wmfwr.cxx:98
LINESTYLE_NONE
const OUString & GetText() const
Definition: metaact.hxx:495
const Fraction & GetScaleY() const
Definition: mapmod.cxx:174
RasterOp
Definition: vclenum.hxx:194
const Bitmap & GetBitmap() const
Definition: metaact.hxx:672
void WMFRecord_MoveTo(const Point &rPoint)
Definition: wmfwr.cxx:605
int nCount
sal_uLong nWrittenBitmaps
Definition: wmfwr.hxx:106
void WMFRecord_CreatePenIndirect(const Color &rColor, const LineInfo &rLineInfo)
Definition: wmfwr.cxx:370
WMFWriter()
Definition: wmfwr.cxx:137
sal_uInt16 nDstBrushHandle
Definition: wmfwr.hxx:97
TextAlign eTextAlign
Definition: wmfwr.hxx:39
const Gradient & GetGradient() const
Definition: metaact.hxx:989
#define W_FW_LIGHT
Definition: wmfwr.cxx:121
SvStream & WriteUInt32(sal_uInt32 nUInt32)
#define W_FF_DONTCARE
Definition: wmfwr.cxx:112
const Color & GetColor() const
Definition: metaact.hxx:1221
void WMFRecord_SetTextColor(const Color &rColor)
Definition: wmfwr.cxx:753
#define W_DSTINVERT
Definition: wmfwr.cxx:95
Color aDstTextColor
Definition: wmfwr.hxx:87
sal_uInt16 CalcSaveTargetMapMode(MapMode &rMapMode, const Size &rPrefSize)
Definition: wmfwr.cxx:1797
#define W_SRCCOPY
Definition: wmfwr.cxx:91
PITCH_VARIABLE
void WriteRectangle(const tools::Rectangle &rRect)
Definition: wmfwr.cxx:244
Color aSrcFillColor
Definition: wmfwr.hxx:72
const Size & GetSize() const
Definition: metaact.hxx:808
void WriteRecords(const GDIMetaFile &rMTF)
Definition: wmfwr.cxx:1006
#define W_FF_DECORATIVE
Definition: wmfwr.cxx:117
FAMILY_DECORATIVE
sal_uInt8 GetBlue() const
#define W_FW_THIN
Definition: wmfwr.cxx:120
#define W_FIXED_PITCH
Definition: wmfwr.cxx:109
void AdaptiveSubdivide(tools::PolyPolygon &rResult) const
void Move(long nHorzMove, long nVertMove)
VclPtr< VirtualDevice > pVirDev
Definition: wmfwr.hxx:62
rtl_TextEncoding GetExtendedTextEncoding(rtl_TextEncoding eEncoding)
#define W_PS_NULL
Definition: wmfwr.cxx:102
sal_uInt16 eDstHorTextAlign
Definition: wmfwr.hxx:93
struct WMFWriterAttrStackMember * pSucc
Definition: wmfwr.hxx:34
void SetAlignment(FontAlign)
Definition: font/font.cxx:101
LineInfo aSrcLineInfo
Definition: wmfwr.hxx:74
#define W_META_SETBKMODE
Definition: wmfwr.cxx:44
#define PRIVATE_ESCAPE_UNICODE
Definition: wmfwr.cxx:135
sal_UCS4 GetFirstChar() const
Get the first character in the font character map.
WEIGHT_SEMILIGHT
#define W_ANSI_CHARSET
Definition: wmfwr.cxx:106
ALIGN_BASELINE
void SetScaleX(const Fraction &rScaleX)
Definition: mapmod.cxx:108
WMFWriterAttrStackMember * pAttrStack
Definition: wmfwr.hxx:80
Color aSrcTextColor
Definition: wmfwr.hxx:73
const tools::Rectangle & GetRect() const
Definition: metaact.hxx:215
FontPitch GetPitch()
Definition: font/font.cxx:690
const Size & GetPrefSize() const
Definition: gdimtf.hxx:175
void WriteEMFRecord(SvMemoryStream &rStream, sal_uInt32 nCurSize, sal_uInt32 nRemainingSize, sal_uInt32 nTotalSize, sal_uInt32 nRecCounts, sal_uInt16 nCheckSum)
Definition: wmfwr.cxx:1873
#define W_TA_RTLREADING
Definition: wmfwr.cxx:89
#define W_META_STRETCHDIB
Definition: wmfwr.cxx:70
int i
#define W_META_SETTEXTCOLOR
Definition: wmfwr.cxx:47
MapMode aTargetMapMode
Definition: wmfwr.hxx:63
void SetAllAttr()
Definition: wmfwr.cxx:931
#define W_FW_BLACK
Definition: wmfwr.cxx:128
const Point & GetPoint() const
Definition: metaact.hxx:494
bool IsSetting() const
Definition: metaact.hxx:1222
void WMFRecord_SetWindowOrg(const Point &rPoint)
Definition: wmfwr.cxx:765
PITCH_FIXED
#define W_META_CREATEBRUSHINDIRECT
Definition: wmfwr.cxx:74
ComplexTextLayoutFlags
Definition: outdevstate.hxx:66
MapMode aSrcMapMode
Definition: wmfwr.hxx:78
#define W_META_POLYLINE
Definition: wmfwr.cxx:62
#define W_META_CHORD
Definition: wmfwr.cxx:67
#define W_OPAQUE
Definition: wmfwr.cxx:77
const BitmapEx & GetBitmapEx() const
Definition: metaact.hxx:773
const tools::Rectangle & GetRect() const
Definition: metaact.hxx:988
vcl::Region aClipRegion
Definition: wmfwr.hxx:43
sal_uLong nWrittenActions
Definition: wmfwr.hxx:105
void WMFRecord_CreateBrushIndirect(const Color &rColor)
Definition: wmfwr.cxx:295
WEIGHT_MEDIUM
#define W_META_ELLIPSE
Definition: wmfwr.cxx:54
const Size & GetSize() const
Definition: metaact.hxx:1568
void SetOrigin(const Point &rOrigin)
Definition: mapmod.cxx:102
sal_uInt32 GetWidth() const
Definition: metaact.hxx:570
sal_Int32 ScaleWidth(sal_Int32 nDX)
Definition: wmfwr.cxx:226
#define W_VARIABLE_PITCH
Definition: wmfwr.cxx:110
RasterOp eSrcRasterOp
Definition: wmfwr.hxx:75
void WMFRecord_IntersectClipRect(const tools::Rectangle &rRect)
Definition: wmfwr.cxx:844
#define W_META_SETROP2
Definition: wmfwr.cxx:45
bool HasFlags() const
void WMFRecord_Ellipse(const tools::Rectangle &rRect)
Definition: wmfwr.cxx:412
#define W_SRCAND
Definition: wmfwr.cxx:93
#define W_META_SETTEXTALIGN
Definition: wmfwr.cxx:66
std::size_t WriteBytes(const void *pData, std::size_t nSize)
WEIGHT_NORMAL
#define W_MFCOMMENT
Definition: wmfwr.cxx:133
WEIGHT_ULTRALIGHT
long Bottom() const
#define W_FW_MEDIUM
Definition: wmfwr.cxx:123
void SetScaleY(const Fraction &rScaleY)
Definition: mapmod.cxx:115
bool WriteEMF(const GDIMetaFile &rMtf)
Definition: emfwr.cxx:239
const Size & GetFontSize() const
Definition: font/font.cxx:673
const OUString & GetText() const
Definition: metaact.hxx:604
ALIGN_BOTTOM
void WMFRecord_ExtTextOut(const Point &rPoint, const OUString &rString, const long *pDXAry)
Definition: wmfwr.cxx:547
void AddGradientActions(const tools::Rectangle &rRect, const Gradient &rGradient, GDIMetaFile &rMtf)
void WMFRecord_RoundRect(const tools::Rectangle &rRect, long nHorzRound, long nVertRound)
Definition: wmfwr.cxx:686
FontStrikeout GetStrikeout() const
Definition: font/font.cxx:712
sal_uInt16 GetSize() const
Color aSrcLineColor
Definition: wmfwr.hxx:71
sal_Int32 GetLen() const
Definition: metaact.hxx:572
const Point & GetPoint() const
Definition: metaact.hxx:774
WEIGHT_ULTRABOLD
::basegfx::B2DPolygon getB2DPolygon() const
ITALIC_NONE
std::size_t write_uInt16_lenPrefixed_uInt8s_FromOString(SvStream &rStrm, const OString &rStr)
void WMFRecord_TextOut(const Point &rPoint, const OUString &rString)
Definition: wmfwr.cxx:826
Size aTargetSize
Definition: wmfwr.hxx:64
#define W_META_INTERSECTCLIPRECT
Definition: wmfwr.cxx:52
void SetLineAndFillAttr()
Definition: wmfwr.cxx:911
const Size & GetSize() const
Definition: metaact.hxx:1605
sal_uLong nActBitmapPercent
Definition: wmfwr.hxx:107
const Bitmap & GetBitmap() const
Definition: metaact.hxx:704
void SetColor(const Color &)
Definition: font/font.cxx:80
#define W_FW_DONTCARE
Definition: wmfwr.cxx:119
#define W_META_SETWINDOWORG
Definition: wmfwr.cxx:48
Bitmap GetBitmap(Color aTransparentReplaceColor) const
Definition: bitmapex.cxx:232
Point LogicToPixel(const Point &rLogicPt) const
Definition: map.cxx:941
const tools::PolyPolygon & GetPolyPolygon() const
Definition: metaact.hxx:1048
void TrueTextOut(const Point &rPoint, const OString &rString)
Definition: wmfwr.cxx:833
#define W_SRCPAINT
Definition: wmfwr.cxx:92
OString OUStringToOString(const OUString &str, ConnectionSettings const *settings)
sal_uInt16 nDstFontHandle
Definition: wmfwr.hxx:97
const Point & GetPoint() const
Definition: metaact.hxx:568
bool IsSetting() const
Definition: metaact.hxx:1249
sal_uInt8 GetGreen() const
#define W_META_SETSTRETCHBLTMODE
Definition: wmfwr.cxx:46
bool GetTextOutlines(PolyPolyVector &, const OUString &rStr, sal_Int32 nBase=0, sal_Int32 nIndex=0, sal_Int32 nLen=-1, sal_uLong nLayoutWidth=0, const long *pDXArray=nullptr) const
Definition: text.cxx:2416
const Point & GetPoint(sal_uInt16 nPos) const
void UpdateRecordHeader()
Definition: wmfwr.cxx:262
bool bEmbedEMF
Definition: wmfwr.hxx:109
void WMFRecord_SetTextAlign(FontAlign eFontAlign, sal_uInt16 eHorTextAlign)
Definition: wmfwr.cxx:737
const Point & GetStartPoint() const
Definition: metaact.hxx:185
ALIGN_TOP
const Color & GetColor() const
Definition: font/font.cxx:664
short GetOrientation() const
Definition: font/font.cxx:686
vcl::Region aDstClipRegion
Definition: wmfwr.hxx:95
#define W_R2_NOT
Definition: wmfwr.cxx:79
const BitmapEx & GetBitmapEx() const
Definition: metaact.hxx:806
sal_uInt32 count() const
void WMFRecord_CreateFontIndirect(const vcl::Font &rFont)
Definition: wmfwr.cxx:308
void WMFRecord_StretchDIB(const Point &rPoint, const Size &rSize, const Bitmap &rBitmap, sal_uInt32 nROP=0)
Definition: wmfwr.cxx:771
#define W_META_MOVETO
Definition: wmfwr.cxx:51
sal_Int32 GetDenominator() const
#define W_META_POLYPOLYGON
Definition: wmfwr.cxx:69
vcl::Font aSrcFont
Definition: wmfwr.hxx:77
FontWeight GetWeight()
Definition: font/font.cxx:691
unsigned char sal_uInt8
void WMFRecord_DeleteObject(sal_uInt16 nObjectHandle)
Definition: wmfwr.cxx:406
void WMFRecord_PolyLine(const tools::Polygon &rPoly)
Definition: wmfwr.cxx:633
void SetFont(const vcl::Font &rNewFont)
LineInfo aDstLineInfo
Definition: wmfwr.hxx:88
MetaAction * GetAction(size_t nAction) const
Definition: gdimtf.cxx:187
void WMFRecord_RestoreDC()
Definition: wmfwr.cxx:680
void SetEndian(SvStreamEndian SvStreamEndian)
#define W_META_CREATEFONTINDIRECT
Definition: wmfwr.cxx:73
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
vcl::Region aSrcClipRegion
Definition: wmfwr.hxx:79
void HandleLineInfoPolyPolygons(const LineInfo &rInfo, const basegfx::B2DPolygon &rLinePolygon)
Definition: wmfwr.cxx:965
FAMILY_SWISS
SvStream & WriteUChar(unsigned char nChar)
void WMFRecord_Escape(sal_uInt32 nEsc, sal_uInt32 nLen, const sal_Int8 *pData)
Definition: wmfwr.cxx:418
const Point & GetPoint() const
Definition: metaact.hxx:153
#define W_TA_BOTTOM
Definition: wmfwr.cxx:87
const Point & GetPoint() const
Definition: metaact.hxx:673
bool bStatus
Definition: wmfwr.hxx:55
void WriteHeightWidth(const Size &rSize)
Definition: wmfwr.cxx:238
#define W_TA_RIGHT
Definition: wmfwr.cxx:85
SvStream & WriteInt16(sal_Int16 nInt16)
static VclPtr< reference_type > Create(Arg &&...arg)
A construction helper for VclPtr.
Definition: vclptr.hxx:127
void WMFRecord_Chord(const tools::Rectangle &rRect, const Point &rStartPt, const Point &rEndPt)
Definition: wmfwr.cxx:287
std::size_t write_uInt8s_FromOString(SvStream &rStrm, const OString &rStr, std::size_t nUnits)
#define W_DEFAULT_PITCH
Definition: wmfwr.cxx:108
void WMFRecord_SetPixel(const Point &rPoint, const Color &rColor)
Definition: wmfwr.cxx:717
sal_uLong nActRecordPos
Definition: wmfwr.hxx:68
sal_uInt64 Tell() const
size_t GetActionSize() const
Definition: gdimtf.cxx:182
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
sal_Int32 GetNumerator() const
#define MAXOBJECTHANDLES
Definition: wmfwr.hxx:30
void WritePointXY(const Point &rPoint)
Definition: wmfwr.cxx:214
void CountActionsAndBitmaps(const GDIMetaFile &rMTF)
Definition: wmfwr.cxx:188
void AddHatchActions(const tools::PolyPolygon &rPolyPoly, const Hatch &rHatch, GDIMetaFile &rMtf)
const Point & GetOrigin() const
Definition: mapmod.cxx:170
MetaActionType GetType() const
Definition: metaact.hxx:90
#define W_META_ESCAPE
Definition: wmfwr.cxx:63
SvStream & WriteChar(char nChar)
#define W_TA_NOUPDATECP
Definition: wmfwr.cxx:83
css::uno::Reference< css::task::XStatusIndicator > GetStatusIndicator() const
vcl::Font aDstFont
Definition: wmfwr.hxx:91
const Hatch & GetHatch() const
Definition: metaact.hxx:1049
bool bHandleAllocated[MAXOBJECTHANDLES]
Definition: wmfwr.hxx:96
void WriteEmbeddedEMF(const GDIMetaFile &rMTF)
Definition: wmfwr.cxx:1821
void AdaptiveSubdivide(tools::Polygon &rResult, const double d=1.0) const
#define W_FW_NORMAL
Definition: wmfwr.cxx:122
FontLineStyle GetUnderline() const
Definition: font/font.cxx:710
void WMFRecord_Polygon(const tools::Polygon &rPoly)
Definition: wmfwr.cxx:619
#define W_FF_SCRIPT
Definition: wmfwr.cxx:116
void FreeHandle(sal_uInt16 nObjectHandle)
Definition: wmfwr.cxx:864
#define W_META_TEXTOUT
Definition: wmfwr.cxx:60
#define W_META_ARC
Definition: wmfwr.cxx:53
#define W_META_LINETO
Definition: wmfwr.cxx:50
css::uno::Reference< css::task::XStatusIndicator > xStatusIndicator
Definition: wmfwr.hxx:59
void WMFRecord_LineTo(const Point &rPoint)
Definition: wmfwr.cxx:599
sal_uInt16 AllocHandle()
Definition: wmfwr.cxx:850
#define W_PS_DASHDOTDOT
Definition: wmfwr.cxx:101
void TrueExtTextOut(const Point &rPoint, const OUString &rString, const OString &rByteString, const long *pDXAry)
Definition: wmfwr.cxx:563
Color aDstFillColor
Definition: wmfwr.hxx:86
long GetTextArray(const OUString &rStr, long *pDXAry, sal_Int32 nIndex=0, sal_Int32 nLen=-1, vcl::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
Definition: text.cxx:962
#define W_PS_DOT
Definition: wmfwr.cxx:99
STRIKEOUT_NONE
void CreateSelectDeleteFont(const vcl::Font &rFont)
Definition: wmfwr.cxx:883
bool WriteDIB(const Bitmap &rSource, SvStream &rOStm, bool bCompressed, bool bFileHeader)
Definition: dibtools.cxx:1857
bool IsStarSymbol(const OUString &rFontName)
bool Replace(const Bitmap &rMask, const Color &rReplaceColor)
Replace all pixel where the given mask is on with the specified color.
FontAlign eDstTextAlign
Definition: wmfwr.hxx:90
#define W_SRCINVERT
Definition: wmfwr.cxx:94
void WriteColor(const Color &rColor)
Definition: wmfwr.cxx:250
void WMFRecord_SetWindowExt(const Size &rSize)
Definition: wmfwr.cxx:759
const Color & GetColor() const
Definition: metaact.hxx:1248
const GDIMetaFile & GetSubstitute() const
Definition: metaact.hxx:1603
#define W_TRANSPARENT
Definition: wmfwr.cxx:76
void setWidth(long nWidth)
bool Crop(const tools::Rectangle &rRectPixel)
Crop the bitmap.
Definition: bitmapex.cxx:430
const tools::Rectangle & GetRect() const
Definition: metaact.hxx:603
#define W_META_RECTANGLE
Definition: wmfwr.cxx:56
sal_Int32 GetIndex() const
Definition: metaact.hxx:571
void CreateSelectDeleteBrush(const Color &rColor)
Definition: wmfwr.cxx:897
SvStream * pWMF
Definition: wmfwr.hxx:61
#define W_META_POLYGON
Definition: wmfwr.cxx:61
bool WMFRecord_Escape_Unicode(const Point &rPoint, const OUString &rStr, const long *pDXAry)
Definition: wmfwr.cxx:444
sal_Int32 GetIndex() const
Definition: metaact.hxx:496
#define W_FW_BOLD
Definition: wmfwr.cxx:125
rtl_TextEncoding GetCharSet() const
Definition: font/font.cxx:679
void WritePointYX(const Point &rPoint)
Definition: wmfwr.cxx:220
sal_uInt16 nPos
void WMFRecord_Pie(const tools::Rectangle &rRect, const Point &rStartPt, const Point &rEndPt)
Definition: wmfwr.cxx:611
#define W_META_PIE
Definition: wmfwr.cxx:55
sal_Int16 nValue
const void * GetData()
#define W_TA_LEFT
Definition: wmfwr.cxx:84
#define W_PS_DASHDOT
Definition: wmfwr.cxx:100
sal_uInt32 count() const
void WMFRecord_SaveDC()
Definition: wmfwr.cxx:693
#define W_FF_MODERN
Definition: wmfwr.cxx:115
void setHeight(long nHeight)