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

Generated by: LCOV version 1.11