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