Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 192, column 9
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ios2met.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/filter/inc -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx

/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx

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 <osl/thread.h>
21#include <o3tl/safeint.hxx>
22#include <tools/poly.hxx>
23#include <tools/fract.hxx>
24#include <tools/stream.hxx>
25#include <sal/log.hxx>
26#include <vcl/graph.hxx>
27#include <vcl/dibtools.hxx>
28#include <vcl/virdev.hxx>
29#include <vcl/lineinfo.hxx>
30#include <vcl/gdimtf.hxx>
31
32#include <math.h>
33#include <memory>
34
35class FilterConfigItem;
36
37namespace {
38
39enum PenStyle { PEN_NULL, PEN_SOLID, PEN_DOT, PEN_DASH, PEN_DASHDOT };
40
41}
42
43// -----------------------------Field Types-------------------------------
44
45#define BegDocumnMagic0xA8A8 0xA8A8 /* Begin Document */
46#define EndDocumnMagic0xA8A9 0xA8A9 /* End Document */
47
48#define BegResGrpMagic0xC6A8 0xC6A8 /* Begin Resource Group */
49#define EndResGrpMagic0xC6A9 0xC6A9 /* End Resource Group */
50
51#define BegColAtrMagic0x77A8 0x77A8 /* Begin Color Attribute Table */
52#define EndColAtrMagic0x77A9 0x77A9 /* End Color Attribute Table */
53#define BlkColAtrMagic0x77B0 0x77B0 /* Color Attribute Table */
54#define MapColAtrMagic0x77AB 0x77AB /* Map Color Attribute Table */
55
56#define BegImgObjMagic0xFBA8 0xFBA8 /* Begin Image Object */
57#define EndImgObjMagic0xFBA9 0xFBA9 /* End Image Object */
58#define DscImgObjMagic0xFBA6 0xFBA6 /* Image Data Descriptor */
59#define DatImgObjMagic0xFBEE 0xFBEE /* Image Picture Data */
60
61#define BegObEnv1Magic0xC7A8 0xC7A8 /* Begin Object Environment Group */
62#define EndObEnv1Magic0xC7A9 0xC7A9 /* End Object Environment Group */
63
64#define BegGrfObjMagic0xBBA8 0xBBA8 /* Begin Graphics Object */
65#define EndGrfObjMagic0xBBA9 0xBBA9 /* End Graphics Object */
66#define DscGrfObjMagic0xBBA6 0xBBA6 /* Graphics Data Descriptor */
67#define DatGrfObjMagic0xBBEE 0xBBEE /* Graphics Data */
68
69#define MapCodFntMagic0x8AAB 0x8AAB /* Map Coded Font */
70#define MapDatResMagic0xC3AB 0xC3AB /* Map Data Resource */
71
72// -----------------------------Order Types-------------------------------
73
74#define GOrdGivArc0xC6 0xC6 /* 1 Arc at given position */
75#define GOrdCurArc0x86 0x86 /* 1 Arc at current position */
76#define GOrdGivBzr0xE5 0xE5 /* 1 Beziercurve at given position */
77#define GOrdCurBzr0xA5 0xA5 /* 1 Beziercurve at current position */
78#define GOrdGivBox0xC0 0xC0 /* 1 Box at given position */
79#define GOrdCurBox0x80 0x80 /* 1 Box at current position */
80#define GOrdGivFil0xC5 0xC5 /* 1 Fillet at given position */
81#define GOrdCurFil0x85 0x85 /* 1 Fillet at current position */
82#define GOrdGivCrc0xC7 0xC7 /* 1 Full arc (circle) at given position */
83#define GOrdCurCrc0x87 0x87 /* 1 Full arc (circle) at current position */
84#define GOrdGivLin0xC1 0xC1 /* 1 Line at given position */
85#define GOrdCurLin0x81 0x81 /* 1 Line at current position */
86#define GOrdGivMrk0xC2 0xC2 /* 1 Marker at given position */
87#define GOrdCurMrk0x82 0x82 /* 1 Marker at current position */
88#define GOrdGivArP0xE3 0xE3 /* 1 Partial arc at given position */
89#define GOrdCurArP0xA3 0xA3 /* 1 Partial arc at current position */
90#define GOrdGivRLn0xE1 0xE1 /* 1 Relative line at given position */
91#define GOrdCurRLn0xA1 0xA1 /* 1 Relative line at current position */
92#define GOrdGivSFl0xE4 0xE4 /* 1 Sharp fillet at given position */
93#define GOrdCurSFl0xA4 0xA4 /* 1 Sharp fillet at current position */
94
95#define GOrdGivStM0xF1 0xF1 /* 1 Character string move at given position */
96#define GOrdCurStM0xB1 0xB1 /* 1 Character string move at current position */
97#define GOrdGivStr0xC3 0xC3 /* 1 Character string at given position */
98#define GOrdCurStr0x83 0x83 /* 1 Character string at current position */
99#define GOrdGivStx0xFEF0 0xFEF0 /* 2 Character string extended at given position */
100#define GOrdCurStx0xFEB0 0xFEB0 /* 2 Character string extended at current position */
101
102#define GOrdGivImg0xD1 0xD1 /* 1 Begin Image at given position */
103#define GOrdCurImg0x91 0x91 /* 1 Begin Image at current position */
104#define GOrdImgDat0x92 0x92 /* 1 Image data */
105#define GOrdEndImg0x93 0x93 /* 1 End Image */
106#define GOrdBegAra0x68 0x68 /* 0 1 Begin area */
107#define GOrdEndAra0x60 0x60 /* 1 End area */
108#define GOrdBegElm0xD2 0xD2 /* 1 Begin element */
109#define GOrdEndElm0x49 0x49 /* 0 1 End element */
110
111#define GOrdBegPth0xD0 0xD0 /* 1 Begin path */
112#define GOrdEndPth0x7F 0x7F /* 0 1 End path */
113#define GOrdFilPth0xD7 0xD7 /* 1 Fill path */
114#define GOrdModPth0xD8 0xD8 /* 1 Modify path */
115#define GOrdOutPth0xD4 0xD4 /* 1 Outline path */
116#define GOrdSClPth0xB4 0xB4 /* 1 Set clip path */
117
118#define GOrdNopNop0x00 0x00 /* 0 0 No operation */
119#define GOrdRemark0x01 0x01 /* 1 Comment */
120#define GOrdSegLab0xD3 0xD3 /* 1 Label */
121#define GOrdBitBlt0xD6 0xD6 /* 1 Bitblt */
122#define GOrdCalSeg0x07 0x07 /* 1 Call Segment */
123#define GOrdSSgBnd0x32 0x32 /* 1 Set segment boundary */
124#define GOrdSegChr0x04 0x04 /* 1 Segment characteristics */
125#define GOrdCloFig0x7D 0x7D /* 0 1 Close Figure */
126#define GOrdEndSym0xFF 0xFF /* 0 0 End of symbol definition */
127#define GOrdEndPlg0x3E 0x3E /* 0 1 End prolog */
128#define GOrdEscape0xD5 0xD5 /* 1 Escape */
129#define GOrdExtEsc0xFED5 0xFED5 /* 2 Extended Escape */
130#define GOrdPolygn0xF3 0xF3 /* 2 Polygons */
131
132#define GOrdStkPop0x3F 0x3F /* 0 1 Pop */
133
134#define GOrdSIvAtr0x14 0x14 /* 1 Set individual attribute */
135#define GOrdPIvAtr0x54 0x54 /* 1 Push and set individual attribute */
136#define GOrdSColor0x0A 0x0A /* 0 1 Set color */
137#define GOrdPColor0x4A 0x4A /* 0 1 Push and set color */
138#define GOrdSIxCol0xA6 0xA6 /* 1 Set indexed color */
139#define GOrdPIxCol0xE6 0xE6 /* 1 Push and set indexed color */
140#define GOrdSXtCol0x26 0x26 /* 1 Set extended color */
141#define GOrdPXtCol0x66 0x66 /* 1 Push and set extended color */
142#define GOrdSBgCol0x25 0x25 /* 1 Set background color */
143#define GOrdPBgCol0x65 0x65 /* 1 Push and set background color */
144#define GOrdSBxCol0xA7 0xA7 /* 1 Set background indexed color */
145#define GOrdPBxCol0xE7 0xE7 /* 1 Push and set background indexed color */
146#define GOrdSMixMd0x0C 0x0C /* 0 1 Set mix */
147#define GOrdPMixMd0x4C 0x4C /* 0 1 Push and set mix */
148#define GOrdSBgMix0x0D 0x0D /* 0 1 Set background mix */
149#define GOrdPBgMix0x4D 0x4D /* 0 1 Push and set background mix */
150
151#define GOrdSPtSet0x08 0x08 /* 0 1 Set pattern set */
152#define GOrdPPtSet0x48 0x48 /* 0 1 Push and set pattern set */
153#define GOrdSPtSym0x28 0x28 /* 0 1 Set pattern symbol */
154#define GOrdPPtSym0x09 0x09 /* 0 1 Push and set pattern symbol */
155#define GOrdSPtRef0xA0 0xA0 /* 1 Set model pattern reference */
156#define GOrdPPtRef0xE0 0xE0 /* 1 Push and set pattern reference point */
157
158#define GOrdSLnEnd0x1A 0x1A /* 0 1 Set line end */
159#define GOrdPLnEnd0x5A 0x5A /* 0 1 Push and set line end */
160#define GOrdSLnJoi0x1B 0x1B /* 0 1 Set line join */
161#define GOrdPLnJoi0x5B 0x5B /* 0 1 Push and set line join */
162#define GOrdSLnTyp0x18 0x18 /* 0 1 Set line type */
163#define GOrdPLnTyp0x58 0x58 /* 0 1 Push and set line type */
164#define GOrdSLnWdt0x19 0x19 /* 0 1 Set line width */
165#define GOrdPLnWdt0x59 0x59 /* 0 1 Push and set line width */
166#define GOrdSFrLWd0x11 0x11 /* 1 Set fractional line width */
167#define GOrdPFrLWd0x51 0x51 /* 1 Push and set fractional line width */
168#define GOrdSStLWd0x15 0x15 /* 1 Set stroke line width */
169#define GOrdPStLWd0x55 0x55 /* 1 Push and set stroke line width */
170
171#define GOrdSChDir0x3A 0x3A /* 0 1 Set character direction */
172#define GOrdPChDir0x7A 0x7A /* 0 1 Push and set character direction */
173#define GOrdSChPrc0x39 0x39 /* 0 1 Set character precision */
174#define GOrdPChPrc0x79 0x79 /* 0 1 Push and set character precision */
175#define GOrdSChSet0x38 0x38 /* 0 1 Set character set */
176#define GOrdPChSet0x78 0x78 /* 0 1 Push and set character set */
177#define GOrdSChAng0x34 0x34 /* 1 Set character angle */
178#define GOrdPChAng0x74 0x74 /* 1 Push and set character angle */
179#define GOrdSChBrx0x05 0x05 /* 1 Set character break extra */
180#define GOrdPChBrx0x45 0x45 /* 1 Push and set character break extra */
181#define GOrdSChCel0x33 0x33 /* 1 Set character cell */
182#define GOrdPChCel0x03 0x03 /* 1 Push and set character cell */
183#define GOrdSChXtr0x17 0x17 /* 1 Set character extra */
184#define GOrdPChXtr0x57 0x57 /* 1 Push and set character extra */
185#define GOrdSChShr0x35 0x35 /* 1 Set character shear */
186#define GOrdPChShr0x75 0x75 /* 1 Push and set character shear */
187#define GOrdSTxAlg0x36 0x36 /* 0 2 Set text allingment */
188#define GOrdPTxAlg0x76 0x76 /* 0 2 Push and set text allingment */
189
190#define GOrdSMkPrc0x3B 0x3B /* 0 1 Set marker precision */
191#define GOrdPMkPrc0x7B 0x7B /* 0 1 Push and set marker precision */
192#define GOrdSMkSet0x3C 0x3C /* 0 1 Set marker set */
193#define GOrdPMkSet0x7C 0x7C /* 0 1 Push and set marker set */
194#define GOrdSMkSym0x29 0x29 /* 0 1 Set marker symbol */
195#define GOrdPMkSym0x69 0x69 /* 0 1 Push and set marker symbol */
196#define GOrdSMkCel0x37 0x37 /* 1 Set marker cell */
197#define GOrdPMkCel0x77 0x77 /* 1 Push and set marker cell */
198
199#define GOrdSArcPa0x22 0x22 /* 1 Set arc parameters */
200#define GOrdPArcPa0x62 0x62 /* 1 Push and set arc parameters */
201
202#define GOrdSCrPos0x21 0x21 /* 1 Set current position */
203#define GOrdPCrPos0x61 0x61 /* 1 Push and set current position */
204
205#define GOrdSMdTrn0x24 0x24 /* 1 Set model transform */
206#define GOrdPMdTrn0x64 0x64 /* 1 Push and set model transform */
207#define GOrdSPkIdn0x43 0x43 /* 1 Set pick identifier */
208#define GOrdPPkIdn0x23 0x23 /* 1 Push and set pick identifier */
209#define GOrdSVwTrn0x31 0x31 /* 1 Set viewing transform */
210#define GOrdSVwWin0x27 0x27 /* 1 Set viewing window */
211#define GOrdPVwWin0x67 0x67 /* 1 Push and set viewing window */
212
213//============================ OS2METReader ==================================
214
215namespace {
216
217struct OSPalette {
218 OSPalette * pSucc;
219 sal_uInt32 * p0RGB; // May be NULL!
220 size_t nSize;
221};
222
223struct OSArea {
224 OSArea * pSucc;
225 sal_uInt8 nFlags;
226 tools::PolyPolygon aPPoly;
227 bool bClosed;
228 Color aCol;
229 Color aBgCol;
230 RasterOp eMix;
231 RasterOp eBgMix;
232 bool bFill;
233};
234
235struct OSPath
236{
237 OSPath* pSucc;
238 sal_uInt32 nID;
239 tools::PolyPolygon aPPoly;
240 bool bClosed;
241 bool bStroke;
242};
243
244struct OSFont {
245 OSFont * pSucc;
246 sal_uInt32 nID;
247 vcl::Font aFont;
248};
249
250struct OSBitmap {
251 OSBitmap * pSucc;
252 sal_uInt32 nID;
253 BitmapEx aBitmapEx;
254
255 // required during reading of the bitmap:
256 SvStream * pBMP; // pointer to temporary Windows-BMP file or NULL
257 sal_uInt32 nWidth, nHeight;
258 sal_uInt16 nBitsPerPixel;
259 sal_uInt32 nMapPos;
260};
261
262struct OSAttr
263{
264 OSAttr * pSucc;
265 sal_uInt16 nPushOrder;
266 sal_uInt8 nIvAttrA, nIvAttrP; // special variables for the Order "GOrdPIvAtr"
267
268 Color aLinCol;
269 Color aLinBgCol;
270 RasterOp eLinMix;
271 RasterOp eLinBgMix;
272 Color aChrCol;
273 Color aChrBgCol;
274 RasterOp eChrMix;
275 RasterOp eChrBgMix;
276 Color aMrkCol;
277 Color aMrkBgCol;
278 RasterOp eMrkMix;
279 RasterOp eMrkBgMix;
280 Color aPatCol;
281 Color aPatBgCol;
282 RasterOp ePatMix;
283 RasterOp ePatBgMix;
284 Color aImgCol;
285 Color aImgBgCol;
286 RasterOp eImgMix;
287 RasterOp eImgBgMix;
288 sal_Int32 nArcP, nArcQ, nArcR, nArcS;
289 short nChrAng;
290 Size aChrCellSize;
291 sal_uInt32 nChrSet;
292 Point aCurPos;
293 PenStyle eLinStyle;
294 sal_uInt16 nLinWidth;
295 Size aMrkCellSize;
296 sal_uInt8 nMrkPrec;
297 sal_uInt8 nMrkSet;
298 sal_uInt8 nMrkSymbol;
299 bool bFill;
300 sal_uInt16 nStrLinWidth;
301
302 OSAttr()
303 : pSucc(nullptr)
304 , nPushOrder(0)
305 , nIvAttrA(0)
306 , nIvAttrP(0)
307 , eLinMix(RasterOp::OverPaint)
308 , eLinBgMix(RasterOp::OverPaint)
309 , eChrMix(RasterOp::OverPaint)
310 , eChrBgMix(RasterOp::OverPaint)
311 , eMrkMix(RasterOp::OverPaint)
312 , eMrkBgMix(RasterOp::OverPaint)
313 , ePatMix(RasterOp::OverPaint)
314 , ePatBgMix(RasterOp::OverPaint)
315 , eImgMix(RasterOp::OverPaint)
316 , eImgBgMix(RasterOp::OverPaint)
317 , nArcP(0)
318 , nArcQ(0)
319 , nArcR(0)
320 , nArcS(0)
321 , nChrAng(0)
322 , nChrSet(0)
323 , eLinStyle(PEN_NULL)
324 , nLinWidth(0)
325 , nMrkPrec(0)
326 , nMrkSet(0)
327 , nMrkSymbol(0)
328 , bFill(false)
329 , nStrLinWidth(0)
330 {
331 }
332};
333
334class OS2METReader {
335
336private:
337
338 int ErrorCode;
339
340 SvStream * pOS2MET; // the OS2MET file to be read
341 VclPtr<VirtualDevice> pVirDev; // here the drawing methods are being called
342 // While doing this a recording in the GDIMetaFile
343 // will take place.
344 tools::Rectangle aBoundingRect; // bounding rectangle as stored in the file
345 tools::Rectangle aCalcBndRect; // bounding rectangle calculated on our own
346 MapMode aGlobMapMode; // resolution of the picture
347 bool bCoord32;
348
349 OSPalette * pPaletteStack;
350
351 LineInfo aLineInfo;
352
353 OSArea * pAreaStack; // Areas that are being worked on
354
355 OSPath * pPathStack; // Paths that are being worked on
356 OSPath * pPathList; // finished Paths
357
358 OSFont * pFontList;
359
360 OSBitmap * pBitmapList;
361
362 OSAttr aDefAttr;
363 OSAttr aAttr;
364 OSAttr * pAttrStack;
365
366 std::unique_ptr<SvStream> xOrdFile;
367
368 void AddPointsToPath(const tools::Polygon & rPoly);
369 void AddPointsToArea(const tools::Polygon & rPoly);
370 void CloseFigure();
371 void PushAttr(sal_uInt16 nPushOrder);
372 void PopAttr();
373
374 void ChangeBrush( const Color& rPatColor, bool bFill );
375 void SetPen( const Color& rColor, sal_uInt16 nStrLinWidth = 0, PenStyle ePenStyle = PEN_SOLID );
376 void SetRasterOp(RasterOp eROP);
377
378 void SetPalette0RGB(sal_uInt16 nIndex, sal_uInt32 nCol);
379 sal_uInt32 GetPalette0RGB(sal_uInt32 nIndex);
380 // gets color from palette, or, if it doesn't exist,
381 // interprets nIndex as immediate RGB value.
382 Color GetPaletteColor(sal_uInt32 nIndex);
383
384
385 bool IsLineInfo() const;
386 void DrawPolyLine( const tools::Polygon& rPolygon );
387 void DrawPolygon( const tools::Polygon& rPolygon );
388 void DrawPolyPolygon( const tools::PolyPolygon& rPolygon );
389 sal_uInt16 ReadBigEndianWord();
390 sal_uInt32 ReadBigEndian3BytesLong();
391 sal_uInt32 ReadLittleEndian3BytesLong();
392 sal_Int32 ReadCoord(bool b32);
393 Point ReadPoint( const bool bAdjustBoundRect = true );
394 static RasterOp OS2MixToRasterOp(sal_uInt8 nMix);
395 void ReadLine(bool bGivenPos, sal_uInt16 nOrderLen);
396 void ReadRelLine(bool bGivenPos, sal_uInt16 nOrderLen);
397 void ReadBox(bool bGivenPos);
398 void ReadBitBlt();
399 void ReadChrStr(bool bGivenPos, bool bMove, bool bExtra, sal_uInt16 nOrderLen);
400 void ReadArc(bool bGivenPos);
401 void ReadFullArc(bool bGivenPos, sal_uInt16 nOrderSize);
402 void ReadPartialArc(bool bGivenPos, sal_uInt16 nOrderSize);
403 void ReadPolygons();
404 void ReadBezier(bool bGivenPos, sal_uInt16 nOrderLen);
405 void ReadFillet(bool bGivenPos, sal_uInt16 nOrderLen);
406 void ReadFilletSharp(bool bGivenPos, sal_uInt16 nOrderLen);
407 void ReadMarker(bool bGivenPos, sal_uInt16 nOrderLen);
408 void ReadOrder(sal_uInt16 nOrderID, sal_uInt16 nOrderLen);
409 void ReadDsc(sal_uInt16 nDscID);
410 void ReadImageData(sal_uInt16 nDataID, sal_uInt16 nDataLen);
411 void ReadFont(sal_uInt16 nFieldSize);
412 void ReadField(sal_uInt16 nFieldType, sal_uInt16 nFieldSize);
413
414public:
415
416 OS2METReader();
417 ~OS2METReader();
418
419 void ReadOS2MET( SvStream & rStreamOS2MET, GDIMetaFile & rGDIMetaFile );
420 // Reads from the stream an OS2MET file and fills up the GDIMetaFile
421
422};
423
424}
425
426//=================== Methods of OS2METReader ==============================
427
428OS2METReader::OS2METReader()
429 : ErrorCode(0)
430 , pOS2MET(nullptr)
431 , pVirDev(VclPtr<VirtualDevice>::Create())
432 , aBoundingRect()
433 , aCalcBndRect()
434 , aGlobMapMode()
435 , bCoord32(false)
436 , pPaletteStack(nullptr)
437 , aLineInfo()
438 , pAreaStack(nullptr)
439 , pPathStack(nullptr)
440 , pPathList(nullptr)
441 , pFontList(nullptr)
442 , pBitmapList(nullptr)
443 , aDefAttr()
444 , aAttr()
445 , pAttrStack(nullptr)
446{
447 pVirDev->EnableOutput(false);
448}
449
450OS2METReader::~OS2METReader()
451{
452 pVirDev.disposeAndClear();
3
Calling 'VclPtr::disposeAndClear'
453
454 while (pAreaStack!=nullptr) {
455 OSArea * p=pAreaStack;
456 pAreaStack=p->pSucc;
457 delete p;
458 }
459
460 while (pPathStack!=nullptr) {
461 OSPath * p=pPathStack;
462 pPathStack=p->pSucc;
463 delete p;
464 }
465
466 while (pPathList!=nullptr) {
467 OSPath * p=pPathList;
468 pPathList=p->pSucc;
469 delete p;
470 }
471
472 while (pFontList!=nullptr) {
473 OSFont * p=pFontList;
474 pFontList=p->pSucc;
475 delete p;
476 }
477
478 while (pBitmapList!=nullptr) {
479 OSBitmap * p=pBitmapList;
480 pBitmapList=p->pSucc;
481 delete p->pBMP;
482 delete p;
483 }
484
485 while (pAttrStack!=nullptr) {
486 OSAttr * p=pAttrStack;
487 pAttrStack=p->pSucc;
488 delete p;
489 }
490
491 while (pPaletteStack!=nullptr) {
492 OSPalette * p=pPaletteStack;
493 pPaletteStack=p->pSucc;
494 delete[] p->p0RGB;
495 delete p;
496 }
497}
498
499bool OS2METReader::IsLineInfo() const
500{
501 return ( ! ( aLineInfo.IsDefault() || ( aLineInfo.GetStyle() == LineStyle::NONE ) || ( pVirDev->GetLineColor() == COL_TRANSPARENT ) ) );
502}
503
504void OS2METReader::DrawPolyLine( const tools::Polygon& rPolygon )
505{
506 if ( aLineInfo.GetStyle() == LineStyle::Dash || ( aLineInfo.GetWidth() > 1 ) )
507 pVirDev->DrawPolyLine( rPolygon, aLineInfo );
508 else
509 pVirDev->DrawPolyLine( rPolygon );
510}
511
512void OS2METReader::DrawPolygon( const tools::Polygon& rPolygon )
513{
514 if ( IsLineInfo() )
515 {
516 pVirDev->Push( PushFlags::LINECOLOR );
517 pVirDev->SetLineColor( COL_TRANSPARENT );
518 pVirDev->DrawPolygon( rPolygon );
519 pVirDev->Pop();
520 pVirDev->DrawPolyLine( rPolygon, aLineInfo );
521 }
522 else
523 pVirDev->DrawPolygon( rPolygon );
524}
525
526void OS2METReader::DrawPolyPolygon( const tools::PolyPolygon& rPolyPolygon )
527{
528 if ( IsLineInfo() )
529 {
530 pVirDev->Push( PushFlags::LINECOLOR );
531 pVirDev->SetLineColor( COL_TRANSPARENT );
532 pVirDev->DrawPolyPolygon( rPolyPolygon );
533 pVirDev->Pop();
534 for ( sal_uInt16 i = 0; i < rPolyPolygon.Count(); i++ )
535 pVirDev->DrawPolyLine( rPolyPolygon.GetObject( i ), aLineInfo );
536 }
537 else
538 pVirDev->DrawPolyPolygon( rPolyPolygon );
539}
540
541void OS2METReader::AddPointsToArea(const tools::Polygon & rPoly)
542{
543 sal_uInt16 nOldSize, nNewSize,i;
544
545 if (pAreaStack==nullptr || rPoly.GetSize()==0) return;
546 tools::PolyPolygon * pPP=&(pAreaStack->aPPoly);
547 if (pPP->Count()==0 || pAreaStack->bClosed) pPP->Insert(rPoly);
548 else {
549 tools::Polygon aLastPoly(pPP->GetObject(pPP->Count()-1));
550 nOldSize=aLastPoly.GetSize();
551 if (nOldSize && aLastPoly.GetPoint(nOldSize-1)==rPoly.GetPoint(0)) nOldSize--;
552 nNewSize=nOldSize+rPoly.GetSize();
553 aLastPoly.SetSize(nNewSize);
554 for (i=nOldSize; i<nNewSize; i++) {
555 aLastPoly.SetPoint(rPoly.GetPoint(i-nOldSize),i);
556 }
557 pPP->Replace(aLastPoly,pPP->Count()-1);
558 }
559 pAreaStack->bClosed=false;
560}
561
562void OS2METReader::AddPointsToPath(const tools::Polygon & rPoly)
563{
564 sal_uInt16 nOldSize, nNewSize,i;
565
566 if (pPathStack==nullptr || rPoly.GetSize()==0) return;
567 tools::PolyPolygon * pPP=&(pPathStack->aPPoly);
568 if (pPP->Count()==0 /*|| pPathStack->bClosed==sal_True*/) pPP->Insert(rPoly);
569 else {
570 tools::Polygon aLastPoly(pPP->GetObject(pPP->Count()-1));
571 nOldSize=aLastPoly.GetSize();
572 if (nOldSize && aLastPoly.GetPoint(nOldSize-1)!=rPoly.GetPoint(0)) pPP->Insert(rPoly);
573 else {
574 nOldSize--;
575 nNewSize=nOldSize+rPoly.GetSize();
576 aLastPoly.SetSize(nNewSize);
577 for (i=nOldSize; i<nNewSize; i++) {
578 aLastPoly.SetPoint(rPoly.GetPoint(i-nOldSize),i);
579 }
580 pPP->Replace(aLastPoly,pPP->Count()-1);
581 }
582 }
583 pPathStack->bClosed=false;
584}
585
586void OS2METReader::CloseFigure()
587{
588 if (pAreaStack!=nullptr) pAreaStack->bClosed=true;
589 else if (pPathStack!=nullptr) pPathStack->bClosed=true;
590}
591
592void OS2METReader::PushAttr(sal_uInt16 nPushOrder)
593{
594 OSAttr * p;
595 p=new OSAttr;
596 *p=aAttr;
597 p->pSucc=pAttrStack; pAttrStack=p;
598 p->nPushOrder=nPushOrder;
599}
600
601void OS2METReader::PopAttr()
602{
603 OSAttr * p=pAttrStack;
604
605 if (p==nullptr) return;
606 switch (p->nPushOrder) {
607
608 case GOrdPIvAtr0x54:
609 switch (p->nIvAttrA) {
610 case 1: switch (p->nIvAttrP) {
611 case 1: aAttr.aLinCol=p->aLinCol; break;
612 case 2: aAttr.aChrCol=p->aChrCol; break;
613 case 3: aAttr.aMrkCol=p->aMrkCol; break;
614 case 4: aAttr.aPatCol=p->aPatCol; break;
615 case 5: aAttr.aImgCol=p->aImgCol; break;
616 } break;
617 case 2: switch (p->nIvAttrP) {
618 case 1: aAttr.aLinBgCol=p->aLinBgCol; break;
619 case 2: aAttr.aChrBgCol=p->aChrBgCol; break;
620 case 3: aAttr.aMrkBgCol=p->aMrkBgCol; break;
621 case 4: aAttr.aPatBgCol=p->aPatBgCol; break;
622 case 5: aAttr.aImgBgCol=p->aImgBgCol; break;
623 } break;
624 case 3: switch (p->nIvAttrP) {
625 case 1: aAttr.eLinMix=p->eLinMix; break;
626 case 2: aAttr.eChrMix=p->eChrMix; break;
627 case 3: aAttr.eMrkMix=p->eMrkMix; break;
628 case 4: aAttr.ePatMix=p->ePatMix; break;
629 case 5: aAttr.eImgMix=p->eImgMix; break;
630 } break;
631 case 4: switch (p->nIvAttrP) {
632 case 1: aAttr.eLinBgMix=p->eLinBgMix; break;
633 case 2: aAttr.eChrBgMix=p->eChrBgMix; break;
634 case 3: aAttr.eMrkBgMix=p->eMrkBgMix; break;
635 case 4: aAttr.ePatBgMix=p->ePatBgMix; break;
636 case 5: aAttr.eImgBgMix=p->eImgBgMix; break;
637 } break;
638 }
639 break;
640
641 case GOrdPLnTyp0x58: aAttr.eLinStyle=p->eLinStyle; break;
642
643 case GOrdPLnWdt0x59: aAttr.nLinWidth=p->nLinWidth; break;
644
645 case GOrdPStLWd0x55: aAttr.nStrLinWidth=p->nStrLinWidth; break;
646
647 case GOrdPChSet0x78: aAttr.nChrSet=p->nChrSet; break;
648
649 case GOrdPChAng0x74: aAttr.nChrAng=p->nChrAng; break;
650
651 case GOrdPMixMd0x4C:
652 aAttr.eLinMix=p->eLinMix;
653 aAttr.eChrMix=p->eChrMix;
654 aAttr.eMrkMix=p->eMrkMix;
655 aAttr.ePatMix=p->ePatMix;
656 aAttr.eImgMix=p->eImgMix;
657 break;
658
659 case GOrdPBgMix0x4D:
660 aAttr.eLinBgMix=p->eLinBgMix;
661 aAttr.eChrBgMix=p->eChrBgMix;
662 aAttr.eMrkBgMix=p->eMrkBgMix;
663 aAttr.ePatBgMix=p->ePatBgMix;
664 aAttr.eImgBgMix=p->eImgBgMix;
665 break;
666
667 case GOrdPPtSym0x09: aAttr.bFill = p->bFill; break;
668
669 case GOrdPColor0x4A:
670 case GOrdPIxCol0xE6:
671 case GOrdPXtCol0x66:
672 aAttr.aLinCol=p->aLinCol;
673 aAttr.aChrCol=p->aChrCol;
674 aAttr.aMrkCol=p->aMrkCol;
675 aAttr.aPatCol=p->aPatCol;
676 aAttr.aImgCol=p->aImgCol;
677 break;
678
679 case GOrdPBgCol0x65:
680 case GOrdPBxCol0xE7:
681 aAttr.aLinBgCol=p->aLinBgCol;
682 aAttr.aChrBgCol=p->aChrBgCol;
683 aAttr.aMrkBgCol=p->aMrkBgCol;
684 aAttr.aPatBgCol=p->aPatBgCol;
685 aAttr.aImgBgCol=p->aImgBgCol;
686 break;
687
688 case GOrdPMkPrc0x7B: aAttr.nMrkPrec=aDefAttr.nMrkPrec; break;
689
690 case GOrdPMkSet0x7C: aAttr.nMrkSet=aDefAttr.nMrkSet; break;
691
692 case GOrdPMkSym0x69: aAttr.nMrkSymbol=aDefAttr.nMrkSymbol; break;
693
694 case GOrdPMkCel0x77: aAttr.aMrkCellSize=aDefAttr.aMrkCellSize; break;
695
696 case GOrdPArcPa0x62:
697 aAttr.nArcP=p->nArcP; aAttr.nArcQ=p->nArcQ;
698 aAttr.nArcR=p->nArcR; aAttr.nArcS=p->nArcS;
699 break;
700
701 case GOrdPCrPos0x61:
702 aAttr.aCurPos=p->aCurPos;
703 break;
704 }
705 pAttrStack=p->pSucc;
706 delete p;
707}
708
709void OS2METReader::ChangeBrush(const Color& rPatColor, bool bFill )
710{
711 Color aColor;
712
713 if( bFill )
714 aColor = rPatColor;
715 else
716 aColor = COL_TRANSPARENT;
717
718 if( pVirDev->GetFillColor() != aColor )
719 pVirDev->SetFillColor( aColor );
720}
721
722void OS2METReader::SetPen( const Color& rColor, sal_uInt16 nLineWidth, PenStyle ePenStyle )
723{
724 LineStyle eLineStyle( LineStyle::Solid );
725
726 if ( pVirDev->GetLineColor() != rColor )
727 pVirDev->SetLineColor( rColor );
728 aLineInfo.SetWidth( nLineWidth );
729
730 sal_uInt16 nDotCount = 0;
731 sal_uInt16 nDashCount = 0;
732 switch ( ePenStyle )
733 {
734 case PEN_NULL :
735 eLineStyle = LineStyle::NONE;
736 break;
737 case PEN_DASHDOT :
738 nDashCount++;
739 [[fallthrough]];
740 case PEN_DOT :
741 nDotCount++;
742 nDashCount--;
743 [[fallthrough]];
744 case PEN_DASH :
745 nDashCount++;
746 aLineInfo.SetDotCount( nDotCount );
747 aLineInfo.SetDashCount( nDashCount );
748 aLineInfo.SetDistance( nLineWidth );
749 aLineInfo.SetDotLen( nLineWidth );
750 aLineInfo.SetDashLen( nLineWidth << 2 );
751 eLineStyle = LineStyle::Dash;
752 break;
753 case PEN_SOLID:
754 break; // -Wall not handled...
755 }
756 aLineInfo.SetStyle( eLineStyle );
757}
758
759void OS2METReader::SetRasterOp(RasterOp eROP)
760{
761 if (pVirDev->GetRasterOp()!=eROP) pVirDev->SetRasterOp(eROP);
762}
763
764void OS2METReader::SetPalette0RGB(sal_uInt16 nIndex, sal_uInt32 nCol)
765{
766 if (pPaletteStack==nullptr) {
767 pPaletteStack=new OSPalette;
768 pPaletteStack->pSucc=nullptr;
769 pPaletteStack->p0RGB=nullptr;
770 pPaletteStack->nSize=0;
771 }
772 if (pPaletteStack->p0RGB==nullptr || nIndex>=pPaletteStack->nSize) {
773 sal_uInt32 * pOld0RGB=pPaletteStack->p0RGB;
774 size_t nOldSize = pPaletteStack->nSize;
775 if (pOld0RGB==nullptr) nOldSize=0;
776 pPaletteStack->nSize=2*(nIndex+1);
777 if (pPaletteStack->nSize<256) pPaletteStack->nSize=256;
778 pPaletteStack->p0RGB = new sal_uInt32[pPaletteStack->nSize];
779 for (size_t i=0; i < pPaletteStack->nSize; ++i)
780 {
781 if (i<nOldSize) pPaletteStack->p0RGB[i]=pOld0RGB[i];
782 else if (i==0) pPaletteStack->p0RGB[i]=0x00ffffff;
783 else pPaletteStack->p0RGB[i]=0;
784 }
785 delete[] pOld0RGB;
786 }
787 pPaletteStack->p0RGB[nIndex]=nCol;
788}
789
790sal_uInt32 OS2METReader::GetPalette0RGB(sal_uInt32 nIndex)
791{
792 if (pPaletteStack!=nullptr && pPaletteStack->p0RGB!=nullptr &&
793 pPaletteStack->nSize>nIndex) nIndex=pPaletteStack->p0RGB[nIndex];
794 return nIndex;
795}
796
797Color OS2METReader::GetPaletteColor(sal_uInt32 nIndex)
798{
799 nIndex=GetPalette0RGB(nIndex);
800 return Color(sal::static_int_cast< sal_uInt8 >((nIndex>>16)&0xff),
801 sal::static_int_cast< sal_uInt8 >((nIndex>>8)&0xff),
802 sal::static_int_cast< sal_uInt8 >(nIndex&0xff));
803}
804
805sal_uInt16 OS2METReader::ReadBigEndianWord()
806{
807 sal_uInt8 nLo(0), nHi(0);
808 pOS2MET->ReadUChar( nHi ).ReadUChar( nLo );
809 return (static_cast<sal_uInt16>(nHi)<<8)|(static_cast<sal_uInt16>(nLo)&0x00ff);
810}
811
812sal_uInt32 OS2METReader::ReadBigEndian3BytesLong()
813{
814 sal_uInt8 nHi(0);
815 pOS2MET->ReadUChar( nHi );
816 sal_uInt16 nLo = ReadBigEndianWord();
817 return ((static_cast<sal_uInt32>(nHi)<<16)&0x00ff0000)|static_cast<sal_uInt32>(nLo);
818}
819
820sal_uInt32 OS2METReader::ReadLittleEndian3BytesLong()
821{
822 sal_uInt8 nHi,nMed,nLo;
823
824 pOS2MET->ReadUChar( nLo ).ReadUChar( nMed ).ReadUChar( nHi );
825 return ((static_cast<sal_uInt32>(nHi)&0xff)<<16)|((static_cast<sal_uInt32>(nMed)&0xff)<<8)|(static_cast<sal_uInt32>(nLo)&0xff);
826}
827
828sal_Int32 OS2METReader::ReadCoord(bool b32)
829{
830 sal_Int32 l(0);
831
832 if (b32) pOS2MET->ReadInt32( l );
833 else { short s(0); pOS2MET->ReadInt16( s ); l = static_cast<sal_Int32>(s); }
834 return l;
835}
836
837Point OS2METReader::ReadPoint( const bool bAdjustBoundRect )
838{
839 sal_Int32 x = ReadCoord(bCoord32);
840 sal_Int32 y = ReadCoord(bCoord32);
841 x=x-aBoundingRect.Left();
842 y=aBoundingRect.Bottom()-y;
843
844 if (bAdjustBoundRect)
845 {
846 if (x == SAL_MAX_INT32((sal_Int32) 0x7FFFFFFF) || y == SAL_MAX_INT32((sal_Int32) 0x7FFFFFFF))
847 pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERRORErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 21 ));
848 else
849 aCalcBndRect.Union(tools::Rectangle(x, y, x + 1, y + 1));
850 }
851
852 return Point(x,y);
853}
854
855RasterOp OS2METReader::OS2MixToRasterOp(sal_uInt8 nMix)
856{
857 switch (nMix) {
858 case 0x0c: return RasterOp::Invert;
859 case 0x04: return RasterOp::Xor;
860 case 0x0b: return RasterOp::Xor;
861 default: return RasterOp::OverPaint;
862 }
863}
864
865void OS2METReader::ReadLine(bool bGivenPos, sal_uInt16 nOrderLen)
866{
867 sal_uInt16 i,nPolySize;
868
869 if (bCoord32) nPolySize=nOrderLen/8; else nPolySize=nOrderLen/4;
870 if (!bGivenPos) nPolySize++;
871 if (nPolySize==0) return;
872 tools::Polygon aPolygon(nPolySize);
873 for (i=0; i<nPolySize; i++) {
874 if (i==0 && !bGivenPos) aPolygon.SetPoint(aAttr.aCurPos,i);
875 else aPolygon.SetPoint(ReadPoint(),i);
876 }
877 aAttr.aCurPos=aPolygon.GetPoint(nPolySize-1);
878 if (pAreaStack!=nullptr) AddPointsToArea(aPolygon);
879 else if (pPathStack!=nullptr) AddPointsToPath(aPolygon);
880 else
881 {
882 SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle );
883 SetRasterOp(aAttr.eLinMix);
884 DrawPolyLine( aPolygon );
885 }
886}
887
888void OS2METReader::ReadRelLine(bool bGivenPos, sal_uInt16 nOrderLen)
889{
890 sal_uInt16 i,nPolySize;
891 Point aP0;
892
893 if (bGivenPos) {
894 aP0=ReadPoint();
895 if (bCoord32) nOrderLen-=8; else nOrderLen-=4;
896 }
897 else aP0=aAttr.aCurPos;
898 if (nOrderLen > pOS2MET->remainingSize())
899 throw css::uno::Exception("attempt to read past end of input", nullptr);
900 nPolySize=nOrderLen/2;
901 if (nPolySize==0) return;
902 tools::Polygon aPolygon(nPolySize);
903 for (i=0; i<nPolySize; i++) {
904 sal_Int8 nsignedbyte;
905 pOS2MET->ReadSChar( nsignedbyte ); aP0.AdjustX(static_cast<sal_Int32>(nsignedbyte));
906 pOS2MET->ReadSChar( nsignedbyte ); aP0.AdjustY(-static_cast<sal_Int32>(nsignedbyte));
907 aCalcBndRect.Union(tools::Rectangle(aP0,Size(1,1)));
908 aPolygon.SetPoint(aP0,i);
909 }
910 aAttr.aCurPos=aPolygon.GetPoint(nPolySize-1);
911 if (pAreaStack!=nullptr) AddPointsToArea(aPolygon);
912 else if (pPathStack!=nullptr) AddPointsToPath(aPolygon);
913 else
914 {
915 SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle );
916 SetRasterOp(aAttr.eLinMix);
917 DrawPolyLine( aPolygon );
918 }
919}
920
921void OS2METReader::ReadBox(bool bGivenPos)
922{
923 sal_uInt8 nFlags;
924 Point P0;
925
926 pOS2MET->ReadUChar( nFlags );
927 pOS2MET->SeekRel(1);
928
929 if ( bGivenPos )
930 P0 = ReadPoint();
931 else
932 P0 = aAttr.aCurPos;
933
934 aAttr.aCurPos = ReadPoint();
935 sal_Int32 nHRound = ReadCoord(bCoord32);
936 sal_Int32 nVRound = ReadCoord(bCoord32);
937
938 tools::Rectangle aBoxRect( P0, aAttr.aCurPos );
939
940 if ( pAreaStack )
941 AddPointsToArea( tools::Polygon( aBoxRect ) );
942 else if ( pPathStack )
943 AddPointsToPath( tools::Polygon( aBoxRect ) );
944 else
945 {
946 if ( nFlags & 0x20 )
947 SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle );
948 else
949 SetPen( COL_TRANSPARENT );
950
951 if ( nFlags & 0x40 )
952 {
953 ChangeBrush(aAttr.aPatCol, aAttr.bFill);
954 SetRasterOp(aAttr.ePatMix);
955 }
956 else
957 {
958 ChangeBrush( COL_TRANSPARENT, false );
959 SetRasterOp(aAttr.eLinMix);
960 }
961
962 if ( IsLineInfo() )
963 {
964 tools::Polygon aPolygon( aBoxRect, nHRound, nVRound );
965 if ( nFlags & 0x40 )
966 {
967 pVirDev->Push( PushFlags::LINECOLOR );
968 pVirDev->SetLineColor( COL_TRANSPARENT );
969 pVirDev->DrawRect( aBoxRect, nHRound, nVRound );
970 pVirDev->Pop();
971 }
972 pVirDev->DrawPolyLine( aPolygon, aLineInfo );
973 }
974 else
975 pVirDev->DrawRect( aBoxRect, nHRound, nVRound );
976 }
977}
978
979void OS2METReader::ReadBitBlt()
980{
981 Point aP1,aP2;
982 Size aSize;
983 sal_uInt32 nID;
984 OSBitmap * pB;
985
986 pOS2MET->SeekRel(4);
987 pOS2MET->ReadUInt32( nID );
988 pOS2MET->SeekRel(4);
989 aP1=ReadPoint(); aP2=ReadPoint();
990 if (aP1.X() > aP2.X()) { auto nt=aP1.X(); aP1.setX(aP2.X() ); aP2.setX(nt ); }
991 if (aP1.Y() > aP2.Y()) { auto nt=aP1.Y(); aP1.setY(aP2.Y() ); aP2.setY(nt ); }
992 aSize=Size(aP2.X()-aP1.X(),aP2.Y()-aP1.Y());
993
994 pB=pBitmapList;
995 while (pB!=nullptr && pB->nID!=nID) pB=pB->pSucc;
996 if (pB!=nullptr) {
997 SetRasterOp(aAttr.ePatMix);
998 pVirDev->DrawBitmapEx(aP1,aSize,pB->aBitmapEx);
999 }
1000}
1001
1002void OS2METReader::ReadChrStr(bool bGivenPos, bool bMove, bool bExtra, sal_uInt16 nOrderLen)
1003{
1004 Point aP0;
1005 sal_uInt16 i, nLen;
1006 OSFont * pF;
1007 vcl::Font aFont;
1008 Size aSize;
1009
1010 pF = pFontList;
1011 while (pF!=nullptr && pF->nID!=aAttr.nChrSet) pF=pF->pSucc;
1012 if (pF!=nullptr)
1013 aFont = pF->aFont;
1014 aFont.SetColor(aAttr.aChrCol);
1015 aFont.SetFontSize(Size(0,aAttr.aChrCellSize.Height()));
1016 if ( aAttr.nChrAng != 0 )
1017 aFont.SetOrientation(aAttr.nChrAng);
1018
1019 if (bGivenPos)
1020 aP0 = ReadPoint();
1021 else
1022 aP0 = aAttr.aCurPos;
1023 if (bExtra)
1024 {
1025 pOS2MET->SeekRel(2);
1026 ReadPoint( false );
1027 ReadPoint( false );
1028 pOS2MET->ReadUInt16( nLen );
1029 }
1030 else
1031 {
1032 if ( !bGivenPos )
1033 nLen = nOrderLen;
1034 else if ( bCoord32 )
1035 nLen = nOrderLen-8;
1036 else
1037 nLen = nOrderLen-4;
1038 }
1039 if (nLen > pOS2MET->remainingSize())
1040 throw css::uno::Exception("attempt to read past end of input", nullptr);
1041 std::unique_ptr<char[]> pChr(new char[nLen+1]);
1042 for (i=0; i<nLen; i++)
1043 pOS2MET->ReadChar( pChr[i] );
1044 pChr[nLen] = 0;
1045 OUString aStr( pChr.get(), strlen(pChr.get()), osl_getThreadTextEncoding() );
1046 SetRasterOp(aAttr.eChrMix);
1047 if (pVirDev->GetFont()!=aFont)
1048 pVirDev->SetFont(aFont);
1049 pVirDev->DrawText(aP0,aStr);
1050
1051 aSize = Size( pVirDev->GetTextWidth(aStr), pVirDev->GetTextHeight() );
1052 if ( aAttr.nChrAng == 0 )
1053 {
1054 aCalcBndRect.Union(tools::Rectangle( Point(aP0.X(),aP0.Y()-aSize.Height()),
1055 Size(aSize.Width(),aSize.Height()*2)));
1056 if (bMove)
1057 aAttr.aCurPos = Point( aP0.X() + aSize.Width(), aP0.Y());
1058 }
1059 else
1060 {
1061 tools::Polygon aDummyPoly(4);
1062
1063 aDummyPoly.SetPoint( Point( aP0.X(), aP0.Y() ), 0); // TOP LEFT
1064 aDummyPoly.SetPoint( Point( aP0.X(), aP0.Y() - aSize.Height() ), 1); // BOTTOM LEFT
1065 aDummyPoly.SetPoint( Point( aP0.X() + aSize.Width(), aP0.Y() ), 2); // TOP RIGHT
1066 aDummyPoly.SetPoint( Point( aP0.X() + aSize.Width(), aP0.Y() - aSize.Height() ), 3);// BOTTOM RIGHT
1067 aDummyPoly.Rotate( aP0, aAttr.nChrAng );
1068 if ( bMove )
1069 aAttr.aCurPos = aDummyPoly.GetPoint( 0 );
1070 aCalcBndRect.Union( tools::Rectangle( aDummyPoly.GetPoint( 0 ), aDummyPoly.GetPoint( 3 ) ) );
1071 aCalcBndRect.Union( tools::Rectangle( aDummyPoly.GetPoint( 1 ), aDummyPoly.GetPoint( 2 ) ) );
1072 }
1073}
1074
1075void OS2METReader::ReadArc(bool bGivenPos)
1076{
1077 Point aP1, aP2, aP3;
1078 double x1,y1,x2,y2,x3,y3,p,q,cx,cy,ncx,ncy,r,rx,ry,w1,w3;
1079 if (bGivenPos) aP1=ReadPoint(); else aP1=aAttr.aCurPos;
1080 aP2=ReadPoint(); aP3=ReadPoint();
1081 aAttr.aCurPos=aP3;
1082 SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle );
1083 SetRasterOp(aAttr.eLinMix);
1084 // Ok, given are 3 point of the ellipse, and the relation
1085 // of width and height (as p to q):
1086 x1=aP1.X(); y1=aP1.Y();
1087 x2=aP2.X(); y2=aP2.Y();
1088 x3=aP3.X(); y3=aP3.Y();
1089 p=aAttr.nArcP;q=aAttr.nArcQ;
1090 // Calculation of the center point cx, cy of the ellipse:
1091 ncy=2*p*p*((y3-y1)*(x2-x1)-(y1-y2)*(x1-x3));
1092 ncx=2*q*q*(x2-x1);
1093 if ( (ncx<0.001 && ncx>-0.001) || (ncy<0.001 && ncy>-0.001) ) {
1094 // Calculation impossible, points are all on the same straight line
1095 pVirDev->DrawLine(aP1,aP2);
1096 pVirDev->DrawLine(aP2,aP3);
1097 return;
1098 }
1099 cy=( q*q*((x3*x3-x1*x1)*(x2-x1)+(x2*x2-x1*x1)*(x1-x3)) +
1100 p*p*((y3*y3-y1*y1)*(x2-x1)+(y2*y2-y1*y1)*(x1-x3)) ) / ncy;
1101 cx=( q*q*(x2*x2-x1*x1)+p*p*(y2*y2-y1*y1)+cy*2*p*p*(y1-y2) ) / ncx;
1102 // now we still need the radius in x and y direction:
1103 r=sqrt(q*q*(x1-cx)*(x1-cx)+p*p*(y1-cy)*(y1-cy));
1104 rx=r/q; ry=r/p;
1105 // We now have to find out how the starting and the end point
1106 // have to be chosen so that point no. 2 lies inside the drawn arc:
1107 w1=fmod((atan2(x1-cx,y1-cy)-atan2(x2-cx,y2-cy)),6.28318530718); if (w1<0) w1+=6.28318530718;
1108 w3=fmod((atan2(x3-cx,y3-cy)-atan2(x2-cx,y2-cy)),6.28318530718); if (w3<0) w3+=6.28318530718;
1109 if (w3<w1) {
1110 pVirDev->DrawArc(tools::Rectangle(static_cast<sal_Int32>(cx-rx),static_cast<sal_Int32>(cy-ry),
1111 static_cast<sal_Int32>(cx+rx),static_cast<sal_Int32>(cy+ry)),aP1,aP3);
1112 }
1113 else {
1114 pVirDev->DrawArc(tools::Rectangle(static_cast<sal_Int32>(cx-rx),static_cast<sal_Int32>(cy-ry),
1115 static_cast<sal_Int32>(cx+rx),static_cast<sal_Int32>(cy+ry)),aP3,aP1);
1116 }
1117}
1118
1119void OS2METReader::ReadFullArc(bool bGivenPos, sal_uInt16 nOrderSize)
1120{
1121 Point aCenter;
1122 tools::Rectangle aRect;
1123
1124 if (bGivenPos) {
1125 aCenter=ReadPoint();
1126 if (bCoord32) nOrderSize-=8; else nOrderSize-=4;
1127 }
1128 else aCenter=aAttr.aCurPos;
1129
1130 sal_Int32 nP = aAttr.nArcP;
1131 sal_Int32 nQ = aAttr.nArcQ;
1132 if (nP < 0)
1133 nP = o3tl::saturating_toggle_sign(nP);
1134 if (nQ < 0)
1135 nQ = o3tl::saturating_toggle_sign(nQ);
1136 sal_uInt32 nMul(0);
1137 if (nOrderSize>=4)
1138 pOS2MET->ReadUInt32( nMul );
1139 else {
1140 sal_uInt16 nMulS(0);
1141 pOS2MET->ReadUInt16( nMulS );
1142 nMul=static_cast<sal_uInt32>(nMulS)<<8;
1143 }
1144 if (nMul!=0x00010000) {
1145 nP=(nP*nMul)>>16;
1146 nQ=(nQ*nMul)>>16;
1147 }
1148
1149 aRect=tools::Rectangle(aCenter.X()-nP,aCenter.Y()-nQ,
1150 aCenter.X()+nP,aCenter.Y()+nQ);
1151 aCalcBndRect.Union(aRect);
1152
1153 if (pAreaStack!=nullptr) {
1154 ChangeBrush(aAttr.aPatCol, aAttr.bFill);
1155 SetRasterOp(aAttr.ePatMix);
1156 if ((pAreaStack->nFlags&0x40)!=0)
1157 SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle );
1158 else
1159 SetPen( COL_TRANSPARENT, 0, PEN_NULL );
1160 }
1161 else
1162 {
1163 SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle );
1164 ChangeBrush(COL_TRANSPARENT, false);
1165 SetRasterOp(aAttr.eLinMix);
1166 }
1167 pVirDev->DrawEllipse(aRect);
1168}
1169
1170void OS2METReader::ReadPartialArc(bool bGivenPos, sal_uInt16 nOrderSize)
1171{
1172 Point aP0, aCenter,aPStart,aPEnd;
1173 tools::Rectangle aRect;
1174
1175 if (bGivenPos) {
1176 aP0=ReadPoint();
1177 if (bCoord32) nOrderSize-=8; else nOrderSize-=4;
1178 }
1179 else aP0=aAttr.aCurPos;
1180 aCenter=ReadPoint();
1181
1182 sal_Int32 nP = aAttr.nArcP;
1183 sal_Int32 nQ = aAttr.nArcQ;
1184 if (nP < 0)
1185 nP = o3tl::saturating_toggle_sign(nP);
1186 if (nQ < 0)
1187 nQ = o3tl::saturating_toggle_sign(nQ);
1188 sal_uInt32 nMul(0);
1189 if (nOrderSize>=12)
1190 pOS2MET->ReadUInt32( nMul );
1191 else {
1192 sal_uInt16 nMulS(0);
1193 pOS2MET->ReadUInt16( nMulS );
1194 nMul=static_cast<sal_uInt32>(nMulS)<<8;
1195 }
1196 if (nMul!=0x00010000) {
1197 nP=(nP*nMul)>>16;
1198 nQ=(nQ*nMul)>>16;
1199 }
1200
1201 sal_Int32 nStart(0), nSweep(0);
1202 pOS2MET->ReadInt32( nStart ).ReadInt32( nSweep );
1203 double fStart = static_cast<double>(nStart)/65536.0/180.0*3.14159265359;
1204 double fEnd = fStart+ static_cast<double>(nSweep)/65536.0/180.0*3.14159265359;
1205 aPStart=Point(aCenter.X()+static_cast<sal_Int32>( cos(fStart)*nP),
1206 aCenter.Y()+static_cast<sal_Int32>(-sin(fStart)*nQ));
1207 aPEnd= Point(aCenter.X()+static_cast<sal_Int32>( cos(fEnd)*nP),
1208 aCenter.Y()+static_cast<sal_Int32>(-sin(fEnd)*nQ));
1209
1210 aRect=tools::Rectangle(aCenter.X()-nP,aCenter.Y()-nQ,
1211 aCenter.X()+nP,aCenter.Y()+nQ);
1212 aCalcBndRect.Union(aRect);
1213
1214 SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle );
1215 SetRasterOp(aAttr.eLinMix);
1216
1217 pVirDev->DrawLine(aP0,aPStart);
1218 pVirDev->DrawArc(aRect,aPStart,aPEnd);
1219 aAttr.aCurPos=aPEnd;
1220}
1221
1222void OS2METReader::ReadPolygons()
1223{
1224 tools::PolyPolygon aPolyPoly;
1225 tools::Polygon aPoly;
1226 Point aPoint;
1227
1228 sal_uInt8 nFlags(0);
1229 sal_uInt32 nNumPolys(0);
1230 pOS2MET->ReadUChar(nFlags).ReadUInt32(nNumPolys);
1231
1232 if (nNumPolys > SAL_MAX_UINT16((sal_uInt16) 0xFFFF))
1233 {
1234 pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERRORErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 21 ));
1235 ErrorCode=11;
1236 return;
1237 }
1238
1239 for (sal_uInt32 i=0; i<nNumPolys; ++i)
1240 {
1241 sal_uInt32 nNumPoints(0);
1242 pOS2MET->ReadUInt32(nNumPoints);
1243 sal_uInt32 nLimit = SAL_MAX_UINT16((sal_uInt16) 0xFFFF);
1244 if (i==0) --nLimit;
1245 if (nNumPoints > nLimit)
1246 {
1247 pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERRORErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 21 ));
1248 ErrorCode=11;
1249 return;
1250 }
1251 if (i==0) ++nNumPoints;
1252 aPoly.SetSize(static_cast<short>(nNumPoints));
1253 for (sal_uInt32 j=0; j<nNumPoints; ++j)
1254 {
1255 if (i==0 && j==0) aPoint=aAttr.aCurPos;
1256 else aPoint=ReadPoint();
1257 aPoly.SetPoint(aPoint,static_cast<short>(j));
1258 if (i==nNumPolys-1 && j==nNumPoints-1) aAttr.aCurPos=aPoint;
1259 }
1260 aPolyPoly.Insert(aPoly);
1261 }
1262
1263 ChangeBrush(aAttr.aPatCol, aAttr.bFill);
1264 SetRasterOp(aAttr.ePatMix);
1265 if ((nFlags&0x01)!=0)
1266 SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle );
1267 else
1268 SetPen( COL_TRANSPARENT, 0, PEN_NULL );
1269 DrawPolyPolygon( aPolyPoly );
1270}
1271
1272void OS2METReader::ReadBezier(bool bGivenPos, sal_uInt16 nOrderLen)
1273{
1274 sal_uInt16 i, nNumPoints = nOrderLen / ( bCoord32 ? 8 : 4 );
1275
1276 if( !bGivenPos )
1277 nNumPoints++;
1278
1279 if( !nNumPoints )
1280 return;
1281
1282 tools::Polygon aPolygon( nNumPoints );
1283
1284 for( i=0; i < nNumPoints; i++ )
1285 {
1286 if( i==0 && !bGivenPos)
1287 aPolygon.SetPoint( aAttr.aCurPos, i );
1288 else
1289 aPolygon.SetPoint( ReadPoint(), i );
1290 }
1291
1292 if( !( nNumPoints % 4 ) )
1293 {
1294 // create bezier polygon
1295 const sal_uInt16 nSegPoints = 25;
1296 const sal_uInt16 nSegments = aPolygon.GetSize() >> 2;
1297 tools::Polygon aBezPoly( nSegments * nSegPoints );
1298
1299 sal_uInt16 nSeg, nBezPos, nStartPos;
1300 for( nSeg = 0, nBezPos = 0, nStartPos = 0; nSeg < nSegments; nSeg++, nStartPos += 4 )
1301 {
1302 const tools::Polygon aSegPoly( aPolygon[ nStartPos ], aPolygon[ nStartPos + 1 ],
1303 aPolygon[ nStartPos + 3 ], aPolygon[ nStartPos + 2 ],
1304 nSegPoints );
1305
1306 for( sal_uInt16 nSegPos = 0; nSegPos < nSegPoints; )
1307 aBezPoly[ nBezPos++ ] = aSegPoly[ nSegPos++ ];
1308 }
1309
1310 nNumPoints = nBezPos;
1311
1312 if( nNumPoints != aBezPoly.GetSize() )
1313 aBezPoly.SetSize( nNumPoints );
1314
1315 aPolygon = aBezPoly;
1316 }
1317
1318 aAttr.aCurPos = aPolygon[ nNumPoints - 1 ];
1319
1320 if (pAreaStack!=nullptr)
1321 AddPointsToArea(aPolygon);
1322 else if (pPathStack!=nullptr)
1323 AddPointsToPath(aPolygon);
1324 else
1325 {
1326 SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle );
1327 SetRasterOp(aAttr.eLinMix);
1328 DrawPolyLine( aPolygon );
1329 }
1330}
1331
1332void OS2METReader::ReadFillet(bool bGivenPos, sal_uInt16 nOrderLen)
1333{
1334 sal_uInt16 i,nNumPoints;
1335
1336 if (bCoord32) nNumPoints=nOrderLen/8; else nNumPoints=nOrderLen/4;
1337 if (!bGivenPos) nNumPoints++;
1338 if (nNumPoints==0) return;
1339 tools::Polygon aPolygon(nNumPoints);
1340 for (i=0; i<nNumPoints; i++) {
1341 if (i==0 && !bGivenPos) aPolygon.SetPoint(aAttr.aCurPos,i);
1342 else aPolygon.SetPoint(ReadPoint(),i);
1343 }
1344 aAttr.aCurPos=aPolygon.GetPoint(nNumPoints-1);
1345 if (pAreaStack!=nullptr) AddPointsToArea(aPolygon);
1346 else if (pPathStack!=nullptr) AddPointsToPath(aPolygon);
1347 else {
1348 SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle );
1349 SetRasterOp(aAttr.eLinMix);
1350 DrawPolyLine( aPolygon );
1351 }
1352}
1353
1354void OS2METReader::ReadFilletSharp(bool bGivenPos, sal_uInt16 nOrderLen)
1355{
1356 sal_uInt16 i,nNumPoints;
1357
1358 if (bGivenPos) {
1359 aAttr.aCurPos=ReadPoint();
1360 if (bCoord32) nOrderLen-=8; else nOrderLen-=4;
1361 }
1362 if (bCoord32) nNumPoints=1+nOrderLen/10;
1363 else nNumPoints=1+nOrderLen/6;
1364 tools::Polygon aPolygon(nNumPoints);
1365 aPolygon.SetPoint(aAttr.aCurPos,0);
1366 for (i=1; i<nNumPoints; i++) aPolygon.SetPoint(ReadPoint(),i);
1367 aAttr.aCurPos=aPolygon.GetPoint(nNumPoints-1);
1368 if (pAreaStack!=nullptr) AddPointsToArea(aPolygon);
1369 else if (pPathStack!=nullptr) AddPointsToPath(aPolygon);
1370 else
1371 {
1372 SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle );
1373 SetRasterOp(aAttr.eLinMix);
1374 DrawPolyLine( aPolygon );
1375 }
1376}
1377
1378void OS2METReader::ReadMarker(bool bGivenPos, sal_uInt16 nOrderLen)
1379{
1380 sal_uInt16 i,nNumPoints;
1381
1382 SetPen( aAttr.aMrkCol );
1383 SetRasterOp(aAttr.eMrkMix);
1384 if (aAttr.nMrkSymbol>=5 && aAttr.nMrkSymbol<=9)
1385 {
1386 ChangeBrush(aAttr.aMrkCol, true);
1387 }
1388 else
1389 {
1390 ChangeBrush(COL_TRANSPARENT, false);
1391 }
1392 if (bCoord32) nNumPoints=nOrderLen/8; else nNumPoints=nOrderLen/4;
1393 if (!bGivenPos) nNumPoints++;
1394 for (i=0; i<nNumPoints; i++) {
1395 if (i!=0 || bGivenPos) aAttr.aCurPos=ReadPoint();
1396 const auto x = aAttr.aCurPos.X();
1397 const auto y = aAttr.aCurPos.Y();
1398 aCalcBndRect.Union(tools::Rectangle(x-5,y-5,x+5,y+5));
1399 switch (aAttr.nMrkSymbol) {
1400 case 2: // PLUS
1401 pVirDev->DrawLine(Point(x-4,y),Point(x+4,y));
1402 pVirDev->DrawLine(Point(x,y-4),Point(x,y+4));
1403 break;
1404 case 3: // DIAMOND
1405 case 7: { // SOLIDDIAMOND
1406 tools::Polygon aPoly(4);
1407 aPoly.SetPoint(Point(x,y+4),0);
1408 aPoly.SetPoint(Point(x+4,y),1);
1409 aPoly.SetPoint(Point(x,y-4),2);
1410 aPoly.SetPoint(Point(x-4,y),3);
1411 pVirDev->DrawPolygon(aPoly);
1412 break;
1413 }
1414 case 4: // SQUARE
1415 case 8: { // SOLIDSUARE
1416 tools::Polygon aPoly(4);
1417 aPoly.SetPoint(Point(x+4,y+4),0);
1418 aPoly.SetPoint(Point(x+4,y-4),1);
1419 aPoly.SetPoint(Point(x-4,y-4),2);
1420 aPoly.SetPoint(Point(x-4,y+4),3);
1421 pVirDev->DrawPolygon(aPoly);
1422 break;
1423 }
1424 case 5: { // SIXPOINTSTAR
1425 tools::Polygon aPoly(12);
1426 aPoly.SetPoint(Point(x ,y-4),0);
1427 aPoly.SetPoint(Point(x+2,y-2),1);
1428 aPoly.SetPoint(Point(x+4,y-2),2);
1429 aPoly.SetPoint(Point(x+2,y ),3);
1430 aPoly.SetPoint(Point(x+4,y+2),4);
1431 aPoly.SetPoint(Point(x+2,y+2),5);
1432 aPoly.SetPoint(Point(x ,y+4),6);
1433 aPoly.SetPoint(Point(x-2,y+2),7);
1434 aPoly.SetPoint(Point(x-4,y+2),8);
1435 aPoly.SetPoint(Point(x-2,y ),9);
1436 aPoly.SetPoint(Point(x-4,y-2),10);
1437 aPoly.SetPoint(Point(x-2,y-2),11);
1438 pVirDev->DrawPolygon(aPoly);
1439 break;
1440 }
1441 case 6: { // EIGHTPOINTSTAR
1442 tools::Polygon aPoly(16);
1443 aPoly.SetPoint(Point(x ,y-4),0);
1444 aPoly.SetPoint(Point(x+1,y-2),1);
1445 aPoly.SetPoint(Point(x+3,y-3),2);
1446 aPoly.SetPoint(Point(x+2,y-1),3);
1447 aPoly.SetPoint(Point(x+4,y ),4);
1448 aPoly.SetPoint(Point(x+2,y+1),5);
1449 aPoly.SetPoint(Point(x+3,y+3),6);
1450 aPoly.SetPoint(Point(x+1,y+2),7);
1451 aPoly.SetPoint(Point(x ,y+4),8);
1452 aPoly.SetPoint(Point(x-1,y+2),9);
1453 aPoly.SetPoint(Point(x-3,y+3),10);
1454 aPoly.SetPoint(Point(x-2,y+1),11);
1455 aPoly.SetPoint(Point(x-4,y ),12);
1456 aPoly.SetPoint(Point(x-2,y-1),13);
1457 aPoly.SetPoint(Point(x-3,y-3),14);
1458 aPoly.SetPoint(Point(x-1,y-2),15);
1459 pVirDev->DrawPolygon(aPoly);
1460 break;
1461 }
1462 case 9: // DOT
1463 pVirDev->DrawEllipse(tools::Rectangle(x-1,y-1,x+1,y+1));
1464 break;
1465 case 10: // SMALLCIRCLE
1466 pVirDev->DrawEllipse(tools::Rectangle(x-2,y-2,x+2,y+2));
1467 break;
1468 case 64: // BLANK
1469 break;
1470 default: // (=1) CROSS
1471 pVirDev->DrawLine(Point(x-4,y-4),Point(x+4,y+4));
1472 pVirDev->DrawLine(Point(x-4,y+4),Point(x+4,y-4));
1473 break;
1474 }
1475 }
1476}
1477
1478void OS2METReader::ReadOrder(sal_uInt16 nOrderID, sal_uInt16 nOrderLen)
1479{
1480 switch (nOrderID) {
1481
1482 case GOrdGivArc0xC6: ReadArc(true); break;
1483 case GOrdCurArc0x86: ReadArc(false); break;
1484
1485 case GOrdGivBzr0xE5: ReadBezier(true,nOrderLen); break;
1486 case GOrdCurBzr0xA5: ReadBezier(false,nOrderLen); break;
1487
1488 case GOrdGivBox0xC0: ReadBox(true); break;
1489 case GOrdCurBox0x80: ReadBox(false); break;
1490
1491 case GOrdGivFil0xC5: ReadFillet(true,nOrderLen); break;
1492 case GOrdCurFil0x85: ReadFillet(false,nOrderLen); break;
1493
1494 case GOrdGivCrc0xC7: ReadFullArc(true,nOrderLen); break;
1495 case GOrdCurCrc0x87: ReadFullArc(false,nOrderLen); break;
1496
1497 case GOrdGivLin0xC1: ReadLine(true, nOrderLen); break;
1498 case GOrdCurLin0x81: ReadLine(false, nOrderLen); break;
1499
1500 case GOrdGivMrk0xC2: ReadMarker(true, nOrderLen); break;
1501 case GOrdCurMrk0x82: ReadMarker(false, nOrderLen); break;
1502
1503 case GOrdGivArP0xE3: ReadPartialArc(true,nOrderLen); break;
1504 case GOrdCurArP0xA3: ReadPartialArc(false,nOrderLen); break;
1505
1506 case GOrdGivRLn0xE1: ReadRelLine(true,nOrderLen); break;
1507 case GOrdCurRLn0xA1: ReadRelLine(false,nOrderLen); break;
1508
1509 case GOrdGivSFl0xE4: ReadFilletSharp(true,nOrderLen); break;
1510 case GOrdCurSFl0xA4: ReadFilletSharp(false,nOrderLen); break;
1511
1512 case GOrdGivStM0xF1: ReadChrStr(true , true , false, nOrderLen); break;
1513 case GOrdCurStM0xB1: ReadChrStr(false, true , false, nOrderLen); break;
1514 case GOrdGivStr0xC3: ReadChrStr(true , false, false, nOrderLen); break;
1515 case GOrdCurStr0x83: ReadChrStr(false, false, false, nOrderLen); break;
1516 case GOrdGivStx0xFEF0: ReadChrStr(true , false, true , nOrderLen); break;
1517 case GOrdCurStx0xFEB0: ReadChrStr(false, false, true , nOrderLen); break;
1518
1519 case GOrdGivImg0xD1: SAL_INFO("filter.os2met","GOrdGivImg")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdGivImg") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1519" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdGivImg"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdGivImg"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1519" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdGivImg") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1519" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdGivImg"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdGivImg"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1519" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1520 break;
1521 case GOrdCurImg0x91: SAL_INFO("filter.os2met","GOrdCurImg")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdCurImg") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1521" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdCurImg"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdCurImg"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1521" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdCurImg") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1521" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdCurImg"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdCurImg"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1521" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1522 break;
1523 case GOrdImgDat0x92: SAL_INFO("filter.os2met","GOrdImgDat")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdImgDat") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1523" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdImgDat"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdImgDat"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1523" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdImgDat") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1523" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdImgDat"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdImgDat"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1523" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1524 break;
1525 case GOrdEndImg0x93: SAL_INFO("filter.os2met","GOrdEndImg")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdEndImg") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1525" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdEndImg"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdEndImg"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1525" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdEndImg") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1525" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdEndImg"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdEndImg"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1525" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1526 break;
1527
1528 case GOrdBegAra0x68: {
1529 OSArea * p=new OSArea;
1530 p->bClosed=false;
1531 p->pSucc=pAreaStack; pAreaStack=p;
1532 pOS2MET->ReadUChar( p->nFlags );
1533 p->aCol=aAttr.aPatCol;
1534 p->aBgCol=aAttr.aPatBgCol;
1535 p->eMix=aAttr.ePatMix;
1536 p->eBgMix=aAttr.ePatBgMix;
1537 p->bFill=aAttr.bFill;
1538 break;
1539 }
1540 case GOrdEndAra0x60:
1541 {
1542 OSArea * p=pAreaStack;
1543 if ( p )
1544 {
1545 pAreaStack = p->pSucc;
1546 if ( pPathStack )
1547 {
1548 for ( sal_uInt16 i=0; i<p->aPPoly.Count(); i++ )
1549 {
1550 AddPointsToPath( p->aPPoly.GetObject( i ) );
1551 CloseFigure();
1552 }
1553 }
1554 else
1555 {
1556 if ( ( p->nFlags & 0x40 ) == 0 )
1557 SetPen( COL_TRANSPARENT, 0, PEN_NULL );
1558 else
1559 SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle );
1560
1561 ChangeBrush(p->aCol, p->bFill);
1562 SetRasterOp(p->eMix);
1563 DrawPolyPolygon( p->aPPoly );
1564 }
1565 delete p;
1566 }
1567 }
1568 break;
1569
1570 case GOrdBegElm0xD2: SAL_INFO("filter.os2met","GOrdBegElm")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdBegElm") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1570" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdBegElm"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdBegElm"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1570" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdBegElm") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1570" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdBegElm"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdBegElm"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1570" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1571 break;
1572 case GOrdEndElm0x49: SAL_INFO("filter.os2met","GOrdEndElm")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdEndElm") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1572" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdEndElm"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdEndElm"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1572" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdEndElm") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1572" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdEndElm"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdEndElm"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1572" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1573 break;
1574
1575 case GOrdBegPth0xD0: {
1576 OSPath * p=new OSPath;
1577 p->pSucc=pPathStack; pPathStack=p;
1578 pOS2MET->SeekRel(2);
1579 pOS2MET->ReadUInt32( p->nID );
1580 p->bClosed=false;
1581 p->bStroke=false;
1582 break;
1583 }
1584 case GOrdEndPth0x7F: {
1585 OSPath * p, * pprev, * psucc;
1586 if (pPathStack==nullptr) break;
1587 p=pPathList; pprev=nullptr;
1588 while (p!=nullptr) {
1589 psucc=p->pSucc;
1590 if (p->nID==pPathStack->nID) {
1591 if (pprev==nullptr) pPathList=psucc; else pprev->pSucc=psucc;
1592 delete p;
1593 }
1594 else pprev=p;
1595 p=psucc;
1596 }
1597 p=pPathStack;
1598 pPathStack=p->pSucc;
1599 p->pSucc=pPathList; pPathList=p;
1600 break;
1601 }
1602 case GOrdFilPth0xD7:
1603 {
1604 sal_uInt32 nID;
1605 sal_uInt16 nDummy;
1606 OSPath* p = pPathList;
1607
1608 pOS2MET->ReadUInt16( nDummy )
1609 .ReadUInt32( nID );
1610
1611 if ( ! ( nDummy & 0x20 ) ) // #30933# i do not know the exact meaning of this bit,
1612 { // but if set it seems to be better not to fill this path
1613 while( p && p->nID != nID )
1614 p = p->pSucc;
1615
1616 if( p )
1617 {
1618 if( p->bStroke )
1619 {
1620 SetPen( aAttr.aPatCol, aAttr.nStrLinWidth );
1621 ChangeBrush(COL_TRANSPARENT, false);
1622 SetRasterOp( aAttr.ePatMix );
1623 if ( IsLineInfo() )
1624 {
1625 for ( sal_uInt16 i = 0; i < p->aPPoly.Count(); i++ )
1626 pVirDev->DrawPolyLine( p->aPPoly.GetObject( i ), aLineInfo );
1627 }
1628 else
1629 pVirDev->DrawPolyPolygon( p->aPPoly );
1630 }
1631 else
1632 {
1633 SetPen( COL_TRANSPARENT, 0, PEN_NULL );
1634 ChangeBrush( aAttr.aPatCol, aAttr.bFill );
1635 SetRasterOp( aAttr.ePatMix );
1636 pVirDev->DrawPolyPolygon( p->aPPoly );
1637 }
1638 }
1639 }
1640 }
1641 break;
1642
1643 case GOrdModPth0xD8:
1644 {
1645 OSPath* p = pPathList;
1646
1647 while( p && p->nID != 1 )
1648 p = p->pSucc;
1649
1650 if( p )
1651 p->bStroke = true;
1652 }
1653 break;
1654
1655 case GOrdOutPth0xD4:
1656 {
1657 sal_uInt32 nID;
1658 sal_uInt16 i,nC;
1659 OSPath* p=pPathList;
1660 pOS2MET->SeekRel(2);
1661 pOS2MET->ReadUInt32( nID );
1662 while (p!=nullptr && p->nID!=nID)
1663 p=p->pSucc;
1664
1665 if( p!=nullptr )
1666 {
1667 SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle );
1668 SetRasterOp(aAttr.eLinMix);
1669 ChangeBrush(COL_TRANSPARENT, false);
1670 nC=p->aPPoly.Count();
1671 for (i=0; i<nC; i++)
1672 {
1673 if (i+1<nC || p->bClosed)
1674 DrawPolygon( p->aPPoly.GetObject( i ) );
1675 else
1676 DrawPolyLine( p->aPPoly.GetObject( i ) );
1677 }
1678 }
1679 break;
1680 }
1681 case GOrdSClPth0xB4: {
1682 SAL_INFO("filter.os2met","GOrdSClPth")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdSClPth") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1682" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSClPth"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSClPth"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1682" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdSClPth") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1682" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSClPth"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSClPth"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1682" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1683 sal_uInt32 nID;
1684 OSPath * p=pPathList;
1685 pOS2MET->SeekRel(2);
1686 pOS2MET->ReadUInt32( nID );
1687 if (nID==0) p=nullptr;
1688 while (p!=nullptr && p->nID!=nID) p=p->pSucc;
1689 if (p!=nullptr) pVirDev->SetClipRegion(vcl::Region(p->aPPoly));
1690 else pVirDev->SetClipRegion();
1691 break;
1692 }
1693 case GOrdNopNop0x00:
1694 break;
1695 case GOrdRemark0x01: SAL_INFO("filter.os2met","GOrdRemark")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdRemark") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1695" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdRemark"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdRemark"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1695" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdRemark") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1695" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdRemark"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdRemark"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1695" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1696 break;
1697 case GOrdSegLab0xD3: SAL_INFO("filter.os2met","GOrdSegLab")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdSegLab") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1697" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSegLab"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSegLab"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1697" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdSegLab") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1697" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSegLab"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSegLab"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1697" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1698 break;
1699
1700 case GOrdBitBlt0xD6: ReadBitBlt(); break;
1701
1702 case GOrdCalSeg0x07: SAL_INFO("filter.os2met","GOrdCalSeg")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdCalSeg") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1702" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdCalSeg"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdCalSeg"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1702" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdCalSeg") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1702" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdCalSeg"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdCalSeg"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1702" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1703 break;
1704 case GOrdSSgBnd0x32: SAL_INFO("filter.os2met","GOrdSSgBnd")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdSSgBnd") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1704" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSSgBnd"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSSgBnd"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1704" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdSSgBnd") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1704" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSSgBnd"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSSgBnd"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1704" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1705 break;
1706 case GOrdSegChr0x04: SAL_INFO("filter.os2met","GOrdSegChr")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdSegChr") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1706" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSegChr"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSegChr"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1706" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdSegChr") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1706" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSegChr"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSegChr"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1706" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1707 break;
1708 case GOrdCloFig0x7D:
1709 CloseFigure();
1710 break;
1711 case GOrdEndSym0xFF: SAL_INFO("filter.os2met","GOrdEndSym")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdEndSym") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1711" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdEndSym"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdEndSym"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1711" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdEndSym") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1711" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdEndSym"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdEndSym"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1711" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1712 break;
1713 case GOrdEndPlg0x3E: SAL_INFO("filter.os2met","GOrdEndPlg")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdEndPlg") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1713" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdEndPlg"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdEndPlg"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1713" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdEndPlg") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1713" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdEndPlg"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdEndPlg"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1713" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1714 break;
1715 case GOrdEscape0xD5: SAL_INFO("filter.os2met","GOrdEscape")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdEscape") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1715" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdEscape"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdEscape"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1715" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdEscape") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1715" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdEscape"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdEscape"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1715" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1716 break;
1717 case GOrdExtEsc0xFED5: SAL_INFO("filter.os2met","GOrdExtEsc")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdExtEsc") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1717" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdExtEsc"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdExtEsc"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1717" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdExtEsc") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1717" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdExtEsc"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdExtEsc"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1717" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1718 break;
1719
1720 case GOrdPolygn0xF3: ReadPolygons(); break;
1721
1722 case GOrdStkPop0x3F: PopAttr(); break;
1723
1724 case GOrdPIvAtr0x54: PushAttr(nOrderID);
1725 [[fallthrough]];
1726 case GOrdSIvAtr0x14: {
1727 sal_uInt8 nA, nP, nFlags;
1728 Color aCol;
1729 RasterOp eROP;
1730 pOS2MET->ReadUChar( nA ).ReadUChar( nP ).ReadUChar( nFlags );
1731 if (nOrderID==GOrdPIvAtr0x54) {
1732 pAttrStack->nIvAttrA=nA;
1733 pAttrStack->nIvAttrP=nP;
1734 }
1735 if (nA<=2) {
1736 if ((nFlags&0x80)!=0) {
1737 if (nA==1) switch (nP) {
1738 case 1: aAttr.aLinCol=aDefAttr.aLinCol; break;
1739 case 2: aAttr.aChrCol=aDefAttr.aChrCol; break;
1740 case 3: aAttr.aMrkCol=aDefAttr.aMrkCol; break;
1741 case 4: aAttr.aPatCol=aDefAttr.aPatCol; break;
1742 case 5: aAttr.aImgCol=aDefAttr.aImgCol; break;
1743 }
1744 else switch (nP) {
1745 case 1: aAttr.aLinBgCol=aDefAttr.aLinBgCol; break;
1746 case 2: aAttr.aChrBgCol=aDefAttr.aChrBgCol; break;
1747 case 3: aAttr.aMrkBgCol=aDefAttr.aMrkBgCol; break;
1748 case 4: aAttr.aPatBgCol=aDefAttr.aPatBgCol; break;
1749 case 5: aAttr.aImgBgCol=aDefAttr.aImgBgCol; break;
1750 }
1751 }
1752 else {
1753 const auto nVal = ReadLittleEndian3BytesLong();
1754 if ((nFlags&0x40)!=0 && nVal==1) aCol=COL_BLACK;
1755 else if ((nFlags&0x40)!=0 && nVal==2) aCol=COL_WHITE;
1756 else if ((nFlags&0x40)!=0 && nVal==4) aCol=COL_WHITE;
1757 else if ((nFlags&0x40)!=0 && nVal==5) aCol=COL_BLACK;
1758 else aCol=GetPaletteColor(nVal);
1759 if (nA==1) switch (nP) {
1760 case 1: aAttr.aLinCol=aCol; break;
1761 case 2: aAttr.aChrCol=aCol; break;
1762 case 3: aAttr.aMrkCol=aCol; break;
1763 case 4: aAttr.aPatCol=aCol; break;
1764 case 5: aAttr.aImgCol=aCol; break;
1765 }
1766 else switch (nP) {
1767 case 1: aAttr.aLinBgCol=aCol; break;
1768 case 2: aAttr.aChrBgCol=aCol; break;
1769 case 3: aAttr.aMrkBgCol=aCol; break;
1770 case 4: aAttr.aPatBgCol=aCol; break;
1771 case 5: aAttr.aImgBgCol=aCol; break;
1772 }
1773 }
1774 }
1775 else {
1776 sal_uInt8 nMix;
1777 pOS2MET->ReadUChar( nMix );
1778 if (nMix==0) {
1779 switch (nP) {
1780 case 1: aAttr.eLinBgMix=aDefAttr.eLinBgMix; break;
1781 case 2: aAttr.eChrBgMix=aDefAttr.eChrBgMix; break;
1782 case 3: aAttr.eMrkBgMix=aDefAttr.eMrkBgMix; break;
1783 case 4: aAttr.ePatBgMix=aDefAttr.ePatBgMix; break;
1784 case 5: aAttr.eImgBgMix=aDefAttr.eImgBgMix; break;
1785 }
1786 }
1787 else {
1788 eROP=OS2MixToRasterOp(nMix);
1789 switch (nP) {
1790 case 1: aAttr.eLinBgMix=eROP; break;
1791 case 2: aAttr.eChrBgMix=eROP; break;
1792 case 3: aAttr.eMrkBgMix=eROP; break;
1793 case 4: aAttr.ePatBgMix=eROP; break;
1794 case 5: aAttr.eImgBgMix=eROP; break;
1795 }
1796 }
1797 }
1798 break;
1799 }
1800 case GOrdPIxCol0xE6: PushAttr(nOrderID);
1801 [[fallthrough]];
1802 case GOrdSIxCol0xA6: {
1803 sal_uInt8 nFlags;
1804 pOS2MET->ReadUChar( nFlags );
1805 if ((nFlags&0x80)!=0) {
1806 aAttr.aLinCol=aDefAttr.aLinCol;
1807 aAttr.aChrCol=aDefAttr.aChrCol;
1808 aAttr.aMrkCol=aDefAttr.aMrkCol;
1809 aAttr.aPatCol=aDefAttr.aPatCol;
1810 aAttr.aImgCol=aDefAttr.aImgCol;
1811 }
1812 else {
1813 Color aCol;
1814 const auto nVal = ReadLittleEndian3BytesLong();
1815 if ((nFlags&0x40)!=0 && nVal==1) aCol=COL_BLACK;
1816 else if ((nFlags&0x40)!=0 && nVal==2) aCol=COL_WHITE;
1817 else if ((nFlags&0x40)!=0 && nVal==4) aCol=COL_WHITE;
1818 else if ((nFlags&0x40)!=0 && nVal==5) aCol=COL_BLACK;
1819 else aCol=GetPaletteColor(nVal);
1820 aAttr.aLinCol = aAttr.aChrCol = aAttr.aMrkCol = aAttr.aPatCol =
1821 aAttr.aImgCol = aCol;
1822 }
1823 break;
1824 }
1825
1826 case GOrdPColor0x4A:
1827 case GOrdPXtCol0x66: PushAttr(nOrderID);
1828 [[fallthrough]];
1829 case GOrdSColor0x0A:
1830 case GOrdSXtCol0x26: {
1831 sal_uInt16 nVal;
1832 if (nOrderID==GOrdPColor0x4A || nOrderID==GOrdSColor0x0A) {
1833 sal_uInt8 nbyte;
1834 pOS2MET->ReadUChar( nbyte ); nVal=static_cast<sal_uInt16>(nbyte)|0xff00;
1835 }
1836 else pOS2MET->ReadUInt16( nVal );
1837 if (nVal==0x0000 || nVal==0xff00) {
1838 aAttr.aLinCol=aDefAttr.aLinCol;
1839 aAttr.aChrCol=aDefAttr.aChrCol;
1840 aAttr.aMrkCol=aDefAttr.aMrkCol;
1841 aAttr.aPatCol=aDefAttr.aPatCol;
1842 aAttr.aImgCol=aDefAttr.aImgCol;
1843 }
1844 else {
1845 Color aCol;
1846 if (nVal==0x0007) aCol=COL_WHITE;
1847 else if (nVal==0x0008) aCol=COL_BLACK;
1848 else if (nVal==0xff08) aCol=GetPaletteColor(1);
1849 else aCol=GetPaletteColor(static_cast<sal_uInt32>(nVal) & 0x000000ff);
1850 aAttr.aLinCol = aAttr.aChrCol = aAttr.aMrkCol = aAttr.aPatCol =
1851 aAttr.aImgCol = aCol;
1852 }
1853 break;
1854 }
1855
1856 case GOrdPBgCol0x65: PushAttr(nOrderID);
1857 [[fallthrough]];
1858 case GOrdSBgCol0x25: {
1859 sal_uInt16 nVal;
1860 pOS2MET->ReadUInt16( nVal );
1861 if (nVal==0x0000 || nVal==0xff00) {
1862 aAttr.aLinBgCol=aDefAttr.aLinBgCol;
1863 aAttr.aChrBgCol=aDefAttr.aChrBgCol;
1864 aAttr.aMrkBgCol=aDefAttr.aMrkBgCol;
1865 aAttr.aPatBgCol=aDefAttr.aPatBgCol;
1866 aAttr.aImgBgCol=aDefAttr.aImgBgCol;
1867 }
1868 else {
1869 Color aCol;
1870 if (nVal==0x0007) aCol=COL_WHITE;
1871 else if (nVal==0x0008) aCol=COL_BLACK;
1872 else if (nVal==0xff08) aCol=GetPaletteColor(0);
1873 else aCol=GetPaletteColor(static_cast<sal_uInt32>(nVal) & 0x000000ff);
1874 aAttr.aLinBgCol = aAttr.aChrBgCol = aAttr.aMrkBgCol =
1875 aAttr.aPatBgCol = aAttr.aImgBgCol = aCol;
1876 }
1877 break;
1878 }
1879 case GOrdPBxCol0xE7: PushAttr(nOrderID);
1880 [[fallthrough]];
1881 case GOrdSBxCol0xA7: {
1882 sal_uInt8 nFlags;
1883 pOS2MET->ReadUChar( nFlags );
1884 if ((nFlags&0x80)!=0) {
1885 aAttr.aLinBgCol=aDefAttr.aLinBgCol;
1886 aAttr.aChrBgCol=aDefAttr.aChrBgCol;
1887 aAttr.aMrkBgCol=aDefAttr.aMrkBgCol;
1888 aAttr.aPatBgCol=aDefAttr.aPatBgCol;
1889 aAttr.aImgBgCol=aDefAttr.aImgBgCol;
1890 }
1891 else {
1892 Color aCol;
1893 const auto nVal = ReadLittleEndian3BytesLong();
1894 if ((nFlags&0x40)!=0 && nVal==1) aCol=COL_BLACK;
1895 else if ((nFlags&0x40)!=0 && nVal==2) aCol=COL_WHITE;
1896 else if ((nFlags&0x40)!=0 && nVal==4) aCol=COL_WHITE;
1897 else if ((nFlags&0x40)!=0 && nVal==5) aCol=COL_BLACK;
1898 else aCol=GetPaletteColor(nVal);
1899 aAttr.aLinBgCol = aAttr.aChrBgCol = aAttr.aMrkBgCol =
1900 aAttr.aPatBgCol = aAttr.aImgBgCol = aCol;
1901 }
1902 break;
1903 }
1904
1905 case GOrdPMixMd0x4C: PushAttr(nOrderID);
1906 [[fallthrough]];
1907 case GOrdSMixMd0x0C: {
1908 sal_uInt8 nMix;
1909 pOS2MET->ReadUChar( nMix );
1910 if (nMix==0) {
1911 aAttr.eLinMix=aDefAttr.eLinMix;
1912 aAttr.eChrMix=aDefAttr.eChrMix;
1913 aAttr.eMrkMix=aDefAttr.eMrkMix;
1914 aAttr.ePatMix=aDefAttr.ePatMix;
1915 aAttr.eImgMix=aDefAttr.eImgMix;
1916 }
1917 else {
1918 aAttr.eLinMix = aAttr.eChrMix = aAttr.eMrkMix =
1919 aAttr.ePatMix = aAttr.eImgMix = OS2MixToRasterOp(nMix);
1920 }
1921 break;
1922 }
1923 case GOrdPBgMix0x4D: PushAttr(nOrderID);
1924 [[fallthrough]];
1925 case GOrdSBgMix0x0D: {
1926 sal_uInt8 nMix;
1927 pOS2MET->ReadUChar( nMix );
1928 if (nMix==0) {
1929 aAttr.eLinBgMix=aDefAttr.eLinBgMix;
1930 aAttr.eChrBgMix=aDefAttr.eChrBgMix;
1931 aAttr.eMrkBgMix=aDefAttr.eMrkBgMix;
1932 aAttr.ePatBgMix=aDefAttr.ePatBgMix;
1933 aAttr.eImgBgMix=aDefAttr.eImgBgMix;
1934 }
1935 else {
1936 aAttr.eLinBgMix = aAttr.eChrBgMix = aAttr.eMrkBgMix =
1937 aAttr.ePatBgMix = aAttr.eImgBgMix = OS2MixToRasterOp(nMix);
1938 }
1939 break;
1940 }
1941 case GOrdPPtSet0x48: PushAttr(nOrderID);
1942 [[fallthrough]];
1943 case GOrdSPtSet0x08: SAL_INFO("filter.os2met","GOrdSPtSet")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdSPtSet") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1943" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSPtSet"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSPtSet"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1943" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdSPtSet") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1943" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSPtSet"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSPtSet"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1943" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1944 break;
1945
1946 case GOrdPPtSym0x09: PushAttr(nOrderID);
1947 [[fallthrough]];
1948 case GOrdSPtSym0x28: {
1949 sal_uInt8 nPatt;
1950 pOS2MET->ReadUChar( nPatt );
1951 aAttr.bFill = ( nPatt != 0x0f );
1952 break;
1953 }
1954
1955 case GOrdPPtRef0xE0: PushAttr(nOrderID);
1956 [[fallthrough]];
1957 case GOrdSPtRef0xA0: SAL_INFO("filter.os2met","GOrdSPtRef")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdSPtRef") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1957" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSPtRef"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSPtRef"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1957" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdSPtRef") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1957" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSPtRef"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSPtRef"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "1957" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1958 break;
1959
1960 case GOrdPLnEnd0x5A: PushAttr(nOrderID);
1961 [[fallthrough]];
1962 case GOrdSLnEnd0x1A:
1963 break;
1964
1965 case GOrdPLnJoi0x5B: PushAttr(nOrderID);
1966 [[fallthrough]];
1967 case GOrdSLnJoi0x1B:
1968 break;
1969
1970 case GOrdPLnTyp0x58: PushAttr(nOrderID);
1971 [[fallthrough]];
1972 case GOrdSLnTyp0x18: {
1973 sal_uInt8 nType;
1974 pOS2MET->ReadUChar( nType );
1975 switch (nType) {
1976 case 0: aAttr.eLinStyle=aDefAttr.eLinStyle; break;
1977 case 1: case 4: aAttr.eLinStyle=PEN_DOT; break;
1978 case 2: case 5: aAttr.eLinStyle=PEN_DASH; break;
1979 case 3: case 6: aAttr.eLinStyle=PEN_DASHDOT; break;
1980 case 8: aAttr.eLinStyle=PEN_NULL; break;
1981 default: aAttr.eLinStyle=PEN_SOLID;
1982 }
1983 break;
1984 }
1985 case GOrdPLnWdt0x59: PushAttr(nOrderID);
1986 [[fallthrough]];
1987 case GOrdSLnWdt0x19: {
1988 sal_uInt8 nbyte;
1989 pOS2MET->ReadUChar( nbyte );
1990 if (nbyte==0) aAttr.nLinWidth=aDefAttr.nLinWidth;
1991 else aAttr.nLinWidth=static_cast<sal_uInt16>(nbyte)-1;
1992 break;
1993 }
1994 case GOrdPFrLWd0x51: PushAttr(nOrderID);
1995 [[fallthrough]];
1996 case GOrdSFrLWd0x11:
1997 break;
1998
1999 case GOrdPStLWd0x55: PushAttr(nOrderID);
2000 [[fallthrough]];
2001 case GOrdSStLWd0x15 :
2002 {
2003 sal_uInt8 nFlags;
2004
2005 pOS2MET->ReadUChar( nFlags );
2006 if ( nFlags & 0x80 )
2007 aAttr.nStrLinWidth = aDefAttr.nStrLinWidth;
2008 else
2009 {
2010 pOS2MET->SeekRel( 1 );
2011 sal_Int32 nWd = ReadCoord( bCoord32 );
2012 if (nWd < 0)
2013 nWd = o3tl::saturating_toggle_sign(nWd);
2014 aAttr.nStrLinWidth = static_cast<sal_uInt16>(nWd);
2015 }
2016 break;
2017 }
2018 case GOrdPChDir0x7A: PushAttr(nOrderID);
2019 [[fallthrough]];
2020 case GOrdSChDir0x3A:
2021 break;
2022
2023 case GOrdPChPrc0x79: PushAttr(nOrderID);
2024 [[fallthrough]];
2025 case GOrdSChPrc0x39:
2026 break;
2027
2028 case GOrdPChSet0x78: PushAttr(nOrderID);
2029 [[fallthrough]];
2030 case GOrdSChSet0x38: {
2031 sal_uInt8 nbyte; pOS2MET->ReadUChar( nbyte );
2032 aAttr.nChrSet=static_cast<sal_uInt32>(nbyte)&0xff;
2033 break;
2034 }
2035 case GOrdPChAng0x74: PushAttr(nOrderID);
2036 [[fallthrough]];
2037 case GOrdSChAng0x34: {
2038 sal_Int32 nX = ReadCoord(bCoord32);
2039 sal_Int32 nY = ReadCoord(bCoord32);
2040 if (nX>=0 && nY==0) aAttr.nChrAng=0;
2041 else {
2042 aAttr.nChrAng=static_cast<short>(atan2(static_cast<double>(nY),static_cast<double>(nX))/3.1415926539*1800.0);
2043 while (aAttr.nChrAng<0) aAttr.nChrAng+=3600;
2044 aAttr.nChrAng%=3600;
2045 }
2046 break;
2047 }
2048 case GOrdPChBrx0x45: PushAttr(nOrderID);
2049 [[fallthrough]];
2050 case GOrdSChBrx0x05:
2051 break;
2052
2053 case GOrdPChCel0x03: PushAttr(nOrderID);
2054 [[fallthrough]];
2055 case GOrdSChCel0x33: {
2056 sal_uInt16 nLen=nOrderLen;
2057 auto nWidth = ReadCoord(bCoord32);
2058 auto nHeight = ReadCoord(bCoord32);
2059 if (nWidth < 0 || nHeight < 0)
2060 aAttr.aChrCellSize = aDefAttr.aChrCellSize;
2061 else
2062 aAttr.aChrCellSize = Size(nWidth, nHeight);
2063 if (bCoord32) nLen-=8; else nLen-=4;
2064 if (nLen>=4) {
2065 pOS2MET->SeekRel(4); nLen-=4;
2066 }
2067 if (nLen>=2) {
2068 sal_uInt8 nbyte;
2069 pOS2MET->ReadUChar( nbyte );
2070 if ((nbyte&0x80)==0 && aAttr.aChrCellSize==Size(0,0))
2071 aAttr.aChrCellSize = aDefAttr.aChrCellSize;
2072 }
2073 break;
2074 }
2075 case GOrdPChXtr0x57: PushAttr(nOrderID);
2076 [[fallthrough]];
2077 case GOrdSChXtr0x17:
2078 break;
2079
2080 case GOrdPChShr0x75: PushAttr(nOrderID);
2081 [[fallthrough]];
2082 case GOrdSChShr0x35:
2083 break;
2084
2085 case GOrdPTxAlg0x76: PushAttr(nOrderID);
2086 [[fallthrough]];
2087 case GOrdSTxAlg0x36: SAL_INFO("filter.os2met","GOrdSTxAlg")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdSTxAlg") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2087" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSTxAlg"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSTxAlg"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2087" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdSTxAlg") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2087" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSTxAlg"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSTxAlg"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2087" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2088 break;
2089
2090 case GOrdPMkPrc0x7B: PushAttr(nOrderID);
2091 [[fallthrough]];
2092 case GOrdSMkPrc0x3B: {
2093 sal_uInt8 nbyte;
2094 pOS2MET->ReadUChar( nbyte );
2095 if (nbyte==0) aAttr.nMrkPrec=aDefAttr.nMrkPrec;
2096 else aAttr.nMrkPrec=nbyte;
2097 break;
2098 }
2099
2100 case GOrdPMkSet0x7C: PushAttr(nOrderID);
2101 [[fallthrough]];
2102 case GOrdSMkSet0x3C: {
2103 sal_uInt8 nbyte;
2104 pOS2MET->ReadUChar( nbyte );
2105 if (nbyte==0) aAttr.nMrkSet=aDefAttr.nMrkSet;
2106 else aAttr.nMrkSet=nbyte;
2107 break;
2108 }
2109
2110 case GOrdPMkSym0x69: PushAttr(nOrderID);
2111 [[fallthrough]];
2112 case GOrdSMkSym0x29: {
2113 sal_uInt8 nbyte;
2114 pOS2MET->ReadUChar( nbyte );
2115 if (nbyte==0) aAttr.nMrkSymbol=aDefAttr.nMrkSymbol;
2116 else aAttr.nMrkSymbol=nbyte;
2117 break;
2118 }
2119
2120 case GOrdPMkCel0x77: PushAttr(nOrderID);
2121 [[fallthrough]];
2122 case GOrdSMkCel0x37: {
2123 sal_uInt16 nLen=nOrderLen;
2124 aAttr.aMrkCellSize.setWidth(ReadCoord(bCoord32) );
2125 aAttr.aMrkCellSize.setHeight(ReadCoord(bCoord32) );
2126 if (bCoord32) nLen-=8; else nLen-=4;
2127 if (nLen>=2) {
2128 sal_uInt8 nbyte;
2129 pOS2MET->ReadUChar( nbyte );
2130 if ((nbyte&0x80)==0 && aAttr.aMrkCellSize==Size(0,0))
2131 aAttr.aMrkCellSize=aDefAttr.aMrkCellSize;
2132 }
2133 break;
2134 }
2135
2136 case GOrdPArcPa0x62: PushAttr(nOrderID);
2137 [[fallthrough]];
2138 case GOrdSArcPa0x22:
2139 aAttr.nArcP=ReadCoord(bCoord32);
2140 aAttr.nArcQ=ReadCoord(bCoord32);
2141 aAttr.nArcR=ReadCoord(bCoord32);
2142 aAttr.nArcS=ReadCoord(bCoord32);
2143 break;
2144
2145 case GOrdPCrPos0x61: PushAttr(nOrderID);
2146 [[fallthrough]];
2147 case GOrdSCrPos0x21:
2148 aAttr.aCurPos=ReadPoint();
2149 break;
2150
2151 case GOrdPMdTrn0x64: PushAttr(nOrderID);
2152 [[fallthrough]];
2153 case GOrdSMdTrn0x24: SAL_INFO("filter.os2met","GOrdSMdTrn")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdSMdTrn") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2153" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSMdTrn"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSMdTrn"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2153" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdSMdTrn") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2153" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSMdTrn"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSMdTrn"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2153" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2154 break;
2155
2156 case GOrdPPkIdn0x23: PushAttr(nOrderID);
2157 [[fallthrough]];
2158 case GOrdSPkIdn0x43: SAL_INFO("filter.os2met","GOrdSPkIdn")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdSPkIdn") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2158" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSPkIdn"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSPkIdn"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2158" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdSPkIdn") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2158" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSPkIdn"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSPkIdn"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2158" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2159 break;
2160
2161 case GOrdSVwTrn0x31: SAL_INFO("filter.os2met","GOrdSVwTrn")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdSVwTrn") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2161" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSVwTrn"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSVwTrn"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2161" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdSVwTrn") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2161" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSVwTrn"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSVwTrn"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2161" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2162 break;
2163
2164 case GOrdPVwWin0x67: PushAttr(nOrderID);
2165 [[fallthrough]];
2166 case GOrdSVwWin0x27: SAL_INFO("filter.os2met","GOrdSVwWin")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "GOrdSVwWin") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2166" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSVwWin"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSVwWin"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2166" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "GOrdSVwWin") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2166" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "GOrdSVwWin"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "GOrdSVwWin"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2166" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2167 break;
2168 default: SAL_INFO("filter.os2met","Unknown order: " << nOrderID)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Unknown order: " <<
nOrderID) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2168" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Unknown order: " << nOrderID)
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Unknown order: " << nOrderID; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2168" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Unknown order: " << nOrderID) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2168" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Unknown order: " << nOrderID)
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Unknown order: " << nOrderID; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2168" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2169 }
2170}
2171
2172void OS2METReader::ReadDsc(sal_uInt16 nDscID)
2173{
2174 switch (nDscID) {
2175 case 0x00f7: { // 'Specify GVM Subset'
2176 sal_uInt8 nbyte;
2177 pOS2MET->SeekRel(6);
2178 pOS2MET->ReadUChar( nbyte );
2179 if (nbyte==0x05) bCoord32=true;
2180 else if (nbyte==0x04) bCoord32=false;
2181 else {
2182 pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERRORErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 21 ));
2183 ErrorCode=1;
2184 }
2185 break;
2186 }
2187 case 0x00f6:
2188 {
2189 // 'Set Picture Descriptor'
2190 bool b32;
2191 sal_uInt8 nbyte,nUnitType;
2192
2193 pOS2MET->SeekRel(2);
2194 pOS2MET->ReadUChar( nbyte );
2195
2196 if (nbyte==0x05)
2197 b32=true;
2198 else if(nbyte==0x04)
2199 b32=false;
2200 else
2201 {
2202 b32 = false; // -Wall added the case.
2203 pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERRORErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 21 ));
2204 ErrorCode=2;
2205 }
2206
2207 pOS2MET->ReadUChar( nUnitType );
2208
2209 sal_Int32 xr = ReadCoord(b32);
2210 sal_Int32 yr = ReadCoord(b32);
2211
2212 ReadCoord(b32);
2213
2214 if (nUnitType==0x00 && xr>0 && yr>0)
2215 aGlobMapMode=MapMode(MapUnit::MapInch,Point(0,0),Fraction(10,xr),Fraction(10,yr));
2216 else if (nUnitType==0x01 && xr>0 && yr>0)
2217 aGlobMapMode=MapMode(MapUnit::MapCM,Point(0,0),Fraction(10,xr),Fraction(10,yr));
2218 else
2219 aGlobMapMode=MapMode();
2220
2221 sal_Int32 x1 = ReadCoord(b32);
2222 sal_Int32 x2 = ReadCoord(b32);
2223 sal_Int32 y1 = ReadCoord(b32);
2224 sal_Int32 y2 = ReadCoord(b32);
2225
2226 if (x1>x2)
2227 {
2228 const auto nt = x1;
2229 x1=x2;
2230 x2=nt;
2231 }
2232
2233 if (y1>y2)
2234 {
2235 const auto nt = y1;
2236 y1=y2;
2237 y2=nt;
2238 }
2239
2240 aBoundingRect.SetLeft( x1 );
2241 aBoundingRect.SetRight( x2 );
2242 aBoundingRect.SetTop( y1 );
2243 aBoundingRect.SetBottom( y2 );
2244
2245 // no output beside this bounding rect
2246 pVirDev->IntersectClipRegion( tools::Rectangle( Point(), aBoundingRect.GetSize() ) );
2247
2248 break;
2249 }
2250 case 0x0021: // 'Set Current Defaults'
2251 break;
2252 }
2253}
2254
2255void OS2METReader::ReadImageData(sal_uInt16 nDataID, sal_uInt16 nDataLen)
2256{
2257 OSBitmap * p=pBitmapList; if (p==nullptr) return;
2258
2259 switch (nDataID) {
2260
2261 case 0x0070: // Begin Segment
2262 break;
2263
2264 case 0x0091: // Begin Image Content
2265 break;
2266
2267 case 0x0094: // Image Size
2268 pOS2MET->SeekRel(5);
2269 p->nHeight=ReadBigEndianWord();
2270 p->nWidth=ReadBigEndianWord();
2271 break;
2272
2273 case 0x0095: // Image Encoding
2274 break;
2275
2276 case 0x0096: { // Image IDE-Size
2277 sal_uInt8 nbyte;
2278 pOS2MET->ReadUChar( nbyte ); p->nBitsPerPixel=nbyte;
2279 break;
2280 }
2281
2282 case 0x0097: // Image LUT-ID
2283 break;
2284
2285 case 0x009b: // IDE Structure
2286 break;
2287
2288 case 0xfe92: { // Image Data
2289 // At the latest we now need the temporary BMP file and
2290 // inside this file we need the header and the palette.
2291 if (p->pBMP==nullptr) {
2292 p->pBMP=new SvMemoryStream();
2293 p->pBMP->SetEndian(SvStreamEndian::LITTLE);
2294 if (p->nWidth==0 || p->nHeight==0 || p->nBitsPerPixel==0) {
2295 pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERRORErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 21 ));
2296 ErrorCode=3;
2297 return;
2298 }
2299 // write (Windows-)BITMAPINFOHEADER:
2300 p->pBMP->WriteUInt32( 40 ).WriteUInt32( p->nWidth ).WriteUInt32( p->nHeight );
2301 p->pBMP->WriteUInt16( 1 ).WriteUInt16( p->nBitsPerPixel );
2302 p->pBMP->WriteUInt32( 0 ).WriteUInt32( 0 ).WriteUInt32( 0 ).WriteUInt32( 0 );
2303 p->pBMP->WriteUInt32( 0 ).WriteUInt32( 0 );
2304 // write color table:
2305 if (p->nBitsPerPixel<=8) {
2306 sal_uInt16 i, nColTabSize=1<<(p->nBitsPerPixel);
2307 for (i=0; i<nColTabSize; i++) p->pBMP->WriteUInt32( GetPalette0RGB(i) );
2308 }
2309 }
2310 // OK, now the map data is being pushed. Unfortunately OS2 and BMP
2311 // do have a different RGB ordering when using 24-bit
2312 std::unique_ptr<sal_uInt8[]> pBuf(new sal_uInt8[nDataLen]);
2313 pOS2MET->ReadBytes(pBuf.get(), nDataLen);
2314 sal_uInt32 nBytesPerLineToSwap = (p->nBitsPerPixel == 24) ?
2315 ((p->nWidth * 3 + 3) & 0xfffffffc) : 0;
2316 if (nBytesPerLineToSwap) {
2317 sal_uInt32 nAlign = p->nMapPos - (p->nMapPos % nBytesPerLineToSwap);
2318 sal_uInt32 i=0;
2319 while (nAlign+i+2<p->nMapPos+nDataLen) {
2320 if (nAlign+i>=p->nMapPos) {
2321 sal_uInt32 j = nAlign + i - p->nMapPos;
2322 std::swap(pBuf[j], pBuf[j+2]);
2323 }
2324 i+=3;
2325 if (i + 2 >= nBytesPerLineToSwap) {
2326 nAlign += nBytesPerLineToSwap;
2327 i=0;
2328 }
2329 }
2330 }
2331 p->pBMP->WriteBytes(pBuf.get(), nDataLen);
2332 p->nMapPos+=nDataLen;
2333 break;
2334 }
2335 case 0x0093: // End Image Content
2336 break;
2337
2338 case 0x0071: // End Segment
2339 break;
2340 }
2341}
2342
2343void OS2METReader::ReadFont(sal_uInt16 nFieldSize)
2344{
2345 sal_uInt8 nByte, nTripType, nTripType2;
2346 OSFont * pF=new OSFont;
2347 pF->pSucc=pFontList; pFontList=pF;
2348 pF->nID=0;
2349 pF->aFont.SetTransparent(true);
2350 pF->aFont.SetAlignment(ALIGN_BASELINE);
2351
2352 auto nPos=pOS2MET->Tell();
2353 auto nMaxPos = nPos + nFieldSize;
2354 pOS2MET->SeekRel(2); nPos+=2;
2355 while (nPos<nMaxPos && pOS2MET->GetError()==ERRCODE_NONEErrCode(0)) {
2356 pOS2MET->ReadUChar( nByte );
2357 sal_uInt16 nLen = static_cast<sal_uInt16>(nByte) & 0x00ff;
2358 if (nLen == 0)
2359 {
2360 pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERRORErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 21 ));
2361 ErrorCode=4;
2362 }
2363 pOS2MET->ReadUChar( nTripType );
2364 switch (nTripType) {
2365 case 0x02:
2366 pOS2MET->ReadUChar( nTripType2 );
2367 switch (nTripType2) {
2368 case 0x84: // Font name
2369 break;
2370 case 0x08: { // Font Typeface
2371 char str[33];
2372 pOS2MET->SeekRel(1);
2373 pOS2MET->ReadBytes( &str, 32 );
2374 str[ 32 ] = 0;
2375 OUString aStr( str, strlen(str), osl_getThreadTextEncoding() );
2376 if ( aStr.equalsIgnoreAsciiCase( "Helv" ) )
2377 aStr = "Helvetica";
2378 pF->aFont.SetFamilyName( aStr );
2379 break;
2380 }
2381 }
2382 break;
2383 case 0x24: // Icid
2384 pOS2MET->ReadUChar( nTripType2 );
2385 switch (nTripType2) {
2386 case 0x05: //Icid
2387 pOS2MET->ReadUChar( nByte );
2388 pF->nID=static_cast<sal_uInt32>(nByte)&0xff;
2389 break;
2390 }
2391 break;
2392 case 0x20: // Font Binary GCID
2393 break;
2394 case 0x1f: { // Font Attributes
2395 FontWeight eWeight;
2396 sal_uInt8 nbyte;
2397 pOS2MET->ReadUChar( nbyte );
2398 switch (nbyte) {
2399 case 1: eWeight=WEIGHT_THIN; break;
2400 case 2: eWeight=WEIGHT_ULTRALIGHT; break;
2401 case 3: eWeight=WEIGHT_LIGHT; break;
2402 case 4: eWeight=WEIGHT_SEMILIGHT; break;
2403 case 5: eWeight=WEIGHT_NORMAL; break;
2404 case 6: eWeight=WEIGHT_SEMIBOLD; break;
2405 case 7: eWeight=WEIGHT_BOLD; break;
2406 case 8: eWeight=WEIGHT_ULTRABOLD; break;
2407 case 9: eWeight=WEIGHT_BLACK; break;
2408 default: eWeight=WEIGHT_DONTKNOW;
2409 }
2410 pF->aFont.SetWeight(eWeight);
2411 break;
2412 }
2413 }
2414 nPos+=nLen;
2415 pOS2MET->Seek(nPos);
2416 }
2417}
2418
2419void OS2METReader::ReadField(sal_uInt16 nFieldType, sal_uInt16 nFieldSize)
2420{
2421 switch (nFieldType) {
2422 case BegDocumnMagic0xA8A8:
2423 break;
2424 case EndDocumnMagic0xA8A9:
2425 break;
2426 case BegResGrpMagic0xC6A8:
2427 break;
2428 case EndResGrpMagic0xC6A9:
2429 break;
2430 case BegColAtrMagic0x77A8:
2431 break;
2432 case EndColAtrMagic0x77A9:
2433 break;
2434 case BlkColAtrMagic0x77B0: {
2435 sal_uInt8 nbyte;
2436 sal_uInt16 nStartIndex, nEndIndex, i, nElemLen, nBytesPerCol;
2437
2438 auto nPos = pOS2MET->Tell();
2439 auto nMaxPos = nPos + nFieldSize;
2440 pOS2MET->SeekRel(3); nPos+=3;
2441 while (nPos<nMaxPos && pOS2MET->GetError()==ERRCODE_NONEErrCode(0)) {
2442 pOS2MET->ReadUChar( nbyte ); nElemLen=static_cast<sal_uInt16>(nbyte) & 0x00ff;
2443 if (nElemLen>11) {
2444 pOS2MET->SeekRel(4);
2445 nStartIndex=ReadBigEndianWord();
2446 pOS2MET->SeekRel(3);
2447 pOS2MET->ReadUChar( nbyte );
2448 nBytesPerCol=static_cast<sal_uInt16>(nbyte) & 0x00ff;
2449 if (nBytesPerCol == 0)
2450 {
2451 pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERRORErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 21 ));
2452 ErrorCode=4;
2453 break;
2454 }
2455 nEndIndex=nStartIndex+(nElemLen-11)/nBytesPerCol;
2456 for (i=nStartIndex; i<nEndIndex; i++) {
2457 if (nBytesPerCol > 3) pOS2MET->SeekRel(nBytesPerCol-3);
2458 auto nCol = ReadBigEndian3BytesLong();
2459 SetPalette0RGB(i, nCol);
2460 }
2461 }
2462 else if (nElemLen<10) {
2463 pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERRORErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 21 ));
2464 ErrorCode=4;
2465 }
2466 nPos += nElemLen;
2467 pOS2MET->Seek(nPos);
2468 }
2469 break;
2470 }
2471 case MapColAtrMagic0x77AB:
2472 break;
2473 case BegImgObjMagic0xFBA8: {
2474 // create new bitmap by now: (will be filled later)
2475 OSBitmap * pB=new OSBitmap;
2476 pB->pSucc=pBitmapList; pBitmapList=pB;
2477 pB->pBMP=nullptr; pB->nWidth=0; pB->nHeight=0; pB->nBitsPerPixel=0;
2478 pB->nMapPos=0;
2479 // determine ID of the bitmap:
2480 pB->nID=0;
2481 for (sal_uInt8 i = 0; i < 4; ++i) {
2482 sal_uInt8 nbyte(0),nbyte2(0);
2483 pOS2MET->ReadUChar(nbyte).ReadUChar(nbyte2);
2484 nbyte -= 0x30;
2485 nbyte2 -= 0x30;
2486 nbyte = (nbyte << 4) | nbyte2;
2487 pB->nID=(pB->nID>>8)|(static_cast<sal_uInt32>(nbyte)<<24);
2488 }
2489 // put new palette on the palette stack: (will be filled later)
2490 OSPalette * pP=new OSPalette;
2491 pP->pSucc=pPaletteStack; pPaletteStack=pP;
2492 pP->p0RGB=nullptr; pP->nSize=0;
2493 break;
2494 }
2495 case EndImgObjMagic0xFBA9: {
2496 // read temporary Windows BMP file:
2497 if (pBitmapList==nullptr || pBitmapList->pBMP==nullptr ||
2498 pBitmapList->pBMP->GetError()!=ERRCODE_NONEErrCode(0)) {
2499 pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERRORErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 21 ));
2500 ErrorCode=5;
2501 return;
2502 }
2503 pBitmapList->pBMP->Seek(0);
2504
2505 ReadDIBBitmapEx(pBitmapList->aBitmapEx, *(pBitmapList->pBMP), false);
2506
2507 if (pBitmapList->pBMP->GetError()!=ERRCODE_NONEErrCode(0)) {
2508 pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERRORErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 21 ));
2509 ErrorCode=6;
2510 }
2511 delete pBitmapList->pBMP; pBitmapList->pBMP=nullptr;
2512 // kill palette from stack:
2513 OSPalette * pP=pPaletteStack;
2514 if (pP!=nullptr) {
2515 pPaletteStack=pP->pSucc;
2516 delete[] pP->p0RGB;
2517 delete pP;
2518 }
2519 break;
2520 }
2521 case DscImgObjMagic0xFBA6:
2522 break;
2523 case DatImgObjMagic0xFBEE: {
2524 sal_uInt16 nDataID, nDataLen;
2525 sal_uInt8 nbyte;
2526
2527 auto nPos = pOS2MET->Tell();
2528 auto nMaxPos = nPos + nFieldSize;
2529 while (nPos<nMaxPos && pOS2MET->GetError()==ERRCODE_NONEErrCode(0)) {
2530 pOS2MET->ReadUChar( nbyte ); nDataID=static_cast<sal_uInt16>(nbyte)&0x00ff;
2531 if (nDataID==0x00fe) {
2532 pOS2MET->ReadUChar( nbyte );
2533 nDataID=(nDataID<<8)|(static_cast<sal_uInt16>(nbyte)&0x00ff);
2534 nDataLen=ReadBigEndianWord();
2535 nPos+=4;
2536 }
2537 else {
2538 pOS2MET->ReadUChar( nbyte ); nDataLen=static_cast<sal_uInt16>(nbyte)&0x00ff;
2539 nPos+=2;
2540 }
2541 ReadImageData(nDataID, nDataLen);
2542 nPos += nDataLen;
2543 pOS2MET->Seek(nPos);
2544 }
2545 break;
2546 }
2547
2548 case BegObEnv1Magic0xC7A8:
2549 break;
2550 case EndObEnv1Magic0xC7A9:
2551 break;
2552 case BegGrfObjMagic0xBBA8:
2553 break;
2554 case EndGrfObjMagic0xBBA9: {
2555 SvStream * pSave;
2556 sal_uInt16 nOrderID, nOrderLen;
2557 sal_uInt8 nbyte;
2558
2559 if (!xOrdFile)
2560 break;
2561
2562 // In xOrdFile all "DatGrfObj" fields were collected so that the
2563 // therein contained "Orders" are continuous and not segmented by fields.
2564 // To read them from the memory stream without having any trouble,
2565 // we use a little trick:
2566
2567 pSave=pOS2MET;
2568 pOS2MET=xOrdFile.get(); //(!)
2569 auto nMaxPos = pOS2MET->Tell();
2570 pOS2MET->Seek(0);
2571
2572 // "Segment header":
2573 pOS2MET->ReadUChar( nbyte );
2574 if (nbyte==0x70) { // header exists
2575 pOS2MET->SeekRel(15); // but we don't need it
2576 }
2577 else pOS2MET->SeekRel(-1); // no header, go back one byte
2578
2579 // loop through Order:
2580 while (pOS2MET->Tell()<nMaxPos && pOS2MET->GetError()==ERRCODE_NONEErrCode(0)) {
2581 pOS2MET->ReadUChar( nbyte ); nOrderID=static_cast<sal_uInt16>(nbyte) & 0x00ff;
2582 if (nOrderID==0x00fe) {
2583 pOS2MET->ReadUChar( nbyte );
2584 nOrderID=(nOrderID << 8) | (static_cast<sal_uInt16>(nbyte) & 0x00ff);
2585 }
2586 if (nOrderID>0x00ff || nOrderID==GOrdPolygn0xF3) {
2587 // ooo: As written in OS2 documentation, the order length should now
2588 // be written as big endian word. (Quote: "Highorder byte precedes loworder byte").
2589 // In reality there are files in which the length is stored as little endian word
2590 // (at least for nOrderID==GOrdPolygn)
2591 // So we throw a coin or what else can we do?
2592 pOS2MET->ReadUChar( nbyte ); nOrderLen=static_cast<sal_uInt16>(nbyte)&0x00ff;
2593 pOS2MET->ReadUChar( nbyte ); if (nbyte!=0) nOrderLen=nOrderLen<<8|(static_cast<sal_uInt16>(nbyte)&0x00ff);
2594 }
2595 else if (nOrderID==GOrdSTxAlg0x36 || nOrderID==GOrdPTxAlg0x76) nOrderLen=2;
2596 else if ((nOrderID&0xff88)==0x0008) nOrderLen=1;
2597 else if (nOrderID==0x0000 || nOrderID==0x00ff) nOrderLen=0;
2598 else { pOS2MET->ReadUChar( nbyte ); nOrderLen=static_cast<sal_uInt16>(nbyte) & 0x00ff; }
2599 auto nPos=pOS2MET->Tell();
2600 ReadOrder(nOrderID, nOrderLen);
2601 if (nPos+nOrderLen < pOS2MET->Tell()) {
2602 SAL_INFO("filter.os2met","Order is shorter than expected. OrderID: " << nOrderID << " Position: " << nPos)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Order is shorter than expected. OrderID: "
<< nOrderID << " Position: " << nPos) == 1
) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2602" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Order is shorter than expected. OrderID: "
<< nOrderID << " Position: " << nPos), 0);
} else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Order is shorter than expected. OrderID: " <<
nOrderID << " Position: " << nPos; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2602" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Order is shorter than expected. OrderID: " <<
nOrderID << " Position: " << nPos) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2602" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Order is shorter than expected. OrderID: "
<< nOrderID << " Position: " << nPos), 0);
} else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Order is shorter than expected. OrderID: " <<
nOrderID << " Position: " << nPos; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2602" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2603 }
2604 else if (nPos+nOrderLen != pOS2MET->Tell()) {
2605 SAL_INFO("filter.os2met","Order was not read completely. OrderID: " << nOrderID << " Position: " << nPos)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Order was not read completely. OrderID: "
<< nOrderID << " Position: " << nPos) == 1
) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"
), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2605" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Order was not read completely. OrderID: "
<< nOrderID << " Position: " << nPos), 0);
} else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Order was not read completely. OrderID: " <<
nOrderID << " Position: " << nPos; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2605" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Order was not read completely. OrderID: " <<
nOrderID << " Position: " << nPos) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2605" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Order was not read completely. OrderID: "
<< nOrderID << " Position: " << nPos), 0);
} else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Order was not read completely. OrderID: " <<
nOrderID << " Position: " << nPos; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2605" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2606 }
2607 pOS2MET->Seek(nPos+nOrderLen);
2608 }
2609
2610 pOS2MET=pSave;
2611 if (xOrdFile->GetError()) {
2612 pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERRORErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 21 ));
2613 ErrorCode=10;
2614 }
2615 xOrdFile.reset();
2616 break;
2617 }
2618 case DscGrfObjMagic0xBBA6: {
2619 sal_uInt16 nDscID, nDscLen;
2620 sal_uInt8 nbyte;
2621
2622 auto nMaxPos = pOS2MET->Tell() + nFieldSize;
2623 while (pOS2MET->Tell()<nMaxPos && pOS2MET->GetError()==ERRCODE_NONEErrCode(0)) {
2624 pOS2MET->ReadUChar( nbyte ); nDscID =static_cast<sal_uInt16>(nbyte) & 0x00ff;
2625 pOS2MET->ReadUChar( nbyte ); nDscLen=static_cast<sal_uInt16>(nbyte) & 0x00ff;
2626 auto nPos = pOS2MET->Tell();
2627 ReadDsc(nDscID);
2628 pOS2MET->Seek(nPos+nDscLen);
2629 }
2630 break;
2631 }
2632 case DatGrfObjMagic0xBBEE: {
2633 if (!xOrdFile) {
2634 xOrdFile.reset(new SvMemoryStream);
2635 xOrdFile->SetEndian(SvStreamEndian::LITTLE);
2636 }
2637 std::unique_ptr<sal_uInt8[]> pBuf(new sal_uInt8[nFieldSize]);
2638 pOS2MET->ReadBytes(pBuf.get(), nFieldSize);
2639 xOrdFile->WriteBytes(pBuf.get(), nFieldSize);
2640 break;
2641 }
2642 case MapCodFntMagic0x8AAB:
2643 ReadFont(nFieldSize);
2644 break;
2645
2646 case MapDatResMagic0xC3AB:
2647 break;
2648 }
2649}
2650
2651void OS2METReader::ReadOS2MET( SvStream & rStreamOS2MET, GDIMetaFile & rGDIMetaFile )
2652{
2653 ErrorCode=0;
2654
2655 pOS2MET = &rStreamOS2MET;
2656 auto nOrigPos = pOS2MET->Tell();
2657 SvStreamEndian nOrigNumberFormat = pOS2MET->GetEndian();
2658
2659 bCoord32 = true;
2660 pPaletteStack=nullptr;
2661 pAreaStack=nullptr;
2662 pPathStack=nullptr;
2663 pPathList=nullptr;
2664 pFontList=nullptr;
2665 pBitmapList=nullptr;
2666 pAttrStack=nullptr;
2667
2668 aDefAttr.aLinCol =COL_BLACK;
2669 aDefAttr.aLinBgCol =COL_WHITE;
2670 aDefAttr.eLinMix =RasterOp::OverPaint;
2671 aDefAttr.eLinBgMix =RasterOp::OverPaint;
2672 aDefAttr.aChrCol =COL_BLACK;
2673 aDefAttr.aChrBgCol =COL_WHITE;
2674 aDefAttr.eChrMix =RasterOp::OverPaint;
2675 aDefAttr.eChrBgMix =RasterOp::OverPaint;
2676 aDefAttr.aMrkCol =COL_BLACK;
2677 aDefAttr.aMrkBgCol =COL_WHITE;
2678 aDefAttr.eMrkMix =RasterOp::OverPaint;
2679 aDefAttr.eMrkBgMix =RasterOp::OverPaint;
2680 aDefAttr.aPatCol =COL_BLACK;
2681 aDefAttr.aPatBgCol =COL_WHITE;
2682 aDefAttr.ePatMix =RasterOp::OverPaint;
2683 aDefAttr.ePatBgMix =RasterOp::OverPaint;
2684 aDefAttr.aImgCol =COL_BLACK;
2685 aDefAttr.aImgBgCol =COL_WHITE;
2686 aDefAttr.eImgMix =RasterOp::OverPaint;
2687 aDefAttr.eImgBgMix =RasterOp::OverPaint;
2688 aDefAttr.nArcP =1;
2689 aDefAttr.nArcQ =1;
2690 aDefAttr.nArcR =0;
2691 aDefAttr.nArcS =0;
2692 aDefAttr.nChrAng =0;
2693 aDefAttr.aChrCellSize=Size(12,12);
2694 aDefAttr.nChrSet =0;
2695 aDefAttr.aCurPos =Point(0,0);
2696 aDefAttr.eLinStyle =PEN_SOLID;
2697 aDefAttr.nLinWidth =0;
2698 aDefAttr.aMrkCellSize=Size(10,10);
2699 aDefAttr.nMrkPrec =0x01;
2700 aDefAttr.nMrkSet =0xff;
2701 aDefAttr.nMrkSymbol =0x01;
2702 aDefAttr.bFill =true;
2703 aDefAttr.nStrLinWidth=0;
2704
2705 aAttr=aDefAttr;
2706
2707 xOrdFile.reset();
2708
2709 rGDIMetaFile.Record(pVirDev);
2710
2711 pOS2MET->SetEndian(SvStreamEndian::LITTLE);
2712
2713 sal_uInt64 nPos = pOS2MET->Tell();
2714
2715 for (;;) {
2716
2717 sal_uInt16 nFieldSize = ReadBigEndianWord();
2718 sal_uInt8 nMagicByte(0);
2719 pOS2MET->ReadUChar( nMagicByte );
2720 if (nMagicByte!=0xd3) {
2721 pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERRORErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 21 ));
2722 ErrorCode=7;
2723 break;
2724 }
2725
2726 sal_uInt16 nFieldType(0);
2727 pOS2MET->ReadUInt16(nFieldType);
2728
2729 pOS2MET->SeekRel(3);
2730
2731 if (pOS2MET->GetError())
2732 break;
2733
2734 if (nFieldType==EndDocumnMagic0xA8A9)
2735 break;
2736
2737 if (pOS2MET->eof() || nFieldSize < 8)
2738 {
2739 pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERRORErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 21 ));
2740 ErrorCode=8;
2741 break;
2742 }
2743
2744 nPos+=8; nFieldSize-=8;
2745
2746 if (nFieldSize > pOS2MET->remainingSize())
2747 {
2748 pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERRORErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 21 ));
2749 ErrorCode=8;
2750 break;
2751 }
2752
2753 ReadField(nFieldType, nFieldSize);
2754 nPos += nFieldSize;
2755
2756 if (pOS2MET->Tell() > nPos)
2757 {
2758 pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERRORErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 21 ));
2759 ErrorCode=9;
2760 break;
2761 }
2762 pOS2MET->Seek(nPos);
2763 }
2764
2765 rGDIMetaFile.Stop();
2766
2767 rGDIMetaFile.SetPrefMapMode( aGlobMapMode );
2768
2769 if( aBoundingRect.GetWidth() && aBoundingRect.GetHeight() )
2770 rGDIMetaFile.SetPrefSize( aBoundingRect.GetSize() );
2771 else
2772 {
2773 if( aCalcBndRect.Left() || aCalcBndRect.Top() )
2774 rGDIMetaFile.Move( -aCalcBndRect.Left(), -aCalcBndRect.Top() );
2775
2776 rGDIMetaFile.SetPrefSize( aCalcBndRect.GetSize() );
2777 }
2778
2779 pOS2MET->SetEndian(nOrigNumberFormat);
2780
2781 if (pOS2MET->GetError()) {
2782 SAL_INFO("filter.os2met","Error code: " << ErrorCode)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "filter.os2met")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Error code: " <<
ErrorCode) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2782" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Error code: " << ErrorCode), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Error code: " << ErrorCode; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2782" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Error code: " << ErrorCode) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2782" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Error code: " << ErrorCode), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Error code: " << ErrorCode; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("filter.os2met"), ("/home/maarten/src/libreoffice/core/filter/source/graphicfilter/ios2met/ios2met.cxx"
":" "2782" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2783 pOS2MET->Seek(nOrigPos);
2784 }
2785}
2786
2787//================== GraphicImport - the exported function ================
2788
2789extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) bool
2790imeGraphicImport( SvStream & rStream, Graphic & rGraphic, FilterConfigItem* )
2791{
2792 OS2METReader aOS2METReader;
2793 GDIMetaFile aMTF;
2794 bool bRet = false;
2795
2796 try
2797 {
2798 aOS2METReader.ReadOS2MET( rStream, aMTF );
2799
2800 if ( !rStream.GetError() )
1
Taking false branch
2801 {
2802 rGraphic=Graphic( aMTF );
2803 bRet = true;
2804 }
2805 }
2806 catch (const css::uno::Exception&)
2807 {
2808 }
2809
2810 return bRet;
2
Calling '~OS2METReader'
2811}
2812
2813/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx

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#ifndef INCLUDED_VCL_PTR_HXX
21#define INCLUDED_VCL_PTR_HXX
22
23#include <sal/config.h>
24
25#include <rtl/ref.hxx>
26
27#include <utility>
28#include <type_traits>
29
30#ifdef DBG_UTIL
31#ifndef _WIN32
32#include <vcl/vclmain.hxx>
33#endif
34#endif
35
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase(
44 int (*)[sizeof(T)])
45{ return std::is_base_of<VclReferenceBase, T>::value; }
46
47} // namespace vcl::detail
48
49/**
50 * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
51 *
52 * For more details on the design please see vcl/README.lifecycle
53 *
54 * @param reference_type must be a subclass of vcl::Window
55 */
56template <class reference_type>
57class VclPtr
58{
59 static_assert(
60 vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>(
61 nullptr),
62 "template argument type must be derived from VclReferenceBase");
63
64 ::rtl::Reference<reference_type> m_rInnerRef;
65
66public:
67 /** Constructor...
68 */
69 VclPtr()
70 : m_rInnerRef()
71 {}
72
73 /** Constructor...
74 */
75 VclPtr (reference_type * pBody)
76 : m_rInnerRef(pBody)
77 {}
78
79 /** Constructor... that doesn't take a ref.
80 */
81 VclPtr (reference_type * pBody, __sal_NoAcquire)
82 : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
83 {}
84
85 /** Up-casting conversion constructor: Copies interface reference.
86
87 Does not work for up-casts to ambiguous bases. For the special case of
88 up-casting to Reference< XInterface >, see the corresponding conversion
89 operator.
90
91 @param rRef another reference
92 */
93 template< class derived_type >
94 VclPtr(
95 const VclPtr< derived_type > & rRef,
96 typename std::enable_if<
97 std::is_base_of<reference_type, derived_type>::value, int>::type
98 = 0 )
99 : m_rInnerRef( static_cast<reference_type*>(rRef) )
100 {
101 }
102
103#if defined(DBG_UTIL) && !defined(_WIN32)
104 virtual ~VclPtr()
105 {
106 assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain
::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 106, __extension__ __PRETTY_FUNCTION__))
;
107 // We can be one of the intermediate counts, but if we are the last
108 // VclPtr keeping this object alive, then something forgot to call dispose().
109 assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
110 && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 }
112 VclPtr(VclPtr const &) = default;
113 VclPtr(VclPtr &&) = default;
114 VclPtr & operator =(VclPtr const &) = default;
115 VclPtr & operator =(VclPtr &&) = default;
116#endif
117
118 /**
119 * A construction helper for VclPtr. Since VclPtr types are created
120 * with a reference-count of one - to help fit into the existing
121 * code-flow; this helps us to construct them easily.
122 *
123 * For more details on the design please see vcl/README.lifecycle
124 *
125 * @tparam reference_type must be a subclass of vcl::Window
126 */
127 template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg)
128 {
129 return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
130 }
131
132 /** Probably most common used: handle->someBodyOp().
133 */
134 reference_type * operator->() const
135 {
136 return m_rInnerRef.get();
137 }
138
139 /** Get the body. Can be used instead of operator->().
140 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
141 are the same.
142 */
143 reference_type * get() const
144 {
145 return m_rInnerRef.get();
146 }
147
148 void set(reference_type *pBody)
149 {
150 m_rInnerRef.set(pBody);
151 }
152
153 void reset(reference_type *pBody)
154 {
155 m_rInnerRef.set(pBody);
156 }
157
158 /** Up-casting copy assignment operator.
159
160 Does not work for up-casts to ambiguous bases.
161
162 @param rRef another reference
163 */
164 template<typename derived_type>
165 typename std::enable_if<
166 std::is_base_of<reference_type, derived_type>::value,
167 VclPtr &>::type
168 operator =(VclPtr<derived_type> const & rRef)
169 {
170 m_rInnerRef.set(rRef.get());
171 return *this;
172 }
173
174 VclPtr & operator =(reference_type * pBody)
175 {
176 m_rInnerRef.set(pBody);
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
183 }
184
185 explicit operator bool () const
186 {
187 return m_rInnerRef.get() != nullptr;
188 }
189
190 void clear()
191 {
192 m_rInnerRef.clear();
193 }
194
195 void reset()
196 {
197 m_rInnerRef.clear();
198 }
199
200 void disposeAndClear()
201 {
202 // hold it alive for the lifetime of this method
203 ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
4
Calling copy constructor for 'Reference<VirtualDevice>'
7
Returning from copy constructor for 'Reference<VirtualDevice>'
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
8
Calling 'Reference::clear'
15
Returning; memory was released
205 if (aTmp.get()) {
16
Calling 'Reference::get'
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

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#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
5
Assuming field 'm_pBody' is non-null
6
Taking true branch
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody)
113 m_pBody->release();
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody
8.1
Field 'm_pBody' is non-null
8.1
Field 'm_pBody' is non-null
8.1
Field 'm_pBody' is non-null
8.1
Field 'm_pBody' is non-null
)
9
Taking true branch
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
10
Calling 'VclReferenceBase::release'
14
Returning; memory was released
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
17
Use of memory after it is freed
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.hxx

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#ifndef INCLUDED_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
11
Assuming the condition is true
12
Taking true branch
40 delete this;
13
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif