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