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