LCOV - code coverage report
Current view: top level - cppcanvas/source/mtfrenderer - emfplus.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 659 0.0 %
Date: 2012-08-25 Functions: 0 39 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 1368 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2010 Novell, Inc.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include <tools/stream.hxx>
      30                 :            : #include <vcl/metaact.hxx>
      31                 :            : #include <svtools/filter.hxx>
      32                 :            : #include <basegfx/tools/canvastools.hxx>
      33                 :            : #include <basegfx/tools/gradienttools.hxx>
      34                 :            : #include <basegfx/tools/tools.hxx>
      35                 :            : #include <basegfx/numeric/ftools.hxx>
      36                 :            : #include <basegfx/point/b2dpoint.hxx>
      37                 :            : #include <basegfx/vector/b2dsize.hxx>
      38                 :            : #include <basegfx/range/b2drange.hxx>
      39                 :            : #include <basegfx/range/b2drectangle.hxx>
      40                 :            : #include <basegfx/polygon/b2dpolygon.hxx>
      41                 :            : #include <basegfx/polygon/b2dpolypolygon.hxx>
      42                 :            : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      43                 :            : #include <vcl/canvastools.hxx>
      44                 :            : #include <rtl/ustring.hxx>
      45                 :            : #include <sal/alloca.h>
      46                 :            : 
      47                 :            : #include <com/sun/star/rendering/XCanvas.hpp>
      48                 :            : #include <com/sun/star/rendering/TexturingMode.hpp>
      49                 :            : 
      50                 :            : #include <bitmapaction.hxx>
      51                 :            : #include <implrenderer.hxx>
      52                 :            : #include <outdevstate.hxx>
      53                 :            : #include <polypolyaction.hxx>
      54                 :            : #include <textaction.hxx>
      55                 :            : #include <stdio.h>
      56                 :            : 
      57                 :            : #define EmfPlusRecordTypeHeader 16385
      58                 :            : #define EmfPlusRecordTypeEndOfFile 16386
      59                 :            : #define EmfPlusRecordTypeGetDC 16388
      60                 :            : #define EmfPlusRecordTypeObject 16392
      61                 :            : #define EmfPlusRecordTypeFillRects 16394
      62                 :            : #define EmfPlusRecordTypeFillPolygon 16396
      63                 :            : #define EmfPlusRecordTypeDrawLines 16397
      64                 :            : #define EmfPlusRecordTypeFillPath 16404
      65                 :            : #define EmfPlusRecordTypeDrawPath 16405
      66                 :            : #define EmfPlusRecordTypeDrawImage 16410
      67                 :            : #define EmfPlusRecordTypeDrawImagePoints 16411
      68                 :            : #define EmfPlusRecordTypeDrawString 16412
      69                 :            : #define EmfPlusRecordTypeSetRenderingOrigin 16413
      70                 :            : #define EmfPlusRecordTypeSetAntiAliasMode 16414
      71                 :            : #define EmfPlusRecordTypeSetTextRenderingHint 16415
      72                 :            : #define EmfPlusRecordTypeSetInterpolationMode 16417
      73                 :            : #define EmfPlusRecordTypeSetPixelOffsetMode 16418
      74                 :            : #define EmfPlusRecordTypeSetCompositingQuality 16420
      75                 :            : #define EmfPlusRecordTypeSave 16421
      76                 :            : #define EmfPlusRecordTypeSetWorldTransform 16426
      77                 :            : #define EmfPlusRecordTypeResetWorldTransform 16427
      78                 :            : #define EmfPlusRecordTypeMultiplyWorldTransform 16428
      79                 :            : #define EmfPlusRecordTypeSetPageTransform 16432
      80                 :            : #define EmfPlusRecordTypeSetClipPath 16435
      81                 :            : #define EmfPlusRecordTypeSetClipRegion 16436
      82                 :            : #define EmfPlusRecordTypeDrawDriverString 16438
      83                 :            : 
      84                 :            : #define EmfPlusObjectTypeBrush 0x100
      85                 :            : #define EmfPlusObjectTypePen 0x200
      86                 :            : #define EmfPlusObjectTypePath 0x300
      87                 :            : #define EmfPlusObjectTypeRegion 0x400
      88                 :            : #define EmfPlusObjectTypeImage 0x500
      89                 :            : #define EmfPlusObjectTypeFont 0x600
      90                 :            : #define EmfPlusObjectTypeStringFormat 0x700
      91                 :            : #define EmfPlusObjectTypeImageAttributes 0x800
      92                 :            : 
      93                 :            : #define EmfPlusRegionInitialStateRectangle 0x10000000
      94                 :            : #define EmfPlusRegionInitialStatePath 0x10000001
      95                 :            : #define EmfPlusRegionInitialStateEmpty 0x10000002
      96                 :            : #define EmfPlusRegionInitialStateInfinite 0x10000003
      97                 :            : 
      98                 :            : #if OSL_DEBUG_LEVEL > 1
      99                 :            : #define EMFP_DEBUG(x) x
     100                 :            : #else
     101                 :            : #define EMFP_DEBUG(x)
     102                 :            : #endif
     103                 :            : 
     104                 :            : using namespace ::com::sun::star;
     105                 :            : 
     106                 :            : namespace cppcanvas
     107                 :            : {
     108                 :            :     namespace internal
     109                 :            :     {
     110                 :            : 
     111                 :            :         EMFP_DEBUG (void dumpWords (SvStream& s, int i)
     112                 :            :         {
     113                 :            :             sal_uInt32 pos = s.Tell ();
     114                 :            :             sal_Int16 data;
     115                 :            :             for (; i > 0; i --) {
     116                 :            :                 s >> data;
     117                 :            :                 printf ("EMF+\tdata: %04hX\n", data);
     118                 :            :             }
     119                 :            :             s.Seek (pos);
     120                 :            :         });
     121                 :            : 
     122                 :          0 :         struct EMFPObject
     123                 :            :         {
     124         [ #  # ]:          0 :             virtual ~EMFPObject() {}
     125                 :            :         };
     126                 :            : 
     127                 :            :         struct EMFPPath : public EMFPObject
     128                 :            :         {
     129                 :            :             ::basegfx::B2DPolyPolygon    aPolygon;
     130                 :            :             sal_Int32                    nPoints;
     131                 :            :             float*                       pPoints;
     132                 :            :             sal_uInt8*                   pPointTypes;
     133                 :            : 
     134                 :            :         public:
     135                 :          0 :             EMFPPath (sal_Int32 _nPoints, bool bLines = false)
     136         [ #  # ]:          0 :             {
     137 [ #  # ][ #  # ]:          0 :                 if( _nPoints<0 || sal_uInt32(_nPoints)>SAL_MAX_INT32/(2*sizeof(float)) )
     138                 :          0 :                     _nPoints = SAL_MAX_INT32/(2*sizeof(float));
     139                 :          0 :                 nPoints = _nPoints;
     140         [ #  # ]:          0 :                 pPoints = new float [nPoints*2];
     141         [ #  # ]:          0 :                 if (!bLines)
     142         [ #  # ]:          0 :                     pPointTypes = new sal_uInt8 [_nPoints];
     143                 :            :                 else
     144                 :          0 :                     pPointTypes = NULL;
     145                 :          0 :             }
     146                 :            : 
     147                 :          0 :             ~EMFPPath ()
     148         [ #  # ]:          0 :             {
     149         [ #  # ]:          0 :                 delete [] pPoints;
     150         [ #  # ]:          0 :                 delete [] pPointTypes;
     151         [ #  # ]:          0 :             }
     152                 :            : 
     153                 :            :             // TODO: remove rR argument when debug code is not longer needed
     154                 :          0 :             void Read (SvStream& s, sal_uInt32 pathFlags, ImplRenderer& rR)
     155                 :            :             {
     156         [ #  # ]:          0 :                 for (int i = 0; i < nPoints; i ++) {
     157         [ #  # ]:          0 :                     if (pathFlags & 0x4000) {
     158                 :            :                         // points are stored in short 16bit integer format
     159                 :            :                         sal_uInt16 x, y;
     160                 :            : 
     161 [ #  # ][ #  # ]:          0 :                         s >> x >> y;
     162                 :            :                         EMFP_DEBUG (printf ("EMF+\tpoint [x,y]: %hd,%hd\n", x, y));
     163                 :          0 :                         pPoints [i*2] = x;
     164                 :          0 :                         pPoints [i*2 + 1] = y;
     165                 :            :                     } else {
     166                 :            :                         // points are stored in Single (float) format
     167                 :          0 :                         s >> pPoints [i*2] >> pPoints [i*2 + 1];
     168                 :            :                         EMFP_DEBUG (printf ("EMF+\tpoint [x,y]: %f,%f\n", pPoints [i*2], pPoints [i*2 + 1]));
     169                 :            :                     }
     170                 :            :                 }
     171                 :            : 
     172         [ #  # ]:          0 :                 if (pPointTypes)
     173         [ #  # ]:          0 :                     for (int i = 0; i < nPoints; i ++) {
     174                 :          0 :                         s >> pPointTypes [i];
     175                 :            :                         EMFP_DEBUG (printf ("EMF+\tpoint type: %x\n", pPointTypes [i]));
     176                 :            :                     }
     177                 :            : 
     178                 :          0 :                 aPolygon.clear ();
     179                 :            : 
     180                 :            :                 (void) rR; // avoid warnings
     181                 :            :                 EMFP_DEBUG (
     182                 :            :                     const ::basegfx::B2DRectangle aBounds (::basegfx::tools::getRange (GetPolygon (rR)));
     183                 :            :                     printf ("EMF+\tpolygon bounding box: %f,%f %fx%f (mapped)\n", aBounds.getMinX (), aBounds.getMinY (), aBounds.getWidth (), aBounds.getHeight ()));
     184                 :          0 :             }
     185                 :            : 
     186                 :          0 :             ::basegfx::B2DPolyPolygon& GetPolygon (ImplRenderer& rR, bool bMapIt = true)
     187                 :            :             {
     188         [ #  # ]:          0 :                 ::basegfx::B2DPolygon polygon;
     189                 :            : 
     190         [ #  # ]:          0 :                 aPolygon.clear ();
     191                 :            : 
     192                 :          0 :                 int last_normal = 0, p = 0;
     193                 :          0 :                 ::basegfx::B2DPoint prev, mapped;
     194                 :          0 :                 bool hasPrev = false;
     195         [ #  # ]:          0 :                 for (int i = 0; i < nPoints; i ++) {
     196 [ #  # ][ #  # ]:          0 :                     if (p && pPointTypes && (pPointTypes [i] == 0)) {
                 [ #  # ]
     197         [ #  # ]:          0 :                         aPolygon.append (polygon);
     198                 :          0 :                         last_normal = i;
     199                 :          0 :                         p = 0;
     200         [ #  # ]:          0 :                         polygon.clear ();
     201                 :            :                     }
     202                 :            : 
     203         [ #  # ]:          0 :                     if (bMapIt)
     204                 :          0 :                         mapped = rR.Map (pPoints [i*2], pPoints [i*2 + 1]);
     205                 :            :                     else
     206                 :          0 :                         mapped = ::basegfx::B2DPoint (pPoints [i*2], pPoints [i*2 + 1]);
     207                 :            :                     //EMFP_DEBUG (printf ("polygon point: %f,%f mapped: %f,%f\n", pPoints [i*2], pPoints [i*2 + 1], mapped.getX (), mapped.getY ()));
     208         [ #  # ]:          0 :                     if (pPointTypes) {
     209         [ #  # ]:          0 :                         if ((pPointTypes [i] & 0x07) == 3) {
     210         [ #  # ]:          0 :                             if (((i - last_normal )% 3) == 1) {
     211         [ #  # ]:          0 :                                 polygon.setNextControlPoint (p - 1, mapped);
     212                 :            :                                 EMFP_DEBUG (printf ("polygon append  next: %d mapped: %f,%f\n", p - 1, mapped.getX (), mapped.getY ()));
     213                 :          0 :                                 continue;
     214         [ #  # ]:          0 :                             } else if (((i - last_normal) % 3) == 2) {
     215                 :          0 :                                 prev = mapped;
     216                 :          0 :                                 hasPrev = true;
     217                 :          0 :                                 continue;
     218                 :            :                             }
     219                 :            :                         } else
     220                 :          0 :                             last_normal = i;
     221                 :            :                     }
     222         [ #  # ]:          0 :                     polygon.append (mapped);
     223                 :            :                     EMFP_DEBUG (printf ("polygon append point: %f,%f mapped: %f,%f\n", pPoints [i*2], pPoints [i*2 + 1], mapped.getX (), mapped.getY ()));
     224         [ #  # ]:          0 :                     if (hasPrev) {
     225         [ #  # ]:          0 :                         polygon.setPrevControlPoint (p, prev);
     226                 :            :                         EMFP_DEBUG (printf ("polygon append  prev: %d mapped: %f,%f\n", p, prev.getX (), prev.getY ()));
     227                 :          0 :                         hasPrev = false;
     228                 :            :                     }
     229                 :          0 :                     p ++;
     230 [ #  # ][ #  # ]:          0 :                     if (pPointTypes && (pPointTypes [i] & 0x80)) { // closed polygon
     231         [ #  # ]:          0 :                         polygon.setClosed (true);
     232         [ #  # ]:          0 :                         aPolygon.append (polygon);
     233                 :            :                         EMFP_DEBUG (printf ("close polygon\n"));
     234                 :          0 :                         last_normal = i + 1;
     235                 :          0 :                         p = 0;
     236         [ #  # ]:          0 :                         polygon.clear ();
     237                 :            :                     }
     238                 :            :                 }
     239                 :            : 
     240 [ #  # ][ #  # ]:          0 :                 if (polygon.count ())
     241         [ #  # ]:          0 :                     aPolygon.append (polygon);
     242                 :            : 
     243                 :            :                 EMFP_DEBUG (
     244                 :            :                     for (unsigned int i=0; i<aPolygon.count(); i++) {
     245                 :            :                         polygon = aPolygon.getB2DPolygon(i);
     246                 :            :                         printf ("polygon: %d\n", i);
     247                 :            :                         for (unsigned int j=0; j<polygon.count(); j++) {
     248                 :            :                             ::basegfx::B2DPoint point = polygon.getB2DPoint(j);
     249                 :            :                             printf ("point: %f,%f\n", point.getX(), point.getY());
     250                 :            :                             if (polygon.isPrevControlPointUsed(j)) {
     251                 :            :                                 point = polygon.getPrevControlPoint(j);
     252                 :            :                                 printf ("prev: %f,%f\n", point.getX(), point.getY());
     253                 :            :                             }
     254                 :            :                             if (polygon.isNextControlPointUsed(j)) {
     255                 :            :                                 point = polygon.getNextControlPoint(j);
     256                 :            :                                 printf ("next: %f,%f\n", point.getX(), point.getY());
     257                 :            :                             }
     258                 :            :                         }
     259                 :            :                     }
     260                 :            :                 );
     261                 :            : 
     262         [ #  # ]:          0 :                 return aPolygon;
     263                 :            :             }
     264                 :            :         };
     265                 :            : 
     266                 :            :         struct EMFPRegion : public EMFPObject
     267                 :            :         {
     268                 :            :             sal_Int32 parts;
     269                 :            :             sal_Int32 *combineMode;
     270                 :            :             sal_Int32 initialState;
     271                 :            :             EMFPPath *initialPath;
     272                 :            :             float ix, iy, iw, ih;
     273                 :            : 
     274                 :          0 :             EMFPRegion ()
     275                 :          0 :             {
     276                 :          0 :                 combineMode = NULL;
     277                 :          0 :                 initialPath = NULL;
     278                 :          0 :             }
     279                 :            : 
     280                 :          0 :             ~EMFPRegion ()
     281                 :          0 :             {
     282         [ #  # ]:          0 :                 if (combineMode) {
     283         [ #  # ]:          0 :                     delete [] combineMode;
     284                 :          0 :                     combineMode = NULL;
     285                 :            :                 }
     286         [ #  # ]:          0 :                 if (initialPath) {
     287 [ #  # ][ #  # ]:          0 :                     delete initialPath;
     288                 :          0 :                     initialPath = NULL;
     289                 :            :                 }
     290         [ #  # ]:          0 :             }
     291                 :            : 
     292                 :          0 :             void Read (SvStream& s)
     293                 :            :             {
     294                 :            :                 sal_uInt32 header;
     295                 :            : 
     296 [ #  # ][ #  # ]:          0 :                 s >> header >> parts;
     297                 :            : 
     298                 :            :                 EMFP_DEBUG (printf ("EMF+\tregion\n"));
     299                 :            :                 EMFP_DEBUG (printf ("EMF+\theader: 0x%08x parts: %d\n", (unsigned int)header, (int)parts));
     300                 :            : 
     301         [ #  # ]:          0 :                 if (parts) {
     302 [ #  # ][ #  # ]:          0 :                     if( parts<0 || sal_uInt32(parts)>SAL_MAX_INT32/sizeof(sal_Int32) )
     303                 :          0 :                         parts = SAL_MAX_INT32/sizeof(sal_Int32);
     304                 :            : 
     305         [ #  # ]:          0 :                     combineMode = new sal_Int32 [parts];
     306                 :            : 
     307         [ #  # ]:          0 :                     for (int i = 0; i < parts; i ++) {
     308         [ #  # ]:          0 :                         s >> combineMode [i];
     309                 :            :                         EMFP_DEBUG (printf ("EMF+\tcombine mode [%d]: 0x%08x\n", i,(unsigned int)combineMode [i]));
     310                 :            :                     }
     311                 :            :                 }
     312                 :            : 
     313         [ #  # ]:          0 :                 s >> initialState;
     314                 :            :                 EMFP_DEBUG (printf ("EMF+\tinitial state: 0x%d\n",(int) initialState));
     315                 :          0 :             }
     316                 :            :         };
     317                 :            : 
     318                 :            :         struct EMFPBrush : public EMFPObject
     319                 :            :         {
     320                 :            :             ::Color solidColor;
     321                 :            :             sal_uInt32 type;
     322                 :            :             sal_uInt32 additionalFlags;
     323                 :            : 
     324                 :            :             /* linear gradient */
     325                 :            :             sal_Int32 wrapMode;
     326                 :            :             float areaX, areaY, areaWidth, areaHeight;
     327                 :            :             ::Color secondColor; // first color is stored in solidColor;
     328                 :            :             XForm transformation;
     329                 :            :             bool hasTransformation;
     330                 :            :             sal_Int32 blendPoints;
     331                 :            :             float* blendPositions;
     332                 :            :             float* blendFactors;
     333                 :            :             sal_Int32 colorblendPoints;
     334                 :            :             float* colorblendPositions;
     335                 :            :             ::Color* colorblendColors;
     336                 :            :             sal_Int32 surroundColorsNumber;
     337                 :            :             ::Color* surroundColors;
     338                 :            :             EMFPPath *path;
     339                 :            : 
     340                 :            :         public:
     341                 :          0 :             EMFPBrush ()
     342         [ #  # ]:          0 :             {
     343                 :          0 :                 blendPositions = NULL;
     344                 :          0 :                 colorblendPositions = NULL;
     345                 :          0 :                 colorblendColors = NULL;
     346                 :          0 :                 surroundColors = NULL;
     347                 :          0 :                 path = NULL;
     348                 :          0 :                 hasTransformation = false;
     349                 :          0 :             }
     350                 :            : 
     351                 :          0 :             ~EMFPBrush ()
     352                 :          0 :             {
     353         [ #  # ]:          0 :                 if (blendPositions != NULL) {
     354         [ #  # ]:          0 :                     delete[] blendPositions;
     355                 :          0 :                     blendPositions = NULL;
     356                 :            :                 }
     357         [ #  # ]:          0 :                 if (colorblendPositions != NULL) {
     358         [ #  # ]:          0 :                     delete[] colorblendPositions;
     359                 :          0 :                     colorblendPositions = NULL;
     360                 :            :                 }
     361         [ #  # ]:          0 :                 if (colorblendColors != NULL) {
     362         [ #  # ]:          0 :                     delete[] colorblendColors;
     363                 :          0 :                     colorblendColors = NULL;
     364                 :            :                 }
     365         [ #  # ]:          0 :                 if (surroundColors != NULL) {
     366         [ #  # ]:          0 :                     delete[] surroundColors;
     367                 :          0 :                     surroundColors = NULL;
     368                 :            :                 }
     369         [ #  # ]:          0 :                 if (path) {
     370 [ #  # ][ #  # ]:          0 :                     delete path;
     371                 :          0 :                     path = NULL;
     372                 :            :                 }
     373         [ #  # ]:          0 :             }
     374                 :            : 
     375                 :            :             sal_uInt32 GetType() const { return type; }
     376                 :          0 :             const ::Color& GetColor() const { return solidColor; }
     377                 :            : 
     378                 :          0 :             void Read (SvStream& s, ImplRenderer& rR)
     379                 :            :             {
     380                 :            :                 sal_uInt32 header;
     381                 :            : 
     382 [ #  # ][ #  # ]:          0 :                 s >> header >> type;
     383                 :            : 
     384                 :            :                 EMFP_DEBUG (printf ("EMF+\tbrush\nEMF+\theader: 0x%08x type: %d\n",(unsigned int) header,(int) type));
     385                 :            : 
     386   [ #  #  #  # ]:          0 :                 switch (type) {
     387                 :            :                 case 0:
     388                 :            :                     {
     389                 :            :                         sal_uInt32 color;
     390                 :            : 
     391         [ #  # ]:          0 :                         s >> color;
     392                 :          0 :                         solidColor = ::Color (0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
     393                 :            :                         EMFP_DEBUG (printf ("EMF+\tsolid color: 0x%08x\n", (unsigned int)color));
     394                 :            : 
     395                 :            :                         break;
     396                 :            :                     }
     397                 :            :                 // path gradient
     398                 :            :                 case 3:
     399                 :            :                     {
     400 [ #  # ][ #  # ]:          0 :                         s >> additionalFlags >> wrapMode;
     401                 :            : 
     402                 :            :                         EMFP_DEBUG (printf ("EMF+\tpath gradient, additional flags: 0x%02x\n",(unsigned int) additionalFlags));
     403                 :            : 
     404                 :            :                         sal_uInt32 color;
     405                 :            : 
     406         [ #  # ]:          0 :                         s >> color;
     407                 :          0 :                         solidColor = ::Color (0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
     408                 :            :                         EMFP_DEBUG (printf ("EMF+\tcenter color: 0x%08x\n",(unsigned int) color));
     409                 :            : 
     410 [ #  # ][ #  # ]:          0 :                         s >> areaX >> areaY;
     411                 :            :                         EMFP_DEBUG (printf ("EMF+\tcenter point: %f,%f\n", areaX, areaY));
     412                 :            : 
     413         [ #  # ]:          0 :                         s >> surroundColorsNumber;
     414                 :            :                         EMFP_DEBUG (printf ("EMF+\tsurround colors: %d\n",(int) surroundColorsNumber));
     415                 :            : 
     416 [ #  # ][ #  # ]:          0 :                         if( surroundColorsNumber<0 || sal_uInt32(surroundColorsNumber)>SAL_MAX_INT32/sizeof(::Color) )
     417                 :          0 :                             surroundColorsNumber = SAL_MAX_INT32/sizeof(::Color);
     418                 :            : 
     419 [ #  # ][ #  # ]:          0 :                         surroundColors = new ::Color [surroundColorsNumber];
     420         [ #  # ]:          0 :                         for (int i = 0; i < surroundColorsNumber; i++) {
     421         [ #  # ]:          0 :                             s >> color;
     422                 :          0 :                             surroundColors[i] = ::Color (0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
     423         [ #  # ]:          0 :                             if (i == 0)
     424                 :          0 :                                 secondColor = surroundColors [0];
     425                 :            :                             EMFP_DEBUG (printf ("EMF+\tsurround color[%d]: 0x%08x\n", i, (unsigned int)color));
     426                 :            :                         }
     427                 :            : 
     428         [ #  # ]:          0 :                         if (additionalFlags & 0x01) {
     429                 :            :                             sal_Int32 pathLength;
     430                 :            : 
     431         [ #  # ]:          0 :                             s >> pathLength;
     432                 :            :                             EMFP_DEBUG (printf ("EMF+\tpath length: %d\n", (int)pathLength));
     433                 :            : 
     434                 :          0 :                             sal_uInt32 pos = s.Tell ();
     435                 :            :                             EMFP_DEBUG (dumpWords (s, 32));
     436                 :            : 
     437                 :            :                             sal_uInt32 pathHeader;
     438                 :            :                             sal_Int32 pathPoints, pathFlags;
     439 [ #  # ][ #  # ]:          0 :                             s >> pathHeader >> pathPoints >> pathFlags;
                 [ #  # ]
     440                 :            : 
     441                 :            :                             EMFP_DEBUG (printf ("EMF+\tpath (brush path gradient)\n"));
     442                 :            :                             EMFP_DEBUG (printf ("EMF+\theader: 0x%08x points: %d additional flags: 0x%d\n", (unsigned int)pathHeader, (int)pathPoints, (int)pathFlags));
     443                 :            : 
     444 [ #  # ][ #  # ]:          0 :                             path = new EMFPPath (pathPoints);
     445         [ #  # ]:          0 :                             path->Read (s, pathFlags, rR);
     446                 :            : 
     447         [ #  # ]:          0 :                             s.Seek (pos + pathLength);
     448                 :            : 
     449 [ #  # ][ #  # ]:          0 :                             const ::basegfx::B2DRectangle aBounds (::basegfx::tools::getRange (path->GetPolygon (rR, false)));
     450         [ #  # ]:          0 :                             areaWidth = aBounds.getWidth ();
     451         [ #  # ]:          0 :                             areaHeight = aBounds.getHeight ();
     452                 :            : 
     453                 :            :                             EMFP_DEBUG (printf ("EMF+\tpolygon bounding box: %f,%f %fx%f\n", aBounds.getMinX (), aBounds.getMinY (), aBounds.getWidth (), aBounds.getHeight ()));
     454                 :            : 
     455                 :            : 
     456         [ #  # ]:          0 :                         if (additionalFlags & 0x02) {
     457                 :            :                             EMFP_DEBUG (printf ("EMF+\tuse transformation\n"));
     458         [ #  # ]:          0 :                             s >> transformation;
     459                 :          0 :                             hasTransformation = true;
     460                 :            :                             EMFP_DEBUG (printf ("EMF+\tm11: %f m12: %f\nEMF+\tm21: %f m22: %f\nEMF+\tdx: %f dy: %f\n",
     461                 :            :                                     transformation.eM11, transformation.eM12,
     462                 :            :                                     transformation.eM21, transformation.eM22,
     463                 :            :                                     transformation.eDx, transformation.eDy));
     464                 :            :                         }
     465         [ #  # ]:          0 :                         if (additionalFlags & 0x08) {
     466         [ #  # ]:          0 :                             s >> blendPoints;
     467                 :            :                             EMFP_DEBUG (printf ("EMF+\tuse blend, points: %d\n", (int)blendPoints));
     468 [ #  # ][ #  # ]:          0 :                             if( blendPoints<0 || sal_uInt32(blendPoints)>SAL_MAX_INT32/(2*sizeof(float)) )
     469                 :          0 :                                 blendPoints = SAL_MAX_INT32/(2*sizeof(float));
     470         [ #  # ]:          0 :                             blendPositions = new float [2*blendPoints];
     471                 :          0 :                             blendFactors = blendPositions + blendPoints;
     472         [ #  # ]:          0 :                             for (int i=0; i < blendPoints; i ++) {
     473         [ #  # ]:          0 :                                 s >> blendPositions [i];
     474                 :            :                                 EMFP_DEBUG (printf ("EMF+\tposition[%d]: %f\n", i, blendPositions [i]));
     475                 :            :                             }
     476         [ #  # ]:          0 :                             for (int i=0; i < blendPoints; i ++) {
     477         [ #  # ]:          0 :                                 s >> blendFactors [i];
     478                 :            :                                 EMFP_DEBUG (printf ("EMF+\tfactor[%d]: %f\n", i, blendFactors [i]));
     479                 :            :                             }
     480                 :            :                         }
     481                 :            : 
     482         [ #  # ]:          0 :                         if (additionalFlags & 0x04) {
     483         [ #  # ]:          0 :                             s >> colorblendPoints;
     484                 :            :                             EMFP_DEBUG (printf ("EMF+\tuse color blend, points: %d\n", (int)colorblendPoints));
     485 [ #  # ][ #  # ]:          0 :                             if( colorblendPoints<0 || sal_uInt32(colorblendPoints)>SAL_MAX_INT32/sizeof(float) )
     486                 :          0 :                                 colorblendPoints = SAL_MAX_INT32/sizeof(float);
     487         [ #  # ]:          0 :                             if( sal_uInt32(colorblendPoints)>SAL_MAX_INT32/sizeof(::Color) )
     488                 :          0 :                                 colorblendPoints = SAL_MAX_INT32/sizeof(::Color);
     489         [ #  # ]:          0 :                             colorblendPositions = new float [colorblendPoints];
     490 [ #  # ][ #  # ]:          0 :                             colorblendColors = new ::Color [colorblendPoints];
     491         [ #  # ]:          0 :                             for (int i=0; i < colorblendPoints; i ++) {
     492         [ #  # ]:          0 :                                 s >> colorblendPositions [i];
     493                 :            :                                 EMFP_DEBUG (printf ("EMF+\tposition[%d]: %f\n", i, colorblendPositions [i]));
     494                 :            :                             }
     495         [ #  # ]:          0 :                             for (int i=0; i < colorblendPoints; i ++) {
     496         [ #  # ]:          0 :                                 s >> color;
     497                 :          0 :                                 colorblendColors [i] = ::Color (0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
     498                 :            :                                 EMFP_DEBUG (printf ("EMF+\tcolor[%d]: 0x%08x\n", i,(unsigned int) color));
     499                 :            :                             }
     500                 :            :                         }
     501                 :            :                         } else {
     502                 :            :                             EMFP_DEBUG (dumpWords (s, 1024));
     503                 :            :             }
     504                 :            :                         break;
     505                 :            :                     }
     506                 :            :                 // linear gradient
     507                 :            :                 case 4:
     508                 :            :                     {
     509 [ #  # ][ #  # ]:          0 :                         s >> additionalFlags >> wrapMode;
     510                 :            : 
     511                 :            :                         EMFP_DEBUG (printf ("EMF+\tlinear gradient, additional flags: 0x%02x\n", (unsigned int)additionalFlags));
     512                 :            : 
     513 [ #  # ][ #  # ]:          0 :                         s >> areaX >> areaY >> areaWidth >> areaHeight;
         [ #  # ][ #  # ]
     514                 :            : 
     515                 :            :                         EMFP_DEBUG (printf ("EMF+\tarea: %f,%f - %fx%f\n", areaX, areaY, areaWidth, areaHeight));
     516                 :            : 
     517                 :            :                         sal_uInt32 color;
     518                 :            : 
     519         [ #  # ]:          0 :                         s >> color;
     520                 :          0 :                         solidColor = ::Color (0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
     521                 :            :                         EMFP_DEBUG (printf ("EMF+\tfirst color: 0x%08x\n", color));
     522                 :            : 
     523         [ #  # ]:          0 :                         s >> color;
     524                 :          0 :                         secondColor = ::Color (0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
     525                 :            :                         EMFP_DEBUG (printf ("EMF+\tsecond color: 0x%08x\n", color));
     526                 :            : 
     527                 :            :                         // repeated colors, unknown meaning, see http://www.aces.uiuc.edu/~jhtodd/Metafile/MetafileRecords/ObjectBrush.html
     528         [ #  # ]:          0 :                         s >> color;
     529         [ #  # ]:          0 :                         s >> color;
     530                 :            : 
     531         [ #  # ]:          0 :                         if (additionalFlags & 0x02) {
     532                 :            :                             EMFP_DEBUG (printf ("EMF+\tuse transformation\n"));
     533         [ #  # ]:          0 :                             s >> transformation;
     534                 :          0 :                             hasTransformation = true;
     535                 :            :                             EMFP_DEBUG (printf ("EMF+\tm11: %f m12: %f\nEMF+\tm21: %f m22: %f\nEMF+\tdx: %f dy: %f\n",
     536                 :            :                                     transformation.eM11, transformation.eM12,
     537                 :            :                                     transformation.eM21, transformation.eM22,
     538                 :            :                                     transformation.eDx, transformation.eDy));
     539                 :            :                         }
     540         [ #  # ]:          0 :                         if (additionalFlags & 0x08) {
     541         [ #  # ]:          0 :                             s >> blendPoints;
     542                 :            :                             EMFP_DEBUG (printf ("EMF+\tuse blend, points: %d\n", (int)blendPoints));
     543 [ #  # ][ #  # ]:          0 :                             if( blendPoints<0 || sal_uInt32(blendPoints)>SAL_MAX_INT32/(2*sizeof(float)) )
     544                 :          0 :                                 blendPoints = SAL_MAX_INT32/(2*sizeof(float));
     545         [ #  # ]:          0 :                             blendPositions = new float [2*blendPoints];
     546                 :          0 :                             blendFactors = blendPositions + blendPoints;
     547         [ #  # ]:          0 :                             for (int i=0; i < blendPoints; i ++) {
     548         [ #  # ]:          0 :                                 s >> blendPositions [i];
     549                 :            :                                 EMFP_DEBUG (printf ("EMF+\tposition[%d]: %f\n", i, blendPositions [i]));
     550                 :            :                             }
     551         [ #  # ]:          0 :                             for (int i=0; i < blendPoints; i ++) {
     552         [ #  # ]:          0 :                                 s >> blendFactors [i];
     553                 :            :                                 EMFP_DEBUG (printf ("EMF+\tfactor[%d]: %f\n", i, blendFactors [i]));
     554                 :            :                             }
     555                 :            :                         }
     556                 :            : 
     557         [ #  # ]:          0 :                         if (additionalFlags & 0x04) {
     558         [ #  # ]:          0 :                             s >> colorblendPoints;
     559                 :            :                             EMFP_DEBUG (printf ("EMF+\tuse color blend, points: %d\n", (int)colorblendPoints));
     560 [ #  # ][ #  # ]:          0 :                             if( colorblendPoints<0 || sal_uInt32(colorblendPoints)>SAL_MAX_INT32/sizeof(float) )
     561                 :          0 :                                 colorblendPoints = SAL_MAX_INT32/sizeof(float);
     562         [ #  # ]:          0 :                             if( sal_uInt32(colorblendPoints)>SAL_MAX_INT32/sizeof(::Color) )
     563                 :          0 :                                 colorblendPoints = sal_uInt32(SAL_MAX_INT32)/sizeof(::Color);
     564         [ #  # ]:          0 :                             colorblendPositions = new float [colorblendPoints];
     565 [ #  # ][ #  # ]:          0 :                             colorblendColors = new ::Color [colorblendPoints];
     566         [ #  # ]:          0 :                             for (int i=0; i < colorblendPoints; i ++) {
     567         [ #  # ]:          0 :                                 s >> colorblendPositions [i];
     568                 :            :                                 EMFP_DEBUG (printf ("EMF+\tposition[%d]: %f\n", i, colorblendPositions [i]));
     569                 :            :                             }
     570         [ #  # ]:          0 :                             for (int i=0; i < colorblendPoints; i ++) {
     571         [ #  # ]:          0 :                                 s >> color;
     572                 :          0 :                                 colorblendColors [i] = ::Color (0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
     573                 :            :                                 EMFP_DEBUG (printf ("EMF+\tcolor[%d]: 0x%08x\n", i, (unsigned int)color));
     574                 :            :                             }
     575                 :            :                         }
     576                 :            : 
     577                 :            :                         break;
     578                 :            :                     }
     579                 :            :                 default:
     580                 :            :                     EMFP_DEBUG (printf ("EMF+\tunhandled brush type: %08x\n", (unsigned int)type));
     581                 :            :                 }
     582                 :          0 :             }
     583                 :            :         };
     584                 :            : 
     585         [ #  # ]:          0 :         struct EMFPPen : public EMFPBrush
     586                 :            :         {
     587                 :            :             XForm transformation;
     588                 :            :             float width;
     589                 :            :             sal_Int32 startCap;
     590                 :            :             sal_Int32 endCap;
     591                 :            :             sal_Int32 lineJoin;
     592                 :            :             float mitterLimit;
     593                 :            :             sal_Int32 dashStyle;
     594                 :            :             sal_Int32 dashCap;
     595                 :            :             float dashOffset;
     596                 :            :             sal_Int32 dashPatternLen;
     597                 :            :             float *dashPattern;
     598                 :            :             sal_Int32 alignment;
     599                 :            :             sal_Int32 compoundArrayLen;
     600                 :            :             float *compoundArray;
     601                 :            :             sal_Int32 customStartCapLen;
     602                 :            :             sal_uInt8 *customStartCap;
     603                 :            :             sal_Int32 customEndCapLen;
     604                 :            :             sal_uInt8 *customEndCap;
     605                 :            : 
     606                 :            :         public:
     607         [ #  # ]:          0 :             EMFPPen () : EMFPBrush ()
     608                 :            :             {
     609                 :          0 :             }
     610                 :            : 
     611                 :          0 :             void SetStrokeAttributes (rendering::StrokeAttributes& rStrokeAttributes, ImplRenderer& rR, const OutDevState& rState)
     612                 :            :             {
     613                 :            :                 EMFP_DEBUG (if (width == 0.0) printf ("EMF+\tTODO: pen with zero width - using minimal which might not be correct\n"));
     614 [ #  # ][ #  # ]:          0 :                 rStrokeAttributes.StrokeWidth = (rState.mapModeTransform * rR.MapSize (width == 0.0 ? 0.05 : width, 0)).getX ();
     615                 :          0 :             }
     616                 :            : 
     617                 :          0 :             void Read (SvStream& s, ImplRenderer& rR, sal_Int32, sal_Int32 )
     618                 :            :             {
     619                 :            :                 sal_uInt32 header, unknown, penFlags, unknown2;
     620                 :            :                 int i;
     621                 :            : 
     622 [ #  # ][ #  # ]:          0 :                 s >> header >> unknown >> penFlags >> unknown2 >> width;
         [ #  # ][ #  # ]
                 [ #  # ]
     623                 :            : 
     624                 :            :                 EMFP_DEBUG (printf ("EMF+\tpen\nEMF+\theader: 0x%08x unknown: 0x%08x additional flags: 0x%08x unknown: 0x%08x width: %f\n", (unsigned int)header, (unsigned int)unknown, (unsigned int)penFlags,(unsigned int) unknown2, width));
     625                 :            : 
     626         [ #  # ]:          0 :                 if (penFlags & 1)
     627         [ #  # ]:          0 :                     s >> transformation;
     628                 :            : 
     629         [ #  # ]:          0 :                 if (penFlags & 2)
     630         [ #  # ]:          0 :                     s >> startCap;
     631                 :            :                 else
     632                 :          0 :                     startCap = 0;
     633                 :            : 
     634         [ #  # ]:          0 :                 if (penFlags & 4)
     635         [ #  # ]:          0 :                     s >> endCap;
     636                 :            :                 else
     637                 :          0 :                     endCap = 0;
     638                 :            : 
     639         [ #  # ]:          0 :                 if (penFlags & 8)
     640         [ #  # ]:          0 :                     s >> lineJoin;
     641                 :            :                 else
     642                 :          0 :                     lineJoin = 0;
     643                 :            : 
     644         [ #  # ]:          0 :                 if (penFlags & 16)
     645         [ #  # ]:          0 :                     s >> mitterLimit;
     646                 :            :                 else
     647                 :          0 :                     mitterLimit = 0;
     648                 :            : 
     649         [ #  # ]:          0 :                 if (penFlags & 32)
     650         [ #  # ]:          0 :                     s >> dashStyle;
     651                 :            :                 else
     652                 :          0 :                     dashStyle = 0;
     653                 :            : 
     654         [ #  # ]:          0 :                 if (penFlags & 64)
     655         [ #  # ]:          0 :                     s >> dashCap;
     656                 :            :                 else
     657                 :          0 :                     dashCap = 0;
     658                 :            : 
     659         [ #  # ]:          0 :                 if (penFlags & 128)
     660         [ #  # ]:          0 :                     s >> dashOffset;
     661                 :            :                 else
     662                 :          0 :                     dashOffset = 0;
     663                 :            : 
     664         [ #  # ]:          0 :                 if (penFlags & 256) {
     665         [ #  # ]:          0 :                     s >> dashPatternLen;
     666 [ #  # ][ #  # ]:          0 :                     if( dashPatternLen<0 || sal_uInt32(dashPatternLen)>SAL_MAX_INT32/sizeof(float) )
     667                 :          0 :                         dashPatternLen = SAL_MAX_INT32/sizeof(float);
     668         [ #  # ]:          0 :                     dashPattern = new float [dashPatternLen];
     669         [ #  # ]:          0 :                     for (i = 0; i < dashPatternLen; i++)
     670         [ #  # ]:          0 :                         s >> dashPattern [i];
     671                 :            :                 } else
     672                 :          0 :                     dashPatternLen = 0;
     673                 :            : 
     674         [ #  # ]:          0 :                 if (penFlags & 512)
     675         [ #  # ]:          0 :                     s >> alignment;
     676                 :            :                 else
     677                 :          0 :                     alignment = 0;
     678                 :            : 
     679         [ #  # ]:          0 :                 if (penFlags & 1024) {
     680         [ #  # ]:          0 :                     s >> compoundArrayLen;
     681 [ #  # ][ #  # ]:          0 :                     if( compoundArrayLen<0 || sal_uInt32(compoundArrayLen)>SAL_MAX_INT32/sizeof(float) )
     682                 :          0 :                         compoundArrayLen = SAL_MAX_INT32/sizeof(float);
     683         [ #  # ]:          0 :                     compoundArray = new float [compoundArrayLen];
     684         [ #  # ]:          0 :                     for (i = 0; i < compoundArrayLen; i++)
     685         [ #  # ]:          0 :                         s >> compoundArray [i];
     686                 :            :                 } else
     687                 :          0 :                     compoundArrayLen = 0;
     688                 :            : 
     689         [ #  # ]:          0 :                 if (penFlags & 2048) {
     690         [ #  # ]:          0 :                     s >> customStartCapLen;
     691         [ #  # ]:          0 :                     if( customStartCapLen<0 )
     692                 :          0 :                         customStartCapLen=0;
     693         [ #  # ]:          0 :                     customStartCap = new sal_uInt8 [customStartCapLen];
     694         [ #  # ]:          0 :                     for (i = 0; i < customStartCapLen; i++)
     695         [ #  # ]:          0 :                         s >> customStartCap [i];
     696                 :            :                 } else
     697                 :          0 :                     customStartCapLen = 0;
     698                 :            : 
     699         [ #  # ]:          0 :                 if (penFlags & 4096) {
     700         [ #  # ]:          0 :                     s >> customEndCapLen;
     701         [ #  # ]:          0 :                     if( customEndCapLen<0 )
     702                 :          0 :                         customEndCapLen=0;
     703         [ #  # ]:          0 :                     customEndCap = new sal_uInt8 [customEndCapLen];
     704         [ #  # ]:          0 :                     for (i = 0; i < customEndCapLen; i++)
     705         [ #  # ]:          0 :                         s >> customEndCap [i];
     706                 :            :                 } else
     707                 :          0 :                     customEndCapLen = 0;
     708                 :            : 
     709         [ #  # ]:          0 :                 EMFPBrush::Read (s, rR);
     710                 :          0 :             }
     711                 :            :         };
     712                 :            : 
     713 [ #  # ][ #  # ]:          0 :         struct EMFPImage : public EMFPObject
                 [ #  # ]
     714                 :            :         {
     715                 :            :             sal_uInt32 type;
     716                 :            :             sal_Int32 width;
     717                 :            :             sal_Int32 height;
     718                 :            :             sal_Int32 stride;
     719                 :            :             sal_Int32 pixelFormat;
     720                 :            :             Graphic graphic;
     721                 :            : 
     722                 :            : 
     723                 :          0 :             void Read (SvMemoryStream &s, sal_Bool bUseWholeStream)
     724                 :            :             {
     725                 :            :                 sal_uInt32 header, unknown;
     726                 :            : 
     727 [ #  # ][ #  # ]:          0 :                 s >> header >> type;
     728                 :            : 
     729                 :            :                 EMFP_DEBUG (printf ("EMF+\timage\nEMF+\theader: 0x%08x type: 0x%08x\n", header, type));
     730                 :            : 
     731         [ #  # ]:          0 :                 if (type == 1) { // bitmap
     732 [ #  # ][ #  # ]:          0 :                     s >> width >> height >> stride >> pixelFormat >> unknown;
         [ #  # ][ #  # ]
                 [ #  # ]
     733                 :            :                     EMFP_DEBUG (printf ("EMF+\tbitmap width: %d height: %d stride: %d pixelFormat: 0x%08x\n", width, height, stride, pixelFormat));
     734         [ #  # ]:          0 :                     if (width == 0) { // non native formats
     735         [ #  # ]:          0 :                         GraphicFilter filter;
     736                 :            : 
     737 [ #  # ][ #  # ]:          0 :                         filter.ImportGraphic (graphic, String (), s);
                 [ #  # ]
     738         [ #  # ]:          0 :                         EMFP_DEBUG (printf ("EMF+\tbitmap width: %ld height: %ld\n", graphic.GetBitmap ().GetSizePixel ().Width (), graphic.GetBitmap ().GetSizePixel ().Height ()));
     739                 :            :                     }
     740                 :            : 
     741         [ #  # ]:          0 :                 } else if (type == 2) {
     742                 :            :                     sal_Int32 mfType, mfSize;
     743                 :            : 
     744 [ #  # ][ #  # ]:          0 :                     s >> mfType >> mfSize;
     745                 :            :                     EMFP_DEBUG (printf ("EMF+\tmetafile type: %d dataSize: %d\n", mfType, mfSize));
     746                 :            : 
     747         [ #  # ]:          0 :                     GraphicFilter filter;
     748                 :            :                     // workaround buggy metafiles, which have wrong mfSize set (n#705956 for example)
     749 [ #  # ][ #  # ]:          0 :                     SvMemoryStream mfStream (((char *)s.GetData()) + s.Tell(), bUseWholeStream ? s.remainingSize() : mfSize, STREAM_READ);
         [ #  # ][ #  # ]
     750                 :            : 
     751 [ #  # ][ #  # ]:          0 :                     filter.ImportGraphic (graphic, String (), mfStream);
                 [ #  # ]
     752                 :            : 
     753                 :            :                     // debug code - write the stream to debug file /tmp/emf-stream.emf
     754                 :            :                     EMFP_DEBUG(
     755                 :            :                         mfStream.Seek(0);
     756                 :            :                         static int emfp_debug_stream_numnber = 0;
     757                 :            :                         rtl::OUString emfp_debug_filename("/tmp/emf-embedded-stream");
     758                 :            :                         emfp_debug_filename += rtl::OUString::valueOf(emfp_debug_stream_numnber++);
     759                 :            :                         emfp_debug_filename += rtl::OUString(".emf");
     760                 :            : 
     761                 :            :                         SvFileStream file( emfp_debug_filename, STREAM_WRITE | STREAM_TRUNC );
     762                 :            : 
     763                 :            :                         mfStream >> file;
     764                 :            :                         file.Flush();
     765                 :            :                         file.Close()
     766 [ #  # ][ #  # ]:          0 :                     );
     767                 :            :                 }
     768                 :          0 :             }
     769                 :            :         };
     770                 :            : 
     771         [ #  # ]:          0 :         struct EMFPFont : public EMFPObject
     772                 :            :         {
     773                 :            :             sal_uInt32 version;
     774                 :            :             float emSize;
     775                 :            :             sal_uInt32 sizeUnit;
     776                 :            :             sal_Int32 fontFlags;
     777                 :            :             rtl::OUString family;
     778                 :            : 
     779                 :          0 :             void Read (SvMemoryStream &s)
     780                 :            :             {
     781                 :            :                 sal_uInt32 header;
     782                 :            :                 sal_uInt32 reserved;
     783                 :            :                 sal_uInt32 length;
     784                 :            : 
     785 [ #  # ][ #  # ]:          0 :                 s >> header >> emSize >> sizeUnit >> fontFlags >> reserved >> length;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     786                 :            : 
     787                 :            :                 OSL_ASSERT( ( header >> 12 ) == 0xdbc01 );
     788                 :            : 
     789                 :            :                 EMFP_DEBUG (printf ("EMF+\tfont\nEMF+\theader: 0x%08x version: 0x%08x size: %f unit: 0x%08x\n",(unsigned int) header >> 12, (unsigned int)header & 0x1fff, emSize, (unsigned int)sizeUnit));
     790                 :            :                 EMFP_DEBUG (printf ("EMF+\tflags: 0x%08x reserved: 0x%08x length: 0x%08x\n", (unsigned int)fontFlags, (unsigned int)reserved, (unsigned int)length));
     791                 :            : 
     792 [ #  # ][ #  # ]:          0 :                 if( length > 0 && length < 0x4000 ) {
     793                 :          0 :                     sal_Unicode *chars = (sal_Unicode *) alloca( sizeof( sal_Unicode ) * length );
     794                 :            : 
     795         [ #  # ]:          0 :                     for( sal_uInt32 i = 0; i < length; i++ )
     796         [ #  # ]:          0 :                     s >> chars[ i ];
     797                 :            : 
     798                 :          0 :                     family = ::rtl::OUString( chars, length );
     799                 :            :                     EMFP_DEBUG (printf ("EMF+\tfamily: %s\n", rtl::OUStringToOString( family, RTL_TEXTENCODING_UTF8).getStr()));
     800                 :            :                 }
     801                 :          0 :             }
     802                 :            :         };
     803                 :            : 
     804                 :          0 :         void ImplRenderer::ReadRectangle (SvStream& s, float& x, float& y, float &width, float& height, bool bCompressed)
     805                 :            :         {
     806         [ #  # ]:          0 :             if (bCompressed) {
     807                 :            :                 sal_Int16 ix, iy, iw, ih;
     808                 :            : 
     809 [ #  # ][ #  # ]:          0 :                 s >> ix >> iy >> iw >> ih;
         [ #  # ][ #  # ]
     810                 :            : 
     811                 :          0 :                 x = ix;
     812                 :          0 :                 y = iy;
     813                 :          0 :                 width = iw;
     814                 :          0 :                 height = ih;
     815                 :            :             } else
     816                 :          0 :                 s >> x >> y >> width >> height;
     817                 :          0 :         }
     818                 :            : 
     819                 :          0 :         void ImplRenderer::ReadPoint (SvStream& s, float& x, float& y, sal_uInt32 flags)
     820                 :            :         {
     821         [ #  # ]:          0 :             if (flags & 0x4000) {
     822                 :            :                 sal_Int16 ix, iy;
     823                 :            : 
     824 [ #  # ][ #  # ]:          0 :                 s >> ix >> iy;
     825                 :            : 
     826                 :          0 :                 x = ix;
     827                 :          0 :                 y = iy;
     828                 :            :             } else
     829                 :          0 :                 s >> x >> y;
     830                 :          0 :         }
     831                 :            : 
     832                 :          0 :         void ImplRenderer::MapToDevice (double& x, double& y)
     833                 :            :         {
     834                 :            :             // TODO: other untis
     835                 :          0 :             x = 100*nMmX*x/nPixX;
     836                 :          0 :             y = 100*nMmY*y/nPixY;
     837                 :          0 :         }
     838                 :            : 
     839                 :          0 :         ::basegfx::B2DPoint ImplRenderer::Map (double ix, double iy)
     840                 :            :         {
     841                 :            :             double x, y;
     842                 :            : 
     843                 :          0 :             x = ix*aWorldTransform.eM11 + iy*aWorldTransform.eM21 + aWorldTransform.eDx;
     844                 :          0 :             y = ix*aWorldTransform.eM12 + iy*aWorldTransform.eM22 + aWorldTransform.eDy;
     845                 :            : 
     846                 :          0 :             MapToDevice (x, y);
     847                 :            : 
     848                 :          0 :             x -= nFrameLeft;
     849                 :          0 :             y -= nFrameTop;
     850                 :            : 
     851                 :          0 :             x *= aBaseTransform.eM11;
     852                 :          0 :             y *= aBaseTransform.eM22;
     853                 :            : 
     854                 :          0 :             return ::basegfx::B2DPoint (x, y);
     855                 :            :         }
     856                 :            : 
     857                 :          0 :         ::basegfx::B2DSize ImplRenderer::MapSize (double iwidth, double iheight)
     858                 :            :         {
     859                 :            :             double w, h;
     860                 :            : 
     861                 :          0 :             w = iwidth*aWorldTransform.eM11 + iheight*aWorldTransform.eM21;
     862                 :          0 :             h = iwidth*aWorldTransform.eM12 + iheight*aWorldTransform.eM22;
     863                 :            : 
     864                 :          0 :             MapToDevice (w, h);
     865                 :            : 
     866                 :          0 :             w *= aBaseTransform.eM11;
     867                 :          0 :             h *= aBaseTransform.eM22;
     868                 :            : 
     869                 :          0 :             return ::basegfx::B2DSize (w, h);
     870                 :            :         }
     871                 :            : 
     872                 :            : #define COLOR(x) \
     873                 :            :     ::vcl::unotools::colorToDoubleSequence( ::Color (0xff - (x >> 24), \
     874                 :            :                              (x >> 16) & 0xff, \
     875                 :            :                              (x >> 8) & 0xff, \
     876                 :            :                              x & 0xff), \
     877                 :            :                         rCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace());
     878                 :            : #define SET_FILL_COLOR(x) \
     879                 :            :     rState.fillColor = COLOR(x);
     880                 :            : #define SET_TEXT_COLOR(x) \
     881                 :            :     rState.textColor = COLOR(x);
     882                 :            : 
     883                 :          0 :         void ImplRenderer::EMFPPlusFillPolygon (::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms,
     884                 :            :                                                 OutDevState& rState, const CanvasSharedPtr& rCanvas, bool isColor, sal_uInt32 brushIndexOrColor)
     885                 :            :         {
     886         [ #  # ]:          0 :             ::basegfx::B2DPolyPolygon localPolygon (polygon);
     887                 :            : 
     888                 :            :             EMFP_DEBUG (printf ("EMF+\tfill polygon\n"));
     889                 :            : 
     890         [ #  # ]:          0 :             localPolygon.transform( rState.mapModeTransform );
     891                 :            : 
     892         [ #  # ]:          0 :             ActionSharedPtr pPolyAction;
     893                 :            : 
     894         [ #  # ]:          0 :             if (isColor) {
     895                 :            :                 EMFP_DEBUG (printf ("EMF+\t\tcolor fill\n"));
     896                 :            : 
     897                 :          0 :                 rState.isFillColorSet = true;
     898                 :          0 :                 rState.isLineColorSet = false;
     899 [ #  # ][ #  # ]:          0 :                 SET_FILL_COLOR(brushIndexOrColor);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     900                 :            : 
     901 [ #  # ][ #  # ]:          0 :                 pPolyAction = ActionSharedPtr ( internal::PolyPolyActionFactory::createPolyPolyAction( localPolygon, rParms.mrCanvas, rState ) );
                 [ #  # ]
     902                 :            : 
     903                 :            :             } else {
     904                 :          0 :                 rState.isFillColorSet = true;
     905                 :            :                 // extract UseBrush
     906                 :          0 :                 EMFPBrush* brush = (EMFPBrush*) aObjects [brushIndexOrColor & 0xff];
     907                 :            :                 EMFP_DEBUG (printf ("EMF+\tbrush fill slot: %u (type: %u)\n", (unsigned int)brushIndexOrColor, (unsigned int)brush->GetType ()));
     908                 :            : 
     909                 :            :                 // give up in case something wrong happened
     910         [ #  # ]:          0 :                 if( !brush )
     911                 :            :                     return;
     912                 :            : 
     913                 :          0 :                 rState.isFillColorSet = false;
     914                 :          0 :                 rState.isLineColorSet = false;
     915                 :            : 
     916 [ #  # ][ #  # ]:          0 :                 if (brush->type == 3 || brush->type == 4) {
     917                 :            : 
     918 [ #  # ][ #  # ]:          0 :                     if (brush->type == 3 && !(brush->additionalFlags & 0x1))
     919                 :            :                         return;  // we are unable to parse these brushes yet
     920                 :            : 
     921         [ #  # ]:          0 :                 ::basegfx::B2DHomMatrix aTextureTransformation;
     922         [ #  # ]:          0 :                 ::basegfx::B2DHomMatrix aWorldTransformation;
     923         [ #  # ]:          0 :                 ::basegfx::B2DHomMatrix aBaseTransformation;
     924         [ #  # ]:          0 :                 rendering::Texture aTexture;
     925                 :            : 
     926         [ #  # ]:          0 :                 aWorldTransformation.set (0, 0, aWorldTransform.eM11);
     927         [ #  # ]:          0 :                 aWorldTransformation.set (0, 1, aWorldTransform.eM21);
     928         [ #  # ]:          0 :                 aWorldTransformation.set (0, 2, aWorldTransform.eDx);
     929         [ #  # ]:          0 :                 aWorldTransformation.set (1, 0, aWorldTransform.eM12);
     930         [ #  # ]:          0 :                 aWorldTransformation.set (1, 1, aWorldTransform.eM22);
     931         [ #  # ]:          0 :                 aWorldTransformation.set (1, 2, aWorldTransform.eDy);
     932                 :            : 
     933         [ #  # ]:          0 :                 aBaseTransformation.set (0, 0, aBaseTransform.eM11);
     934         [ #  # ]:          0 :                 aBaseTransformation.set (0, 1, aBaseTransform.eM21);
     935         [ #  # ]:          0 :                 aBaseTransformation.set (0, 2, aBaseTransform.eDx);
     936         [ #  # ]:          0 :                 aBaseTransformation.set (1, 0, aBaseTransform.eM12);
     937         [ #  # ]:          0 :                 aBaseTransformation.set (1, 1, aBaseTransform.eM22);
     938         [ #  # ]:          0 :                 aBaseTransformation.set (1, 2, aBaseTransform.eDy);
     939                 :            : 
     940         [ #  # ]:          0 :                 if (brush->type == 4) {
     941         [ #  # ]:          0 :                     aTextureTransformation.scale (brush->areaWidth, brush->areaHeight);
     942         [ #  # ]:          0 :                     aTextureTransformation.translate (brush->areaX, brush->areaY);
     943                 :            :                 } else {
     944         [ #  # ]:          0 :                     aTextureTransformation.translate (-0.5, -0.5);
     945         [ #  # ]:          0 :                     aTextureTransformation.scale (brush->areaWidth, brush->areaHeight);
     946         [ #  # ]:          0 :                     aTextureTransformation.translate (brush->areaX,brush->areaY);
     947                 :            :                 }
     948                 :            : 
     949         [ #  # ]:          0 :                 if (brush->hasTransformation) {
     950         [ #  # ]:          0 :                     ::basegfx::B2DHomMatrix aTransformation;
     951                 :            : 
     952         [ #  # ]:          0 :                     aTransformation.set (0, 0, brush->transformation.eM11);
     953         [ #  # ]:          0 :                     aTransformation.set (0, 1, brush->transformation.eM21);
     954         [ #  # ]:          0 :                     aTransformation.set (0, 2, brush->transformation.eDx);
     955         [ #  # ]:          0 :                     aTransformation.set (1, 0, brush->transformation.eM12);
     956         [ #  # ]:          0 :                     aTransformation.set (1, 1, brush->transformation.eM22);
     957         [ #  # ]:          0 :                     aTransformation.set (1, 2, brush->transformation.eDy);
     958                 :            : 
     959 [ #  # ][ #  # ]:          0 :                     aTextureTransformation *= aTransformation;
     960                 :            :                 }
     961                 :            : 
     962         [ #  # ]:          0 :                 aTextureTransformation *= aWorldTransformation;
     963         [ #  # ]:          0 :                 aTextureTransformation.scale (100.0*nMmX/nPixX, 100.0*nMmY/nPixY);
     964         [ #  # ]:          0 :                 aTextureTransformation.translate (-nFrameLeft, -nFrameTop);
     965         [ #  # ]:          0 :                 aTextureTransformation *= rState.mapModeTransform;
     966         [ #  # ]:          0 :                 aTextureTransformation *= aBaseTransformation;
     967                 :            : 
     968                 :          0 :                 aTexture.RepeatModeX = rendering::TexturingMode::CLAMP;
     969                 :          0 :                 aTexture.RepeatModeY = rendering::TexturingMode::CLAMP;
     970                 :          0 :                 aTexture.Alpha = 1.0;
     971                 :            : 
     972         [ #  # ]:          0 :         basegfx::ODFGradientInfo aGradInfo;
     973                 :          0 :         rtl::OUString aGradientService;
     974                 :            : 
     975                 :            :                     const uno::Sequence< double > aStartColor(
     976                 :            :                         ::vcl::unotools::colorToDoubleSequence( brush->solidColor,
     977 [ #  # ][ #  # ]:          0 :                                                                 rParms.mrCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace() ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     978                 :            :                     const uno::Sequence< double > aEndColor(
     979                 :            :                         ::vcl::unotools::colorToDoubleSequence( brush->secondColor,
     980 [ #  # ][ #  # ]:          0 :                                                                 rParms.mrCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace() ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     981         [ #  # ]:          0 :                     uno::Sequence< uno::Sequence < double > > aColors (2);
     982         [ #  # ]:          0 :                     uno::Sequence< double > aStops (2);
     983                 :            : 
     984         [ #  # ]:          0 :                     if (brush->blendPositions) {
     985                 :            :                         EMFP_DEBUG (printf ("EMF+\t\tuse blend\n"));
     986         [ #  # ]:          0 :                         aColors.realloc (brush->blendPoints);
     987         [ #  # ]:          0 :                         aStops.realloc (brush->blendPoints);
     988                 :          0 :                         int length = aStartColor.getLength ();
     989         [ #  # ]:          0 :                         uno::Sequence< double > aColor (length);
     990                 :            : 
     991                 :            :                         OSL_ASSERT (length == aEndColor.getLength());
     992                 :            : 
     993         [ #  # ]:          0 :                         for (int i = 0; i < brush->blendPoints; i++) {
     994         [ #  # ]:          0 :                             aStops[i] = brush->blendPositions [i];
     995                 :            : 
     996         [ #  # ]:          0 :                             for (int j = 0; j < length; j++) {
     997         [ #  # ]:          0 :                                 if (brush->type == 4) {
     998                 :            : //                                     // gamma correction
     999                 :            : //                                     if (brush->additionalFlags & 0x80)
    1000                 :            : //                                         aColor [j] = pow (aStartColor [j]*(1 - brush->blendFactors[i]) + aEndColor [j]*brush->blendFactors[i], 1/2.2);
    1001                 :            : //                                     else
    1002         [ #  # ]:          0 :                                     aColor [j] = aStartColor [j]*(1 - brush->blendFactors[i]) + aEndColor [j]*brush->blendFactors[i];
    1003                 :            :                                 } else
    1004         [ #  # ]:          0 :                                     aColor [j] = aStartColor [j]*brush->blendFactors[i] + aEndColor [j]*(1 - brush->blendFactors[i]);
    1005                 :            :                             }
    1006                 :            : 
    1007 [ #  # ][ #  # ]:          0 :                             aColors[i] = aColor;
    1008         [ #  # ]:          0 :                         }
    1009         [ #  # ]:          0 :                     } else if (brush->colorblendPositions) {
    1010                 :            :                         EMFP_DEBUG (printf ("EMF+\t\tuse color blend\n"));
    1011         [ #  # ]:          0 :                         aColors.realloc (brush->colorblendPoints);
    1012         [ #  # ]:          0 :                         aStops.realloc (brush->colorblendPoints);
    1013                 :            : 
    1014         [ #  # ]:          0 :                         for (int i = 0; i < brush->colorblendPoints; i++) {
    1015         [ #  # ]:          0 :                             aStops[i] = brush->colorblendPositions [i];
    1016 [ #  # ][ #  # ]:          0 :                             aColors[(brush->type == 4) ? i : brush->colorblendPoints - 1 - i] = ::vcl::unotools::colorToDoubleSequence( brush->colorblendColors [i],
    1017 [ #  # ][ #  # ]:          0 :                                                                                                                                         rParms.mrCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace() );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1018                 :            :                         }
    1019                 :            :                     } else {
    1020         [ #  # ]:          0 :                         aStops[0] = 0.0;
    1021         [ #  # ]:          0 :                         aStops[1] = 1.0;
    1022                 :            : 
    1023         [ #  # ]:          0 :                         if (brush->type == 4) {
    1024 [ #  # ][ #  # ]:          0 :                             aColors[0] = aStartColor;
    1025 [ #  # ][ #  # ]:          0 :                             aColors[1] = aEndColor;
    1026                 :            :                         } else {
    1027 [ #  # ][ #  # ]:          0 :                             aColors[1] = aStartColor;
    1028 [ #  # ][ #  # ]:          0 :                             aColors[0] = aEndColor;
    1029                 :            :                         }
    1030                 :            :                     }
    1031                 :            : 
    1032                 :            :                     EMFP_DEBUG (printf ("EMF+\t\tset gradient\n"));
    1033         [ #  # ]:          0 :            basegfx::B2DRange aBoundsRectangle (0, 0, 1, 1);
    1034         [ #  # ]:          0 :                     if (brush->type == 4) {
    1035                 :          0 :            aGradientService = "LinearGradient";
    1036                 :            :            basegfx::tools::createLinearODFGradientInfo( aGradInfo,
    1037                 :            :                                     aBoundsRectangle,
    1038                 :          0 :                                     aStops.getLength(),
    1039                 :            :                                     0,
    1040         [ #  # ]:          0 :                                     0 );
    1041                 :            : 
    1042                 :            :                     } else {
    1043                 :          0 :             aGradientService = "EllipticalGradient";
    1044                 :            :             basegfx::tools::createEllipticalODFGradientInfo( aGradInfo,
    1045                 :            :                                      aBoundsRectangle,
    1046                 :            :                                      ::basegfx::B2DVector( 0, 0 ),
    1047                 :          0 :                                      aStops.getLength(),
    1048                 :            :                                      0,
    1049         [ #  # ]:          0 :                                      0 );
    1050                 :            :                     }
    1051                 :            : 
    1052                 :            :             uno::Reference< lang::XMultiServiceFactory > xFactory(
    1053 [ #  # ][ #  # ]:          0 :             rParms.mrCanvas->getUNOCanvas()->getDevice()->getParametricPolyPolygonFactory() );
         [ #  # ][ #  # ]
                 [ #  # ]
    1054                 :            : 
    1055         [ #  # ]:          0 :             if( xFactory.is() ) {
    1056         [ #  # ]:          0 :             uno::Sequence<uno::Any> args( 3 );
    1057                 :          0 :             beans::PropertyValue aProp;
    1058                 :          0 :             aProp.Name = "Colors";
    1059         [ #  # ]:          0 :             aProp.Value <<= aColors;
    1060 [ #  # ][ #  # ]:          0 :             args[0] <<= aProp;
    1061                 :          0 :             aProp.Name = "Stops";
    1062         [ #  # ]:          0 :             aProp.Value <<= aStops;
    1063 [ #  # ][ #  # ]:          0 :             args[1] <<= aProp;
    1064                 :          0 :             aProp.Name = "AspectRatio";
    1065         [ #  # ]:          0 :             aProp.Value <<= static_cast<sal_Int32>(1);
    1066 [ #  # ][ #  # ]:          0 :             args[2] <<= aProp;
    1067                 :            : 
    1068                 :            :             aTexture.Gradient.set(
    1069         [ #  # ]:          0 :                 xFactory->createInstanceWithArguments( aGradientService,
    1070                 :          0 :                                    args ),
    1071 [ #  # ][ #  # ]:          0 :                 uno::UNO_QUERY);
                 [ #  # ]
    1072                 :            :             }
    1073                 :            : 
    1074                 :            :             ::basegfx::unotools::affineMatrixFromHomMatrix( aTexture.AffineTransform,
    1075         [ #  # ]:          0 :                                     aTextureTransformation );
    1076                 :            : 
    1077         [ #  # ]:          0 :             if( aTexture.Gradient.is() )
    1078                 :            :             pPolyAction =
    1079                 :            :                 ActionSharedPtr ( internal::PolyPolyActionFactory::createPolyPolyAction( localPolygon,
    1080                 :            :                                                      rParms.mrCanvas,
    1081                 :            :                                                      rState,
    1082 [ #  # ][ #  # ]:          0 :                                                      aTexture ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1083                 :            :                 }
    1084                 :            :             }
    1085                 :            : 
    1086         [ #  # ]:          0 :             if( pPolyAction )
    1087                 :            :             {
    1088                 :            :                 EMFP_DEBUG (printf ("EMF+\t\tadd poly action\n"));
    1089                 :            : 
    1090                 :            :                 maActions.push_back(
    1091                 :            :                     MtfAction(
    1092                 :            :                         pPolyAction,
    1093 [ #  # ][ #  # ]:          0 :                         rParms.mrCurrActionIndex ) );
                 [ #  # ]
    1094                 :            : 
    1095         [ #  # ]:          0 :                 rParms.mrCurrActionIndex += pPolyAction->getActionCount()-1;
    1096 [ #  # ][ #  # ]:          0 :             }
         [ #  # ][ #  # ]
    1097                 :            :         }
    1098                 :            : 
    1099                 :          0 :         void ImplRenderer::processObjectRecord(SvMemoryStream& rObjectStream, sal_uInt16 flags, sal_Bool bUseWholeStream)
    1100                 :            :         {
    1101                 :            :             sal_uInt32 index;
    1102                 :            : 
    1103                 :            :             EMFP_DEBUG (printf ("EMF+ Object slot: %hd flags: %hx\n", flags & 0xff, flags & 0xff00));
    1104                 :            : 
    1105                 :          0 :             index = flags & 0xff;
    1106         [ #  # ]:          0 :             if (aObjects [index] != NULL) {
    1107         [ #  # ]:          0 :                 delete aObjects [index];
    1108                 :          0 :                 aObjects [index] = NULL;
    1109                 :            :             }
    1110                 :            : 
    1111   [ #  #  #  #  :          0 :             switch (flags & 0x7f00) {
                #  #  # ]
    1112                 :            :             case EmfPlusObjectTypeBrush:
    1113                 :            :                 {
    1114                 :            :                     EMFPBrush *brush;
    1115 [ #  # ][ #  # ]:          0 :                     aObjects [index] = brush = new EMFPBrush ();
    1116         [ #  # ]:          0 :                     brush->Read (rObjectStream, *this);
    1117                 :            : 
    1118                 :            :                     break;
    1119                 :            :                 }
    1120                 :            :             case EmfPlusObjectTypePen:
    1121                 :            :                 {
    1122                 :            :                     EMFPPen *pen;
    1123 [ #  # ][ #  # ]:          0 :                     aObjects [index] = pen = new EMFPPen ();
    1124         [ #  # ]:          0 :                     pen->Read (rObjectStream, *this, nHDPI, nVDPI);
    1125                 :            : 
    1126                 :            :                     break;
    1127                 :            :                 }
    1128                 :            :             case EmfPlusObjectTypePath:
    1129                 :            :                 sal_uInt32 header, pathFlags;
    1130                 :            :                 sal_Int32 points;
    1131                 :            : 
    1132 [ #  # ][ #  # ]:          0 :                 rObjectStream >> header >> points >> pathFlags;
                 [ #  # ]
    1133                 :            : 
    1134                 :            :                 EMFP_DEBUG (printf ("EMF+\tpath\n"));
    1135                 :            :                 EMFP_DEBUG (printf ("EMF+\theader: 0x%08x points: %d additional flags: 0x%08x\n", (unsigned int)header, (int)points, (unsigned int)pathFlags));
    1136                 :            : 
    1137                 :            :                 EMFPPath *path;
    1138 [ #  # ][ #  # ]:          0 :                 aObjects [index] = path = new EMFPPath (points);
    1139         [ #  # ]:          0 :                 path->Read (rObjectStream, pathFlags, *this);
    1140                 :            : 
    1141                 :            :                 break;
    1142                 :            :             case EmfPlusObjectTypeRegion: {
    1143                 :            :                 EMFPRegion *region;
    1144                 :            : 
    1145         [ #  # ]:          0 :                 aObjects [index] = region = new EMFPRegion ();
    1146         [ #  # ]:          0 :                 region->Read (rObjectStream);
    1147                 :            : 
    1148                 :            :                 break;
    1149                 :            :             }
    1150                 :            :             case EmfPlusObjectTypeImage:
    1151                 :            :                 {
    1152                 :            :                     EMFPImage *image;
    1153 [ #  # ][ #  # ]:          0 :                     aObjects [index] = image = new EMFPImage ();
    1154         [ #  # ]:          0 :                     image->Read (rObjectStream, bUseWholeStream);
    1155                 :            : 
    1156                 :            :                     break;
    1157                 :            :                 }
    1158                 :            :             case EmfPlusObjectTypeFont:
    1159                 :            :                 {
    1160                 :            :                     EMFPFont *font;
    1161         [ #  # ]:          0 :                     aObjects [index] = font = new EMFPFont ();
    1162         [ #  # ]:          0 :                     font->Read (rObjectStream);
    1163                 :            : 
    1164                 :            :                     break;
    1165                 :            :                 }
    1166                 :            :             default:
    1167                 :            :                 EMFP_DEBUG (printf ("EMF+\tObject unhandled flags: 0x%04x\n", flags & 0xff00));
    1168                 :            :                 break;
    1169                 :            :             }
    1170                 :          0 :         }
    1171                 :            : 
    1172                 :          0 :         double ImplRenderer::setFont (sal_uInt8 objectId, const ActionFactoryParameters& rParms, OutDevState& rState)
    1173                 :            :         {
    1174                 :          0 :             EMFPFont *font = (EMFPFont*) aObjects[ objectId ];
    1175                 :            : 
    1176                 :          0 :             rendering::FontRequest aFontRequest;
    1177                 :          0 :             aFontRequest.FontDescription.FamilyName = font->family;
    1178                 :          0 :             double cellSize = font->emSize;
    1179         [ #  # ]:          0 :             aFontRequest.CellSize = (rState.mapModeTransform*MapSize( cellSize, 0 )).getX();
    1180 [ #  # ][ #  # ]:          0 :             rState.xFont = rParms.mrCanvas->getUNOCanvas()->createFont( aFontRequest,
    1181                 :            :                                                uno::Sequence< beans::PropertyValue >(),
    1182 [ #  # ][ #  # ]:          0 :                                                geometry::Matrix2D() );
         [ #  # ][ #  # ]
    1183                 :            : 
    1184                 :          0 :             return cellSize;
    1185                 :            :         }
    1186                 :            : 
    1187                 :          0 :         void ImplRenderer::processEMFPlus( MetaCommentAction* pAct, const ActionFactoryParameters& rFactoryParms,
    1188                 :            :                                            OutDevState& rState, const CanvasSharedPtr& rCanvas )
    1189                 :            :         {
    1190                 :          0 :             sal_uInt32 length = pAct->GetDataSize ();
    1191         [ #  # ]:          0 :             SvMemoryStream rMF ((void*) pAct->GetData (), length, STREAM_READ);
    1192                 :            : 
    1193                 :          0 :             length -= 4;
    1194                 :            : 
    1195         [ #  # ]:          0 :             while (length > 0) {
    1196                 :            :                 sal_uInt16 type, flags;
    1197                 :            :                 sal_uInt32 size, dataSize;
    1198                 :            :                 sal_uInt32 next;
    1199                 :            : 
    1200 [ #  # ][ #  # ]:          0 :                 rMF >> type >> flags >> size >> dataSize;
         [ #  # ][ #  # ]
    1201                 :            : 
    1202                 :          0 :                 next = rMF.Tell() + ( size - 12 );
    1203                 :            : 
    1204                 :            :                 EMFP_DEBUG (printf ("EMF+ record size: %u type: %04hx flags: %04hx data size: %u\n", (unsigned int)size, type, flags, (unsigned int)dataSize));
    1205                 :            : 
    1206 [ #  # ][ #  # ]:          0 :                 if (type == EmfPlusRecordTypeObject && ((mbMultipart && (flags & 0x7fff) == (mMFlags & 0x7fff)) || (flags & 0x8000))) {
         [ #  # ][ #  # ]
    1207         [ #  # ]:          0 :                     if (!mbMultipart) {
    1208                 :          0 :                         mbMultipart = true;
    1209                 :          0 :                         mMFlags = flags;
    1210         [ #  # ]:          0 :                         mMStream.Seek(0);
    1211                 :            :                     }
    1212                 :            : 
    1213                 :            :                     // 1st 4 bytes are unknown
    1214 [ #  # ][ #  # ]:          0 :                     mMStream.Write (((const char *)rMF.GetData()) + rMF.Tell() + 4, dataSize - 4);
    1215                 :            :                     EMFP_DEBUG (printf ("EMF+ read next object part size: %u type: %04hx flags: %04hx data size: %u\n", (unsigned int)size, type, flags, (unsigned int)dataSize));
    1216                 :            :                 } else {
    1217         [ #  # ]:          0 :                     if (mbMultipart) {
    1218                 :            :                         EMFP_DEBUG (printf ("EMF+ multipart record flags: %04hx\n", mMFlags));
    1219         [ #  # ]:          0 :                         mMStream.Seek (0);
    1220         [ #  # ]:          0 :                         processObjectRecord (mMStream, mMFlags, sal_True);
    1221                 :            :                     }
    1222                 :          0 :                     mbMultipart = false;
    1223                 :            :                 }
    1224                 :            : 
    1225 [ #  # ][ #  # ]:          0 :                 if (type != EmfPlusRecordTypeObject || !(flags & 0x8000))
    1226   [ #  #  #  #  :          0 :                 switch (type) {
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    1227                 :            :                 case EmfPlusRecordTypeHeader:
    1228                 :            :                     sal_uInt32 header, version;
    1229                 :            : 
    1230 [ #  # ][ #  # ]:          0 :                     rMF >> header >> version >> nHDPI >> nVDPI;
         [ #  # ][ #  # ]
    1231                 :            : 
    1232                 :            :                     EMFP_DEBUG (printf ("EMF+ Header\n"));
    1233                 :            :                     EMFP_DEBUG (printf ("EMF+\theader: 0x%08x version: %u horizontal DPI: %d vertical DPI: %d dual: %d\n", (int)header, (unsigned int)version, (int)nHDPI, (int)nVDPI,(int)( flags & 1)));
    1234                 :            : 
    1235                 :            :                     break;
    1236                 :            :                 case EmfPlusRecordTypeEndOfFile:
    1237                 :            :                     EMFP_DEBUG (printf ("EMF+ EndOfFile\n"));
    1238                 :            :                     break;
    1239                 :            :                 case EmfPlusRecordTypeGetDC:
    1240                 :            :                     EMFP_DEBUG (printf ("EMF+ GetDC\n"));
    1241                 :            :                     EMFP_DEBUG (printf ("EMF+\talready used in svtools wmf/emf filter parser\n"));
    1242                 :            :                     break;
    1243                 :            :                 case EmfPlusRecordTypeObject:
    1244         [ #  # ]:          0 :                     processObjectRecord (rMF, flags);
    1245                 :            :                     break;
    1246                 :            :                 case EmfPlusRecordTypeFillPath:
    1247                 :            :                     {
    1248                 :          0 :                         sal_uInt32 index = flags & 0xff;
    1249                 :            :                         sal_uInt32 brushIndexOrColor;
    1250                 :            : 
    1251         [ #  # ]:          0 :                         rMF >> brushIndexOrColor;
    1252                 :            : 
    1253                 :            :                         EMFP_DEBUG (printf ("EMF+ FillPath slot: %u\n", (unsigned int)index));
    1254                 :            : 
    1255 [ #  # ][ #  # ]:          0 :                         EMFPPlusFillPolygon (((EMFPPath*) aObjects [index])->GetPolygon (*this), rFactoryParms, rState, rCanvas, flags & 0x8000, brushIndexOrColor);
    1256                 :            :                     }
    1257                 :            :                     break;
    1258                 :            :                 case EmfPlusRecordTypeFillRects:
    1259                 :            :                     {
    1260                 :            :                         EMFP_DEBUG (printf ("EMF+ FillRects\n"));
    1261                 :            : 
    1262                 :            :                         sal_uInt32 brushIndexOrColor;
    1263                 :            :                         sal_Int32 rectangles;
    1264         [ #  # ]:          0 :                         ::basegfx::B2DPolygon polygon;
    1265                 :            : 
    1266 [ #  # ][ #  # ]:          0 :                         rMF >> brushIndexOrColor >> rectangles;
    1267                 :            : 
    1268                 :            :                         EMFP_DEBUG (printf ("EMF+\t%s: 0x%08x\n", (flags & 0x8000) ? "color" : "brush index", (unsigned int)brushIndexOrColor));
    1269                 :            : 
    1270         [ #  # ]:          0 :                         for (int i=0; i < rectangles; i++) {
    1271         [ #  # ]:          0 :                             if (flags & 0x4000) {
    1272                 :            :                                 /* 16bit integers */
    1273                 :            :                                 sal_Int16 x, y, width, height;
    1274                 :            : 
    1275 [ #  # ][ #  # ]:          0 :                                 rMF >> x >> y >> width >> height;
         [ #  # ][ #  # ]
    1276                 :            : 
    1277         [ #  # ]:          0 :                                 polygon.append (Map (x, y));
    1278         [ #  # ]:          0 :                                 polygon.append (Map (x + width, y));
    1279         [ #  # ]:          0 :                                 polygon.append (Map (x + width, y + height));
    1280         [ #  # ]:          0 :                                 polygon.append (Map (x, y + height));
    1281                 :            : 
    1282                 :            :                                 EMFP_DEBUG (printf ("EMF+\trectangle: %d,%d %dx%d\n", x, y, width, height));
    1283                 :            :                             } else {
    1284                 :            :                                 /* Single's */
    1285                 :            :                                 float x, y, width, height;
    1286                 :            : 
    1287 [ #  # ][ #  # ]:          0 :                                 rMF >> x >> y >> width >> height;
         [ #  # ][ #  # ]
    1288                 :            : 
    1289         [ #  # ]:          0 :                                 polygon.append (Map (x, y));
    1290         [ #  # ]:          0 :                                 polygon.append (Map (x + width, y));
    1291         [ #  # ]:          0 :                                 polygon.append (Map (x + width, y + height));
    1292         [ #  # ]:          0 :                                 polygon.append (Map (x, y + height));
    1293                 :            : 
    1294                 :            :                                 EMFP_DEBUG (printf ("EMF+\trectangle: %f,%f %fx%f\n", x, y, width, height));
    1295                 :            :                             }
    1296                 :            : 
    1297         [ #  # ]:          0 :                             ::basegfx::B2DPolyPolygon polyPolygon (polygon);
    1298                 :            : 
    1299         [ #  # ]:          0 :                             EMFPPlusFillPolygon (polyPolygon, rFactoryParms, rState, rCanvas, flags & 0x8000, brushIndexOrColor);
    1300         [ #  # ]:          0 :                         }
    1301         [ #  # ]:          0 :                         break;
    1302                 :            :                     }
    1303                 :            :                 case EmfPlusRecordTypeFillPolygon:
    1304                 :            :                     {
    1305                 :            :                         EMFP_DEBUG (sal_uInt8 index = flags & 0xff);
    1306                 :            :                         sal_uInt32 brushIndexOrColor;
    1307                 :            :                         sal_Int32 points;
    1308                 :            : 
    1309         [ #  # ]:          0 :                         rMF >> brushIndexOrColor;
    1310         [ #  # ]:          0 :                         rMF >> points;
    1311                 :            : 
    1312                 :            :                         EMFP_DEBUG (printf ("EMF+ FillPolygon in slot: %d points: %d\n", index, points));
    1313                 :            :                         EMFP_DEBUG (printf ("EMF+\t%s: 0x%08x\n", (flags & 0x8000) ? "color" : "brush index", brushIndexOrColor));
    1314                 :            : 
    1315         [ #  # ]:          0 :                         EMFPPath path (points, true);
    1316         [ #  # ]:          0 :                         path.Read (rMF, flags, *this);
    1317                 :            : 
    1318                 :            : 
    1319 [ #  # ][ #  # ]:          0 :                         EMFPPlusFillPolygon (path.GetPolygon (*this), rFactoryParms, rState, rCanvas, flags & 0x8000, brushIndexOrColor);
    1320                 :            : 
    1321         [ #  # ]:          0 :                         break;
    1322                 :            :                     }
    1323                 :            :                 case EmfPlusRecordTypeDrawLines:
    1324                 :            :                     {
    1325                 :          0 :                         sal_uInt32 index = flags & 0xff;
    1326                 :            :                         sal_uInt32 points;
    1327                 :            : 
    1328         [ #  # ]:          0 :                         rMF >> points;
    1329                 :            : 
    1330                 :            :                         EMFP_DEBUG (printf ("EMF+ DrawLines in slot: %u points: %u\n", (unsigned int)index, (unsigned int)points));
    1331                 :            : 
    1332         [ #  # ]:          0 :                         EMFPPath path (points, true);
    1333         [ #  # ]:          0 :                         path.Read (rMF, flags, *this);
    1334                 :            : 
    1335                 :          0 :                         EMFPPen* pen = (EMFPPen*) aObjects [index];
    1336                 :            : 
    1337                 :          0 :                         rState.isFillColorSet = false;
    1338                 :          0 :                         rState.isLineColorSet = true;
    1339                 :          0 :                         rState.lineColor = ::vcl::unotools::colorToDoubleSequence (pen->GetColor (),
    1340 [ #  # ][ #  # ]:          0 :                                                                                    rCanvas->getUNOCanvas ()->getDevice()->getDeviceColorSpace() );
         [ #  # ][ #  # ]
           [ #  #  #  # ]
         [ #  # ][ #  # ]
    1341         [ #  # ]:          0 :                         ::basegfx::B2DPolyPolygon& polygon (path.GetPolygon (*this));
    1342                 :            : 
    1343         [ #  # ]:          0 :                         polygon.transform( rState.mapModeTransform );
    1344                 :            : 
    1345         [ #  # ]:          0 :                         rendering::StrokeAttributes aStrokeAttributes;
    1346                 :            : 
    1347         [ #  # ]:          0 :                         pen->SetStrokeAttributes (aStrokeAttributes, *this, rState);
    1348                 :            : 
    1349                 :            :             ActionSharedPtr pPolyAction(
    1350                 :            :                 internal::PolyPolyActionFactory::createPolyPolyAction(
    1351         [ #  # ]:          0 :                     polygon, rFactoryParms.mrCanvas, rState, aStrokeAttributes ) );
    1352                 :            : 
    1353         [ #  # ]:          0 :             if( pPolyAction )
    1354                 :            :             {
    1355                 :            :                 maActions.push_back(
    1356                 :            :                     MtfAction(
    1357                 :            :                         pPolyAction,
    1358 [ #  # ][ #  # ]:          0 :                         rFactoryParms.mrCurrActionIndex ) );
                 [ #  # ]
    1359                 :            : 
    1360         [ #  # ]:          0 :                 rFactoryParms.mrCurrActionIndex += pPolyAction->getActionCount()-1;
    1361                 :            :             }
    1362                 :            : 
    1363 [ #  # ][ #  # ]:          0 :                         break;
                 [ #  # ]
    1364                 :            :                     }
    1365                 :            :                 case EmfPlusRecordTypeDrawPath:
    1366                 :            :                     {
    1367                 :            :                         sal_uInt32 penIndex;
    1368                 :            : 
    1369         [ #  # ]:          0 :                         rMF >> penIndex;
    1370                 :            : 
    1371                 :            :                         EMFP_DEBUG (printf ("EMF+ DrawPath\n"));
    1372                 :            :                         EMFP_DEBUG (printf ("EMF+\tpen: %u\n", (unsigned int)penIndex));
    1373                 :            : 
    1374                 :          0 :                         EMFPPath* path = (EMFPPath*) aObjects [flags & 0xff];
    1375                 :          0 :                         EMFPPen* pen = (EMFPPen*) aObjects [penIndex & 0xff];
    1376                 :            : 
    1377                 :            :                         SAL_WARN_IF( !pen, "cppcanvas", "EmfPlusRecordTypeDrawPath missing pen" );
    1378                 :            :                         SAL_WARN_IF( !path, "cppcanvas", "EmfPlusRecordTypeDrawPath missing path" );
    1379                 :            : 
    1380 [ #  # ][ #  # ]:          0 :                         if (pen && path)
    1381                 :            :                         {
    1382                 :          0 :                             rState.isFillColorSet = false;
    1383                 :          0 :                             rState.isLineColorSet = true;
    1384                 :          0 :                             rState.lineColor = ::vcl::unotools::colorToDoubleSequence (pen->GetColor (),
    1385 [ #  # ][ #  # ]:          0 :                                                                                        rCanvas->getUNOCanvas ()->getDevice()->getDeviceColorSpace());
         [ #  # ][ #  # ]
           [ #  #  #  # ]
         [ #  # ][ #  # ]
    1386         [ #  # ]:          0 :                             ::basegfx::B2DPolyPolygon& polygon (path->GetPolygon (*this));
    1387                 :            : 
    1388         [ #  # ]:          0 :                             polygon.transform( rState.mapModeTransform );
    1389         [ #  # ]:          0 :                             rendering::StrokeAttributes aStrokeAttributes;
    1390                 :            : 
    1391         [ #  # ]:          0 :                             pen->SetStrokeAttributes (aStrokeAttributes, *this, rState);
    1392                 :            : 
    1393                 :            :                             ActionSharedPtr pPolyAction(
    1394                 :            :                                 internal::PolyPolyActionFactory::createPolyPolyAction(
    1395         [ #  # ]:          0 :                                     polygon, rFactoryParms.mrCanvas, rState, aStrokeAttributes ) );
    1396                 :            : 
    1397         [ #  # ]:          0 :                             if( pPolyAction )
    1398                 :            :                             {
    1399                 :            :                                 maActions.push_back(
    1400                 :            :                                     MtfAction(
    1401                 :            :                                         pPolyAction,
    1402 [ #  # ][ #  # ]:          0 :                                         rFactoryParms.mrCurrActionIndex ) );
                 [ #  # ]
    1403                 :            : 
    1404         [ #  # ]:          0 :                                 rFactoryParms.mrCurrActionIndex += pPolyAction->getActionCount()-1;
    1405 [ #  # ][ #  # ]:          0 :                             }
    1406                 :            :                         }
    1407                 :            :                         break;
    1408                 :            :                     }
    1409                 :            :                 case EmfPlusRecordTypeDrawImage:
    1410                 :            :                 case EmfPlusRecordTypeDrawImagePoints:
    1411                 :            :                     {
    1412                 :            :                         sal_uInt32 attrIndex;
    1413                 :            :                         sal_Int32 sourceUnit;
    1414                 :            : 
    1415 [ #  # ][ #  # ]:          0 :                         rMF >> attrIndex >> sourceUnit;
    1416                 :            : 
    1417                 :            :                         EMFP_DEBUG (printf ("EMF+ %s attributes index: %d source unit: %d\n", type == EmfPlusRecordTypeDrawImagePoints ? "DrawImagePoints" : "DrawImage", (int)attrIndex, (int)sourceUnit));
    1418                 :            :                         EMFP_DEBUG (printf ("EMF+\tTODO: use image attributes\n"));
    1419                 :            : 
    1420 [ #  # ][ #  # ]:          0 :                         if (sourceUnit == 2 && aObjects [flags & 0xff]) { // we handle only GraphicsUnit.Pixel now
    1421                 :          0 :                             EMFPImage& image = *(EMFPImage *) aObjects [flags & 0xff];
    1422                 :            :                             float sx, sy, sw, sh;
    1423                 :            :                             sal_Int32 aCount;
    1424                 :            : 
    1425         [ #  # ]:          0 :                             ReadRectangle (rMF, sx, sy, sw, sh);
    1426                 :            : 
    1427                 :            :                             EMFP_DEBUG (printf ("EMF+ %s source rectangle: %f,%f %fx%f\n", type == EmfPlusRecordTypeDrawImagePoints ? "DrawImagePoints" : "DrawImage", sx, sy, sw, sh));
    1428                 :            : 
    1429                 :          0 :                             ::basegfx::B2DPoint aDstPoint;
    1430                 :          0 :                             ::basegfx::B2DSize aDstSize;
    1431                 :          0 :                             bool bValid = false;
    1432                 :            : 
    1433         [ #  # ]:          0 :                             if (type == EmfPlusRecordTypeDrawImagePoints) {
    1434         [ #  # ]:          0 :                                 rMF >> aCount;
    1435                 :            : 
    1436         [ #  # ]:          0 :                                 if( aCount == 3) { // TODO: now that we now that this value is count we should support it better
    1437                 :            :                                     float x1, y1, x2, y2, x3, y3;
    1438                 :            : 
    1439         [ #  # ]:          0 :                                     ReadPoint (rMF, x1, y1, flags);
    1440         [ #  # ]:          0 :                                     ReadPoint (rMF, x2, y2, flags);
    1441         [ #  # ]:          0 :                                     ReadPoint (rMF, x3, y3, flags);
    1442                 :            : 
    1443                 :          0 :                                     aDstPoint = Map (x1, y1);
    1444         [ #  # ]:          0 :                                     aDstSize = MapSize(x2 - x1, y3 - y1);
    1445                 :            : 
    1446                 :          0 :                                     bValid = true;
    1447                 :            :                                 }
    1448         [ #  # ]:          0 :                             } else if (type == EmfPlusRecordTypeDrawImage) {
    1449                 :            :                                 float dx, dy, dw, dh;
    1450                 :            : 
    1451         [ #  # ]:          0 :                                 ReadRectangle (rMF, dx, dy, dw, dh, flags & 0x4000);
    1452                 :            : 
    1453                 :          0 :                                 aDstPoint = Map (dx, dy);
    1454         [ #  # ]:          0 :                                 aDstSize = MapSize(dw, dh);
    1455                 :            : 
    1456                 :          0 :                                 bValid = true;
    1457                 :            :                             }
    1458                 :            : 
    1459         [ #  # ]:          0 :                             if (bValid) {
    1460         [ #  # ]:          0 :                                 BitmapEx aBmp( image.graphic.GetBitmapEx () );
    1461                 :          0 :                                 const Rectangle aCropRect (::vcl::unotools::pointFromB2DPoint (basegfx::B2DPoint (sx, sy)),
    1462   [ #  #  #  # ]:          0 :                                                            ::vcl::unotools::sizeFromB2DSize (basegfx::B2DSize(sw, sh)));
                 [ #  # ]
    1463         [ #  # ]:          0 :                                 aBmp.Crop( aCropRect );
    1464                 :            : 
    1465                 :            : 
    1466                 :          0 :                                 Size aSize( aBmp.GetSizePixel() );
    1467 [ #  # ][ #  # ]:          0 :                                 if( aSize.Width() > 0 && aSize.Height() > 0 ) {
                 [ #  # ]
    1468                 :            :                                     ActionSharedPtr pBmpAction (
    1469                 :            :                                         internal::BitmapActionFactory::createBitmapAction (
    1470                 :            :                                             aBmp,
    1471                 :            :                                             rState.mapModeTransform * aDstPoint,
    1472                 :            :                                             rState.mapModeTransform * aDstSize,
    1473                 :            :                                             rCanvas,
    1474 [ #  # ][ #  # ]:          0 :                                             rState));
                 [ #  # ]
    1475                 :            : 
    1476         [ #  # ]:          0 :                                     if( pBmpAction ) {
    1477                 :            :                                         maActions.push_back( MtfAction( pBmpAction,
    1478 [ #  # ][ #  # ]:          0 :                                                                         rFactoryParms.mrCurrActionIndex ) );
                 [ #  # ]
    1479                 :            : 
    1480         [ #  # ]:          0 :                                         rFactoryParms.mrCurrActionIndex += pBmpAction->getActionCount()-1;
    1481         [ #  # ]:          0 :                                     }
    1482                 :            :                                 } else {
    1483                 :            :                                     EMFP_DEBUG (printf ("EMF+ warning: empty bitmap\n"));
    1484         [ #  # ]:          0 :                                 }
    1485                 :            :                             } else {
    1486                 :            :                                 EMFP_DEBUG (printf ("EMF+ DrawImage(Points) TODO (fixme)\n"));
    1487                 :          0 :                             }
    1488                 :            :                         } else {
    1489                 :            :                             EMFP_DEBUG (printf ("EMF+ DrawImage(Points) TODO (fixme) - possibly unsupported source units for crop rectangle\n"));
    1490                 :            :                         }
    1491                 :            :                         break;
    1492                 :            :                     }
    1493                 :            :                 case EmfPlusRecordTypeDrawString:
    1494                 :            :                     {
    1495                 :            :                         EMFP_DEBUG (printf ("EMF+ DrawString\n"));
    1496                 :            : 
    1497                 :            :                         sal_uInt32 brushId;
    1498                 :            :                         sal_uInt32 formatId;
    1499                 :            :                         sal_uInt32 stringLength;
    1500                 :            : 
    1501 [ #  # ][ #  # ]:          0 :                         rMF >> brushId >> formatId >> stringLength;
                 [ #  # ]
    1502                 :            :                         EMFP_DEBUG (printf ("EMF+ DrawString brushId: %x formatId: %x length: %x\n", brushId, formatId, stringLength));
    1503                 :            : 
    1504         [ #  # ]:          0 :                         if (flags & 0x8000) {
    1505                 :            :                             float lx, ly, lw, lh;
    1506                 :            : 
    1507 [ #  # ][ #  # ]:          0 :                             rMF >> lx >> ly >> lw >> lh;
         [ #  # ][ #  # ]
    1508                 :            : 
    1509                 :            :                             EMFP_DEBUG (printf ("EMF+ DrawString layoutRect: %f,%f - %fx%f\n", lx, ly, lw, lh));
    1510                 :            : 
    1511         [ #  # ]:          0 :                             rtl::OUString text = read_uInt16s_ToOUString(rMF, stringLength);
    1512                 :            : 
    1513         [ #  # ]:          0 :                             double cellSize = setFont (flags & 0xff, rFactoryParms, rState);
    1514 [ #  # ][ #  # ]:          0 :                             SET_TEXT_COLOR( brushId );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1515                 :            : 
    1516                 :            :                             ActionSharedPtr pTextAction(
    1517                 :            :                                 TextActionFactory::createTextAction(
    1518                 :            :                                                                     // position is just rough guess for now
    1519                 :            :                                                                     // we should calculate it exactly from layoutRect or font
    1520                 :          0 :                                     ::vcl::unotools::pointFromB2DPoint ( Map( lx + 0.15*cellSize, ly + cellSize ) ),
    1521                 :            :                                     ::Size(),
    1522                 :            :                                     ::Color(),
    1523                 :            :                                     ::Size(),
    1524                 :            :                                     ::Color(),
    1525                 :            :                                     text,
    1526                 :            :                                     0,
    1527                 :            :                                     stringLength,
    1528                 :            :                                     NULL,
    1529                 :            :                                     rFactoryParms.mrVDev,
    1530                 :            :                                     rFactoryParms.mrCanvas,
    1531                 :            :                                     rState,
    1532                 :            :                                     rFactoryParms.mrParms,
    1533         [ #  # ]:          0 :                                     false ) );
           [ #  #  #  # ]
                 [ #  # ]
    1534         [ #  # ]:          0 :                             if( pTextAction )
    1535                 :            :                             {
    1536                 :            :                                 EMFP_DEBUG (printf ("EMF+\t\tadd text action\n"));
    1537                 :            : 
    1538                 :            :                                 maActions.push_back(
    1539                 :            :                                                     MtfAction(
    1540                 :            :                                                               pTextAction,
    1541 [ #  # ][ #  # ]:          0 :                                                               rFactoryParms.mrCurrActionIndex ) );
                 [ #  # ]
    1542                 :            : 
    1543         [ #  # ]:          0 :                                 rFactoryParms.mrCurrActionIndex += pTextAction->getActionCount()-1;
    1544         [ #  # ]:          0 :                             }
    1545                 :            :                         } else {
    1546                 :            :                             EMFP_DEBUG (printf ("EMF+ DrawString TODO - drawing with brush not yet supported\n"));
    1547                 :            :                         }
    1548                 :            :                     }
    1549                 :            :                     break;
    1550                 :            :                 case EmfPlusRecordTypeSetPageTransform:
    1551         [ #  # ]:          0 :                     rMF >> fPageScale;
    1552                 :            : 
    1553                 :            :                     EMFP_DEBUG (printf ("EMF+ SetPageTransform\n"));
    1554                 :            :                     EMFP_DEBUG (printf ("EMF+\tscale: %f unit: %d\n", fPageScale, flags));
    1555                 :            :                     EMFP_DEBUG (printf ("EMF+\tTODO\n"));
    1556                 :            :                     break;
    1557                 :            :                 case EmfPlusRecordTypeSetRenderingOrigin:
    1558 [ #  # ][ #  # ]:          0 :                     rMF >> nOriginX >> nOriginY;
    1559                 :            :                     EMFP_DEBUG (printf ("EMF+ SetRenderingOrigin\n"));
    1560                 :            :                     EMFP_DEBUG (printf ("EMF+\torigin [x,y]: %d,%d\n", (int)nOriginX, (int)nOriginY));
    1561                 :            :                     break;
    1562                 :            :                 case EmfPlusRecordTypeSetTextRenderingHint:
    1563                 :            :                     EMFP_DEBUG (printf ("EMF+ SetTextRenderingHint\n"));
    1564                 :            :                     EMFP_DEBUG (printf ("EMF+\tTODO\n"));
    1565                 :            :                     break;
    1566                 :            :                 case EmfPlusRecordTypeSetAntiAliasMode:
    1567                 :            :                     EMFP_DEBUG (printf ("EMF+ SetAntiAliasMode\n"));
    1568                 :            :                     EMFP_DEBUG (printf ("EMF+\tTODO\n"));
    1569                 :            :                     break;
    1570                 :            :                 case EmfPlusRecordTypeSetInterpolationMode:
    1571                 :            :                     EMFP_DEBUG (printf ("EMF+ InterpolationMode\n"));
    1572                 :            :                     EMFP_DEBUG (printf ("EMF+\tTODO\n"));
    1573                 :            :                     break;
    1574                 :            :                 case EmfPlusRecordTypeSetPixelOffsetMode:
    1575                 :            :                     EMFP_DEBUG (printf ("EMF+ SetPixelOffsetMode\n"));
    1576                 :            :                     EMFP_DEBUG (printf ("EMF+\tTODO\n"));
    1577                 :            :                     break;
    1578                 :            :                 case EmfPlusRecordTypeSetCompositingQuality:
    1579                 :            :                     EMFP_DEBUG (printf ("EMF+ SetCompositingQuality\n"));
    1580                 :            :                     EMFP_DEBUG (printf ("EMF+\tTODO\n"));
    1581                 :            :                     break;
    1582                 :            :                 case EmfPlusRecordTypeSave:
    1583                 :            :                     EMFP_DEBUG (printf ("EMF+ Save\n"));
    1584                 :            :                     EMFP_DEBUG (printf ("EMF+\tTODO\n"));
    1585                 :            :                     break;
    1586                 :            :                 case EmfPlusRecordTypeSetWorldTransform: {
    1587                 :            :                     EMFP_DEBUG (printf ("EMF+ SetWorldTransform\n"));
    1588         [ #  # ]:          0 :                     XForm transform;
    1589         [ #  # ]:          0 :                     rMF >> transform;
    1590                 :          0 :                     aWorldTransform.Set (transform);
    1591                 :            :                     EMFP_DEBUG (printf ("EMF+\tm11: %f m12: %f\nEMF+\tm21: %f m22: %f\nEMF+\tdx: %f dy: %f\n",
    1592                 :            :                             aWorldTransform.eM11, aWorldTransform.eM12,
    1593                 :            :                             aWorldTransform.eM21, aWorldTransform.eM22,
    1594                 :            :                             aWorldTransform.eDx, aWorldTransform.eDy));
    1595                 :            :                     break;
    1596                 :            :                 }
    1597                 :            :                 case EmfPlusRecordTypeResetWorldTransform:
    1598                 :            :                     EMFP_DEBUG (printf ("EMF+ ResetWorldTransform\n"));
    1599                 :          0 :                     aWorldTransform.SetIdentity ();
    1600                 :            :                     break;
    1601                 :            :                 case EmfPlusRecordTypeMultiplyWorldTransform: {
    1602                 :            :                     EMFP_DEBUG (printf ("EMF+ MultiplyWorldTransform\n"));
    1603         [ #  # ]:          0 :                     XForm transform;
    1604         [ #  # ]:          0 :                     rMF >> transform;
    1605                 :            : 
    1606                 :            :                     EMFP_DEBUG (printf ("EMF+\tmatrix m11: %f m12: %f\nEMF+\tm21: %f m22: %f\nEMF+\tdx: %f dy: %f\n",
    1607                 :            :                             transform.eM11, transform.eM12,
    1608                 :            :                             transform.eM21, transform.eM22,
    1609                 :            :                             transform.eDx, transform.eDy));
    1610                 :            : 
    1611         [ #  # ]:          0 :                     if (flags & 0x2000)  // post multiply
    1612                 :          0 :                         aWorldTransform.Multiply (transform);
    1613                 :            :                     else {               // pre multiply
    1614                 :          0 :                         transform.Multiply (aWorldTransform);
    1615                 :          0 :                         aWorldTransform.Set (transform);
    1616                 :            :                     }
    1617                 :            :                     EMFP_DEBUG (printf ("EMF+\tresult world matrix m11: %f m12: %f\nEMF+\tm21: %f m22: %f\nEMF+\tdx: %f dy: %f\n",
    1618                 :            :                             aWorldTransform.eM11, aWorldTransform.eM12,
    1619                 :            :                             aWorldTransform.eM21, aWorldTransform.eM22,
    1620                 :            :                             aWorldTransform.eDx, aWorldTransform.eDy));
    1621                 :            :                     break;
    1622                 :            :                 }
    1623                 :            :                 case EmfPlusRecordTypeSetClipPath:
    1624                 :            :                     {
    1625                 :            :                         EMFP_DEBUG (printf ("EMF+ SetClipPath\n"));
    1626                 :            :                         EMFP_DEBUG (printf ("EMF+\tpath in slot: %d\n", flags & 0xff));
    1627                 :            : 
    1628                 :          0 :                         EMFPPath& path = *(EMFPPath*) aObjects [flags & 0xff];
    1629         [ #  # ]:          0 :                         ::basegfx::B2DPolyPolygon& clipPoly (path.GetPolygon (*this));
    1630                 :            : 
    1631         [ #  # ]:          0 :                         clipPoly.transform (rState.mapModeTransform);
    1632         [ #  # ]:          0 :                         updateClipping (clipPoly, rFactoryParms, false);
    1633                 :            : 
    1634                 :            :                         break;
    1635                 :            :                     }
    1636                 :            :                 case EmfPlusRecordTypeSetClipRegion: {
    1637                 :            :                     EMFP_DEBUG (printf ("EMF+ SetClipRegion\n"));
    1638                 :            :                     EMFP_DEBUG (printf ("EMF+\tregion in slot: %d combine mode: %d\n", flags & 0xff, (flags & 0xff00) >> 8));
    1639                 :          0 :                     EMFPRegion *region = (EMFPRegion*)aObjects [flags & 0xff];
    1640                 :            : 
    1641                 :            :                     // reset clip
    1642 [ #  # ][ #  # ]:          0 :                     if (region && region->parts == 0 && region->initialState == EmfPlusRegionInitialStateInfinite) {
                 [ #  # ]
    1643 [ #  # ][ #  # ]:          0 :                         updateClipping (::basegfx::B2DPolyPolygon (), rFactoryParms, false);
                 [ #  # ]
    1644                 :            :                     } else {
    1645                 :            :                         EMFP_DEBUG (printf ("EMF+\tTODO\n"));
    1646                 :            :             }
    1647                 :            :                     break;
    1648                 :            :                 }
    1649                 :            :             case EmfPlusRecordTypeDrawDriverString: {
    1650                 :            :                     EMFP_DEBUG (printf ("EMF+ DrawDriverString, flags: 0x%04x\n", flags));
    1651                 :            :             sal_uInt32 brushIndexOrColor;
    1652                 :            :             sal_uInt32 optionFlags;
    1653                 :            :             sal_uInt32 hasMatrix;
    1654                 :            :             sal_uInt32 glyphsCount;
    1655                 :            : 
    1656 [ #  # ][ #  # ]:          0 :             rMF >> brushIndexOrColor >> optionFlags >> hasMatrix >> glyphsCount;
         [ #  # ][ #  # ]
    1657                 :            : 
    1658                 :            :             EMFP_DEBUG (printf ("EMF+\t%s: 0x%08x\n", (flags & 0x8000) ? "color" : "brush index", (unsigned int)brushIndexOrColor));
    1659                 :            :             EMFP_DEBUG (printf ("EMF+\toption flags: 0x%08x\n", (unsigned int)optionFlags));
    1660                 :            :             EMFP_DEBUG (printf ("EMF+\thas matrix: %u\n", (unsigned int)hasMatrix));
    1661                 :            :             EMFP_DEBUG (printf ("EMF+\tglyphs: %u\n", (unsigned int)glyphsCount));
    1662                 :            : 
    1663 [ #  # ][ #  # ]:          0 :             if( ( optionFlags & 1 ) && glyphsCount > 0 ) {
    1664         [ #  # ]:          0 :             float *charsPosX = new float[glyphsCount];
    1665         [ #  # ]:          0 :             float *charsPosY = new float[glyphsCount];
    1666                 :            : 
    1667         [ #  # ]:          0 :             rtl::OUString text = read_uInt16s_ToOUString(rMF, glyphsCount);
    1668                 :            : 
    1669         [ #  # ]:          0 :             for( sal_uInt32 i=0; i<glyphsCount; i++) {
    1670 [ #  # ][ #  # ]:          0 :                 rMF >> charsPosX[i] >> charsPosY[i];
    1671                 :            :                 EMFP_DEBUG (printf ("EMF+\tglyphPosition[%u]: %f, %f\n", (unsigned int)i, charsPosX[i], charsPosY[i]));
    1672                 :            :             }
    1673                 :            : 
    1674         [ #  # ]:          0 :             XForm transform;
    1675         [ #  # ]:          0 :             if( hasMatrix ) {
    1676         [ #  # ]:          0 :                 rMF >> transform;
    1677                 :            :                 EMFP_DEBUG (printf ("EMF+\tmatrix:: %f, %f, %f, %f, %f, %f\n", transform.eM11, transform.eM12, transform.eM21, transform.eM22, transform.eDx, transform.eDy));
    1678                 :            :             }
    1679                 :            : 
    1680                 :            :             // add the text action
    1681         [ #  # ]:          0 :             setFont (flags & 0xff, rFactoryParms, rState);
    1682                 :            : 
    1683         [ #  # ]:          0 :             if( flags & 0x8000 )
    1684 [ #  # ][ #  # ]:          0 :                 SET_TEXT_COLOR(brushIndexOrColor);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1685                 :            : 
    1686                 :            :             ActionSharedPtr pTextAction(
    1687                 :            :                 TextActionFactory::createTextAction(
    1688                 :          0 :                 ::vcl::unotools::pointFromB2DPoint ( Map( charsPosX[0], charsPosY[0] ) ),
    1689                 :            :                 ::Size(),
    1690                 :            :                 ::Color(),
    1691                 :            :                 ::Size(),
    1692                 :            :                 ::Color(),
    1693                 :            :                 text,
    1694                 :            :                 0,
    1695                 :            :                 glyphsCount,
    1696                 :            :                 NULL,
    1697                 :            :                 rFactoryParms.mrVDev,
    1698                 :            :                 rFactoryParms.mrCanvas,
    1699                 :            :                 rState,
    1700                 :            :                 rFactoryParms.mrParms,
    1701 [ #  # ][ #  # ]:          0 :                 false ) );
           [ #  #  #  # ]
    1702                 :            : 
    1703         [ #  # ]:          0 :             if( pTextAction )
    1704                 :            :             {
    1705                 :            :                 EMFP_DEBUG (printf ("EMF+\t\tadd text action\n"));
    1706                 :            : 
    1707                 :            :                 maActions.push_back(
    1708                 :            :                 MtfAction(
    1709                 :            :                     pTextAction,
    1710 [ #  # ][ #  # ]:          0 :                     rFactoryParms.mrCurrActionIndex ) );
                 [ #  # ]
    1711                 :            : 
    1712         [ #  # ]:          0 :                 rFactoryParms.mrCurrActionIndex += pTextAction->getActionCount()-1;
    1713                 :            :             }
    1714                 :            : 
    1715         [ #  # ]:          0 :             delete[] charsPosX;
    1716 [ #  # ][ #  # ]:          0 :             delete[] charsPosY;
    1717                 :            :             } else {
    1718                 :            :             EMFP_DEBUG (printf ("EMF+\tTODO: fonts (non-unicode glyphs chars)\n"));
    1719                 :            :             }
    1720                 :            : 
    1721                 :            :                     break;
    1722                 :            :         }
    1723                 :            :                 default:
    1724                 :            :                     EMFP_DEBUG (printf ("EMF+ unhandled record type: %d\n", type));
    1725                 :            :                     EMFP_DEBUG (printf ("EMF+\tTODO\n"));
    1726                 :            :                 }
    1727                 :            : 
    1728         [ #  # ]:          0 :                 rMF.Seek (next);
    1729                 :            : 
    1730                 :          0 :                 length -= size;
    1731         [ #  # ]:          0 :             }
    1732                 :          0 :         }
    1733                 :            :     }
    1734                 :            : }
    1735                 :            : 
    1736                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10