LCOV - code coverage report
Current view: top level - filter/source/graphicfilter/eos2met - eos2met.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 0 1184 0.0 %
Date: 2014-04-11 Functions: 0 57 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <vcl/fltcall.hxx>
      21             : 
      22             : #include <math.h>
      23             : #include <tools/stream.hxx>
      24             : #include <tools/bigint.hxx>
      25             : #include <vcl/metaact.hxx>
      26             : #include <vcl/salbtype.hxx>
      27             : #include <tools/poly.hxx>
      28             : #include <vcl/graph.hxx>
      29             : #include <vcl/gradient.hxx>
      30             : #include <vcl/hatch.hxx>
      31             : #include <vcl/metric.hxx>
      32             : #include <vcl/font.hxx>
      33             : #include <vcl/virdev.hxx>
      34             : #include <vcl/svapp.hxx>
      35             : #include <vcl/msgbox.hxx>
      36             : #include <svl/solar.hrc>
      37             : #include <vcl/gdimetafiletools.hxx>
      38             : #include <vcl/dibtools.hxx>
      39             : #include <boost/scoped_array.hpp>
      40             : 
      41             : // -----------------------------Field Types-------------------------------
      42             : 
      43             : #define BegDocumnMagic 0xA8A8 /* Begin Document */
      44             : #define EndDocumnMagic 0xA8A9 /* End Document   */
      45             : 
      46             : #define BegResGrpMagic 0xC6A8 /* Begin Resource Group */
      47             : #define EndResGrpMagic 0xC6A9 /* End Resource Group   */
      48             : 
      49             : #define BegColAtrMagic 0x77A8 /* Begin Color Attribute Table */
      50             : #define EndColAtrMagic 0x77A9 /* End Color Attribute Table   */
      51             : #define BlkColAtrMagic 0x77B0 /* Color Attribute Table       */
      52             : #define MapColAtrMagic 0x77AB /* Map Color Attribute Table   */
      53             : 
      54             : #define BegImgObjMagic 0xFBA8 /* Begin Image Object    */
      55             : #define EndImgObjMagic 0xFBA9 /* End Image Object      */
      56             : #define DscImgObjMagic 0xFBA6 /* Image Data Descriptor */
      57             : #define DatImgObjMagic 0xFBEE /* Image Picture Data    */
      58             : 
      59             : #define BegObjEnvMagic 0xC7A8 /* Begin Object Environment Group */
      60             : #define EndObjEnvMagic 0xC7A9 /* End Object Environment Group   */
      61             : 
      62             : #define BegGrfObjMagic 0xBBA8 /* Begin Graphics Object   */
      63             : #define EndGrfObjMagic 0xBBA9 /* End Graphics Object     */
      64             : #define DscGrfObjMagic 0xBBA6 /* Graphics Data Descritor */
      65             : #define DatGrfObjMagic 0xBBEE /* Graphics Data           */
      66             : 
      67             : #define MapCodFntMagic 0x8AAB /* Map Coded Font    */
      68             : #define MapDatResMagic 0xC3AB /* Map Data Resource */
      69             : 
      70             : // Struktur des Metafiles
      71             : // BegDocumn
      72             : //   BegResGrp
      73             : //     BegColAtr
      74             : //       BlkColAtr
      75             : //     EndColAtr
      76             : //     BegImgObj[0..n]
      77             : //       BegResGrp[]
      78             : //         BegColAtr[]
      79             : //           BlkColAtr
      80             : //         EndColAtr
      81             : //       EndResGrp
      82             : //       BegObjEnv[]
      83             : //         MapColAtr
      84             : //       EndObjEnv
      85             : //       DscImgObj
      86             : //       DatImgOb1
      87             : //       DatImgOb2[1..n]
      88             : //     EndImgObj
      89             : //     BegGrfObj
      90             : //       BegObjEnv[]
      91             : //         MapColAtr
      92             : //         MapCodFnt1
      93             : //         MapCodFnt2[0..n]
      94             : //         MapDatRes[0..n]
      95             : //       EndObjEnv
      96             : //       DscGrfObj
      97             : //       DatGrfObj[0..n]
      98             : //     EndGrfObj
      99             : //   EndResGrp
     100             : // EndDocumn
     101             : 
     102             : //============================== METWriter ===================================
     103             : 
     104           0 : struct METChrSet
     105             : {
     106             :     struct METChrSet * pSucc;
     107             :     sal_uInt8 nSet;
     108             :     OUString aName;
     109             :     FontWeight eWeight;
     110             : };
     111             : 
     112           0 : struct METGDIStackMember
     113             : {
     114             :     struct METGDIStackMember *  pSucc;
     115             :     Color                       aLineColor;
     116             :     Color                       aFillColor;
     117             :     RasterOp                    eRasterOp;
     118             :     Font                        aFont;
     119             :     MapMode                     aMapMode;
     120             :     Rectangle                   aClipRect;
     121             : };
     122             : 
     123           0 : class METWriter
     124             : {
     125             : private:
     126             : 
     127             :     sal_Bool                bStatus;
     128             :     sal_uLong               nLastPercent; // with which number pCallback has been called the last time
     129             :     SvStream*           pMET;
     130             :     Rectangle           aPictureRect;
     131             :     MapMode             aPictureMapMode;
     132             :     MapMode             aTargetMapMode;
     133             :     sal_uLong               nActualFieldStartPos;     // start position of the current 'Field'
     134             :     sal_uLong               nNumberOfDataFields;  // number of commenced 'Graphcis Data Fields'
     135             :     Color               aGDILineColor;
     136             :     Color               aGDIFillColor;
     137             :     RasterOp            eGDIRasterOp;
     138             :     Font                aGDIFont;
     139             :     MapMode             aGDIMapMode;   // currently ununsed!
     140             :     Rectangle           aGDIClipRect; // currently ununsed!
     141             :     METGDIStackMember*  pGDIStack;
     142             :     Color               aMETColor;
     143             :     Color               aMETBackgroundColor;
     144             :     Color               aMETPatternSymbol;
     145             :     RasterOp            eMETMix ;
     146             :     long                nMETStrokeLineWidth;
     147             :     Size                aMETChrCellSize;
     148             :     short               nMETChrAngle;
     149             :     sal_uInt8               nMETChrSet;
     150             :     METChrSet*          pChrSetList; // list of Character-Sets
     151             :     sal_uInt8               nNextChrSetId; // the first unused ChrSet-Id
     152             :     sal_uLong               nActBitmapId; // Field-Id of the next Bitmap
     153             :     sal_uLong               nNumberOfActions; // number of Actions in the GDIMetafile
     154             :     sal_uLong               nNumberOfBitmaps; // number of Bitmaps
     155             :     sal_uLong               nWrittenActions;  // number of already processed actions during the writing of the orders
     156             :     sal_uLong               nWrittenBitmaps;  // number of already written Bitmaps
     157             :     sal_uLong               nActBitmapPercent; // percentage of the next bitmap that's already written
     158             : 
     159             :     ::std::auto_ptr< VirtualDevice >    apDummyVDev;
     160             :     OutputDevice*                       pCompDev;
     161             : 
     162             :     com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;
     163             : 
     164             :     void MayCallback();
     165             :         // calculates a percentage based on the 5 parameters above and then does a
     166             :         // Callback as the case may be. Sets bStatus to sal_False if the user wants to cancel
     167             : 
     168             :     void CountActionsAndBitmaps(const GDIMetaFile * pMTF);
     169             :         // Counts the bitmaps and actions (nNumberOfActions and nNumberOfBitmaps have to
     170             :         // be set to 0 at the beginning, since this method is recursive)
     171             : 
     172             :     void WriteBigEndianShort(sal_uInt16 nWord);
     173             :     void WriteBigEndianLong(sal_uLong nLong);
     174             : 
     175             :     void WritePoint(Point aPt);
     176             :     void WriteClipRect( const Rectangle& rRect );
     177             :     void WriteFieldIntroducer(sal_uInt16 nFieldSize, sal_uInt16 nFieldType,
     178             :                               sal_uInt8 nFlags, sal_uInt16 nSegSeqNum);
     179             :     void UpdateFieldSize();
     180             : 
     181             :     void WriteFieldId(sal_uLong nId);
     182             : 
     183             :     void CreateChrSets(const GDIMetaFile * pMTF);
     184             :     void CreateChrSet(const Font & rFont);
     185             :     void WriteChrSets();
     186             :     sal_uInt8 FindChrSet(const Font & rFont);
     187             : 
     188             :     void WriteColorAttributeTable(sal_uLong nFieldId=4, BitmapPalette* pPalette=NULL,
     189             :                                   sal_uInt8 nBasePartFlags=0x40, sal_uInt8 nBasePartLCTID=0);
     190             : 
     191             :     void WriteImageObject(const Bitmap & rBitmap);
     192             :     void WriteImageObjects(const GDIMetaFile * pMTF);
     193             : 
     194             :     void WriteDataDescriptor(const GDIMetaFile * pMTF);
     195             : 
     196             :     void WillWriteOrder(sal_uLong nNextOrderMaximumLength);
     197             : 
     198             :     void METSetAndPushLineInfo( const LineInfo& rLineInfo );
     199             :     void METPopLineInfo( const LineInfo& rLineInfo );
     200             :     void METBitBlt(Point aPt, Size aSize, const Size& rSizePixel);
     201             :     void METBeginArea(sal_Bool bBoundaryLine);
     202             :     void METEndArea();
     203             :     void METBeginPath(sal_uInt32 nPathId);
     204             :     void METEndPath();
     205             :     void METFillPath(sal_uInt32 nPathId);
     206             :     void METOutlinePath(sal_uInt32 nPathId);
     207             :     void METCloseFigure();
     208             :     void METMove(Point aPt);
     209             :     void METLine(Point aPt1, Point aPt2);
     210             :     void METLine(const Polygon & rPolygon);
     211             :     void METLine(const PolyPolygon & rPolyPolygon);
     212             :     void METLineAtCurPos(Point aPt);
     213             :     void METBox(sal_Bool bFill, sal_Bool bBoundary,
     214             :                 Rectangle aRect, sal_uInt32 nHAxis, sal_uInt32 nVAxis);
     215             :     void METFullArc(Point aCenter, double fMultiplier);
     216             :     void METPartialArcAtCurPos(Point aCenter, double fMultiplier,
     217             :                                double fStartAngle, double fSweepAngle);
     218             :     void METChrStr(Point aPt, const OUString& aStr);
     219             :     void METSetArcParams(sal_Int32 nP, sal_Int32 nQ, sal_Int32 nR, sal_Int32 nS);
     220             :     void METSetColor(Color aColor);
     221             :     void METSetBackgroundColor(Color aColor);
     222             :     void METSetMix(RasterOp eROP);
     223             :     void METSetChrCellSize(Size aSize);
     224             :     void METSetChrAngle(short nAngle);
     225             :     void METSetChrSet(sal_uInt8 nSet);
     226             : 
     227             :     void WriteOrders(const GDIMetaFile * pMTF);
     228             : 
     229             :     void WriteObjectEnvironmentGroup(const GDIMetaFile * pMTF);
     230             : 
     231             :     void WriteGraphicsObject(const GDIMetaFile * pMTF);
     232             : 
     233             :     void WriteResourceGroup(const GDIMetaFile * pMTF);
     234             : 
     235             :     void WriteDocument(const GDIMetaFile * pMTF);
     236             : 
     237             : public:
     238             : 
     239           0 :     METWriter()
     240             :         : bStatus(sal_False)
     241             :         , nLastPercent( 0 )
     242             :         , pMET(NULL)
     243             :         , nActualFieldStartPos( 0 )
     244             :         , nNumberOfDataFields( 0 )
     245             :         , eGDIRasterOp( ROP_OVERPAINT )
     246             :         , pGDIStack(NULL)
     247             :         , eMETMix( ROP_OVERPAINT )
     248             :         , nMETStrokeLineWidth(0)
     249             :         , nMETChrAngle(0)
     250             :         , nMETChrSet( 0 )
     251             :         , pChrSetList(NULL)
     252             :         , nNextChrSetId( 0 )
     253             :         , nActBitmapId( 0 )
     254             :         , nNumberOfActions( 0 )
     255             :         , nNumberOfBitmaps( 0 )
     256             :         , nWrittenActions( 0 )
     257             :         , nWrittenBitmaps( 0 )
     258             :         , nActBitmapPercent( 0 )
     259           0 :         , pCompDev(NULL)
     260             :     {
     261           0 :         pCompDev = reinterpret_cast< OutputDevice* >( Application::GetAppWindow() );
     262           0 :         if( !pCompDev )
     263             :         {
     264           0 :             apDummyVDev.reset( new VirtualDevice );
     265           0 :             pCompDev = apDummyVDev.get();
     266             :         }
     267           0 :     }
     268             : 
     269             :     sal_Bool WriteMET( const GDIMetaFile & rMTF, SvStream & rTargetStream,
     270             :                         FilterConfigItem* pConfigItem );
     271             : };
     272             : 
     273             : 
     274             : //========================== Methods of METWriter ==========================
     275             : 
     276           0 : void METWriter::MayCallback()
     277             : {
     278           0 :     if ( xStatusIndicator.is() )
     279             :     {
     280             :         sal_uLong nPercent;
     281           0 :         nPercent=((nWrittenBitmaps<<14)+(nActBitmapPercent<<14)/100+nWrittenActions)
     282           0 :                 *100/((nNumberOfBitmaps<<14)+nNumberOfActions);
     283             : 
     284           0 :         if (nPercent>=nLastPercent+3)
     285             :         {
     286           0 :             nLastPercent = nPercent;
     287           0 :             if ( nPercent <= 100 )
     288           0 :                 xStatusIndicator->setValue( nPercent );
     289             :         }
     290             :     }
     291           0 : }
     292             : 
     293           0 : void METWriter::WriteClipRect( const Rectangle& rRect )
     294             : {
     295           0 :     aGDIClipRect = rRect;
     296           0 :     sal_uInt32 nPathId = ( rRect.IsEmpty() ) ? 0 : 1;
     297           0 :     if ( nPathId )
     298             :     {
     299           0 :         Polygon aPoly( rRect );
     300           0 :         METBeginPath( nPathId );
     301           0 :         METLine( aPoly );
     302           0 :         METEndPath();
     303             :     }
     304           0 :     WillWriteOrder(8);
     305           0 :     pMET->WriteUChar( (sal_uInt8)0xb4 ).WriteUChar( (sal_uInt8)6 )
     306           0 :          .WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0 ).WriteUInt32( nPathId );
     307           0 : }
     308             : 
     309           0 : void METWriter::CountActionsAndBitmaps(const GDIMetaFile * pMTF)
     310             : {
     311             :     const MetaAction* pMA;
     312             : 
     313           0 :     for( size_t nAction = 0, nActionCount=pMTF->GetActionSize(); nAction < nActionCount; nAction++ )
     314             :     {
     315           0 :         pMA =  pMTF->GetAction(nAction);
     316             : 
     317           0 :         switch (pMA->GetType())
     318             :         {
     319             :             case META_EPS_ACTION :
     320             :             {
     321           0 :                 const GDIMetaFile aGDIMetaFile( ((const MetaEPSAction*)pMA)->GetSubstitute() );
     322           0 :                 size_t nCount = aGDIMetaFile.GetActionSize();
     323             :                 size_t i;
     324           0 :                 for ( i = 0; i < nCount; i++ )
     325           0 :                     if ( ((const MetaAction*)aGDIMetaFile.GetAction( i ))->GetType() == META_BMPSCALE_ACTION )
     326           0 :                         break;
     327           0 :                 if ( i == nCount)
     328           0 :                     break;
     329             :             }
     330             :             case META_BMP_ACTION:
     331             :             case META_BMPSCALE_ACTION:
     332             :             case META_BMPSCALEPART_ACTION:
     333             :             case META_BMPEX_ACTION:
     334             :             case META_BMPEXSCALE_ACTION:
     335             :             case META_BMPEXSCALEPART_ACTION:
     336           0 :                 nNumberOfBitmaps++;
     337           0 :             break;
     338             :         }
     339           0 :         nNumberOfActions++;
     340             :     }
     341           0 : }
     342             : 
     343             : 
     344           0 : void METWriter::WriteBigEndianShort(sal_uInt16 nWord)
     345             : {
     346           0 :     pMET->WriteUChar( (sal_uInt8)(nWord>>8) ).WriteUChar( (sal_uInt8)(nWord&0x00ff) );
     347           0 : }
     348             : 
     349             : 
     350           0 : void METWriter::WriteBigEndianLong(sal_uLong nLong)
     351             : {
     352           0 :     WriteBigEndianShort((sal_uInt16)(nLong>>16));
     353           0 :     WriteBigEndianShort((sal_uInt16)(nLong&0x0000ffff));
     354           0 : }
     355             : 
     356             : 
     357           0 : void METWriter::WritePoint(Point aPt)
     358             : {
     359           0 :     Point aNewPt = pCompDev->LogicToLogic( aPt, aPictureMapMode, aTargetMapMode );
     360             : 
     361           0 :     pMET->WriteInt32( (sal_Int32) ( aNewPt.X() - aPictureRect.Left() ) )
     362           0 :          .WriteInt32( (sal_Int32) ( aPictureRect.Bottom() - aNewPt.Y() ) );
     363           0 : }
     364             : 
     365             : 
     366           0 : void METWriter::WriteFieldIntroducer(sal_uInt16 nFieldSize, sal_uInt16 nFieldType,
     367             :                                      sal_uInt8 nFlags, sal_uInt16 nSegSeqNum)
     368             : {
     369           0 :     nActualFieldStartPos=pMET->Tell();
     370           0 :     WriteBigEndianShort(nFieldSize);
     371           0 :     pMET->WriteUChar( (sal_uInt8)0xd3 ).WriteUInt16( nFieldType ).WriteUChar( nFlags ).WriteUInt16( nSegSeqNum );
     372           0 : }
     373             : 
     374             : 
     375           0 : void METWriter::UpdateFieldSize()
     376             : {
     377             :     sal_uLong nPos;
     378             : 
     379           0 :     nPos=pMET->Tell();
     380           0 :     pMET->Seek(nActualFieldStartPos);
     381           0 :     WriteBigEndianShort((sal_uInt16)(nPos-nActualFieldStartPos));
     382           0 :     pMET->Seek(nPos);
     383           0 : }
     384             : 
     385             : 
     386           0 : void METWriter::WriteFieldId(sal_uLong nId)
     387             : {
     388             :     sal_uInt8 nbyte;
     389             :     short i;
     390             : 
     391           0 :     for (i=1; i<=8; i++) {
     392           0 :         nbyte= '0' + (sal_uInt8)((nId >> (32-i*4)) & 0x0f);
     393           0 :         pMET->WriteUChar( nbyte );
     394             :     }
     395           0 : }
     396             : 
     397             : 
     398           0 : void METWriter::CreateChrSets(const GDIMetaFile * pMTF)
     399             : {
     400             :     size_t nAction, nActionCount;
     401             :     const MetaAction * pMA;
     402             : 
     403           0 :     if (bStatus==sal_False)
     404           0 :         return;
     405             : 
     406           0 :     nActionCount = pMTF->GetActionSize();
     407             : 
     408           0 :     for (nAction = 0; nAction < nActionCount; nAction++)
     409             :     {
     410           0 :         pMA = pMTF->GetAction(nAction);
     411             : 
     412           0 :         switch (pMA->GetType())
     413             :         {
     414             :             case META_FONT_ACTION:
     415             :             {
     416           0 :                 const MetaFontAction* pA = (const MetaFontAction*) pMA;
     417           0 :                 CreateChrSet( pA->GetFont() );
     418             :             }
     419           0 :             break;
     420             :         }
     421             :     }
     422             : }
     423             : 
     424             : 
     425           0 : void METWriter::CreateChrSet(const Font & rFont)
     426             : {
     427             :     METChrSet * pCS;
     428             : 
     429           0 :     if ( FindChrSet( rFont ) == 0 )
     430             :     {
     431           0 :         pCS = new METChrSet;
     432           0 :         pCS->pSucc = pChrSetList; pChrSetList=pCS;
     433           0 :         pCS->nSet = nNextChrSetId++;
     434           0 :         pCS->aName = rFont.GetName();
     435           0 :         pCS->eWeight = rFont.GetWeight();
     436             :     }
     437           0 : }
     438             : 
     439             : 
     440           0 : sal_uInt8 METWriter::FindChrSet(const Font & rFont)
     441             : {
     442             :     METChrSet* pCS;
     443             : 
     444           0 :     for (pCS=pChrSetList; pCS!=NULL; pCS=pCS->pSucc)
     445             :     {
     446           0 :         if (pCS->aName==rFont.GetName() && pCS->eWeight==rFont.GetWeight() )
     447           0 :             return pCS->nSet;
     448             :     }
     449             : 
     450           0 :     return 0;
     451             : }
     452             : 
     453             : 
     454           0 : void METWriter::WriteChrSets()
     455             : {
     456             :     sal_uInt16 i;
     457           0 :     char c = 0;
     458             :     METChrSet * pCS;
     459             :     sal_uInt8 nbyte;
     460             : 
     461           0 :     for (pCS=pChrSetList; pCS!=NULL; pCS=pCS->pSucc)
     462             :     {
     463             : 
     464           0 :         WriteFieldIntroducer(0x58,MapCodFntMagic,0,0);
     465             : 
     466           0 :         WriteBigEndianShort(0x0050);
     467             : 
     468           0 :         pMET->WriteUChar( (sal_uInt8)0x0c ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x84 ).WriteUChar( (sal_uInt8)0x00 );
     469           0 :         pMET->WriteUChar( (sal_uInt8)0xa4 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x01 );
     470           0 :         pMET->WriteUChar( (sal_uInt8)0x01 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
     471             : 
     472           0 :         pMET->WriteUChar( (sal_uInt8)0x04 ).WriteUChar( (sal_uInt8)0x24 ).WriteUChar( (sal_uInt8)0x05 ).WriteUChar( (sal_uInt8)pCS->nSet );
     473             : 
     474           0 :         pMET->WriteUChar( (sal_uInt8)0x14 ).WriteUChar( (sal_uInt8)0x1f );
     475           0 :         switch (pCS->eWeight)
     476             :         {
     477           0 :             case WEIGHT_THIN:       nbyte=1; break;
     478           0 :             case WEIGHT_ULTRALIGHT: nbyte=2; break;
     479           0 :             case WEIGHT_LIGHT:      nbyte=3; break;
     480           0 :             case WEIGHT_SEMILIGHT:  nbyte=4; break;
     481           0 :             case WEIGHT_NORMAL:     nbyte=5; break;
     482           0 :             case WEIGHT_SEMIBOLD:   nbyte=6; break;
     483           0 :             case WEIGHT_BOLD:       nbyte=7; break;
     484           0 :             case WEIGHT_ULTRABOLD:  nbyte=8; break;
     485           0 :             case WEIGHT_BLACK:      nbyte=9; break;
     486           0 :             default:                nbyte=5;
     487             :         }
     488           0 :         pMET->WriteUChar( nbyte );
     489           0 :         pMET->WriteUChar( (sal_uInt8)0x05 );
     490           0 :         pMET->WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
     491           0 :         pMET->WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
     492           0 :         pMET->WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
     493           0 :         pMET->WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x0c );
     494             : 
     495           0 :         pMET->WriteUChar( (sal_uInt8)0x06 ).WriteUChar( (sal_uInt8)0x20 ).WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0xd4 );
     496           0 :         pMET->WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0x52 );
     497             : 
     498           0 :         pMET->WriteUChar( (sal_uInt8)0x24 ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x08 ).WriteUChar( (sal_uInt8)0x00 );
     499             :         OString n(OUStringToOString(pCS->aName,
     500           0 :             osl_getThreadTextEncoding()));
     501           0 :         for (i=0; i<32; i++)
     502             :         {
     503           0 :             if ( i == 0 || c != 0 )
     504           0 :                 c = n[i];
     505           0 :             pMET->WriteChar( c );
     506             :         }
     507           0 :     }
     508           0 : }
     509             : 
     510             : 
     511           0 : void METWriter::WriteColorAttributeTable(sal_uLong nFieldId, BitmapPalette* pPalette, sal_uInt8 nBasePartFlags, sal_uInt8 nBasePartLCTID)
     512             : {
     513             :     sal_uInt16 nIndex,nNumI,i;
     514             : 
     515           0 :     if (bStatus==sal_False) return;
     516             : 
     517             :     //--- The Field 'Begin Color Attribute Table':
     518           0 :     WriteFieldIntroducer(16,BegColAtrMagic,0,0);
     519           0 :     WriteFieldId(nFieldId);
     520             : 
     521             :     //--- The Field 'Color Attribute Table':
     522           0 :     WriteFieldIntroducer(0,BlkColAtrMagic,0,0);
     523           0 :     pMET->WriteUChar( nBasePartFlags ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( nBasePartLCTID ); // 'Base Part'
     524           0 :     if (pPalette!=NULL)
     525             :     {
     526           0 :         nIndex=0;
     527           0 :         while (nIndex<pPalette->GetEntryCount())
     528             :         {
     529           0 :             nNumI=pPalette->GetEntryCount()-nIndex;
     530           0 :             if (nNumI>81) nNumI=81;
     531           0 :             pMET->WriteUChar( (sal_uInt8)(11+nNumI*3) );                   // length of the parameter
     532           0 :             pMET->WriteUChar( (sal_uInt8)1 ).WriteUChar( (sal_uInt8)0 ).WriteUChar( (sal_uInt8)1 );        // typ: element list, Reserved, Format: RGB
     533           0 :             pMET->WriteUChar( (sal_uInt8)0 ); WriteBigEndianShort(nIndex); // start-Index (3 Bytes)
     534           0 :             pMET->WriteUChar( (sal_uInt8)8 ).WriteUChar( (sal_uInt8)8 ).WriteUChar( (sal_uInt8)8 );        // Bits per component R,G,B
     535           0 :             pMET->WriteUChar( (sal_uInt8)3 );                              // number of bytes per entry
     536           0 :             for (i=0; i<nNumI; i++)
     537             :             {
     538           0 :                 const BitmapColor& rCol = (*pPalette)[ nIndex ];
     539             : 
     540           0 :                 pMET->WriteUChar( (sal_uInt8) rCol.GetRed() );
     541           0 :                 pMET->WriteUChar( (sal_uInt8) rCol.GetGreen() );
     542           0 :                 pMET->WriteUChar( (sal_uInt8) rCol.GetBlue() );
     543           0 :                 nIndex++;
     544             :             }
     545             :         }
     546             :     }
     547             :     else
     548             :     {
     549             :         // 'Trible Generating'
     550           0 :         pMET->WriteUChar( (sal_uInt8)0x0a ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x01 ).WriteUChar( (sal_uInt8)0x00 );
     551           0 :         pMET->WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x08 ).WriteUChar( (sal_uInt8)0x08 ).WriteUChar( (sal_uInt8)0x08 );
     552             :     }
     553           0 :     UpdateFieldSize();
     554             : 
     555             :     //--- The Field 'End Color Attribute Table':
     556           0 :     WriteFieldIntroducer(16,EndColAtrMagic,0,0);
     557           0 :     WriteFieldId(nFieldId);
     558             : 
     559           0 :     if (pMET->GetError())
     560           0 :         bStatus=sal_False;
     561             : }
     562             : 
     563             : 
     564           0 : void METWriter::WriteImageObject(const Bitmap & rBitmap)
     565             : {
     566           0 :     SvMemoryStream aTemp(0x00010000,0x00010000);
     567             :     sal_uInt32 nWidth,nHeight,nResX,nResY;
     568             :     sal_uLong nBytesPerLine,i,j,nNumColors,ny,nLines;
     569             :     sal_uLong nActColMapId;
     570             :     sal_uInt16 nBitsPerPixel;
     571             :     sal_uInt8 nbyte;
     572             : 
     573           0 :     if (bStatus==sal_False)
     574           0 :         return;
     575             : 
     576           0 :     nActColMapId=((nActBitmapId>>24)&0x000000ff) | ((nActBitmapId>> 8)&0x0000ff00) |
     577           0 :                  ((nActBitmapId<< 8)&0x00ff0000) | ((nActBitmapId<<24)&0xff000000);
     578             : 
     579             :     //--- The Field 'Begin Image Object':
     580           0 :     WriteFieldIntroducer(16,BegImgObjMagic,0,0);
     581           0 :     WriteFieldId(nActBitmapId);
     582             : 
     583             :     // generate Windows-BMP file
     584           0 :     WriteDIB(rBitmap, aTemp, false, true);
     585             : 
     586             :     // read header of the Windows-BMP file:
     587           0 :     aTemp.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
     588           0 :     aTemp.Seek(18);
     589           0 :     aTemp.ReadUInt32( nWidth ).ReadUInt32( nHeight );
     590           0 :     aTemp.SeekRel(2);
     591           0 :     aTemp.ReadUInt16( nBitsPerPixel );
     592           0 :     aTemp.SeekRel(8);
     593           0 :     aTemp.ReadUInt32( nResX ).ReadUInt32( nResY );
     594           0 :     aTemp.SeekRel(8);
     595             : 
     596           0 :     nNumColors=1<<nBitsPerPixel;
     597           0 :     nBytesPerLine=((nWidth*nBitsPerPixel+0x0000001f) & 0xffffffe0 ) >> 3;
     598             : 
     599             :     // read color palette as the case may be and write it to the MET file:
     600           0 :     if (nBitsPerPixel<=8)
     601             :     {
     602           0 :         BitmapPalette   aPal( (sal_uInt16) nNumColors );
     603             :         sal_uInt8           nr,ng,nb;
     604             : 
     605           0 :         for (i=0; i<nNumColors; i++)
     606             :         {
     607           0 :             aTemp.ReadUChar( nb ).ReadUChar( ng ).ReadUChar( nr ); aTemp.SeekRel(1);
     608           0 :             aPal[ (sal_uInt16) i ] = BitmapColor( nr, ng, nb );
     609             :         }
     610             : 
     611             :         //--- The Field 'Begin Resource Group':
     612           0 :         WriteFieldIntroducer(16,BegResGrpMagic,0,0);
     613           0 :         WriteFieldId(nActColMapId);
     614             : 
     615             :         //--- writer color table:
     616           0 :         WriteColorAttributeTable(nActColMapId,&aPal,0,1);
     617             : 
     618             :         //--- The Field 'End Resource Group':
     619           0 :         WriteFieldIntroducer(16,EndResGrpMagic,0,0);
     620           0 :         WriteFieldId(nActColMapId);
     621             : 
     622             :         //--- The Field 'Begin Object Environment Group':
     623           0 :         WriteFieldIntroducer(16,BegObjEnvMagic,0,0);
     624           0 :         WriteFieldId(nActBitmapId);
     625             : 
     626             :         //--- The Field 'Map Color Attribute Table':
     627           0 :         WriteFieldIntroducer(26,MapColAtrMagic,0,0);
     628           0 :         WriteBigEndianShort(0x0012);
     629           0 :         pMET->WriteUChar( (sal_uInt8)0x0c ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x84 ).WriteUChar( (sal_uInt8)0x00 );
     630           0 :         WriteFieldId(nActColMapId);
     631           0 :         pMET->WriteUChar( (sal_uInt8)0x04 ).WriteUChar( (sal_uInt8)0x24 ).WriteUChar( (sal_uInt8)0x07 ).WriteUChar( (sal_uInt8)0x01 );
     632             : 
     633             :         //--- The Field 'End Object Environment Group':
     634           0 :         WriteFieldIntroducer(16,EndObjEnvMagic,0,0);
     635           0 :         WriteFieldId(nActBitmapId);
     636             :     }
     637             : 
     638             :     //--- The Field 'Image Data Descriptor':
     639           0 :     WriteFieldIntroducer(17,DscImgObjMagic,0,0);
     640           0 :     pMET->WriteUChar( (sal_uInt8)0x01 ); // Unit of measure: tens of centimeters
     641           0 :     WriteBigEndianShort((sal_uInt16)nResX);
     642           0 :     WriteBigEndianShort((sal_uInt16)nResY);
     643           0 :     WriteBigEndianShort((sal_uInt16)nWidth);
     644           0 :     WriteBigEndianShort((sal_uInt16)nHeight);
     645             : 
     646             :     //--- The first Field 'Image Picture Data':
     647           0 :     WriteFieldIntroducer(0,DatImgObjMagic,0,0);
     648             : 
     649             :     // Begin Segment:
     650           0 :     pMET->WriteUChar( (sal_uInt8)0x70 ).WriteUChar( (sal_uInt8)0x00 );
     651             : 
     652             :     // Begin Image Content:
     653           0 :     pMET->WriteUChar( (sal_uInt8)0x91 ).WriteUChar( (sal_uInt8)0x01 ).WriteUChar( (sal_uInt8)0xff );
     654             : 
     655             :     // Image Size:
     656           0 :     pMET->WriteUChar( (sal_uInt8)0x94 ).WriteUChar( (sal_uInt8)0x09 ).WriteUChar( (sal_uInt8)0x02 );
     657           0 :     pMET->WriteUInt16( (sal_uInt16) 0 ).WriteUInt16( (sal_uInt16) 0 );
     658           0 :     WriteBigEndianShort((sal_uInt16)nHeight);
     659           0 :     WriteBigEndianShort((sal_uInt16)nWidth);
     660             : 
     661             :     // Image Encoding:
     662           0 :     pMET->WriteUChar( (sal_uInt8)0x95 ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0x03 );
     663             : 
     664             :     // Image IDE-Size:
     665           0 :     pMET->WriteUChar( (sal_uInt8)0x96 ).WriteUChar( (sal_uInt8)0x01 ).WriteUChar( (sal_uInt8)nBitsPerPixel );
     666             : 
     667           0 :     if (nBitsPerPixel<=8) {
     668             :         // Image LUT-ID
     669           0 :         pMET->WriteUChar( (sal_uInt8)0x97 ).WriteUChar( (sal_uInt8)0x01 ).WriteUChar( (sal_uInt8)0x01 );
     670             :     }
     671             :     else {
     672             :         // IDE Structure
     673           0 :         pMET->WriteUChar( (sal_uInt8)0x9b ).WriteUChar( (sal_uInt8)0x08 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x01 );
     674           0 :         pMET->WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x08 );
     675           0 :         pMET->WriteUChar( (sal_uInt8)0x08 ).WriteUChar( (sal_uInt8)0x08 );
     676             :     }
     677             : 
     678           0 :     boost::scoped_array<sal_uInt8> pBuf(new sal_uInt8[nBytesPerLine]);
     679           0 :     ny=0;
     680           0 :     while (ny<nHeight) {
     681             : 
     682             :         // finalize the previous field 'Image Picture Data':
     683           0 :         UpdateFieldSize();
     684             : 
     685             :         // and start a new field 'Image Picture Data':
     686           0 :         WriteFieldIntroducer(0,DatImgObjMagic,0,0);
     687             : 
     688             :         // read and write several Scanlines:
     689           0 :         nLines=nHeight-ny;
     690           0 :         if (nLines*nBytesPerLine>30000) nLines=30000/nBytesPerLine;
     691           0 :         if (nLines<1) nLines=1;
     692           0 :         WriteBigEndianShort(0xfe92);
     693           0 :         WriteBigEndianShort((sal_uInt16)(nLines*nBytesPerLine));
     694           0 :         for (i=0; i<nLines; i++) {
     695           0 :             aTemp.Read(pBuf.get(),nBytesPerLine);
     696           0 :             if (nBitsPerPixel==24) {
     697           0 :                 for (j=2; j<nBytesPerLine; j+=3) {
     698           0 :                     nbyte=pBuf[j]; pBuf[j]=pBuf[j-2]; pBuf[j-2]=nbyte;
     699             :                 }
     700             :             }
     701           0 :             pMET->Write(pBuf.get(),nBytesPerLine);
     702           0 :             ny++;
     703             :         }
     704           0 :         if (aTemp.GetError() || pMET->GetError()) bStatus=sal_False;
     705           0 :         nActBitmapPercent=(ny+1)*100/nHeight;
     706           0 :         MayCallback();
     707           0 :         if (bStatus==sal_False) return;
     708             :     }
     709           0 :     pBuf.reset();
     710             : 
     711             :     // End Image Content:
     712           0 :     pMET->WriteUChar( (sal_uInt8)0x93 ).WriteUChar( (sal_uInt8)0x00 );
     713             : 
     714             :     // End Segment:
     715           0 :     pMET->WriteUChar( (sal_uInt8)0x71 ).WriteUChar( (sal_uInt8)0x00 );
     716             : 
     717             :     // finalize the last field 'Image Picture Data':
     718           0 :     UpdateFieldSize();
     719             : 
     720             :     //--- The Field 'End Image Object':
     721           0 :     WriteFieldIntroducer(16,EndImgObjMagic,0,0);
     722           0 :     WriteFieldId(nActBitmapId);
     723             : 
     724             :     // increase Ids:
     725           0 :     nActBitmapId++;
     726             : 
     727             :     // count Bitmaps:
     728           0 :     nWrittenBitmaps++;
     729           0 :     nActBitmapPercent=0;
     730             : 
     731           0 :     if (pMET->GetError()) bStatus=sal_False;
     732             : }
     733             : 
     734             : 
     735           0 : void METWriter::WriteImageObjects(const GDIMetaFile * pMTF)
     736             : {
     737             :     const MetaAction*   pMA;
     738             : 
     739           0 :     if (bStatus==sal_False)
     740           0 :         return;
     741             : 
     742           0 :     for ( size_t nAction = 0, nActionCount = pMTF->GetActionSize(); nAction < nActionCount; nAction++)
     743             :     {
     744           0 :         pMA = pMTF->GetAction(nAction);
     745             : 
     746           0 :         switch (pMA->GetType())
     747             :         {
     748             :             case META_BMP_ACTION:
     749             :             {
     750           0 :                 METSetMix( eGDIRasterOp );
     751           0 :                 WriteImageObject( ( (MetaBmpAction*) pMA )->GetBitmap() );
     752             :             }
     753           0 :             break;
     754             : 
     755             :             case META_BMPSCALE_ACTION:
     756             :             {
     757           0 :                 METSetMix( eGDIRasterOp );
     758           0 :                 WriteImageObject( ( (MetaBmpScaleAction*) pMA )->GetBitmap() );
     759             :             }
     760           0 :             break;
     761             : 
     762             :             case META_BMPSCALEPART_ACTION:
     763             :             {
     764           0 :                 METSetMix( eGDIRasterOp );
     765           0 :                 WriteImageObject( ( (MetaBmpScalePartAction*) pMA )->GetBitmap() );
     766             :             }
     767           0 :             break;
     768             : 
     769             :             case META_BMPEX_ACTION:
     770             :             {
     771           0 :                 METSetMix( eGDIRasterOp );
     772           0 :                 WriteImageObject( Graphic( ( (MetaBmpExAction*) pMA )->GetBitmapEx() ).GetBitmap() );
     773             :             }
     774           0 :             break;
     775             : 
     776             :             case META_BMPEXSCALE_ACTION:
     777             :             {
     778           0 :                 METSetMix( eGDIRasterOp );
     779           0 :                 WriteImageObject( Graphic( ( (MetaBmpExScaleAction*) pMA )->GetBitmapEx() ).GetBitmap() );
     780             :             }
     781           0 :             break;
     782             : 
     783             :             case META_BMPEXSCALEPART_ACTION:
     784             :             {
     785           0 :                 METSetMix( eGDIRasterOp );
     786           0 :                 WriteImageObject( Graphic( ( (MetaBmpExScalePartAction*) pMA )->GetBitmapEx() ).GetBitmap() );
     787             :             }
     788           0 :             break;
     789             : 
     790             :             case META_EPS_ACTION :
     791             :             {
     792           0 :                 const MetaEPSAction* pA = (const MetaEPSAction*)pMA;
     793           0 :                 const GDIMetaFile aGDIMetaFile( pA->GetSubstitute() );
     794             : 
     795           0 :                 size_t nCount = aGDIMetaFile.GetActionSize();
     796           0 :                 for ( size_t i = 0; i < nCount; i++ )
     797             :                 {
     798           0 :                     const MetaAction* pMetaAct = aGDIMetaFile.GetAction( i );
     799           0 :                     if ( pMetaAct->GetType() == META_BMPSCALE_ACTION )
     800             :                     {
     801           0 :                         const MetaBmpScaleAction* pBmpScaleAction = (const MetaBmpScaleAction*)pMetaAct;
     802           0 :                         METSetMix( eGDIRasterOp );
     803           0 :                         WriteImageObject( pBmpScaleAction->GetBitmap() );
     804           0 :                         break;
     805             :                     }
     806           0 :                 }
     807             :             }
     808           0 :             break;
     809             :         }
     810             : 
     811           0 :         if (bStatus==sal_False)
     812           0 :             break;
     813             :     }
     814             : 
     815           0 :     if (pMET->GetError())
     816           0 :         bStatus=sal_False;
     817             : }
     818             : 
     819           0 : void METWriter::WriteDataDescriptor(const GDIMetaFile *)
     820             : {
     821           0 :     if (bStatus==sal_False)
     822           0 :         return;
     823             : 
     824           0 :     WriteFieldIntroducer(0,DscGrfObjMagic,0,0);
     825             : 
     826             : 
     827             :     // The following is the OS2 original documentation and the associated implementation
     828             : 
     829             : 
     830             :     //  Parameters (all required and in this order)
     831             : 
     832             :     //  0         0xF7 Specify GVM Subset
     833             :     //  1         Length of following data 0x07
     834             :     //  2         0xB0 drawing order subset
     835             :     //  3-4       0x0000
     836             :     //  5         0x23 Level 3.2
     837             :     //  6         0x01 Version 1
     838             :     //  7         Length of following field 0x01
     839             :     //  8         Coordinate types in data
     840             :     //       0x04Intel16
     841             :     //       0x05Intel32
     842           0 :     pMET->WriteUChar( (sal_uInt8)0xf7 ).WriteUChar( (sal_uInt8)0x07 ).WriteUChar( (sal_uInt8)0xb0 ).WriteUChar( (sal_uInt8)0x00 )
     843           0 :          .WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x23 ).WriteUChar( (sal_uInt8)0x01 ).WriteUChar( (sal_uInt8)0x01 )
     844           0 :          .WriteUChar( (sal_uInt8)0x05 );
     845             : 
     846             :     //  0         0xF6 Set Picture Descriptor
     847             :     //  1         Length of following data
     848             :     //  2         Flags
     849             :     //       0    B'0' Picture in 2D
     850             :     //       1    Picture Dimensions
     851             :     //            B'0'  Not absolute (PU_ARBITRARY PS)
     852             :     //            B'1'  Absolute (example: PU_TWIPS PS)
     853             :     //       2    Picture Elements
     854             :     //            B'0'  Not pels
     855             :     //            B'1'  Pels (PU_PELS PS)
     856             :     //                  (Bit 1 must also be set)
     857             :     //       3-7  B'00000'
     858             :     //  3         0x00 Reserved
     859             :     //  4         Picture frame size coordinate type
     860             :     //       0x04  Intel16
     861             :     //       0x05  Intel32
     862             :     //  5         UnitsOfMeasure
     863             :     //       0x00  Ten inches
     864             :     //       0x01  Decimeter
     865             :     //  6-11 or 6-17(2 or 4 bytes) Resolution.
     866             :     //       GPS Units / UOM on x axis
     867             :     //       GPS Units / UOM on y axis
     868             :     //       GPS Units / UOM on z axis
     869             :     //  12-23 or 18-41(2 or 4 bytes) Window Size.
     870             :     //       GPS X left, X right
     871             :     //       GPS Y bottom, Y top
     872             :     //       GPS Z near, Z far
     873           0 :     Size aUnitsPerDecimeter=OutputDevice::LogicToLogic(Size(10,10),MapMode(MAP_CM),aPictureMapMode);
     874           0 :     pMET->WriteUChar( (sal_uInt8)0xf6 ).WriteUChar( (sal_uInt8)0x28 ).WriteUChar( (sal_uInt8)0x40 ).WriteUChar( (sal_uInt8)0x00 )
     875           0 :          .WriteUChar( (sal_uInt8)0x05 ).WriteUChar( (sal_uInt8)0x01 )
     876           0 :          .WriteUInt32( (sal_uInt32)(aUnitsPerDecimeter.Width()) )
     877           0 :          .WriteUInt32( (sal_uInt32)(aUnitsPerDecimeter.Height()) )
     878           0 :          .WriteUInt32( (sal_uInt32)0 )
     879           0 :          .WriteUInt32( (sal_uInt32)0 ).WriteUInt32( (sal_uInt32)aPictureRect.GetWidth() )
     880           0 :          .WriteUInt32( (sal_uInt32)0 ).WriteUInt32( (sal_uInt32)aPictureRect.GetHeight() )
     881           0 :          .WriteUInt32( (sal_uInt32)0 ).WriteUInt32( (sal_uInt32)0 );
     882             : 
     883             :     //  0         0x21 Set Current Defaults
     884             :     //  1         Length of following data
     885             :     //  2         Set Default Parameter Format 0x08
     886             :     //  3-4       Mask 0xE000
     887             :     //  5         Names 0x8F
     888             :     //  6         Coordinates
     889             :     //       0x00  Picture in 2D
     890             :     //  7         Transforms
     891             :     //       0x04  Intel16
     892             :     //       0x05  Intel32
     893             :     //  8         Geometrics
     894             :     //       0x04  Intel16
     895             :     //       0x05  Intel32
     896           0 :     pMET->WriteUChar( (sal_uInt8)0x21 ).WriteUChar( (sal_uInt8)0x07 ).WriteUChar( (sal_uInt8)0x08 ).WriteUChar( (sal_uInt8)0xe0 )
     897           0 :          .WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x8f ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x05 )
     898           0 :          .WriteUChar( (sal_uInt8)0x05 );
     899             : 
     900             :     //  0         0x21 Set Current Defaults
     901             :     //  1         Length of following data
     902             :     //  2         Set default viewing transform 0x07
     903             :     //  3-4       Mask 0xCC0C
     904             :     //  5         Names 0x8F
     905             :     //  6-n       M11, M12, M21, M22, M41, M42   Matrix elements
     906           0 :     pMET->WriteUChar( (sal_uInt8)0x21 ).WriteUChar( (sal_uInt8)0x1c ).WriteUChar( (sal_uInt8)0x07 ).WriteUChar( (sal_uInt8)0xcc )
     907           0 :          .WriteUChar( (sal_uInt8)0x0c ).WriteUChar( (sal_uInt8)0x8f )
     908           0 :          .WriteUInt32( (sal_uInt32)0x00010000 ).WriteUInt32( (sal_uInt32)0x00000000 ).WriteUInt32( (sal_uInt32)0x00000000 )
     909           0 :          .WriteUInt32( (sal_uInt32)0x00010000 ).WriteUInt32( (sal_uInt32)0x00000000 ).WriteUInt32( (sal_uInt32)0x00000000 );
     910             : 
     911             :     //  0         0x21 Set Current Defaults
     912             :     //  1         Length of following data
     913             :     //  2         Set default line attributes 0x01
     914             :     //  3-4       Mask - OR of as many of the following bits as are required:
     915             :     //       0x8000  Line type
     916             :     //       0x4000  Line width
     917             :     //       0x2000  Line end
     918             :     //       0x1000  Line join
     919             :     //       0x0800  Stroke width
     920             :     //       0x0008  Line color
     921             :     //       0x0002  Line mix
     922             :     //  5         Flags
     923             :     //
     924             :     //       0x0F Set indicated default attributes to initial values. (Data field is not present in this
     925             :     //             instance).
     926             :     //       0x8F Set indicated default attributes to specified values.
     927             :     //  6-n       Data - data values as required, in the following order if present.
     928             :     //            No space is reserved for attributes for which the corresponding mask flag was not
     929             :     //            set.
     930             :     //
     931             :     //       (1 byte)  - Line type
     932             :     //       (1 byte)  - Line width
     933             :     //       (1 byte)  - Line end
     934             :     //       (1 byte)  - Line join
     935             :     //       (G bytes) - Stroke width
     936             :     //       (4 bytes) - Line color
     937             :     //       (1 byte)  - Line mix (G=2 or 4 depending on the Geometrics parameter of Set Default
     938             :     //            Parameter Format)
     939             :     // Nanu! witziger-weise fehlt obiger Abschnitt in den Metadateien. Also lassen wir ihn auch weg
     940             : 
     941             :     //  0         0x21 Set Current Defaults
     942             :     //  1         Length of following data
     943             :     //  2         Set Default Character Attributes 0x02
     944             :     //  3-4       Mask - OR of as many of the following bits as are required:
     945             :     //
     946             :     //       0x8000  Character angle
     947             :     //       0x4000  Character box
     948             :     //       0x2000  Character direction
     949             :     //       0x1000  Character precision
     950             :     //       0x0800  Character set
     951             :     //       0x0400  Character shear
     952             :     //       0x0040  Character break extra
     953             :     //       0x0020  Character extra
     954             :     //       0x0008  Character color
     955             :     //       0x0004  Character background color
     956             :     //       0x0002  Character mix
     957             :     //       0x0001  Character background mix
     958             :     //  5         Flags
     959             :     //       0x0FSet indicated default attributes to initial values.  (Data field is not present in this
     960             :     //            case).
     961             :     //       0x8FSet indicated default attributes to specified values.
     962             :     //  6-n       Data - data values as required, in the following order if present.
     963             :     //            No space is reserved for attributes for which the corresponding Mask flag was not
     964             :     //            set.
     965             :     //       (2*G bytes)     - Character angle
     966             :     //       (2*G + 4 bytes)- Character box
     967             :     //       (1 byte)        - Character direction
     968             :     //       (1 byte)        - Character precision
     969             :     //       (1 byte)        - Character set
     970             :     //       (2*G bytes)     - Character shear
     971             :     //       (4 bytes)       - Character break extra
     972             :     //       (4 bytes)       - Character extra
     973             :     //       (4 bytes)       - Character color
     974             :     //       (4 bytes)       - Character background color
     975             :     //       (1 byte)        - Character mix
     976             :     //       (1 byte)        - Character background mix (G=2 or 4 depending on the Geometrics
     977             :     //            parameter of Set Default Parameter Format)
     978           0 :     pMET->WriteUChar( (sal_uInt8)0x21 ).WriteUChar( (sal_uInt8)0x10 ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x40 )
     979           0 :          .WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x8f )
     980           0 :          .WriteUChar( (sal_uInt8)0xaa ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 )
     981           0 :          .WriteUChar( (sal_uInt8)0x44 ).WriteUChar( (sal_uInt8)0x04 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 )
     982           0 :          .WriteUChar( (sal_uInt8)0xa8 ).WriteUChar( (sal_uInt8)0xaa ).WriteUChar( (sal_uInt8)0x40 ).WriteUChar( (sal_uInt8)0x44 );
     983             : 
     984             :     //  0         0x21 Set Current Defaults
     985             :     //  1         Length of following data
     986             :     //  2         Set Default Marker Attributes 0x03
     987             :     //  3-4       Mask - OR of as many of the following bits as are required:
     988             :     //       0x4000  Marker box
     989             :     //       0x1000  Marker precision
     990             :     //       0x0800  Marker set
     991             :     //       0x0100  Marker symbol
     992             :     //       0x0008  Marker color
     993             :     //       0x0004  Marker background color
     994             :     //       0x0002  Marker mix
     995             :     //       0x0001  Marker background mix
     996             :     //  5         Flags
     997             :     //       0x0F  Set indicated default attributes to initial values.
     998             :     //             (Data field is not present in this instance)
     999             :     //       0x8F  Set indicated default attributes to specified values.
    1000             :     //  6-n       Data - data values as required, in this order if present.
    1001             :     //            No space is reserved for attributes for which the corresponding Mask flag was not
    1002             :     //            set.
    1003             :     //       (2*G bytes)    - Marker box
    1004             :     //       (1 byte)       - Marker precision
    1005             :     //       (1 byte)       - Marker set
    1006             :     //       (1 byte)       - Marker symbol
    1007             :     //       (4 bytes)      - Marker color
    1008             :     //       (4 bytes)      - Marker background color
    1009             :     //       (1 byte)       - Marker mix
    1010             :     //       (1 byte)       - Marker background mix (G=2 or 4 depending on the Geometrics
    1011             :     //            parameter of Set Default Parameter Format)
    1012           0 :     pMET->WriteUChar( (sal_uInt8)0x21 ).WriteUChar( (sal_uInt8)0x0c ).WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0x40 )
    1013           0 :          .WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x8f )
    1014           0 :          .WriteUChar( (sal_uInt8)0x66 ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 )
    1015           0 :          .WriteUChar( (sal_uInt8)0x66 ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
    1016             : 
    1017             :     //  0         0x21 Set Current Defaults
    1018             :     //  1         Length of following data
    1019             :     //  2         Set Default Pattern Attributes 0x04
    1020             :     //  3-4       Mask - OR of as many of the following bits as are required:
    1021             :     //       0x0800  Pattern set
    1022             :     //       0x0100  Pattern symbol
    1023             :     //       0x0080  Pattern reference point
    1024             :     //       0x0008  Pattern color
    1025             :     //       0x0004  Pattern background color
    1026             :     //       0x0002  Pattern mix
    1027             :     //       0x0001  Pattern background mix
    1028             :     //       5       Flags
    1029             :     //
    1030             :     //            0x0F Set indicated default attributes to initial values.
    1031             :     //                  (Data field is not present in this instance)
    1032             :     //            0x8F Set indicated default attributes to specified values.
    1033             :     //       6-n     Data - data values as required, in this order if present.
    1034             :     //               No space is reserved for attributes for which the corresponding Mask flag was
    1035             :     //               not set.
    1036             :     //
    1037             :     //            (1 byte)     - Pattern set
    1038             :     //            (1 byte)     - Pattern symbol
    1039             :     //            (2*G bytes)  - Pattern reference point
    1040             :     //            (4 bytes)    - Pattern color
    1041             :     //            (4 bytes)    - Pattern background color
    1042             :     //            (1 byte)     - Pattern mix
    1043             :     //            (1 byte)     - Pattern background mix (G=2 or 4 depending on the Geometrics
    1044             :     //               parameter of Set Default Parameter Format)
    1045             :     //       0       0x21 Set Current Defaults
    1046             :     //       1       Length of following data
    1047             :     //       2       Set Default Image Attributes 0x06
    1048             :     //       3-4     Mask - OR of as many of these bits as are required:
    1049             :     //            0x0008  Image color
    1050             :     //            0x0004  Image background color
    1051             :     //            0x0002  Image mix
    1052             :     //            0x0001  Image background mix
    1053             :     //       5       Flags
    1054             :     //            0x0F Set indicated default attributes to initial values. (Data field is not present in
    1055             :     //                  this instance)
    1056             :     //            0x8F Set indicated default attributes to specified values.
    1057             :     //       6-n     Data - data values as required, in this order if present.
    1058             :     //               No space is reserved for attributes for which the corresponding Mask flag was
    1059             :     //               not set.
    1060             :     //            (4 bytes)  - Image color
    1061             :     //            (4 bytes)  - Image background color
    1062             :     //            (1 byte)   - Image mix
    1063             :     //            (1 byte)   - Image background mix
    1064             :     //       0       0x21 Set Current Defaults
    1065             :     //       1       Length of following data
    1066             :     //       2       Set Default Viewing Window 0x05
    1067             :     //       3-4     Mask - OR of as many of the following bits as are required:
    1068             :     //            0x8000  x left limit
    1069             :     //            0x4000  x right limit
    1070             :     //            0x2000  y bottom limit
    1071             :     //            0x1000  y top limit
    1072             :     //       5       Flags
    1073             :     //            0x0F Set indicated default attributes to initial values.
    1074             :     //                  (Data field is not present in this case).
    1075             :     //            0x8F Set indicated default attributes to specified values.
    1076             :     //       6-n     Data - data values as required, in the following order if present.
    1077             :     //               No space is reserved for attributes for which the corresponding Mask flag was
    1078             :     //               not set.
    1079             :     //            (2*G bytes)  - x left limit
    1080             :     //            (2*G bytes)  - x right limit
    1081             :     //            (2*G bytes)  - y bottom limit
    1082             :     //            (2*G bytes)  - y top limit (G=2 or 4 depending on the Geometrics parameter of Set
    1083             :     //               Default Parameter Format)
    1084             :     //       0       0x21 Set Current Defaults
    1085             :     //       1       Length of following data
    1086             :     //       2       Set Default Arc Parameters 0x0B
    1087             :     //       3-4     Mask - OR of as many of the following bits as are required:
    1088             :     //            0x8000  P value
    1089             :     //            0x4000  Q value
    1090             :     //            0x2000  R value
    1091             :     //            0x1000  S value
    1092             :     //       5       Flags
    1093             :     //            0x0F Set indicated default attributes to initial values.
    1094             :     //                  (Data field is not present in this case).
    1095             :     //            0x8F Set indicated default attributes to specified values.
    1096             :     //       6-n     Data - data values as required, in the following order if present.
    1097             :     //               No space is reserved for attributes for which the corresponding Mask flag was
    1098             :     //               not set.
    1099             :     //            (G bytes)  - P value
    1100             :     //            (G bytes)  - Q value
    1101             :     //            (G bytes)  - R value
    1102             :     //            (G bytes)  - S value (G=2 or 4 depending on the Geometrics parameter of Set
    1103             :     //               Default Parameter Format)
    1104             :     //       0       0x21 Set Current Defaults
    1105             :     //       1       Length of following data
    1106             :     //       2       Set Default Pick Identifier 0x0C
    1107             :     //       3-4     Mask - OR of as many of the following bits as are required:
    1108             :     //            0x8000  Pick identifier
    1109             :     //       5       Flags
    1110             :     //            0x0F Set indicated default attributes to initial values.
    1111             :     //                  (Data field is not present in this case).
    1112             :     //            0x8F Set indicated default attributes to specified values.
    1113             :     //       6-n     Data - data values as required, in the following order if present.
    1114             :     //               No space is reserved for attributes for which the corresponding Mask flag was
    1115             :     //               not set.
    1116             :     //            (4 bytes)  - Pick identifier
    1117             : 
    1118             :     //       0       0xE7 Set Bit-map Identifier
    1119             :     //       1       Length of following data 0x07
    1120             :     //       2-3     Usage Flags 0x8000
    1121             :     //       4-7     Bit-map handle
    1122             :     //       8       Lcid
    1123           0 :     if (nNumberOfBitmaps>0) {
    1124           0 :         pMET->WriteUChar( (sal_uInt8)0xe7 ).WriteUChar( (sal_uInt8)0x07 ).WriteUChar( (sal_uInt8)0x80 ).WriteUChar( (sal_uInt8)0x00 );
    1125           0 :         WriteBigEndianLong(nActBitmapId);
    1126           0 :         pMET->WriteUChar( (sal_uInt8)0xfe );
    1127             :     }
    1128             : 
    1129           0 :     UpdateFieldSize();
    1130             : 
    1131           0 :     if (pMET->GetError()) bStatus=sal_False;
    1132             : }
    1133             : 
    1134             : 
    1135           0 : void METWriter::WillWriteOrder(sal_uLong nNextOrderMaximumLength)
    1136             : {
    1137             :     // The parameters of a 'Graphics Data Fields' can be (according to OS2
    1138             :     // documentation) at most 32759 bytes long. Meant by this is the size
    1139             :     // of the field minus the 'Structured Field Introducer' (size 8).
    1140             :     // So the size of the whole field can be at most 8+32759=32767=0x7fff.
    1141             :     // To be on the safe side whe use 30000 as the limit.
    1142           0 :     if (pMET->Tell()-nActualFieldStartPos+nNextOrderMaximumLength>30000)
    1143             :     {
    1144           0 :         UpdateFieldSize();
    1145           0 :         WriteFieldIntroducer(0,DatGrfObjMagic,0,0);
    1146           0 :         nNumberOfDataFields++;
    1147             :     }
    1148           0 : }
    1149             : 
    1150             : 
    1151             : 
    1152           0 : void METWriter::METBitBlt(Point aPt, Size aSize, const Size& rBmpSizePixel)
    1153             : {
    1154           0 :     WillWriteOrder(46);
    1155           0 :     pMET->WriteUChar( (sal_uInt8)0xd6 ).WriteUChar( (sal_uInt8)44 ).WriteUInt16( (sal_uInt16)0 ).WriteUInt16( (sal_uInt16) 0x00cc );
    1156           0 :     WriteBigEndianLong(nActBitmapId++);
    1157           0 :     pMET->WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
    1158           0 :     WritePoint(Point(aPt.X(),aPt.Y()+aSize.Height()));
    1159           0 :     WritePoint(Point(aPt.X()+aSize.Width(),aPt.Y()));
    1160           0 :     pMET->WriteUInt32( (sal_uInt32)0 ).WriteUInt32( (sal_uInt32)0 )
    1161           0 :          .WriteUInt32( (sal_uInt32)(rBmpSizePixel.Width()) )
    1162           0 :          .WriteUInt32( (sal_uInt32)(rBmpSizePixel.Height()) );
    1163           0 : }
    1164             : 
    1165           0 : void METWriter::METSetAndPushLineInfo( const LineInfo& rLineInfo )
    1166             : {
    1167           0 :     sal_Int32 nWidth = pCompDev->LogicToLogic( Size( rLineInfo.GetWidth(),0 ), aPictureMapMode, aTargetMapMode ).Width();
    1168             : 
    1169           0 :     WillWriteOrder( 8 );            // set stroke linewidth
    1170           0 :     pMET  ->WriteUChar( (sal_uInt8)0x15 )
    1171           0 :            .WriteUChar( (sal_uInt8)6 )
    1172           0 :            .WriteUChar( (sal_uInt8)0 )             // Flags
    1173           0 :            .WriteUChar( (sal_uInt8)0 )
    1174           0 :            .WriteInt32( nWidth );
    1175             : 
    1176           0 :     if ( rLineInfo.GetStyle() != LINE_SOLID )
    1177             :     {
    1178           0 :         sal_uInt8 nStyle = 0;           // LineDefault;
    1179             : 
    1180           0 :         switch ( rLineInfo.GetStyle() )
    1181             :         {
    1182             :             case LINE_NONE :
    1183           0 :                 nStyle = 8;
    1184           0 :             break;
    1185             : 
    1186             :             case LINE_DASH :
    1187             :             {
    1188           0 :                 if ( rLineInfo.GetDotCount() )
    1189             :                 {
    1190           0 :                     if ( !rLineInfo.GetDashCount() )
    1191           0 :                         nStyle = 1; // LINE_DOT
    1192             :                     else
    1193           0 :                         nStyle = 3; // LINE_DASH_DOT
    1194             :                 }
    1195             :                 else
    1196           0 :                     nStyle = 2;     // LINE_DASH
    1197             :             }
    1198           0 :             break;
    1199             :             case LineStyle_SOLID:
    1200             :             case LineStyle_FORCE_EQUAL_SIZE:
    1201           0 :                 break;  // not handled -Wall
    1202             :         }
    1203           0 :         WillWriteOrder( 2 );
    1204           0 :         pMET->WriteUChar( (sal_uInt8)0x18 ).WriteUChar( nStyle );     // set LineType
    1205             :     }
    1206           0 : }
    1207             : 
    1208           0 : void METWriter::METPopLineInfo( const LineInfo& rLineInfo )
    1209             : {
    1210           0 :     WillWriteOrder( 8 );            // set stroke linewidth
    1211           0 :     pMET  ->WriteUChar( (sal_uInt8)0x15 )
    1212           0 :            .WriteUChar( (sal_uInt8)6 )
    1213           0 :            .WriteUChar( (sal_uInt8)0 )             // Flags
    1214           0 :            .WriteUChar( (sal_uInt8)0 )
    1215           0 :            .WriteUInt32( (sal_uInt32)1 );
    1216             : 
    1217           0 :     if ( rLineInfo.GetStyle() != LINE_SOLID )
    1218             :     {
    1219           0 :         WillWriteOrder( 2 );
    1220           0 :         pMET->WriteUChar( (sal_uInt8)0x18 ).WriteUChar( (sal_uInt8)0 );       // set LineType
    1221             :     }
    1222           0 : }
    1223             : 
    1224           0 : void METWriter::METBeginArea(sal_Bool bBoundaryLine)
    1225             : {
    1226           0 :     WillWriteOrder(2);
    1227           0 :     pMET->WriteUChar( (sal_uInt8)0x68 );
    1228           0 :     if (bBoundaryLine) pMET->WriteUChar( (sal_uInt8)0xc0 );
    1229           0 :     else               pMET->WriteUChar( (sal_uInt8)0x80 );
    1230           0 : }
    1231             : 
    1232             : 
    1233           0 : void METWriter::METEndArea()
    1234             : {
    1235           0 :     WillWriteOrder(2);
    1236           0 :     pMET->WriteUChar( (sal_uInt8)0x60 ).WriteUChar( (sal_uInt8)0 );
    1237           0 : }
    1238             : 
    1239             : 
    1240           0 : void METWriter::METBeginPath(sal_uInt32 nPathId)
    1241             : {
    1242           0 :     WillWriteOrder(8);
    1243           0 :     pMET->WriteUChar( (sal_uInt8)0xd0 ).WriteUChar( (sal_uInt8)6 ).WriteUInt16( (sal_uInt16) 0 ).WriteUInt32( nPathId );
    1244           0 : }
    1245             : 
    1246             : 
    1247           0 : void METWriter::METEndPath()
    1248             : {
    1249           0 :     WillWriteOrder(2);
    1250           0 :     pMET->WriteUChar( (sal_uInt8)0x7f ).WriteUChar( (sal_uInt8)0 );
    1251           0 : }
    1252             : 
    1253             : 
    1254           0 : void METWriter::METFillPath(sal_uInt32 nPathId)
    1255             : {
    1256           0 :     WillWriteOrder(8);
    1257           0 :     pMET->WriteUChar( (sal_uInt8)0xd7 ).WriteUChar( (sal_uInt8)6 )
    1258           0 :          .WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0 ).WriteUInt32( nPathId );
    1259           0 : }
    1260             : 
    1261             : 
    1262           0 : void METWriter::METOutlinePath(sal_uInt32 nPathId)
    1263             : {
    1264           0 :     WillWriteOrder(8);
    1265           0 :     pMET->WriteUChar( (sal_uInt8)0xd4 ).WriteUChar( (sal_uInt8)6 )
    1266           0 :          .WriteUChar( (sal_uInt8)0 ).WriteUChar( (sal_uInt8)0 ).WriteUInt32( nPathId );
    1267           0 : }
    1268             : 
    1269             : 
    1270           0 : void METWriter::METCloseFigure()
    1271             : {
    1272           0 :     WillWriteOrder(2);
    1273           0 :     pMET->WriteUChar( (sal_uInt8)0x7d ).WriteUChar( (sal_uInt8)0 );
    1274           0 : }
    1275             : 
    1276             : 
    1277           0 : void METWriter::METMove(Point aPt)
    1278             : {
    1279           0 :     WillWriteOrder(10);
    1280           0 :     pMET->WriteUChar( (sal_uInt8)0x21 ).WriteUChar( (sal_uInt8)8 );
    1281           0 :     WritePoint(aPt);
    1282           0 : }
    1283             : 
    1284             : 
    1285           0 : void METWriter::METLine(Point aPt1, Point aPt2)
    1286             : {
    1287           0 :     WillWriteOrder(18);
    1288           0 :     pMET->WriteUChar( (sal_uInt8)0xc1 ).WriteUChar( (sal_uInt8)16 );
    1289           0 :     WritePoint(aPt1); WritePoint(aPt2);
    1290           0 : }
    1291             : 
    1292             : 
    1293           0 : void METWriter::METLine(const Polygon & rPolygon)
    1294             : {
    1295             :     sal_uInt16 nNumPoints,i,j,nOrderPoints;
    1296             :     sal_Bool bFirstOrder;
    1297             : 
    1298           0 :     bFirstOrder=sal_True;
    1299           0 :     i=0; nNumPoints=rPolygon.GetSize();
    1300           0 :     while (i<nNumPoints) {
    1301           0 :         nOrderPoints=nNumPoints-i;
    1302           0 :         if (nOrderPoints>30) nOrderPoints=30;
    1303           0 :         WillWriteOrder(nOrderPoints*8+2);
    1304           0 :         if (bFirstOrder==sal_True) {
    1305           0 :             pMET->WriteUChar( (sal_uInt8)0xc1 ); // Line at given pos
    1306           0 :             bFirstOrder=sal_False;
    1307             :         }
    1308             :         else {
    1309           0 :             pMET->WriteUChar( (sal_uInt8)0x81 ); // Line at current pos
    1310             :         }
    1311           0 :         pMET->WriteUChar( (sal_uInt8)(nOrderPoints*8) );
    1312           0 :         for (j=0; j<nOrderPoints; j++) WritePoint(rPolygon.GetPoint(i++));
    1313             :     }
    1314           0 : }
    1315             : 
    1316             : 
    1317           0 : void METWriter::METLine(const PolyPolygon & rPolyPolygon)
    1318             : {
    1319             :     sal_uInt16 i,nCount;
    1320           0 :     nCount=rPolyPolygon.Count();
    1321           0 :     for (i=0; i<nCount; i++) {
    1322           0 :         METLine(rPolyPolygon.GetObject(i));
    1323           0 :         METCloseFigure();
    1324             :     }
    1325           0 : }
    1326             : 
    1327             : 
    1328           0 : void METWriter::METLineAtCurPos(Point aPt)
    1329             : {
    1330           0 :     WillWriteOrder(10);
    1331           0 :     pMET->WriteUChar( (sal_uInt8)0x81 ).WriteUChar( (sal_uInt8)8 );
    1332           0 :     WritePoint(aPt);
    1333           0 : }
    1334             : 
    1335             : 
    1336           0 : void METWriter::METBox(sal_Bool bFill, sal_Bool bBoundary,
    1337             :                        Rectangle aRect, sal_uInt32 nHAxis, sal_uInt32 nVAxis)
    1338             : {
    1339           0 :     sal_uInt8 nFlags=0;
    1340           0 :     if (bFill)     nFlags|=0x40;
    1341           0 :     if (bBoundary) nFlags|=0x20;
    1342             : 
    1343           0 :     WillWriteOrder(28);
    1344           0 :     pMET->WriteUChar( (sal_uInt8)0xc0 ).WriteUChar( (sal_uInt8)26 ).WriteUChar( nFlags ).WriteUChar( (sal_uInt8)0 );
    1345           0 :     WritePoint(aRect.BottomLeft());
    1346           0 :     WritePoint(aRect.TopRight());
    1347           0 :     pMET->WriteUInt32( nHAxis ).WriteUInt32( nVAxis );
    1348           0 : }
    1349             : 
    1350             : 
    1351           0 : void METWriter::METFullArc(Point aCenter, double fMultiplier)
    1352             : {
    1353           0 :     WillWriteOrder(14);
    1354           0 :     pMET->WriteUChar( (sal_uInt8)0xc7 ).WriteUChar( (sal_uInt8)12 );
    1355           0 :     WritePoint(aCenter);
    1356           0 :     pMET->WriteInt32( (sal_Int32)(fMultiplier*65536.0+0.5) );
    1357           0 : }
    1358             : 
    1359             : 
    1360           0 : void METWriter::METPartialArcAtCurPos(Point aCenter, double fMultiplier,
    1361             :                                       double fStartAngle, double fSweepAngle)
    1362             : {
    1363           0 :     fStartAngle*=180.0/3.14159265359;
    1364           0 :     while (fStartAngle>360.0) fStartAngle-=360.0;
    1365           0 :     while (fStartAngle<0.0) fStartAngle+=360.0;
    1366           0 :     fSweepAngle*=180.0/3.14159265359;
    1367           0 :     while (fSweepAngle>360.0) fSweepAngle-=360.0;
    1368           0 :     while (fSweepAngle<.00) fSweepAngle+=360.0;
    1369           0 :     WillWriteOrder(22);
    1370           0 :     pMET->WriteUChar( (sal_uInt8)0xa3 ).WriteUChar( (sal_uInt8)20 );
    1371           0 :     WritePoint(aCenter);
    1372           0 :     pMET->WriteInt32( (sal_Int32)(fMultiplier*65536.0+0.5) );
    1373           0 :     pMET->WriteInt32( (sal_Int32)(fStartAngle*65536.0+0.5) );
    1374           0 :     pMET->WriteInt32( (sal_Int32)(fSweepAngle*65536.0+0.5) );
    1375           0 : }
    1376             : 
    1377             : 
    1378           0 : void METWriter::METChrStr( Point aPt, const OUString& aUniStr )
    1379             : {
    1380             :     OString aStr(OUStringToOString(aUniStr,
    1381           0 :         osl_getThreadTextEncoding()));
    1382           0 :     sal_uInt16 nLen = aStr.getLength();
    1383           0 :     WillWriteOrder( 11 + nLen );
    1384           0 :     pMET->WriteUChar( (sal_uInt8)0xc3 ).WriteUChar( (sal_uInt8)( 9 + nLen ) );
    1385           0 :     WritePoint(aPt);
    1386           0 :     for (sal_uInt16 i = 0; i < nLen; ++i)
    1387           0 :         pMET->WriteChar( aStr[i] );
    1388           0 :     pMET->WriteUChar( (sal_uInt8)0 );
    1389           0 : }
    1390             : 
    1391             : 
    1392           0 : void METWriter::METSetArcParams(sal_Int32 nP, sal_Int32 nQ, sal_Int32 nR, sal_Int32 nS)
    1393             : {
    1394           0 :     WillWriteOrder(18);
    1395           0 :     pMET->WriteUChar( (sal_uInt8)0x22 ).WriteUChar( (sal_uInt8)16 ).WriteInt32( nP ).WriteInt32( nQ ).WriteInt32( nR ).WriteInt32( nS );
    1396           0 : }
    1397             : 
    1398             : 
    1399           0 : void METWriter::METSetColor(Color aColor)
    1400             : {
    1401           0 :     if (aColor==aMETColor) return;
    1402           0 :     aMETColor=aColor;
    1403             : 
    1404           0 :     WillWriteOrder(6);
    1405           0 :     pMET->WriteUChar( (sal_uInt8)0xa6 ).WriteUChar( (sal_uInt8)4 ).WriteUChar( (sal_uInt8)0 )
    1406           0 :          .WriteUChar( (sal_uInt8)(aColor.GetBlue()) )
    1407           0 :          .WriteUChar( (sal_uInt8)(aColor.GetGreen()) )
    1408           0 :          .WriteUChar( (sal_uInt8)(aColor.GetRed()) );
    1409             : }
    1410             : 
    1411             : 
    1412           0 : void METWriter::METSetBackgroundColor(Color aColor)
    1413             : {
    1414           0 :     if (aColor==aMETBackgroundColor) return;
    1415           0 :     aMETBackgroundColor=aColor;
    1416             : 
    1417           0 :     WillWriteOrder(6);
    1418           0 :     pMET->WriteUChar( (sal_uInt8)0xa7 ).WriteUChar( (sal_uInt8)4 ).WriteUChar( (sal_uInt8)0 )
    1419           0 :          .WriteUChar( (sal_uInt8)(aColor.GetBlue()) )
    1420           0 :          .WriteUChar( (sal_uInt8)(aColor.GetGreen()) )
    1421           0 :          .WriteUChar( (sal_uInt8)(aColor.GetRed()) );
    1422             : }
    1423             : 
    1424           0 : void METWriter::METSetMix(RasterOp eROP)
    1425             : {
    1426             :     sal_uInt8 nMix;
    1427             : 
    1428           0 :     if (eMETMix==eROP)
    1429           0 :         return;
    1430             : 
    1431           0 :     eMETMix=eROP;
    1432             : 
    1433           0 :     switch (eROP)
    1434             :     {
    1435           0 :         case ROP_INVERT: nMix=0x0c; break;
    1436           0 :         case ROP_XOR:    nMix=0x04; break;
    1437           0 :         default:         nMix=0x02;
    1438             :     }
    1439             : 
    1440           0 :     WillWriteOrder(2);
    1441           0 :     pMET->WriteUChar( (sal_uInt8)0x0c ).WriteUChar( nMix );
    1442             : }
    1443             : 
    1444             : 
    1445           0 : void METWriter::METSetChrCellSize(Size aSize)
    1446             : {
    1447           0 :     if (aMETChrCellSize==aSize)
    1448           0 :         return;
    1449             : 
    1450           0 :     aMETChrCellSize=aSize;
    1451           0 :     WillWriteOrder(10);
    1452           0 :     if (aSize.Width()==0) aSize.Width()=aSize.Height();
    1453           0 :     pMET->WriteUChar( (sal_uInt8)0x33 ).WriteUChar( (sal_uInt8)8 ).WriteInt32( (sal_Int32)aSize.Width() ).WriteInt32( (sal_Int32)aSize.Height() );
    1454             : }
    1455             : 
    1456             : 
    1457           0 : void METWriter::METSetChrAngle(short nAngle)
    1458             : {
    1459             :     sal_Int32 nax, nay;
    1460             : 
    1461           0 :     if (nMETChrAngle==nAngle) return;
    1462           0 :     nMETChrAngle=nAngle;
    1463             : 
    1464           0 :     if (nAngle==0)
    1465             :     {
    1466           0 :         nax=256;
    1467           0 :         nay=0;
    1468             :     }
    1469             :     else
    1470             :     {
    1471           0 :         double fa=((double)nAngle)/1800.0*3.14159265359;
    1472           0 :         nax=(long)(256.0*cos(fa)+0.5);
    1473           0 :         nay=(long)(256.0*sin(fa)+0.5);
    1474             :     }
    1475             : 
    1476           0 :     WillWriteOrder(10);
    1477           0 :     pMET->WriteUChar( (sal_uInt8)0x34 ).WriteUChar( (sal_uInt8)8 ).WriteInt32( nax ).WriteInt32( nay );
    1478             : }
    1479             : 
    1480             : 
    1481           0 : void METWriter::METSetChrSet(sal_uInt8 nSet)
    1482             : {
    1483           0 :     if (nMETChrSet==nSet)
    1484           0 :         return;
    1485             : 
    1486           0 :     nMETChrSet=nSet;
    1487           0 :     WillWriteOrder(2);
    1488           0 :     pMET->WriteUChar( (sal_uInt8)0x38 ).WriteUChar( nSet );
    1489             : }
    1490             : 
    1491             : 
    1492           0 : void METWriter::WriteOrders( const GDIMetaFile* pMTF )
    1493             : {
    1494           0 :     if(bStatus==sal_False)
    1495           0 :         return;
    1496             : 
    1497           0 :     for( size_t nA = 0, nACount = pMTF->GetActionSize(); nA < nACount; nA++ )
    1498             :     {
    1499           0 :         const MetaAction* pMA = pMTF->GetAction( nA );
    1500             : 
    1501           0 :         switch (pMA->GetType())
    1502             :         {
    1503             :             case META_PIXEL_ACTION:
    1504             :             {
    1505           0 :                 const MetaPixelAction* pA = (const MetaPixelAction*) pMA;
    1506           0 :                 METSetMix( eGDIRasterOp );
    1507           0 :                 METSetColor( pA->GetColor() );
    1508           0 :                 METLine( pA->GetPoint(),pA->GetPoint() );
    1509             :             }
    1510           0 :             break;
    1511             : 
    1512             :             case META_POINT_ACTION:
    1513             :             {
    1514           0 :                 const MetaPointAction* pA = (const MetaPointAction*) pMA;
    1515             : 
    1516           0 :                 METSetArcParams(1,1,0,0);
    1517           0 :                 METSetMix(eGDIRasterOp);
    1518           0 :                 METSetColor(aGDILineColor);
    1519           0 :                 METBeginArea(sal_False);
    1520           0 :                 METFullArc(pA->GetPoint(),0.5);
    1521           0 :                 METEndArea();
    1522             :             }
    1523           0 :             break;
    1524             : 
    1525             :             case META_LINE_ACTION:
    1526             :             {
    1527           0 :                 const MetaLineAction* pA = (const MetaLineAction*) pMA;
    1528             : 
    1529           0 :                 if( aGDILineColor != Color( COL_TRANSPARENT ) )
    1530             :                 {
    1531           0 :                     LineInfo aLineInfo( pA->GetLineInfo() );
    1532           0 :                     if ( ! ( aLineInfo.IsDefault() ) )
    1533           0 :                         METSetAndPushLineInfo( aLineInfo );
    1534             : 
    1535           0 :                     METSetMix( eGDIRasterOp );
    1536           0 :                     METSetColor(aGDILineColor);
    1537           0 :                     METBeginPath( 1 );
    1538           0 :                     METLine( pA->GetStartPoint(), pA->GetEndPoint() );
    1539           0 :                     METEndPath();
    1540           0 :                     METOutlinePath( 1 );
    1541             : 
    1542           0 :                     if ( ! ( aLineInfo.IsDefault() ) )
    1543           0 :                         METPopLineInfo( aLineInfo );
    1544             :                 }
    1545             :             }
    1546           0 :             break;
    1547             : 
    1548             :             case META_RECT_ACTION:
    1549             :             {
    1550           0 :                 const MetaRectAction* pA = (const MetaRectAction*) pMA;
    1551             : 
    1552           0 :                 if( aGDIFillColor != Color( COL_TRANSPARENT ) )
    1553             :                 {
    1554           0 :                     METSetMix( eGDIRasterOp );
    1555           0 :                     METSetColor( aGDIFillColor );
    1556           0 :                     METSetBackgroundColor( aGDIFillColor );
    1557           0 :                     METBox( sal_True, sal_False, pA->GetRect(), 0, 0 );
    1558             :                 }
    1559             : 
    1560           0 :                 if( aGDILineColor != Color( COL_TRANSPARENT ) )
    1561             :                 {
    1562           0 :                     METSetMix( eGDIRasterOp );
    1563           0 :                     METSetColor( aGDILineColor );
    1564           0 :                     METBox( sal_False, sal_True, pA->GetRect(), 0, 0 );
    1565             :                 }
    1566             :             }
    1567           0 :             break;
    1568             : 
    1569             :             case META_ROUNDRECT_ACTION:
    1570             :             {
    1571           0 :                 const MetaRoundRectAction* pA = (const MetaRoundRectAction*) pMA;
    1572             : 
    1573           0 :                 if( aGDIFillColor != Color( COL_TRANSPARENT ) )
    1574             :                 {
    1575           0 :                     METSetMix( eGDIRasterOp );
    1576           0 :                     METSetColor( aGDIFillColor );
    1577           0 :                     METSetBackgroundColor( aGDIFillColor );
    1578           0 :                     METBox( sal_True, sal_False, pA->GetRect(), pA->GetHorzRound(), pA->GetVertRound() );
    1579             :                 }
    1580             : 
    1581           0 :                 if( aGDILineColor != Color( COL_TRANSPARENT ) )
    1582             :                 {
    1583           0 :                     METSetMix( eGDIRasterOp );
    1584           0 :                     METSetColor( aGDILineColor );
    1585           0 :                     METBox( sal_False, sal_True, pA->GetRect(), pA->GetHorzRound(), pA->GetVertRound() );
    1586             :                 }
    1587             :             }
    1588           0 :             break;
    1589             : 
    1590             :             case META_ELLIPSE_ACTION:
    1591             :             {
    1592           0 :                 const MetaEllipseAction*    pA = (const MetaEllipseAction*) pMA;
    1593           0 :                 Point                       aCenter;
    1594             : 
    1595           0 :                 aCenter.X()=(pA->GetRect().Left()+pA->GetRect().Right())/2;
    1596           0 :                 aCenter.Y()=(pA->GetRect().Top()+pA->GetRect().Bottom())/2;
    1597             : 
    1598           0 :                 METSetArcParams(pA->GetRect().GetWidth(), pA->GetRect().GetHeight(),0,0);
    1599             : 
    1600           0 :                 if( aGDIFillColor != Color( COL_TRANSPARENT ) )
    1601             :                 {
    1602           0 :                     METSetMix( eGDIRasterOp );
    1603           0 :                     METSetColor( aGDIFillColor );
    1604           0 :                     METSetBackgroundColor( aGDIFillColor );
    1605           0 :                     METBeginArea(sal_False);
    1606           0 :                     METFullArc(aCenter,0.5);
    1607           0 :                     METEndArea();
    1608             :                 }
    1609             : 
    1610           0 :                 if( aGDILineColor != Color( COL_TRANSPARENT ) )
    1611             :                 {
    1612           0 :                     METSetMix( eGDIRasterOp );
    1613           0 :                     METSetColor( aGDILineColor );
    1614           0 :                     METFullArc( aCenter,0.5 );
    1615             :                 }
    1616             :             }
    1617           0 :             break;
    1618             : 
    1619             :             case META_ARC_ACTION:
    1620             :             {
    1621           0 :                 const MetaArcAction*    pA = (const MetaArcAction*) pMA;
    1622           0 :                 Point                   aStartPos,aCenter;
    1623             :                 double                  fdx,fdy,fa1,fa2;
    1624             : 
    1625           0 :                 aCenter.X()=(pA->GetRect().Left()+pA->GetRect().Right())/2;
    1626           0 :                 aCenter.Y()=(pA->GetRect().Top()+pA->GetRect().Bottom())/2;
    1627           0 :                 fdx=(double)(pA->GetStartPoint().X()-aCenter.X());
    1628           0 :                 fdy=(double)(pA->GetStartPoint().Y()-aCenter.Y());
    1629           0 :                 fdx*=(double)pA->GetRect().GetHeight();
    1630           0 :                 fdy*=(double)pA->GetRect().GetWidth();
    1631           0 :                 if (fdx==0.0 && fdy==0.0) fdx=1.0;
    1632           0 :                 fa1=atan2(-fdy,fdx);
    1633           0 :                 fdx=(double)(pA->GetEndPoint().X()-aCenter.X());
    1634           0 :                 fdy=(double)(pA->GetEndPoint().Y()-aCenter.Y());
    1635           0 :                 fdx*=(double)pA->GetRect().GetHeight();
    1636           0 :                 fdy*=(double)pA->GetRect().GetWidth();
    1637           0 :                 if (fdx==0.0 && fdy==0.0) fdx=1.0;
    1638           0 :                 fa2=atan2(-fdy,fdx);
    1639           0 :                 aStartPos.X()=aCenter.X()+(long)(((double)pA->GetRect().GetWidth())*cos(fa1)/2.0+0.5);
    1640           0 :                 aStartPos.Y()=aCenter.Y()-(long)(((double)pA->GetRect().GetHeight())*sin(fa1)/2.0+0.5);
    1641             : 
    1642           0 :                 if( aGDILineColor != Color( COL_TRANSPARENT ) )
    1643             :                 {
    1644           0 :                     METSetMix( eGDIRasterOp );
    1645           0 :                     METSetColor( aGDILineColor );
    1646           0 :                     METSetArcParams(pA->GetRect().GetWidth(), pA->GetRect().GetHeight(),0,0);
    1647           0 :                     METBeginPath(1);
    1648           0 :                     METMove(aStartPos);
    1649           0 :                     METPartialArcAtCurPos(aCenter,0.5,fa1,fa2-fa1);
    1650           0 :                     METEndPath();
    1651           0 :                     METOutlinePath(1);
    1652             :                 }
    1653             :             }
    1654           0 :             break;
    1655             : 
    1656             :             case META_PIE_ACTION:
    1657             :             {
    1658           0 :                 const MetaPieAction*    pA = (const MetaPieAction*) pMA;
    1659           0 :                 Point                   aCenter;
    1660             :                 double                  fdx,fdy,fa1,fa2;
    1661             : 
    1662           0 :                 aCenter.X()=(pA->GetRect().Left()+pA->GetRect().Right())/2;
    1663           0 :                 aCenter.Y()=(pA->GetRect().Top()+pA->GetRect().Bottom())/2;
    1664           0 :                 fdx=(double)(pA->GetStartPoint().X()-aCenter.X());
    1665           0 :                 fdy=(double)(pA->GetStartPoint().Y()-aCenter.Y());
    1666           0 :                 fdx*=(double)pA->GetRect().GetHeight();
    1667           0 :                 fdy*=(double)pA->GetRect().GetWidth();
    1668           0 :                 if (fdx==0.0 && fdy==0.0) fdx=1.0;
    1669           0 :                 fa1=atan2(-fdy,fdx);
    1670           0 :                 fdx=(double)(pA->GetEndPoint().X()-aCenter.X());
    1671           0 :                 fdy=(double)(pA->GetEndPoint().Y()-aCenter.Y());
    1672           0 :                 fdx*=(double)pA->GetRect().GetHeight();
    1673           0 :                 fdy*=(double)pA->GetRect().GetWidth();
    1674           0 :                 if (fdx==0.0 && fdy==0.0) fdx=1.0;
    1675           0 :                 fa2=atan2(-fdy,fdx);
    1676             : 
    1677           0 :                 METSetArcParams(pA->GetRect().GetWidth(), pA->GetRect().GetHeight(),0,0);
    1678             : 
    1679           0 :                 if( aGDIFillColor != Color( COL_TRANSPARENT ) )
    1680             :                 {
    1681           0 :                     METSetMix( eGDIRasterOp );
    1682           0 :                     METSetColor( aGDIFillColor );
    1683           0 :                     METSetBackgroundColor( aGDIFillColor );
    1684           0 :                     METBeginPath(1);
    1685           0 :                     METMove(aCenter);
    1686           0 :                     METPartialArcAtCurPos(aCenter,0.5,fa1,fa2-fa1);
    1687           0 :                     METLineAtCurPos(aCenter);
    1688           0 :                     METEndPath();
    1689           0 :                     METFillPath(1);
    1690             :                 }
    1691             : 
    1692           0 :                 if( aGDILineColor != Color( COL_TRANSPARENT ) )
    1693             :                 {
    1694           0 :                     METSetMix( eGDIRasterOp );
    1695           0 :                     METSetColor( aGDILineColor );
    1696           0 :                     METBeginPath(1);
    1697           0 :                     METMove(aCenter);
    1698           0 :                     METPartialArcAtCurPos(aCenter,0.5,fa1,fa2-fa1);
    1699           0 :                     METLineAtCurPos(aCenter);
    1700           0 :                     METEndPath();
    1701           0 :                     METOutlinePath(1);
    1702             :                 }
    1703             :             }
    1704           0 :             break;
    1705             : 
    1706             :             case META_CHORD_ACTION:
    1707             :             {
    1708           0 :                 const MetaChordAction*  pA = (const MetaChordAction*) pMA;
    1709           0 :                 Point                   aStartPos,aCenter;
    1710             :                 double                  fdx,fdy,fa1,fa2;
    1711             : 
    1712           0 :                 aCenter.X()=(pA->GetRect().Left()+pA->GetRect().Right())/2;
    1713           0 :                 aCenter.Y()=(pA->GetRect().Top()+pA->GetRect().Bottom())/2;
    1714           0 :                 fdx=(double)(pA->GetStartPoint().X()-aCenter.X());
    1715           0 :                 fdy=(double)(pA->GetStartPoint().Y()-aCenter.Y());
    1716           0 :                 fdx*=(double)pA->GetRect().GetHeight();
    1717           0 :                 fdy*=(double)pA->GetRect().GetWidth();
    1718           0 :                 if (fdx==0.0 && fdy==0.0) fdx=1.0;
    1719           0 :                 fa1=atan2(-fdy,fdx);
    1720           0 :                 fdx=(double)(pA->GetEndPoint().X()-aCenter.X());
    1721           0 :                 fdy=(double)(pA->GetEndPoint().Y()-aCenter.Y());
    1722           0 :                 fdx*=(double)pA->GetRect().GetHeight();
    1723           0 :                 fdy*=(double)pA->GetRect().GetWidth();
    1724           0 :                 if (fdx==0.0 && fdy==0.0) fdx=1.0;
    1725           0 :                 fa2=atan2(-fdy,fdx);
    1726           0 :                 aStartPos.X()=aCenter.X()+(long)(((double)pA->GetRect().GetWidth())*cos(fa1)/2.0+0.5);
    1727           0 :                 aStartPos.Y()=aCenter.Y()-(long)(((double)pA->GetRect().GetHeight())*sin(fa1)/2.0+0.5);
    1728             : 
    1729           0 :                 if( aGDIFillColor != Color( COL_TRANSPARENT ) )
    1730             :                 {
    1731           0 :                     METSetMix( eGDIRasterOp );
    1732           0 :                     METSetColor( aGDIFillColor );
    1733           0 :                     METSetBackgroundColor( aGDIFillColor );
    1734           0 :                     METBeginPath(1);
    1735           0 :                     METMove(aStartPos);
    1736           0 :                     METPartialArcAtCurPos(aCenter,0.5,fa1,fa2-fa1);
    1737           0 :                     METLineAtCurPos(aStartPos);
    1738           0 :                     METEndPath();
    1739           0 :                     METFillPath(1);
    1740             :                 }
    1741             : 
    1742           0 :                 if( aGDILineColor != Color( COL_TRANSPARENT ) )
    1743             :                 {
    1744           0 :                     METSetMix( eGDIRasterOp );
    1745           0 :                     METSetColor( aGDILineColor );
    1746           0 :                     METBeginPath(1);
    1747           0 :                     METMove(aStartPos);
    1748           0 :                     METPartialArcAtCurPos(aCenter,0.5,fa1,fa2-fa1);
    1749           0 :                     METLineAtCurPos(aStartPos);
    1750           0 :                     METEndPath();
    1751           0 :                     METOutlinePath(1);
    1752             :                 }
    1753             :             }
    1754           0 :             break;
    1755             : 
    1756             :             case META_POLYLINE_ACTION:
    1757             :             {
    1758           0 :                 const MetaPolyLineAction* pA = (const MetaPolyLineAction*) pMA;
    1759             : 
    1760           0 :                 if( aGDILineColor != Color( COL_TRANSPARENT ) )
    1761             :                 {
    1762           0 :                     LineInfo aLineInfo( pA->GetLineInfo() );
    1763           0 :                     if ( ! ( aLineInfo.IsDefault() ) )
    1764           0 :                         METSetAndPushLineInfo( aLineInfo );
    1765             : 
    1766           0 :                     METSetMix(eGDIRasterOp);
    1767           0 :                     METSetColor(aGDILineColor);
    1768           0 :                     METBeginPath(1);
    1769           0 :                     Polygon aSimplePoly;
    1770           0 :                     const Polygon& rPoly = pA->GetPolygon();
    1771           0 :                     if ( rPoly.HasFlags() )
    1772           0 :                         rPoly.AdaptiveSubdivide( aSimplePoly );
    1773             :                     else
    1774           0 :                         aSimplePoly = rPoly;
    1775           0 :                     METLine( aSimplePoly );
    1776           0 :                     METEndPath();
    1777           0 :                     METOutlinePath(1);
    1778             : 
    1779           0 :                     if ( ! ( aLineInfo.IsDefault() ) )
    1780           0 :                         METPopLineInfo( aLineInfo );
    1781             :                 }
    1782             :             }
    1783           0 :             break;
    1784             : 
    1785             :             case META_POLYGON_ACTION:
    1786             :             {
    1787           0 :                 const MetaPolygonAction* pA = (const MetaPolygonAction*) pMA;
    1788           0 :                 Polygon aSimplePoly;
    1789           0 :                 const Polygon& rPoly = pA->GetPolygon();
    1790           0 :                 if ( rPoly.HasFlags() )
    1791           0 :                     rPoly.AdaptiveSubdivide( aSimplePoly );
    1792             :                 else
    1793           0 :                     aSimplePoly = rPoly;
    1794           0 :                 if( aGDIFillColor != Color( COL_TRANSPARENT ) )
    1795             :                 {
    1796           0 :                     METSetMix(eGDIRasterOp);
    1797           0 :                     METSetColor(aGDIFillColor );
    1798           0 :                     METSetBackgroundColor(aGDIFillColor );
    1799           0 :                     METBeginPath(1);
    1800           0 :                     METLine( aSimplePoly );
    1801           0 :                     METEndPath();
    1802           0 :                     METFillPath(1);
    1803             :                 }
    1804             : 
    1805           0 :                 if( aGDILineColor != Color( COL_TRANSPARENT ) )
    1806             :                 {
    1807           0 :                     METSetMix(eGDIRasterOp);
    1808           0 :                     METSetColor(aGDILineColor );
    1809           0 :                     METBeginPath(1);
    1810           0 :                     METLine( aSimplePoly );
    1811           0 :                     METEndPath();
    1812           0 :                     METOutlinePath(1);
    1813           0 :                 }
    1814             :             }
    1815           0 :             break;
    1816             : 
    1817             :             case META_POLYPOLYGON_ACTION:
    1818             :             {
    1819           0 :                 const MetaPolyPolygonAction* pA = (const MetaPolyPolygonAction*) pMA;
    1820             : 
    1821           0 :                 PolyPolygon aSimplePolyPoly( pA->GetPolyPolygon() );
    1822           0 :                 sal_uInt16 i, nCount = aSimplePolyPoly.Count();
    1823           0 :                 for ( i = 0; i < nCount; i++ )
    1824             :                 {
    1825           0 :                     if ( aSimplePolyPoly[ i ].HasFlags() )
    1826             :                     {
    1827           0 :                         Polygon aSimplePoly;
    1828           0 :                         aSimplePolyPoly[ i ].AdaptiveSubdivide( aSimplePoly );
    1829           0 :                         aSimplePolyPoly[ i ] = aSimplePoly;
    1830             :                     }
    1831             :                 }
    1832           0 :                 if( aGDIFillColor != Color( COL_TRANSPARENT ) )
    1833             :                 {
    1834           0 :                     METSetMix(eGDIRasterOp);
    1835           0 :                     METSetColor(aGDIFillColor);
    1836           0 :                     METSetBackgroundColor(aGDIFillColor);
    1837           0 :                     METBeginPath(1);
    1838           0 :                     METLine( aSimplePolyPoly );
    1839           0 :                     METEndPath();
    1840           0 :                     METFillPath(1);
    1841             :                 }
    1842             : 
    1843           0 :                 if( aGDILineColor != Color( COL_TRANSPARENT ) )
    1844             :                 {
    1845           0 :                     METSetMix(eGDIRasterOp);
    1846           0 :                     METSetColor(aGDILineColor);
    1847           0 :                     METBeginPath(1);
    1848           0 :                     METLine( aSimplePolyPoly );
    1849           0 :                     METEndPath();
    1850           0 :                     METOutlinePath(1);
    1851           0 :                 }
    1852             :             }
    1853           0 :             break;
    1854             : 
    1855             :             case META_TEXT_ACTION:
    1856             :             {
    1857           0 :                 const MetaTextAction*   pA = (const MetaTextAction*) pMA;
    1858           0 :                 Point                   aPt( pA->GetPoint() );
    1859             : 
    1860           0 :                 if( aGDIFont.GetAlign() != ALIGN_BASELINE)
    1861             :                 {
    1862           0 :                     VirtualDevice aVDev;
    1863             : 
    1864           0 :                     if( aGDIFont.GetAlign()==ALIGN_TOP )
    1865           0 :                         aPt.Y()+=(long)aVDev.GetFontMetric( aGDIFont ).GetAscent();
    1866             :                     else
    1867           0 :                         aPt.Y()-=(long)aVDev.GetFontMetric( aGDIFont ).GetDescent();
    1868             :                 }
    1869             : 
    1870           0 :                 METSetMix(eGDIRasterOp);
    1871           0 :                 METSetColor(aGDIFont.GetColor());
    1872           0 :                 METSetBackgroundColor(aGDIFont.GetFillColor());
    1873           0 :                 METSetChrCellSize(aGDIFont.GetSize());
    1874           0 :                 METSetChrAngle(aGDIFont.GetOrientation());
    1875           0 :                 METSetChrSet(FindChrSet(aGDIFont));
    1876           0 :                 METChrStr(aPt, pA->GetText().copy(pA->GetIndex(),pA->GetLen()));
    1877             :             }
    1878           0 :             break;
    1879             : 
    1880             :             case META_TEXTARRAY_ACTION:
    1881             :             {
    1882           0 :                 const MetaTextArrayAction*  pA = (const MetaTextArrayAction*) pMA;
    1883             :                 sal_uInt16                      i;
    1884           0 :                 OUString                    aStr;
    1885           0 :                 Polygon                     aPolyDummy(1);
    1886             :                 short                       nOrientation;
    1887           0 :                 Point                       aPt( pA->GetPoint() );
    1888             : 
    1889           0 :                 if( aGDIFont.GetAlign() != ALIGN_BASELINE )
    1890             :                 {
    1891           0 :                     VirtualDevice aVDev;
    1892           0 :                     if( aGDIFont.GetAlign() == ALIGN_TOP )
    1893           0 :                         aPt.Y()+=(long)aVDev.GetFontMetric(aGDIFont).GetAscent();
    1894             :                     else
    1895           0 :                         aPt.Y()-=(long)aVDev.GetFontMetric(aGDIFont).GetDescent();
    1896             :                 }
    1897             : 
    1898           0 :                 METSetMix(eGDIRasterOp);
    1899           0 :                 METSetColor(aGDIFont.GetColor());
    1900           0 :                 METSetBackgroundColor(aGDIFont.GetFillColor());
    1901           0 :                 METSetChrCellSize(aGDIFont.GetSize());
    1902           0 :                 METSetChrAngle( nOrientation = aGDIFont.GetOrientation() );
    1903           0 :                 METSetChrSet(FindChrSet(aGDIFont));
    1904           0 :                 aStr = pA->GetText().copy(pA->GetIndex(),pA->GetLen());
    1905             : 
    1906           0 :                 if( pA->GetDXArray()!=NULL )
    1907             :                 {
    1908           0 :                     Point aPt2;
    1909             : 
    1910           0 :                     for( i=0; i < aStr.getLength(); i++ )
    1911             :                     {
    1912           0 :                         aPt2 = aPt;
    1913           0 :                         if ( i > 0 )
    1914             :                         {
    1915           0 :                             aPt2.X() += pA->GetDXArray()[i-1];
    1916           0 :                             if ( nOrientation )
    1917             :                             {
    1918           0 :                                 aPolyDummy.SetPoint( aPt2, 0 );
    1919           0 :                                 aPolyDummy.Rotate( aPt, nOrientation );
    1920           0 :                                 aPt2 = aPolyDummy.GetPoint( 0 );
    1921             :                             }
    1922             :                         }
    1923           0 :                         METChrStr( aPt2, OUString( aStr[ i ] ) );
    1924             :                     }
    1925             :                 }
    1926             :                 else
    1927           0 :                     METChrStr( aPt, aStr );
    1928             :             }
    1929           0 :             break;
    1930             : 
    1931             :             case META_STRETCHTEXT_ACTION:
    1932             :             {
    1933           0 :                 const MetaStretchTextAction*    pA = (const MetaStretchTextAction*) pMA;
    1934           0 :                 VirtualDevice                   aVDev;
    1935             :                 sal_uInt16                          i;
    1936             :                 sal_Int32                       nNormSize;
    1937           0 :                 OUString                        aStr;
    1938           0 :                 Polygon                         aPolyDummy(1);
    1939             :                 short                           nOrientation;
    1940           0 :                 Point                           aPt( pA->GetPoint() );
    1941           0 :                 Point                           aPt2;
    1942             : 
    1943           0 :                 aVDev.SetFont( aGDIFont );
    1944             : 
    1945           0 :                 if( aGDIFont.GetAlign() != ALIGN_BASELINE)
    1946             :                 {
    1947           0 :                     if( aGDIFont.GetAlign() == ALIGN_TOP )
    1948           0 :                         aPt.Y()+=(long)aVDev.GetFontMetric().GetAscent();
    1949             :                     else
    1950           0 :                         aPt.Y()-=(long)aVDev.GetFontMetric().GetDescent();
    1951             :                 }
    1952             : 
    1953           0 :                 METSetMix(eGDIRasterOp);
    1954           0 :                 METSetColor(aGDIFont.GetColor());
    1955           0 :                 METSetBackgroundColor(aGDIFont.GetFillColor());
    1956           0 :                 METSetChrCellSize(aGDIFont.GetSize());
    1957           0 :                 METSetChrAngle( nOrientation = aGDIFont.GetOrientation() );
    1958           0 :                 METSetChrSet(FindChrSet(aGDIFont));
    1959           0 :                 aStr = pA->GetText().copy(pA->GetIndex(),pA->GetLen());
    1960           0 :                 boost::scoped_array<sal_Int32> pDXAry(new sal_Int32[aStr.getLength()]);
    1961           0 :                 nNormSize = aVDev.GetTextArray( aStr, pDXAry.get() );
    1962             : 
    1963           0 :                 for ( i = 0; i < aStr.getLength(); i++ )
    1964             :                 {
    1965           0 :                     aPt2 = aPt;
    1966           0 :                     if ( i > 0 )
    1967             :                     {
    1968           0 :                         aPt2.X() += pDXAry[i-1]*((long)pA->GetWidth())/ nNormSize;
    1969           0 :                         if ( nOrientation )
    1970             :                         {
    1971           0 :                             aPolyDummy.SetPoint( aPt2, 0 );
    1972           0 :                             aPolyDummy.Rotate( aPt, nOrientation );
    1973           0 :                             aPt2 = aPolyDummy.GetPoint( 0 );
    1974             :                         }
    1975             :                     }
    1976           0 :                     METChrStr( aPt2, OUString( aStr[ i ] ) );
    1977           0 :                 }
    1978             :             }
    1979           0 :             break;
    1980             : 
    1981             :             case META_TEXTRECT_ACTION:
    1982             :             {
    1983             : //              OSL_FAIL( "Unsupported MET-Action: META_TEXTRECT_ACTION!" );
    1984             :             }
    1985           0 :             break;
    1986             : 
    1987             :             case META_BMP_ACTION:
    1988             :             {
    1989           0 :                 const MetaBmpAction*    pA = (const MetaBmpAction*) pMA;
    1990           0 :                 const Size              aSizePixel( pA->GetBitmap().GetSizePixel() );
    1991             : 
    1992           0 :                 METSetMix(eGDIRasterOp);
    1993           0 :                 METBitBlt( pA->GetPoint(), pCompDev->PixelToLogic( aSizePixel, aPictureMapMode ), aSizePixel );
    1994             :             }
    1995           0 :             break;
    1996             : 
    1997             :             case META_BMPSCALE_ACTION:
    1998             :             {
    1999           0 :                 const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pMA;
    2000             : 
    2001           0 :                 METSetMix(eGDIRasterOp);
    2002           0 :                 METBitBlt( pA->GetPoint(), pA->GetSize(), pA->GetBitmap().GetSizePixel() );
    2003             :             }
    2004           0 :             break;
    2005             : 
    2006             :             case META_BMPSCALEPART_ACTION:
    2007             :             {
    2008           0 :                 const MetaBmpScalePartAction*   pA = (const MetaBmpScalePartAction*) pMA;
    2009           0 :                 Bitmap                          aTmp( pA->GetBitmap() );
    2010             : 
    2011           0 :                 aTmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
    2012           0 :                 METSetMix( eGDIRasterOp );
    2013           0 :                 METBitBlt( pA->GetDestPoint(), pA->GetDestSize(), pA->GetBitmap().GetSizePixel() );
    2014             :             }
    2015           0 :             break;
    2016             : 
    2017             :             case META_BMPEX_ACTION:
    2018             :             {
    2019           0 :                 const MetaBmpExAction*  pA = (const MetaBmpExAction*) pMA;
    2020           0 :                 const Size              aSizePixel( pA->GetBitmapEx().GetSizePixel() );
    2021             : 
    2022           0 :                 METSetMix( eGDIRasterOp );
    2023           0 :                 METBitBlt( pA->GetPoint(), pCompDev->PixelToLogic( aSizePixel, aPictureMapMode ), aSizePixel );
    2024             :             }
    2025           0 :             break;
    2026             : 
    2027             :             case META_BMPEXSCALE_ACTION:
    2028             :             {
    2029           0 :                 const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pMA;
    2030           0 :                 const Size                  aSizePixel( pA->GetBitmapEx().GetSizePixel() );
    2031             : 
    2032           0 :                 METSetMix( eGDIRasterOp );
    2033           0 :                 METBitBlt( pA->GetPoint(), pA->GetSize(), aSizePixel );
    2034             :             }
    2035           0 :             break;
    2036             : 
    2037             :             case META_BMPEXSCALEPART_ACTION:
    2038             :             {
    2039           0 :                 const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*) pMA;
    2040           0 :                 Bitmap                          aTmp( Graphic( pA->GetBitmapEx() ).GetBitmap() );
    2041             : 
    2042           0 :                 aTmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
    2043           0 :                 METSetMix( eGDIRasterOp );
    2044           0 :                 METBitBlt( pA->GetDestPoint(), pA->GetDestSize(), aTmp.GetSizePixel() );
    2045             :             }
    2046           0 :             break;
    2047             : 
    2048             :             case META_EPS_ACTION :
    2049             :             {
    2050           0 :                 const MetaEPSAction* pA = (const MetaEPSAction*)pMA;
    2051           0 :                 const GDIMetaFile aGDIMetaFile( pA->GetSubstitute() );
    2052             : 
    2053           0 :                 size_t nCount = aGDIMetaFile.GetActionSize();
    2054           0 :                 for ( size_t i = 0; i < nCount; i++ )
    2055             :                 {
    2056           0 :                     const MetaAction* pMetaAct = aGDIMetaFile.GetAction( i );
    2057           0 :                     if ( pMetaAct->GetType() == META_BMPSCALE_ACTION )
    2058             :                     {
    2059           0 :                         const MetaBmpScaleAction* pBmpScaleAction = (const MetaBmpScaleAction*)pMetaAct;
    2060           0 :                         METSetMix(eGDIRasterOp);
    2061           0 :                         METBitBlt( pA->GetPoint(), pA->GetSize(), pBmpScaleAction->GetBitmap().GetSizePixel() );
    2062           0 :                         break;
    2063             :                     }
    2064           0 :                 }
    2065             :             }
    2066           0 :             break;
    2067             : 
    2068             :             case META_MASK_ACTION:
    2069           0 :             break;
    2070             : 
    2071             :             case META_MASKSCALE_ACTION:
    2072           0 :             break;
    2073             : 
    2074             :             case META_MASKSCALEPART_ACTION:
    2075           0 :             break;
    2076             : 
    2077             :             case META_GRADIENT_ACTION:
    2078             :             {
    2079           0 :                 VirtualDevice               aVDev;
    2080           0 :                 GDIMetaFile                 aTmpMtf;
    2081           0 :                 const MetaGradientAction*   pA = (const MetaGradientAction*) pMA;
    2082             : 
    2083           0 :                 aVDev.SetMapMode( aTargetMapMode );
    2084           0 :                 aVDev.AddGradientActions( pA->GetRect(), pA->GetGradient(), aTmpMtf );
    2085           0 :                 WriteOrders( &aTmpMtf );
    2086             :             }
    2087           0 :             break;
    2088             : 
    2089             :             case META_HATCH_ACTION:
    2090             :             {
    2091           0 :                 VirtualDevice           aVDev;
    2092           0 :                 GDIMetaFile             aTmpMtf;
    2093           0 :                 const MetaHatchAction*  pA = (const MetaHatchAction*) pMA;
    2094             : 
    2095           0 :                 aVDev.SetMapMode( aTargetMapMode );
    2096           0 :                 aVDev.AddHatchActions( pA->GetPolyPolygon(), pA->GetHatch(), aTmpMtf );
    2097           0 :                 WriteOrders( &aTmpMtf );
    2098             :             }
    2099           0 :             break;
    2100             : 
    2101             :             case META_WALLPAPER_ACTION:
    2102           0 :             break;
    2103             : 
    2104             :             case META_CLIPREGION_ACTION:
    2105           0 :             break;
    2106             : 
    2107             :             case META_ISECTRECTCLIPREGION_ACTION:
    2108             :             {
    2109           0 :                 const MetaISectRectClipRegionAction* pA = (const MetaISectRectClipRegionAction*) pMA;
    2110           0 :                 WriteClipRect( pA->GetRect() );
    2111             :             }
    2112           0 :             break;
    2113             : 
    2114             :             case META_ISECTREGIONCLIPREGION_ACTION:
    2115           0 :             break;
    2116             : 
    2117             :             case META_MOVECLIPREGION_ACTION:
    2118           0 :             break;
    2119             : 
    2120             :             case META_LINECOLOR_ACTION:
    2121             :             {
    2122           0 :                 const MetaLineColorAction* pA = (const MetaLineColorAction*) pMA;
    2123             : 
    2124           0 :                 if( pA->IsSetting() )
    2125           0 :                     aGDILineColor = pA->GetColor();
    2126             :                 else
    2127           0 :                     aGDILineColor = Color( COL_TRANSPARENT );
    2128             :             }
    2129           0 :             break;
    2130             : 
    2131             :             case META_FILLCOLOR_ACTION:
    2132             :             {
    2133           0 :                 const MetaFillColorAction* pA = (const MetaFillColorAction*) pMA;
    2134             : 
    2135           0 :                 if( pA->IsSetting() )
    2136           0 :                     aGDIFillColor = pA->GetColor();
    2137             :                 else
    2138           0 :                     aGDIFillColor = Color( COL_TRANSPARENT );
    2139             :             }
    2140           0 :             break;
    2141             : 
    2142             :             case META_TEXTCOLOR_ACTION:
    2143             :             {
    2144           0 :                 const MetaTextColorAction* pA = (const MetaTextColorAction*) pMA;
    2145           0 :                 aGDIFont.SetColor( pA->GetColor() );
    2146             :             }
    2147           0 :             break;
    2148             : 
    2149             :             case META_TEXTFILLCOLOR_ACTION:
    2150             :             {
    2151           0 :                 const MetaTextFillColorAction* pA = (const MetaTextFillColorAction*) pMA;
    2152             : 
    2153           0 :                 if( pA->IsSetting() )
    2154           0 :                     aGDIFont.SetFillColor( pA->GetColor() );
    2155             :                 else
    2156           0 :                     aGDIFont.SetFillColor( Color( COL_TRANSPARENT ) );
    2157             :             }
    2158           0 :             break;
    2159             : 
    2160             :             case META_TEXTALIGN_ACTION:
    2161           0 :             break;
    2162             : 
    2163             :             case META_MAPMODE_ACTION:
    2164             :             {
    2165           0 :                 const MetaMapModeAction* pA = (const MetaMapModeAction*) pMA;
    2166             : 
    2167           0 :                 if( aPictureMapMode != pA->GetMapMode() )
    2168             :                 {
    2169           0 :                     if ( pA->GetMapMode().GetMapUnit() == MAP_RELATIVE )
    2170             :                     {
    2171           0 :                         MapMode aMM = pA->GetMapMode();
    2172           0 :                         Fraction aScaleX = aMM.GetScaleX();
    2173           0 :                         Fraction aScaleY = aMM.GetScaleY();
    2174             : 
    2175           0 :                         Point aOrigin = aPictureMapMode.GetOrigin();
    2176           0 :                         BigInt aX( aOrigin.X() );
    2177           0 :                         aX *= BigInt( aScaleX.GetDenominator() );
    2178             : 
    2179           0 :                         if( aOrigin.X() >= 0 )
    2180             :                         {
    2181           0 :                             if( aScaleX.GetNumerator() >= 0 )
    2182           0 :                                 aX += BigInt( aScaleX.GetNumerator()/2 );
    2183             :                             else
    2184           0 :                                 aX -= BigInt( (aScaleX.GetNumerator()+1)/2 );
    2185             :                         }
    2186             :                         else
    2187             :                         {
    2188           0 :                             if( aScaleX.GetNumerator() >= 0 )
    2189           0 :                                 aX -= BigInt( (aScaleX.GetNumerator()-1)/2 );
    2190             :                             else
    2191           0 :                                 aX += BigInt( aScaleX.GetNumerator()/2 );
    2192             :                         }
    2193             : 
    2194           0 :                         aX /= BigInt( aScaleX.GetNumerator() );
    2195           0 :                         aOrigin.X() = (long) aX + aMM.GetOrigin().X();
    2196             : 
    2197           0 :                         BigInt aY( aOrigin.Y() );
    2198           0 :                         aY *= BigInt( aScaleY.GetDenominator() );
    2199             : 
    2200           0 :                         if( aOrigin.Y() >= 0 )
    2201             :                         {
    2202           0 :                             if( aScaleY.GetNumerator() >= 0 )
    2203           0 :                                 aY += BigInt( aScaleY.GetNumerator()/2 );
    2204             :                             else
    2205           0 :                                 aY -= BigInt( (aScaleY.GetNumerator()+1)/2 );
    2206             :                         }
    2207             :                         else
    2208             :                         {
    2209           0 :                             if( aScaleY.GetNumerator() >= 0 )
    2210           0 :                                 aY -= BigInt( (aScaleY.GetNumerator()-1)/2 );
    2211             :                             else
    2212           0 :                                 aY += BigInt( aScaleY.GetNumerator()/2 );
    2213             :                         }
    2214             : 
    2215           0 :                         aY /= BigInt( aScaleY.GetNumerator() );
    2216           0 :                         aOrigin.Y() = (long)aY + aMM.GetOrigin().Y();
    2217           0 :                         aPictureMapMode.SetOrigin( aOrigin );
    2218             : 
    2219           0 :                         aScaleX *= aPictureMapMode.GetScaleX();
    2220           0 :                         aScaleY *= aPictureMapMode.GetScaleY();
    2221           0 :                         aPictureMapMode.SetScaleX( aScaleX );
    2222           0 :                         aPictureMapMode.SetScaleY( aScaleY );
    2223             :                     }
    2224             :                     else
    2225           0 :                         aPictureMapMode=pA->GetMapMode();
    2226             :                 }
    2227             :             }
    2228           0 :             break;
    2229             : 
    2230             :             case META_FONT_ACTION:
    2231             :             {
    2232           0 :                 aGDIFont = ( (const MetaFontAction*) pMA )->GetFont();
    2233             :             }
    2234           0 :             break;
    2235             : 
    2236             :             case META_PUSH_ACTION:
    2237             :             {
    2238           0 :                 METGDIStackMember* pGS = new METGDIStackMember;
    2239             : 
    2240           0 :                 pGS->pSucc=pGDIStack; pGDIStack=pGS;
    2241           0 :                 pGS->aLineColor=aGDILineColor;
    2242           0 :                 pGS->aFillColor=aGDIFillColor;
    2243           0 :                 pGS->eRasterOp=eGDIRasterOp;
    2244           0 :                 pGS->aFont=aGDIFont;
    2245           0 :                 pGS->aMapMode=aPictureMapMode;
    2246           0 :                 pGS->aClipRect=aGDIClipRect;
    2247             :             }
    2248           0 :             break;
    2249             : 
    2250             :             case META_POP_ACTION:
    2251             :             {
    2252             :                 METGDIStackMember* pGS;
    2253             : 
    2254           0 :                 if( pGDIStack )
    2255             :                 {
    2256           0 :                     pGS=pGDIStack; pGDIStack=pGS->pSucc;
    2257           0 :                     aGDILineColor=pGS->aLineColor;
    2258           0 :                     aGDIFillColor=pGS->aFillColor;
    2259           0 :                     eGDIRasterOp=pGS->eRasterOp;
    2260           0 :                     aGDIFont=pGS->aFont;
    2261           0 :                     if ( pGS->aClipRect != aGDIClipRect )
    2262           0 :                         WriteClipRect( pGS->aClipRect );
    2263           0 :                     aPictureMapMode=pGS->aMapMode;
    2264           0 :                     delete pGS;
    2265             :                 }
    2266             :             }
    2267           0 :             break;
    2268             : 
    2269             :             case META_RASTEROP_ACTION:
    2270             :             {
    2271           0 :                 eGDIRasterOp = ( (const MetaRasterOpAction*) pMA )->GetRasterOp();
    2272             :             }
    2273           0 :             break;
    2274             : 
    2275             :             case META_TRANSPARENT_ACTION:
    2276             :             {
    2277           0 :                 if( aGDIFillColor != Color( COL_TRANSPARENT ) )
    2278             :                 {
    2279           0 :                     METSetMix(eGDIRasterOp);
    2280           0 :                     METSetColor(aGDIFillColor);
    2281           0 :                     METSetBackgroundColor(aGDIFillColor);
    2282           0 :                     METBeginPath(1);
    2283           0 :                     METLine(( (const MetaTransparentAction*) pMA )->GetPolyPolygon());
    2284           0 :                     METEndPath();
    2285           0 :                     METFillPath(1);
    2286             :                 }
    2287             : 
    2288           0 :                 if( aGDILineColor != Color( COL_TRANSPARENT ) )
    2289             :                 {
    2290           0 :                     METSetMix(eGDIRasterOp);
    2291           0 :                     METSetColor(aGDILineColor);
    2292           0 :                     METBeginPath(1);
    2293           0 :                     METLine(( (const MetaTransparentAction*) pMA )->GetPolyPolygon());
    2294           0 :                     METEndPath();
    2295           0 :                     METOutlinePath(1);
    2296             :                 }
    2297             :             }
    2298           0 :             break;
    2299             : 
    2300             :             case META_FLOATTRANSPARENT_ACTION:
    2301             :             {
    2302           0 :                 const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pMA;
    2303             : 
    2304           0 :                 GDIMetaFile     aTmpMtf( pA->GetGDIMetaFile() );
    2305           0 :                 Point           aSrcPt( aTmpMtf.GetPrefMapMode().GetOrigin() );
    2306           0 :                 const Size      aSrcSize( aTmpMtf.GetPrefSize() );
    2307           0 :                 const Point     aDestPt( pA->GetPoint() );
    2308           0 :                 const Size      aDestSize( pA->GetSize() );
    2309           0 :                 const double    fScaleX = aSrcSize.Width() ? (double) aDestSize.Width() / aSrcSize.Width() : 1.0;
    2310           0 :                 const double    fScaleY = aSrcSize.Height() ? (double) aDestSize.Height() / aSrcSize.Height() : 1.0;
    2311             :                 long            nMoveX, nMoveY;
    2312             : 
    2313           0 :                 if( fScaleX != 1.0 || fScaleY != 1.0 )
    2314             :                 {
    2315           0 :                     aTmpMtf.Scale( fScaleX, fScaleY );
    2316           0 :                     aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
    2317             :                 }
    2318             : 
    2319           0 :                 nMoveX = aDestPt.X() - aSrcPt.X(), nMoveY = aDestPt.Y() - aSrcPt.Y();
    2320             : 
    2321           0 :                 if( nMoveX || nMoveY )
    2322           0 :                     aTmpMtf.Move( nMoveX, nMoveY );
    2323             : 
    2324           0 :                 WriteOrders( &aTmpMtf );
    2325             :             }
    2326           0 :             break;
    2327             :       }
    2328             : 
    2329           0 :       nWrittenActions++;
    2330           0 :       MayCallback();
    2331             : 
    2332           0 :       if( pMET->GetError() )
    2333           0 :         bStatus=sal_False;
    2334             : 
    2335           0 :       if( bStatus == sal_False )
    2336           0 :         break;
    2337             :     }
    2338             : }
    2339             : 
    2340           0 : void METWriter::WriteObjectEnvironmentGroup(const GDIMetaFile * pMTF)
    2341             : {
    2342             :     sal_uLong i, nId;
    2343             : 
    2344             :     //--- The Field 'Begin Object Environment Group':
    2345           0 :     WriteFieldIntroducer(16,BegObjEnvMagic,0,0);
    2346           0 :     WriteFieldId(7);
    2347             : 
    2348             :     //--- The Field 'Map Color Attribute Table':
    2349           0 :     WriteFieldIntroducer(22,MapColAtrMagic,0,0);
    2350           0 :     WriteBigEndianShort(0x000e);
    2351           0 :     pMET->WriteUChar( (sal_uInt8)0x0c ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x84 ).WriteUChar( (sal_uInt8)0x00 );
    2352           0 :     WriteFieldId(4);
    2353             : 
    2354             :     //--- The first Field 'Map Coded Font':
    2355           0 :     WriteFieldIntroducer(32,MapCodFntMagic,0,0);
    2356           0 :     WriteBigEndianShort(0x0018);
    2357           0 :     pMET->WriteUChar( (sal_uInt8)0x0c ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x84 ).WriteUChar( (sal_uInt8)0x00 );
    2358           0 :     pMET->WriteUChar( (sal_uInt8)0xff ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
    2359           0 :     pMET->WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
    2360           0 :     pMET->WriteUChar( (sal_uInt8)0x04 ).WriteUChar( (sal_uInt8)0x24 ).WriteUChar( (sal_uInt8)0x05 ).WriteUChar( (sal_uInt8)0x00 );
    2361           0 :     pMET->WriteUChar( (sal_uInt8)0x06 ).WriteUChar( (sal_uInt8)0x20 );
    2362           0 :     pMET->WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0x97 ).WriteUChar( (sal_uInt8)0x01 ).WriteUChar( (sal_uInt8)0xb5 );
    2363             : 
    2364             :     //--- The additional Fields 'Map Coded Font':
    2365           0 :     CreateChrSets(pMTF);
    2366           0 :     WriteChrSets();
    2367             : 
    2368             :     //--- The Fields 'Map Data Resource':
    2369           0 :     nId=nActBitmapId;
    2370           0 :     for (i=0; i<nNumberOfBitmaps; i++)
    2371             :     {
    2372           0 :         WriteFieldIntroducer(29,MapDatResMagic,0,0);
    2373           0 :         WriteBigEndianShort(0x0015);
    2374           0 :         pMET->WriteUChar( (sal_uInt8)0x0c ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x84 ).WriteUChar( (sal_uInt8)0x00 );
    2375           0 :         WriteFieldId(nId);
    2376           0 :         pMET->WriteUChar( (sal_uInt8)0x07 ).WriteUChar( (sal_uInt8)0x22 ).WriteUChar( (sal_uInt8)0x10 );
    2377           0 :         pMET->WriteUInt32( (sal_uInt32)nId );
    2378           0 :         nId++;
    2379             :     }
    2380             : 
    2381             :     //--- Das Feld 'End Object Environment Group':
    2382           0 :     WriteFieldIntroducer(16,EndObjEnvMagic,0,0);
    2383           0 :     WriteFieldId(7);
    2384           0 : }
    2385             : 
    2386             : 
    2387           0 : void METWriter::WriteGraphicsObject(const GDIMetaFile * pMTF)
    2388             : {
    2389             :     sal_uLong nSegmentSize,nPos,nDataFieldsStartPos;
    2390             : 
    2391           0 :     if( bStatus==sal_False )
    2392           0 :         return;
    2393             : 
    2394             :     //--- Das Feld 'Begin Graphics Object':
    2395           0 :     WriteFieldIntroducer(16,BegGrfObjMagic,0,0);
    2396           0 :     WriteFieldId(7);
    2397             : 
    2398             :     // Map Color Attribute Table, Fonts and other stuff:
    2399           0 :     WriteObjectEnvironmentGroup(pMTF);
    2400             : 
    2401             :     //--- The Field 'Graphics Data Descriptor':
    2402           0 :     WriteDataDescriptor(pMTF);
    2403             : 
    2404             :     // initialise the counter for Data Fields:
    2405           0 :     nNumberOfDataFields=0;
    2406             : 
    2407             :     // and remember the position of the first Data Field:
    2408           0 :     nDataFieldsStartPos=pMET->Tell();
    2409             : 
    2410             :     //--- start of the first Field 'Graphics Data'
    2411           0 :     WriteFieldIntroducer(0,DatGrfObjMagic,0,0);
    2412           0 :     nNumberOfDataFields++;
    2413             : 
    2414             :     // now at first we write the head of the segment:
    2415           0 :     pMET->WriteUChar( (sal_uInt8)0x70 ).WriteUChar( (sal_uInt8)0x0e ).WriteUInt32( (sal_uInt32)0 );
    2416           0 :     pMET->WriteUChar( (sal_uInt8)0x70 ).WriteUChar( (sal_uInt8)0x10 ); // Flags
    2417           0 :     pMET->WriteUInt16( (sal_uInt16)0 ); // Lo-Word of the length of the segment data  (Big Endian)
    2418           0 :     pMET->WriteUInt32( (sal_uInt32)0 );  // Reserved
    2419           0 :     pMET->WriteUInt16( (sal_uInt16)0 ); // Hi-Word of the length of the segment (Big Endian) (Ohh Ohh OS2)
    2420             :     // Annotation: we're writing the correct data length again below
    2421             : 
    2422             :     // now all orders are being written out:
    2423             :     // (wobei die Sache ggf. in mehrere 'Graphics Data Fields' aufgeteilt
    2424             :     // wird, per Methode WillWriteOrder(..))
    2425           0 :     WriteOrders(pMTF);
    2426             : 
    2427             :     //--- terminate the last Field 'Graphic Data':
    2428           0 :     UpdateFieldSize();
    2429             : 
    2430             :     //--- and finally correct the segment size:
    2431           0 :     nPos=pMET->Tell();
    2432           0 :     nSegmentSize=nPos-nDataFieldsStartPos;
    2433           0 :     nSegmentSize-=nNumberOfDataFields*8; // Structured Field Introducers are not counted
    2434           0 :     pMET->Seek(nDataFieldsStartPos+16); // seek to the Lo-Word of the segment size
    2435           0 :     WriteBigEndianShort((sal_uInt16)(nSegmentSize&0x0000ffff)); // Und schreiben
    2436           0 :     pMET->Seek(nDataFieldsStartPos+22); // seek to the Hi-Word of the segment size
    2437           0 :     WriteBigEndianShort((sal_uInt16)(nSegmentSize>>16)); // and writing it
    2438           0 :     pMET->Seek(nPos); // back to business as usual
    2439             : 
    2440             :     //--- The Field 'End Graphic Objects':
    2441           0 :     WriteFieldIntroducer(16,EndGrfObjMagic,0,0);
    2442           0 :     WriteFieldId(7);
    2443             : 
    2444           0 :     if( pMET->GetError() )
    2445           0 :         bStatus=sal_False;
    2446             : }
    2447             : 
    2448             : 
    2449           0 : void METWriter::WriteResourceGroup(const GDIMetaFile * pMTF)
    2450             : {
    2451           0 :     if( bStatus==sal_False )
    2452           0 :         return;
    2453             : 
    2454             :     //--- The Field 'Begin Resource Group':
    2455           0 :     WriteFieldIntroducer(16,BegResGrpMagic,0,0);
    2456           0 :     WriteFieldId(2);
    2457             : 
    2458             :     //--- The Content:
    2459           0 :     WriteColorAttributeTable();
    2460           0 :     nActBitmapId=0x77777700;
    2461           0 :     WriteImageObjects(pMTF);
    2462           0 :     nActBitmapId=0x77777700;
    2463           0 :     WriteGraphicsObject(pMTF);
    2464             : 
    2465             :     //--- The Field 'End Resource Group':
    2466           0 :     WriteFieldIntroducer(16,EndResGrpMagic,0,0);
    2467           0 :     WriteFieldId(2);
    2468             : 
    2469           0 :     if( pMET->GetError() )
    2470           0 :         bStatus=sal_False;
    2471             : }
    2472             : 
    2473             : 
    2474           0 : void METWriter::WriteDocument(const GDIMetaFile * pMTF)
    2475             : {
    2476           0 :     if( bStatus==sal_False )
    2477           0 :         return;
    2478             : 
    2479             :     //--- The Field 'Begin Document':
    2480           0 :     WriteFieldIntroducer(0,BegDocumnMagic,0,0);
    2481           0 :     WriteFieldId(1);
    2482           0 :     pMET->WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
    2483           0 :     pMET->WriteUChar( (sal_uInt8)0x05 ).WriteUChar( (sal_uInt8)0x18 ).WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0x0c ).WriteUChar( (sal_uInt8)0x00 );
    2484           0 :     pMET->WriteUChar( (sal_uInt8)0x06 ).WriteUChar( (sal_uInt8)0x01 ).WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0xd4 ).WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0x52 );
    2485           0 :     pMET->WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0x65 ).WriteUChar( (sal_uInt8)0x00 );
    2486           0 :     UpdateFieldSize();
    2487             : 
    2488             :     //--- The Content:
    2489           0 :     WriteResourceGroup(pMTF);
    2490             : 
    2491             :     //--- The Field 'End Document':
    2492           0 :     WriteFieldIntroducer(16,EndDocumnMagic,0,0);
    2493           0 :     WriteFieldId(1);
    2494             : 
    2495           0 :     if( pMET->GetError() )
    2496           0 :         bStatus=sal_False;
    2497             : }
    2498             : 
    2499           0 : sal_Bool METWriter::WriteMET( const GDIMetaFile& rMTF, SvStream& rTargetStream, FilterConfigItem* pFilterConfigItem )
    2500             : {
    2501           0 :     if ( pFilterConfigItem )
    2502             :     {
    2503           0 :         xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
    2504           0 :         if ( xStatusIndicator.is() )
    2505             :         {
    2506           0 :             OUString aMsg;
    2507           0 :             xStatusIndicator->start( aMsg, 100 );
    2508             :         }
    2509             :     }
    2510             : 
    2511             :     METChrSet*          pCS;
    2512             :     METGDIStackMember*  pGS;
    2513             : 
    2514           0 :     bStatus=sal_True;
    2515           0 :     nLastPercent=0;
    2516             : 
    2517           0 :     pMET=&rTargetStream;
    2518           0 :     pMET->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
    2519             : 
    2520           0 :     aPictureRect = Rectangle( Point(), rMTF.GetPrefSize() );
    2521           0 :     aTargetMapMode = aPictureMapMode = rMTF.GetPrefMapMode();
    2522             : 
    2523           0 :     aGDILineColor=Color( COL_BLACK );
    2524           0 :     aGDIFillColor=Color( COL_WHITE );
    2525           0 :     eGDIRasterOp=ROP_OVERPAINT;
    2526           0 :     aGDIFont=Font();
    2527           0 :     aGDIMapMode=MapMode();
    2528           0 :     aGDIClipRect=Rectangle();
    2529           0 :     pGDIStack=NULL;
    2530           0 :     aMETColor=Color(COL_BLACK);
    2531           0 :     aMETBackgroundColor=Color(COL_WHITE);
    2532           0 :     eMETMix=ROP_OVERPAINT;
    2533           0 :     nMETStrokeLineWidth=1;
    2534           0 :     aMETChrCellSize=Size(0,0);
    2535           0 :     nMETChrAngle=0;
    2536           0 :     nMETChrSet=0x00;
    2537           0 :     pChrSetList=NULL;
    2538           0 :     nNextChrSetId=1;
    2539           0 :     nNumberOfActions=0;
    2540           0 :     nNumberOfBitmaps=0;
    2541           0 :     nWrittenActions=0;
    2542           0 :     nWrittenBitmaps=0;
    2543           0 :     nActBitmapPercent=0;
    2544             : 
    2545           0 :     CountActionsAndBitmaps(&rMTF);
    2546             : 
    2547           0 :     WriteDocument(&rMTF);
    2548             : 
    2549           0 :     while( pChrSetList )
    2550             :     {
    2551           0 :         pCS=pChrSetList;
    2552           0 :         pChrSetList=pCS->pSucc;
    2553           0 :         delete pCS;
    2554             :     }
    2555             : 
    2556           0 :     while( pGDIStack )
    2557             :     {
    2558           0 :         pGS=pGDIStack;
    2559           0 :         pGDIStack=pGS->pSucc;
    2560           0 :         delete pGS;
    2561             :     }
    2562             : 
    2563           0 :     if ( xStatusIndicator.is() )
    2564           0 :         xStatusIndicator->end();
    2565             : 
    2566           0 :     return bStatus;
    2567             : }
    2568             : 
    2569             : //================== GraphicExport - the exported Function ================
    2570             : 
    2571             : // this needs to be kept in sync with
    2572             : // ImpFilterLibCacheEntry::GetImportFunction() from
    2573             : // vcl/source/filter/graphicfilter.cxx
    2574             : #if defined(DISABLE_DYNLOADING)
    2575             : #define GraphicExport emeGraphicExport
    2576             : #endif
    2577             : 
    2578             : extern "C" SAL_DLLPUBLIC_EXPORT bool SAL_CALL
    2579           0 : GraphicExport( SvStream & rStream, Graphic & rGraphic, FilterConfigItem* pFilterConfigItem )
    2580             : {
    2581           0 :     METWriter aMETWriter;
    2582             : 
    2583             :     // #119735# just use GetGDIMetaFile, it will create a buffered version of contained bitmap now automatically
    2584           0 :     GDIMetaFile aMetafile(rGraphic.GetGDIMetaFile());
    2585             : 
    2586           0 :     if(usesClipActions(aMetafile))
    2587             :     {
    2588             :         // #i121267# It is necessary to prepare the metafile since the export does *not* support
    2589             :         // clip regions. This tooling method clips the geometry content of the metafile internally
    2590             :         // against it's own clip regions, so that the export is safe to ignore clip regions
    2591           0 :         clipMetafileContentAgainstOwnRegions(aMetafile);
    2592             :     }
    2593             : 
    2594           0 :     return aMETWriter.WriteMET( aMetafile, rStream, pFilterConfigItem );
    2595             : }
    2596             : 
    2597             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10