1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/log.hxx>
21 #include <osl/thread.h>
22 #include <tools/stream.hxx>
23 #include <tools/vcompat.hxx>
24 #include <comphelper/configuration.hxx>
26 #include <vcl/filter/SvmReader.hxx>
27 #include <vcl/rendercontext/DrawTextFlags.hxx>
28 #include <vcl/TypeSerializer.hxx>
29 #include <vcl/dibtools.hxx>
30 #include <vcl/gdimtf.hxx>
31 #include <vcl/metaact.hxx>
33 #include "SvmConverter.hxx"
40 ImplMetaReadData
& m_rData
;
41 rtl_TextEncoding m_eOrigCharSet
;
44 DepthGuard(ImplMetaReadData
& rData
, SvStream
const& rIStm
)
46 , m_eOrigCharSet(m_rData
.meActualCharSet
)
48 ++m_rData
.mnParseDepth
;
49 m_rData
.meActualCharSet
= rIStm
.GetStreamCharSet();
51 bool TooDeep() const { return m_rData
.mnParseDepth
> 1024; }
54 --m_rData
.mnParseDepth
;
55 m_rData
.meActualCharSet
= m_eOrigCharSet
;
60 SvmReader::SvmReader(SvStream
& rIStm
)
65 SvStream
& SvmReader::Read(GDIMetaFile
& rMetaFile
, ImplMetaReadData
* pData
)
67 if (mrStream
.GetError())
69 SAL_WARN("vcl.gdi", "Stream error: " << mrStream
.GetError());
73 sal_uInt64 nStmPos
= mrStream
.Tell();
74 SvStreamEndian nOldFormat
= mrStream
.GetEndian();
76 mrStream
.SetEndian(SvStreamEndian::LITTLE
);
83 mrStream
.ReadBytes(aId
, 6);
84 if (mrStream
.good() && !strcmp(aId
, "VCLMTF"))
87 sal_uInt32 nStmCompressMode
= 0;
88 sal_uInt32 nCount
= 0;
89 std::unique_ptr
<VersionCompatRead
> pCompat(new VersionCompatRead(mrStream
));
91 mrStream
.ReadUInt32(nStmCompressMode
);
92 TypeSerializer
aSerializer(mrStream
);
94 aSerializer
.readMapMode(aMapMode
);
95 rMetaFile
.SetPrefMapMode(aMapMode
);
97 aSerializer
.readSize(aSize
);
98 rMetaFile
.SetPrefSize(aSize
);
99 mrStream
.ReadUInt32(nCount
);
101 pCompat
.reset(); // destructor writes stuff into the header
103 std::unique_ptr
<ImplMetaReadData
> xReadData
;
106 xReadData
.reset(new ImplMetaReadData
);
107 pData
= xReadData
.get();
109 DepthGuard
aDepthGuard(*pData
, mrStream
);
111 if (aDepthGuard
.TooDeep())
112 throw std::runtime_error("too much recursion");
114 for (sal_uInt32 nAction
= 0; (nAction
< nCount
) && !mrStream
.eof(); nAction
++)
116 rtl::Reference
<MetaAction
> pAction
= MetaActionHandler(pData
);
119 if (pAction
->GetType() == MetaActionType::COMMENT
)
121 MetaCommentAction
* pCommentAct
122 = static_cast<MetaCommentAction
*>(pAction
.get());
124 if (pCommentAct
->GetComment() == "EMF_PLUS")
125 rMetaFile
.UseCanvas(true);
127 rMetaFile
.AddAction(pAction
);
133 mrStream
.Seek(nStmPos
);
134 SVMConverter(mrStream
, rMetaFile
);
139 SAL_WARN("vcl", "GDIMetaFile exception during load");
140 mrStream
.SetError(SVSTREAM_FILEFORMAT_ERROR
);
144 if (mrStream
.GetError())
147 mrStream
.Seek(nStmPos
);
150 mrStream
.SetEndian(nOldFormat
);
154 rtl::Reference
<MetaAction
> SvmReader::MetaActionHandler(ImplMetaReadData
* pData
)
156 rtl::Reference
<MetaAction
> pAction
;
158 mrStream
.ReadUInt16(nTmp
);
159 MetaActionType nType
= static_cast<MetaActionType
>(nTmp
);
163 case MetaActionType::NONE
:
164 return DefaultHandler();
165 case MetaActionType::PIXEL
:
166 return PixelHandler();
167 case MetaActionType::POINT
:
168 return PointHandler();
169 case MetaActionType::LINE
:
170 return LineHandler();
171 case MetaActionType::RECT
:
172 return RectHandler();
173 case MetaActionType::ROUNDRECT
:
174 return RoundRectHandler();
175 case MetaActionType::ELLIPSE
:
176 return EllipseHandler();
177 case MetaActionType::ARC
:
179 case MetaActionType::PIE
:
181 case MetaActionType::CHORD
:
182 return ChordHandler();
183 case MetaActionType::POLYLINE
:
184 return PolyLineHandler();
185 case MetaActionType::POLYGON
:
186 return PolygonHandler();
187 case MetaActionType::POLYPOLYGON
:
188 return PolyPolygonHandler();
189 case MetaActionType::TEXT
:
190 return TextHandler(pData
);
191 case MetaActionType::TEXTARRAY
:
192 return TextArrayHandler(pData
);
193 case MetaActionType::STRETCHTEXT
:
194 return StretchTextHandler(pData
);
195 case MetaActionType::TEXTRECT
:
196 return TextRectHandler(pData
);
197 case MetaActionType::TEXTLINE
:
198 return TextLineHandler();
199 case MetaActionType::BMP
:
201 case MetaActionType::BMPSCALE
:
202 return BmpScaleHandler();
203 case MetaActionType::BMPSCALEPART
:
204 return BmpScalePartHandler();
205 case MetaActionType::BMPEX
:
206 return BmpExHandler();
207 case MetaActionType::BMPEXSCALE
:
208 return BmpExScaleHandler();
209 case MetaActionType::BMPEXSCALEPART
:
210 return BmpExScalePartHandler();
211 case MetaActionType::MASK
:
212 return MaskHandler();
213 case MetaActionType::MASKSCALE
:
214 return MaskScaleHandler();
215 case MetaActionType::MASKSCALEPART
:
216 return MaskScalePartHandler();
217 case MetaActionType::GRADIENT
:
218 return GradientHandler();
219 case MetaActionType::GRADIENTEX
:
220 return GradientExHandler();
221 case MetaActionType::HATCH
:
222 return HatchHandler();
223 case MetaActionType::WALLPAPER
:
224 return WallpaperHandler();
225 case MetaActionType::CLIPREGION
:
226 return ClipRegionHandler();
227 case MetaActionType::ISECTRECTCLIPREGION
:
228 return ISectRectClipRegionHandler();
229 case MetaActionType::ISECTREGIONCLIPREGION
:
230 return ISectRegionClipRegionHandler();
231 case MetaActionType::MOVECLIPREGION
:
232 return MoveClipRegionHandler();
233 case MetaActionType::LINECOLOR
:
234 return LineColorHandler();
235 case MetaActionType::FILLCOLOR
:
236 return FillColorHandler();
237 case MetaActionType::TEXTCOLOR
:
238 return TextColorHandler();
239 case MetaActionType::TEXTFILLCOLOR
:
240 return TextFillColorHandler();
241 case MetaActionType::TEXTLINECOLOR
:
242 return TextLineColorHandler();
243 case MetaActionType::OVERLINECOLOR
:
244 return OverlineColorHandler();
245 case MetaActionType::TEXTALIGN
:
246 return TextAlignHandler();
247 case MetaActionType::MAPMODE
:
248 return MapModeHandler();
249 case MetaActionType::FONT
:
250 return FontHandler(pData
);
251 case MetaActionType::PUSH
:
252 return PushHandler();
253 case MetaActionType::POP
:
255 case MetaActionType::RASTEROP
:
256 return RasterOpHandler();
257 case MetaActionType::Transparent
:
258 return TransparentHandler();
259 case MetaActionType::FLOATTRANSPARENT
:
260 return FloatTransparentHandler(pData
);
261 case MetaActionType::EPS
:
263 case MetaActionType::REFPOINT
:
264 return RefPointHandler();
265 case MetaActionType::COMMENT
:
266 return CommentHandler();
267 case MetaActionType::LAYOUTMODE
:
268 return LayoutModeHandler();
269 case MetaActionType::TEXTLANGUAGE
:
270 return TextLanguageHandler();
274 VersionCompatRead
aCompat(mrStream
);
282 void SvmReader::ReadColor(Color
& rColor
)
285 mrStream
.ReadUInt32(nTmp
);
286 rColor
= ::Color(ColorTransparency
, nTmp
);
289 rtl::Reference
<MetaAction
> SvmReader::LineColorHandler()
291 rtl::Reference
<MetaLineColorAction
> pAction(new MetaLineColorAction
);
293 VersionCompatRead
aCompat(mrStream
);
297 mrStream
.ReadCharAsBool(aBool
);
299 pAction
->SetSetting(aBool
);
300 pAction
->SetColor(aColor
);
305 rtl::Reference
<MetaAction
> SvmReader::FillColorHandler()
307 rtl::Reference
<MetaFillColorAction
> pAction(new MetaFillColorAction
);
309 VersionCompatRead
aCompat(mrStream
);
314 mrStream
.ReadCharAsBool(aBool
);
316 pAction
->SetColor(aColor
);
317 pAction
->SetSetting(aBool
);
322 rtl::Reference
<MetaAction
> SvmReader::RectHandler()
324 rtl::Reference
<MetaRectAction
> pAction(new MetaRectAction
);
326 VersionCompatRead
aCompat(mrStream
);
327 TypeSerializer
aSerializer(mrStream
);
329 tools::Rectangle aRectangle
;
330 aSerializer
.readRectangle(aRectangle
);
331 pAction
->SetRect(aRectangle
);
336 rtl::Reference
<MetaAction
> SvmReader::PointHandler()
338 rtl::Reference
<MetaPointAction
> pAction(new MetaPointAction
);
340 VersionCompatRead
aCompat(mrStream
);
341 TypeSerializer
aSerializer(mrStream
);
344 aSerializer
.readPoint(aPoint
);
345 pAction
->SetPoint(aPoint
);
350 rtl::Reference
<MetaAction
> SvmReader::PixelHandler()
352 rtl::Reference
<MetaPixelAction
> pAction(new MetaPixelAction
);
354 VersionCompatRead
aCompat(mrStream
);
355 TypeSerializer
aSerializer(mrStream
);
358 aSerializer
.readPoint(aPoint
);
362 pAction
->SetPoint(aPoint
);
363 pAction
->SetColor(aColor
);
368 rtl::Reference
<MetaAction
> SvmReader::LineHandler()
370 rtl::Reference
<MetaLineAction
> pAction(new MetaLineAction
);
372 VersionCompatRead
aCompat(mrStream
);
375 TypeSerializer
aSerializer(mrStream
);
378 aSerializer
.readPoint(aPoint
);
379 aSerializer
.readPoint(aEndPoint
);
381 pAction
->SetStartPoint(aPoint
);
382 pAction
->SetEndPoint(aEndPoint
);
385 if (aCompat
.GetVersion() >= 2)
388 ReadLineInfo(mrStream
, aLineInfo
);
389 pAction
->SetLineInfo(aLineInfo
);
395 rtl::Reference
<MetaAction
> SvmReader::RoundRectHandler()
397 rtl::Reference
<MetaRoundRectAction
> pAction(new MetaRoundRectAction
);
399 VersionCompatRead
aCompat(mrStream
);
400 TypeSerializer
aSerializer(mrStream
);
402 tools::Rectangle aRectangle
;
403 aSerializer
.readRectangle(aRectangle
);
404 sal_uInt32
HorzRound(0);
405 sal_uInt32
VertRound(0);
406 mrStream
.ReadUInt32(HorzRound
).ReadUInt32(VertRound
);
408 pAction
->SetRect(aRectangle
);
409 pAction
->SetHorzRound(HorzRound
);
410 pAction
->SetVertRound(VertRound
);
415 rtl::Reference
<MetaAction
> SvmReader::EllipseHandler()
417 rtl::Reference
<MetaEllipseAction
> pAction(new MetaEllipseAction
);
419 VersionCompatRead
aCompat(mrStream
);
420 TypeSerializer
aSerializer(mrStream
);
422 tools::Rectangle aRectangle
;
423 aSerializer
.readRectangle(aRectangle
);
425 pAction
->SetRect(aRectangle
);
430 rtl::Reference
<MetaAction
> SvmReader::ArcHandler()
432 rtl::Reference
<MetaArcAction
> pAction(new MetaArcAction
);
434 VersionCompatRead
aCompat(mrStream
);
435 TypeSerializer
aSerializer(mrStream
);
437 tools::Rectangle aRectangle
;
438 aSerializer
.readRectangle(aRectangle
);
440 aSerializer
.readPoint(aPoint
);
442 aSerializer
.readPoint(aEndPoint
);
444 pAction
->SetRect(aRectangle
);
445 pAction
->SetStartPoint(aPoint
);
446 pAction
->SetEndPoint(aEndPoint
);
451 rtl::Reference
<MetaAction
> SvmReader::PieHandler()
453 rtl::Reference
<MetaPieAction
> pAction(new MetaPieAction
);
455 VersionCompatRead
aCompat(mrStream
);
456 TypeSerializer
aSerializer(mrStream
);
458 tools::Rectangle aRectangle
;
459 aSerializer
.readRectangle(aRectangle
);
461 aSerializer
.readPoint(aPoint
);
463 aSerializer
.readPoint(aEndPoint
);
465 pAction
->SetRect(aRectangle
);
466 pAction
->SetStartPoint(aPoint
);
467 pAction
->SetEndPoint(aEndPoint
);
472 rtl::Reference
<MetaAction
> SvmReader::ChordHandler()
474 rtl::Reference
<MetaChordAction
> pAction(new MetaChordAction
);
476 VersionCompatRead
aCompat(mrStream
);
477 TypeSerializer
aSerializer(mrStream
);
479 tools::Rectangle aRectangle
;
480 aSerializer
.readRectangle(aRectangle
);
482 aSerializer
.readPoint(aPoint
);
484 aSerializer
.readPoint(aEndPoint
);
486 pAction
->SetRect(aRectangle
);
487 pAction
->SetStartPoint(aPoint
);
488 pAction
->SetEndPoint(aEndPoint
);
493 rtl::Reference
<MetaAction
> SvmReader::PolyLineHandler()
495 rtl::Reference
<MetaPolyLineAction
> pAction(new MetaPolyLineAction
);
497 VersionCompatRead
aCompat(mrStream
);
500 tools::Polygon aPolygon
;
501 ReadPolygon(mrStream
, aPolygon
);
504 if (aCompat
.GetVersion() >= 2)
507 ReadLineInfo(mrStream
, aLineInfo
);
508 pAction
->SetLineInfo(aLineInfo
);
510 if (aCompat
.GetVersion() >= 3)
512 sal_uInt8
bHasPolyFlags(0);
513 mrStream
.ReadUChar(bHasPolyFlags
);
515 aPolygon
.Read(mrStream
);
517 pAction
->SetPolygon(aPolygon
);
522 rtl::Reference
<MetaAction
> SvmReader::PolygonHandler()
524 rtl::Reference
<MetaPolygonAction
> pAction(new MetaPolygonAction
);
526 VersionCompatRead
aCompat(mrStream
);
528 tools::Polygon aPolygon
;
529 ReadPolygon(mrStream
, aPolygon
); // Version 1
531 if (aCompat
.GetVersion() >= 2) // Version 2
533 sal_uInt8
bHasPolyFlags(0);
534 mrStream
.ReadUChar(bHasPolyFlags
);
536 aPolygon
.Read(mrStream
);
539 pAction
->SetPolygon(aPolygon
);
544 rtl::Reference
<MetaAction
> SvmReader::PolyPolygonHandler()
546 rtl::Reference
<MetaPolyPolygonAction
> pAction(new MetaPolyPolygonAction
);
548 VersionCompatRead
aCompat(mrStream
);
549 tools::PolyPolygon aPolyPolygon
;
550 ReadPolyPolygon(mrStream
, aPolyPolygon
); // Version 1
552 if (aCompat
.GetVersion() < 2) // Version 2
554 pAction
->SetPolyPolygon(aPolyPolygon
);
558 sal_uInt16
nNumberOfComplexPolygons(0);
559 mrStream
.ReadUInt16(nNumberOfComplexPolygons
);
560 const size_t nMinRecordSize
= sizeof(sal_uInt16
);
561 const size_t nMaxRecords
= mrStream
.remainingSize() / nMinRecordSize
;
562 if (nNumberOfComplexPolygons
> nMaxRecords
)
564 SAL_WARN("vcl.gdi", "Parsing error: " << nMaxRecords
<< " max possible entries, but "
565 << nNumberOfComplexPolygons
566 << " claimed, truncating");
567 nNumberOfComplexPolygons
= nMaxRecords
;
569 for (sal_uInt16 i
= 0; i
< nNumberOfComplexPolygons
; ++i
)
571 sal_uInt16
nIndex(0);
572 mrStream
.ReadUInt16(nIndex
);
573 tools::Polygon aPoly
;
574 aPoly
.Read(mrStream
);
575 if (nIndex
>= aPolyPolygon
.Count())
577 SAL_WARN("vcl.gdi", "svm contains polygon index " << nIndex
578 << " outside possible range "
579 << aPolyPolygon
.Count());
582 aPolyPolygon
.Replace(aPoly
, nIndex
);
585 pAction
->SetPolyPolygon(aPolyPolygon
);
590 rtl::Reference
<MetaAction
> SvmReader::TextHandler(const ImplMetaReadData
* pData
)
592 rtl::Reference
<MetaTextAction
> pAction(new MetaTextAction
);
594 VersionCompatRead
aCompat(mrStream
);
595 TypeSerializer
aSerializer(mrStream
);
598 aSerializer
.readPoint(aPoint
);
599 OUString aStr
= mrStream
.ReadUniOrByteString(pData
->meActualCharSet
);
600 sal_uInt16
nTmpIndex(0);
601 mrStream
.ReadUInt16(nTmpIndex
);
602 sal_uInt16
nTmpLen(0);
603 mrStream
.ReadUInt16(nTmpLen
);
605 pAction
->SetPoint(aPoint
);
607 if (aCompat
.GetVersion() >= 2) // Version 2
608 aStr
= read_uInt16_lenPrefixed_uInt16s_ToOUString(mrStream
);
610 if (nTmpIndex
> aStr
.getLength())
612 SAL_WARN("vcl.gdi", "inconsistent offset");
613 nTmpIndex
= aStr
.getLength();
616 if (nTmpLen
> aStr
.getLength() - nTmpIndex
)
618 SAL_WARN("vcl.gdi", "inconsistent len");
619 nTmpLen
= aStr
.getLength() - nTmpIndex
;
622 pAction
->SetIndex(nTmpIndex
);
623 pAction
->SetLen(nTmpLen
);
625 pAction
->SetText(aStr
);
630 rtl::Reference
<MetaAction
> SvmReader::TextArrayHandler(const ImplMetaReadData
* pData
)
632 rtl::Reference
<MetaTextArrayAction
> pAction(new MetaTextArrayAction
);
636 VersionCompatRead
aCompat(mrStream
);
637 TypeSerializer
aSerializer(mrStream
);
640 aSerializer
.readPoint(aPoint
);
641 pAction
->SetPoint(aPoint
);
643 OUString aStr
= mrStream
.ReadUniOrByteString(pData
->meActualCharSet
);
644 pAction
->SetText(aStr
);
646 sal_uInt16
nTmpIndex(0);
647 mrStream
.ReadUInt16(nTmpIndex
);
649 sal_uInt16
nTmpLen(0);
650 mrStream
.ReadUInt16(nTmpLen
);
652 sal_Int32
nAryLen(0);
653 mrStream
.ReadInt32(nAryLen
);
655 if (nTmpLen
> aStr
.getLength() - nTmpIndex
)
657 SAL_WARN("vcl.gdi", "inconsistent offset and len");
658 pAction
->SetIndex(0);
659 pAction
->SetLen(aStr
.getLength());
663 pAction
->SetIndex(nTmpIndex
);
664 pAction
->SetLen(nTmpLen
);
668 // #i9762#, #106172# Ensure that DX array is at least mnLen entries long
669 if (nTmpLen
>= nAryLen
)
675 for (i
= 0; i
< nAryLen
; i
++)
677 mrStream
.ReadInt32(val
);
678 aArray
.push_back(val
);
680 // #106172# setup remainder
681 for (; i
< nTmpLen
; i
++)
684 catch (std::bad_alloc
&)
694 if (aCompat
.GetVersion() >= 2) // Version 2
696 aStr
= read_uInt16_lenPrefixed_uInt16s_ToOUString(mrStream
);
697 pAction
->SetText(aStr
);
699 if (nTmpLen
> aStr
.getLength() - nTmpIndex
)
701 SAL_WARN("vcl.gdi", "inconsistent offset and len");
702 pAction
->SetIndex(0);
703 pAction
->SetLen(aStr
.getLength());
709 pAction
->SetDXArray(std::move(aArray
));
711 if (aCompat
.GetVersion() >= 3) // Version 3
713 sal_uInt32
nKashidaAryLen(0);
714 mrStream
.ReadUInt32(nKashidaAryLen
);
715 nTmpLen
= std::min(nKashidaAryLen
, static_cast<sal_uInt32
>(pAction
->GetDXArray().size()));
718 // aKashidaArray, if not empty, must be the same size as aArray
719 std::vector
<sal_Bool
> aKashidaArray(pAction
->GetDXArray().size(), 0);
721 // [-loplugin:fakebool] false positive:
722 sal_Bool
val(sal_False
);
723 for (sal_uInt32 i
= 0; i
< nTmpLen
; i
++)
725 mrStream
.ReadUChar(val
);
726 aKashidaArray
[i
] = val
;
728 pAction
->SetKashidaArray(std::move(aKashidaArray
));
732 if (aCompat
.GetVersion() >= 4) // Version 4
734 bool bTmpHasContext
= false;
735 mrStream
.ReadCharAsBool(bTmpHasContext
);
739 sal_uInt16 nTmpContextIndex
= 0;
740 mrStream
.ReadUInt16(nTmpContextIndex
);
742 sal_uInt16 nTmpContextLen
= 0;
743 mrStream
.ReadUInt16(nTmpContextLen
);
745 sal_uInt16 nTmpEnd
= nTmpIndex
+ nTmpLen
;
746 sal_uInt16 nTmpContextEnd
= nTmpContextIndex
+ nTmpContextLen
;
747 if ((nTmpContextEnd
<= aStr
.getLength()) && (nTmpContextIndex
<= nTmpIndex
)
748 && (nTmpContextEnd
>= nTmpEnd
))
750 pAction
->SetLayoutContextIndex(nTmpContextIndex
);
751 pAction
->SetLayoutContextLen(nTmpContextLen
);
755 SAL_WARN("vcl.gdi", "inconsistent layout context offset and len");
763 rtl::Reference
<MetaAction
> SvmReader::StretchTextHandler(const ImplMetaReadData
* pData
)
765 rtl::Reference
<MetaStretchTextAction
> pAction(new MetaStretchTextAction
);
767 VersionCompatRead
aCompat(mrStream
);
768 TypeSerializer
aSerializer(mrStream
);
771 aSerializer
.readPoint(aPoint
);
772 OUString aStr
= mrStream
.ReadUniOrByteString(pData
->meActualCharSet
);
773 sal_uInt32
nTmpWidth(0);
774 mrStream
.ReadUInt32(nTmpWidth
);
775 sal_uInt16
nTmpIndex(0);
776 mrStream
.ReadUInt16(nTmpIndex
);
777 sal_uInt16
nTmpLen(0);
778 mrStream
.ReadUInt16(nTmpLen
);
780 pAction
->SetPoint(aPoint
);
781 pAction
->SetWidth(nTmpWidth
);
783 if (aCompat
.GetVersion() >= 2) // Version 2
784 aStr
= read_uInt16_lenPrefixed_uInt16s_ToOUString(mrStream
);
786 if (nTmpIndex
> aStr
.getLength())
788 SAL_WARN("vcl.gdi", "inconsistent offset");
789 nTmpIndex
= aStr
.getLength();
792 if (nTmpLen
> aStr
.getLength() - nTmpIndex
)
794 SAL_WARN("vcl.gdi", "inconsistent len");
795 nTmpLen
= aStr
.getLength() - nTmpIndex
;
798 pAction
->SetIndex(nTmpIndex
);
799 pAction
->SetLen(nTmpLen
);
801 pAction
->SetText(aStr
);
806 rtl::Reference
<MetaAction
> SvmReader::TextRectHandler(const ImplMetaReadData
* pData
)
808 rtl::Reference
<MetaTextRectAction
> pAction(new MetaTextRectAction
);
810 VersionCompatRead
aCompat(mrStream
);
811 TypeSerializer
aSerializer(mrStream
);
813 tools::Rectangle aRect
;
814 aSerializer
.readRectangle(aRect
);
815 OUString aStr
= mrStream
.ReadUniOrByteString(pData
->meActualCharSet
);
817 mrStream
.ReadUInt16(nTmp
);
819 pAction
->SetRect(aRect
);
821 DrawTextFlags
nFlags(static_cast<DrawTextFlags
>(nTmp
));
822 const static bool bFuzzing
= comphelper::IsFuzzing();
824 nFlags
= nFlags
& ~DrawTextFlags::MultiLine
;
826 pAction
->SetStyle(nFlags
);
828 if (aCompat
.GetVersion() >= 2) // Version 2
829 aStr
= read_uInt16_lenPrefixed_uInt16s_ToOUString(mrStream
);
831 pAction
->SetText(aStr
);
836 rtl::Reference
<MetaAction
> SvmReader::TextLineHandler()
838 rtl::Reference
<MetaTextLineAction
> pAction(new MetaTextLineAction
);
840 VersionCompatRead
aCompat(mrStream
);
841 TypeSerializer
aSerializer(mrStream
);
844 aSerializer
.readPoint(aPos
);
845 sal_Int32
nTempWidth(0);
846 mrStream
.ReadInt32(nTempWidth
);
848 pAction
->SetStartPoint(aPos
);
851 SAL_WARN("vcl.gdi", "negative width");
854 pAction
->SetWidth(nTempWidth
);
856 sal_uInt32
nTempStrikeout(0);
857 mrStream
.ReadUInt32(nTempStrikeout
);
858 sal_uInt32
nTempUnderline(0);
859 mrStream
.ReadUInt32(nTempUnderline
);
861 pAction
->SetStrikeout(static_cast<FontStrikeout
>(nTempStrikeout
& SAL_MAX_ENUM
));
862 pAction
->SetUnderline(static_cast<FontLineStyle
>(nTempUnderline
& SAL_MAX_ENUM
));
864 if (aCompat
.GetVersion() >= 2)
866 sal_uInt32
nTempOverline(0);
867 mrStream
.ReadUInt32(nTempOverline
);
868 pAction
->SetOverline(static_cast<FontLineStyle
>(nTempOverline
& SAL_MAX_ENUM
));
874 rtl::Reference
<MetaAction
> SvmReader::BmpHandler()
876 rtl::Reference
<MetaBmpAction
> pAction(new MetaBmpAction
);
878 VersionCompatRead
aCompat(mrStream
);
880 ReadDIB(aBmp
, mrStream
, true);
881 TypeSerializer
aSerializer(mrStream
);
883 aSerializer
.readPoint(aPoint
);
885 pAction
->SetBitmap(aBmp
);
886 pAction
->SetPoint(aPoint
);
891 rtl::Reference
<MetaAction
> SvmReader::BmpScaleHandler()
893 rtl::Reference
<MetaBmpScaleAction
> pAction(new MetaBmpScaleAction
);
895 VersionCompatRead
aCompat(mrStream
);
897 ReadDIB(aBmp
, mrStream
, true);
898 TypeSerializer
aSerializer(mrStream
);
900 aSerializer
.readPoint(aPoint
);
903 aSerializer
.readSize(aSz
);
905 pAction
->SetBitmap(aBmp
);
906 pAction
->SetPoint(aPoint
);
907 pAction
->SetSize(aSz
);
912 rtl::Reference
<MetaAction
> SvmReader::BmpScalePartHandler()
914 rtl::Reference
<MetaBmpScalePartAction
> pAction(new MetaBmpScalePartAction
);
916 VersionCompatRead
aCompat(mrStream
);
918 ReadDIB(aBmp
, mrStream
, true);
919 TypeSerializer
aSerializer(mrStream
);
921 aSerializer
.readPoint(aDestPoint
);
923 aSerializer
.readSize(aDestSize
);
925 aSerializer
.readPoint(aSrcPoint
);
927 aSerializer
.readSize(aSrcSize
);
929 pAction
->SetBitmap(aBmp
);
930 pAction
->SetDestPoint(aDestPoint
);
931 pAction
->SetDestSize(aDestSize
);
932 pAction
->SetSrcPoint(aSrcPoint
);
933 pAction
->SetSrcSize(aSrcSize
);
938 rtl::Reference
<MetaAction
> SvmReader::BmpExHandler()
940 rtl::Reference
<MetaBmpExAction
> pAction(new MetaBmpExAction
);
942 VersionCompatRead
aCompat(mrStream
);
944 ReadDIBBitmapEx(aBmpEx
, mrStream
);
945 TypeSerializer
aSerializer(mrStream
);
947 aSerializer
.readPoint(aPoint
);
949 pAction
->SetPoint(aPoint
);
950 pAction
->SetBitmapEx(aBmpEx
);
955 rtl::Reference
<MetaAction
> SvmReader::BmpExScaleHandler()
957 rtl::Reference
<MetaBmpExScaleAction
> pAction(new MetaBmpExScaleAction
);
959 VersionCompatRead
aCompat(mrStream
);
961 ReadDIBBitmapEx(aBmpEx
, mrStream
);
962 TypeSerializer
aSerializer(mrStream
);
964 aSerializer
.readPoint(aPoint
);
967 aSerializer
.readSize(aSize
);
969 pAction
->SetBitmapEx(aBmpEx
);
970 pAction
->SetPoint(aPoint
);
971 pAction
->SetSize(aSize
);
976 rtl::Reference
<MetaAction
> SvmReader::BmpExScalePartHandler()
978 rtl::Reference
<MetaBmpExScalePartAction
> pAction(new MetaBmpExScalePartAction
);
980 VersionCompatRead
aCompat(mrStream
);
982 ReadDIBBitmapEx(aBmpEx
, mrStream
);
983 TypeSerializer
aSerializer(mrStream
);
985 aSerializer
.readPoint(aDstPoint
);
987 aSerializer
.readSize(aDstSize
);
989 aSerializer
.readPoint(aSrcPoint
);
991 aSerializer
.readSize(aSrcSize
);
993 pAction
->SetBitmapEx(aBmpEx
);
994 pAction
->SetDestPoint(aDstPoint
);
995 pAction
->SetDestSize(aDstSize
);
996 pAction
->SetSrcPoint(aSrcPoint
);
997 pAction
->SetSrcSize(aSrcSize
);
1002 rtl::Reference
<MetaAction
> SvmReader::MaskHandler()
1004 rtl::Reference
<MetaMaskAction
> pAction(new MetaMaskAction
);
1006 VersionCompatRead
aCompat(mrStream
);
1008 ReadDIB(aBmp
, mrStream
, true);
1009 TypeSerializer
aSerializer(mrStream
);
1011 aSerializer
.readPoint(aPoint
);
1013 pAction
->SetBitmap(aBmp
);
1014 pAction
->SetPoint(aPoint
);
1019 rtl::Reference
<MetaAction
> SvmReader::MaskScaleHandler()
1021 rtl::Reference
<MetaMaskScaleAction
> pAction(new MetaMaskScaleAction
);
1023 VersionCompatRead
aCompat(mrStream
);
1025 ReadDIB(aBmp
, mrStream
, true);
1026 TypeSerializer
aSerializer(mrStream
);
1028 aSerializer
.readPoint(aPoint
);
1030 aSerializer
.readSize(aSize
);
1032 pAction
->SetBitmap(aBmp
);
1033 pAction
->SetPoint(aPoint
);
1034 pAction
->SetSize(aSize
);
1039 rtl::Reference
<MetaAction
> SvmReader::MaskScalePartHandler()
1041 rtl::Reference
<MetaMaskScalePartAction
> pAction(new MetaMaskScalePartAction
);
1043 VersionCompatRead
aCompat(mrStream
);
1045 ReadDIB(aBmp
, mrStream
, true);
1048 TypeSerializer
aSerializer(mrStream
);
1050 aSerializer
.readPoint(aDstPt
);
1052 aSerializer
.readSize(aDstSz
);
1054 aSerializer
.readPoint(aSrcPt
);
1056 aSerializer
.readSize(aSrcSz
);
1058 pAction
->SetBitmap(aBmp
);
1059 pAction
->SetColor(aColor
);
1060 pAction
->SetDestPoint(aDstPt
);
1061 pAction
->SetDestSize(aDstSz
);
1062 pAction
->SetSrcPoint(aSrcPt
);
1063 pAction
->SetSrcSize(aSrcSz
);
1068 rtl::Reference
<MetaAction
> SvmReader::GradientHandler()
1070 rtl::Reference
<MetaGradientAction
> pAction(new MetaGradientAction
);
1072 VersionCompatRead
aCompat(mrStream
);
1073 TypeSerializer
aSerializer(mrStream
);
1075 tools::Rectangle aRect
;
1076 aSerializer
.readRectangle(aRect
);
1078 aSerializer
.readGradient(aGradient
);
1080 pAction
->SetRect(aRect
);
1081 pAction
->SetGradient(aGradient
);
1086 rtl::Reference
<MetaAction
> SvmReader::GradientExHandler()
1088 rtl::Reference
<MetaGradientExAction
> pAction(new MetaGradientExAction
);
1090 VersionCompatRead
aCompat(mrStream
);
1091 tools::PolyPolygon aPolyPoly
;
1092 ReadPolyPolygon(mrStream
, aPolyPoly
);
1093 TypeSerializer
aSerializer(mrStream
);
1095 aSerializer
.readGradient(aGradient
);
1097 pAction
->SetGradient(aGradient
);
1098 pAction
->SetPolyPolygon(aPolyPoly
);
1103 rtl::Reference
<MetaAction
> SvmReader::HatchHandler()
1105 rtl::Reference
<MetaHatchAction
> pAction(new MetaHatchAction
);
1107 VersionCompatRead
aCompat(mrStream
);
1108 tools::PolyPolygon aPolyPoly
;
1109 ReadPolyPolygon(mrStream
, aPolyPoly
);
1111 ReadHatch(mrStream
, aHatch
);
1113 pAction
->SetPolyPolygon(aPolyPoly
);
1114 pAction
->SetHatch(aHatch
);
1119 rtl::Reference
<MetaAction
> SvmReader::WallpaperHandler()
1121 rtl::Reference
<MetaWallpaperAction
> pAction(new MetaWallpaperAction
);
1123 VersionCompatRead
aCompat(mrStream
);
1124 Wallpaper aWallpaper
;
1125 ReadWallpaper(mrStream
, aWallpaper
);
1127 pAction
->SetWallpaper(aWallpaper
);
1132 rtl::Reference
<MetaAction
> SvmReader::ClipRegionHandler()
1134 rtl::Reference
<MetaClipRegionAction
> pAction(new MetaClipRegionAction
);
1136 VersionCompatRead
aCompat(mrStream
);
1137 vcl::Region aRegion
;
1138 ReadRegion(mrStream
, aRegion
);
1140 mrStream
.ReadCharAsBool(aClip
);
1142 pAction
->SetRegion(aRegion
);
1143 pAction
->SetClipping(aClip
);
1148 rtl::Reference
<MetaAction
> SvmReader::ISectRectClipRegionHandler()
1150 rtl::Reference
<MetaISectRectClipRegionAction
> pAction(new MetaISectRectClipRegionAction
);
1152 VersionCompatRead
aCompat(mrStream
);
1153 TypeSerializer
aSerializer(mrStream
);
1154 tools::Rectangle aRect
;
1155 aSerializer
.readRectangle(aRect
);
1157 pAction
->SetRect(aRect
);
1162 rtl::Reference
<MetaAction
> SvmReader::ISectRegionClipRegionHandler()
1164 rtl::Reference
<MetaISectRegionClipRegionAction
> pAction(new MetaISectRegionClipRegionAction
);
1166 VersionCompatRead
aCompat(mrStream
);
1167 vcl::Region aRegion
;
1168 ReadRegion(mrStream
, aRegion
);
1169 pAction
->SetRegion(aRegion
);
1174 rtl::Reference
<MetaAction
> SvmReader::MoveClipRegionHandler()
1176 rtl::Reference
<MetaMoveClipRegionAction
> pAction(new MetaMoveClipRegionAction
);
1178 VersionCompatRead
aCompat(mrStream
);
1179 sal_Int32
nTmpHM(0), nTmpVM(0);
1180 mrStream
.ReadInt32(nTmpHM
).ReadInt32(nTmpVM
);
1182 pAction
->SetHorzMove(nTmpHM
);
1183 pAction
->SetVertMove(nTmpVM
);
1188 rtl::Reference
<MetaAction
> SvmReader::TextColorHandler()
1190 rtl::Reference
<MetaTextColorAction
> pAction(new MetaTextColorAction
);
1192 VersionCompatRead
aCompat(mrStream
);
1196 pAction
->SetColor(aColor
);
1201 rtl::Reference
<MetaAction
> SvmReader::TextFillColorHandler()
1203 rtl::Reference
<MetaTextFillColorAction
> pAction(new MetaTextFillColorAction
);
1205 VersionCompatRead
aCompat(mrStream
);
1209 mrStream
.ReadCharAsBool(bSet
);
1211 pAction
->SetColor(aColor
);
1212 pAction
->SetSetting(bSet
);
1217 rtl::Reference
<MetaAction
> SvmReader::TextLineColorHandler()
1219 rtl::Reference
<MetaTextLineColorAction
> pAction(new MetaTextLineColorAction
);
1221 VersionCompatRead
aCompat(mrStream
);
1225 mrStream
.ReadCharAsBool(bSet
);
1227 pAction
->SetColor(aColor
);
1228 pAction
->SetSetting(bSet
);
1233 rtl::Reference
<MetaAction
> SvmReader::OverlineColorHandler()
1235 rtl::Reference
<MetaOverlineColorAction
> pAction(new MetaOverlineColorAction
);
1237 VersionCompatRead
aCompat(mrStream
);
1241 mrStream
.ReadCharAsBool(bSet
);
1243 pAction
->SetColor(aColor
);
1244 pAction
->SetSetting(bSet
);
1249 rtl::Reference
<MetaAction
> SvmReader::TextAlignHandler()
1251 rtl::Reference
<MetaTextAlignAction
> pAction(new MetaTextAlignAction
);
1253 VersionCompatRead
aCompat(mrStream
);
1254 sal_uInt16
nTmp16(0);
1255 mrStream
.ReadUInt16(nTmp16
);
1257 pAction
->SetTextAlign(static_cast<TextAlign
>(nTmp16
));
1262 rtl::Reference
<MetaAction
> SvmReader::MapModeHandler()
1264 VersionCompatRead
aCompat(mrStream
);
1265 TypeSerializer
aSerializer(mrStream
);
1268 const bool bSuccess
= aSerializer
.readMapMode(aMapMode
);
1272 rtl::Reference
<MetaMapModeAction
> pAction(new MetaMapModeAction
);
1273 pAction
->SetMapMode(aMapMode
);
1277 rtl::Reference
<MetaAction
> SvmReader::FontHandler(ImplMetaReadData
* pData
)
1279 rtl::Reference
<MetaFontAction
> pAction(new MetaFontAction
);
1281 VersionCompatRead
aCompat(mrStream
);
1283 ReadFont(mrStream
, aFont
);
1284 pData
->meActualCharSet
= aFont
.GetCharSet();
1285 if (pData
->meActualCharSet
== RTL_TEXTENCODING_DONTKNOW
)
1286 pData
->meActualCharSet
= osl_getThreadTextEncoding();
1288 pAction
->SetFont(aFont
);
1293 rtl::Reference
<MetaAction
> SvmReader::PushHandler()
1295 rtl::Reference
<MetaPushAction
> pAction(new MetaPushAction
);
1297 VersionCompatRead
aCompat(mrStream
);
1299 mrStream
.ReadUInt16(nTmp
);
1301 pAction
->SetPushFlags(static_cast<vcl::PushFlags
>(nTmp
));
1306 rtl::Reference
<MetaAction
> SvmReader::PopHandler()
1308 rtl::Reference
<MetaPopAction
> pAction(new MetaPopAction
);
1310 VersionCompatRead
aCompat(mrStream
);
1315 rtl::Reference
<MetaAction
> SvmReader::RasterOpHandler()
1317 rtl::Reference
<MetaRasterOpAction
> pAction(new MetaRasterOpAction
);
1319 sal_uInt16
nTmp16(0);
1321 VersionCompatRead
aCompat(mrStream
);
1322 mrStream
.ReadUInt16(nTmp16
);
1324 pAction
->SetRasterOp(static_cast<RasterOp
>(nTmp16
));
1329 rtl::Reference
<MetaAction
> SvmReader::TransparentHandler()
1331 rtl::Reference
<MetaTransparentAction
> pAction(new MetaTransparentAction
);
1333 VersionCompatRead
aCompat(mrStream
);
1334 tools::PolyPolygon aPolyPoly
;
1335 ReadPolyPolygon(mrStream
, aPolyPoly
);
1336 sal_uInt16
nTransPercent(0);
1337 mrStream
.ReadUInt16(nTransPercent
);
1339 pAction
->SetPolyPolygon(aPolyPoly
);
1340 pAction
->SetTransparence(nTransPercent
);
1345 rtl::Reference
<MetaAction
> SvmReader::FloatTransparentHandler(ImplMetaReadData
* pData
)
1347 rtl::Reference
<MetaFloatTransparentAction
> pAction(new MetaFloatTransparentAction
);
1349 VersionCompatRead
aCompat(mrStream
);
1351 SvmReader
aReader(mrStream
);
1352 aReader
.Read(aMtf
, pData
);
1353 TypeSerializer
aSerializer(mrStream
);
1355 aSerializer
.readPoint(aPoint
);
1358 aSerializer
.readSize(aSize
);
1361 aSerializer
.readGradient(aGradient
);
1363 pAction
->SetGDIMetaFile(aMtf
);
1364 pAction
->SetPoint(aPoint
);
1365 pAction
->SetSize(aSize
);
1366 pAction
->SetGradient(aGradient
);
1368 // tdf#155479 add support for MCGR and SVG export
1369 if (aCompat
.GetVersion() > 1)
1371 basegfx::BColorStops aColorStops
;
1373 double fOff
, fR
, fG
, fB
;
1374 mrStream
.ReadUInt16(nTmp
);
1376 const size_t nMaxPossibleEntries
= mrStream
.remainingSize() / 4 * sizeof(double);
1377 if (nTmp
> nMaxPossibleEntries
)
1379 SAL_WARN("vcl.gdi", "gradient record claims to have: " << nTmp
<< " entries, but only "
1380 << nMaxPossibleEntries
1381 << " possible, clamping");
1382 nTmp
= nMaxPossibleEntries
;
1385 for (sal_uInt16
a(0); a
< nTmp
; a
++)
1387 mrStream
.ReadDouble(fOff
);
1388 mrStream
.ReadDouble(fR
);
1389 mrStream
.ReadDouble(fG
);
1390 mrStream
.ReadDouble(fB
);
1392 aColorStops
.emplace_back(fOff
, basegfx::BColor(fR
, fG
, fB
));
1395 pAction
->addSVGTransparencyColorStops(aColorStops
);
1401 rtl::Reference
<MetaAction
> SvmReader::EPSHandler()
1403 rtl::Reference
<MetaEPSAction
> pAction(new MetaEPSAction
);
1405 VersionCompatRead
aCompat(mrStream
);
1406 TypeSerializer
aSerializer(mrStream
);
1408 aSerializer
.readGfxLink(aGfxLink
);
1410 aSerializer
.readPoint(aPoint
);
1412 aSerializer
.readSize(aSize
);
1416 pAction
->SetLink(aGfxLink
);
1417 pAction
->SetPoint(aPoint
);
1418 pAction
->SetSize(aSize
);
1419 pAction
->SetSubstitute(aSubst
);
1424 rtl::Reference
<MetaAction
> SvmReader::RefPointHandler()
1426 rtl::Reference
<MetaRefPointAction
> pAction(new MetaRefPointAction
);
1428 VersionCompatRead
aCompat(mrStream
);
1429 TypeSerializer
aSerializer(mrStream
);
1432 aSerializer
.readPoint(aRefPoint
);
1434 mrStream
.ReadCharAsBool(bSet
);
1436 pAction
->SetRefPoint(aRefPoint
);
1437 pAction
->SetSetting(bSet
);
1442 rtl::Reference
<MetaAction
> SvmReader::CommentHandler()
1444 rtl::Reference
<MetaCommentAction
> pAction(new MetaCommentAction
);
1446 VersionCompatRead
aCompat(mrStream
);
1448 aComment
= read_uInt16_lenPrefixed_uInt8s_ToOString(mrStream
);
1449 sal_Int32
nValue(0);
1450 sal_uInt32
nDataSize(0);
1451 mrStream
.ReadInt32(nValue
).ReadUInt32(nDataSize
);
1453 if (nDataSize
> mrStream
.remainingSize())
1455 SAL_WARN("vcl.gdi", "Parsing error: " << mrStream
.remainingSize() << " available data, but "
1456 << nDataSize
<< " claimed, truncating");
1457 nDataSize
= mrStream
.remainingSize();
1460 SAL_INFO("vcl.gdi", "MetaCommentAction::Read " << aComment
);
1462 std::unique_ptr
<sal_uInt8
[]> pData
;
1467 pData
.reset(new sal_uInt8
[nDataSize
]);
1468 mrStream
.ReadBytes(pData
.get(), nDataSize
);
1471 pAction
->SetComment(aComment
);
1472 pAction
->SetDataSize(nDataSize
);
1473 pAction
->SetValue(nValue
);
1474 pAction
->SetData(pData
.get(), nDataSize
);
1479 rtl::Reference
<MetaAction
> SvmReader::LayoutModeHandler()
1481 rtl::Reference
<MetaLayoutModeAction
> pAction(new MetaLayoutModeAction
);
1483 VersionCompatRead
aCompat(mrStream
);
1485 mrStream
.ReadUInt32(tmp
);
1487 pAction
->SetLayoutMode(static_cast<vcl::text::ComplexTextLayoutFlags
>(tmp
));
1492 rtl::Reference
<MetaAction
> SvmReader::TextLanguageHandler()
1494 rtl::Reference
<MetaTextLanguageAction
> pAction(new MetaTextLanguageAction
);
1496 VersionCompatRead
aCompat(mrStream
);
1497 sal_uInt16 nTmp
= 0;
1498 mrStream
.ReadUInt16(nTmp
);
1500 pAction
->SetTextLanguage(static_cast<LanguageType
>(nTmp
));
1505 rtl::Reference
<MetaAction
> SvmReader::DefaultHandler()
1507 return rtl::Reference
<MetaAction
>(new MetaAction
);
1509 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */