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