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