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

Generated by: LCOV version 1.11