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