/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_filter.hxx" #include #include #include #include #include #include #include // MT: NOOLDSV, someone should change the code... enum PenStyle { PEN_NULL, PEN_SOLID, PEN_DOT, PEN_DASH, PEN_DASHDOT }; //============================== defines =================================== #define OOODEBUG(str,Num) //InfoBox(NULL,String(str)+String(" ")+String(Num)).Execute(); // -----------------------------Feld-Typen------------------------------- #define BegDocumnMagic 0xA8A8 /* Begin Document */ #define EndDocumnMagic 0xA8A9 /* End Document */ #define BegResGrpMagic 0xC6A8 /* Begin Resource Group */ #define EndResGrpMagic 0xC6A9 /* End Resource Group */ #define BegColAtrMagic 0x77A8 /* Begin Color Attribute Table */ #define EndColAtrMagic 0x77A9 /* End Color Attribute Table */ #define BlkColAtrMagic 0x77B0 /* Color Attribute Table */ #define MapColAtrMagic 0x77AB /* Map Color Attribute Table */ #define BegImgObjMagic 0xFBA8 /* Begin Image Object */ #define EndImgObjMagic 0xFBA9 /* End Image Object */ #define DscImgObjMagic 0xFBA6 /* Image Data Descriptor */ #define DatImgObjMagic 0xFBEE /* Image Picture Data */ #define BegObEnv1Magic 0xC7A8 /* Begin Object Environment Group */ #define EndObEnv1Magic 0xC7A9 /* End Object Environment Group */ #define BegGrfObjMagic 0xBBA8 /* Begin Graphics Object */ #define EndGrfObjMagic 0xBBA9 /* End Graphics Object */ #define DscGrfObjMagic 0xBBA6 /* Graphics Data Descritor */ #define DatGrfObjMagic 0xBBEE /* Graphics Data */ #define MapCodFntMagic 0x8AAB /* Map Coded Font */ #define MapDatResMagic 0xC3AB /* Map Data Resource */ // -----------------------------Order-Typen------------------------------- #define GOrdGivArc 0xC6 /* 1 Arc at given position */ #define GOrdCurArc 0x86 /* 1 Arc at current position */ #define GOrdGivBzr 0xE5 /* 1 Beziercurve at given position */ #define GOrdCurBzr 0xA5 /* 1 Beziercurve at current position */ #define GOrdGivBox 0xC0 /* 1 Box at given position */ #define GOrdCurBox 0x80 /* 1 Box at current position */ #define GOrdGivFil 0xC5 /* 1 Fillet at given position */ #define GOrdCurFil 0x85 /* 1 Fillet at current position */ #define GOrdGivCrc 0xC7 /* 1 Full arc (circle) at given position */ #define GOrdCurCrc 0x87 /* 1 Full arc (circle) at current position */ #define GOrdGivLin 0xC1 /* 1 Line at given position */ #define GOrdCurLin 0x81 /* 1 Line at current position */ #define GOrdGivMrk 0xC2 /* 1 Marker at given position */ #define GOrdCurMrk 0x82 /* 1 Marker at current position */ #define GOrdGivArP 0xE3 /* 1 Partial arc at given position */ #define GOrdCurArP 0xA3 /* 1 Partial arc at current position */ #define GOrdGivRLn 0xE1 /* 1 Relative line at given position */ #define GOrdCurRLn 0xA1 /* 1 Relative line at current position */ #define GOrdGivSFl 0xE4 /* 1 Sharp fillet at given position */ #define GOrdCurSFl 0xA4 /* 1 Sharp fillet at current position */ #define GOrdGivStM 0xF1 /* 1 Character string move at given position */ #define GOrdCurStM 0xB1 /* 1 Character string move at current position */ #define GOrdGivStr 0xC3 /* 1 Character string at given position */ #define GOrdCurStr 0x83 /* 1 Character string at current position */ #define GOrdGivStx 0xFEF0 /* 2 Character string extended at given position */ #define GOrdCurStx 0xFEB0 /* 2 Character string extended at current position */ #define GOrdGivImg 0xD1 /* 1 Begin Image at given position */ #define GOrdCurImg 0x91 /* 1 Begin Image at current position */ #define GOrdImgDat 0x92 /* 1 Image data */ #define GOrdEndImg 0x93 /* 1 End Image */ #define GOrdBegAra 0x68 /* 0 1 Begin area */ #define GOrdEndAra 0x60 /* 1 End area */ #define GOrdBegElm 0xD2 /* 1 Begin element */ #define GOrdEndElm 0x49 /* 0 1 End element */ #define GOrdBegPth 0xD0 /* 1 Begin path */ #define GOrdEndPth 0x7F /* 0 1 End path */ #define GOrdFilPth 0xD7 /* 1 Fill path */ #define GOrdModPth 0xD8 /* 1 Modify path */ #define GOrdOutPth 0xD4 /* 1 Outline path */ #define GOrdSClPth 0xB4 /* 1 Set clip path */ #define GOrdNopNop 0x00 /* 0 0 No operation */ #define GOrdRemark 0x01 /* 1 Comment */ #define GOrdSegLab 0xD3 /* 1 Label */ #define GOrdBitBlt 0xD6 /* 1 Bitblt */ #define GOrdCalSeg 0x07 /* 1 Call Segment */ #define GOrdSSgBnd 0x32 /* 1 Set segment boundary */ #define GOrdSegChr 0x04 /* 1 Segment characteristics */ #define GOrdCloFig 0x7D /* 0 1 Close Figure */ #define GOrdEndSym 0xFF /* 0 0 End of symbol definition */ #define GOrdEndPlg 0x3E /* 0 1 End prolog */ #define GOrdEscape 0xD5 /* 1 Escape */ #define GOrdExtEsc 0xFED5 /* 2 Extended Escape */ #define GOrdPolygn 0xF3 /* 2 Polygons */ #define GOrdStkPop 0x3F /* 0 1 Pop */ #define GOrdSIvAtr 0x14 /* 1 Set individual attribute */ #define GOrdPIvAtr 0x54 /* 1 Push and set individual attribute */ #define GOrdSColor 0x0A /* 0 1 Set color */ #define GOrdPColor 0x4A /* 0 1 Push and set color */ #define GOrdSIxCol 0xA6 /* 1 Set indexed color */ #define GOrdPIxCol 0xE6 /* 1 Push and set indexed color */ #define GOrdSXtCol 0x26 /* 1 Set extended color */ #define GOrdPXtCol 0x66 /* 1 Push and set extended color */ #define GOrdSBgCol 0x25 /* 1 Set background color */ #define GOrdPBgCol 0x65 /* 1 Push and set background color */ #define GOrdSBxCol 0xA7 /* 1 Set background indexed color */ #define GOrdPBxCol 0xE7 /* 1 Push and set background indexed color */ #define GOrdSMixMd 0x0C /* 0 1 Set mix */ #define GOrdPMixMd 0x4C /* 0 1 Push and set mix */ #define GOrdSBgMix 0x0D /* 0 1 Set background mix */ #define GOrdPBgMix 0x4D /* 0 1 Push and set background mix */ #define GOrdSPtSet 0x08 /* 0 1 Set pattern set */ #define GOrdPPtSet 0x48 /* 0 1 Push and set pattern set */ #define GOrdSPtSym 0x28 /* 0 1 Set pattern symbol */ #define GOrdPPtSym 0x09 /* 0 1 Push and set pattern symbol */ #define GOrdSPtRef 0xA0 /* 1 Set model pattern reference */ #define GOrdPPtRef 0xE0 /* 1 Push and set pattern reference point */ #define GOrdSLnEnd 0x1A /* 0 1 Set line end */ #define GOrdPLnEnd 0x5A /* 0 1 Push and set line end */ #define GOrdSLnJoi 0x1B /* 0 1 Set line join */ #define GOrdPLnJoi 0x5B /* 0 1 Push and set line join */ #define GOrdSLnTyp 0x18 /* 0 1 Set line type */ #define GOrdPLnTyp 0x58 /* 0 1 Push and set line type */ #define GOrdSLnWdt 0x19 /* 0 1 Set line width */ #define GOrdPLnWdt 0x59 /* 0 1 Push and set line width */ #define GOrdSFrLWd 0x11 /* 1 Set fractional line width */ #define GOrdPFrLWd 0x51 /* 1 Push and set fractional line width */ #define GOrdSStLWd 0x15 /* 1 Set stroke line width */ #define GOrdPStLWd 0x55 /* 1 Push and set stroke line width */ #define GOrdSChDir 0x3A /* 0 1 Set character direction */ #define GOrdPChDir 0x7A /* 0 1 Push and set character direction */ #define GOrdSChPrc 0x39 /* 0 1 Set character precision */ #define GOrdPChPrc 0x79 /* 0 1 Push and set character precision */ #define GOrdSChSet 0x38 /* 0 1 Set character set */ #define GOrdPChSet 0x78 /* 0 1 Push and set character set */ #define GOrdSChAng 0x34 /* 1 Set character angle */ #define GOrdPChAng 0x74 /* 1 Push and set character angle */ #define GOrdSChBrx 0x05 /* 1 Set character break extra */ #define GOrdPChBrx 0x45 /* 1 Push and set character break extra */ #define GOrdSChCel 0x33 /* 1 Set character cell */ #define GOrdPChCel 0x03 /* 1 Push and set character cell */ #define GOrdSChXtr 0x17 /* 1 Set character extra */ #define GOrdPChXtr 0x57 /* 1 Push and set character extra */ #define GOrdSChShr 0x35 /* 1 Set character shear */ #define GOrdPChShr 0x75 /* 1 Push and set character shear */ #define GOrdSTxAlg 0x36 /* 0 2 Set text allingment */ #define GOrdPTxAlg 0x76 /* 0 2 Push and set text allingment */ #define GOrdSMkPrc 0x3B /* 0 1 Set marker precision */ #define GOrdPMkPrc 0x7B /* 0 1 Push and set marker precision */ #define GOrdSMkSet 0x3C /* 0 1 Set marker set */ #define GOrdPMkSet 0x7C /* 0 1 Push and set marker set */ #define GOrdSMkSym 0x29 /* 0 1 Set marker symbol */ #define GOrdPMkSym 0x69 /* 0 1 Push and set marker symbol */ #define GOrdSMkCel 0x37 /* 1 Set marker cell */ #define GOrdPMkCel 0x77 /* 1 Push and set marker cell */ #define GOrdSArcPa 0x22 /* 1 Set arc parameters */ #define GOrdPArcPa 0x62 /* 1 Push and set arc parameters */ #define GOrdSCrPos 0x21 /* 1 Set current position */ #define GOrdPCrPos 0x61 /* 1 Push and set current position */ #define GOrdSMdTrn 0x24 /* 1 Set model transform */ #define GOrdPMdTrn 0x64 /* 1 Push and set model transform */ #define GOrdSPkIdn 0x43 /* 1 Set pick identifier */ #define GOrdPPkIdn 0x23 /* 1 Push and set pick identifier */ #define GOrdSVwTrn 0x31 /* 1 Set viewing transform */ #define GOrdSVwWin 0x27 /* 1 Set viewing window */ #define GOrdPVwWin 0x67 /* 1 Push and set viewing window */ //============================ OS2METReader ================================== struct OSPalette { OSPalette * pSucc; sal_uInt32 * p0RGB; // Darf auch NULL sein! sal_uInt16 nSize; }; struct OSArea { OSArea * pSucc; sal_uInt8 nFlags; PolyPolygon aPPoly; sal_Bool bClosed; Color aCol; Color aBgCol; RasterOp eMix; RasterOp eBgMix; sal_Bool bFill; OSArea(){} ~OSArea(){} }; struct OSPath { OSPath* pSucc; sal_uInt32 nID; PolyPolygon aPPoly; sal_Bool bClosed; sal_Bool bStroke; OSPath(){} ~OSPath(){} }; struct OSFont { OSFont * pSucc; sal_uLong nID; Font aFont; OSFont(){} ~OSFont(){} }; struct OSBitmap { OSBitmap * pSucc; sal_uLong nID; Bitmap aBitmap; // Waehrend des Lesens der Bitmap benoetigt: SvStream * pBMP; // Zeiger auf temporaere Windows-BMP-Datei oder NULL sal_uInt32 nWidth, nHeight; sal_uInt16 nBitsPerPixel; sal_uLong nMapPos; OSBitmap(){} ~OSBitmap(){} }; struct OSAttr { OSAttr * pSucc; sal_uInt16 nPushOrder; sal_uInt8 nIvAttrA, nIvAttrP; // Spezialvariablen fuer den Order "GOrdPIvAtr" Color aLinCol; Color aLinBgCol; RasterOp eLinMix; RasterOp eLinBgMix; Color aChrCol; Color aChrBgCol; RasterOp eChrMix; RasterOp eChrBgMix; Color aMrkCol; Color aMrkBgCol; RasterOp eMrkMix; RasterOp eMrkBgMix; Color aPatCol; Color aPatBgCol; RasterOp ePatMix; RasterOp ePatBgMix; Color aImgCol; Color aImgBgCol; RasterOp eImgMix; RasterOp eImgBgMix; long nArcP, nArcQ, nArcR, nArcS; short nChrAng; // long nChrBreakExtra; Size aChrCellSize; // sal_uInt8 nChrDir; // long nChrExtra; // sal_uInt8 nChrPrec; sal_uLong nChrSet; // Size aChrShear; Point aCurPos; // long nFracLinWidth; // sal_uInt8 nLinEnd; // sal_uInt8 nLinJoin; PenStyle eLinStyle; sal_uInt16 nLinWidth; Size aMrkCellSize; sal_uInt8 nMrkPrec; sal_uInt8 nMrkSet; sal_uInt8 nMrkSymbol; // //... aModTransform; // Point aPatRef; // sal_uInt8 nPatSet; sal_Bool bFill; // sal_uLong nPickId; // //... aSegBound; sal_uInt16 nStrLinWidth; // sal_uInt8 nTxtAlignHor,nTxtAlignVer; // //... aViewTransform; // //... aViewWindow; OSAttr(){} ~OSAttr(){} }; class OS2METReader { private: long ErrorCode; SvStream * pOS2MET; // Die einzulesende OS2MET-Datei VirtualDevice * pVirDev; // Hier werden die Drawing-Methoden aufgerufen. // Dabei findet ein Recording in das GDIMetaFile // statt. sal_uLong nOrigPos; // Anfaengliche Position in pOS2MET sal_uInt16 nOrigNumberFormat; // Anfaengliches Nummern-Format von pOS2MET Rectangle aBoundingRect; // Boundingrectangle wie in Datei angegeben Rectangle aCalcBndRect; // selbst ermitteltes Boundingrectangle MapMode aGlobMapMode; // Aufloesung des Bildes sal_Bool bCoord32; OSPalette * pPaletteStack; LineInfo aLineInfo; OSArea * pAreaStack; // Areas, die in Arbeit sind OSPath * pPathStack; // Paths, die in Arbeit sind OSPath * pPathList; // Vollendete Paths OSFont * pFontList; OSBitmap * pBitmapList; OSAttr aDefAttr; OSAttr aAttr; OSAttr * pAttrStack; SvStream * pOrdFile; sal_Bool Callback(sal_uInt16 nPercent); void AddPointsToPath(const Polygon & rPoly); void AddPointsToArea(const Polygon & rPoly); void CloseFigure(); void PushAttr(sal_uInt16 nPushOrder); void PopAttr(); void ChangeBrush( const Color& rPatColor, const Color& rBGColor, sal_Bool bFill ); void SetPen( const Color& rColor, sal_uInt16 nStrLinWidth = 0, PenStyle ePenStyle = PEN_SOLID ); void SetRasterOp(RasterOp eROP); void SetPalette0RGB(sal_uInt16 nIndex, sal_uLong nCol); sal_uInt32 GetPalette0RGB(sal_uInt32 nIndex); // Holt Farbe aus der Palette, oder, wenn nicht vorhanden, // interpretiert nIndex als direkten RGB-Wert. Color GetPaletteColor(sal_uInt32 nIndex); sal_Bool IsLineInfo(); void DrawPolyLine( const Polygon& rPolygon ); void DrawPolygon( const Polygon& rPolygon ); void DrawPolyPolygon( const PolyPolygon& rPolygon ); sal_uInt16 ReadBigEndianWord(); sal_uLong ReadBigEndian3BytesLong(); sal_uLong ReadLittleEndian3BytesLong(); long ReadCoord(sal_Bool b32); Point ReadPoint( const sal_Bool bAdjustBoundRect = sal_True ); RasterOp OS2MixToRasterOp(sal_uInt8 nMix); void ReadLine(sal_Bool bGivenPos, sal_uInt16 nOrderLen); void ReadRelLine(sal_Bool bGivenPos, sal_uInt16 nOrderLen); void ReadBox(sal_Bool bGivenPos); void ReadBitBlt(); void ReadChrStr(sal_Bool bGivenPos, sal_Bool bMove, sal_Bool bExtra, sal_uInt16 nOrderLen); void ReadArc(sal_Bool bGivenPos); void ReadFullArc(sal_Bool bGivenPos, sal_uInt16 nOrderSize); void ReadPartialArc(sal_Bool bGivenPos, sal_uInt16 nOrderSize); void ReadPolygons(); void ReadBezier(sal_Bool bGivenPos, sal_uInt16 nOrderLen); void ReadFillet(sal_Bool bGivenPos, sal_uInt16 nOrderLen); void ReadFilletSharp(sal_Bool bGivenPos, sal_uInt16 nOrderLen); void ReadMarker(sal_Bool bGivenPos, sal_uInt16 nOrderLen); void ReadOrder(sal_uInt16 nOrderID, sal_uInt16 nOrderLen); void ReadDsc(sal_uInt16 nDscID, sal_uInt16 nDscLen); void ReadImageData(sal_uInt16 nDataID, sal_uInt16 nDataLen); void ReadFont(sal_uInt16 nFieldSize); void ReadField(sal_uInt16 nFieldType, sal_uInt16 nFieldSize); public: OS2METReader(); ~OS2METReader(); void ReadOS2MET( SvStream & rStreamOS2MET, GDIMetaFile & rGDIMetaFile ); // Liesst aus dem Stream eine OS2MET-Datei und fuellt das GDIMetaFile }; //=================== Methoden von OS2METReader ============================== sal_Bool OS2METReader::Callback(sal_uInt16 /*nPercent*/) { /* if (pCallback!=NULL) { if (((*pCallback)(pCallerData,nPercent))==sal_True) { pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERROR); return sal_True; } } */ return sal_False; } OS2METReader::OS2METReader() { } OS2METReader::~OS2METReader() { } sal_Bool OS2METReader::IsLineInfo() { return ( ! ( aLineInfo.IsDefault() || ( aLineInfo.GetStyle() == LINE_NONE ) || ( pVirDev->GetLineColor() == COL_TRANSPARENT ) ) ); } void OS2METReader::DrawPolyLine( const Polygon& rPolygon ) { if ( aLineInfo.GetStyle() == LINE_DASH || ( aLineInfo.GetWidth() > 1 ) ) pVirDev->DrawPolyLine( rPolygon, aLineInfo ); else pVirDev->DrawPolyLine( rPolygon ); } void OS2METReader::DrawPolygon( const Polygon& rPolygon ) { if ( IsLineInfo() ) { pVirDev->Push( PUSH_LINECOLOR ); pVirDev->SetLineColor( COL_TRANSPARENT ); pVirDev->DrawPolygon( rPolygon ); pVirDev->Pop(); pVirDev->DrawPolyLine( rPolygon, aLineInfo ); } else pVirDev->DrawPolygon( rPolygon ); } void OS2METReader::DrawPolyPolygon( const PolyPolygon& rPolyPolygon ) { if ( IsLineInfo() ) { pVirDev->Push( PUSH_LINECOLOR ); pVirDev->SetLineColor( COL_TRANSPARENT ); pVirDev->DrawPolyPolygon( rPolyPolygon ); pVirDev->Pop(); for ( sal_uInt16 i = 0; i < rPolyPolygon.Count(); i++ ) pVirDev->DrawPolyLine( rPolyPolygon.GetObject( i ), aLineInfo ); } else pVirDev->DrawPolyPolygon( rPolyPolygon ); } void OS2METReader::AddPointsToArea(const Polygon & rPoly) { sal_uInt16 nOldSize, nNewSize,i; if (pAreaStack==NULL || rPoly.GetSize()==0) return; PolyPolygon * pPP=&(pAreaStack->aPPoly); if (pPP->Count()==0 || pAreaStack->bClosed==sal_True) pPP->Insert(rPoly); else { Polygon aLastPoly(pPP->GetObject(pPP->Count()-1)); nOldSize=aLastPoly.GetSize(); if (aLastPoly.GetPoint(nOldSize-1)==rPoly.GetPoint(0)) nOldSize--; nNewSize=nOldSize+rPoly.GetSize(); aLastPoly.SetSize(nNewSize); for (i=nOldSize; iReplace(aLastPoly,pPP->Count()-1); } pAreaStack->bClosed=sal_False; } void OS2METReader::AddPointsToPath(const Polygon & rPoly) { sal_uInt16 nOldSize, nNewSize,i; if (pPathStack==NULL || rPoly.GetSize()==0) return; PolyPolygon * pPP=&(pPathStack->aPPoly); if (pPP->Count()==0 /*|| pPathStack->bClosed==sal_True*/) pPP->Insert(rPoly); else { Polygon aLastPoly(pPP->GetObject(pPP->Count()-1)); nOldSize=aLastPoly.GetSize(); if (aLastPoly.GetPoint(nOldSize-1)!=rPoly.GetPoint(0)) pPP->Insert(rPoly); else { nOldSize--; nNewSize=nOldSize+rPoly.GetSize(); aLastPoly.SetSize(nNewSize); for (i=nOldSize; iReplace(aLastPoly,pPP->Count()-1); } } pPathStack->bClosed=sal_False; } void OS2METReader::CloseFigure() { if (pAreaStack!=NULL) pAreaStack->bClosed=sal_True; else if (pPathStack!=NULL) pPathStack->bClosed=sal_True; } void OS2METReader::PushAttr(sal_uInt16 nPushOrder) { OSAttr * p; p=new OSAttr; *p=aAttr; p->pSucc=pAttrStack; pAttrStack=p; p->nPushOrder=nPushOrder; } void OS2METReader::PopAttr() { OSAttr * p=pAttrStack; if (p==NULL) return; switch (p->nPushOrder) { case GOrdPIvAtr: switch (p->nIvAttrA) { case 1: switch (p->nIvAttrP) { case 1: aAttr.aLinCol=p->aLinCol; break; case 2: aAttr.aChrCol=p->aChrCol; break; case 3: aAttr.aMrkCol=p->aMrkCol; break; case 4: aAttr.aPatCol=p->aPatCol; break; case 5: aAttr.aImgCol=p->aImgCol; break; } break; case 2: switch (p->nIvAttrP) { case 1: aAttr.aLinBgCol=p->aLinBgCol; break; case 2: aAttr.aChrBgCol=p->aChrBgCol; break; case 3: aAttr.aMrkBgCol=p->aMrkBgCol; break; case 4: aAttr.aPatBgCol=p->aPatBgCol; break; case 5: aAttr.aImgBgCol=p->aImgBgCol; break; } break; case 3: switch (p->nIvAttrP) { case 1: aAttr.eLinMix=p->eLinMix; break; case 2: aAttr.eChrMix=p->eChrMix; break; case 3: aAttr.eMrkMix=p->eMrkMix; break; case 4: aAttr.ePatMix=p->ePatMix; break; case 5: aAttr.eImgMix=p->eImgMix; break; } break; case 4: switch (p->nIvAttrP) { case 1: aAttr.eLinBgMix=p->eLinBgMix; break; case 2: aAttr.eChrBgMix=p->eChrBgMix; break; case 3: aAttr.eMrkBgMix=p->eMrkBgMix; break; case 4: aAttr.ePatBgMix=p->ePatBgMix; break; case 5: aAttr.eImgBgMix=p->eImgBgMix; break; } break; } break; case GOrdPLnTyp: aAttr.eLinStyle=p->eLinStyle; break; case GOrdPLnWdt: aAttr.nLinWidth=p->nLinWidth; break; case GOrdPStLWd: aAttr.nStrLinWidth=p->nStrLinWidth; break; case GOrdPChSet: aAttr.nChrSet=p->nChrSet; break; case GOrdPChAng: aAttr.nChrAng=p->nChrAng; break; case GOrdPMixMd: aAttr.eLinMix=p->eLinMix; aAttr.eChrMix=p->eChrMix; aAttr.eMrkMix=p->eMrkMix; aAttr.ePatMix=p->ePatMix; aAttr.eImgMix=p->eImgMix; break; case GOrdPBgMix: aAttr.eLinBgMix=p->eLinBgMix; aAttr.eChrBgMix=p->eChrBgMix; aAttr.eMrkBgMix=p->eMrkBgMix; aAttr.ePatBgMix=p->ePatBgMix; aAttr.eImgBgMix=p->eImgBgMix; break; case GOrdPPtSym: aAttr.bFill = p->bFill; break; case GOrdPColor: case GOrdPIxCol: case GOrdPXtCol: aAttr.aLinCol=p->aLinCol; aAttr.aChrCol=p->aChrCol; aAttr.aMrkCol=p->aMrkCol; aAttr.aPatCol=p->aPatCol; aAttr.aImgCol=p->aImgCol; break; case GOrdPBgCol: case GOrdPBxCol: aAttr.aLinBgCol=p->aLinBgCol; aAttr.aChrBgCol=p->aChrBgCol; aAttr.aMrkBgCol=p->aMrkBgCol; aAttr.aPatBgCol=p->aPatBgCol; aAttr.aImgBgCol=p->aImgBgCol; break; case GOrdPMkPrc: aAttr.nMrkPrec=aDefAttr.nMrkPrec; break; case GOrdPMkSet: aAttr.nMrkSet=aDefAttr.nMrkSet; break; case GOrdPMkSym: aAttr.nMrkSymbol=aDefAttr.nMrkSymbol; break; case GOrdPMkCel: aAttr.aMrkCellSize=aDefAttr.aMrkCellSize; break; case GOrdPArcPa: aAttr.nArcP=p->nArcP; aAttr.nArcQ=p->nArcQ; aAttr.nArcR=p->nArcR; aAttr.nArcS=p->nArcS; break; case GOrdPCrPos: aAttr.aCurPos=p->aCurPos; break; } pAttrStack=p->pSucc; delete p; } void OS2METReader::ChangeBrush(const Color& rPatColor, const Color& /*rBGColor*/, sal_Bool bFill ) { Color aColor; if( bFill ) aColor = rPatColor; else aColor = Color( COL_TRANSPARENT ); if( pVirDev->GetFillColor() != aColor ) pVirDev->SetFillColor( aColor ); } void OS2METReader::SetPen( const Color& rColor, sal_uInt16 nLineWidth, PenStyle ePenStyle ) { LineStyle eLineStyle( LINE_SOLID ); if ( pVirDev->GetLineColor() != rColor ) pVirDev->SetLineColor( rColor ); aLineInfo.SetWidth( nLineWidth ); sal_uInt16 nDotCount = 0; sal_uInt16 nDashCount = 0; switch ( ePenStyle ) { case PEN_NULL : eLineStyle = LINE_NONE; break; case PEN_DASHDOT : nDashCount++; case PEN_DOT : nDotCount++; nDashCount--; case PEN_DASH : nDashCount++; aLineInfo.SetDotCount( nDotCount ); aLineInfo.SetDashCount( nDashCount ); aLineInfo.SetDistance( nLineWidth ); aLineInfo.SetDotLen( nLineWidth ); aLineInfo.SetDashLen( nLineWidth << 2 ); eLineStyle = LINE_DASH; break; case PEN_SOLID: break; // -Wall not handled... } aLineInfo.SetStyle( eLineStyle ); } void OS2METReader::SetRasterOp(RasterOp eROP) { if (pVirDev->GetRasterOp()!=eROP) pVirDev->SetRasterOp(eROP); } void OS2METReader::SetPalette0RGB(sal_uInt16 nIndex, sal_uLong nCol) { if (pPaletteStack==NULL) { pPaletteStack=new OSPalette; pPaletteStack->pSucc=NULL; pPaletteStack->p0RGB=NULL; pPaletteStack->nSize=0; } if (pPaletteStack->p0RGB==NULL || nIndex>=pPaletteStack->nSize) { sal_uInt32 * pOld0RGB=pPaletteStack->p0RGB; sal_uInt16 i,nOldSize=pPaletteStack->nSize; if (pOld0RGB==NULL) nOldSize=0; pPaletteStack->nSize=2*(nIndex+1); if (pPaletteStack->nSize<256) pPaletteStack->nSize=256; pPaletteStack->p0RGB = new sal_uInt32[pPaletteStack->nSize]; for (i=0; inSize; i++) { if (ip0RGB[i]=pOld0RGB[i]; else if (i==0) pPaletteStack->p0RGB[i]=0x00ffffff; else pPaletteStack->p0RGB[i]=0; } if (pOld0RGB!=NULL) delete[] pOld0RGB; } pPaletteStack->p0RGB[nIndex]=nCol; } sal_uInt32 OS2METReader::GetPalette0RGB(sal_uInt32 nIndex) { if (pPaletteStack!=NULL && pPaletteStack->p0RGB!=NULL && pPaletteStack->nSize>nIndex) nIndex=pPaletteStack->p0RGB[nIndex]; return nIndex; } Color OS2METReader::GetPaletteColor(sal_uInt32 nIndex) { nIndex=GetPalette0RGB(nIndex); return Color(sal::static_int_cast< sal_uInt8 >((nIndex>>16)&0xff), sal::static_int_cast< sal_uInt8 >((nIndex>>8)&0xff), sal::static_int_cast< sal_uInt8 >(nIndex&0xff)); } sal_uInt16 OS2METReader::ReadBigEndianWord() { sal_uInt8 nLo,nHi; *pOS2MET >> nHi >> nLo; return (((sal_uInt16)nHi)<<8)|(((sal_uInt16)nLo)&0x00ff); } sal_uLong OS2METReader::ReadBigEndian3BytesLong() { sal_uInt16 nLo; sal_uInt8 nHi; *pOS2MET >> nHi; nLo=ReadBigEndianWord(); return ((((sal_uLong)nHi)<<16)&0x00ff0000)|((sal_uLong)nLo); } sal_uLong OS2METReader::ReadLittleEndian3BytesLong() { sal_uInt8 nHi,nMed,nLo; *pOS2MET >> nLo >> nMed >> nHi; return ((((sal_uLong)nHi)&0xff)<<16)|((((sal_uLong)nMed)&0xff)<<8)|(((sal_uLong)nLo)&0xff); } long OS2METReader::ReadCoord(sal_Bool b32) { long l; short s; if (b32) *pOS2MET >> l; else { *pOS2MET >> s; l=(long)s; } return l; } Point OS2METReader::ReadPoint( const sal_Bool bAdjustBoundRect ) { long x,y; x=ReadCoord(bCoord32); y=ReadCoord(bCoord32); x=x-aBoundingRect.Left(); y=aBoundingRect.Bottom()-y; if ( bAdjustBoundRect ) aCalcBndRect.Union(Rectangle(x,y,x+1,y+1)); return Point(x,y); } RasterOp OS2METReader::OS2MixToRasterOp(sal_uInt8 nMix) { switch (nMix) { case 0x0c: return ROP_INVERT; case 0x04: return ROP_XOR; case 0x0b: return ROP_XOR; default: return ROP_OVERPAINT; } } void OS2METReader::ReadLine(sal_Bool bGivenPos, sal_uInt16 nOrderLen) { sal_uInt16 i,nPolySize; if (bCoord32) nPolySize=nOrderLen/8; else nPolySize=nOrderLen/4; if (!bGivenPos) nPolySize++; if (nPolySize==0) return; Polygon aPolygon(nPolySize); for (i=0; i> nunsignedbyte; aP0.X()+=(sal_Int8)nunsignedbyte; *pOS2MET >> nunsignedbyte; aP0.Y()+=(sal_Int8)nunsignedbyte; #else sal_Int8 nsignedbyte; *pOS2MET >> nsignedbyte; aP0.X()+=(long)nsignedbyte; *pOS2MET >> nsignedbyte; aP0.Y()-=(long)nsignedbyte; #endif aCalcBndRect.Union(Rectangle(aP0,Size(1,1))); aPolygon.SetPoint(aP0,i); } aAttr.aCurPos=aPolygon.GetPoint(nPolySize-1); if (pAreaStack!=NULL) AddPointsToArea(aPolygon); else if (pPathStack!=NULL) AddPointsToPath(aPolygon); else { SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle ); SetRasterOp(aAttr.eLinMix); DrawPolyLine( aPolygon ); } } void OS2METReader::ReadBox(sal_Bool bGivenPos) { sal_uInt8 nFlags; Point P0; long nHRound,nVRound; *pOS2MET >> nFlags; pOS2MET->SeekRel(1); if ( bGivenPos ) P0 = ReadPoint(); else P0 = aAttr.aCurPos; aAttr.aCurPos=ReadPoint(); nHRound=ReadCoord(bCoord32); nVRound=ReadCoord(bCoord32); Rectangle aBoxRect( P0, aAttr.aCurPos ); if ( pAreaStack ) AddPointsToArea( Polygon( aBoxRect ) ); else if ( pPathStack ) AddPointsToPath( Polygon( aBoxRect ) ); else { if ( nFlags & 0x20 ) SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle ); else SetPen( COL_TRANSPARENT ); if ( nFlags & 0x40 ) { ChangeBrush(aAttr.aPatCol,aAttr.aPatBgCol,aAttr.bFill); SetRasterOp(aAttr.ePatMix); } else { ChangeBrush( Color( COL_TRANSPARENT ), Color( COL_TRANSPARENT ), sal_False ); SetRasterOp(aAttr.eLinMix); } if ( IsLineInfo() ) { Polygon aPolygon( aBoxRect, nHRound, nVRound ); if ( nFlags & 0x40 ) { pVirDev->Push( PUSH_LINECOLOR ); pVirDev->SetLineColor( COL_TRANSPARENT ); pVirDev->DrawRect( aBoxRect, nHRound, nVRound ); pVirDev->Pop(); } pVirDev->DrawPolyLine( aPolygon, aLineInfo ); } else pVirDev->DrawRect( aBoxRect, nHRound, nVRound ); } } void OS2METReader::ReadBitBlt() { Point aP1,aP2; Size aSize; sal_uInt32 nID; OSBitmap * pB; long nt; pOS2MET->SeekRel(4); *pOS2MET >> nID; pOS2MET->SeekRel(4); aP1=ReadPoint(); aP2=ReadPoint(); if (aP1.X() > aP2.X()) { nt=aP1.X(); aP1.X()=aP2.X(); aP2.X()=nt; } if (aP1.Y() > aP2.Y()) { nt=aP1.Y(); aP1.Y()=aP2.Y(); aP2.Y()=nt; } aSize=Size(aP2.X()-aP1.X(),aP2.Y()-aP1.Y()); pB=pBitmapList; while (pB!=NULL && pB->nID!=nID) pB=pB->pSucc; if (pB!=NULL) { SetRasterOp(aAttr.ePatMix); pVirDev->DrawBitmap(aP1,aSize,pB->aBitmap); } } void OS2METReader::ReadChrStr(sal_Bool bGivenPos, sal_Bool bMove, sal_Bool bExtra, sal_uInt16 nOrderLen) { Point aP0; sal_uInt16 i, nLen; char * pChr; OSFont * pF; Font aFont; Size aSize; pF = pFontList; while (pF!=NULL && pF->nID!=aAttr.nChrSet) pF=pF->pSucc; if (pF!=NULL) aFont = pF->aFont; aFont.SetColor(aAttr.aChrCol); aFont.SetSize(Size(0,aAttr.aChrCellSize.Height())); if ( aAttr.nChrAng != 0 ) aFont.SetOrientation(aAttr.nChrAng); if (bGivenPos) aP0 = ReadPoint(); else aP0 = aAttr.aCurPos; if (bExtra) { pOS2MET->SeekRel(2); ReadPoint( sal_False ); ReadPoint( sal_False ); *pOS2MET >> nLen; } else { if ( !bGivenPos ) nLen = nOrderLen; else if ( bCoord32 ) nLen = nOrderLen-8; else nLen = nOrderLen-4; } pChr = new char[nLen+1]; for (i=0; i> pChr[i]; pChr[nLen] = 0; String aStr( (const sal_Char*)pChr, gsl_getSystemTextEncoding() ); SetRasterOp(aAttr.eChrMix); if (pVirDev->GetFont()!=aFont) pVirDev->SetFont(aFont); pVirDev->DrawText(aP0,aStr); aSize = Size( pVirDev->GetTextWidth(aStr), pVirDev->GetTextHeight() ); if ( aAttr.nChrAng == 0 ) { aCalcBndRect.Union(Rectangle( Point(aP0.X(),aP0.Y()-aSize.Height()), Size(aSize.Width(),aSize.Height()*2))); if (bMove) aAttr.aCurPos = Point( aP0.X() + aSize.Width(), aP0.Y()); } else { Polygon aDummyPoly(4); aDummyPoly.SetPoint( Point( aP0.X(), aP0.Y() ), 0); // TOP LEFT aDummyPoly.SetPoint( Point( aP0.X(), aP0.Y() - aSize.Height() ), 1); // BOTTOM LEFT aDummyPoly.SetPoint( Point( aP0.X() + aSize.Width(), aP0.Y() ), 2); // TOP RIGHT aDummyPoly.SetPoint( Point( aP0.X() + aSize.Width(), aP0.Y() - aSize.Height() ), 3);// BOTTOM RIGHT aDummyPoly.Rotate( aP0, (short)aAttr.nChrAng ); if ( bMove ) aAttr.aCurPos = aDummyPoly.GetPoint( 0 ); aCalcBndRect.Union( Rectangle( aDummyPoly.GetPoint( 0 ), aDummyPoly.GetPoint( 3 ) ) ); aCalcBndRect.Union( Rectangle( aDummyPoly.GetPoint( 1 ), aDummyPoly.GetPoint( 2 ) ) ); } delete[] pChr; } void OS2METReader::ReadArc(sal_Bool bGivenPos) { Point aP1, aP2, aP3; double x1,y1,x2,y2,x3,y3,p,q,cx,cy,ncx,ncy,r,rx,ry,w1,w3; if (bGivenPos) aP1=ReadPoint(); else aP1=aAttr.aCurPos; aP2=ReadPoint(); aP3=ReadPoint(); aAttr.aCurPos=aP3; SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle ); SetRasterOp(aAttr.eLinMix); // OK, gegeben sind 3 Punkte der Ellipse, und das Verhaeltnis // Breite zu Hoehe (als p zu q): x1=aP1.X(); y1=aP1.Y(); x2=aP2.X(); y2=aP2.Y(); x3=aP3.X(); y3=aP3.Y(); p=aAttr.nArcP;q=aAttr.nArcQ; // Berechnet wird der Mittelpunkt cx,cy der Ellipse: ncy=2*p*p*((y3-y1)*(x2-x1)-(y1-y2)*(x1-x3)); ncx=2*q*q*(x2-x1); if ( (ncx<0.001 && ncx>-0.001) || (ncy<0.001 && ncy>-0.001) ) { // Berechnung nicht moeglich, Punkte liegen auf einer Linie pVirDev->DrawLine(aP1,aP2); pVirDev->DrawLine(aP2,aP3); return; } cy=( q*q*((x3*x3-x1*x1)*(x2-x1)+(x2*x2-x1*x1)*(x1-x3)) + p*p*((y3*y3-y1*y1)*(x2-x1)+(y2*y2-y1*y1)*(x1-x3)) ) / ncy; cx=( q*q*(x2*x2-x1*x1)+p*p*(y2*y2-y1*y1)+cy*2*p*p*(y1-y2) ) / ncx; // Nun brauchen wir noch den Radius in x und y Richtung: r=sqrt(q*q*(x1-cx)*(x1-cx)+p*p*(y1-cy)*(y1-cy)); rx=r/q; ry=r/p; // Jetzt stellt sich "nur noch" die Frage, wie Start- und Endpunkt // gewaehlt werden muessen, damit Punkt Nr. 2 innerhalb des // gezeichneten Bogens liegt: w1=fmod((atan2(x1-cx,y1-cy)-atan2(x2-cx,y2-cy)),6.28318530718); if (w1<0) w1+=6.28318530718; w3=fmod((atan2(x3-cx,y3-cy)-atan2(x2-cx,y2-cy)),6.28318530718); if (w3<0) w3+=6.28318530718; if (w3DrawArc(Rectangle((long)(cx-rx),(long)(cy-ry), (long)(cx+rx),(long)(cy+ry)),aP1,aP3); } else { pVirDev->DrawArc(Rectangle((long)(cx-rx),(long)(cy-ry), (long)(cx+rx),(long)(cy+ry)),aP3,aP1); } } void OS2METReader::ReadFullArc(sal_Bool bGivenPos, sal_uInt16 nOrderSize) { Point aCenter; long nP,nQ,nR,nS; Rectangle aRect; sal_uInt32 nMul; sal_uInt16 nMulS; if (bGivenPos) { aCenter=ReadPoint(); if (bCoord32) nOrderSize-=8; else nOrderSize-=4; } else aCenter=aAttr.aCurPos; nP=aAttr.nArcP; nQ=aAttr.nArcQ; nR=aAttr.nArcR; nS=aAttr.nArcS; if (nP<0) nP=-nP; if (nQ<0) nQ=-nQ; if (nR<0) nR=-nR; if (nS<0) nS=-nS; if (nOrderSize>=4) *pOS2MET >> nMul; else { *pOS2MET >> nMulS; nMul=((sal_uLong)nMulS)<<8; } if (nMul!=0x00010000) { nP=(nP*nMul)>>16; nQ=(nQ*nMul)>>16; nR=(nR*nMul)>>16; nS=(nS*nMul)>>16; } aRect=Rectangle(aCenter.X()-nP,aCenter.Y()-nQ, aCenter.X()+nP,aCenter.Y()+nQ); aCalcBndRect.Union(aRect); if (pAreaStack!=NULL) { ChangeBrush(aAttr.aPatCol,aAttr.aPatBgCol,aAttr.bFill); SetRasterOp(aAttr.ePatMix); if ((pAreaStack->nFlags&0x40)!=0) SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle ); else SetPen( COL_TRANSPARENT, 0, PEN_NULL ); } else { SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle ); ChangeBrush(Color( COL_TRANSPARENT ),Color( COL_TRANSPARENT ),sal_False); SetRasterOp(aAttr.eLinMix); } pVirDev->DrawEllipse(aRect); } void OS2METReader::ReadPartialArc(sal_Bool bGivenPos, sal_uInt16 nOrderSize) { Point aP0, aCenter,aPStart,aPEnd; long nP,nQ,nR,nS,nStart, nSweep; Rectangle aRect; sal_uInt32 nMul; sal_uInt16 nMulS; double fStart, fEnd; if (bGivenPos) { aP0=ReadPoint(); if (bCoord32) nOrderSize-=8; else nOrderSize-=4; } else aP0=aAttr.aCurPos; aCenter=ReadPoint(); nP=aAttr.nArcP; nQ=aAttr.nArcQ; nR=aAttr.nArcR; nS=aAttr.nArcS; if (nP<0) nP=-nP; if (nQ<0) nQ=-nQ; if (nR<0) nR=-nR; if (nS<0) nS=-nS; if (nOrderSize>=12) *pOS2MET >> nMul; else { *pOS2MET >> nMulS; nMul=((sal_uLong)nMulS)<<8; } if (nMul!=0x00010000) { nP=(nP*nMul)>>16; nQ=(nQ*nMul)>>16; nR=(nR*nMul)>>16; nS=(nS*nMul)>>16; } *pOS2MET >> nStart >> nSweep; fStart=((double)nStart)/65536.0/180.0*3.14159265359; fEnd=fStart+((double)nSweep)/65536.0/180.0*3.14159265359; aPStart=Point(aCenter.X()+(long)( cos(fStart)*nP), aCenter.Y()+(long)(-sin(fStart)*nQ)); aPEnd= Point(aCenter.X()+(long)( cos(fEnd)*nP), aCenter.Y()+(long)(-sin(fEnd)*nQ)); aRect=Rectangle(aCenter.X()-nP,aCenter.Y()-nQ, aCenter.X()+nP,aCenter.Y()+nQ); aCalcBndRect.Union(aRect); SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle ); SetRasterOp(aAttr.eLinMix); pVirDev->DrawLine(aP0,aPStart); pVirDev->DrawArc(aRect,aPStart,aPEnd); aAttr.aCurPos=aPEnd; } void OS2METReader::ReadPolygons() { sal_uInt32 i,j,nNumPolys, nNumPoints; PolyPolygon aPolyPoly; Polygon aPoly; Point aPoint; sal_uInt8 nFlags; *pOS2MET >> nFlags >> nNumPolys; for (i=0; i> nNumPoints; if (i==0) nNumPoints++; aPoly.SetSize((short)nNumPoints); for (j=0; j> 2; Polygon aBezPoly( nSegments * nSegPoints ); sal_uInt16 nSeg, nBezPos, nStartPos; for( nSeg = 0, nBezPos = 0, nStartPos = 0; nSeg < nSegments; nSeg++, nStartPos += 4 ) { const Polygon aSegPoly( aPolygon[ nStartPos ], aPolygon[ nStartPos + 1 ], aPolygon[ nStartPos + 3 ], aPolygon[ nStartPos + 2 ], nSegPoints ); for( sal_uInt16 nSegPos = 0; nSegPos < nSegPoints; ) aBezPoly[ nBezPos++ ] = aSegPoly[ nSegPos++ ]; } nNumPoints = nBezPos; if( nNumPoints != aBezPoly.GetSize() ) aBezPoly.SetSize( nNumPoints ); aPolygon = aBezPoly; } aAttr.aCurPos = aPolygon[ nNumPoints - 1 ]; if (pAreaStack!=NULL) AddPointsToArea(aPolygon); else if (pPathStack!=NULL) AddPointsToPath(aPolygon); else { SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle ); SetRasterOp(aAttr.eLinMix); DrawPolyLine( aPolygon ); } } void OS2METReader::ReadFillet(sal_Bool bGivenPos, sal_uInt16 nOrderLen) { sal_uInt16 i,nNumPoints; if (bCoord32) nNumPoints=nOrderLen/8; else nNumPoints=nOrderLen/4; if (!bGivenPos) nNumPoints++; if (nNumPoints==0) return; Polygon aPolygon(nNumPoints); for (i=0; i=5 && aAttr.nMrkSymbol<=9) { ChangeBrush(aAttr.aMrkCol,aAttr.aMrkCol,sal_True); } else { ChangeBrush(Color(COL_TRANSPARENT),Color(COL_TRANSPARENT),sal_False); } if (bCoord32) nNumPoints=nOrderLen/8; else nNumPoints=nOrderLen/4; if (!bGivenPos) nNumPoints++; for (i=0; iDrawLine(Point(x-4,y),Point(x+4,y)); pVirDev->DrawLine(Point(x,y-4),Point(x,y+4)); break; case 3: // DIAMOND case 7: { // SOLIDDIAMOND Polygon aPoly(4); aPoly.SetPoint(Point(x,y+4),0); aPoly.SetPoint(Point(x+4,y),1); aPoly.SetPoint(Point(x,y-4),2); aPoly.SetPoint(Point(x-4,y),3); pVirDev->DrawPolygon(aPoly); break; } case 4: // SQARE case 8: { // SOLIDSUARE Polygon aPoly(4); aPoly.SetPoint(Point(x+4,y+4),0); aPoly.SetPoint(Point(x+4,y-4),1); aPoly.SetPoint(Point(x-4,y-4),2); aPoly.SetPoint(Point(x-4,y+4),3); pVirDev->DrawPolygon(aPoly); break; } case 5: { // SIXPOINTSTAR Polygon aPoly(12); aPoly.SetPoint(Point(x ,y-4),0); aPoly.SetPoint(Point(x+2,y-2),1); aPoly.SetPoint(Point(x+4,y-2),2); aPoly.SetPoint(Point(x+2,y ),3); aPoly.SetPoint(Point(x+4,y+2),4); aPoly.SetPoint(Point(x+2,y+2),5); aPoly.SetPoint(Point(x ,y+4),6); aPoly.SetPoint(Point(x-2,y+2),7); aPoly.SetPoint(Point(x-4,y+2),8); aPoly.SetPoint(Point(x-2,y ),9); aPoly.SetPoint(Point(x-4,y-2),10); aPoly.SetPoint(Point(x-2,y-2),11); pVirDev->DrawPolygon(aPoly); break; } case 6: { // EIGHTPOINTSTAR Polygon aPoly(16); aPoly.SetPoint(Point(x ,y-4),0); aPoly.SetPoint(Point(x+1,y-2),1); aPoly.SetPoint(Point(x+3,y-3),2); aPoly.SetPoint(Point(x+2,y-1),3); aPoly.SetPoint(Point(x+4,y ),4); aPoly.SetPoint(Point(x+2,y+1),5); aPoly.SetPoint(Point(x+3,y+3),6); aPoly.SetPoint(Point(x+1,y+2),7); aPoly.SetPoint(Point(x ,y+4),8); aPoly.SetPoint(Point(x-1,y+2),9); aPoly.SetPoint(Point(x-3,y+3),10); aPoly.SetPoint(Point(x-2,y+1),11); aPoly.SetPoint(Point(x-4,y ),12); aPoly.SetPoint(Point(x-2,y-1),13); aPoly.SetPoint(Point(x-3,y-3),14); aPoly.SetPoint(Point(x-1,y-2),15); pVirDev->DrawPolygon(aPoly); break; } case 9: // DOT pVirDev->DrawEllipse(Rectangle(x-1,y-1,x+1,y+1)); break; case 10: // SMALLCIRCLE pVirDev->DrawEllipse(Rectangle(x-2,y-2,x+2,y+2)); break; case 64: // BLANK break; default: // (=1) CROSS pVirDev->DrawLine(Point(x-4,y-4),Point(x+4,y+4)); pVirDev->DrawLine(Point(x-4,y+4),Point(x+4,y-4)); break; } } } void OS2METReader::ReadOrder(sal_uInt16 nOrderID, sal_uInt16 nOrderLen) { switch (nOrderID) { case GOrdGivArc: ReadArc(sal_True); break; case GOrdCurArc: ReadArc(sal_False); break; case GOrdGivBzr: ReadBezier(sal_True,nOrderLen); break; case GOrdCurBzr: ReadBezier(sal_False,nOrderLen); break; case GOrdGivBox: ReadBox(sal_True); break; case GOrdCurBox: ReadBox(sal_False); break; case GOrdGivFil: ReadFillet(sal_True,nOrderLen); break; case GOrdCurFil: ReadFillet(sal_False,nOrderLen); break; case GOrdGivCrc: ReadFullArc(sal_True,nOrderLen); break; case GOrdCurCrc: ReadFullArc(sal_False,nOrderLen); break; case GOrdGivLin: ReadLine(sal_True, nOrderLen); break; case GOrdCurLin: ReadLine(sal_False, nOrderLen); break; case GOrdGivMrk: ReadMarker(sal_True, nOrderLen); break; case GOrdCurMrk: ReadMarker(sal_False, nOrderLen); break; case GOrdGivArP: ReadPartialArc(sal_True,nOrderLen); break; case GOrdCurArP: ReadPartialArc(sal_False,nOrderLen); break; case GOrdGivRLn: ReadRelLine(sal_True,nOrderLen); break; case GOrdCurRLn: ReadRelLine(sal_False,nOrderLen); break; case GOrdGivSFl: ReadFilletSharp(sal_True,nOrderLen); break; case GOrdCurSFl: ReadFilletSharp(sal_False,nOrderLen); break; case GOrdGivStM: ReadChrStr(sal_True , sal_True , sal_False, nOrderLen); break; case GOrdCurStM: ReadChrStr(sal_False, sal_True , sal_False, nOrderLen); break; case GOrdGivStr: ReadChrStr(sal_True , sal_False, sal_False, nOrderLen); break; case GOrdCurStr: ReadChrStr(sal_False, sal_False, sal_False, nOrderLen); break; case GOrdGivStx: ReadChrStr(sal_True , sal_False, sal_True , nOrderLen); break; case GOrdCurStx: ReadChrStr(sal_False, sal_False, sal_True , nOrderLen); break; case GOrdGivImg: OOODEBUG("GOrdGivImg",0); break; case GOrdCurImg: OOODEBUG("GOrdCurImg",0); break; case GOrdImgDat: OOODEBUG("GOrdImgDat",0); break; case GOrdEndImg: OOODEBUG("GOrdEndImg",0); break; case GOrdBegAra: { OSArea * p=new OSArea; p->bClosed=sal_False; p->pSucc=pAreaStack; pAreaStack=p; *pOS2MET >> (p->nFlags); p->aCol=aAttr.aPatCol; p->aBgCol=aAttr.aPatBgCol; p->eMix=aAttr.ePatMix; p->eBgMix=aAttr.ePatBgMix; p->bFill=aAttr.bFill; break; } case GOrdEndAra: { OSArea * p=pAreaStack; if ( p ) { pAreaStack = p->pSucc; if ( pPathStack ) { for ( sal_uInt16 i=0; iaPPoly.Count(); i++ ) { AddPointsToPath( p->aPPoly.GetObject( i ) ); CloseFigure(); } } else { if ( ( p->nFlags & 0x40 ) == 0 ) SetPen( COL_TRANSPARENT, 0, PEN_NULL ); else SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle ); ChangeBrush(p->aCol,p->aBgCol,p->bFill); SetRasterOp(p->eMix); DrawPolyPolygon( p->aPPoly ); } delete p; } } break; case GOrdBegElm:// OOODEBUG("GOrdBegElm",0); break; case GOrdEndElm:// OOODEBUG("GOrdEndElm",0); break; case GOrdBegPth: { OSPath * p=new OSPath; p->pSucc=pPathStack; pPathStack=p; pOS2MET->SeekRel(2); *pOS2MET >> p->nID; p->bClosed=sal_False; p->bStroke=sal_False; break; } case GOrdEndPth: { OSPath * p, * pprev, * psucc; if (pPathStack==NULL) break; p=pPathList; pprev=NULL; while (p!=NULL) { psucc=p->pSucc; if (p->nID==pPathStack->nID) { if (pprev==NULL) pPathList=psucc; else pprev->pSucc=psucc; delete p; } else pprev=p; p=psucc; } p=pPathStack; pPathStack=p->pSucc; p->pSucc=pPathList; pPathList=p; break; } case GOrdFilPth: { sal_uInt32 nID; sal_uInt16 nDummy; OSPath* p = pPathList; *pOS2MET >> nDummy >> nID; if ( ! ( nDummy & 0x20 ) ) // #30933# i do not know the exact meaning of this bit, { // but if set it seems to be better not to fill this path while( p && p->nID != nID ) p = p->pSucc; if( p ) { if( p->bStroke ) { SetPen( aAttr.aPatCol, aAttr.nStrLinWidth, PEN_SOLID ); ChangeBrush(Color(COL_TRANSPARENT),Color(COL_TRANSPARENT),sal_False); SetRasterOp( aAttr.ePatMix ); if ( IsLineInfo() ) { for ( sal_uInt16 i = 0; i < p->aPPoly.Count(); i++ ) pVirDev->DrawPolyLine( p->aPPoly.GetObject( i ), aLineInfo ); } else pVirDev->DrawPolyPolygon( p->aPPoly ); } else { SetPen( COL_TRANSPARENT, 0, PEN_NULL ); ChangeBrush( aAttr.aPatCol, aAttr.aPatBgCol, aAttr.bFill ); SetRasterOp( aAttr.ePatMix ); pVirDev->DrawPolyPolygon( p->aPPoly ); } } } } break; case GOrdModPth: { OSPath* p = pPathList; while( p && p->nID != 1 ) p = p->pSucc; if( p ) p->bStroke = sal_True; } break; case GOrdOutPth: { sal_uInt32 nID; sal_uInt16 i,nC; OSPath* p=pPathList; pOS2MET->SeekRel(2); *pOS2MET >> nID; while (p!=NULL && p->nID!=nID) p=p->pSucc; if( p!=NULL ) { SetPen( aAttr.aLinCol, aAttr.nStrLinWidth, aAttr.eLinStyle ); SetRasterOp(aAttr.eLinMix); ChangeBrush(Color(COL_TRANSPARENT),Color(COL_TRANSPARENT),sal_False); nC=p->aPPoly.Count(); for (i=0; ibClosed==sal_True) DrawPolygon( p->aPPoly.GetObject( i ) ); else DrawPolyLine( p->aPPoly.GetObject( i ) ); } } break; } case GOrdSClPth: { OOODEBUG("GOrdSClPth",0); sal_uInt32 nID; OSPath * p=pPathList; pOS2MET->SeekRel(2); *pOS2MET >> nID; if (nID==0) p=NULL; while (p!=NULL && p->nID!=nID) p=p->pSucc; if (p!=NULL) pVirDev->SetClipRegion(Region(p->aPPoly)); else pVirDev->SetClipRegion(); break; } case GOrdNopNop: break; case GOrdRemark: //OOODEBUG("GOrdRemark",0); break; case GOrdSegLab: OOODEBUG("GOrdSegLab",0); break; case GOrdBitBlt: ReadBitBlt(); break; case GOrdCalSeg: OOODEBUG("GOrdCalSeg",0); break; case GOrdSSgBnd: OOODEBUG("GOrdSSgBnd",0); break; case GOrdSegChr: OOODEBUG("GOrdSegChr",0); break; case GOrdCloFig: CloseFigure(); break; case GOrdEndSym: OOODEBUG("GOrdEndSym",0); break; case GOrdEndPlg: OOODEBUG("GOrdEndPlg",0); break; case GOrdEscape: OOODEBUG("GOrdEscape",0); break; case GOrdExtEsc: OOODEBUG("GOrdExtEsc",0); break; case GOrdPolygn: ReadPolygons(); break; case GOrdStkPop: PopAttr(); break; case GOrdPIvAtr: PushAttr(nOrderID); case GOrdSIvAtr: { sal_uInt8 nA, nP, nFlags, nMix; sal_uLong nVal; Color aCol; RasterOp eROP; *pOS2MET >> nA >> nP >> nFlags; if (nOrderID==GOrdPIvAtr) { pAttrStack->nIvAttrA=nA; pAttrStack->nIvAttrP=nP; } if (nA<=2) { if ((nFlags&0x80)!=0) { if (nA==1) switch (nP) { case 1: aAttr.aLinCol=aDefAttr.aLinCol; break; case 2: aAttr.aChrCol=aDefAttr.aChrCol; break; case 3: aAttr.aMrkCol=aDefAttr.aMrkCol; break; case 4: aAttr.aPatCol=aDefAttr.aPatCol; break; case 5: aAttr.aImgCol=aDefAttr.aImgCol; break; } else switch (nP) { case 1: aAttr.aLinBgCol=aDefAttr.aLinBgCol; break; case 2: aAttr.aChrBgCol=aDefAttr.aChrBgCol; break; case 3: aAttr.aMrkBgCol=aDefAttr.aMrkBgCol; break; case 4: aAttr.aPatBgCol=aDefAttr.aPatBgCol; break; case 5: aAttr.aImgBgCol=aDefAttr.aImgBgCol; break; } } else { nVal=ReadLittleEndian3BytesLong(); if ((nFlags&0x40)!=0 && nVal==1) aCol=Color(COL_BLACK); else if ((nFlags&0x40)!=0 && nVal==2) aCol=Color(COL_WHITE); else if ((nFlags&0x40)!=0 && nVal==4) aCol=Color(COL_WHITE); else if ((nFlags&0x40)!=0 && nVal==5) aCol=Color(COL_BLACK); else aCol=GetPaletteColor(nVal); if (nA==1) switch (nP) { case 1: aAttr.aLinCol=aCol; break; case 2: aAttr.aChrCol=aCol; break; case 3: aAttr.aMrkCol=aCol; break; case 4: aAttr.aPatCol=aCol; break; case 5: aAttr.aImgCol=aCol; break; } else switch (nP) { case 1: aAttr.aLinBgCol=aCol; break; case 2: aAttr.aChrBgCol=aCol; break; case 3: aAttr.aMrkBgCol=aCol; break; case 4: aAttr.aPatBgCol=aCol; break; case 5: aAttr.aImgBgCol=aCol; break; } } } else { *pOS2MET >> nMix; if (nMix==0) { if (nA==1) switch (nP) { case 1: aAttr.eLinMix=aDefAttr.eLinMix; break; case 2: aAttr.eChrMix=aDefAttr.eChrMix; break; case 3: aAttr.eMrkMix=aDefAttr.eMrkMix; break; case 4: aAttr.ePatMix=aDefAttr.ePatMix; break; case 5: aAttr.eImgMix=aDefAttr.eImgMix; break; } else switch (nP) { case 1: aAttr.eLinBgMix=aDefAttr.eLinBgMix; break; case 2: aAttr.eChrBgMix=aDefAttr.eChrBgMix; break; case 3: aAttr.eMrkBgMix=aDefAttr.eMrkBgMix; break; case 4: aAttr.ePatBgMix=aDefAttr.ePatBgMix; break; case 5: aAttr.eImgBgMix=aDefAttr.eImgBgMix; break; } } else { eROP=OS2MixToRasterOp(nMix); if (nA==1) switch (nP) { case 1: aAttr.eLinMix=eROP; break; case 2: aAttr.eChrMix=eROP; break; case 3: aAttr.eMrkMix=eROP; break; case 4: aAttr.ePatMix=eROP; break; case 5: aAttr.eImgMix=eROP; break; } else switch (nP) { case 1: aAttr.eLinBgMix=eROP; break; case 2: aAttr.eChrBgMix=eROP; break; case 3: aAttr.eMrkBgMix=eROP; break; case 4: aAttr.ePatBgMix=eROP; break; case 5: aAttr.eImgBgMix=eROP; break; } } } break; } case GOrdPIxCol: PushAttr(nOrderID); case GOrdSIxCol: { sal_uInt8 nFlags; sal_uLong nVal; Color aCol; *pOS2MET >> nFlags; if ((nFlags&0x80)!=0) { aAttr.aLinCol=aDefAttr.aLinCol; aAttr.aChrCol=aDefAttr.aChrCol; aAttr.aMrkCol=aDefAttr.aMrkCol; aAttr.aPatCol=aDefAttr.aPatCol; aAttr.aImgCol=aDefAttr.aImgCol; } else { nVal=ReadLittleEndian3BytesLong(); if ((nFlags&0x40)!=0 && nVal==1) aCol=Color(COL_BLACK); else if ((nFlags&0x40)!=0 && nVal==2) aCol=Color(COL_WHITE); else if ((nFlags&0x40)!=0 && nVal==4) aCol=Color(COL_WHITE); else if ((nFlags&0x40)!=0 && nVal==5) aCol=Color(COL_BLACK); else aCol=GetPaletteColor(nVal); aAttr.aLinCol = aAttr.aChrCol = aAttr.aMrkCol = aAttr.aPatCol = aAttr.aImgCol = aCol; } break; } case GOrdPColor: case GOrdPXtCol: PushAttr(nOrderID); case GOrdSColor: case GOrdSXtCol: { sal_uInt8 nbyte; sal_uInt16 nVal; Color aCol; if (nOrderID==GOrdPColor || nOrderID==GOrdSColor) { *pOS2MET >> nbyte; nVal=((sal_uInt16)nbyte)|0xff00; } else *pOS2MET >> nVal; if (nVal==0x0000 || nVal==0xff00) { aAttr.aLinCol=aDefAttr.aLinCol; aAttr.aChrCol=aDefAttr.aChrCol; aAttr.aMrkCol=aDefAttr.aMrkCol; aAttr.aPatCol=aDefAttr.aPatCol; aAttr.aImgCol=aDefAttr.aImgCol; } else { if (nVal==0x0007) aCol=Color(COL_WHITE); else if (nVal==0x0008) aCol=Color(COL_BLACK); else if (nVal==0xff08) aCol=GetPaletteColor(1); else aCol=GetPaletteColor(((sal_uLong)nVal) & 0x000000ff); aAttr.aLinCol = aAttr.aChrCol = aAttr.aMrkCol = aAttr.aPatCol = aAttr.aImgCol = aCol; } break; } case GOrdPBgCol: PushAttr(nOrderID); case GOrdSBgCol: { sal_uInt16 nVal; Color aCol; *pOS2MET >> nVal; if (nVal==0x0000 || nVal==0xff00) { aAttr.aLinBgCol=aDefAttr.aLinBgCol; aAttr.aChrBgCol=aDefAttr.aChrBgCol; aAttr.aMrkBgCol=aDefAttr.aMrkBgCol; aAttr.aPatBgCol=aDefAttr.aPatBgCol; aAttr.aImgBgCol=aDefAttr.aImgBgCol; } else { if (nVal==0x0007) aCol=Color(COL_WHITE); else if (nVal==0x0008) aCol=Color(COL_BLACK); else if (nVal==0xff08) aCol=GetPaletteColor(0); else aCol=GetPaletteColor(((sal_uLong)nVal) & 0x000000ff); aAttr.aLinBgCol = aAttr.aChrBgCol = aAttr.aMrkBgCol = aAttr.aPatBgCol = aAttr.aImgBgCol = aCol; } break; } case GOrdPBxCol: PushAttr(nOrderID); case GOrdSBxCol: { sal_uInt8 nFlags; sal_uLong nVal; Color aCol; *pOS2MET >> nFlags; if ((nFlags&0x80)!=0) { aAttr.aLinBgCol=aDefAttr.aLinBgCol; aAttr.aChrBgCol=aDefAttr.aChrBgCol; aAttr.aMrkBgCol=aDefAttr.aMrkBgCol; aAttr.aPatBgCol=aDefAttr.aPatBgCol; aAttr.aImgBgCol=aDefAttr.aImgBgCol; } else { nVal=ReadLittleEndian3BytesLong(); if ((nFlags&0x40)!=0 && nVal==1) aCol=Color(COL_BLACK); else if ((nFlags&0x40)!=0 && nVal==2) aCol=Color(COL_WHITE); else if ((nFlags&0x40)!=0 && nVal==4) aCol=Color(COL_WHITE); else if ((nFlags&0x40)!=0 && nVal==5) aCol=Color(COL_BLACK); else aCol=GetPaletteColor(nVal); aAttr.aLinBgCol = aAttr.aChrBgCol = aAttr.aMrkBgCol = aAttr.aPatBgCol = aAttr.aImgBgCol = aCol; } break; } case GOrdPMixMd: PushAttr(nOrderID); case GOrdSMixMd: { sal_uInt8 nMix; *pOS2MET >> nMix; if (nMix==0) { aAttr.eLinMix=aDefAttr.eLinMix; aAttr.eChrMix=aDefAttr.eChrMix; aAttr.eMrkMix=aDefAttr.eMrkMix; aAttr.ePatMix=aDefAttr.ePatMix; aAttr.eImgMix=aDefAttr.eImgMix; } else { aAttr.eLinMix = aAttr.eChrMix = aAttr.eMrkMix = aAttr.ePatMix = aAttr.eImgMix = OS2MixToRasterOp(nMix); } break; } case GOrdPBgMix: PushAttr(nOrderID); case GOrdSBgMix: { sal_uInt8 nMix; *pOS2MET >> nMix; if (nMix==0) { aAttr.eLinBgMix=aDefAttr.eLinBgMix; aAttr.eChrBgMix=aDefAttr.eChrBgMix; aAttr.eMrkBgMix=aDefAttr.eMrkBgMix; aAttr.ePatBgMix=aDefAttr.ePatBgMix; aAttr.eImgBgMix=aDefAttr.eImgBgMix; } else { aAttr.eLinBgMix = aAttr.eChrBgMix = aAttr.eMrkBgMix = aAttr.ePatBgMix = aAttr.eImgBgMix = OS2MixToRasterOp(nMix); } break; } case GOrdPPtSet: PushAttr(nOrderID); case GOrdSPtSet: OOODEBUG("GOrdSPtSet",0); break; case GOrdPPtSym: PushAttr(nOrderID); case GOrdSPtSym: { sal_uInt8 nPatt; *pOS2MET >> nPatt; aAttr.bFill = ( nPatt != 0x0f ); break; } case GOrdPPtRef: PushAttr(nOrderID); case GOrdSPtRef: OOODEBUG("GOrdSPtRef",0); break; case GOrdPLnEnd: PushAttr(nOrderID); case GOrdSLnEnd: break; case GOrdPLnJoi: PushAttr(nOrderID); case GOrdSLnJoi: break; case GOrdPLnTyp: PushAttr(nOrderID); case GOrdSLnTyp: { sal_uInt8 nType; *pOS2MET >> nType; switch (nType) { case 0: aAttr.eLinStyle=aDefAttr.eLinStyle; break; case 1: case 4: aAttr.eLinStyle=PEN_DOT; break; case 2: case 5: aAttr.eLinStyle=PEN_DASH; break; case 3: case 6: aAttr.eLinStyle=PEN_DASHDOT; break; case 8: aAttr.eLinStyle=PEN_NULL; break; default: aAttr.eLinStyle=PEN_SOLID; } break; } case GOrdPLnWdt: PushAttr(nOrderID); case GOrdSLnWdt: { sal_uInt8 nbyte; *pOS2MET >> nbyte; if (nbyte==0) aAttr.nLinWidth=aDefAttr.nLinWidth; else aAttr.nLinWidth=(sal_uInt16)nbyte-1; break; } case GOrdPFrLWd: PushAttr(nOrderID); case GOrdSFrLWd: break; case GOrdPStLWd: PushAttr(nOrderID); case GOrdSStLWd : { sal_uInt8 nFlags; long nWd; *pOS2MET >> nFlags; if ( nFlags & 0x80 ) aAttr.nStrLinWidth = aDefAttr.nStrLinWidth; else { pOS2MET->SeekRel( 1 ); nWd = ReadCoord( bCoord32 ); if ( nWd < 0 ) nWd = -nWd; aAttr.nStrLinWidth = (sal_uInt16)nWd; } break; } case GOrdPChDir: PushAttr(nOrderID); case GOrdSChDir: break; case GOrdPChPrc: PushAttr(nOrderID); case GOrdSChPrc: break; case GOrdPChSet: PushAttr(nOrderID); case GOrdSChSet: { sal_uInt8 nbyte; *pOS2MET >> nbyte; aAttr.nChrSet=((sal_uLong)nbyte)&0xff; break; } case GOrdPChAng: PushAttr(nOrderID); case GOrdSChAng: { long nX,nY; nX=ReadCoord(bCoord32); nY=ReadCoord(bCoord32); if (nX>=0 && nY==0) aAttr.nChrAng=0; else { aAttr.nChrAng=(short)(atan2((double)nY,(double)nX)/3.1415926539*1800.0); while (aAttr.nChrAng<0) aAttr.nChrAng+=3600; aAttr.nChrAng%=3600; } break; } case GOrdPChBrx: PushAttr(nOrderID); case GOrdSChBrx: break; case GOrdPChCel: PushAttr(nOrderID); case GOrdSChCel: { sal_uInt8 nbyte; sal_uInt16 nLen=nOrderLen; aAttr.aChrCellSize.Width()=ReadCoord(bCoord32); aAttr.aChrCellSize.Height()=ReadCoord(bCoord32); if (bCoord32) nLen-=8; else nLen-=4; if (nLen>=4) { pOS2MET->SeekRel(4); nLen-=4; } if (nLen>=2) { *pOS2MET >> nbyte; if ((nbyte&0x80)==0 && aAttr.aChrCellSize==Size(0,0)) aAttr.aChrCellSize=aDefAttr.aChrCellSize; } break; } case GOrdPChXtr: PushAttr(nOrderID); case GOrdSChXtr: break; case GOrdPChShr: PushAttr(nOrderID); case GOrdSChShr: break; case GOrdPTxAlg: PushAttr(nOrderID); case GOrdSTxAlg: OOODEBUG("GOrdSTxAlg",0); break; case GOrdPMkPrc: PushAttr(nOrderID); case GOrdSMkPrc: { sal_uInt8 nbyte; *pOS2MET >> nbyte; if (nbyte==0) aAttr.nMrkPrec=aDefAttr.nMrkPrec; else aAttr.nMrkPrec=nbyte; break; } case GOrdPMkSet: PushAttr(nOrderID); case GOrdSMkSet: { sal_uInt8 nbyte; *pOS2MET >> nbyte; if (nbyte==0) aAttr.nMrkSet=aDefAttr.nMrkSet; else aAttr.nMrkSet=nbyte; break; } case GOrdPMkSym: PushAttr(nOrderID); case GOrdSMkSym: { sal_uInt8 nbyte; *pOS2MET >> nbyte; if (nbyte==0) aAttr.nMrkSymbol=aDefAttr.nMrkSymbol; else aAttr.nMrkSymbol=nbyte; break; } case GOrdPMkCel: PushAttr(nOrderID); case GOrdSMkCel: { sal_uInt8 nbyte; sal_uInt16 nLen=nOrderLen; aAttr.aMrkCellSize.Width()=ReadCoord(bCoord32); aAttr.aMrkCellSize.Height()=ReadCoord(bCoord32); if (bCoord32) nLen-=8; else nLen-=4; if (nLen>=2) { *pOS2MET >> nbyte; if ((nbyte&0x80)==0 && aAttr.aMrkCellSize==Size(0,0)) aAttr.aMrkCellSize=aDefAttr.aMrkCellSize; } break; } case GOrdPArcPa: PushAttr(nOrderID); case GOrdSArcPa: aAttr.nArcP=ReadCoord(bCoord32); aAttr.nArcQ=ReadCoord(bCoord32); aAttr.nArcR=ReadCoord(bCoord32); aAttr.nArcS=ReadCoord(bCoord32); break; case GOrdPCrPos: PushAttr(nOrderID); case GOrdSCrPos: aAttr.aCurPos=ReadPoint(); break; case GOrdPMdTrn: PushAttr(nOrderID); case GOrdSMdTrn: OOODEBUG("GOrdSMdTrn",0); break; case GOrdPPkIdn: PushAttr(nOrderID); case GOrdSPkIdn: OOODEBUG("GOrdSPkIdn",0); break; case GOrdSVwTrn: OOODEBUG("GOrdSVwTrn",0); break; case GOrdPVwWin: PushAttr(nOrderID); case GOrdSVwWin: OOODEBUG("GOrdSVwWin",0); break; default: OOODEBUG("Order unbekannt:",nOrderID); } } void OS2METReader::ReadDsc(sal_uInt16 nDscID, sal_uInt16 /*nDscLen*/) { switch (nDscID) { case 0x00f7: { // 'Specify GVM Subset' sal_uInt8 nbyte; pOS2MET->SeekRel(6); *pOS2MET >> nbyte; if (nbyte==0x05) bCoord32=sal_True; else if (nbyte==0x04) bCoord32=sal_False; else { pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERROR); ErrorCode=1; } break; } case 0x00f6: { // 'Set Picture Descriptor' sal_Bool b32; sal_uInt8 nbyte,nUnitType; long x1,y1,x2,y2,nt,xr,yr; pOS2MET->SeekRel(2); *pOS2MET >> nbyte; if (nbyte==0x05) b32=sal_True; else if(nbyte==0x04) b32=sal_False; else { b32 = sal_False; // -Wall added the case. pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERROR); ErrorCode=2; } *pOS2MET >> nUnitType; xr=ReadCoord(b32); yr=ReadCoord(b32); ReadCoord(b32); if (nUnitType==0x00 && xr>0 && yr>0) aGlobMapMode=MapMode(MAP_INCH,Point(0,0),Fraction(10,xr),Fraction(10,yr)); else if (nUnitType==0x01 && xr>0 && yr>0) aGlobMapMode=MapMode(MAP_CM,Point(0,0),Fraction(10,xr),Fraction(10,yr)); else aGlobMapMode=MapMode(); x1=ReadCoord(b32); x2=ReadCoord(b32); y1=ReadCoord(b32); y2=ReadCoord(b32); if (x1>x2) { nt=x1; x1=x2; x2=nt; } if (y1>y2) { nt=y1; y1=y2; y2=nt; } aBoundingRect.Left() = x1; aBoundingRect.Right() = x2; aBoundingRect.Top() = y1; aBoundingRect.Bottom() = y2; // no output beside this bounding rect pVirDev->IntersectClipRegion( Rectangle( Point(), aBoundingRect.GetSize() ) ); break; } case 0x0021: // 'Set Current Defaults' break; } } void OS2METReader::ReadImageData(sal_uInt16 nDataID, sal_uInt16 nDataLen) { OSBitmap * p=pBitmapList; if (p==NULL) return; // Nanu ? switch (nDataID) { case 0x0070: // Begin Segment break; case 0x0091: // Begin Image Content break; case 0x0094: // Image Size pOS2MET->SeekRel(5); p->nHeight=ReadBigEndianWord(); p->nWidth=ReadBigEndianWord(); break; case 0x0095: // Image Encoding break; case 0x0096: { // Image IDE-Size sal_uInt8 nbyte; *pOS2MET >> nbyte; p->nBitsPerPixel=nbyte; break; } case 0x0097: // Image LUT-ID break; case 0x009b: // IDE Structure break; case 0xfe92: { // Image Data // Spaetestens jetzt brauchen wir die temporaere BMP-Datei // und darin mindestens den Header + Palette. if (p->pBMP==NULL) { p->pBMP=new SvMemoryStream(); p->pBMP->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN); if (p->nWidth==0 || p->nHeight==0 || p->nBitsPerPixel==0) { pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERROR); ErrorCode=3; return; } // Schreibe (Windows-)BITMAPINFOHEADER: *(p->pBMP) << ((sal_uInt32)40) << p->nWidth << p->nHeight; *(p->pBMP) << ((sal_uInt16)1) << p->nBitsPerPixel; *(p->pBMP) << ((sal_uInt32)0) << ((sal_uInt32)0) << ((sal_uInt32)0) << ((sal_uInt32)0); *(p->pBMP) << ((sal_uInt32)0) << ((sal_uInt32)0); // Schreibe Farbtabelle: if (p->nBitsPerPixel<=8) { sal_uInt16 i, nColTabSize=1<<(p->nBitsPerPixel); for (i=0; ipBMP) << GetPalette0RGB(i); } } // OK, nun werden die Map-Daten ruebergeschoben. Leider haben OS2 und // BMP eine unterschiedliche Reihenfolge von RGB bei 24-Bit. sal_uInt8 * pBuf=new sal_uInt8[nDataLen]; pOS2MET->Read(pBuf,nDataLen); if (p->nBitsPerPixel==24) { sal_uLong i, j, nAlign, nBytesPerLine; sal_uInt8 nTemp; nBytesPerLine=(p->nWidth*3+3)&0xfffffffc; nAlign=p->nMapPos-(p->nMapPos % nBytesPerLine); i=0; while (nAlign+i+2nMapPos+nDataLen) { if (nAlign+i>=p->nMapPos) { j=nAlign+i-p->nMapPos; nTemp=pBuf[j]; pBuf[j]=pBuf[j+2]; pBuf[j+2]=nTemp; } i+=3; if (i+2>=nBytesPerLine) { nAlign+=nBytesPerLine; i=0; } } } p->pBMP->Write(pBuf,nDataLen); p->nMapPos+=nDataLen; delete[] pBuf; break; } case 0x0093: // End Image Content break; case 0x0071: // End Segment break; } } void OS2METReader::ReadFont(sal_uInt16 nFieldSize) { sal_uLong nPos, nMaxPos; sal_uInt16 nLen; sal_uInt8 nByte, nTripType, nTripType2; OSFont * pF=new OSFont; pF->pSucc=pFontList; pFontList=pF; pF->nID=0; pF->aFont.SetTransparent(sal_True); pF->aFont.SetAlign(ALIGN_BASELINE); nPos=pOS2MET->Tell(); nMaxPos=nPos+(sal_uLong)nFieldSize; pOS2MET->SeekRel(2); nPos+=2; while (nPosGetError()==0) { *pOS2MET >> nByte; nLen =((sal_uInt16)nByte) & 0x00ff; *pOS2MET >> nTripType; switch (nTripType) { case 0x02: *pOS2MET >> nTripType2; switch (nTripType2) { case 0x84: // Font name break; case 0x08: { // Font Typeface char str[33]; pOS2MET->SeekRel(1); pOS2MET->Read( &str, 32 ); str[ 32 ] = 0; String aStr( (const sal_Char*)str, gsl_getSystemTextEncoding() ); if ( aStr.CompareIgnoreCaseToAscii( "Helv" ) == COMPARE_EQUAL ) aStr = String::CreateFromAscii( "Helvetica" ); pF->aFont.SetName( aStr ); break; } } break; case 0x24: // Icid *pOS2MET >> nTripType2; switch (nTripType2) { case 0x05: //Icid *pOS2MET >> nByte; pF->nID=((sal_uLong)nByte)&0xff; break; } break; case 0x20: // Font Binary GCID break; case 0x1f: { // Font Attributes FontWeight eWeight; sal_uInt8 nbyte; *pOS2MET >> nbyte; switch (nbyte) { case 1: eWeight=WEIGHT_THIN; break; case 2: eWeight=WEIGHT_ULTRALIGHT; break; case 3: eWeight=WEIGHT_LIGHT; break; case 4: eWeight=WEIGHT_SEMILIGHT; break; case 5: eWeight=WEIGHT_NORMAL; break; case 6: eWeight=WEIGHT_SEMIBOLD; break; case 7: eWeight=WEIGHT_BOLD; break; case 8: eWeight=WEIGHT_ULTRABOLD; break; case 9: eWeight=WEIGHT_BLACK; break; default: eWeight=WEIGHT_DONTKNOW; } pF->aFont.SetWeight(eWeight); break; } } nPos+=nLen; pOS2MET->Seek(nPos); } } void OS2METReader::ReadField(sal_uInt16 nFieldType, sal_uInt16 nFieldSize) { switch (nFieldType) { case BegDocumnMagic: break; case EndDocumnMagic: break; case BegResGrpMagic: break; case EndResGrpMagic: break; case BegColAtrMagic: break; case EndColAtrMagic: break; case BlkColAtrMagic: { sal_uLong nPos, nMaxPos; sal_uInt8 nbyte; sal_uLong nCol; sal_uInt16 nStartIndex, nEndIndex, i, nElemLen, nBytesPerCol; nPos=pOS2MET->Tell(); nMaxPos=nPos+(sal_uLong)nFieldSize; pOS2MET->SeekRel(3); nPos+=3; while (nPosGetError()==0) { *pOS2MET >> nbyte; nElemLen=((sal_uInt16)nbyte) & 0x00ff; if (nElemLen>11) { pOS2MET->SeekRel(4); nStartIndex=ReadBigEndianWord(); pOS2MET->SeekRel(3); *pOS2MET >> nbyte; nBytesPerCol=((sal_uInt16)nbyte) & 0x00ff; nEndIndex=nStartIndex+(nElemLen-11)/nBytesPerCol; for (i=nStartIndex; i 3) pOS2MET->SeekRel(nBytesPerCol-3); nCol=ReadBigEndian3BytesLong(); SetPalette0RGB(i,nCol); } } else if (nElemLen<10) { pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERROR); ErrorCode=4; } nPos+=(sal_uLong)nElemLen; pOS2MET->Seek(nPos); } break; } case MapColAtrMagic: break; case BegImgObjMagic: { // neue Bitmap schonmal herstellen: (wird spaeter gefuellt) OSBitmap * pB=new OSBitmap; pB->pSucc=pBitmapList; pBitmapList=pB; pB->pBMP=NULL; pB->nWidth=0; pB->nHeight=0; pB->nBitsPerPixel=0; pB->nMapPos=0; // ID der Bitmap ermitteln: sal_uInt8 i,nbyte,nbyte2; pB->nID=0; for (i=0; i<4; i++) { *pOS2MET >> nbyte >> nbyte2; nbyte=((nbyte-0x30)<<4)|(nbyte2-0x30); pB->nID=(pB->nID>>8)|(((sal_uLong)nbyte)<<24); } // neue Palette auf den Paletten-Stack bringen: (wird spaeter gefuellt) OSPalette * pP=new OSPalette; pP->pSucc=pPaletteStack; pPaletteStack=pP; pP->p0RGB=NULL; pP->nSize=0; break; } case EndImgObjMagic: { // Temporaere Windows-BMP-Datei auslesen: if (pBitmapList==NULL || pBitmapList->pBMP==NULL || pBitmapList->pBMP->GetError()!=0) { pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERROR); ErrorCode=5; return; } pBitmapList->pBMP->Seek(0); ReadDIB(pBitmapList->aBitmap, *(pBitmapList->pBMP), false); if (pBitmapList->pBMP->GetError()!=0) { pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERROR); ErrorCode=6; } delete pBitmapList->pBMP; pBitmapList->pBMP=NULL; // Palette vom Stack killen: OSPalette * pP=pPaletteStack; if (pP!=NULL) { pPaletteStack=pP->pSucc; if (pP->p0RGB!=NULL) delete[] pP->p0RGB; delete pP; } break; } case DscImgObjMagic: break; case DatImgObjMagic: { sal_uInt16 nDataID, nDataLen; sal_uInt8 nbyte; sal_uLong nPos, nMaxPos; nPos=pOS2MET->Tell(); nMaxPos=nPos+(sal_uLong)nFieldSize; while (nPosGetError()==0) { *pOS2MET >> nbyte; nDataID=((sal_uInt16)nbyte)&0x00ff; if (nDataID==0x00fe) { *pOS2MET >> nbyte; nDataID=(nDataID<<8)|(((sal_uInt16)nbyte)&0x00ff); nDataLen=ReadBigEndianWord(); nPos+=4; } else { *pOS2MET >> nbyte; nDataLen=((sal_uInt16)nbyte)&0x00ff; nPos+=2; } ReadImageData(nDataID, nDataLen); nPos+=(sal_uLong)nDataLen; pOS2MET->Seek(nPos); } break; } case BegObEnv1Magic: break; case EndObEnv1Magic: break; case BegGrfObjMagic: break; case EndGrfObjMagic: { SvStream * pSave; sal_uLong nPos, nMaxPos; sal_uInt16 nOrderID, nOrderLen; sal_uInt8 nbyte; if (pOrdFile==NULL) break; // in pOrdFile wurden alle "DatGrfObj"-Felder gesammelt, so // dass die darin enthaltnen "Orders" zusammenhangend und nicht durch // "Fields" segmentiert sind. Um sie aus dem MemoryStream auszulesen, // ohne grosse Umstaende deswegen zu haben (frueher wurden die "Orders" // direkt aus pOS2MET gelesen), hier ein kleiner Trick: pSave=pOS2MET; pOS2MET=pOrdFile; //(!) nMaxPos=pOS2MET->Tell(); pOS2MET->Seek(0); // "Segmentheader": *pOS2MET >> nbyte; if (nbyte==0x70) { // Header vorhanden pOS2MET->SeekRel(15); // brauchen wir aber nicht } else pOS2MET->SeekRel(-1); // Kein Header, Byte zurueck // Schleife ueber Order: while (pOS2MET->Tell()GetError()==0) { *pOS2MET >> nbyte; nOrderID=((sal_uInt16)nbyte) & 0x00ff; if (nOrderID==0x00fe) { *pOS2MET >> nbyte; nOrderID=(nOrderID << 8) | (((sal_uInt16)nbyte) & 0x00ff); } if (nOrderID>0x00ff || nOrderID==GOrdPolygn) { // ooo: Laut OS2-Doku sollte die Orderlaenge nun als Big-Endian-Word // gegeben sein (Zitat: "Highorder byte precedes loworder byte"). // Tatsaechlich gibt es aber Dateien, die die Laenge als // Little-Endian-Word angeben (zu mindestens fuer nOrderID==GOrdPolygn). // Also werfen wir eine Muenze oder was ? *pOS2MET >> nbyte; nOrderLen=(sal_uInt16)nbyte&0x00ff; *pOS2MET >> nbyte; if (nbyte!=0) nOrderLen=nOrderLen<<8|(((sal_uInt16)nbyte)&0x00ff); } else if (nOrderID==GOrdSTxAlg || nOrderID==GOrdPTxAlg) nOrderLen=2; else if ((nOrderID&0xff88)==0x0008) nOrderLen=1; else if (nOrderID==0x0000 || nOrderID==0x00ff) nOrderLen=0; else { *pOS2MET >> nbyte; nOrderLen=((sal_uInt16)nbyte) & 0x00ff; } nPos=pOS2MET->Tell(); ReadOrder(nOrderID, nOrderLen); if (nPos+nOrderLen < pOS2MET->Tell()) { OOODEBUG("Order kuerzer als er denkt! OrderID:",nOrderID); OOODEBUG("...und zwar bei Position (Parameteranfang):",nPos); } else if (nPos+nOrderLen != pOS2MET->Tell()) { OOODEBUG(String(nOrderID)+String(" Order nicht alles gelesen! bei:"),nPos); } pOS2MET->Seek(nPos+nOrderLen); } pOS2MET=pSave; if (pOrdFile->GetError()) { pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERROR); ErrorCode=10; } delete pOrdFile; pOrdFile=NULL; break; } case DscGrfObjMagic: { sal_uLong nPos, nMaxPos; sal_uInt16 nDscID, nDscLen; sal_uInt8 nbyte; nMaxPos=pOS2MET->Tell()+(sal_uLong)nFieldSize; while (pOS2MET->Tell()GetError()==0) { *pOS2MET >> nbyte; nDscID =((sal_uInt16)nbyte) & 0x00ff; *pOS2MET >> nbyte; nDscLen=((sal_uInt16)nbyte) & 0x00ff; nPos=pOS2MET->Tell(); ReadDsc(nDscID, nDscLen); pOS2MET->Seek(nPos+nDscLen); } break; } case DatGrfObjMagic: { if (pOrdFile==NULL) { pOrdFile = new SvMemoryStream; pOrdFile->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN); } sal_uInt8 * pBuf; pBuf = new sal_uInt8[nFieldSize]; pOS2MET->Read(pBuf,nFieldSize); pOrdFile->Write(pBuf,nFieldSize); delete[] pBuf; break; } case MapCodFntMagic: ReadFont(nFieldSize); break; case MapDatResMagic: break; } } void OS2METReader::ReadOS2MET( SvStream & rStreamOS2MET, GDIMetaFile & rGDIMetaFile ) { sal_uInt16 nFieldSize; sal_uInt16 nFieldType; sal_uLong nPos, nStartPos, nEndPos, nPercent, nLastPercent; sal_uInt8 nMagicByte; ErrorCode=0; pOS2MET = &rStreamOS2MET; nOrigPos = pOS2MET->Tell(); nOrigNumberFormat = pOS2MET->GetNumberFormatInt(); bCoord32 = sal_True; pPaletteStack=NULL; pAreaStack=NULL; pPathStack=NULL; pPathList=NULL; pFontList=NULL; pBitmapList=NULL; pAttrStack=NULL; aDefAttr.aLinCol =Color(COL_BLACK); aDefAttr.aLinBgCol =Color(COL_WHITE); aDefAttr.eLinMix =ROP_OVERPAINT; aDefAttr.eLinBgMix =ROP_OVERPAINT; aDefAttr.aChrCol =Color(COL_BLACK); aDefAttr.aChrBgCol =Color(COL_WHITE); aDefAttr.eChrMix =ROP_OVERPAINT; aDefAttr.eChrBgMix =ROP_OVERPAINT; aDefAttr.aMrkCol =Color(COL_BLACK); aDefAttr.aMrkBgCol =Color(COL_WHITE); aDefAttr.eMrkMix =ROP_OVERPAINT; aDefAttr.eMrkBgMix =ROP_OVERPAINT; aDefAttr.aPatCol =Color(COL_BLACK); aDefAttr.aPatBgCol =Color(COL_WHITE); aDefAttr.ePatMix =ROP_OVERPAINT; aDefAttr.ePatBgMix =ROP_OVERPAINT; aDefAttr.aImgCol =Color(COL_BLACK); aDefAttr.aImgBgCol =Color(COL_WHITE); aDefAttr.eImgMix =ROP_OVERPAINT; aDefAttr.eImgBgMix =ROP_OVERPAINT; aDefAttr.nArcP =1; aDefAttr.nArcQ =1; aDefAttr.nArcR =0; aDefAttr.nArcS =0; aDefAttr.nChrAng =0; aDefAttr.aChrCellSize=Size(12,12); aDefAttr.nChrSet =0; aDefAttr.aCurPos =Point(0,0); aDefAttr.eLinStyle =PEN_SOLID; aDefAttr.nLinWidth =0; aDefAttr.aMrkCellSize=Size(10,10); aDefAttr.nMrkPrec =0x01; aDefAttr.nMrkSet =0xff; aDefAttr.nMrkSymbol =0x01; aDefAttr.bFill =sal_True; aDefAttr.nStrLinWidth=0; aAttr=aDefAttr; pOrdFile=NULL; pVirDev = new VirtualDevice(); pVirDev->EnableOutput(sal_False); rGDIMetaFile.Record(pVirDev); pOS2MET->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN); nStartPos=pOS2MET->Tell(); nEndPos=pOS2MET->Seek(STREAM_SEEK_TO_END); pOS2MET->Seek(nStartPos); Callback(0); nLastPercent=0; nPos=pOS2MET->Tell(); if ( nStartPos == nEndPos ) { nEndPos = 100; nStartPos = 0; } for (;;) { nPercent=(nPos-nStartPos)*100/(nEndPos-nStartPos); if (nLastPercent+4<=nPercent) { if (Callback((sal_uInt16)nPercent)==sal_True) break; nLastPercent=nPercent; } nFieldSize=ReadBigEndianWord(); *pOS2MET >> nMagicByte; if (nMagicByte!=0xd3) { pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERROR); ErrorCode=7; break; } *pOS2MET >> nFieldType; pOS2MET->SeekRel(3); nPos+=8; nFieldSize-=8; if (pOS2MET->GetError()) break; if (pOS2MET->IsEof()) { pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERROR); ErrorCode=8; break; } if (nFieldType==EndDocumnMagic) break; ReadField(nFieldType, nFieldSize); nPos+=(sal_uLong)nFieldSize; if (pOS2MET->Tell()>nPos) { pOS2MET->SetError(SVSTREAM_FILEFORMAT_ERROR); ErrorCode=9; break; } pOS2MET->Seek(nPos); } rGDIMetaFile.Stop(); delete pVirDev; rGDIMetaFile.SetPrefMapMode( aGlobMapMode ); if( aBoundingRect.GetWidth() && aBoundingRect.GetHeight() ) rGDIMetaFile.SetPrefSize( aBoundingRect.GetSize() ); else { if( aCalcBndRect.Left() || aCalcBndRect.Top() ) rGDIMetaFile.Move( -aCalcBndRect.Left(), -aCalcBndRect.Top() ); rGDIMetaFile.SetPrefSize( aCalcBndRect.GetSize() ); } if (pOrdFile!=NULL) delete pOrdFile; while (pAreaStack!=NULL) { OSArea * p=pAreaStack; pAreaStack=p->pSucc; delete p; } while (pPathStack!=NULL) { OSPath * p=pPathStack; pPathStack=p->pSucc; delete p; } while (pPathList!=NULL) { OSPath * p=pPathList; pPathList=p->pSucc; delete p; } while (pFontList!=NULL) { OSFont * p=pFontList; pFontList=p->pSucc; delete p; } while (pBitmapList!=NULL) { OSBitmap * p=pBitmapList; pBitmapList=p->pSucc; if (p->pBMP!=NULL) delete p->pBMP; delete p; } while (pAttrStack!=NULL) { OSAttr * p=pAttrStack; pAttrStack=p->pSucc; delete p; } while (pPaletteStack!=NULL) { OSPalette * p=pPaletteStack; pPaletteStack=p->pSucc; if (p->p0RGB!=NULL) delete[] p->p0RGB; delete p; } pOS2MET->SetNumberFormatInt(nOrigNumberFormat); if (pOS2MET->GetError()) { OOODEBUG("Fehler Nr.:",ErrorCode); pOS2MET->Seek(nOrigPos); } } //================== GraphicImport - die exportierte Funktion ================ extern "C" sal_Bool __LOADONCALLAPI GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem*, sal_Bool ) { OS2METReader aOS2METReader; GDIMetaFile aMTF; sal_Bool bRet = sal_False; aOS2METReader.ReadOS2MET( rStream, aMTF ); if ( !rStream.GetError() ) { rGraphic=Graphic( aMTF ); bRet = sal_True; } return bRet; }