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 <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( 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<long[]> pDXAry;
717  sal_Int32 nDXAryLen = 0;
718  if (nAryLen > 0)
719  {
720  const size_t nMinRecordSize = sizeof(sal_Int32);
721  const size_t nMaxRecords = rIStm.remainingSize() / nMinRecordSize;
722  if (o3tl::make_unsigned(nAryLen) > nMaxRecords)
723  {
724  SAL_WARN("vcl.gdi", "Parsing error: " << nMaxRecords <<
725  " max possible entries, but " << nAryLen << " claimed, truncating");
726  nAryLen = nMaxRecords;
727  }
728 
729  sal_Int32 nStrLen( aStr.getLength() );
730 
731  nDXAryLen = std::max(nAryLen, nStrLen);
732 
733  if (nDXAryLen < nLen)
734  {
735  //MetaTextArrayAction ctor expects pDXAry to be >= nLen if set, so if this can't
736  //be achieved, don't read it, it's utterly broken.
737  SAL_WARN("vcl.gdi", "dxary too short, discarding completely");
738  rIStm.SeekRel(sizeof(sal_Int32) * nDXAryLen);
739  nLen = 0;
740  nIndex = 0;
741  }
742  else
743  {
744  pDXAry.reset(new long[nDXAryLen]);
745 
746  for (sal_Int32 j = 0; j < nAryLen; ++j)
747  {
748  rIStm.ReadInt32( nTmp );
749  pDXAry[ j ] = nTmp;
750  }
751 
752  // #106172# Add last DX array elem, if missing
753  if( nAryLen != nStrLen )
754  {
755  if (nAryLen+1 == nStrLen && nIndex >= 0)
756  {
757  std::unique_ptr<long[]> pTmpAry(new long[nStrLen]);
758 
759  aFontVDev->GetTextArray( aStr, pTmpAry.get(), nIndex, nLen );
760 
761  // now, the difference between the
762  // last and the second last DX array
763  // is the advancement for the last
764  // glyph. Thus, to complete our meta
765  // action's DX array, just add that
766  // difference to last elem and store
767  // in very last.
768  if( nStrLen > 1 )
769  pDXAry[ nStrLen-1 ] = pDXAry[ nStrLen-2 ] + pTmpAry[ nStrLen-1 ] - pTmpAry[ nStrLen-2 ];
770  else
771  pDXAry[ nStrLen-1 ] = pTmpAry[ nStrLen-1 ]; // len=1: 0th position taken to be 0
772  }
773 #ifdef DBG_UTIL
774  else
775  OSL_FAIL("More than one DX array element missing on SVM import");
776 #endif
777  }
778  }
779  }
780  if ( nUnicodeCommentActionNumber == i )
781  ImplReadUnicodeComment( nUnicodeCommentStreamPos, rIStm, aStr );
782  rMtf.AddAction( new MetaTextArrayAction( aPt, aStr, pDXAry.get(), nIndex, nLen ) );
783  }
784 
785  if (nActionSize < 24)
787  else
788  rIStm.Seek(nActBegin + nActionSize);
789  }
790  break;
791 
793  {
794  sal_Int32 nIndex(0), nLen(0), nWidth(0), nTmp(0);
795 
796  aSerializer.readPoint(aPt);
797  rIStm.ReadInt32( nIndex ).ReadInt32( nLen ).ReadInt32( nTmp ).ReadInt32( nWidth );
798  if (nTmp > 0)
799  {
800  OString aByteStr = read_uInt8s_ToOString(rIStm, nTmp);
801  sal_uInt8 nTerminator = 0;
802  rIStm.ReadUChar( nTerminator );
803  SAL_WARN_IF( nTerminator != 0, "vcl.gdi", "expected string to be NULL terminated" );
804 
805  OUString aStr(OStringToOUString(aByteStr, eActualCharSet));
806  if ( nUnicodeCommentActionNumber == i )
807  ImplReadUnicodeComment( nUnicodeCommentStreamPos, rIStm, aStr );
808  rMtf.AddAction( new MetaStretchTextAction( aPt, nWidth, aStr, nIndex, nLen ) );
809  }
810 
811  if (nActionSize < 28)
813  else
814  rIStm.Seek(nActBegin + nActionSize);
815  }
816  break;
817 
818  case GDI_BITMAP_ACTION:
819  {
820  Bitmap aBmp;
821 
822  aSerializer.readPoint(aPt);
823  ReadDIB(aBmp, rIStm, true);
824  rMtf.AddAction( new MetaBmpAction( aPt, aBmp ) );
825  }
826  break;
827 
829  {
830  Bitmap aBmp;
831 
832  aSerializer.readPoint(aPt);
833  aSerializer.readSize(aSz);
834  ReadDIB(aBmp, rIStm, true);
835  rMtf.AddAction( new MetaBmpScaleAction( aPt, aSz, aBmp ) );
836  }
837  break;
838 
840  {
841  Bitmap aBmp;
842  Size aSz2;
843 
844  aSerializer.readPoint(aPt);
845  aSerializer.readSize(aSz);
846  aSerializer.readPoint(aPt1);
847  aSerializer.readSize(aSz2);
848  ReadDIB(aBmp, rIStm, true);
849  rMtf.AddAction( new MetaBmpScalePartAction( aPt, aSz, aPt1, aSz2, aBmp ) );
850  }
851  break;
852 
853  case GDI_PEN_ACTION:
854  {
855  sal_Int32 nPenWidth;
856  sal_Int16 nPenStyle;
857 
858  ImplReadColor( rIStm, aActionColor );
859  rIStm.ReadInt32( nPenWidth ).ReadInt16( nPenStyle );
860 
861  aLineInfo.SetStyle( nPenStyle ? LineStyle::Solid : LineStyle::NONE );
862  aLineInfo.SetWidth( nPenWidth );
863  bFatLine = nPenStyle && !aLineInfo.IsDefault();
864 
865  rMtf.AddAction( new MetaLineColorAction( aActionColor, nPenStyle != 0 ) );
866  }
867  break;
868 
870  {
871  sal_Int16 nBrushStyle;
872 
873  ImplReadColor( rIStm, aActionColor );
874  rIStm.SeekRel( 6 );
875  rIStm.ReadInt16( nBrushStyle );
876  rMtf.AddAction( new MetaFillColorAction( aActionColor, nBrushStyle != 0 ) );
877  rIStm.SeekRel( 2 );
878  }
879  break;
880 
881  case GDI_MAPMODE_ACTION:
882  {
883  if (ImplReadMapMode(rIStm, aMapMode))
884  {
885  rMtf.AddAction(new MetaMapModeAction(aMapMode));
886 
887  // #106172# Track font relevant data in shadow VDev
888  aFontVDev->SetMapMode(aMapMode);
889  };
890  }
891  break;
892 
894  {
895  vcl::Region aRegion;
896  sal_Int16 nRegType;
897  sal_Int16 bIntersect;
898  bool bClip = false;
899 
900  rIStm.ReadInt16( nRegType ).ReadInt16( bIntersect );
901  ImplReadRect( rIStm, aRect );
902 
903  switch( nRegType )
904  {
905  case 0:
906  break;
907 
908  case 1:
909  {
910  tools::Rectangle aRegRect;
911 
912  ImplReadRect( rIStm, aRegRect );
913  aRegion = vcl::Region( aRegRect );
914  bClip = true;
915  }
916  break;
917 
918  case 2:
919  {
920  if (ImplReadPoly(rIStm, aActionPoly))
921  {
922  aRegion = vcl::Region( aActionPoly );
923  bClip = true;
924  }
925  }
926  break;
927 
928  case 3:
929  {
930  bool bSuccess = true;
931  tools::PolyPolygon aPolyPoly;
932  sal_Int32 nPolyCount32(0);
933  rIStm.ReadInt32(nPolyCount32);
934  sal_uInt16 nPolyCount(nPolyCount32);
935 
936  for (sal_uInt16 j = 0; j < nPolyCount && rIStm.good(); ++j)
937  {
938  if (!ImplReadPoly(rIStm, aActionPoly))
939  {
940  bSuccess = false;
941  break;
942  }
943  aPolyPoly.Insert(aActionPoly);
944  }
945 
946  if (bSuccess)
947  {
948  aRegion = vcl::Region( aPolyPoly );
949  bClip = true;
950  }
951  }
952  break;
953  }
954 
955  if( bIntersect )
956  aRegion.Intersect( aRect );
957 
958  rMtf.AddAction( new MetaClipRegionAction( aRegion, bClip ) );
959  }
960  break;
961 
963  {
964  sal_Int32 nTmp(0), nTmp1(0);
965  rIStm.ReadInt32( nTmp ).ReadInt32( nTmp1 );
966  rMtf.AddAction( new MetaMoveClipRegionAction( nTmp, nTmp1 ) );
967  }
968  break;
969 
971  {
972  ImplReadRect( rIStm, aRect );
973  rMtf.AddAction( new MetaISectRectClipRegionAction( aRect ) );
974  }
975  break;
976 
977  case GDI_RASTEROP_ACTION:
978  {
979  RasterOp eRasterOp;
980  sal_Int16 nRasterOp;
981 
982  rIStm.ReadInt16( nRasterOp );
983 
984  switch( nRasterOp )
985  {
986  case 1:
987  eRasterOp = RasterOp::Invert;
988  break;
989 
990  case 4:
991  case 5:
992  eRasterOp = RasterOp::Xor;
993  break;
994 
995  default:
996  eRasterOp = RasterOp::OverPaint;
997  break;
998  }
999 
1000  rMtf.AddAction( new MetaRasterOpAction( eRasterOp ) );
1001  }
1002  break;
1003 
1004  case GDI_PUSH_ACTION:
1005  {
1006  aLIStack.push(std::make_unique<LineInfo>(aLineInfo));
1007  rMtf.AddAction( new MetaPushAction( PushFlags::ALL ) );
1008 
1009  // #106172# Track font relevant data in shadow VDev
1010  aFontVDev->Push();
1011  }
1012  break;
1013 
1014  case GDI_POP_ACTION:
1015  {
1016 
1017  std::unique_ptr<LineInfo> xLineInfo;
1018  if (!aLIStack.empty())
1019  {
1020  xLineInfo = std::move(aLIStack.top());
1021  aLIStack.pop();
1022  }
1023 
1024  // restore line info
1025  if (xLineInfo)
1026  {
1027  aLineInfo = *xLineInfo;
1028  xLineInfo.reset();
1029  bFatLine = ( LineStyle::NONE != aLineInfo.GetStyle() ) && !aLineInfo.IsDefault();
1030  }
1031 
1032  rMtf.AddAction( new MetaPopAction() );
1033 
1034  // #106172# Track font relevant data in shadow VDev
1035  aFontVDev->Pop();
1036  }
1037  break;
1038 
1039  case GDI_GRADIENT_ACTION:
1040  {
1041  Color aStartCol;
1042  Color aEndCol;
1043  sal_Int16 nStyle;
1044  sal_Int16 nAngle;
1045  sal_Int16 nBorder;
1046  sal_Int16 nOfsX;
1047  sal_Int16 nOfsY;
1048  sal_Int16 nIntensityStart;
1049  sal_Int16 nIntensityEnd;
1050 
1051  ImplReadRect( rIStm, aRect );
1052  rIStm.ReadInt16( nStyle );
1053  ImplReadColor( rIStm, aStartCol );
1054  ImplReadColor( rIStm, aEndCol );
1055  rIStm.ReadInt16( nAngle ).ReadInt16( nBorder ).ReadInt16( nOfsX ).ReadInt16( nOfsY ).ReadInt16( nIntensityStart ).ReadInt16( nIntensityEnd );
1056 
1057  Gradient aGrad( static_cast<GradientStyle>(nStyle), aStartCol, aEndCol );
1058 
1059  aGrad.SetAngle( nAngle );
1060  aGrad.SetBorder( nBorder );
1061  aGrad.SetOfsX( nOfsX );
1062  aGrad.SetOfsY( nOfsY );
1063  aGrad.SetStartIntensity( nIntensityStart );
1064  aGrad.SetEndIntensity( nIntensityEnd );
1065  rMtf.AddAction( new MetaGradientAction( aRect, aGrad ) );
1066  }
1067  break;
1068 
1070  {
1071  tools::PolyPolygon aPolyPoly;
1072  sal_Int32 nFollowingActionCount(0);
1073  sal_Int16 nTrans(0);
1074 
1075  ReadPolyPolygon( rIStm, aPolyPoly );
1076  rIStm.ReadInt16( nTrans ).ReadInt32( nFollowingActionCount );
1077  ImplSkipActions( rIStm, nFollowingActionCount );
1078  rMtf.AddAction( new MetaTransparentAction( aPolyPoly, nTrans ) );
1079 
1080  i = SkipActions(i, nFollowingActionCount, nActions);
1081  }
1082  break;
1083 
1085  {
1086  GDIMetaFile aMtf;
1087  Point aPos;
1088  Size aSize;
1089  Gradient aGradient;
1090  sal_Int32 nFollowingActionCount(0);
1091 
1092  ReadGDIMetaFile( rIStm, aMtf );
1093  aSerializer.readPoint(aPos);
1094  aSerializer.readSize(aSize);
1095  aSerializer.readGradient(aGradient);
1096  rIStm.ReadInt32( nFollowingActionCount );
1097  ImplSkipActions( rIStm, nFollowingActionCount );
1098  rMtf.AddAction( new MetaFloatTransparentAction( aMtf, aPos, aSize, aGradient ) );
1099 
1100  i = SkipActions(i, nFollowingActionCount, nActions);
1101  }
1102  break;
1103 
1104  case GDI_HATCH_COMMENT:
1105  {
1106  tools::PolyPolygon aPolyPoly;
1107  Hatch aHatch;
1108  sal_Int32 nFollowingActionCount(0);
1109 
1110  ReadPolyPolygon( rIStm, aPolyPoly );
1111  ReadHatch( rIStm, aHatch );
1112  rIStm.ReadInt32( nFollowingActionCount );
1113  ImplSkipActions( rIStm, nFollowingActionCount );
1114  rMtf.AddAction( new MetaHatchAction( aPolyPoly, aHatch ) );
1115 
1116  i = SkipActions(i, nFollowingActionCount, nActions);
1117  }
1118  break;
1119 
1120  case GDI_REFPOINT_COMMENT:
1121  {
1122  Point aRefPoint;
1123  bool bSet;
1124  sal_Int32 nFollowingActionCount(0);
1125 
1126  aSerializer.readPoint(aRefPoint);
1127  rIStm.ReadCharAsBool( bSet ).ReadInt32( nFollowingActionCount );
1128  ImplSkipActions( rIStm, nFollowingActionCount );
1129  rMtf.AddAction( new MetaRefPointAction( aRefPoint, bSet ) );
1130 
1131  i = SkipActions(i, nFollowingActionCount, nActions);
1132 
1133  // #106172# Track font relevant data in shadow VDev
1134  if( bSet )
1135  aFontVDev->SetRefPoint( aRefPoint );
1136  else
1137  aFontVDev->SetRefPoint();
1138  }
1139  break;
1140 
1142  {
1143  Color aColor;
1144  bool bSet;
1145  sal_Int32 nFollowingActionCount(0);
1146 
1147  aSerializer.readColor(aColor);
1148  rIStm.ReadCharAsBool( bSet ).ReadInt32( nFollowingActionCount );
1149  ImplSkipActions( rIStm, nFollowingActionCount );
1150  rMtf.AddAction( new MetaTextLineColorAction( aColor, bSet ) );
1151 
1152  i = SkipActions(i, nFollowingActionCount, nActions);
1153  }
1154  break;
1155 
1156  case GDI_TEXTLINE_COMMENT:
1157  {
1158  Point aStartPt;
1159  sal_Int32 nWidth(0);
1160  sal_uInt32 nStrikeout(0);
1161  sal_uInt32 nUnderline(0);
1162  sal_Int32 nFollowingActionCount(0);
1163 
1164  aSerializer.readPoint(aStartPt);
1165  rIStm.ReadInt32(nWidth ).ReadUInt32(nStrikeout).ReadUInt32(nUnderline).ReadInt32(nFollowingActionCount);
1166  ImplSkipActions(rIStm, nFollowingActionCount);
1167  rMtf.AddAction( new MetaTextLineAction( aStartPt, nWidth,
1168  static_cast<FontStrikeout>(nStrikeout),
1169  static_cast<FontLineStyle>(nUnderline),
1170  LINESTYLE_NONE ) );
1171 
1172  i = SkipActions(i, nFollowingActionCount, nActions);
1173  }
1174  break;
1175 
1177  {
1178  tools::PolyPolygon aPolyPoly;
1179  Gradient aGradient;
1180  sal_Int32 nFollowingActionCount(0);
1181 
1182  ReadPolyPolygon( rIStm, aPolyPoly );
1183  aSerializer.readGradient(aGradient);
1184  rIStm.ReadInt32( nFollowingActionCount );
1185  ImplSkipActions( rIStm, nFollowingActionCount );
1186  rMtf.AddAction( new MetaGradientExAction( aPolyPoly, aGradient ) );
1187 
1188  i = SkipActions(i, nFollowingActionCount, nActions);
1189  }
1190  break;
1191 
1192  case GDI_COMMENT_COMMENT:
1193  {
1194  std::vector<sal_uInt8> aData;
1195 
1196  OString aComment = read_uInt16_lenPrefixed_uInt8s_ToOString(rIStm);
1197  sal_Int32 nValue(0);
1198  sal_uInt32 nDataSize(0);
1199  rIStm.ReadInt32(nValue).ReadUInt32(nDataSize);
1200 
1201  if (nDataSize)
1202  {
1203  const size_t nMaxPossibleData = rIStm.remainingSize();
1204  if (nDataSize > nMaxPossibleActions)
1205  {
1206  SAL_WARN("vcl.gdi", "svm record claims to have: " << nDataSize << " data, but only " << nMaxPossibleData << " possible");
1207  nDataSize = nMaxPossibleActions;
1208  }
1209  aData.resize(nDataSize);
1210  nDataSize = rIStm.ReadBytes(aData.data(), nDataSize);
1211  }
1212 
1213  sal_Int32 nFollowingActionCount(0);
1214  rIStm.ReadInt32(nFollowingActionCount);
1215  ImplSkipActions( rIStm, nFollowingActionCount );
1216  rMtf.AddAction(new MetaCommentAction(aComment, nValue, aData.data(), nDataSize));
1217 
1218  i = SkipActions(i, nFollowingActionCount, nActions);
1219  }
1220  break;
1221 
1222  case GDI_UNICODE_COMMENT:
1223  {
1224  nUnicodeCommentActionNumber = i + 1;
1225  nUnicodeCommentStreamPos = rIStm.Tell() - 6;
1226  if (nActionSize < 4)
1228  else
1229  rIStm.SeekRel(nActionSize - 4);
1230  }
1231  break;
1232 
1233  default:
1234  if (nActionSize < 4)
1236  else
1237  rIStm.SeekRel(nActionSize - 4);
1238  break;
1239  }
1240  }
1241 
1242  rIStm.SetEndian( nOldFormat );
1243 }
1244 
1245 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetFamily(FontFamily)
Definition: font/font.cxx:123
#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:257
static bool ImplReadMapMode(SvStream &rIStm, MapMode &rMapMode)
void SetFillColor(const Color &)
Definition: font/font.cxx:88
long GetWidth() const
#define GDI_LINEDASHDOT_ACTION
Definition: hatch.hxx:44
sal_Int32 nIndex
const tools::Polygon & GetObject(sal_uInt16 nPos) const
void SetFontSize(const Size &)
Definition: font/font.cxx:117
long GetHeight() const
bool ReadDIB(Bitmap &rTarget, SvStream &rIStm, bool bFileHeader, bool bMSOFormat)
Definition: dibtools.cxx:1732
void SetBlue(sal_uInt8 nBlue)
void SetFlags(sal_uInt16 nPos, PolyFlags eFlags)
const char aData[]
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
#define GDI_TEXTARRAY_ACTION
#define GDI_FILLBRUSH_ACTION
SvStream & ReadCharAsBool(bool &rBool)
#define GDI_FONT_ACTION
void SetPrefSize(const Size &rSize)
Definition: gdimtf.hxx:174
void SetWeight(FontWeight)
Definition: font/font.cxx:215
#define GDI_ELLIPSE_ACTION
#define GDI_PIXEL_ACTION
void SetOutline(bool bOutline)
Definition: font/font.cxx:233
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:129
void SetOrientation(short nLineOrientation)
Definition: font/font.cxx:192
void SetEndIntensity(sal_uInt16 nIntens)
WEIGHT_LIGHT
#define GDI_CLIPREGION_ACTION
sal_uInt64 SeekRel(sal_Int64 nPos)
FontAlign GetAlignment() const
Definition: font/font.cxx:668
#define GDI_TEXTLINE_COMMENT
static void ImplReadExtendedPolyPolygonAction(SvStream &rIStm, tools::PolyPolygon &rPolyPoly)
WEIGHT_BOLD
OString read_uInt16_lenPrefixed_uInt8s_ToOString(SvStream &rStrm)
constexpr::Color COL_TRANSPARENT(0xFF, 0xFF, 0xFF, 0xFF)
ErrCode GetError() const
void SetOfsY(sal_uInt16 nOfsY)
LINESTYLE_NONE
#define GDI_BITMAPSCALE_ACTION
RasterOp
Definition: vclenum.hxx:194
int nCount
#define GDI_REFPOINT_COMMENT
#define GDI_POP_ACTION
#define GDI_LINECAP_ACTION
void Insert(const tools::Polygon &rPoly, sal_uInt16 nPos=POLYPOLY_APPEND)
void SetUnderline(FontLineStyle)
Definition: font/font.cxx:245
#define GDI_POLYPOLYGON_ACTION
sal_uInt64 remainingSize()
#define GDI_BITMAPSCALEPART_ACTION
void readSize(Size &rSize)
void SetShadow(bool bShadow)
Definition: font/font.cxx:239
void SetPitch(FontPitch ePitch)
Definition: font/font.cxx:186
#define LF_FACESIZE
#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:101
void SetFamilyName(const OUString &rFamilyName)
Definition: font/font.cxx:107
int i
uno_Any a
#define GDI_RECT_ACTION
#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)
long const nBorder
#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:665
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:80
SvStream & ReadInt32(sal_Int32 &rInt32)
#define GDI_COMMENT_COMMENT
std::size_t ReadBytes(void *pData, std::size_t nSize)
#define GDI_HATCH_COMMENT
SvStreamEndian GetEndian() const
const Color & GetColor() const
Definition: font/font.cxx:664
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:178
void SetAngle(sal_uInt16 nAngle)
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:543
MetaAction * GetAction(size_t nAction) const
Definition: gdimtf.cxx:162
void SetGreen(sal_uInt8 nGreen)
void SetTransparent(bool bTransparent)
Definition: font/font.cxx:95
SvStream & ReadGDIMetaFile(SvStream &rIStm, GDIMetaFile &rGDIMetaFile, ImplMetaReadData *pData)
Definition: gdimtf.cxx:2622
void SetEndian(SvStreamEndian SvStreamEndian)
OUString aName
bool IsTransparent() const
Definition: font/font.cxx:666
#define SVSTREAM_FILEFORMAT_ERROR
Definition: errcode.hxx:262
rtl_TextEncoding GetStreamCharSet() const
#define GDI_LINEJOIN_ACTION
sal_uInt64 Tell() const
size_t GetActionSize() const
Definition: gdimtf.cxx:157
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:227
#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
void setWidth(long nWidth)
#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:679
Point Center() const
sal_uInt16 nPos
sal_Int16 nValue
void SetPrefMapMode(const MapMode &rMapMode)
Definition: gdimtf.hxx:177
#define GDI_BITMAP_ACTION
void readColor(Color &rColor)
#define GDI_TEXTLINECOLOR_COMMENT
void setHeight(long nHeight)