LCOV - code coverage report
Current view: top level - filter/source/graphicfilter/ipict - ipict.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 664 915 72.6 %
Date: 2014-11-03 Functions: 42 45 93.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <string.h>
      21             : #include <osl/thread.h>
      22             : #include <vcl/bmpacc.hxx>
      23             : #include <vcl/graph.hxx>
      24             : #include <tools/poly.hxx>
      25             : #include <vcl/virdev.hxx>
      26             : #include <math.h>
      27             : 
      28             : #include "ipict.hxx"
      29             : #include "shape.hxx"
      30             : #include <boost/scoped_array.hpp>
      31             : 
      32             : class FilterConfigItem;
      33             : 
      34             : namespace PictReaderInternal {
      35             :   //! utilitary class to store a pattern, ...
      36             :   class Pattern {
      37             :   public:
      38             :     //! constructor
      39         786 :     Pattern() {
      40         786 :       isColor = false; isRead = false;
      41         786 :       penStyle=PEN_SOLID; brushStyle = BRUSH_SOLID;
      42         786 :       nBitCount = 64;
      43         786 :     }
      44             : 
      45             :     //! reads black/white pattern from SvStream
      46             :     sal_uLong read(SvStream &stream);
      47             :     //! sets the color
      48           0 :     void setColor(Color &col) { isColor = true; color = col; }
      49             :     /** returns a color which can be "used" to replace the pattern,
      50             :      *     created from ForeColor and BackColor, ...
      51             :      *
      52             :      * note: maybe, we must also use some mode PatCopy, ... to define the color
      53             :      */
      54          18 :     Color getColor(Color bkColor=COL_WHITE, Color fgColor = COL_BLACK) const {
      55          18 :       if (isColor) return color;
      56             :       // we create a gray pattern from nBitCount
      57          18 :       double alpha = nBitCount / 64.0;
      58          18 :       return Color(sal_uInt8(alpha*fgColor.GetRed()+(1.0-alpha)*bkColor.GetRed()),
      59          18 :            sal_uInt8(alpha*fgColor.GetGreen()+(1.0-alpha)*bkColor.GetGreen()),
      60          54 :            sal_uInt8(alpha*fgColor.GetBlue()+(1.0-alpha)*bkColor.GetBlue()));
      61             :     }
      62             : 
      63             :     //! returns true if this is the default pattern
      64         648 :     bool isDefault() const { return isRead == false; }
      65             : 
      66             :     enum PenStyle { PEN_NULL, PEN_SOLID, PEN_DOT, PEN_DASH, PEN_DASHDOT };
      67             :     enum BrushStyle { BRUSH_NULL, BRUSH_SOLID, BRUSH_HORZ, BRUSH_VERT,
      68             :               BRUSH_CROSS, BRUSH_DIAGCROSS, BRUSH_UPDIAG, BRUSH_DOWNDIAG,
      69             :               BRUSH_25, BRUSH_50, BRUSH_75,
      70             :               BRUSH_BITMAP };
      71             :     // Data
      72             :     enum PenStyle penStyle;
      73             :     enum BrushStyle brushStyle;
      74             :     short nBitCount;
      75             : 
      76             :     bool isColor; // true if it is a color pattern
      77             :     Color color;
      78             : 
      79             :   protected:
      80             :     // flag to know if the pattern came from reading the picture, or if it is the default pattern
      81             :     bool isRead;
      82             :   };
      83             : 
      84          10 :   sal_uLong Pattern::read(SvStream &stream) {
      85             :     short nx,ny;
      86             :     unsigned char nbyte[8];
      87             :     sal_uLong nHiBytes, nLoBytes;
      88          10 :     isColor = false;
      89             : 
      90             :     // count the no of bits in pattern which are set to 1:
      91          10 :     nBitCount=0;
      92          90 :     for (ny=0; ny<8; ny++) {
      93          80 :       stream.ReadChar( reinterpret_cast<char&>(nbyte[ny]) );
      94         720 :       for (nx=0; nx<8; nx++) {
      95         640 :     if ( (nbyte[ny] & (1<<nx)) != 0 ) nBitCount++;
      96             :       }
      97             :     }
      98             : 
      99             :     // store pattern in 2 long words:
     100          20 :     nHiBytes=(((((((sal_uLong)nbyte[0])<<8)|
     101          30 :          (sal_uLong)nbyte[1])<<8)|
     102          30 :            (sal_uLong)nbyte[2])<<8)|
     103          20 :       (sal_uLong)nbyte[3];
     104          20 :     nLoBytes=(((((((sal_uLong)nbyte[4])<<8)|
     105          30 :          (sal_uLong)nbyte[5])<<8)|
     106          30 :            (sal_uLong)nbyte[6])<<8)|
     107          20 :       (sal_uLong)nbyte[7];
     108             : 
     109             :     // create a PenStyle:
     110          10 :     if      (nBitCount<=0)  penStyle=PEN_NULL;
     111           2 :     else if (nBitCount<=16) penStyle=PEN_DOT;
     112           2 :     else if (nBitCount<=32) penStyle=PEN_DASHDOT;
     113           2 :     else if (nBitCount<=48) penStyle=PEN_DASH;
     114           2 :     else                    penStyle=PEN_SOLID;
     115             : 
     116             :     // create a BrushStyle:
     117          10 :     if      (nHiBytes==0xffffffff && nLoBytes==0xffffffff) brushStyle=BRUSH_SOLID;
     118           8 :     else if (nHiBytes==0xff000000 && nLoBytes==0x00000000) brushStyle=BRUSH_HORZ;
     119           8 :     else if (nHiBytes==0x80808080 && nLoBytes==0x80808080) brushStyle=BRUSH_VERT;
     120           8 :     else if (nHiBytes==0xff808080 && nLoBytes==0x80808080) brushStyle=BRUSH_CROSS;
     121           8 :     else if (nHiBytes==0x01824428 && nLoBytes==0x10284482) brushStyle=BRUSH_DIAGCROSS;
     122           8 :     else if (nHiBytes==0x80402010 && nLoBytes==0x08040201) brushStyle=BRUSH_UPDIAG;
     123           8 :     else if (nHiBytes==0x01020408 && nLoBytes==0x10204080) brushStyle=BRUSH_DOWNDIAG;
     124           8 :     else if (nBitCount<=24) brushStyle=BRUSH_25;
     125           0 :     else if (nBitCount<=40) brushStyle=BRUSH_50;
     126           0 :     else if (nBitCount<=56) brushStyle=BRUSH_75;
     127           0 :     else                    brushStyle=BRUSH_SOLID;
     128             : 
     129          10 :     isRead = true;
     130             : 
     131          10 :     return 8;
     132             :   }
     133             : }
     134             : 
     135             : //============================ PictReader ==================================
     136             : 
     137             : enum PictDrawingMethod {
     138             :     PDM_FRAME, PDM_PAINT, PDM_ERASE, PDM_INVERT, PDM_FILL,
     139             :     PDM_TEXT, PDM_UNDEFINED
     140             : };
     141             : 
     142         262 : class PictReader {
     143             :   typedef class PictReaderInternal::Pattern Pattern;
     144             : private:
     145             : 
     146             :     SvStream    * pPict;             // The Pict file to read.
     147             :     VirtualDevice * pVirDev;         // Here the drawing methos will be called.
     148             :                                      // A recording into the GDIMetaFile will take place.
     149             : 
     150             :     sal_uLong     nOrigPos;          // Initial position in pPict.
     151             :     sal_uInt16    nOrigNumberFormat; // Initial number format von pPict.
     152             :     bool      IsVersion2;        // If it is a version 2 Pictfile.
     153             :     Rectangle     aBoundingRect;     // Min/Max-Rectangle for the whole drawing.
     154             : 
     155             :     Point         aPenPosition;
     156             :     Point         aTextPosition;
     157             :     Color         aActForeColor;
     158             :     Color         aActBackColor;
     159             :     Pattern       eActPenPattern;
     160             :     Pattern       eActFillPattern;
     161             :     Pattern       eActBackPattern;
     162             :     Size          nActPenSize;
     163             :  // Note: Postscript mode is stored by setting eActRop to ROP_1
     164             :     RasterOp      eActROP;
     165             :     PictDrawingMethod eActMethod;
     166             :     Size          aActOvalSize;
     167             :     vcl::Font     aActFont;
     168             : 
     169             :     Fraction        aHRes;
     170             :     Fraction        aVRes;
     171             : 
     172             :     bool Callback(sal_uInt16 nPercent);
     173             : 
     174             :     Point ReadPoint();
     175             : 
     176             :     Point ReadDeltaH(Point aBase);
     177             :     Point ReadDeltaV(Point aBase);
     178             : 
     179             :     Point ReadUnsignedDeltaH(Point aBase);
     180             :     Point ReadUnsignedDeltaV(Point aBase);
     181             : 
     182             :     Size ReadSize();
     183             : 
     184             :     Color ReadColor();
     185             : 
     186             :     Color ReadRGBColor();
     187             : 
     188             :     void ReadRectangle(Rectangle & rRect);
     189             : 
     190             :     sal_uLong ReadPolygon(Polygon & rPoly);
     191             : 
     192             :     sal_uLong ReadPixPattern(Pattern &pattern);
     193             : 
     194             :     Rectangle aLastRect;
     195             :     sal_uLong ReadAndDrawRect(PictDrawingMethod eMethod);
     196             :     sal_uLong ReadAndDrawSameRect(PictDrawingMethod eMethod);
     197             : 
     198             :     Rectangle aLastRoundRect;
     199             :     sal_uLong ReadAndDrawRoundRect(PictDrawingMethod eMethod);
     200             :     sal_uLong ReadAndDrawSameRoundRect(PictDrawingMethod eMethod);
     201             : 
     202             :     Rectangle aLastOval;
     203             :     sal_uLong ReadAndDrawOval(PictDrawingMethod eMethod);
     204             :     sal_uLong ReadAndDrawSameOval(PictDrawingMethod eMethod);
     205             : 
     206             :     Polygon aLastPolygon;
     207             :     sal_uLong ReadAndDrawPolygon(PictDrawingMethod eMethod);
     208             :     sal_uLong ReadAndDrawSamePolygon(PictDrawingMethod eMethod);
     209             : 
     210             :     Rectangle aLastArcRect;
     211             :     sal_uLong ReadAndDrawArc(PictDrawingMethod eMethod);
     212             :     sal_uLong ReadAndDrawSameArc(PictDrawingMethod eMethod);
     213             : 
     214             :     sal_uLong ReadAndDrawRgn(PictDrawingMethod eMethod);
     215             :     sal_uLong ReadAndDrawSameRgn(PictDrawingMethod eMethod);
     216             : 
     217             :         // returns true, if we do not need to print the shape/text/frame
     218        4212 :         bool IsInvisible(PictDrawingMethod eMethod) const {
     219        4212 :       if (eActROP == ROP_1) return true;
     220        3980 :       if (eMethod==PDM_FRAME && (nActPenSize.Width() == 0 || nActPenSize.Height() == 0)) return true;
     221        3800 :       return false;
     222             :     }
     223             :     void DrawingMethod(PictDrawingMethod eMethod);
     224             : 
     225             :     sal_uLong ReadAndDrawText();
     226             : 
     227             :     sal_uLong ReadPixMapEtc(Bitmap & rBitmap, bool bBaseAddr, bool bColorTable,
     228             :                         Rectangle * pSrcRect, Rectangle * pDestRect,
     229             :                         bool bMode, bool bMaskRgn);
     230             : 
     231             :     void ReadHeader();
     232             :         // Reads the header of the Pict file, set IsVersion and aBoundingRect
     233             : 
     234             :     sal_uLong ReadData(sal_uInt16 nOpcode);
     235             :         // Reads the date of anOopcode and executes the operation.
     236             :         // The number of data bytes belonging to the opcode will be returned
     237             :         // in any case.
     238             : 
     239             :     void SetLineColor( const Color& rColor );
     240             :     void SetFillColor( const Color& rColor );
     241             : 
     242             :   // OSNOLA: returns the text encoding which must be used for system id
     243             :   static rtl_TextEncoding GetTextEncoding (sal_uInt16 fId = 0xFFFF);
     244             : public:
     245             : 
     246         262 :     PictReader()
     247             :         : pPict(NULL)
     248             :         , pVirDev(NULL)
     249             :         , nOrigPos(0)
     250             :         , nOrigNumberFormat(0)
     251             :         , IsVersion2(false)
     252             :         , eActROP(ROP_OVERPAINT)
     253         262 :         , eActMethod(PDM_UNDEFINED)
     254             :     {
     255         262 :         aActFont.SetCharSet(GetTextEncoding());
     256         262 :     }
     257             : 
     258             :     void ReadPict( SvStream & rStreamPict, GDIMetaFile & rGDIMetaFile );
     259             :         // reads a pict file from the stream and fills the GDIMetaFile
     260             : 
     261             : };
     262             : 
     263             : 
     264             : 
     265             : #define SETBYTE                                         \
     266             :     switch ( nPixelSize )                               \
     267             :     {                                                   \
     268             :         case 1 :                                        \
     269             :             pAcc->SetPixelIndex( ny, nx++, nDat >> 7 ); \
     270             :             if ( nx == nWidth ) break;                  \
     271             :             pAcc->SetPixelIndex( ny, nx++, nDat >> 6 ); \
     272             :             if ( nx == nWidth ) break;                  \
     273             :             pAcc->SetPixelIndex( ny, nx++, nDat >> 5 ); \
     274             :             if ( nx == nWidth ) break;                  \
     275             :             pAcc->SetPixelIndex( ny, nx++, nDat >> 4 ); \
     276             :             if ( nx == nWidth ) break;                  \
     277             :             pAcc->SetPixelIndex( ny, nx++, nDat >> 3 ); \
     278             :             if ( nx == nWidth ) break;                  \
     279             :             pAcc->SetPixelIndex( ny, nx++, nDat >> 2 ); \
     280             :             if ( nx == nWidth ) break;                  \
     281             :             pAcc->SetPixelIndex( ny, nx++, nDat >> 1 ); \
     282             :             if ( nx == nWidth ) break;                  \
     283             :             pAcc->SetPixelIndex( ny, nx++, nDat );      \
     284             :             break;                                      \
     285             :         case 2 :                                        \
     286             :             pAcc->SetPixelIndex( ny, nx++, nDat >> 6 ); \
     287             :             if ( nx == nWidth ) break;                  \
     288             :             pAcc->SetPixelIndex( ny, nx++, (nDat>>4)&3);\
     289             :             if ( nx == nWidth ) break;                  \
     290             :             pAcc->SetPixelIndex( ny, nx++, (nDat>>2)&3 );\
     291             :             if ( nx == nWidth ) break;                  \
     292             :             pAcc->SetPixelIndex( ny, nx++, nDat & 3);       \
     293             :             break;                                      \
     294             :         case 4 :                                        \
     295             :             pAcc->SetPixelIndex( ny, nx++, nDat >> 4 ); \
     296             :             if ( nx == nWidth ) break;                  \
     297             :             pAcc->SetPixelIndex( ny, nx++, nDat );      \
     298             :             break;                                      \
     299             :         case 8 :                                        \
     300             :             pAcc->SetPixelIndex( ny, nx++, nDat );      \
     301             :             break;                                      \
     302             :     }
     303             : 
     304             : 
     305             : 
     306             : #define BITMAPERROR                                     \
     307             : {                                                       \
     308             :     if ( pAcc )                                         \
     309             :         aBitmap.ReleaseAccess( pAcc );                  \
     310             :     if ( pReadAcc )                                     \
     311             :         aBitmap.ReleaseAccess( pReadAcc );              \
     312             :     return 0xffffffff;                                  \
     313             : }
     314             : 
     315             : //=================== methods of PictReader ==============================
     316        1610 : rtl_TextEncoding PictReader::GetTextEncoding (sal_uInt16 fId) {
     317             :   static bool first = true;
     318             :   static rtl_TextEncoding enc = RTL_TEXTENCODING_APPLE_ROMAN;
     319        1610 :   if (first) {
     320           4 :     rtl_TextEncoding def = osl_getThreadTextEncoding();
     321             :     // we keep osl_getThreadTextEncoding only if it is a mac encoding
     322           4 :     switch(def) {
     323             :     case RTL_TEXTENCODING_APPLE_ROMAN:
     324             :     case RTL_TEXTENCODING_APPLE_ARABIC:
     325             :     case RTL_TEXTENCODING_APPLE_CENTEURO:
     326             :     case RTL_TEXTENCODING_APPLE_CROATIAN:
     327             :     case RTL_TEXTENCODING_APPLE_CYRILLIC:
     328             :     case RTL_TEXTENCODING_APPLE_DEVANAGARI:
     329             :     case RTL_TEXTENCODING_APPLE_FARSI:
     330             :     case RTL_TEXTENCODING_APPLE_GREEK:
     331             :     case RTL_TEXTENCODING_APPLE_GUJARATI:
     332             :     case RTL_TEXTENCODING_APPLE_GURMUKHI:
     333             :     case RTL_TEXTENCODING_APPLE_HEBREW:
     334             :     case RTL_TEXTENCODING_APPLE_ICELAND:
     335             :     case RTL_TEXTENCODING_APPLE_ROMANIAN:
     336             :     case RTL_TEXTENCODING_APPLE_THAI:
     337             :     case RTL_TEXTENCODING_APPLE_TURKISH:
     338             :     case RTL_TEXTENCODING_APPLE_UKRAINIAN:
     339             :     case RTL_TEXTENCODING_APPLE_CHINSIMP:
     340             :     case RTL_TEXTENCODING_APPLE_CHINTRAD:
     341             :     case RTL_TEXTENCODING_APPLE_JAPANESE:
     342             :     case RTL_TEXTENCODING_APPLE_KOREAN:
     343           0 :       enc = def; break;
     344           4 :     default: break;
     345             :     }
     346           4 :     first = false;
     347             :   }
     348        1610 :   if (fId == 13) return RTL_TEXTENCODING_ADOBE_DINGBATS; // CHECKME
     349        1610 :   if (fId == 23) return RTL_TEXTENCODING_ADOBE_SYMBOL;
     350        1192 :   return enc;
     351             : }
     352             : 
     353         648 : void PictReader::SetLineColor( const Color& rColor )
     354             : {
     355         648 :     pVirDev->SetLineColor( rColor );
     356         648 : }
     357             : 
     358         648 : void PictReader::SetFillColor( const Color& rColor )
     359             : {
     360         648 :     pVirDev->SetFillColor( rColor );
     361         648 : }
     362             : 
     363        2112 : bool PictReader::Callback(sal_uInt16 /*nPercent*/)
     364             : {
     365        2112 :     return false;
     366             : }
     367             : 
     368        5716 : Point PictReader::ReadPoint()
     369             : {
     370             :     short nx,ny;
     371             : 
     372        5716 :     pPict->ReadInt16( ny ).ReadInt16( nx );
     373             : 
     374        5716 :    Point aPoint( (long)nx - aBoundingRect.Left(),
     375       11432 :                  (long)ny - aBoundingRect.Top() );
     376             : 
     377             :    SAL_INFO("filter.pict", "ReadPoint: " << aPoint);
     378        5716 :    return aPoint;
     379             : }
     380             : 
     381         976 : Point PictReader::ReadDeltaH(Point aBase)
     382             : {
     383             :     signed char ndh;
     384             : 
     385         976 :     pPict->ReadChar( reinterpret_cast<char&>(ndh) );
     386             : 
     387         976 :     return Point( aBase.X() + (long)ndh, aBase.Y() );
     388             : }
     389             : 
     390         976 : Point PictReader::ReadDeltaV(Point aBase)
     391             : {
     392             :     signed char ndv;
     393             : 
     394         976 :     pPict->ReadChar( reinterpret_cast<char&>(ndv) );
     395             : 
     396         976 :     return Point( aBase.X(), aBase.Y() + (long)ndv );
     397             : }
     398             : 
     399        1764 : Point PictReader::ReadUnsignedDeltaH(Point aBase)
     400             : {
     401             :     sal_uInt8 ndh;
     402             : 
     403        1764 :     pPict->ReadUChar( ndh );
     404             : 
     405        1764 :     return Point( aBase.X() + (long)ndh, aBase.Y() );
     406             : }
     407             : 
     408         578 : Point PictReader::ReadUnsignedDeltaV(Point aBase)
     409             : {
     410             :     sal_uInt8 ndv;
     411             : 
     412         578 :     pPict->ReadUChar( ndv );
     413             : 
     414         578 :     return Point( aBase.X(), aBase.Y() + (long)ndv );
     415             : }
     416             : 
     417         208 : Size PictReader::ReadSize()
     418             : {
     419             :     short nx,ny;
     420             : 
     421         208 :     pPict->ReadInt16( ny ).ReadInt16( nx );
     422             : 
     423         208 :     return Size( (long)nx, (long)ny );
     424             : }
     425             : 
     426           0 : Color PictReader::ReadColor()
     427             : {
     428             :     sal_uInt32 nCol;
     429           0 :     Color aCol;
     430             : 
     431           0 :     pPict->ReadUInt32( nCol );
     432           0 :     switch (nCol)
     433             :     {
     434           0 :         case  33: aCol=Color( COL_BLACK );        break;
     435           0 :         case  30: aCol=Color( COL_WHITE );        break;
     436           0 :         case 205: aCol=Color( COL_LIGHTRED );     break;
     437           0 :         case 341: aCol=Color( COL_LIGHTGREEN );   break;
     438           0 :         case 409: aCol=Color( COL_LIGHTBLUE );    break;
     439           0 :         case 273: aCol=Color( COL_LIGHTCYAN );    break;
     440           0 :         case 137: aCol=Color( COL_LIGHTMAGENTA ); break;
     441           0 :         case  69: aCol=Color( COL_YELLOW );       break;
     442           0 :         default:  aCol=Color( COL_LIGHTGRAY );
     443             :     }
     444           0 :     return aCol;
     445             : }
     446             : 
     447             : 
     448          60 : Color PictReader::ReadRGBColor()
     449             : {
     450             :     sal_uInt16 nR, nG, nB;
     451             : 
     452          60 :     pPict->ReadUInt16( nR ).ReadUInt16( nG ).ReadUInt16( nB );
     453          60 :     return Color( (sal_uInt8) ( nR >> 8 ), (sal_uInt8) ( nG >> 8 ), (sal_uInt8) ( nB >> 8 ) );
     454             : }
     455             : 
     456             : 
     457         438 : void PictReader::ReadRectangle(Rectangle & rRect)
     458             : {
     459         438 :     Point aTopLeft, aBottomRight;
     460             : 
     461         438 :     aTopLeft=ReadPoint();
     462         438 :     aBottomRight=ReadPoint();
     463         438 :     rRect=Rectangle(aTopLeft,aBottomRight);
     464             : 
     465             :     SAL_INFO("filter.pict", "ReadRectangle: " << rRect);
     466         438 : }
     467             : 
     468             : 
     469         138 : sal_uLong PictReader::ReadPolygon(Polygon & rPoly)
     470             : {
     471             :     sal_uInt16 nSize,i;
     472             :     sal_uLong nDataSize;
     473             : 
     474         138 :     pPict->ReadUInt16( nSize );
     475         138 :     pPict->SeekRel(8);
     476         138 :     nDataSize=(sal_uLong)nSize;
     477         138 :     nSize=(nSize-10)/4;
     478         138 :     rPoly.SetSize(nSize);
     479         138 :     for (i=0; i<nSize; i++) rPoly.SetPoint(ReadPoint(),i);
     480         138 :     return nDataSize;
     481             : }
     482             : 
     483           0 : sal_uLong PictReader::ReadPixPattern(PictReader::Pattern &pattern)
     484             : {
     485             :     // Don't know if this is correct because no picture which contains PixPatterns found.
     486             :     // Here again the attempt to calculate the size of the date to create simple StarView-Styles
     487             :     // from them. Luckily a PixPattern always contains a normal pattern.
     488             : 
     489             : 
     490             :     sal_uLong nDataSize;
     491             :     sal_uInt16 nPatType;
     492           0 :     Bitmap aBMP;
     493             : 
     494           0 :     pPict->ReadUInt16( nPatType );
     495           0 :     if (nPatType==1) {
     496           0 :             pattern.read(*pPict);
     497           0 :         nDataSize=ReadPixMapEtc(aBMP,false,true,NULL,NULL,false,false);
     498             :         // CHANGEME: use average pixmap colors to update the pattern, ...
     499           0 :         if (nDataSize!=0xffffffff) nDataSize+=10;
     500             :     }
     501           0 :     else if (nPatType==2) {
     502           0 :             pattern.read(*pPict);
     503             :         // RGBColor
     504             :         sal_uInt16 nR, nG, nB;
     505           0 :         pPict->ReadUInt16( nR ).ReadUInt16( nG ).ReadUInt16( nB );
     506           0 :         Color col((sal_uInt8) ( nR >> 8 ), (sal_uInt8) ( nG >> 8 ), (sal_uInt8) ( nB >> 8 ) );
     507           0 :         pattern.setColor(col);
     508           0 :         nDataSize=16;
     509             :     }
     510           0 :     else nDataSize=0xffffffff;
     511             : 
     512           0 :     return nDataSize;
     513             : }
     514             : 
     515          44 : sal_uLong PictReader::ReadAndDrawRect(PictDrawingMethod eMethod)
     516             : {
     517          44 :     ReadRectangle(aLastRect);
     518          44 :     ReadAndDrawSameRect(eMethod);
     519          44 :     return 8;
     520             : }
     521             : 
     522          78 : sal_uLong PictReader::ReadAndDrawSameRect(PictDrawingMethod eMethod)
     523             : {
     524          78 :     if (IsInvisible(eMethod)) return 0;
     525          78 :     DrawingMethod(eMethod);
     526          78 :     PictReaderShape::drawRectangle(pVirDev, eMethod==PDM_FRAME, aLastRect, nActPenSize);
     527          78 :     return 0;
     528             : }
     529             : 
     530           2 : sal_uLong PictReader::ReadAndDrawRoundRect(PictDrawingMethod eMethod)
     531             : {
     532           2 :     ReadRectangle(aLastRoundRect);
     533           2 :     ReadAndDrawSameRoundRect(eMethod);
     534           2 :     return 8;
     535             : }
     536             : 
     537           4 : sal_uLong PictReader::ReadAndDrawSameRoundRect(PictDrawingMethod eMethod)
     538             : {
     539           4 :     if (IsInvisible(eMethod)) return 0;
     540           4 :     DrawingMethod(eMethod);
     541           4 :     PictReaderShape::drawRoundRectangle(pVirDev, eMethod==PDM_FRAME, aLastRoundRect, aActOvalSize, nActPenSize);
     542           4 :     return 0;
     543             : }
     544             : 
     545           2 : sal_uLong PictReader::ReadAndDrawOval(PictDrawingMethod eMethod)
     546             : {
     547           2 :     ReadRectangle(aLastOval);
     548           2 :     ReadAndDrawSameOval(eMethod);
     549           2 :     return 8;
     550             : }
     551             : 
     552           4 : sal_uLong PictReader::ReadAndDrawSameOval(PictDrawingMethod eMethod)
     553             : {
     554           4 :     if (IsInvisible(eMethod)) return 0;
     555           4 :     DrawingMethod(eMethod);
     556           4 :     PictReaderShape::drawEllipse(pVirDev, eMethod==PDM_FRAME, aLastOval, nActPenSize);
     557           4 :     return 0;
     558             : }
     559             : 
     560         138 : sal_uLong PictReader::ReadAndDrawPolygon(PictDrawingMethod eMethod)
     561             : {
     562             :     sal_uLong nDataSize;
     563         138 :     nDataSize=ReadPolygon(aLastPolygon);
     564         138 :     ReadAndDrawSamePolygon(eMethod);
     565         138 :     return nDataSize;
     566             : }
     567             : 
     568         138 : sal_uLong PictReader::ReadAndDrawSamePolygon(PictDrawingMethod eMethod)
     569             : {
     570         138 :     if (IsInvisible(eMethod)) return 0;
     571         138 :     DrawingMethod(eMethod);
     572         138 :     PictReaderShape::drawPolygon(pVirDev, eMethod==PDM_FRAME, aLastPolygon, nActPenSize);
     573         138 :     return 0;
     574             : }
     575             : 
     576             : 
     577          48 : sal_uLong PictReader::ReadAndDrawArc(PictDrawingMethod eMethod)
     578             : {
     579          48 :     ReadRectangle(aLastArcRect);
     580          48 :     ReadAndDrawSameArc(eMethod);
     581          48 :     return 12;
     582             : }
     583             : 
     584          48 : sal_uLong PictReader::ReadAndDrawSameArc(PictDrawingMethod eMethod)
     585             : {
     586             :     short nstartAngle, narcAngle;
     587             :     double fAng1, fAng2;
     588             : 
     589          48 :     pPict->ReadInt16( nstartAngle ).ReadInt16( narcAngle );
     590          48 :     if (IsInvisible(eMethod)) return 4;
     591          48 :     DrawingMethod(eMethod);
     592             : 
     593          48 :     if (narcAngle<0) {
     594           0 :         nstartAngle = nstartAngle + narcAngle;
     595           0 :         narcAngle=-narcAngle;
     596             :     }
     597          48 :     fAng1=((double)nstartAngle)/180.0*3.14159265359;
     598          48 :     fAng2=((double)(nstartAngle+narcAngle))/180.0*3.14159265359;
     599          48 :     PictReaderShape::drawArc(pVirDev, eMethod==PDM_FRAME, aLastArcRect,fAng1,fAng2, nActPenSize);
     600          48 :     return 4;
     601             : }
     602             : 
     603           8 : sal_uLong PictReader::ReadAndDrawRgn(PictDrawingMethod eMethod)
     604             : {
     605             :     sal_uInt16 nSize;
     606             : 
     607           8 :     pPict->ReadUInt16( nSize );
     608             :     // read the DATA
     609             :     //
     610             :     // a region data is a mask and is probably coded as
     611             :     // - the first 8 bytes: bdbox ( which can be read by ReadRectangle )
     612             :     // - then a list of line modifiers: y_i, a_0, b_0, a_1, b_1, ..., a_{n_i}, b_{n_i}, 0x7fff
     613             :     // - 0x7fff
     614             :     // where y_i is the increasing sequences of line coordinates
     615             :     // and on each line: a0 < b0 < a1 < b1 < ... < a_{n_i} < b_{n_i}
     616             : 
     617             :     // it can be probably decoded as :
     618             :     // M=an empty mask: ie. (0, 0, ... ) with (left_box-right_box+1) zeroes
     619             :     // then for each line (y_i):
     620             :     //   - takes M and inverts all values in [a_0,b_0-1], in [a_1,b_1-1] ...
     621             :     //   - sets M = new y_i line mask
     622           8 :     ReadAndDrawSameRgn(eMethod);
     623           8 :     return (sal_uLong)nSize;
     624             : }
     625             : 
     626           8 : sal_uLong PictReader::ReadAndDrawSameRgn(PictDrawingMethod eMethod)
     627             : {
     628           8 :     if (IsInvisible(eMethod)) return 0;
     629           0 :     DrawingMethod(eMethod);
     630             :     // DISPLAY: ...???...
     631           0 :     return 0;
     632             : }
     633             : 
     634        3826 : void PictReader::DrawingMethod(PictDrawingMethod eMethod)
     635             : {
     636        7652 :     if( eActMethod==eMethod ) return;
     637        2124 :     switch (eMethod) {
     638             :         case PDM_FRAME:
     639         444 :                 if (eActPenPattern.isDefault())
     640         438 :               SetLineColor( aActForeColor );
     641             :             else
     642           6 :               SetLineColor(eActPenPattern.getColor(aActBackColor, aActForeColor));
     643         444 :             SetFillColor( Color(COL_TRANSPARENT) );
     644         444 :             pVirDev->SetRasterOp(eActROP);
     645         444 :             break;
     646             :         case PDM_PAINT:
     647         132 :             SetLineColor( Color(COL_TRANSPARENT) );
     648         132 :             if (eActPenPattern.isDefault())
     649         126 :               SetFillColor( aActForeColor );
     650             :             else
     651           6 :               SetFillColor(eActPenPattern.getColor(aActBackColor, aActForeColor));
     652         132 :             pVirDev->SetRasterOp(eActROP);
     653         132 :             break;
     654             :         case PDM_ERASE:
     655          66 :             SetLineColor( Color(COL_TRANSPARENT) );
     656          66 :             if (eActBackPattern.isDefault())
     657          66 :               SetFillColor( aActBackColor );// Osnola: previously aActForeColor
     658             :             else // checkMe
     659           0 :               SetFillColor(eActBackPattern.getColor(COL_BLACK, aActBackColor));
     660          66 :             pVirDev->SetRasterOp(ROP_OVERPAINT);
     661          66 :             break;
     662             :             case PDM_INVERT: // checkme
     663           0 :             SetLineColor( Color(COL_TRANSPARENT));
     664           0 :             SetFillColor( Color( COL_BLACK ) );
     665           0 :             pVirDev->SetRasterOp(ROP_INVERT);
     666           0 :             break;
     667             :         case PDM_FILL:
     668           6 :             SetLineColor( Color(COL_TRANSPARENT) );
     669           6 :             if (eActFillPattern.isDefault())
     670           0 :               SetFillColor( aActForeColor );
     671             :             else
     672           6 :               SetFillColor(eActFillPattern.getColor(aActBackColor, aActForeColor));
     673           6 :             pVirDev->SetRasterOp(ROP_OVERPAINT);
     674           6 :             break;
     675             :         case PDM_TEXT:
     676        1476 :             aActFont.SetColor(aActForeColor);
     677        1476 :             aActFont.SetFillColor(aActBackColor);
     678        1476 :             aActFont.SetTransparent(true);
     679        1476 :             pVirDev->SetFont(aActFont);
     680        1476 :             pVirDev->SetRasterOp(ROP_OVERPAINT);
     681        1476 :             break;
     682             :         default:
     683           0 :             break;  // -Wall undefined not handled...
     684             :     }
     685        2124 :     eActMethod=eMethod;
     686             : }
     687             : 
     688        2794 : sal_uLong PictReader::ReadAndDrawText()
     689             : {
     690             :     char        nByteLen;
     691             :     sal_uInt32  nLen, nDataLen;
     692             :     sal_Char    sText[256];
     693             : 
     694        2794 :     pPict->ReadChar( nByteLen ); nLen=((sal_uLong)nByteLen)&0x000000ff;
     695        2794 :     nDataLen = nLen + 1;
     696        2794 :     pPict->Read( &sText, nLen );
     697             : 
     698        2794 :     if (IsInvisible(PDM_TEXT)) return nDataLen;
     699        2794 :     DrawingMethod(PDM_TEXT);
     700             : 
     701             :     // remove annoying control characters:
     702        5588 :     while ( nLen > 0 && ( (unsigned char)sText[ nLen - 1 ] ) < 32 )
     703           0 :             nLen--;
     704        2794 :     sText[ nLen ] = 0;
     705        2794 :     OUString aString( (const sal_Char*)&sText, strlen(sText), aActFont.GetCharSet());
     706        2794 :     pVirDev->DrawText( Point( aTextPosition.X(), aTextPosition.Y() ), aString );
     707        2794 :     return nDataLen;
     708             : }
     709             : 
     710          26 : sal_uLong PictReader::ReadPixMapEtc( Bitmap &rBitmap, bool bBaseAddr, bool bColorTable, Rectangle* pSrcRect,
     711             :                                     Rectangle* pDestRect, bool bMode, bool bMaskRgn )
     712             : {
     713          26 :     Bitmap              aBitmap;
     714          26 :     BitmapWriteAccess*  pAcc = NULL;
     715          26 :     BitmapReadAccess*   pReadAcc = NULL;
     716             :     sal_uInt16              ny, nx, nColTabSize;
     717             :     sal_uInt16              nRowBytes, nBndX, nBndY, nWidth, nHeight, nVersion, nPackType, nPixelType,
     718             :                         nPixelSize, nCmpCount, nCmpSize;
     719             :     sal_uInt32          nPackSize, nPlaneBytes, nHRes, nVRes;
     720             :     sal_uInt8               nDat, nRed, nGreen, nBlue, nDummy;
     721          26 :     size_t              i, nDataSize = 0;
     722             : 
     723             :     // The calculation of nDataSize is considering the size of the whole data.
     724          26 :     nDataSize = 0;
     725             : 
     726             :     // condionally skip BaseAddr
     727          26 :     if ( bBaseAddr )
     728             :     {
     729           6 :         pPict->SeekRel( 4 );
     730           6 :         nDataSize += 4;
     731             :     }
     732             : 
     733             :     // Read PixMap or Bitmap structure;
     734          26 :     pPict->ReadUInt16( nRowBytes ).ReadUInt16( nBndY ).ReadUInt16( nBndX ).ReadUInt16( nHeight ).ReadUInt16( nWidth );
     735          26 :     nHeight = nHeight - nBndY;
     736          26 :     nWidth = nWidth - nBndX;
     737             : 
     738          26 :     if ( ( nRowBytes & 0x8000 ) != 0 )
     739             :     {   // it is a PixMap
     740           8 :         nRowBytes &= 0x3fff;
     741           8 :         pPict->ReadUInt16( nVersion ).ReadUInt16( nPackType ).ReadUInt32( nPackSize ).ReadUInt32( nHRes ).ReadUInt32( nVRes ).ReadUInt16( nPixelType ).                    ReadUInt16( nPixelSize ).ReadUInt16( nCmpCount ).ReadUInt16( nCmpSize ).ReadUInt32( nPlaneBytes );
     742             : 
     743           8 :         pPict->SeekRel( 8 );
     744           8 :         nDataSize += 46;
     745             : 
     746           8 :         sal_uInt16 nDstBitCount = nPixelSize;
     747           8 :         if ( nDstBitCount > 8 )
     748           6 :             nDstBitCount = 24;
     749           2 :         else if ( nDstBitCount == 2 )
     750           0 :             nDstBitCount = 4;
     751           8 :         aBitmap = Bitmap( Size( nWidth, nHeight ), nDstBitCount );
     752             : 
     753           8 :         if ( ( pAcc = aBitmap.AcquireWriteAccess() ) == NULL )
     754           0 :             BITMAPERROR;
     755             : 
     756           8 :         if ( bColorTable )
     757             :         {
     758           2 :             pPict->SeekRel( 6 );
     759           2 :             pPict->ReadUInt16( nColTabSize );
     760             : 
     761           2 :             if (nColTabSize > 255)
     762           0 :                 BITMAPERROR;
     763             : 
     764           2 :             ++nColTabSize;
     765             : 
     766           2 :             pAcc->SetPaletteEntryCount( nColTabSize );
     767             : 
     768         514 :             for ( i = 0; i < nColTabSize; i++ )
     769             :             {
     770         512 :                 pPict->SeekRel(2);
     771         512 :                 pPict->ReadUChar( nRed ).ReadUChar( nDummy ).ReadUChar( nGreen ).ReadUChar( nDummy ).ReadUChar( nBlue ).ReadUChar( nDummy );
     772         512 :                 pAcc->SetPaletteColor( (sal_uInt16) i, BitmapColor( nRed, nGreen, nBlue ) );
     773             :             }
     774           2 :             nDataSize += 8 + nColTabSize * 8;
     775             :         }
     776             :     }
     777             :     else
     778             :     {
     779          18 :         nRowBytes &= 0x3fff;
     780          18 :         nVersion = 0;
     781          18 :         nPackType = 0;
     782          18 :         nPackSize = nHRes = nVRes = nPlaneBytes = 0;
     783          18 :         nPixelType = 0;
     784          18 :         nPixelSize = nCmpCount = nCmpSize = 1;
     785          18 :         nDataSize += 10;
     786          18 :         aBitmap = Bitmap( Size( nWidth, nHeight ), 1 );
     787          18 :         if ( ( pAcc = aBitmap.AcquireWriteAccess() ) == NULL )
     788           0 :             BITMAPERROR;
     789          18 :         pAcc->SetPaletteEntryCount( 2 );
     790          18 :         pAcc->SetPaletteColor( 0, BitmapColor( 0xff, 0xff, 0xff ) );
     791          18 :         pAcc->SetPaletteColor( 1, BitmapColor( 0, 0, 0 ) );
     792             :     }
     793             : 
     794             :     // conditionally read source rectangle:
     795          26 :     if ( pSrcRect != 0)
     796             :     {
     797             :         sal_uInt16  nTop, nLeft, nBottom, nRight;
     798          26 :         pPict->ReadUInt16( nTop ).ReadUInt16( nLeft ).ReadUInt16( nBottom ).ReadUInt16( nRight );
     799          26 :         *pSrcRect = Rectangle( (sal_uLong)nLeft, (sal_uLong)nTop, (sal_uLong)nRight, (sal_uLong)nBottom );
     800          26 :         nDataSize += 8;
     801             :     }
     802             : 
     803             :     // conditionally read destination rectangle:
     804          26 :     if ( pDestRect != 0 )
     805             :     {
     806          26 :         Point aTL, aBR;
     807          26 :         aTL = ReadPoint();
     808          26 :         aBR = ReadPoint();
     809          26 :         *pDestRect = Rectangle( aTL, aBR );
     810          26 :         nDataSize += 8;
     811             :     }
     812             : 
     813             :     // conditionally read mode (or skip it):
     814          26 :     if ( bMode )
     815             :     {
     816          26 :         pPict->SeekRel(2);
     817          26 :         nDataSize += 2;
     818             :     }
     819             : 
     820             :     // conditionally read region (or skip it):
     821          26 :     if ( bMaskRgn )
     822             :     {
     823             :         sal_uInt16 nSize;
     824           0 :         pPict->ReadUInt16( nSize );
     825           0 :         pPict->SeekRel( nSize - 2 );
     826           0 :         nDataSize += (sal_uLong)nSize;
     827             :     }
     828             : 
     829             : //  aSMem << (nHRes/1665L) << (nVRes/1665L) << ((sal_uLong)0) << ((sal_uLong)0);
     830             : 
     831             :     // read and write Bitmap bits:
     832          26 :     if ( nPixelSize == 1 || nPixelSize == 2 || nPixelSize == 4 || nPixelSize == 8 )
     833             :     {
     834             :         sal_uInt8   nByteCountAsByte, nFlagCounterByte;
     835             :         sal_uInt16  nByteCount, nSrcBPL, nDestBPL;
     836             :         size_t nCount;
     837             : 
     838          20 :         if      ( nPixelSize == 1 ) nSrcBPL = ( nWidth + 7 ) >> 3;
     839           2 :         else if ( nPixelSize == 2 ) nSrcBPL = ( nWidth + 3 ) >> 2;
     840           2 :         else if ( nPixelSize == 4 ) nSrcBPL = ( nWidth + 1 ) >> 1;
     841           2 :         else                        nSrcBPL = nWidth;
     842          20 :         nDestBPL = ( nSrcBPL + 3 ) & 0xfffc;
     843          20 :         if ( nRowBytes < nSrcBPL || nRowBytes > nDestBPL )
     844           0 :             BITMAPERROR;
     845             : 
     846        2870 :         for ( ny = 0; ny < nHeight; ny++ )
     847             :         {
     848        2850 :             nx = 0;
     849        2850 :             if ( nRowBytes < 8 || nPackType == 1 )
     850             :             {
     851           0 :                 for ( i = 0; i < nRowBytes; i++ )
     852             :                 {
     853           0 :                     pPict->ReadUChar( nDat );
     854           0 :                     if ( nx < nWidth )
     855           0 :                         SETBYTE;
     856             :                 }
     857           0 :                 nDataSize += nRowBytes;
     858             :             }
     859             :             else
     860             :             {
     861        2850 :                 if ( nRowBytes > 250 )
     862             :                 {
     863        1970 :                     pPict->ReadUInt16( nByteCount );
     864        1970 :                     nDataSize += 2 + (sal_uLong)nByteCount;
     865             :                 }
     866             :                 else
     867             :                 {
     868         880 :                     pPict->ReadUChar( nByteCountAsByte );
     869         880 :                     nByteCount = ( (sal_uInt16)nByteCountAsByte ) & 0x00ff;
     870         880 :                     nDataSize += 1 + (sal_uLong)nByteCount;
     871             :                 }
     872             : 
     873      118590 :                 while ( nByteCount )
     874             :                 {
     875      112890 :                     pPict->ReadUChar( nFlagCounterByte );
     876      112890 :                     if ( ( nFlagCounterByte & 0x80 ) == 0 )
     877             :                     {
     878       82326 :                         nCount = ( (sal_uInt16)nFlagCounterByte ) + 1;
     879      241828 :                         for ( i = 0; i < nCount; i++ )
     880             :                         {
     881      159502 :                             pPict->ReadUChar( nDat );
     882      159502 :                             if ( nx < nWidth )
     883       16534 :                                 SETBYTE;
     884             :                         }
     885       82326 :                         nByteCount -= 1 + nCount;
     886             :                     }
     887             :                     else
     888             :                     {
     889       30564 :                         nCount = static_cast<sal_uInt16>( 1 - ( ( (sal_uInt16)nFlagCounterByte ) | 0xff00 ) );
     890       30564 :                         pPict->ReadUChar( nDat );
     891     1384132 :                         for ( i = 0; i < nCount; i++ )
     892             :                         {
     893     1353568 :                             if ( nx < nWidth )
     894      386414 :                                 SETBYTE;
     895             :                         }
     896       30564 :                         nByteCount -= 2;
     897             :                     }
     898             :                 }
     899             :             }
     900          20 :         }
     901             :     }
     902           6 :     else if ( nPixelSize == 16 )
     903             :     {
     904             :         sal_uInt8   nByteCountAsByte, nFlagCounterByte;
     905             :         sal_uInt16  nByteCount, nCount, nD;
     906             :         sal_uLong   nSrcBitsPos;
     907             : 
     908           0 :         if ( nRowBytes < 2 * nWidth )
     909           0 :             BITMAPERROR;
     910             : 
     911           0 :         for ( ny = 0; ny < nHeight; ny++ )
     912             :         {
     913           0 :             nx = 0;
     914           0 :             if ( nRowBytes < 8 || nPackType == 1 )
     915             :             {
     916           0 :                 for ( i = 0; i < nWidth; i++ )
     917             :                 {
     918           0 :                     pPict->ReadUInt16( nD );
     919           0 :                     nRed = (sal_uInt8)( nD >> 7 );
     920           0 :                     nGreen = (sal_uInt8)( nD >> 2 );
     921           0 :                     nBlue = (sal_uInt8)( nD << 3 );
     922           0 :                     pAcc->SetPixel( ny, nx++, BitmapColor( nRed, nGreen, nBlue ) );
     923             :                 }
     924           0 :                 nDataSize += ( (sal_uLong)nWidth ) * 2;
     925             :             }
     926             :             else
     927             :             {
     928           0 :                 nSrcBitsPos = pPict->Tell();
     929           0 :                 if ( nRowBytes > 250 )
     930             :                 {
     931           0 :                     pPict->ReadUInt16( nByteCount );
     932           0 :                     nByteCount += 2;
     933             :                 }
     934             :                 else
     935             :                 {
     936           0 :                     pPict->ReadUChar( nByteCountAsByte );
     937           0 :                     nByteCount = ( (sal_uInt16)nByteCountAsByte ) & 0x00ff;
     938           0 :                     nByteCount++;
     939             :                 }
     940           0 :                 while ( nx != nWidth )
     941             :                 {
     942           0 :                     pPict->ReadUChar( nFlagCounterByte );
     943           0 :                     if ( (nFlagCounterByte & 0x80) == 0)
     944             :                     {
     945           0 :                         nCount=((sal_uInt16)nFlagCounterByte)+1;
     946           0 :                         if ( nCount + nx > nWidth)              // SJ: the RLE decoding seems not to be correct here,
     947           0 :                             nCount = nWidth - nx;               // I don't want to change this until I have a bugdoc for
     948           0 :                         for (i=0; i<nCount; i++)                // this case. Have a look at 32bit, there I changed the
     949             :                         {                                       // encoding, so that it is used a straight forward array
     950           0 :                             pPict->ReadUInt16( nD );
     951           0 :                             nRed = (sal_uInt8)( nD >> 7 );
     952           0 :                             nGreen = (sal_uInt8)( nD >> 2 );
     953           0 :                             nBlue = (sal_uInt8)( nD << 3 );
     954           0 :                             pAcc->SetPixel( ny, nx++, BitmapColor( nRed, nGreen, nBlue ) );
     955             :                         }
     956             :                     }
     957             :                     else
     958             :                     {
     959           0 :                         nCount=(1-(((sal_uInt16)nFlagCounterByte)|0xff00));
     960           0 :                         if ( nCount + nx > nWidth )
     961           0 :                             nCount = nWidth - nx;
     962           0 :                         pPict->ReadUInt16( nD );
     963           0 :                         nRed = (sal_uInt8)( nD >> 7 );
     964           0 :                         nGreen = (sal_uInt8)( nD >> 2 );
     965           0 :                         nBlue = (sal_uInt8)( nD << 3 );
     966           0 :                         for (i=0; i<nCount; i++)
     967             :                         {
     968           0 :                             pAcc->SetPixel( ny, nx++, BitmapColor( nRed, nGreen, nBlue ) );
     969             :                         }
     970             :                     }
     971             :                 }
     972           0 :                 nDataSize+=(sal_uLong)nByteCount;
     973           0 :                 pPict->Seek(nSrcBitsPos+(sal_uLong)nByteCount);
     974             :             }
     975             :         }
     976             :     }
     977           6 :     else if (nPixelSize==32)
     978             :     {
     979             :         sal_uInt8               nByteCountAsByte, nFlagCounterByte;
     980             :         sal_uInt16              nByteCount;
     981             :         size_t                  nCount;
     982             :         sal_uLong               nSrcBitsPos;
     983           6 :         BitmapColor         aBitmapColor;
     984           6 :         if ( ( pReadAcc = aBitmap.AcquireReadAccess() ) == NULL )
     985           0 :             BITMAPERROR;
     986           6 :         if ( nRowBytes != 4*nWidth )
     987           2 :             BITMAPERROR;
     988             : 
     989           4 :         if ( nRowBytes < 8 || nPackType == 1 )
     990             :         {
     991           0 :             const size_t nMaxPixels = pPict->remainingSize() / 4;
     992           0 :             const size_t nMaxRows = nMaxPixels / nWidth;
     993           0 :             if (nHeight > nMaxRows)
     994           0 :                 BITMAPERROR;
     995             : 
     996           0 :             for ( ny = 0; ny < nHeight; ny++ )
     997             :             {
     998           0 :                 for ( nx = 0; nx < nWidth; nx++ )
     999             :                 {
    1000           0 :                     pPict->ReadUChar( nDummy ).ReadUChar( nRed ).ReadUChar( nGreen ).ReadUChar( nBlue );
    1001           0 :                     pAcc->SetPixel( ny, nx, BitmapColor( nRed, nGreen, nBlue) );
    1002             :                 }
    1003           0 :                 nDataSize += ( (sal_uLong)nWidth ) * 4;
    1004           0 :             }
    1005             :         }
    1006           4 :         else if ( nPackType == 2 )
    1007             :         {
    1008           0 :             const size_t nMaxPixels = pPict->remainingSize() / 3;
    1009           0 :             const size_t nMaxRows = nMaxPixels / nWidth;
    1010           0 :             if (nHeight > nMaxRows)
    1011           0 :                 BITMAPERROR;
    1012             : 
    1013           0 :             for ( ny = 0; ny < nHeight; ny++ )
    1014             :             {
    1015           0 :                 for ( nx = 0; nx < nWidth; nx++ )
    1016             :                 {
    1017           0 :                     pPict->ReadUChar( nRed ).ReadUChar( nGreen ).ReadUChar( nBlue );
    1018           0 :                     pAcc->SetPixel( ny, nx, BitmapColor( nRed, nGreen, nBlue ) );
    1019             :                 }
    1020           0 :                 nDataSize += ( (sal_uLong)nWidth ) * 3;
    1021             :             }
    1022             :         }
    1023             :         else
    1024             :         {
    1025           4 :             if ( ( nCmpCount == 3 ) || ( nCmpCount == 4 ) )
    1026             :             {
    1027           4 :                 boost::scoped_array<sal_uInt8> pScanline(new sal_uInt8[static_cast<size_t>(nWidth) * nCmpCount]);
    1028        2544 :                 for ( ny = 0; ny < nHeight; ny++ )
    1029             :                 {
    1030        2540 :                     nSrcBitsPos = pPict->Tell();
    1031        2540 :                     if ( nRowBytes > 250 )
    1032             :                     {
    1033        2540 :                         pPict->ReadUInt16( nByteCount );
    1034        2540 :                         nByteCount += 2;
    1035             :                     }
    1036             :                     else
    1037             :                     {
    1038           0 :                         pPict->ReadUChar( nByteCountAsByte );
    1039           0 :                         nByteCount = (sal_uInt8)nByteCountAsByte;
    1040           0 :                         nByteCount++;
    1041             :                     }
    1042        2540 :                     i = 0;
    1043     1386566 :                     while( i < (sal_uInt32)( nWidth * nCmpCount ) )
    1044             :                     {
    1045     1381486 :                         pPict->ReadUChar( nFlagCounterByte );
    1046     1381486 :                         if ( ( nFlagCounterByte & 0x80 ) == 0)
    1047             :                         {
    1048     1378946 :                             nCount = ( (sal_uInt16)nFlagCounterByte ) + 1;
    1049     1378946 :                             if ( ( i + nCount ) > static_cast<size_t>(nWidth) * nCmpCount )
    1050           0 :                                 nCount = static_cast<size_t>(nWidth) * nCmpCount - i;
    1051     4136986 :                             while( nCount-- )
    1052             :                             {
    1053     1379094 :                                 pPict->ReadUChar( nDat );
    1054     1379094 :                                 pScanline[ i++ ] = nDat;
    1055             :                             }
    1056             :                         }
    1057             :                         else
    1058             :                         {
    1059        2540 :                             nCount = ( 1 - ( ( (sal_uInt16)nFlagCounterByte ) | 0xff00 ) );
    1060        2540 :                             if ( ( i + nCount ) > static_cast<size_t>(nWidth) * nCmpCount)
    1061        2540 :                                 nCount = static_cast<size_t>(nWidth) * nCmpCount - i;
    1062        2540 :                             pPict->ReadUChar( nDat );
    1063     7918916 :                             while( nCount-- )
    1064     7913836 :                                 pScanline[ i++ ] = nDat;
    1065             :                         }
    1066             :                     }
    1067        2540 :                     sal_uInt8* pTmp = pScanline.get();
    1068        2540 :                     if ( nCmpCount == 4 )
    1069         538 :                         pTmp += nWidth;
    1070     3035982 :                     for ( nx = 0; nx < nWidth; pTmp++ )
    1071     3033442 :                         pAcc->SetPixel( ny, nx++, BitmapColor( *pTmp, pTmp[ nWidth ], pTmp[ 2 * nWidth ] ) );
    1072        2540 :                     nDataSize += (sal_uLong)nByteCount;
    1073        2540 :                     pPict->Seek( nSrcBitsPos + (sal_uLong)nByteCount );
    1074           4 :                 }
    1075             :             }
    1076           4 :         }
    1077             :     }
    1078             :     else
    1079           0 :         BITMAPERROR;
    1080          24 :     if ( pReadAcc )
    1081           4 :         aBitmap.ReleaseAccess( pReadAcc );
    1082          24 :     aBitmap.ReleaseAccess( pAcc );
    1083          24 :     rBitmap = aBitmap;
    1084          24 :     return nDataSize;
    1085             : }
    1086             : 
    1087         262 : void PictReader::ReadHeader()
    1088             : {
    1089             :     short y1,x1,y2,x2;
    1090             : 
    1091             :     sal_Char    sBuf[ 2 ];
    1092             :     // previous code considers pPict->Tell() as the normal starting position,
    1093             :     // can we have nStartPos != 0 ?
    1094         262 :     sal_uLong   nStartPos = pPict->Tell();
    1095             :     // Standard:
    1096             :     // a picture file begins by 512 bytes (reserved to the application) followed by the picture data
    1097             :     // while clipboard, pictures stored in a document often contain only the picture data.
    1098             : 
    1099             :     // Special cases:
    1100             :     // - some Pict v.1 use 0x00 0x11 0x01 ( instead of 0x11 0x01) to store the version op
    1101             :     //    (we consider here this as another standard for Pict. v.1 )
    1102             :     // - some files seem to contain extra garbage data at the beginning
    1103             :     // - some picture data seem to contain extra NOP opcode(0x00) between the bounding box and the version opcode
    1104             : 
    1105             :     // This code looks hard to find a picture header, ie. it looks at positions
    1106             :     //   - nStartPos+0, nStartPos+512 with potential extra NOP codes between bdbox and version (at most 9 extra NOP)
    1107             :     //   - 512..1024 with more strict bdbox checking and no extra NOP codes
    1108             : 
    1109             :     // Notes:
    1110             :     // - if the header can begin at nStartPos+0 and at nStartPos+512, we try to choose the more
    1111             :     //       <<probable>> ( using the variable confidence)
    1112             :     // - svtools/source/filter.vcl/filter/{filter.cxx,filter2.cxx} only check for standard Pict,
    1113             :     //       this may cause future problems
    1114             :     int st;
    1115             :     sal_uInt32 nOffset;
    1116         262 :     int confidence[2] = { 0, 0};
    1117         516 :     for ( st = 0; st < 3 + 513; st++ )
    1118             :       {
    1119         516 :         int actualConfid = 20; // the actual confidence
    1120         516 :         pPict->ResetError();
    1121         516 :         if (st < 2) nOffset = nStartPos+st*512;
    1122           2 :         else if (st == 2) {
    1123             :           // choose nStartPos+0 or nStartPos+512 even if there are a little dubious
    1124           2 :           int actPos = -1, actConf=0;
    1125           2 :           if (confidence[0] > 0) { actPos = 0; actConf =  confidence[0]; }
    1126           2 :           if (confidence[1] > 0 && confidence[1] >= actConf) actPos = 1;
    1127         256 :           if (actPos < 0) continue;
    1128           2 :           nOffset = nStartPos+actPos*512;
    1129             :         }
    1130             :         else {
    1131           0 :           nOffset = 509+st; // illogical : more logical will be nStartPos+509+st or to consider that nStartPos=0
    1132             :           // a small test to check if versionOp code exists after the bdbox ( with no extra NOP codes)
    1133           0 :           pPict->Seek(nOffset+10);
    1134           0 :           pPict->Read( sBuf, 2 );
    1135           0 :           if (pPict->IsEof() || pPict->GetError()) break;
    1136           0 :           if (sBuf[0] == 0x11 || (sBuf[0] == 0x00 && sBuf[1] == 0x11)) ; // maybe ok
    1137           0 :           else continue;
    1138             :         }
    1139         516 :         pPict->Seek(nOffset);
    1140             : 
    1141             :         // 2 bytes to store size ( version 1 ) ignored
    1142         516 :         pPict->SeekRel( 2 );
    1143         516 :         pPict->ReadInt16( y1 ).ReadInt16( x1 ).ReadInt16( y2 ).ReadInt16( x2 ); // frame rectangle of the picture
    1144         516 :         if (x1 > x2 || y1 > y2) continue; // bad bdbox
    1145        1026 :         if (x1 < -2048 || x2 > 2048 || y1 < -2048 || y2 > 2048 || // origin|dest is very small|large
    1146         760 :         (x1 == x2 && y1 == y2) ) // 1 pixel pict is dubious
    1147         256 :           actualConfid-=3;
    1148         260 :         else if (x2 < x1+8 || y2 < y1+8) // a little dubious
    1149           0 :           actualConfid-=1;
    1150         516 :         if (st >= 3 && actualConfid != 20) continue;
    1151         516 :         aBoundingRect=Rectangle( x1,y1, x2, y2 );
    1152             : 
    1153         516 :         if (pPict->IsEof() || pPict->GetError()) continue;
    1154             :         // read version
    1155         516 :         pPict->Read( sBuf, 2 );
    1156             :         // version 1 file
    1157         516 :         if ( sBuf[ 0 ] == 0x11 && sBuf[ 1 ] == 0x01 ) {
    1158             :           // pict v1 must be rare and we do only few tests
    1159           0 :           if (st < 2) { confidence[st] = --actualConfid; continue; }
    1160         262 :           IsVersion2 = false; return;
    1161             :         }
    1162         516 :         if (sBuf[0] != 0x00) continue; // unrecovable error
    1163         514 :         int numZero = 0;
    1164        2764 :         do
    1165             :           {
    1166        2764 :         numZero++;
    1167        2764 :         pPict->SeekRel(-1);
    1168        2764 :         pPict->Read( sBuf, 2 );
    1169             :           }
    1170        5264 :         while ( sBuf[0] == 0x00 && numZero < 10);
    1171         514 :         actualConfid -= (numZero-1); // extra nop are dubious
    1172         514 :         if (pPict->IsEof() || pPict->GetError()) continue;
    1173         514 :         if (sBuf[0] != 0x11) continue; // not a version opcode
    1174             :         // abnormal version 1 file
    1175         264 :         if (sBuf[1] == 0x01 ) {
    1176             :           // pict v1 must be rare and we do only few tests
    1177           0 :           if (st < 2) { confidence[st] = --actualConfid; continue; }
    1178           0 :           IsVersion2 = false; return;
    1179             :         }
    1180         264 :         if (sBuf[1] != 0x02 ) continue; // not a version 2 file
    1181             : 
    1182         264 :         IsVersion2=true;
    1183             :         short   nExtVer, nReserved;
    1184             :         // 3 Bytes ignored : end of version arg 0x02FF (ie: 0xFF), HeaderOp : 0x0C00
    1185         264 :         pPict->SeekRel( 3 );
    1186         264 :         pPict->ReadInt16( nExtVer ).ReadInt16( nReserved );
    1187         264 :         if (pPict->IsEof() || pPict->GetError()) continue;
    1188             : 
    1189         264 :         if ( nExtVer == -2 ) // extended version 2 picture
    1190             :           {
    1191             :         sal_Int32 nHResFixed, nVResFixed;
    1192          16 :         pPict->ReadInt32( nHResFixed ).ReadInt32( nVResFixed );
    1193          16 :         pPict->ReadInt16( y1 ).ReadInt16( x1 ).ReadInt16( y2 ).ReadInt16( x2 ); // reading the optimal bounding rect
    1194          18 :         if (x1 > x2 || y1 > y2) continue; // bad bdbox
    1195          16 :         if (st < 2 && actualConfid != 20) { confidence[st] = actualConfid; continue; }
    1196             : 
    1197          14 :         double fHRes = nHResFixed;
    1198          14 :         fHRes /= 65536;
    1199          14 :         double fVRes = nVResFixed;
    1200          14 :         fVRes /= 65536;
    1201          14 :         aHRes /= fHRes;
    1202          14 :         aVRes /= fVRes;
    1203          14 :         aBoundingRect=Rectangle( x1,y1, x2, y2 );
    1204          14 :         pPict->SeekRel( 4 ); // 4 bytes reserved
    1205          14 :         return;
    1206             :           }
    1207         248 :         else if (nExtVer == -1 ) { // basic version 2 picture
    1208         248 :           if (st < 2 && actualConfid != 20) { confidence[st] = actualConfid; continue; }
    1209         248 :           pPict->SeekRel( 16); // bdbox(4 fixed number)
    1210         248 :           pPict->SeekRel(4); // 4 bytes reserved
    1211         248 :           return;
    1212             :         }
    1213             :       }
    1214           0 :     pPict->SetError(SVSTREAM_FILEFORMAT_ERROR);
    1215             : }
    1216             : 
    1217             : #if OSL_DEBUG_LEVEL > 0
    1218             : static const char* operationName(sal_uInt16 nOpcode)
    1219             : {
    1220             :     // add here whatever makes the debugging easier for you, otherwise you'll
    1221             :     // see only the operation's opcode
    1222             :     switch (nOpcode)
    1223             :     {
    1224             :         case 0x0001: return "Clip";
    1225             :         case 0x0003: return "TxFont";
    1226             :         case 0x0004: return "TxFace";
    1227             :         case 0x0008: return "PnMode";
    1228             :         case 0x0009: return "PnPat";
    1229             :         case 0x000d: return "TxSize";
    1230             :         case 0x001a: return "RGBFgCol";
    1231             :         case 0x001d: return "HiliteColor";
    1232             :         case 0x0020: return "Line";
    1233             :         case 0x0022: return "ShortLine";
    1234             :         case 0x0028: return "LongText";
    1235             :         case 0x0029: return "DHText";
    1236             :         case 0x002a: return "DVText";
    1237             :         case 0x002c: return "fontName";
    1238             :         case 0x002e: return "glyphState";
    1239             :         case 0x0031: return "paintRect";
    1240             :         case 0x0038: return "frameSameRect";
    1241             :         case 0x0070: return "framePoly";
    1242             :         case 0x0071: return "paintPoly";
    1243             :         case 0x00a1: return "LongComment";
    1244             :         default:     return "";
    1245             :     }
    1246             : }
    1247             : #endif
    1248             : 
    1249       12028 : sal_uLong PictReader::ReadData(sal_uInt16 nOpcode)
    1250             : {
    1251             :     sal_uInt16 nUSHORT;
    1252       12028 :     Point aPoint;
    1253       12028 :     sal_uLong nDataSize=0;
    1254       12028 :     PictDrawingMethod shapeDMethod = PDM_UNDEFINED;
    1255       12028 :     switch (nOpcode & 7) {
    1256        3268 :     case 0: shapeDMethod = PDM_FRAME; break;
    1257        4950 :     case 1: shapeDMethod = PDM_PAINT; break;
    1258        1006 :     case 2: shapeDMethod = PDM_ERASE; break;
    1259        1640 :     case 3: shapeDMethod = PDM_INVERT; break;
    1260         224 :     case 4: shapeDMethod = PDM_FILL; break;
    1261         940 :     default: break;
    1262             :     }
    1263             : 
    1264             : #if OSL_DEBUG_LEVEL > 0
    1265             :     SAL_INFO("filter.pict", "Operation: 0x" << OUString::number(nOpcode, 16) << " [" << operationName(nOpcode) << "]");
    1266             : #endif
    1267             : 
    1268       12028 :     switch(nOpcode) {
    1269             : 
    1270             :     case 0x0000:   // NOP
    1271         458 :         nDataSize=0;
    1272         458 :         break;
    1273             : 
    1274             :     case 0x0001: { // Clip
    1275         342 :         Rectangle aRect;
    1276         342 :         pPict->ReadUInt16( nUSHORT );
    1277         342 :         nDataSize=nUSHORT;
    1278         342 :         ReadRectangle(aRect);
    1279             :         // checkme: do we really want to extend the rectangle here ?
    1280             :         // I do that because the clipping is often used to clean a region,
    1281             :         //   before drawing some text and also to draw this text.
    1282             :         // So using a too small region can lead to clip the end of the text ;
    1283             :         //   but this can be discutable...
    1284         342 :         aRect.setWidth(aRect.getWidth()+1);
    1285         342 :         aRect.setHeight(aRect.getHeight()+1);
    1286         342 :         pVirDev->SetClipRegion( vcl::Region( aRect ) );
    1287         342 :         break;
    1288             :     }
    1289             :     case 0x0002:   // BkPat
    1290           0 :         nDataSize = eActBackPattern.read(*pPict);
    1291           0 :         eActMethod = PDM_UNDEFINED;
    1292           0 :         break;
    1293             : 
    1294             :     case 0x0003:   // TxFont
    1295         932 :         pPict->ReadUInt16( nUSHORT );
    1296         932 :         if      (nUSHORT <=    1) aActFont.SetFamily(FAMILY_SWISS);
    1297         922 :         else if (nUSHORT <=   12) aActFont.SetFamily(FAMILY_DECORATIVE);
    1298         552 :         else if (nUSHORT <=   20) aActFont.SetFamily(FAMILY_ROMAN);
    1299         380 :         else if (nUSHORT ==   21) aActFont.SetFamily(FAMILY_SWISS);
    1300         380 :         else if (nUSHORT ==   22) aActFont.SetFamily(FAMILY_MODERN);
    1301         372 :         else if (nUSHORT <= 1023) aActFont.SetFamily(FAMILY_SWISS);
    1302           2 :         else                      aActFont.SetFamily(FAMILY_ROMAN);
    1303         932 :         aActFont.SetCharSet(GetTextEncoding(nUSHORT));
    1304         932 :         eActMethod=PDM_UNDEFINED;
    1305         932 :         nDataSize=2;
    1306         932 :         break;
    1307             : 
    1308             :     case 0x0004: {  // TxFace
    1309             :         char nFace;
    1310          56 :         pPict->ReadChar( nFace );
    1311          56 :         if ( (nFace & 0x01)!=0 ) aActFont.SetWeight(WEIGHT_BOLD);
    1312          42 :         else                     aActFont.SetWeight(WEIGHT_NORMAL);
    1313          56 :         if ( (nFace & 0x02)!=0 ) aActFont.SetItalic(ITALIC_NORMAL);
    1314          46 :         else                     aActFont.SetItalic(ITALIC_NONE);
    1315          56 :         if ( (nFace & 0x04)!=0 ) aActFont.SetUnderline(UNDERLINE_SINGLE);
    1316          48 :         else                     aActFont.SetUnderline(UNDERLINE_NONE);
    1317          56 :         if ( (nFace & 0x08)!=0 ) aActFont.SetOutline(true);
    1318          54 :         else                     aActFont.SetOutline(false);
    1319          56 :         if ( (nFace & 0x10)!=0 ) aActFont.SetShadow(true);
    1320          56 :         else                     aActFont.SetShadow(false);
    1321          56 :         eActMethod=PDM_UNDEFINED;
    1322          56 :         nDataSize=1;
    1323          56 :         break;
    1324             :     }
    1325             :     case 0x0005:   // TxMode
    1326           0 :         nDataSize=2;
    1327           0 :         break;
    1328             : 
    1329             :     case 0x0006:   // SpExtra
    1330           0 :         nDataSize=4;
    1331           0 :         break;
    1332             : 
    1333             :     case 0x0007: { // PnSize
    1334         206 :         nActPenSize=ReadSize();
    1335         206 :         eActMethod=PDM_UNDEFINED;
    1336         206 :         nDataSize=4;
    1337         206 :         break;
    1338             :     }
    1339             :     case 0x0008:   // PnMode
    1340         120 :         pPict->ReadUInt16( nUSHORT );
    1341             :         // internal code for postscript command (Quickdraw Reference Drawing B-30,B-34)
    1342         120 :         if (nUSHORT==23) eActROP = ROP_1;
    1343             :         else {
    1344         112 :           switch (nUSHORT & 0x0007) {
    1345          58 :             case 0: eActROP=ROP_OVERPAINT; break; // Copy
    1346          54 :             case 1: eActROP=ROP_OVERPAINT; break; // Or
    1347           0 :             case 2: eActROP=ROP_XOR;       break; // Xor
    1348           0 :             case 3: eActROP=ROP_OVERPAINT; break; // Bic
    1349           0 :             case 4: eActROP=ROP_INVERT;    break; // notCopy
    1350           0 :             case 5: eActROP=ROP_OVERPAINT; break; // notOr
    1351           0 :             case 6: eActROP=ROP_XOR;       break; // notXor
    1352           0 :             case 7: eActROP=ROP_OVERPAINT; break; // notBic
    1353             :           }
    1354             :         }
    1355         120 :         eActMethod=PDM_UNDEFINED;
    1356         120 :         nDataSize=2;
    1357         120 :         break;
    1358             : 
    1359             :     case 0x0009:   // PnPat
    1360           4 :         nDataSize=eActPenPattern.read(*pPict);
    1361           4 :         eActMethod=PDM_UNDEFINED;
    1362           4 :         break;
    1363             : 
    1364             :     case 0x000a:   // FillPat
    1365           6 :         nDataSize=eActFillPattern.read(*pPict);
    1366           6 :         eActMethod=PDM_UNDEFINED;
    1367           6 :         break;
    1368             : 
    1369             :     case 0x000b:   // OvSize
    1370           2 :         aActOvalSize=ReadSize();
    1371           2 :         nDataSize=4;
    1372           2 :         break;
    1373             : 
    1374             :     case 0x000c:   // Origin
    1375           0 :         nDataSize=4;
    1376           0 :         break;
    1377             : 
    1378             :     case 0x000d:   // TxSize
    1379             :     {
    1380         714 :         pPict->ReadUInt16( nUSHORT );
    1381         714 :         aActFont.SetSize( Size( 0, (long)nUSHORT ) );
    1382         714 :         eActMethod=PDM_UNDEFINED;
    1383         714 :         nDataSize=2;
    1384             :     }
    1385         714 :     break;
    1386             : 
    1387             :     case 0x000e:   // FgColor
    1388           0 :         aActForeColor=ReadColor();
    1389           0 :         eActMethod=PDM_UNDEFINED;
    1390           0 :         nDataSize=4;
    1391           0 :         break;
    1392             : 
    1393             :     case 0x000f:   // BkColor
    1394           0 :         aActBackColor=ReadColor();
    1395           0 :         nDataSize=4;
    1396           0 :         break;
    1397             : 
    1398             :     case 0x0010:   // TxRatio
    1399          16 :         nDataSize=8;
    1400          16 :         break;
    1401             : 
    1402             :     case 0x0011:   // VersionOp
    1403           0 :         nDataSize=1;
    1404           0 :         break;
    1405             : 
    1406             :     case 0x0012:   // BkPixPat
    1407           0 :         nDataSize=ReadPixPattern(eActBackPattern);
    1408           0 :         eActMethod=PDM_UNDEFINED;
    1409           0 :         break;
    1410             : 
    1411             :     case 0x0013:   // PnPixPat
    1412           0 :         nDataSize=ReadPixPattern(eActPenPattern);
    1413           0 :         eActMethod=PDM_UNDEFINED;
    1414           0 :         break;
    1415             : 
    1416             :     case 0x0014:   // FillPixPat
    1417           0 :         nDataSize=ReadPixPattern(eActFillPattern);
    1418           0 :         eActMethod=PDM_UNDEFINED;
    1419           0 :         break;
    1420             : 
    1421             :     case 0x0015:   // PnLocHFrac
    1422           0 :         nDataSize=2;
    1423           0 :         break;
    1424             : 
    1425             :     case 0x0016:   // ChExtra
    1426           0 :         nDataSize=2;
    1427           0 :         break;
    1428             : 
    1429             :     case 0x0017:   // Reserved (0 Bytes)
    1430             :     case 0x0018:   // Reserved (0 Bytes)
    1431             :     case 0x0019:   // Reserved (0 Bytes)
    1432           0 :         nDataSize=0;
    1433           0 :         break;
    1434             : 
    1435             :     case 0x001a:   // RGBFgCol
    1436          60 :         aActForeColor=ReadRGBColor();
    1437          60 :         eActMethod=PDM_UNDEFINED;
    1438          60 :         nDataSize=6;
    1439          60 :         break;
    1440             : 
    1441             :     case 0x001b:   // RGBBkCol
    1442           0 :         aActBackColor=ReadRGBColor();
    1443           0 :         eActMethod=PDM_UNDEFINED;
    1444           0 :         nDataSize=6;
    1445           0 :         break;
    1446             : 
    1447             :     case 0x001c:   // HiliteMode
    1448           0 :         nDataSize=0;
    1449           0 :         break;
    1450             : 
    1451             :     case 0x001d:   // HiliteColor
    1452           2 :         nDataSize=6;
    1453           2 :         break;
    1454             : 
    1455             :     case 0x001e:   // DefHilite
    1456           4 :         nDataSize=0;
    1457           4 :         break;
    1458             : 
    1459             :     case 0x001f:   // OpColor
    1460           0 :         nDataSize=6;
    1461           0 :         break;
    1462             : 
    1463             :     case 0x0020:   // Line
    1464          82 :         aPoint=ReadPoint(); aPenPosition=ReadPoint();
    1465          82 :         nDataSize=8;
    1466             : 
    1467          82 :         if (IsInvisible(PDM_FRAME)) break;
    1468          82 :         DrawingMethod(PDM_FRAME);
    1469          82 :         PictReaderShape::drawLine(pVirDev, aPoint,aPenPosition, nActPenSize);
    1470          82 :         break;
    1471             : 
    1472             :     case 0x0021:   // LineFrom
    1473          80 :         aPoint=aPenPosition; aPenPosition=ReadPoint();
    1474          80 :         nDataSize=4;
    1475             : 
    1476          80 :         if (IsInvisible(PDM_FRAME)) break;
    1477          80 :         DrawingMethod(PDM_FRAME);
    1478          80 :         PictReaderShape::drawLine(pVirDev, aPoint,aPenPosition, nActPenSize);
    1479          80 :         break;
    1480             : 
    1481             :     case 0x0022:   // ShortLine
    1482         660 :         aPoint=ReadPoint();
    1483         660 :         aPenPosition=ReadDeltaH(aPoint);
    1484         660 :         aPenPosition=ReadDeltaV(aPenPosition);
    1485         660 :         nDataSize=6;
    1486             : 
    1487         660 :         if (IsInvisible(PDM_FRAME)) break;
    1488         510 :         DrawingMethod(PDM_FRAME);
    1489         510 :         PictReaderShape::drawLine(pVirDev, aPoint,aPenPosition, nActPenSize);
    1490         510 :         break;
    1491             : 
    1492             :     case 0x0023:   // ShortLineFrom
    1493         316 :         aPoint=aPenPosition;
    1494         316 :         aPenPosition=ReadDeltaH(aPoint);
    1495         316 :         aPenPosition=ReadDeltaV(aPenPosition);
    1496         316 :         nDataSize=2;
    1497             : 
    1498         316 :         if (IsInvisible(PDM_FRAME)) break;
    1499          62 :         DrawingMethod(PDM_FRAME);
    1500          62 :         PictReaderShape::drawLine(pVirDev, aPoint,aPenPosition, nActPenSize);
    1501          62 :         break;
    1502             : 
    1503             :     case 0x0024:   // Reserved (n Bytes)
    1504             :     case 0x0025:   // Reserved (n Bytes)
    1505             :     case 0x0026:   // Reserved (n Bytes)
    1506             :     case 0x0027:   // Reserved (n Bytes)
    1507           0 :         pPict->ReadUInt16( nUSHORT );
    1508           0 :         nDataSize=2+nUSHORT;
    1509           0 :         break;
    1510             : 
    1511             :     case 0x0028:   // LongText
    1512         842 :         aTextPosition=ReadPoint();
    1513         842 :         nDataSize=4+ReadAndDrawText();
    1514         842 :         break;
    1515             : 
    1516             :     case 0x0029:   // DHText
    1517        1374 :         aTextPosition=ReadUnsignedDeltaH(aTextPosition);
    1518        1374 :         nDataSize=1+ReadAndDrawText();
    1519        1374 :         break;
    1520             : 
    1521             :     case 0x002a:   // DVText
    1522         188 :         aTextPosition=ReadUnsignedDeltaV(aTextPosition);
    1523         188 :         nDataSize=1+ReadAndDrawText();
    1524         188 :         break;
    1525             : 
    1526             :     case 0x002b:   // DHDVText
    1527         390 :         aTextPosition=ReadUnsignedDeltaH(aTextPosition);
    1528         390 :         aTextPosition=ReadUnsignedDeltaV(aTextPosition);
    1529         390 :         nDataSize=2+ReadAndDrawText();
    1530         390 :         break;
    1531             : 
    1532             :     case 0x002c: { // fontName
    1533             :         char        sFName[ 256 ], nByteLen;
    1534             :         sal_uInt16  nLen;
    1535         154 :         pPict->ReadUInt16( nUSHORT ); nDataSize=nUSHORT+2;
    1536         154 :         pPict->ReadUInt16( nUSHORT );
    1537         154 :         if      (nUSHORT <=    1) aActFont.SetFamily(FAMILY_SWISS);
    1538         152 :         else if (nUSHORT <=   12) aActFont.SetFamily(FAMILY_DECORATIVE);
    1539         150 :         else if (nUSHORT <=   20) aActFont.SetFamily(FAMILY_ROMAN);
    1540          54 :         else if (nUSHORT ==   21) aActFont.SetFamily(FAMILY_SWISS);
    1541          54 :         else if (nUSHORT ==   22) aActFont.SetFamily(FAMILY_MODERN);
    1542          50 :         else if (nUSHORT <= 1023) aActFont.SetFamily(FAMILY_SWISS);
    1543           2 :         else                      aActFont.SetFamily(FAMILY_ROMAN);
    1544         154 :         aActFont.SetCharSet(GetTextEncoding(nUSHORT));
    1545         154 :         pPict->ReadChar( nByteLen ); nLen=((sal_uInt16)nByteLen)&0x00ff;
    1546         154 :         pPict->Read( &sFName, nLen );
    1547         154 :         sFName[ nLen ] = 0;
    1548         154 :         OUString aString( (const sal_Char*)&sFName, strlen(sFName), osl_getThreadTextEncoding() );
    1549         154 :         aActFont.SetName( aString );
    1550         154 :         eActMethod=PDM_UNDEFINED;
    1551         154 :         break;
    1552             :     }
    1553             :     case 0x002d:   // lineJustify
    1554           0 :         nDataSize=10;
    1555           0 :         break;
    1556             : 
    1557             :     case 0x002e:   // glyphState
    1558           8 :         pPict->ReadUInt16( nUSHORT );
    1559           8 :         nDataSize=2+nUSHORT;
    1560           8 :         break;
    1561             : 
    1562             :     case 0x002f:   // Reserved (n Bytes)
    1563           0 :         pPict->ReadUInt16( nUSHORT );
    1564           0 :         nDataSize=2+nUSHORT;
    1565           0 :         break;
    1566             : 
    1567             :     case 0x0030:   // frameRect
    1568             :     case 0x0031:   // paintRect
    1569             :     case 0x0032:   // eraseRect
    1570             :     case 0x0033:   // invertRect
    1571             :     case 0x0034:   // fillRect
    1572          44 :         nDataSize=ReadAndDrawRect(shapeDMethod);
    1573          44 :         break;
    1574             : 
    1575             :     case 0x0035:   // Reserved (8 Bytes)
    1576             :     case 0x0036:   // Reserved (8 Bytes)
    1577             :     case 0x0037:   // Reserved (8 Bytes)
    1578           0 :         nDataSize=8;
    1579           0 :         break;
    1580             : 
    1581             :     case 0x0038:   // frameSameRect
    1582             :     case 0x0039:   // paintSameRect
    1583             :     case 0x003a:   // eraseSameRect
    1584             :     case 0x003b:   // invertSameRect
    1585             :     case 0x003c:   // fillSameRect
    1586          34 :         nDataSize=ReadAndDrawSameRect(shapeDMethod);
    1587          34 :         break;
    1588             : 
    1589             :     case 0x003d:   // Reserved (0 Bytes)
    1590             :     case 0x003e:   // Reserved (0 Bytes)
    1591             :     case 0x003f:   // Reserved (0 Bytes)
    1592           0 :         nDataSize=0;
    1593           0 :         break;
    1594             : 
    1595             :     case 0x0040:   // frameRRect
    1596             :     case 0x0041:   // paintRRect
    1597             :     case 0x0042:   // eraseRRect
    1598             :     case 0x0043:   // invertRRect
    1599             :     case 0x0044:   // fillRRect
    1600           2 :         nDataSize=ReadAndDrawRoundRect(shapeDMethod);
    1601           2 :         break;
    1602             : 
    1603             :     case 0x0045:   // Reserved (8 Bytes)
    1604             :     case 0x0046:   // Reserved (8 Bytes)
    1605             :     case 0x0047:   // Reserved (8 Bytes)
    1606           0 :         nDataSize=8;
    1607           0 :         break;
    1608             : 
    1609             :     case 0x0048:   // frameSameRRect
    1610             :     case 0x0049:   // paintSameRRect
    1611             :     case 0x004a:   // eraseSameRRect
    1612             :     case 0x004b:   // invertSameRRect
    1613             :     case 0x004c:   // fillSameRRect
    1614           2 :         nDataSize=ReadAndDrawSameRoundRect(shapeDMethod);
    1615           2 :         break;
    1616             : 
    1617             :     case 0x004d:   // Reserved (0 Bytes)
    1618             :     case 0x004e:   // Reserved (0 Bytes)
    1619             :     case 0x004f:   // Reserved (0 Bytes)
    1620           0 :         nDataSize=0;
    1621           0 :         break;
    1622             : 
    1623             :     case 0x0050:   // frameOval
    1624             :     case 0x0051:   // paintOval
    1625             :     case 0x0052:   // eraseOval
    1626             :     case 0x0053:   // invertOval
    1627             :     case 0x0054:   // fillOval
    1628           2 :         nDataSize=ReadAndDrawOval(shapeDMethod);
    1629           2 :         break;
    1630             : 
    1631             :     case 0x0055:   // Reserved (8 Bytes)
    1632             :     case 0x0056:   // Reserved (8 Bytes)
    1633             :     case 0x0057:   // Reserved (8 Bytes)
    1634           0 :         nDataSize=8;
    1635           0 :         break;
    1636             : 
    1637             :     case 0x0058:   // frameSameOval
    1638             :     case 0x0059:   // paintSameOval
    1639             :     case 0x005a:   // eraseSameOval
    1640             :     case 0x005b:   // invertSameOval
    1641             :     case 0x005c:   // fillSameOval
    1642           2 :         nDataSize=ReadAndDrawSameOval(shapeDMethod);
    1643           2 :         break;
    1644             : 
    1645             :     case 0x005d:   // Reserved (0 Bytes)
    1646             :     case 0x005e:   // Reserved (0 Bytes)
    1647             :     case 0x005f:   // Reserved (0 Bytes)
    1648           0 :         nDataSize=0;
    1649           0 :         break;
    1650             : 
    1651             :     case 0x0060:   // frameArc
    1652             :     case 0x0061:   // paintArc
    1653             :     case 0x0062:   // eraseArc
    1654             :     case 0x0063:   // invertArc
    1655             :     case 0x0064:   // fillArc
    1656          48 :         nDataSize=ReadAndDrawArc(shapeDMethod);
    1657          48 :         break;
    1658             : 
    1659             :     case 0x0065:   // Reserved (12 Bytes)
    1660             :     case 0x0066:   // Reserved (12 Bytes)
    1661             :     case 0x0067:   // Reserved (12 Bytes)
    1662           0 :         nDataSize=12;
    1663           0 :         break;
    1664             : 
    1665             :     case 0x0068:   // frameSameArc
    1666             :     case 0x0069:   // paintSameArc
    1667             :     case 0x006a:   // eraseSameArc
    1668             :     case 0x006b:   // invertSameArc
    1669             :     case 0x006c:   // fillSameArc
    1670           0 :         nDataSize=ReadAndDrawSameArc(shapeDMethod);
    1671           0 :         break;
    1672             : 
    1673             :     case 0x006d:   // Reserved (4 Bytes)
    1674             :     case 0x006e:   // Reserved (4 Bytes)
    1675             :     case 0x006f:   // Reserved (4 Bytes)
    1676           0 :         nDataSize=4;
    1677           0 :         break;
    1678             : 
    1679             :     case 0x0070:   // framePoly
    1680             :     case 0x0071:   // paintPoly
    1681             :     case 0x0072:   // erasePoly
    1682             :     case 0x0073:   // invertPoly
    1683             :     case 0x0074:   // fillPoly
    1684         138 :         nDataSize=ReadAndDrawPolygon(shapeDMethod);
    1685         138 :         break;
    1686             : 
    1687             :     case 0x0075:   // Reserved (Polygon-Size)
    1688             :     case 0x0076:   // Reserved (Polygon-Size)
    1689             :     case 0x0077:   // Reserved (Polygon-Size)
    1690           0 :         pPict->ReadUInt16( nUSHORT ); nDataSize=nUSHORT;
    1691           0 :         break;
    1692             : 
    1693             :     case 0x0078:   // frameSamePoly
    1694             :     case 0x0079:   // paintSamePoly
    1695             :     case 0x007a:   // eraseSamePoly
    1696             :     case 0x007b:   // invertSamePoly
    1697             :     case 0x007c:   // fillSamePoly
    1698           0 :         nDataSize=ReadAndDrawSamePolygon(shapeDMethod);
    1699           0 :         break;
    1700             : 
    1701             :     case 0x007d:   // Reserved (0 Bytes)
    1702             :     case 0x007e:   // Reserved (0 Bytes)
    1703             :     case 0x007f:   // Reserved (0 Bytes)
    1704           0 :         nDataSize=0;
    1705           0 :         break;
    1706             : 
    1707             :     case 0x0080:   // frameRgn
    1708             :     case 0x0081:   // paintRgn
    1709             :     case 0x0082:   // eraseRgn
    1710             :     case 0x0083:   // invertRgn
    1711             :     case 0x0084:   // fillRgn
    1712           8 :         nDataSize=ReadAndDrawRgn(shapeDMethod);
    1713           8 :         break;
    1714             : 
    1715             :     case 0x0085:   // Reserved (Region-Size)
    1716             :     case 0x0086:   // Reserved (Region-Size)
    1717             :     case 0x0087:   // Reserved (Region-Size)
    1718           0 :         pPict->ReadUInt16( nUSHORT ); nDataSize=nUSHORT;
    1719           0 :         break;
    1720             : 
    1721             :     case 0x0088:   // frameSameRgn
    1722             :     case 0x0089:   // paintSameRgn
    1723             :     case 0x008a:   // eraseSameRgn
    1724             :     case 0x008b:   // invertSameRgn
    1725             :     case 0x008c:   // fillSameRgn
    1726           0 :         nDataSize=ReadAndDrawSameRgn(shapeDMethod);
    1727           0 :         break;
    1728             : 
    1729             :     case 0x008d:   // Reserved (0 Bytes)
    1730             :     case 0x008e:   // Reserved (0 Bytes)
    1731             :     case 0x008f:   // Reserved (0 Bytes)
    1732           0 :         nDataSize=0;
    1733           0 :         break;
    1734             : 
    1735             :     case 0x0090: { // BitsRect
    1736           0 :         Bitmap aBmp;
    1737           0 :         Rectangle aSrcRect, aDestRect;
    1738           0 :         nDataSize=ReadPixMapEtc(aBmp, false, true, &aSrcRect, &aDestRect, true, false);
    1739           0 :         DrawingMethod(PDM_PAINT);
    1740           0 :         pVirDev->DrawBitmap(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp);
    1741           0 :         break;
    1742             :     }
    1743             :     case 0x0091: { // BitsRgn
    1744           0 :         Bitmap aBmp;
    1745           0 :         Rectangle aSrcRect, aDestRect;
    1746           0 :         nDataSize=ReadPixMapEtc(aBmp, false, true, &aSrcRect, &aDestRect, true, true);
    1747           0 :         DrawingMethod(PDM_PAINT);
    1748           0 :         pVirDev->DrawBitmap(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp);
    1749           0 :         break;
    1750             :     }
    1751             :     case 0x0092:   // Reserved (n Bytes)
    1752             :     case 0x0093:   // Reserved (n Bytes)
    1753             :     case 0x0094:   // Reserved (n Bytes)
    1754             :     case 0x0095:   // Reserved (n Bytes)
    1755             :     case 0x0096:   // Reserved (n Bytes)
    1756             :     case 0x0097:   // Reserved (n Bytes)
    1757           0 :         pPict->ReadUInt16( nUSHORT ); nDataSize=2+nUSHORT;
    1758           0 :         break;
    1759             : 
    1760             :     case 0x0098: { // PackBitsRect
    1761          20 :         Bitmap aBmp;
    1762          20 :         Rectangle aSrcRect, aDestRect;
    1763          20 :         nDataSize=ReadPixMapEtc(aBmp, false, true, &aSrcRect, &aDestRect, true, false);
    1764          20 :         DrawingMethod(PDM_PAINT);
    1765          20 :         pVirDev->DrawBitmap(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp);
    1766          20 :         break;
    1767             :     }
    1768             :     case 0x0099: { // PackBitsRgn
    1769           0 :         Bitmap aBmp;
    1770           0 :         Rectangle aSrcRect, aDestRect;
    1771           0 :         nDataSize=ReadPixMapEtc(aBmp, false, true, &aSrcRect, &aDestRect, true, true);
    1772           0 :         DrawingMethod(PDM_PAINT);
    1773           0 :         pVirDev->DrawBitmap(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp);
    1774           0 :         break;
    1775             :     }
    1776             :     case 0x009a: { // DirectBitsRect
    1777           6 :         Bitmap aBmp;
    1778           6 :         Rectangle aSrcRect, aDestRect;
    1779           6 :         nDataSize=ReadPixMapEtc(aBmp, true, false, &aSrcRect, &aDestRect, true, false);
    1780           6 :         DrawingMethod(PDM_PAINT);
    1781           6 :         pVirDev->DrawBitmap(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp);
    1782           6 :         break;
    1783             :     }
    1784             :     case 0x009b: { // DirectBitsRgn
    1785           0 :         Bitmap aBmp;
    1786           0 :         Rectangle aSrcRect, aDestRect;
    1787           0 :         nDataSize=ReadPixMapEtc(aBmp, true, false, &aSrcRect, &aDestRect, true, true);
    1788           0 :         DrawingMethod(PDM_PAINT);
    1789           0 :         pVirDev->DrawBitmap(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp);
    1790           0 :         break;
    1791             :     }
    1792             :     case 0x009c:   // Reserved (n Bytes)
    1793             :     case 0x009d:   // Reserved (n Bytes)
    1794             :     case 0x009e:   // Reserved (n Bytes)
    1795             :     case 0x009f:   // Reserved (n Bytes)
    1796           2 :         pPict->ReadUInt16( nUSHORT ); nDataSize=2+nUSHORT;
    1797           2 :         break;
    1798             : 
    1799             :     case 0x00a0:   // ShortComment
    1800        1680 :         nDataSize=2;
    1801        1680 :         break;
    1802             : 
    1803             :     case 0x00a1:   // LongComment
    1804        3016 :         pPict->SeekRel(2); pPict->ReadUInt16( nUSHORT ); nDataSize=4+nUSHORT;
    1805        3016 :         break;
    1806             : 
    1807             :     default: // 0x00a2 bis 0xffff (most times reserved)
    1808           8 :         if      (nOpcode<=0x00af) { pPict->ReadUInt16( nUSHORT ); nDataSize=2+nUSHORT; }
    1809           8 :         else if (nOpcode<=0x00cf) { nDataSize=0; }
    1810           8 :         else if (nOpcode<=0x00fe) { sal_uInt32 nTemp; pPict->ReadUInt32( nTemp ) ; nDataSize = nTemp; nDataSize+=4; }
    1811             :         // Osnola: checkme: in the Quickdraw Ref examples ( for pict v2)
    1812             :         //         0x00ff(EndOfPict) is also not followed by any data...
    1813           8 :         else if (nOpcode==0x00ff) { nDataSize=IsVersion2 ? 2 : 0; } // OpEndPic
    1814           8 :         else if (nOpcode<=0x01ff) { nDataSize=2; }
    1815           8 :         else if (nOpcode<=0x0bfe) { nDataSize=4; }
    1816           8 :         else if (nOpcode<=0x0bff) { nDataSize=22; }
    1817           8 :         else if (nOpcode==0x0c00) { nDataSize=24; } // HeaderOp
    1818           8 :         else if (nOpcode<=0x7eff) { nDataSize=24; }
    1819           6 :         else if (nOpcode<=0x7fff) { nDataSize=254; }
    1820           6 :         else if (nOpcode<=0x80ff) { nDataSize=0; }
    1821           6 :         else                      { sal_uInt32 nTemp; pPict->ReadUInt32( nTemp ) ; nDataSize = nTemp; nDataSize+=4; }
    1822             :     }
    1823             : 
    1824       12028 :     if (nDataSize==0xffffffff) {
    1825           2 :         pPict->SetError(SVSTREAM_FILEFORMAT_ERROR);
    1826           2 :         return 0;
    1827             :     }
    1828       12026 :     return nDataSize;
    1829             : }
    1830             : 
    1831         262 : void PictReader::ReadPict( SvStream & rStreamPict, GDIMetaFile & rGDIMetaFile )
    1832             : {
    1833             :     sal_uInt16          nOpcode;
    1834             :     sal_uInt8           nOneByteOpcode;
    1835             :     sal_uLong           nSize, nPercent, nLastPercent;
    1836             : 
    1837         262 :     pPict               = &rStreamPict;
    1838         262 :     nOrigPos            = pPict->Tell();
    1839         262 :     nOrigNumberFormat   = pPict->GetNumberFormatInt();
    1840             : 
    1841         262 :     aActForeColor       = Color(COL_BLACK);
    1842         262 :     aActBackColor       = Color(COL_WHITE);
    1843         262 :     nActPenSize         = Size(1,1);
    1844         262 :     eActROP             = ROP_OVERPAINT;
    1845         262 :     eActMethod          = PDM_UNDEFINED;
    1846         262 :     aActOvalSize        = Size(1,1);
    1847             : 
    1848         262 :     aActFont.SetCharSet( GetTextEncoding());
    1849         262 :     aActFont.SetFamily(FAMILY_SWISS);
    1850         262 :     aActFont.SetSize(Size(0,12));
    1851         262 :     aActFont.SetAlign(ALIGN_BASELINE);
    1852             : 
    1853         262 :     aHRes = aVRes = Fraction( 1, 1 );
    1854             : 
    1855         262 :     pVirDev = new VirtualDevice();
    1856         262 :     pVirDev->EnableOutput(false);
    1857         262 :     rGDIMetaFile.Record(pVirDev);
    1858             : 
    1859         262 :     pPict->SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN);
    1860             : 
    1861         262 :     sal_uInt64 const nStartPos=pPict->Tell();
    1862         262 :     sal_uInt64 const nRemaining = pPict->remainingSize();
    1863         262 :     Callback(0); nLastPercent=0;
    1864             : 
    1865         262 :     ReadHeader();
    1866             : 
    1867         262 :     aPenPosition=Point(-aBoundingRect.Left(),-aBoundingRect.Top());
    1868         262 :     aTextPosition=aPenPosition;
    1869             : 
    1870         262 :     sal_uInt64 nPos=pPict->Tell();
    1871             : 
    1872             :     for (;;) {
    1873             : 
    1874       12290 :         nPercent = (nPos-nStartPos) * 100 / nRemaining;
    1875       12290 :         if (nLastPercent+4<=nPercent) {
    1876        1850 :             if (Callback((sal_uInt16)nPercent)) break;
    1877        1850 :             nLastPercent=nPercent;
    1878             :         }
    1879             : 
    1880       12290 :         if (IsVersion2 )
    1881       12290 :             pPict->ReadUInt16( nOpcode );
    1882             :         else
    1883             :         {
    1884           0 :             pPict->ReadUChar( nOneByteOpcode );
    1885           0 :             nOpcode=(sal_uInt16)nOneByteOpcode;
    1886             :         }
    1887             : 
    1888       12290 :         if (pPict->GetError())
    1889           2 :             break;
    1890             : 
    1891       12288 :         if (pPict->IsEof())
    1892             :         {
    1893           6 :             pPict->SetError(SVSTREAM_FILEFORMAT_ERROR);
    1894           6 :             break;
    1895             :         }
    1896             : 
    1897       12282 :         if (nOpcode==0x00ff)
    1898         254 :             break;
    1899             : 
    1900       12028 :         nSize=ReadData(nOpcode);
    1901             : 
    1902       12028 :         if ( IsVersion2 )
    1903             :         {
    1904       12028 :             if ( nSize & 1 )
    1905        2480 :                 nSize++;
    1906             : 
    1907       12028 :             nPos+=2+nSize;
    1908             :         }
    1909             :         else
    1910           0 :             nPos+=1+nSize;
    1911             : 
    1912       12028 :         pPict->Seek(nPos);
    1913             :     }
    1914             : 
    1915         262 :     pVirDev->SetClipRegion();
    1916         262 :     rGDIMetaFile.Stop();
    1917         262 :     delete pVirDev;
    1918             : 
    1919         262 :     rGDIMetaFile.SetPrefMapMode( MapMode( MAP_INCH, Point(), aHRes, aVRes ) );
    1920         262 :     rGDIMetaFile.SetPrefSize( aBoundingRect.GetSize() );
    1921             : 
    1922         262 :     pPict->SetNumberFormatInt(nOrigNumberFormat);
    1923             : 
    1924       12290 :     if (pPict->GetError()) pPict->Seek(nOrigPos);
    1925         262 : }
    1926             : 
    1927             : namespace pict {
    1928             : 
    1929         262 : void ReadPictFile(SvStream &rStreamPict, GDIMetaFile& rGDIMetaFile)
    1930             : {
    1931         262 :     PictReader aPictReader;
    1932         262 :     aPictReader.ReadPict(rStreamPict, rGDIMetaFile);
    1933         262 : }
    1934             : 
    1935             : }
    1936             : 
    1937             : //================== GraphicImport - the exported function ================
    1938             : 
    1939             : // this needs to be kept in sync with
    1940             : // ImpFilterLibCacheEntry::GetImportFunction() from
    1941             : // vcl/source/filter/graphicfilter.cxx
    1942             : #if defined(DISABLE_DYNLOADING)
    1943             : #define GraphicImport iptGraphicImport
    1944             : #endif
    1945             : 
    1946             : extern "C" SAL_DLLPUBLIC_EXPORT bool SAL_CALL
    1947         260 : GraphicImport( SvStream& rIStm, Graphic & rGraphic, FilterConfigItem* )
    1948             : {
    1949         260 :     GDIMetaFile aMTF;
    1950         260 :     bool        bRet = false;
    1951             : 
    1952         260 :     pict::ReadPictFile( rIStm, aMTF );
    1953             : 
    1954         260 :     if ( !rIStm.GetError() )
    1955             :     {
    1956         252 :         rGraphic = Graphic( aMTF );
    1957         252 :         bRet = true;
    1958             :     }
    1959             : 
    1960         260 :     return bRet;
    1961          12 : }
    1962             : 
    1963             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10