LibreOffice Module vcl (master)  1
svmconverter.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 <algorithm>
21 #include <string.h>
22 
23 #include <o3tl/safeint.hxx>
24 #include <osl/thread.h>
25 #include <tools/fract.hxx>
26 #include <tools/stream.hxx>
27 #include <vcl/dibtools.hxx>
28 #include <vcl/virdev.hxx>
29 #include <vcl/lineinfo.hxx>
30 #include <vcl/metaact.hxx>
31 #include <sal/log.hxx>
32 #include <osl/diagnose.h>
33 
34 #include <vcl/TypeSerializer.hxx>
35 #include <svmconverter.hxx>
36 #include <memory>
37 #include <stack>
38 
39 // Inlines
40 static void ImplReadRect( SvStream& rIStm, tools::Rectangle& rRect )
41 {
42  Point aTL;
43  Point aBR;
44 
45  TypeSerializer aSerializer(rIStm);
46  aSerializer.readPoint(aTL);
47  aSerializer.readPoint(aBR);
48 
49  rRect = tools::Rectangle( aTL, aBR );
50 }
51 
52 static bool ImplReadPoly(SvStream& rIStm, tools::Polygon& rPoly)
53 {
54  TypeSerializer aSerializer(rIStm);
55 
56  sal_Int32 nSize32(0);
57  rIStm.ReadInt32(nSize32);
58  sal_uInt16 nSize = nSize32;
59 
60  const size_t nMaxPossiblePoints = rIStm.remainingSize() / 2 * sizeof(sal_Int32);
61  if (nSize > nMaxPossiblePoints)
62  {
63  SAL_WARN("vcl.gdi", "svm record claims to have: " << nSize << " points, but only " << nMaxPossiblePoints << " possible");
64  return false;
65  }
66 
67  rPoly = tools::Polygon(nSize);
68 
69  for (sal_uInt16 i = 0; i < nSize && rIStm.good(); ++i)
70  {
71  aSerializer.readPoint(rPoly[i]);
72  }
73  return rIStm.good();
74 }
75 
76 static bool ImplReadPolyPoly(SvStream& rIStm, tools::PolyPolygon& rPolyPoly)
77 {
78  bool bSuccess = true;
79 
80  tools::Polygon aPoly;
81  sal_Int32 nPolyCount32(0);
82  rIStm.ReadInt32(nPolyCount32);
83  sal_uInt16 nPolyCount = static_cast<sal_uInt16>(nPolyCount32);
84 
85  for (sal_uInt16 i = 0; i < nPolyCount && rIStm.good(); ++i)
86  {
87  if (!ImplReadPoly(rIStm, aPoly))
88  {
89  bSuccess = false;
90  break;
91  }
92  rPolyPoly.Insert(aPoly);
93  }
94 
95  return bSuccess && rIStm.good();
96 }
97 
98 static void ImplReadColor( SvStream& rIStm, Color& rColor )
99 {
100  sal_Int16 nVal(0);
101 
102  rIStm.ReadInt16( nVal ); rColor.SetRed( sal::static_int_cast<sal_uInt8>(static_cast<sal_uInt16>(nVal) >> 8) );
103  rIStm.ReadInt16( nVal ); rColor.SetGreen( sal::static_int_cast<sal_uInt8>(static_cast<sal_uInt16>(nVal) >> 8) );
104  rIStm.ReadInt16( nVal ); rColor.SetBlue( sal::static_int_cast<sal_uInt8>(static_cast<sal_uInt16>(nVal) >> 8) );
105 }
106 
107 static bool ImplReadMapMode(SvStream& rIStm, MapMode& rMapMode)
108 {
109  sal_Int16 nUnit(0);
110  rIStm.ReadInt16(nUnit);
111 
112  Point aOrg;
113  TypeSerializer aSerializer(rIStm);
114  aSerializer.readPoint(aOrg);
115 
116  sal_Int32 nXNum(0), nXDenom(0), nYNum(0), nYDenom(0);
117  rIStm.ReadInt32(nXNum).ReadInt32(nXDenom).ReadInt32(nYNum).ReadInt32(nYDenom);
118 
119  if (!rIStm.good() || nXDenom <= 0 || nYDenom <= 0 || nXNum <= 0 || nYNum <= 0)
120  {
121  SAL_WARN("vcl.gdi", "Parsing error: invalid mapmode fraction");
122  return false;
123  }
124 
125  if (nUnit < sal_Int16(MapUnit::Map100thMM) || nUnit > sal_Int16(MapUnit::LAST))
126  {
127  SAL_WARN("vcl.gdi", "Parsing error: invalid mapmode");
128  return false;
129  }
130 
131  rMapMode = MapMode(static_cast<MapUnit>(nUnit), aOrg, Fraction(nXNum, nXDenom), Fraction(nYNum, nYDenom));
132 
133  return true;
134 }
135 
136 static void ImplReadUnicodeComment( sal_uInt32 nStrmPos, SvStream& rIStm, OUString& rString )
137 {
138  sal_uInt32 nOld = rIStm.Tell();
139  if ( nStrmPos )
140  {
141  sal_uInt16 nType;
142  sal_uInt32 nActionSize;
143  std::size_t nStringLen;
144 
145  rIStm.Seek( nStrmPos );
146  rIStm .ReadUInt16( nType )
147  .ReadUInt32( nActionSize );
148 
149  nStringLen = (nActionSize - 4) >> 1;
150 
151  if ( nStringLen && ( nType == GDI_UNICODE_COMMENT ) )
152  rString = read_uInt16s_ToOUString(rIStm, nStringLen);
153  }
154  rIStm.Seek( nOld );
155 }
156 
157 static void ImplSkipActions(SvStream& rIStm, sal_uLong nSkipCount)
158 {
159  sal_Int32 nActionSize;
160  sal_Int16 nType;
161  for (sal_uLong i = 0; i < nSkipCount; ++i)
162  {
163  rIStm.ReadInt16(nType).ReadInt32(nActionSize);
164  if (!rIStm.good() || nActionSize < 4)
165  break;
166  rIStm.SeekRel(nActionSize - 4);
167  }
168 }
169 
171 {
172  TypeSerializer aSerializer(rIStm);
173 
174  rPolyPoly.Clear();
175  sal_uInt16 nPolygonCount(0);
176  rIStm.ReadUInt16( nPolygonCount );
177 
178  if (!nPolygonCount)
179  return;
180 
181  const size_t nMinRecordSize = sizeof(sal_uInt16);
182  const size_t nMaxRecords = rIStm.remainingSize() / nMinRecordSize;
183  if (nPolygonCount > nMaxRecords)
184  {
185  SAL_WARN("vcl.gdi", "Parsing error: " << nMaxRecords <<
186  " max possible entries, but " << nPolygonCount << " claimed, truncating");
187  nPolygonCount = nMaxRecords;
188  }
189 
190  for(sal_uInt16 a(0); a < nPolygonCount; a++)
191  {
192  sal_uInt16 nPointCount(0);
193  rIStm.ReadUInt16(nPointCount);
194 
195  const size_t nMinPolygonSize = sizeof(sal_Int32) * 2;
196  const size_t nMaxPolygons = rIStm.remainingSize() / nMinPolygonSize;
197  if (nPointCount > nMaxPolygons)
198  {
199  SAL_WARN("vcl.gdi", "Parsing error: " << nMaxPolygons <<
200  " max possible entries, but " << nPointCount << " claimed, truncating");
201  nPointCount = nMaxPolygons;
202  }
203 
204  tools::Polygon aCandidate(nPointCount);
205 
206  if (nPointCount)
207  {
208  for(sal_uInt16 b(0); b < nPointCount; b++)
209  {
210  aSerializer.readPoint(aCandidate[b]);
211  }
212 
213  sal_uInt8 bHasFlags(int(false));
214  rIStm.ReadUChar( bHasFlags );
215 
216  if(bHasFlags)
217  {
218  sal_uInt8 aPolyFlags(0);
219 
220  for(sal_uInt16 c(0); c < nPointCount; c++)
221  {
222  rIStm.ReadUChar( aPolyFlags );
223  aCandidate.SetFlags(c, static_cast<PolyFlags>(aPolyFlags));
224  }
225  }
226  }
227 
228  rPolyPoly.Insert(aCandidate);
229  }
230 }
231 
233 {
234  if( !rStm.GetError() )
235  {
236  ImplConvertFromSVM1( rStm, rMtf );
237  }
238 }
239 
240 namespace
241 {
242  sal_Int32 SkipActions(sal_Int32 i, sal_Int32 nFollowingActionCount, sal_Int32 nActions)
243  {
244  sal_Int32 remainingActions = nActions - i;
245  if (nFollowingActionCount < 0)
246  nFollowingActionCount = remainingActions;
247  return std::min(remainingActions, nFollowingActionCount);
248  }
249 }
250 
251 #define LF_FACESIZE 32
252 
253 void static lcl_error( SvStream& rIStm, const SvStreamEndian& nOldFormat, sal_uLong nPos)
254 {
256  rIStm.SetEndian(nOldFormat);
257  rIStm.Seek(nPos);
258  return;
259 }
261 {
262  const sal_uLong nPos = rIStm.Tell();
263  const SvStreamEndian nOldFormat = rIStm.GetEndian();
264 
265  rIStm.SetEndian( SvStreamEndian::LITTLE );
266 
267  char aCode[ 5 ];
268  Size aPrefSz;
269 
270  // read header
271  rIStm.ReadBytes(aCode, sizeof(aCode)); // Identifier
272  sal_Int16 nSize(0);
273  rIStm.ReadInt16( nSize ); // Size
274  sal_Int16 nVersion(0);
275  rIStm.ReadInt16( nVersion ); // Version
276  sal_Int32 nTmp32(0);
277  rIStm.ReadInt32( nTmp32 );
278  if (nTmp32 < 0)
279  {
280  SAL_WARN("vcl.gdi", "svm: value for width should be positive");
281  lcl_error(rIStm, nOldFormat, nPos);
282  return;
283  }
284  aPrefSz.setWidth( nTmp32 ); // PrefSize.Width()
285  rIStm.ReadInt32( nTmp32 );
286  if (nTmp32 < 0)
287  {
288  SAL_WARN("vcl.gdi", "svm: value for height should be positive");
289  lcl_error(rIStm, nOldFormat, nPos);
290  return;
291  }
292  aPrefSz.setHeight( nTmp32 ); // PrefSize.Height()
293 
294  // check header-magic and version
295  if( rIStm.GetError()
296  || ( memcmp( aCode, "SVGDI", sizeof( aCode ) ) != 0 )
297  || ( nVersion != 200 ) )
298  {
299  SAL_WARN("vcl.gdi", "svm: wrong check for header-magic and version");
300  lcl_error(rIStm, nOldFormat, nPos);
301  return;
302  }
303 
304  LineInfo aLineInfo( LineStyle::NONE, 0 );
305  std::stack<std::unique_ptr<LineInfo>> aLIStack;
307  rtl_TextEncoding eActualCharSet = osl_getThreadTextEncoding();
308  bool bFatLine = false;
309 
310  tools::Polygon aActionPoly;
311  tools::Rectangle aRect;
312  Point aPt, aPt1;
313  Size aSz;
314  Color aActionColor;
315 
316  sal_uInt32 nUnicodeCommentStreamPos = 0;
317  sal_Int32 nUnicodeCommentActionNumber = 0;
318 
319  rMtf.SetPrefSize(aPrefSz);
320 
321  MapMode aMapMode;
322  if (ImplReadMapMode(rIStm, aMapMode)) // MapMode
323  rMtf.SetPrefMapMode(aMapMode);
324 
325  sal_Int32 nActions(0);
326  rIStm.ReadInt32(nActions); // Action count
327  if (nActions < 0)
328  {
329  SAL_WARN("vcl.gdi", "svm claims negative action count (" << nActions << ")");
330  nActions = 0;
331  }
332 
333  const size_t nMinActionSize = sizeof(sal_uInt16) + sizeof(sal_Int32);
334  const size_t nMaxPossibleActions = rIStm.remainingSize() / nMinActionSize;
335  if (o3tl::make_unsigned(nActions) > nMaxPossibleActions)
336  {
337  SAL_WARN("vcl.gdi", "svm claims more actions (" << nActions << ") than stream could provide, truncating");
338  nActions = nMaxPossibleActions;
339  }
340 
341  size_t nLastPolygonAction(0);
342 
343  TypeSerializer aSerializer(rIStm);
344 
345  for (sal_Int32 i = 0; i < nActions && rIStm.good(); ++i)
346  {
347  sal_Int16 nType(0);
348  rIStm.ReadInt16(nType);
349  sal_Int32 nActBegin = rIStm.Tell();
350  sal_Int32 nActionSize(0);
351  rIStm.ReadInt32(nActionSize);
352 
353  SAL_WARN_IF( ( nType > 33 ) && ( nType < 1024 ), "vcl.gdi", "Unknown GDIMetaAction while converting!" );
354 
355  switch( nType )
356  {
357  case GDI_PIXEL_ACTION:
358  {
359  aSerializer.readPoint(aPt);
360  ImplReadColor( rIStm, aActionColor );
361  rMtf.AddAction( new MetaPixelAction( aPt, aActionColor ) );
362  }
363  break;
364 
365  case GDI_POINT_ACTION:
366  {
367  aSerializer.readPoint(aPt);
368  rMtf.AddAction( new MetaPointAction( aPt ) );
369  }
370  break;
371 
372  case GDI_LINE_ACTION:
373  {
374  aSerializer.readPoint(aPt);
375  aSerializer.readPoint(aPt1);
376  rMtf.AddAction( new MetaLineAction( aPt, aPt1, aLineInfo ) );
377  }
378  break;
379 
380  case GDI_LINEJOIN_ACTION :
381  {
382  sal_Int16 nLineJoin(0);
383  rIStm.ReadInt16( nLineJoin );
384  aLineInfo.SetLineJoin(static_cast<basegfx::B2DLineJoin>(nLineJoin));
385  }
386  break;
387 
388  case GDI_LINECAP_ACTION :
389  {
390  sal_Int16 nLineCap(0);
391  rIStm.ReadInt16( nLineCap );
392  aLineInfo.SetLineCap(static_cast<css::drawing::LineCap>(nLineCap));
393  }
394  break;
395 
397  {
398  sal_Int16 a(0);
399  sal_Int32 b(0);
400 
401  rIStm.ReadInt16( a ); aLineInfo.SetDashCount(a);
402  rIStm.ReadInt32( b ); aLineInfo.SetDashLen(b);
403  rIStm.ReadInt16( a ); aLineInfo.SetDotCount(a);
404  rIStm.ReadInt32( b ); aLineInfo.SetDotLen(b);
405  rIStm.ReadInt32( b ); aLineInfo.SetDistance(b);
406 
407  if(((aLineInfo.GetDashCount() && aLineInfo.GetDashLen())
408  || (aLineInfo.GetDotCount() && aLineInfo.GetDotLen()))
409  && aLineInfo.GetDistance())
410  {
411  aLineInfo.SetStyle(LineStyle::Dash);
412  }
413  }
414  break;
415 
417  {
418  // read the tools::PolyPolygon in every case
419  tools::PolyPolygon aInputPolyPolygon;
420  ImplReadExtendedPolyPolygonAction(rIStm, aInputPolyPolygon);
421 
422  // now check if it can be set somewhere
423  if(nLastPolygonAction < rMtf.GetActionSize())
424  {
425  MetaPolyLineAction* pPolyLineAction = dynamic_cast< MetaPolyLineAction* >(rMtf.GetAction(nLastPolygonAction));
426 
427  if(pPolyLineAction)
428  {
429  // replace MetaPolyLineAction when we have a single polygon. Do not rely on the
430  // same point count; the originally written GDI_POLYLINE_ACTION may have been
431  // Subdivided for better quality for older usages
432  if(1 == aInputPolyPolygon.Count())
433  {
434  rMtf.ReplaceAction(
435  new MetaPolyLineAction(
436  aInputPolyPolygon.GetObject(0),
437  pPolyLineAction->GetLineInfo()),
438  nLastPolygonAction);
439  }
440  }
441  else
442  {
443  MetaPolyPolygonAction* pPolyPolygonAction = dynamic_cast< MetaPolyPolygonAction* >(rMtf.GetAction(nLastPolygonAction));
444 
445  if(pPolyPolygonAction)
446  {
447  // replace MetaPolyPolygonAction when we have a curved polygon. Do rely on the
448  // same sub-polygon count
449  if(pPolyPolygonAction->GetPolyPolygon().Count() == aInputPolyPolygon.Count())
450  {
451  rMtf.ReplaceAction(
452  new MetaPolyPolygonAction(
453  aInputPolyPolygon),
454  nLastPolygonAction);
455  }
456  }
457  else
458  {
459  MetaPolygonAction* pPolygonAction = dynamic_cast< MetaPolygonAction* >(rMtf.GetAction(nLastPolygonAction));
460 
461  if(pPolygonAction)
462  {
463  // replace MetaPolygonAction
464  if(1 == aInputPolyPolygon.Count())
465  {
466  rMtf.ReplaceAction(
467  new MetaPolygonAction(
468  aInputPolyPolygon.GetObject(0)),
469  nLastPolygonAction);
470  }
471  }
472  }
473  }
474  }
475  }
476  break;
477 
478  case GDI_RECT_ACTION:
479  {
480  ImplReadRect( rIStm, aRect );
481  sal_Int32 nTmp(0), nTmp1(0);
482  rIStm.ReadInt32( nTmp ).ReadInt32( nTmp1 );
483 
484  if( nTmp || nTmp1 )
485  rMtf.AddAction( new MetaRoundRectAction( aRect, nTmp, nTmp1 ) );
486  else
487  {
488  rMtf.AddAction( new MetaRectAction( aRect ) );
489 
490  if( bFatLine )
491  rMtf.AddAction( new MetaPolyLineAction( aRect, aLineInfo ) );
492  }
493  }
494  break;
495 
496  case GDI_ELLIPSE_ACTION:
497  {
498  ImplReadRect( rIStm, aRect );
499 
500  if( bFatLine )
501  {
502  const tools::Polygon aPoly( aRect.Center(), aRect.GetWidth() >> 1, aRect.GetHeight() >> 1 );
503 
504  rMtf.AddAction( new MetaPushAction( PushFlags::LINECOLOR ) );
505  rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, false ) );
506  rMtf.AddAction( new MetaPolygonAction( aPoly ) );
507  rMtf.AddAction( new MetaPopAction() );
508  rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
509  }
510  else
511  rMtf.AddAction( new MetaEllipseAction( aRect ) );
512  }
513  break;
514 
515  case GDI_ARC_ACTION:
516  {
517  ImplReadRect( rIStm, aRect );
518  aSerializer.readPoint(aPt);
519  aSerializer.readPoint(aPt1);
520 
521  if( bFatLine )
522  {
523  const tools::Polygon aPoly( aRect, aPt, aPt1, PolyStyle::Arc );
524 
525  rMtf.AddAction( new MetaPushAction( PushFlags::LINECOLOR ) );
526  rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, false ) );
527  rMtf.AddAction( new MetaPolygonAction( aPoly ) );
528  rMtf.AddAction( new MetaPopAction() );
529  rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
530  }
531  else
532  rMtf.AddAction( new MetaArcAction( aRect, aPt, aPt1 ) );
533  }
534  break;
535 
536  case GDI_PIE_ACTION:
537  {
538  ImplReadRect( rIStm, aRect );
539  aSerializer.readPoint(aPt);
540  aSerializer.readPoint(aPt1);
541 
542  if( bFatLine )
543  {
544  const tools::Polygon aPoly( aRect, aPt, aPt1, PolyStyle::Pie );
545 
546  rMtf.AddAction( new MetaPushAction( PushFlags::LINECOLOR ) );
547  rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, false ) );
548  rMtf.AddAction( new MetaPolygonAction( aPoly ) );
549  rMtf.AddAction( new MetaPopAction() );
550  rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
551  }
552  else
553  rMtf.AddAction( new MetaPieAction( aRect, aPt, aPt1 ) );
554  }
555  break;
556 
559  {
560  ImplReadRect( rIStm, aRect );
561  rMtf.AddAction( new MetaPushAction( PushFlags::RASTEROP ) );
562  rMtf.AddAction( new MetaRasterOpAction( RasterOp::Invert ) );
563  rMtf.AddAction( new MetaRectAction( aRect ) );
564  rMtf.AddAction( new MetaPopAction() );
565  }
566  break;
567 
568  case GDI_POLYLINE_ACTION:
569  {
570  if (ImplReadPoly(rIStm, aActionPoly))
571  {
572  nLastPolygonAction = rMtf.GetActionSize();
573 
574  if( bFatLine )
575  rMtf.AddAction( new MetaPolyLineAction( aActionPoly, aLineInfo ) );
576  else
577  rMtf.AddAction( new MetaPolyLineAction( aActionPoly ) );
578  }
579  }
580  break;
581 
582  case GDI_POLYGON_ACTION:
583  {
584  if (ImplReadPoly(rIStm, aActionPoly))
585  {
586  if( bFatLine )
587  {
588  rMtf.AddAction( new MetaPushAction( PushFlags::LINECOLOR ) );
589  rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, false ) );
590  rMtf.AddAction( new MetaPolygonAction( aActionPoly ) );
591  rMtf.AddAction( new MetaPopAction() );
592  rMtf.AddAction( new MetaPolyLineAction( aActionPoly, aLineInfo ) );
593  }
594  else
595  {
596  nLastPolygonAction = rMtf.GetActionSize();
597  rMtf.AddAction( new MetaPolygonAction( aActionPoly ) );
598  }
599  }
600  }
601  break;
602 
604  {
605  tools::PolyPolygon aPolyPoly;
606 
607  if (ImplReadPolyPoly(rIStm, aPolyPoly))
608  {
609  if( bFatLine )
610  {
611  rMtf.AddAction( new MetaPushAction( PushFlags::LINECOLOR ) );
612  rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, false ) );
613  rMtf.AddAction( new MetaPolyPolygonAction( aPolyPoly ) );
614  rMtf.AddAction( new MetaPopAction() );
615 
616  for( sal_uInt16 nPoly = 0, nCount = aPolyPoly.Count(); nPoly < nCount; nPoly++ )
617  rMtf.AddAction( new MetaPolyLineAction( aPolyPoly[ nPoly ], aLineInfo ) );
618  }
619  else
620  {
621  nLastPolygonAction = rMtf.GetActionSize();
622  rMtf.AddAction( new MetaPolyPolygonAction( aPolyPoly ) );
623  }
624  }
625  }
626  break;
627 
628  case GDI_FONT_ACTION:
629  {
630  vcl::Font aFont;
631  char aName[LF_FACESIZE+1];
632 
633  ImplReadColor( rIStm, aActionColor ); aFont.SetColor( aActionColor );
634  ImplReadColor( rIStm, aActionColor ); aFont.SetFillColor( aActionColor );
635  size_t nRet = rIStm.ReadBytes(aName, LF_FACESIZE);
636  aName[nRet] = 0;
637  aFont.SetFamilyName( OUString( aName, strlen(aName), rIStm.GetStreamCharSet() ) );
638 
639  sal_Int32 nWidth(0), nHeight(0);
640  rIStm.ReadInt32(nWidth).ReadInt32(nHeight);
641  sal_Int16 nCharOrient(0), nLineOrient(0);
642  rIStm.ReadInt16(nCharOrient).ReadInt16(nLineOrient);
643  sal_Int16 nCharSet(0), nFamily(0), nPitch(0), nAlign(0), nWeight(0), nUnderline(0), nStrikeout(0);
644  rIStm.ReadInt16(nCharSet).ReadInt16(nFamily).ReadInt16(nPitch).ReadInt16(nAlign).ReadInt16(nWeight).ReadInt16(nUnderline).ReadInt16(nStrikeout);
645  bool bItalic(false), bOutline(false), bShadow(false), bTransparent(false);
646  rIStm.ReadCharAsBool(bItalic).ReadCharAsBool(bOutline).ReadCharAsBool(bShadow).ReadCharAsBool(bTransparent);
647 
648  aFont.SetFontSize( Size( nWidth, nHeight ) );
649  aFont.SetCharSet( static_cast<rtl_TextEncoding>(nCharSet) );
650  aFont.SetFamily( static_cast<FontFamily>(nFamily) );
651  aFont.SetPitch( static_cast<FontPitch>(nPitch) );
652  aFont.SetAlignment( static_cast<FontAlign>(nAlign) );
653  aFont.SetWeight( ( nWeight == 1 ) ? WEIGHT_LIGHT : ( nWeight == 2 ) ? WEIGHT_NORMAL :
654  ( nWeight == 3 ) ? WEIGHT_BOLD : WEIGHT_DONTKNOW );
655  aFont.SetUnderline( static_cast<FontLineStyle>(nUnderline) );
656  aFont.SetStrikeout( static_cast<FontStrikeout>(nStrikeout) );
657  aFont.SetItalic( bItalic ? ITALIC_NORMAL : ITALIC_NONE );
658  aFont.SetOutline( bOutline );
659  aFont.SetShadow( bShadow );
660  aFont.SetOrientation( Degree10(nLineOrient) );
661  aFont.SetTransparent( bTransparent );
662 
663  eActualCharSet = aFont.GetCharSet();
664  if ( eActualCharSet == RTL_TEXTENCODING_DONTKNOW )
665  eActualCharSet = osl_getThreadTextEncoding();
666 
667  rMtf.AddAction( new MetaFontAction( aFont ) );
668  rMtf.AddAction( new MetaTextAlignAction( aFont.GetAlignment() ) );
669  rMtf.AddAction( new MetaTextColorAction( aFont.GetColor() ) );
670  rMtf.AddAction( new MetaTextFillColorAction( aFont.GetFillColor(), !aFont.IsTransparent() ) );
671 
672  // #106172# Track font relevant data in shadow VDev
673  aFontVDev->SetFont( aFont );
674  }
675  break;
676 
677  case GDI_TEXT_ACTION:
678  {
679  sal_Int32 nIndex(0), nLen(0), nTmp(0);
680  aSerializer.readPoint(aPt);
681  rIStm.ReadInt32( nIndex ).ReadInt32( nLen ).ReadInt32( nTmp );
682  if (nTmp > 0)
683  {
684  OString aByteStr = read_uInt8s_ToOString(rIStm, nTmp);
685  sal_uInt8 nTerminator = 0;
686  rIStm.ReadUChar( nTerminator );
687  SAL_WARN_IF( nTerminator != 0, "vcl.gdi", "expected string to be NULL terminated" );
688 
689  OUString aStr(OStringToOUString(aByteStr, eActualCharSet));
690  if ( nUnicodeCommentActionNumber == i )
691  ImplReadUnicodeComment( nUnicodeCommentStreamPos, rIStm, aStr );
692  rMtf.AddAction( new MetaTextAction( aPt, aStr, nIndex, nLen ) );
693  }
694 
695  if (nActionSize < 24)
697  else
698  rIStm.Seek(nActBegin + nActionSize);
699  }
700  break;
701 
703  {
704  sal_Int32 nIndex(0), nLen(0), nAryLen(0), nTmp(0);
705  aSerializer.readPoint(aPt);
706  rIStm.ReadInt32( nIndex ).ReadInt32( nLen ).ReadInt32( nTmp ).ReadInt32( nAryLen );
707  if (nTmp > 0)
708  {
709  OString aByteStr = read_uInt8s_ToOString(rIStm, nTmp);
710  sal_uInt8 nTerminator = 0;
711  rIStm.ReadUChar( nTerminator );
712  SAL_WARN_IF( nTerminator != 0, "vcl.gdi", "expected string to be NULL terminated" );
713 
714  OUString aStr(OStringToOUString(aByteStr, eActualCharSet));
715 
716  std::unique_ptr<tools::Long[]> pDXAry;
717  if (nAryLen > 0)
718  {
719  const size_t nMinRecordSize = sizeof(sal_Int32);
720  const size_t nMaxRecords = rIStm.remainingSize() / nMinRecordSize;
721  if (o3tl::make_unsigned(nAryLen) > nMaxRecords)
722  {
723  SAL_WARN("vcl.gdi", "Parsing error: " << nMaxRecords <<
724  " max possible entries, but " << nAryLen << " claimed, truncating");
725  nAryLen = nMaxRecords;
726  }
727 
728  sal_Int32 nStrLen( aStr.getLength() );
729 
730  sal_Int32 nDXAryLen = std::max(nAryLen, nStrLen);
731 
732  if (nDXAryLen < nLen)
733  {
734  //MetaTextArrayAction ctor expects pDXAry to be >= nLen if set, so if this can't
735  //be achieved, don't read it, it's utterly broken.
736  SAL_WARN("vcl.gdi", "dxary too short, discarding completely");
737  rIStm.SeekRel(sizeof(sal_Int32) * nDXAryLen);
738  nLen = 0;
739  nIndex = 0;
740  }
741  else
742  {
743  pDXAry.reset(new tools::Long[nDXAryLen]);
744 
745  for (sal_Int32 j = 0; j < nAryLen; ++j)
746  {
747  rIStm.ReadInt32( nTmp );
748  pDXAry[ j ] = nTmp;
749  }
750 
751  // #106172# Add last DX array elem, if missing
752  if( nAryLen != nStrLen )
753  {
754  if (nAryLen+1 == nStrLen && nIndex >= 0)
755  {
756  std::unique_ptr<tools::Long[]> pTmpAry(new tools::Long[nStrLen]);
757 
758  aFontVDev->GetTextArray( aStr, pTmpAry.get(), nIndex, nLen );
759 
760  // now, the difference between the
761  // last and the second last DX array
762  // is the advancement for the last
763  // glyph. Thus, to complete our meta
764  // action's DX array, just add that
765  // difference to last elem and store
766  // in very last.
767  if( nStrLen > 1 )
768  pDXAry[ nStrLen-1 ] = pDXAry[ nStrLen-2 ] + pTmpAry[ nStrLen-1 ] - pTmpAry[ nStrLen-2 ];
769  else
770  pDXAry[ nStrLen-1 ] = pTmpAry[ nStrLen-1 ]; // len=1: 0th position taken to be 0
771  }
772 #ifdef DBG_UTIL
773  else
774  OSL_FAIL("More than one DX array element missing on SVM import");
775 #endif
776  }
777  }
778  }
779  if ( nUnicodeCommentActionNumber == i )
780  ImplReadUnicodeComment( nUnicodeCommentStreamPos, rIStm, aStr );
781  rMtf.AddAction( new MetaTextArrayAction( aPt, aStr, pDXAry.get(), nIndex, nLen ) );
782  }
783 
784  if (nActionSize < 24)
786  else
787  rIStm.Seek(nActBegin + nActionSize);
788  }
789  break;
790 
792  {
793  sal_Int32 nIndex(0), nLen(0), nWidth(0), nTmp(0);
794 
795  aSerializer.readPoint(aPt);
796  rIStm.ReadInt32( nIndex ).ReadInt32( nLen ).ReadInt32( nTmp ).ReadInt32( nWidth );
797  if (nTmp > 0)
798  {
799  OString aByteStr = read_uInt8s_ToOString(rIStm, nTmp);
800  sal_uInt8 nTerminator = 0;
801  rIStm.ReadUChar( nTerminator );
802  SAL_WARN_IF( nTerminator != 0, "vcl.gdi", "expected string to be NULL terminated" );
803 
804  OUString aStr(OStringToOUString(aByteStr, eActualCharSet));
805  if ( nUnicodeCommentActionNumber == i )
806  ImplReadUnicodeComment( nUnicodeCommentStreamPos, rIStm, aStr );
807  rMtf.AddAction( new MetaStretchTextAction( aPt, nWidth, aStr, nIndex, nLen ) );
808  }
809 
810  if (nActionSize < 28)
812  else
813  rIStm.Seek(nActBegin + nActionSize);
814  }
815  break;
816 
817  case GDI_BITMAP_ACTION:
818  {
819  Bitmap aBmp;
820 
821  aSerializer.readPoint(aPt);
822  ReadDIB(aBmp, rIStm, true);
823  rMtf.AddAction( new MetaBmpAction( aPt, aBmp ) );
824  }
825  break;
826 
828  {
829  Bitmap aBmp;
830 
831  aSerializer.readPoint(aPt);
832  aSerializer.readSize(aSz);
833  ReadDIB(aBmp, rIStm, true);
834  rMtf.AddAction( new MetaBmpScaleAction( aPt, aSz, aBmp ) );
835  }
836  break;
837 
839  {
840  Bitmap aBmp;
841  Size aSz2;
842 
843  aSerializer.readPoint(aPt);
844  aSerializer.readSize(aSz);
845  aSerializer.readPoint(aPt1);
846  aSerializer.readSize(aSz2);
847  ReadDIB(aBmp, rIStm, true);
848  rMtf.AddAction( new MetaBmpScalePartAction( aPt, aSz, aPt1, aSz2, aBmp ) );
849  }
850  break;
851 
852  case GDI_PEN_ACTION:
853  {
854  sal_Int32 nPenWidth;
855  sal_Int16 nPenStyle;
856 
857  ImplReadColor( rIStm, aActionColor );
858  rIStm.ReadInt32( nPenWidth ).ReadInt16( nPenStyle );
859 
860  aLineInfo.SetStyle( nPenStyle ? LineStyle::Solid : LineStyle::NONE );
861  aLineInfo.SetWidth( nPenWidth );
862  bFatLine = nPenStyle && !aLineInfo.IsDefault();
863 
864  rMtf.AddAction( new MetaLineColorAction( aActionColor, nPenStyle != 0 ) );
865  }
866  break;
867 
869  {
870  sal_Int16 nBrushStyle;
871 
872  ImplReadColor( rIStm, aActionColor );
873  rIStm.SeekRel( 6 );
874  rIStm.ReadInt16( nBrushStyle );
875  rMtf.AddAction( new MetaFillColorAction( aActionColor, nBrushStyle != 0 ) );
876  rIStm.SeekRel( 2 );
877  }
878  break;
879 
880  case GDI_MAPMODE_ACTION:
881  {
882  if (ImplReadMapMode(rIStm, aMapMode))
883  {
884  rMtf.AddAction(new MetaMapModeAction(aMapMode));
885 
886  // #106172# Track font relevant data in shadow VDev
887  aFontVDev->SetMapMode(aMapMode);
888  };
889  }
890  break;
891 
893  {
894  vcl::Region aRegion;
895  sal_Int16 nRegType;
896  sal_Int16 bIntersect;
897  bool bClip = false;
898 
899  rIStm.ReadInt16( nRegType ).ReadInt16( bIntersect );
900  ImplReadRect( rIStm, aRect );
901 
902  switch( nRegType )
903  {
904  case 0:
905  break;
906 
907  case 1:
908  {
909  tools::Rectangle aRegRect;
910 
911  ImplReadRect( rIStm, aRegRect );
912  aRegion = vcl::Region( aRegRect );
913  bClip = true;
914  }
915  break;
916 
917  case 2:
918  {
919  if (ImplReadPoly(rIStm, aActionPoly))
920  {
921  aRegion = vcl::Region( aActionPoly );
922  bClip = true;
923  }
924  }
925  break;
926 
927  case 3:
928  {
929  bool bSuccess = true;
930  tools::PolyPolygon aPolyPoly;
931  sal_Int32 nPolyCount32(0);
932  rIStm.ReadInt32(nPolyCount32);
933  sal_uInt16 nPolyCount(nPolyCount32);
934 
935  for (sal_uInt16 j = 0; j < nPolyCount && rIStm.good(); ++j)
936  {
937  if (!ImplReadPoly(rIStm, aActionPoly))
938  {
939  bSuccess = false;
940  break;
941  }
942  aPolyPoly.Insert(aActionPoly);
943  }
944 
945  if (bSuccess)
946  {
947  aRegion = vcl::Region( aPolyPoly );
948  bClip = true;
949  }
950  }
951  break;
952  }
953 
954  if( bIntersect )
955  aRegion.Intersect( aRect );
956 
957  rMtf.AddAction( new MetaClipRegionAction( aRegion, bClip ) );
958  }
959  break;
960 
962  {
963  sal_Int32 nTmp(0), nTmp1(0);
964  rIStm.ReadInt32( nTmp ).ReadInt32( nTmp1 );
965  rMtf.AddAction( new MetaMoveClipRegionAction( nTmp, nTmp1 ) );
966  }
967  break;
968 
970  {
971  ImplReadRect( rIStm, aRect );
972  rMtf.AddAction( new MetaISectRectClipRegionAction( aRect ) );
973  }
974  break;
975 
976  case GDI_RASTEROP_ACTION:
977  {
978  RasterOp eRasterOp;
979  sal_Int16 nRasterOp;
980 
981  rIStm.ReadInt16( nRasterOp );
982 
983  switch( nRasterOp )
984  {
985  case 1:
986  eRasterOp = RasterOp::Invert;
987  break;
988 
989  case 4:
990  case 5:
991  eRasterOp = RasterOp::Xor;
992  break;
993 
994  default:
995  eRasterOp = RasterOp::OverPaint;
996  break;
997  }
998 
999  rMtf.AddAction( new MetaRasterOpAction( eRasterOp ) );
1000  }
1001  break;
1002 
1003  case GDI_PUSH_ACTION:
1004  {
1005  aLIStack.push(std::make_unique<LineInfo>(aLineInfo));
1006  rMtf.AddAction( new MetaPushAction( PushFlags::ALL ) );
1007 
1008  // #106172# Track font relevant data in shadow VDev
1009  aFontVDev->Push();
1010  }
1011  break;
1012 
1013  case GDI_POP_ACTION:
1014  {
1015 
1016  std::unique_ptr<LineInfo> xLineInfo;
1017  if (!aLIStack.empty())
1018  {
1019  xLineInfo = std::move(aLIStack.top());
1020  aLIStack.pop();
1021  }
1022 
1023  // restore line info
1024  if (xLineInfo)
1025  {
1026  aLineInfo = *xLineInfo;
1027  xLineInfo.reset();
1028  bFatLine = ( LineStyle::NONE != aLineInfo.GetStyle() ) && !aLineInfo.IsDefault();
1029  }
1030 
1031  rMtf.AddAction( new MetaPopAction() );
1032 
1033  // #106172# Track font relevant data in shadow VDev
1034  aFontVDev->Pop();
1035  }
1036  break;
1037 
1038  case GDI_GRADIENT_ACTION:
1039  {
1040  Color aStartCol;
1041  Color aEndCol;
1042  sal_Int16 nStyle;
1043  sal_Int16 nAngle;
1044  sal_Int16 nBorder;
1045  sal_Int16 nOfsX;
1046  sal_Int16 nOfsY;
1047  sal_Int16 nIntensityStart;
1048  sal_Int16 nIntensityEnd;
1049 
1050  ImplReadRect( rIStm, aRect );
1051  rIStm.ReadInt16( nStyle );
1052  ImplReadColor( rIStm, aStartCol );
1053  ImplReadColor( rIStm, aEndCol );
1054  rIStm.ReadInt16( nAngle ).ReadInt16( nBorder ).ReadInt16( nOfsX ).ReadInt16( nOfsY ).ReadInt16( nIntensityStart ).ReadInt16( nIntensityEnd );
1055 
1056  Gradient aGrad( static_cast<GradientStyle>(nStyle), aStartCol, aEndCol );
1057 
1058  aGrad.SetAngle( Degree10(nAngle) );
1059  aGrad.SetBorder( nBorder );
1060  aGrad.SetOfsX( nOfsX );
1061  aGrad.SetOfsY( nOfsY );
1062  aGrad.SetStartIntensity( nIntensityStart );
1063  aGrad.SetEndIntensity( nIntensityEnd );
1064  rMtf.AddAction( new MetaGradientAction( aRect, aGrad ) );
1065  }
1066  break;
1067 
1069  {
1070  tools::PolyPolygon aPolyPoly;
1071  sal_Int32 nFollowingActionCount(0);
1072  sal_Int16 nTrans(0);
1073 
1074  ReadPolyPolygon( rIStm, aPolyPoly );
1075  rIStm.ReadInt16( nTrans ).ReadInt32( nFollowingActionCount );
1076  ImplSkipActions( rIStm, nFollowingActionCount );
1077  rMtf.AddAction( new MetaTransparentAction( aPolyPoly, nTrans ) );
1078 
1079  i = SkipActions(i, nFollowingActionCount, nActions);
1080  }
1081  break;
1082 
1084  {
1085  GDIMetaFile aMtf;
1086  Point aPos;
1087  Size aSize;
1088  Gradient aGradient;
1089  sal_Int32 nFollowingActionCount(0);
1090 
1091  ReadGDIMetaFile( rIStm, aMtf );
1092  aSerializer.readPoint(aPos);
1093  aSerializer.readSize(aSize);
1094  aSerializer.readGradient(aGradient);
1095  rIStm.ReadInt32( nFollowingActionCount );
1096  ImplSkipActions( rIStm, nFollowingActionCount );
1097  rMtf.AddAction( new MetaFloatTransparentAction( aMtf, aPos, aSize, aGradient ) );
1098 
1099  i = SkipActions(i, nFollowingActionCount, nActions);
1100  }
1101  break;
1102 
1103  case GDI_HATCH_COMMENT:
1104  {
1105  tools::PolyPolygon aPolyPoly;
1106  Hatch aHatch;
1107  sal_Int32 nFollowingActionCount(0);
1108 
1109  ReadPolyPolygon( rIStm, aPolyPoly );
1110  ReadHatch( rIStm, aHatch );
1111  rIStm.ReadInt32( nFollowingActionCount );
1112  ImplSkipActions( rIStm, nFollowingActionCount );
1113  rMtf.AddAction( new MetaHatchAction( aPolyPoly, aHatch ) );
1114 
1115  i = SkipActions(i, nFollowingActionCount, nActions);
1116  }
1117  break;
1118 
1119  case GDI_REFPOINT_COMMENT:
1120  {
1121  Point aRefPoint;
1122  bool bSet;
1123  sal_Int32 nFollowingActionCount(0);
1124 
1125  aSerializer.readPoint(aRefPoint);
1126  rIStm.ReadCharAsBool( bSet ).ReadInt32( nFollowingActionCount );
1127  ImplSkipActions( rIStm, nFollowingActionCount );
1128  rMtf.AddAction( new MetaRefPointAction( aRefPoint, bSet ) );
1129 
1130  i = SkipActions(i, nFollowingActionCount, nActions);
1131 
1132  // #106172# Track font relevant data in shadow VDev
1133  if( bSet )
1134  aFontVDev->SetRefPoint( aRefPoint );
1135  else
1136  aFontVDev->SetRefPoint();
1137  }
1138  break;
1139 
1141  {
1142  Color aColor;
1143  bool bSet;
1144  sal_Int32 nFollowingActionCount(0);
1145 
1146  aSerializer.readColor(aColor);
1147  rIStm.ReadCharAsBool( bSet ).ReadInt32( nFollowingActionCount );
1148  ImplSkipActions( rIStm, nFollowingActionCount );
1149  rMtf.AddAction( new MetaTextLineColorAction( aColor, bSet ) );
1150 
1151  i = SkipActions(i, nFollowingActionCount, nActions);
1152  }
1153  break;
1154 
1155  case GDI_TEXTLINE_COMMENT:
1156  {
1157  Point aStartPt;
1158  sal_Int32 nWidth(0);
1159  sal_uInt32 nStrikeout(0);
1160  sal_uInt32 nUnderline(0);
1161  sal_Int32 nFollowingActionCount(0);
1162 
1163  aSerializer.readPoint(aStartPt);
1164  rIStm.ReadInt32(nWidth ).ReadUInt32(nStrikeout).ReadUInt32(nUnderline).ReadInt32(nFollowingActionCount);
1165  ImplSkipActions(rIStm, nFollowingActionCount);
1166  rMtf.AddAction( new MetaTextLineAction( aStartPt, nWidth,
1167  static_cast<FontStrikeout>(nStrikeout),
1168  static_cast<FontLineStyle>(nUnderline),
1169  LINESTYLE_NONE ) );
1170 
1171  i = SkipActions(i, nFollowingActionCount, nActions);
1172  }
1173  break;
1174 
1176  {
1177  tools::PolyPolygon aPolyPoly;
1178  Gradient aGradient;
1179  sal_Int32 nFollowingActionCount(0);
1180 
1181  ReadPolyPolygon( rIStm, aPolyPoly );
1182  aSerializer.readGradient(aGradient);
1183  rIStm.ReadInt32( nFollowingActionCount );
1184  ImplSkipActions( rIStm, nFollowingActionCount );
1185  rMtf.AddAction( new MetaGradientExAction( aPolyPoly, aGradient ) );
1186 
1187  i = SkipActions(i, nFollowingActionCount, nActions);
1188  }
1189  break;
1190 
1191  case GDI_COMMENT_COMMENT:
1192  {
1193  std::vector<sal_uInt8> aData;
1194 
1195  OString aComment = read_uInt16_lenPrefixed_uInt8s_ToOString(rIStm);
1196  sal_Int32 nValue(0);
1197  sal_uInt32 nDataSize(0);
1198  rIStm.ReadInt32(nValue).ReadUInt32(nDataSize);
1199 
1200  if (nDataSize)
1201  {
1202  const size_t nMaxPossibleData = rIStm.remainingSize();
1203  if (nDataSize > nMaxPossibleActions)
1204  {
1205  SAL_WARN("vcl.gdi", "svm record claims to have: " << nDataSize << " data, but only " << nMaxPossibleData << " possible");
1206  nDataSize = nMaxPossibleActions;
1207  }
1208  aData.resize(nDataSize);
1209  nDataSize = rIStm.ReadBytes(aData.data(), nDataSize);
1210  }
1211 
1212  sal_Int32 nFollowingActionCount(0);
1213  rIStm.ReadInt32(nFollowingActionCount);
1214  ImplSkipActions( rIStm, nFollowingActionCount );
1215  rMtf.AddAction(new MetaCommentAction(aComment, nValue, aData.data(), nDataSize));
1216 
1217  i = SkipActions(i, nFollowingActionCount, nActions);
1218  }
1219  break;
1220 
1221  case GDI_UNICODE_COMMENT:
1222  {
1223  nUnicodeCommentActionNumber = i + 1;
1224  nUnicodeCommentStreamPos = rIStm.Tell() - 6;
1225  if (nActionSize < 4)
1227  else
1228  rIStm.SeekRel(nActionSize - 4);
1229  }
1230  break;
1231 
1232  default:
1233  if (nActionSize < 4)
1235  else
1236  rIStm.SeekRel(nActionSize - 4);
1237  break;
1238  }
1239  }
1240 
1241  rIStm.SetEndian( nOldFormat );
1242 }
1243 
1244 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetFamily(FontFamily)
Definition: font/font.cxx:131
#define GDI_TEXT_ACTION
sal_uInt16 Count() const
#define GDI_LINE_ACTION
SvStream & ReadInt16(sal_Int16 &rInt16)
static void ImplReadRect(SvStream &rIStm, tools::Rectangle &rRect)
void SetStrikeout(FontStrikeout)
Definition: font/font.cxx:265
static bool ImplReadMapMode(SvStream &rIStm, MapMode &rMapMode)
void SetFillColor(const Color &)
Definition: font/font.cxx:96
#define GDI_LINEDASHDOT_ACTION
Definition: hatch.hxx:46
sal_Int32 nIndex
const tools::Polygon & GetObject(sal_uInt16 nPos) const
void SetFontSize(const Size &)
Definition: font/font.cxx:125
bool ReadDIB(Bitmap &rTarget, SvStream &rIStm, bool bFileHeader, bool bMSOFormat)
Definition: dibtools.cxx:1700
void SetBlue(sal_uInt8 nBlue)
void SetFlags(sal_uInt16 nPos, PolyFlags eFlags)
void setWidth(tools::Long nWidth)
SvStream & ReadPolyPolygon(SvStream &rIStream, tools::PolyPolygon &rPolyPoly)
OUString read_uInt16s_ToOUString(SvStream &rStrm, std::size_t nLen)
void readPoint(Point &rPoint)
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
static void ImplSkipActions(SvStream &rIStm, sal_uLong nSkipCount)
static void lcl_error(SvStream &rIStm, const SvStreamEndian &nOldFormat, sal_uLong nPos)
sal_uIntPtr sal_uLong
long Long
constexpr::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
#define GDI_TEXTARRAY_ACTION
#define GDI_FILLBRUSH_ACTION
SvStream & ReadCharAsBool(bool &rBool)
#define GDI_FONT_ACTION
void SetPrefSize(const Size &rSize)
Definition: gdimtf.hxx:176
void SetWeight(FontWeight)
Definition: font/font.cxx:223
#define GDI_ELLIPSE_ACTION
#define GDI_PIXEL_ACTION
void SetOutline(bool bOutline)
Definition: font/font.cxx:241
sal_uInt64 Seek(sal_uInt64 nPos)
#define GDI_UNICODE_COMMENT
#define GDI_GRADIENTEX_COMMENT
void SetBorder(sal_uInt16 nBorder)
void SetCharSet(rtl_TextEncoding)
Definition: font/font.cxx:137
void SetEndIntensity(sal_uInt16 nIntens)
WEIGHT_LIGHT
#define GDI_CLIPREGION_ACTION
sal_uInt64 SeekRel(sal_Int64 nPos)
FontAlign GetAlignment() const
Definition: font/font.cxx:825
#define GDI_TEXTLINE_COMMENT
static void ImplReadExtendedPolyPolygonAction(SvStream &rIStm, tools::PolyPolygon &rPolyPoly)
WEIGHT_BOLD
OString read_uInt16_lenPrefixed_uInt8s_ToOString(SvStream &rStrm)
ErrCode GetError() const
void SetOfsY(sal_uInt16 nOfsY)
LINESTYLE_NONE
#define GDI_BITMAPSCALE_ACTION
RasterOp
Definition: vclenum.hxx:192
int nCount
#define GDI_REFPOINT_COMMENT
#define GDI_POP_ACTION
constexpr tools::Long GetWidth() const
#define GDI_LINECAP_ACTION
void Insert(const tools::Polygon &rPoly, sal_uInt16 nPos=POLYPOLY_APPEND)
void SetUnderline(FontLineStyle)
Definition: font/font.cxx:253
#define GDI_POLYPOLYGON_ACTION
sal_uInt64 remainingSize()
#define GDI_BITMAPSCALEPART_ACTION
void readSize(Size &rSize)
void SetShadow(bool bShadow)
Definition: font/font.cxx:247
void SetPitch(FontPitch ePitch)
Definition: font/font.cxx:194
#define LF_FACESIZE
constexpr OUStringLiteral aData
#define GDI_MOVECLIPREGION_ACTION
static void ImplReadUnicodeComment(sal_uInt32 nStrmPos, SvStream &rIStm, OUString &rString)
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
WEIGHT_DONTKNOW
#define GDI_PEN_ACTION
#define GDI_POLYGON_ACTION
void SetAlignment(FontAlign)
Definition: font/font.cxx:109
void SetFamilyName(const OUString &rFamilyName)
Definition: font/font.cxx:115
int i
uno_Any a
#define GDI_RECT_ACTION
void SetOrientation(Degree10 nLineOrientation)
Definition: font/font.cxx:200
#define GDI_RASTEROP_ACTION
#define GDI_EXTENDEDPOLYGON_ACTION
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
WEIGHT_NORMAL
void SetRed(sal_uInt8 nRed)
static void ImplConvertFromSVM1(SvStream &rIStm, GDIMetaFile &rMtf)
#define GDI_PIE_ACTION
void SetError(ErrCode nErrorCode)
void Intersect(const tools::Rectangle &rRegion)
Definition: region.cxx:584
#define GDI_ARC_ACTION
#define GDI_POINT_ACTION
SvStream & ReadUChar(unsigned char &rChar)
#define GDI_PUSH_ACTION
ITALIC_NONE
const Color & GetFillColor() const
Definition: font/font.cxx:822
sal_Int16 nVersion
#define GDI_INVERTRECT_ACTION
void SetOfsX(sal_uInt16 nOfsX)
static bool ImplReadPolyPoly(SvStream &rIStm, tools::PolyPolygon &rPolyPoly)
#define GDI_ISECTCLIPREGION_ACTION
SvStream & ReadHatch(SvStream &rIStm, Hatch &rHatch)
Definition: gdi/hatch.cxx:79
void SetColor(const Color &)
Definition: font/font.cxx:88
SvStream & ReadInt32(sal_Int32 &rInt32)
#define GDI_COMMENT_COMMENT
std::size_t ReadBytes(void *pData, std::size_t nSize)
tools::Long const nBorder
void SetAngle(Degree10 nAngle)
#define GDI_HATCH_COMMENT
SvStreamEndian GetEndian() const
const Color & GetColor() const
Definition: font/font.cxx:821
SVMConverter(SvStream &rIStm, GDIMetaFile &rMtf)
#define SAL_WARN_IF(condition, area, stream)
ITALIC_NORMAL
unsigned char sal_uInt8
void ReplaceAction(rtl::Reference< MetaAction > pAction, size_t nAction)
Definition: gdimtf.cxx:201
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:563
MetaAction * GetAction(size_t nAction) const
Definition: gdimtf.cxx:185
void SetGreen(sal_uInt8 nGreen)
void SetTransparent(bool bTransparent)
Definition: font/font.cxx:103
SvStream & ReadGDIMetaFile(SvStream &rIStm, GDIMetaFile &rGDIMetaFile, ImplMetaReadData *pData)
Definition: gdimtf.cxx:2639
void SetEndian(SvStreamEndian SvStreamEndian)
OUString aName
bool IsTransparent() const
Definition: font/font.cxx:823
#define SVSTREAM_FILEFORMAT_ERROR
Definition: errcode.hxx:260
rtl_TextEncoding GetStreamCharSet() const
#define GDI_LINEJOIN_ACTION
sal_uInt64 Tell() const
size_t GetActionSize() const
Definition: gdimtf.cxx:180
QPRO_FUNC_TYPE nType
static bool ImplReadPoly(SvStream &rIStm, tools::Polygon &rPoly)
#define GDI_MAPMODE_ACTION
#define GDI_TRANSPARENT_COMMENT
bool good() const
void SetItalic(FontItalic)
Definition: font/font.cxx:235
void setHeight(tools::Long nHeight)
#define GDI_POLYLINE_ACTION
#define SAL_WARN(area, stream)
SvStreamEndian
#define GDI_HIGHLIGHTRECT_ACTION
#define GDI_STRETCHTEXT_ACTION
void readGradient(Gradient &rGradient)
static void ImplReadColor(SvStream &rIStm, Color &rColor)
#define GDI_FLOATTRANSPARENT_COMMENT
#define GDI_GRADIENT_ACTION
OString read_uInt8s_ToOString(SvStream &rStrm, std::size_t nLen)
aStr
void SetStartIntensity(sal_uInt16 nIntens)
rtl_TextEncoding GetCharSet() const
Definition: font/font.cxx:836
Point Center() const
sal_uInt16 nPos
sal_Int16 nValue
void SetPrefMapMode(const MapMode &rMapMode)
Definition: gdimtf.hxx:179
#define GDI_BITMAP_ACTION
constexpr tools::Long GetHeight() const
void readColor(Color &rColor)
#define GDI_TEXTLINECOLOR_COMMENT