1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ipict.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_goodies.hxx"
35 #include <vcl/bmpacc.hxx>
36 #include <vcl/graph.hxx>
37 #include <tools/poly.hxx>
38 #include <vcl/virdev.hxx>
39 #include <svtools/fltcall.hxx>
42 // MT: NOOLDSV, someone should change the code...
43 enum PenStyle
{ PEN_NULL
, PEN_SOLID
, PEN_DOT
, PEN_DASH
, PEN_DASHDOT
};
44 enum BrushStyle
{ BRUSH_NULL
, BRUSH_SOLID
, BRUSH_HORZ
, BRUSH_VERT
,
45 BRUSH_CROSS
, BRUSH_DIAGCROSS
, BRUSH_UPDIAG
, BRUSH_DOWNDIAG
,
46 BRUSH_25
, BRUSH_50
, BRUSH_75
,
49 //============================ PictReader ==================================
51 enum PictDrawingMethod
{
52 PDM_FRAME
, PDM_PAINT
, PDM_ERASE
, PDM_INVERT
, PDM_FILL
,
53 PDM_TEXT
, PDM_UNDEFINED
60 SvStream
* pPict
; // Die einzulesende Pict-Datei
61 VirtualDevice
* pVirDev
; // Hier werden die Drawing-Methoden aufgerufen.
62 // Dabei findet ein Recording in das GDIMetaFile
64 ULONG nOrigPos
; // Anfaengliche Position in pPict
65 UINT16 nOrigNumberFormat
; // Anfaengliches Nummern-Format von pPict
66 BOOL IsVersion2
; // Ob es ein Version 2 Pictfile ist.
67 Rectangle aBoundingRect
; // Min/Max-Rechteck fuer die ganze Zeichnung
73 PenStyle eActPenPenStyle
;
74 BrushStyle eActPenBrushStyle
;
75 BrushStyle eActFillStyle
;
76 BrushStyle eActBackStyle
;
79 PictDrawingMethod eActMethod
;
86 BOOL
Callback(USHORT nPercent
);
90 Point
ReadDeltaH(Point aBase
);
91 Point
ReadDeltaV(Point aBase
);
93 Point
ReadUnsignedDeltaH(Point aBase
);
94 Point
ReadUnsignedDeltaV(Point aBase
);
100 Color
ReadRGBColor();
102 void ReadRectangle(Rectangle
& rRect
);
104 ULONG
ReadPolygon(Polygon
& rPoly
);
106 ULONG
ReadPattern(PenStyle
* pPenStyle
, BrushStyle
* pBrushStyle
);
108 ULONG
ReadPixPattern(PenStyle
* pPenStyle
, BrushStyle
* pBrushStyle
);
111 ULONG
ReadAndDrawRect(PictDrawingMethod eMethod
);
112 ULONG
ReadAndDrawSameRect(PictDrawingMethod eMethod
);
114 Rectangle aLastRoundRect
;
115 ULONG
ReadAndDrawRoundRect(PictDrawingMethod eMethod
);
116 ULONG
ReadAndDrawSameRoundRect(PictDrawingMethod eMethod
);
119 ULONG
ReadAndDrawOval(PictDrawingMethod eMethod
);
120 ULONG
ReadAndDrawSameOval(PictDrawingMethod eMethod
);
122 Polygon aLastPolygon
;
123 ULONG
ReadAndDrawPolygon(PictDrawingMethod eMethod
);
124 ULONG
ReadAndDrawSamePolygon(PictDrawingMethod eMethod
);
126 Rectangle aLastArcRect
;
127 ULONG
ReadAndDrawArc(PictDrawingMethod eMethod
);
128 ULONG
ReadAndDrawSameArc(PictDrawingMethod eMethod
);
130 ULONG
ReadAndDrawRgn(PictDrawingMethod eMethod
);
131 ULONG
ReadAndDrawSameRgn(PictDrawingMethod eMethod
);
133 void DrawingMethod(PictDrawingMethod eMethod
);
135 ULONG
ReadAndDrawText();
137 ULONG
ReadPixMapEtc(Bitmap
& rBitmap
, BOOL bBaseAddr
, BOOL bColorTable
,
138 Rectangle
* pSrcRect
, Rectangle
* pDestRect
,
139 BOOL bMode
, BOOL bMaskRgn
);
142 // Liesst den Kopf der Pict-Datei, setzt IsVersion2 und aBoundingRect
144 ULONG
ReadData(USHORT nOpcode
);
145 // Liesst die Daten eines Opcodes ein und fuehrt die Operation aus.
146 // Auf jeden Fall wird die Anzahl der Datenbytes zu dem Opcode
149 void SetLineColor( const Color
& rColor
);
150 void SetFillColor( const Color
& rColor
);
156 void ReadPict( SvStream
& rStreamPict
, GDIMetaFile
& rGDIMetaFile
);
157 // Liesst aus dem Stream eine Pict-Datei und fuellt das GDIMetaFile
161 //------------------------------------------------------------------------------------------------
164 switch ( nPixelSize ) \
167 pAcc->SetPixel( ny, nx++, nDat >> 7 ); \
168 if ( nx == nWidth ) break; \
169 pAcc->SetPixel( ny, nx++, nDat >> 6 ); \
170 if ( nx == nWidth ) break; \
171 pAcc->SetPixel( ny, nx++, nDat >> 5 ); \
172 if ( nx == nWidth ) break; \
173 pAcc->SetPixel( ny, nx++, nDat >> 4 ); \
174 if ( nx == nWidth ) break; \
175 pAcc->SetPixel( ny, nx++, nDat >> 3 ); \
176 if ( nx == nWidth ) break; \
177 pAcc->SetPixel( ny, nx++, nDat >> 2 ); \
178 if ( nx == nWidth ) break; \
179 pAcc->SetPixel( ny, nx++, nDat >> 1 ); \
180 if ( nx == nWidth ) break; \
181 pAcc->SetPixel( ny, nx++, nDat ); \
184 pAcc->SetPixel( ny, nx++, nDat >> 6 ); \
185 if ( nx == nWidth ) break; \
186 pAcc->SetPixel( ny, nx++, nDat >> 4 & 3); \
187 if ( nx == nWidth ) break; \
188 pAcc->SetPixel( ny, nx++, nDat >> 2 & 3 ); \
189 if ( nx == nWidth ) break; \
190 pAcc->SetPixel( ny, nx++, nDat & 3); \
193 pAcc->SetPixel( ny, nx++, nDat >> 4 ); \
194 if ( nx == nWidth ) break; \
195 pAcc->SetPixel( ny, nx++, nDat ); \
198 pAcc->SetPixel( ny, nx++, nDat ); \
202 //------------------------------------------------------------------------------------------------
204 #define BITMAPERROR \
207 aBitmap.ReleaseAccess( pAcc ); \
209 aBitmap.ReleaseAccess( pReadAcc ); \
213 //=================== Methoden von PictReader ==============================
215 void PictReader::SetLineColor( const Color
& rColor
)
217 pVirDev
->SetLineColor( rColor
);
220 void PictReader::SetFillColor( const Color
& rColor
)
222 pVirDev
->SetFillColor( rColor
);
225 BOOL
PictReader::Callback(USHORT
/*nPercent*/)
228 if (pCallback!=NULL) {
229 if (((*pCallback)(pCallerData,nPercent))==TRUE) {
230 pPict->SetError(SVSTREAM_FILEFORMAT_ERROR);
238 Point
PictReader::ReadPoint()
244 return Point( (long)nx
- aBoundingRect
.Left(),
245 (long)ny
- aBoundingRect
.Top() );
248 Point
PictReader::ReadDeltaH(Point aBase
)
252 *pPict
>> ((char&)ndh
);
254 return Point( aBase
.X() + (long)ndh
, aBase
.Y() );
257 Point
PictReader::ReadDeltaV(Point aBase
)
261 *pPict
>> ((char&)ndv
);
263 return Point( aBase
.X(), aBase
.Y() + (long)ndv
);
266 Point
PictReader::ReadUnsignedDeltaH(Point aBase
)
272 return Point( aBase
.X() + (long)ndh
, aBase
.Y() );
275 Point
PictReader::ReadUnsignedDeltaV(Point aBase
)
281 return Point( aBase
.X(), aBase
.Y() + (long)ndv
);
284 Size
PictReader::ReadSize()
290 return Size( (long)nx
, (long)ny
);
293 Color
PictReader::ReadColor()
301 case 33: aCol
=Color( COL_BLACK
); break;
302 case 30: aCol
=Color( COL_WHITE
); break;
303 case 205: aCol
=Color( COL_LIGHTRED
); break;
304 case 341: aCol
=Color( COL_LIGHTGREEN
); break;
305 case 409: aCol
=Color( COL_LIGHTBLUE
); break;
306 case 273: aCol
=Color( COL_LIGHTCYAN
); break;
307 case 137: aCol
=Color( COL_LIGHTMAGENTA
); break;
308 case 69: aCol
=Color( COL_YELLOW
); break;
309 default: aCol
=Color( COL_LIGHTGRAY
);
315 Color
PictReader::ReadRGBColor()
319 *pPict
>> nR
>> nG
>> nB
;
320 return Color( (BYTE
) ( nR
>> 8 ), (BYTE
) ( nG
>> 8 ), (BYTE
) ( nB
>> 8 ) );
324 void PictReader::ReadRectangle(Rectangle
& rRect
)
326 Point aTopLeft
, aBottomRight
;
328 aTopLeft
=ReadPoint();
329 aBottomRight
=ReadPoint();
330 aBottomRight
.X() -= 1;
331 aBottomRight
.Y() -= 1;
332 rRect
=Rectangle(aTopLeft
,aBottomRight
);
336 ULONG
PictReader::ReadPolygon(Polygon
& rPoly
)
343 nDataSize
=(ULONG
)nSize
;
345 rPoly
.SetSize(nSize
);
346 for (i
=0; i
<nSize
; i
++) rPoly
.SetPoint(ReadPoint(),i
);
350 ULONG
PictReader::ReadPattern(PenStyle
* pPenStyle
, BrushStyle
* pBrushStyle
)
352 short nx
,ny
,nBitCount
;
353 unsigned char nbyte
[8];
356 ULONG nHiBytes
, nLoBytes
;
358 // Anzahl der Bits im Pattern zaehlen, die auf 1 gesetzt sind:
360 for (ny
=0; ny
<8; ny
++) {
361 *pPict
>> ((char&)nbyte
[ny
]);
362 for (nx
=0; nx
<8; nx
++) {
363 if ( (nbyte
[ny
] & (1<<nx
)) != 0 ) nBitCount
++;
367 // Pattern in 2 Langworten unterbringen:
368 nHiBytes
=(((((((ULONG
)nbyte
[0])<<8)|
369 (ULONG
)nbyte
[1])<<8)|
370 (ULONG
)nbyte
[2])<<8)|
372 nLoBytes
=(((((((ULONG
)nbyte
[4])<<8)|
373 (ULONG
)nbyte
[5])<<8)|
374 (ULONG
)nbyte
[6])<<8)|
377 // Einen PenStyle machen:
378 if (nBitCount
<=0) ePnStyle
=PEN_NULL
;
379 else if (nBitCount
<=16) ePnStyle
=PEN_DOT
;
380 else if (nBitCount
<=32) ePnStyle
=PEN_DASHDOT
;
381 else if (nBitCount
<=48) ePnStyle
=PEN_DASH
;
382 else ePnStyle
=PEN_SOLID
;
384 // Einen BrushStyle machen:
385 if (nHiBytes
==0xffffffff && nLoBytes
==0xffffffff) eBrStyle
=BRUSH_SOLID
;
386 else if (nHiBytes
==0xff000000 && nLoBytes
==0x00000000) eBrStyle
=BRUSH_HORZ
;
387 else if (nHiBytes
==0x80808080 && nLoBytes
==0x80808080) eBrStyle
=BRUSH_VERT
;
388 else if (nHiBytes
==0xff808080 && nLoBytes
==0x80808080) eBrStyle
=BRUSH_CROSS
;
389 else if (nHiBytes
==0x01824428 && nLoBytes
==0x10284482) eBrStyle
=BRUSH_DIAGCROSS
;
390 else if (nHiBytes
==0x80402010 && nLoBytes
==0x08040201) eBrStyle
=BRUSH_UPDIAG
;
391 else if (nHiBytes
==0x01020408 && nLoBytes
==0x10204080) eBrStyle
=BRUSH_DOWNDIAG
;
392 else if (nBitCount
<=24) eBrStyle
=BRUSH_25
;
393 else if (nBitCount
<=40) eBrStyle
=BRUSH_50
;
394 else if (nBitCount
<=56) eBrStyle
=BRUSH_75
;
395 else eBrStyle
=BRUSH_SOLID
;
397 if (pPenStyle
!=0) *pPenStyle
=ePnStyle
;
399 if (pBrushStyle
!=0) *pBrushStyle
=eBrStyle
;
404 ULONG
PictReader::ReadPixPattern(PenStyle
* pPenStyle
, BrushStyle
* pBrushStyle
)
406 // Keine Ahnung, ob dies richtig ist, weil kein Bild gefunden, das
407 // PixPatterns enthaelt. Auch hier nur der Versuch, die Groesse der Daten zu
408 // ermitteln, und einfache StarView-Styles daraus zu machen. Gluecklicherweise
409 // enthaelt ein PixPattern immer auch ein normales Pattern.
417 ReadPattern(pPenStyle
,pBrushStyle
);
418 nDataSize
=ReadPixMapEtc(aBMP
,FALSE
,TRUE
,NULL
,NULL
,FALSE
,FALSE
);
419 if (nDataSize
!=0xffffffff) nDataSize
+=10;
421 else if (nPatType
==2) {
422 ReadPattern(pPenStyle
,pBrushStyle
);
423 pPict
->SeekRel(6); // RGBColor
426 else nDataSize
=0xffffffff;
431 ULONG
PictReader::ReadAndDrawRect(PictDrawingMethod eMethod
)
433 ReadRectangle(aLastRect
);
434 DrawingMethod(eMethod
);
435 pVirDev
->DrawRect(aLastRect
);
439 ULONG
PictReader::ReadAndDrawSameRect(PictDrawingMethod eMethod
)
441 DrawingMethod(eMethod
);
442 pVirDev
->DrawRect(aLastRect
);
446 ULONG
PictReader::ReadAndDrawRoundRect(PictDrawingMethod eMethod
)
448 ReadRectangle(aLastRoundRect
);
449 DrawingMethod(eMethod
);
450 pVirDev
->DrawRect(aLastRoundRect
,aActOvalSize
.Width(),aActOvalSize
.Height());
454 ULONG
PictReader::ReadAndDrawSameRoundRect(PictDrawingMethod eMethod
)
456 DrawingMethod(eMethod
);
457 pVirDev
->DrawRect(aLastRoundRect
,aActOvalSize
.Width(),aActOvalSize
.Height());
461 ULONG
PictReader::ReadAndDrawOval(PictDrawingMethod eMethod
)
463 ReadRectangle(aLastOval
);
464 DrawingMethod(eMethod
);
465 pVirDev
->DrawEllipse(aLastOval
);
469 ULONG
PictReader::ReadAndDrawSameOval(PictDrawingMethod eMethod
)
471 DrawingMethod(eMethod
);
472 pVirDev
->DrawEllipse(aLastOval
);
476 ULONG
PictReader::ReadAndDrawPolygon(PictDrawingMethod eMethod
)
480 nDataSize
=ReadPolygon(aLastPolygon
);
481 DrawingMethod(eMethod
);
482 if (eMethod
==PDM_FRAME
) pVirDev
->DrawPolyLine(aLastPolygon
);
483 else pVirDev
->DrawPolygon(aLastPolygon
);
487 ULONG
PictReader::ReadAndDrawSamePolygon(PictDrawingMethod eMethod
)
489 DrawingMethod(eMethod
);
490 if (eMethod
==PDM_FRAME
) pVirDev
->DrawPolyLine(aLastPolygon
);
491 else pVirDev
->DrawPolygon(aLastPolygon
);
496 ULONG
PictReader::ReadAndDrawArc(PictDrawingMethod eMethod
)
498 short nstartAngle
, narcAngle
;
500 Point aStartPt
, aEndPt
, aCenter
;
502 ReadRectangle(aLastArcRect
);
503 *pPict
>> nstartAngle
>> narcAngle
;
505 nstartAngle
= nstartAngle
+ narcAngle
;
506 narcAngle
=-narcAngle
;
508 fAng1
=((double)nstartAngle
)/180.0*3.14159265359;
509 fAng2
=((double)(nstartAngle
+narcAngle
))/180.0*3.14159265359;
510 aCenter
=Point((aLastArcRect
.Left()+aLastArcRect
.Right())/2,
511 (aLastArcRect
.Top()+aLastArcRect
.Bottom())/2);
512 aStartPt
=Point(aCenter
.X()+(long)( sin(fAng2
)*256.0),
513 aCenter
.Y()+(long)(-cos(fAng2
)*256.0));
514 aEndPt
= Point(aCenter
.X()+(long)( sin(fAng1
)*256.0),
515 aCenter
.Y()+(long)(-cos(fAng1
)*256.0));
516 DrawingMethod(eMethod
);
517 if (eMethod
==PDM_FRAME
) pVirDev
->DrawArc(aLastArcRect
,aStartPt
,aEndPt
);
518 else pVirDev
->DrawPie(aLastArcRect
,aStartPt
,aEndPt
);
522 ULONG
PictReader::ReadAndDrawSameArc(PictDrawingMethod eMethod
)
524 short nstartAngle
, narcAngle
;
526 Point aStartPt
, aEndPt
, aCenter
;
528 *pPict
>> nstartAngle
>> narcAngle
;
530 nstartAngle
= nstartAngle
+ narcAngle
;
531 narcAngle
=-narcAngle
;
533 fAng1
=((double)nstartAngle
)/180.0*3.14159265359;
534 fAng2
=((double)(nstartAngle
+narcAngle
))/180.0*3.14159265359;
535 aCenter
=Point((aLastArcRect
.Left()+aLastArcRect
.Right())/2,
536 (aLastArcRect
.Top()+aLastArcRect
.Bottom())/2);
537 aStartPt
=Point(aCenter
.X()+(long)( sin(fAng2
)*256.0),
538 aCenter
.Y()+(long)(-cos(fAng2
)*256.0));
539 aEndPt
= Point(aCenter
.X()+(long)( sin(fAng1
)*256.0),
540 aCenter
.Y()+(long)(-cos(fAng1
)*256.0));
541 DrawingMethod(eMethod
);
542 if (eMethod
==PDM_FRAME
) pVirDev
->DrawArc(aLastArcRect
,aStartPt
,aEndPt
);
543 else pVirDev
->DrawPie(aLastArcRect
,aStartPt
,aEndPt
);
547 ULONG
PictReader::ReadAndDrawRgn(PictDrawingMethod eMethod
)
551 DrawingMethod(eMethod
);
557 ULONG
PictReader::ReadAndDrawSameRgn(PictDrawingMethod eMethod
)
559 DrawingMethod(eMethod
);
564 void PictReader::DrawingMethod(PictDrawingMethod eMethod
)
566 if( eActMethod
==eMethod
) return;
569 SetLineColor( aActForeColor
);
570 SetFillColor( Color(COL_TRANSPARENT
) );
571 pVirDev
->SetRasterOp(eActROP
);
574 SetLineColor( Color(COL_TRANSPARENT
) );
575 SetFillColor( aActForeColor
);
576 pVirDev
->SetRasterOp(eActROP
);
579 SetLineColor( Color(COL_TRANSPARENT
) );
580 SetFillColor( aActForeColor
);
581 pVirDev
->SetRasterOp(ROP_OVERPAINT
);
584 SetLineColor( Color(COL_TRANSPARENT
));
585 SetFillColor( Color( COL_BLACK
) );
586 pVirDev
->SetRasterOp(ROP_INVERT
);
589 SetLineColor( Color(COL_TRANSPARENT
) );
590 SetFillColor( aActForeColor
);
591 pVirDev
->SetRasterOp(ROP_OVERPAINT
);
594 aActFont
.SetColor(aActForeColor
);
595 aActFont
.SetFillColor(aActBackColor
);
596 aActFont
.SetTransparent(TRUE
);
597 pVirDev
->SetFont(aActFont
);
598 pVirDev
->SetRasterOp(ROP_OVERPAINT
);
601 break; // -Wall undefined not handled...
606 ULONG
PictReader::ReadAndDrawText()
609 sal_uInt32 nLen
, nDataLen
;
612 DrawingMethod(PDM_TEXT
);
613 *pPict
>> nByteLen
; nLen
=((ULONG
)nByteLen
)&0x000000ff;
615 pPict
->Read( &sText
, nLen
);
617 // Stoerende Steuerzeuichen wegnehmen:
618 while ( nLen
> 0 && ( (unsigned char)sText
[ nLen
- 1 ] ) < 32 )
621 String
aString( (const sal_Char
*)&sText
, gsl_getSystemTextEncoding() );
622 pVirDev
->DrawText( Point( aTextPosition
.X(), aTextPosition
.Y() ), aString
);
626 ULONG
PictReader::ReadPixMapEtc( Bitmap
&rBitmap
, BOOL bBaseAddr
, BOOL bColorTable
, Rectangle
* pSrcRect
,
627 Rectangle
* pDestRect
, BOOL bMode
, BOOL bMaskRgn
)
630 BitmapWriteAccess
* pAcc
= NULL
;
631 BitmapReadAccess
* pReadAcc
= NULL
;
632 USHORT ny
, nx
, nColTabSize
;
633 USHORT nRowBytes
, nBndX
, nBndY
, nWidth
, nHeight
, nVersion
, nPackType
, nPixelType
,
634 nPixelSize
, nCmpCount
, nCmpSize
;
635 sal_uInt32 nPackSize
, nPlaneBytes
, nHRes
, nVRes
;
636 BYTE nDat
, nRed
, nGreen
, nBlue
, nDummy
;
637 ULONG i
, nDataSize
= 0;
639 // In nDataSize wird mitgerechnet, wie gross die gesammten Daten sind.
642 // ggf. BaseAddr ueberlesen
649 // PixMap oder Bitmap-Struktur einlesen;
650 *pPict
>> nRowBytes
>> nBndY
>> nBndX
>> nHeight
>> nWidth
;
651 nHeight
= nHeight
- nBndY
;
652 nWidth
= nWidth
- nBndX
;
654 if ( ( nRowBytes
& 0x8000 ) != 0 )
657 *pPict
>> nVersion
>> nPackType
>> nPackSize
>> nHRes
>> nVRes
>> nPixelType
>>
658 nPixelSize
>> nCmpCount
>> nCmpSize
>> nPlaneBytes
;
663 sal_uInt16 nDstBitCount
= nPixelSize
;
664 if ( nDstBitCount
> 8 )
666 else if ( nDstBitCount
== 2 )
668 aBitmap
= Bitmap( Size( nWidth
, nHeight
), nDstBitCount
);
670 if ( ( pAcc
= aBitmap
.AcquireWriteAccess() ) == NULL
)
676 *pPict
>> nColTabSize
;
678 if ( ++nColTabSize
> 256 )
681 pAcc
->SetPaletteEntryCount( nColTabSize
);
683 for ( i
= 0; i
< nColTabSize
; i
++ )
686 *pPict
>> nRed
>> nDummy
>> nGreen
>> nDummy
>> nBlue
>> nDummy
;
687 pAcc
->SetPaletteColor( (USHORT
) i
, BitmapColor( nRed
, nGreen
, nBlue
) );
689 nDataSize
+= 8 + nColTabSize
* 8;
697 nPackSize
= nHRes
= nVRes
= nPlaneBytes
= 0;
699 nPixelSize
= nCmpCount
= nCmpSize
= 1;
701 aBitmap
= Bitmap( Size( nWidth
, nHeight
), 1 );
702 if ( ( pAcc
= aBitmap
.AcquireWriteAccess() ) == NULL
)
704 pAcc
->SetPaletteEntryCount( 2 );
705 pAcc
->SetPaletteColor( 0, BitmapColor( 0xff, 0xff, 0xff ) );
706 pAcc
->SetPaletteColor( 1, BitmapColor( 0, 0, 0 ) );
709 // ggf. Quell-Rechteck einlesen:
712 USHORT nTop
, nLeft
, nBottom
, nRight
;
713 *pPict
>> nTop
>> nLeft
>> nBottom
>> nRight
;
714 *pSrcRect
= Rectangle( (ULONG
)nLeft
, (ULONG
)nTop
, (ULONG
)nRight
, (ULONG
)nBottom
);
718 // ggf. Ziel-Rechteck einlesen:
719 if ( pDestRect
!= 0 )
724 *pDestRect
= Rectangle( aTL
, aBR
);
728 // ggf. Modus einlesen (bzw. ueberspringen):
735 // ggf. Region einlesen (bzw. ueberspringen):
740 pPict
->SeekRel( nSize
- 2 );
741 nDataSize
+= (ULONG
)nSize
;
744 // aSMem << (nHRes/1665L) << (nVRes/1665L) << ((ULONG)0) << ((ULONG)0);
746 // Lese und Schreibe Bitmap-Bits:
747 if ( nPixelSize
== 1 || nPixelSize
== 2 || nPixelSize
== 4 || nPixelSize
== 8 )
749 BYTE nByteCountAsByte
, nFlagCounterByte
;
750 USHORT nByteCount
, nCount
, nSrcBPL
, nDestBPL
;
752 if ( nPixelSize
== 1 ) nSrcBPL
= ( nWidth
+ 7 ) >> 3;
753 else if ( nPixelSize
== 2 ) nSrcBPL
= ( nWidth
+ 3 ) >> 2;
754 else if ( nPixelSize
== 4 ) nSrcBPL
= ( nWidth
+ 1 ) >> 1;
755 else nSrcBPL
= nWidth
;
756 nDestBPL
= ( nSrcBPL
+ 3 ) & 0xfffc;
757 if ( nRowBytes
< nSrcBPL
|| nRowBytes
> nDestBPL
)
760 for ( ny
= 0; ny
< nHeight
; ny
++ )
763 if ( nRowBytes
< 8 || nPackType
== 1 )
765 for ( i
= 0; i
< nRowBytes
; i
++ )
771 nDataSize
+= nRowBytes
;
775 if ( nRowBytes
> 250 )
777 *pPict
>> nByteCount
;
778 nDataSize
+= 2 + (ULONG
)nByteCount
;
782 *pPict
>> nByteCountAsByte
;
783 nByteCount
= ( (USHORT
)nByteCountAsByte
) & 0x00ff;
784 nDataSize
+= 1 + (ULONG
)nByteCount
;
789 *pPict
>> nFlagCounterByte
;
790 if ( ( nFlagCounterByte
& 0x80 ) == 0 )
792 nCount
= ( (USHORT
)nFlagCounterByte
) + 1;
793 for ( i
= 0; i
< nCount
; i
++ )
799 nByteCount
-= 1 + nCount
;
803 nCount
= ( 1 - ( ( (USHORT
)nFlagCounterByte
) | 0xff00 ) );
805 for ( i
= 0; i
< nCount
; i
++ )
816 else if ( nPixelSize
== 16 )
818 BYTE nByteCountAsByte
, nFlagCounterByte
;
819 USHORT nByteCount
, nCount
, nDestBPL
,nD
;
822 if ( nRowBytes
< 2 * nWidth
)
825 nDestBPL
= ( ( 3 * nWidth
) + 0x0003 ) & 0xfffc;
827 for ( ny
= 0; ny
< nHeight
; ny
++ )
830 if ( nRowBytes
< 8 || nPackType
== 1 )
832 for ( i
= 0; i
< nWidth
; i
++ )
835 nRed
= (BYTE
)( nD
>> 7 );
836 nGreen
= (BYTE
)( nD
>> 2 );
837 nBlue
= (BYTE
)( nD
<< 3 );
838 pAcc
->SetPixel( ny
, nx
++, BitmapColor( nRed
, nGreen
, nBlue
) );
840 nDataSize
+= ( (ULONG
)nWidth
) * 2;
844 nSrcBitsPos
= pPict
->Tell();
845 if ( nRowBytes
> 250 )
847 *pPict
>> nByteCount
;
852 *pPict
>> nByteCountAsByte
;
853 nByteCount
= ( (USHORT
)nByteCountAsByte
) & 0x00ff;
856 while ( nx
!= nWidth
)
858 *pPict
>> nFlagCounterByte
;
859 if ( (nFlagCounterByte
& 0x80) == 0)
861 nCount
=((USHORT
)nFlagCounterByte
)+1;
862 if ( nCount
+ nx
> nWidth
) // SJ: the RLE decoding seems not to be correct here,
863 nCount
= nWidth
- nx
; // I don't want to change this until I have a bugdoc for
864 for (i
=0; i
<nCount
; i
++) // this case. Have a look at 32bit, there I changed the
865 { // encoding, so that it is used a straight forward array
867 nRed
= (BYTE
)( nD
>> 7 );
868 nGreen
= (BYTE
)( nD
>> 2 );
869 nBlue
= (BYTE
)( nD
<< 3 );
870 pAcc
->SetPixel( ny
, nx
++, BitmapColor( nRed
, nGreen
, nBlue
) );
875 nCount
=(1-(((USHORT
)nFlagCounterByte
)|0xff00));
876 if ( nCount
+ nx
> nWidth
)
877 nCount
= nWidth
- nx
;
879 nRed
= (BYTE
)( nD
>> 7 );
880 nGreen
= (BYTE
)( nD
>> 2 );
881 nBlue
= (BYTE
)( nD
<< 3 );
882 for (i
=0; i
<nCount
; i
++)
884 pAcc
->SetPixel( ny
, nx
++, BitmapColor( nRed
, nGreen
, nBlue
) );
888 nDataSize
+=(ULONG
)nByteCount
;
889 pPict
->Seek(nSrcBitsPos
+(ULONG
)nByteCount
);
893 else if (nPixelSize
==32)
895 BYTE nByteCountAsByte
, nFlagCounterByte
;
896 USHORT nByteCount
, nCount
;
898 BitmapColor aBitmapColor
;
899 if ( ( pReadAcc
= aBitmap
.AcquireReadAccess() ) == NULL
)
901 if ( nRowBytes
!= 4*nWidth
)
904 if ( nRowBytes
< 8 || nPackType
== 1 )
906 for ( ny
= 0; ny
< nHeight
; ny
++ )
908 if ( nRowBytes
< 8 || nPackType
== 1 )
910 for ( nx
= 0; nx
< nWidth
; nx
++ )
912 *pPict
>> nDummy
>> nRed
>> nGreen
>> nBlue
;
913 pAcc
->SetPixel( ny
, nx
, BitmapColor( nRed
, nGreen
, nBlue
) );
915 nDataSize
+= ( (ULONG
)nWidth
) * 4;
919 else if ( nPackType
== 2 )
921 for ( ny
= 0; ny
< nHeight
; ny
++ )
923 for ( nx
= 0; nx
< nWidth
; nx
++ )
925 *pPict
>> nRed
>> nGreen
>> nBlue
;
926 pAcc
->SetPixel( ny
, nx
, BitmapColor( nRed
, nGreen
, nBlue
) );
928 nDataSize
+= ( (ULONG
)nWidth
) * 3;
933 if ( ( nCmpCount
== 3 ) || ( nCmpCount
== 4 ) )
935 sal_uInt8
* pScanline
= new sal_uInt8
[ nWidth
* nCmpCount
];
936 for ( ny
= 0; ny
< nHeight
; ny
++ )
938 nSrcBitsPos
= pPict
->Tell();
939 if ( nRowBytes
> 250 )
941 *pPict
>> nByteCount
;
946 *pPict
>> nByteCountAsByte
;
947 nByteCount
= (BYTE
)nByteCountAsByte
;
951 while( i
< (sal_uInt32
)( nWidth
* nCmpCount
) )
953 *pPict
>> nFlagCounterByte
;
954 if ( ( nFlagCounterByte
& 0x80 ) == 0)
956 nCount
= ( (USHORT
)nFlagCounterByte
) + 1;
957 if ( ( i
+ nCount
) > (sal_uInt32
)( nWidth
* nCmpCount
) )
958 nCount
= (sal_uInt16
)( nWidth
* nCmpCount
- i
);
962 pScanline
[ i
++ ] = nDat
;
967 nCount
= ( 1 - ( ( (USHORT
)nFlagCounterByte
) | 0xff00 ) );
968 if ( ( i
+ nCount
) > (sal_uInt32
)( nWidth
* nCmpCount
) )
969 nCount
= (sal_uInt16
)( nWidth
* nCmpCount
- i
);
972 pScanline
[ i
++ ] = nDat
;
975 sal_uInt8
* pTmp
= pScanline
;
976 if ( nCmpCount
== 4 )
978 for ( nx
= 0; nx
< nWidth
; pTmp
++ )
979 pAcc
->SetPixel( ny
, nx
++, BitmapColor( *pTmp
, pTmp
[ nWidth
], pTmp
[ 2 * nWidth
] ) );
980 nDataSize
+= (ULONG
)nByteCount
;
981 pPict
->Seek( nSrcBitsPos
+ (ULONG
)nByteCount
);
990 aBitmap
.ReleaseAccess( pReadAcc
);
991 aBitmap
.ReleaseAccess( pAcc
);
996 void PictReader::ReadHeader()
1002 pPict
->SeekRel( 10 );
1003 pPict
->Read( sBuf
, 3 );
1004 if ( sBuf
[ 0 ] == 0x00 && sBuf
[ 1 ] == 0x11 && ( sBuf
[ 2 ] == 0x01 || sBuf
[ 2 ] == 0x02 ) )
1005 pPict
->SeekRel( -13 ); // this maybe a pict from a ms document
1007 pPict
->SeekRel( 512 - 13 ); // 512 Bytes Muell am Anfang
1009 pPict
->SeekRel(2); // Lo-16-bits von "picture size"
1010 *pPict
>> y1
>> x1
>> y2
>> x2
; // Rahmen-Rechteck des Bildes
1011 aBoundingRect
=Rectangle( x1
,y1
, --x2
, --y2
);
1013 // Jetzt kommen x-beliebig viele Nullen
1014 // (in manchen Dateien tatsaechlich mehr als eine):
1015 do { *pPict
>> nC
; } while (nC
==0 && pPict
->IsEof()==FALSE
);
1017 // dann sollte der Versions-Opcode 0x11 folgen, dann die Versionsnummer:
1022 IsVersion2
= FALSE
; // Version 1
1023 else // Version 2 oder hoeher
1026 // 3 Bytes ueberspringen, um auf
1027 // ExtVersion2 oder Version2 zu kommen
1028 pPict
->SeekRel( 3 );
1031 // nachsehen, ob wir einen Extended-Version2-Header (==-2) haben
1032 // oder einen einfachen Version2-Header (==-1);
1033 // dementsprechend Aufloesung einlesen oder nicht
1034 if ( nExtVer
== -2 )
1036 sal_Int16 nReserved
;
1037 sal_Int32 nHResFixed
, nVResFixed
;
1038 *pPict
>> nReserved
>> nHResFixed
>> nVResFixed
;
1039 double fHRes
= nHResFixed
;
1041 double fVRes
= nVResFixed
;
1045 *pPict
>> y1
>> x1
>> y2
>> x2
; // reading the optimal bounding rect
1046 aBoundingRect
=Rectangle( x1
,y1
, --x2
, --y2
);
1047 pPict
->SeekRel( -22 );
1051 pPict
->SeekRel( -4 );
1057 // Eigentlich ist dies wohl kein Pict-File, aber es gibt tatsaechlich
1058 // Dateien, bei denen mehr als 512 Bytes "Muell" am Anfang stehen.
1059 // Somit koennte es theoretisch folgende Art von Header geben:
1060 // <beliebig viele Bytes Muell> <Picture-Size (Lo-Bytes)> <BoundingRect>
1061 // <beliebig viele Nullen> <0x11> ..
1062 // Da aber in so einem Fall die Position von <BoundingRect> kaum auszumachen ist,
1063 // gehen wir nun davon aus, dass in einer Datei immer entweder genau 512 Bytes Muell
1064 // am Anfang sind (wie oben versucht), oder (wie normalerweise ueblich) genau eine 0 zwischen
1065 // Bounding-Rectangle und 0x11. Des weiteren mag es hoechstens 1024 Bytes Muell geben,
1066 // und das Ganze nur fuer Version 1 oder 2.
1067 // Somit suchen wir nun nach der Folge 0x00,0x11,0x01 oder 0x00,0x11,0x02 innerhalb der
1068 // "zweiten" 512 Bytes, und nehmen an, dass davor das Bounding-Rect steht, und hoffen
1069 // dass das alles so seine Richtigkeit hat.
1074 *pPict
>> n1
>> n2
>> n3
;
1075 for (i
=0; i
<512; i
++) {
1076 if (n1
==0x00 && n2
==0x11 && (n3
==0x01 || n3
==0x02)) { Found
=1; break; }
1077 n1
=n2
; n2
=n3
; *pPict
>> n3
;
1080 pPict
->SeekRel(-11);
1081 *pPict
>> y1
>> x1
>> y2
>> x2
;
1082 // Lieber nochmal nachsehen, ob das Bounding-Rectangle gut zu sein scheint:
1083 if (x1
+10<x2
&& y1
+10<y2
&& y1
>=-2048 && x1
>=-2048 && x2
<=2048 && y2
<=2048) {
1084 aBoundingRect
=Rectangle( x1
, y1
, --x2
, --y2
);
1094 else pPict
->SetError(SVSTREAM_FILEFORMAT_ERROR
);
1096 else pPict
->SetError(SVSTREAM_FILEFORMAT_ERROR
);
1101 ULONG
PictReader::ReadData(USHORT nOpcode
)
1113 case 0x0001: { // Clip
1117 ReadRectangle(aRect
);
1118 pVirDev
->SetClipRegion( Region( aRect
) );
1121 case 0x0002: // BkPat
1122 nDataSize
=ReadPattern(NULL
,&eActBackStyle
);
1123 eActMethod
=PDM_UNDEFINED
;
1126 case 0x0003: // TxFont
1128 if (nUSHORT
<= 1) aActFont
.SetFamily(FAMILY_SWISS
);
1129 else if (nUSHORT
<= 12) aActFont
.SetFamily(FAMILY_DECORATIVE
);
1130 else if (nUSHORT
<= 20) aActFont
.SetFamily(FAMILY_ROMAN
);
1131 else if (nUSHORT
== 21) aActFont
.SetFamily(FAMILY_SWISS
);
1132 else if (nUSHORT
== 22) aActFont
.SetFamily(FAMILY_MODERN
);
1133 else if (nUSHORT
<= 1023) aActFont
.SetFamily(FAMILY_SWISS
);
1134 else aActFont
.SetFamily(FAMILY_ROMAN
);
1135 if ( nUSHORT
== 23 ) aActFont
.SetCharSet( RTL_TEXTENCODING_SYMBOL
);
1136 else aActFont
.SetCharSet( gsl_getSystemTextEncoding() );
1137 eActMethod
=PDM_UNDEFINED
;
1141 case 0x0004: { // TxFace
1144 if ( (nFace
& 0x01)!=0 ) aActFont
.SetWeight(WEIGHT_BOLD
);
1145 else aActFont
.SetWeight(WEIGHT_NORMAL
);
1146 if ( (nFace
& 0x02)!=0 ) aActFont
.SetItalic(ITALIC_NORMAL
);
1147 else aActFont
.SetItalic(ITALIC_NONE
);
1148 if ( (nFace
& 0x04)!=0 ) aActFont
.SetUnderline(UNDERLINE_SINGLE
);
1149 else aActFont
.SetUnderline(UNDERLINE_NONE
);
1150 if ( (nFace
& 0x08)!=0 ) aActFont
.SetOutline(TRUE
);
1151 else aActFont
.SetOutline(FALSE
);
1152 if ( (nFace
& 0x10)!=0 ) aActFont
.SetShadow(TRUE
);
1153 else aActFont
.SetShadow(FALSE
);
1154 eActMethod
=PDM_UNDEFINED
;
1158 case 0x0005: // TxMode
1162 case 0x0006: // SpExtra
1166 case 0x0007: { // PnSize
1169 nActPenSize
=(USHORT
)((aSize
.Width()+aSize
.Height())/2);
1170 eActMethod
=PDM_UNDEFINED
;
1174 case 0x0008: // PnMode
1176 switch (nUSHORT
& 0x0007) {
1177 case 0: eActROP
=ROP_OVERPAINT
; break; // Copy
1178 case 1: eActROP
=ROP_OVERPAINT
; break; // Or
1179 case 2: eActROP
=ROP_XOR
; break; // Xor
1180 case 3: eActROP
=ROP_OVERPAINT
; break; // Bic
1181 case 4: eActROP
=ROP_INVERT
; break; // notCopy
1182 case 5: eActROP
=ROP_OVERPAINT
; break; // notOr
1183 case 6: eActROP
=ROP_XOR
; break; // notXor
1184 case 7: eActROP
=ROP_OVERPAINT
; break; // notBic
1186 eActMethod
=PDM_UNDEFINED
;
1190 case 0x0009: // PnPat
1191 nDataSize
=ReadPattern(&eActPenPenStyle
,&eActPenBrushStyle
);
1192 eActMethod
=PDM_UNDEFINED
;
1195 case 0x000a: // FillPat
1196 nDataSize
=ReadPattern(NULL
,&eActFillStyle
);
1197 eActMethod
=PDM_UNDEFINED
;
1200 case 0x000b: // OvSize
1201 aActOvalSize
=ReadSize();
1205 case 0x000c: // Origin
1209 case 0x000d: // TxSize
1212 aActFont
.SetSize( Size( 0, (long)nUSHORT
) );
1213 eActMethod
=PDM_UNDEFINED
;
1218 case 0x000e: // FgColor
1219 aActForeColor
=ReadColor();
1220 eActMethod
=PDM_UNDEFINED
;
1224 case 0x000f: // BkColor
1225 aActBackColor
=ReadColor();
1229 case 0x0010: // TxRatio
1233 case 0x0011: // VersionOp
1237 case 0x0012: // BkPixPat
1238 nDataSize
=ReadPixPattern(NULL
,&eActBackStyle
);
1239 eActMethod
=PDM_UNDEFINED
;
1242 case 0x0013: // PnPixPat
1243 nDataSize
=ReadPixPattern(&eActPenPenStyle
,&eActPenBrushStyle
);
1244 eActMethod
=PDM_UNDEFINED
;
1247 case 0x0014: // FillPixPat
1248 nDataSize
=ReadPixPattern(NULL
,&eActFillStyle
);
1249 eActMethod
=PDM_UNDEFINED
;
1252 case 0x0015: // PnLocHFrac
1256 case 0x0016: // ChExtra
1260 case 0x0017: // Reserved (0 Bytes)
1261 case 0x0018: // Reserved (0 Bytes)
1262 case 0x0019: // Reserved (0 Bytes)
1266 case 0x001a: // RGBFgCol
1267 aActForeColor
=ReadRGBColor();
1268 eActMethod
=PDM_UNDEFINED
;
1272 case 0x001b: // RGBBkCol
1273 aActBackColor
=ReadRGBColor();
1274 eActMethod
=PDM_UNDEFINED
;
1278 case 0x001c: // HiliteMode
1282 case 0x001d: // HiliteColor
1286 case 0x001e: // DefHilite
1290 case 0x001f: // OpColor
1294 case 0x0020: // Line
1295 aPoint
=ReadPoint(); aPenPosition
=ReadPoint();
1296 DrawingMethod(PDM_FRAME
);
1297 pVirDev
->DrawLine(aPoint
,aPenPosition
);
1301 case 0x0021: // LineFrom
1302 aPoint
=aPenPosition
; aPenPosition
=ReadPoint();
1303 DrawingMethod(PDM_FRAME
);
1304 pVirDev
->DrawLine(aPoint
,aPenPosition
);
1308 case 0x0022: // ShortLine
1310 aPenPosition
=ReadDeltaH(aPoint
);
1311 aPenPosition
=ReadDeltaV(aPenPosition
);
1312 DrawingMethod(PDM_FRAME
);
1313 pVirDev
->DrawLine(aPoint
,aPenPosition
);
1317 case 0x0023: // ShortLineFrom
1318 aPoint
=aPenPosition
;
1319 aPenPosition
=ReadDeltaH(aPoint
);
1320 aPenPosition
=ReadDeltaV(aPenPosition
);
1321 DrawingMethod(PDM_FRAME
);
1322 pVirDev
->DrawLine(aPoint
,aPenPosition
);
1326 case 0x0024: // Reserved (n Bytes)
1327 case 0x0025: // Reserved (n Bytes)
1328 case 0x0026: // Reserved (n Bytes)
1329 case 0x0027: // Reserved (n Bytes)
1331 nDataSize
=2+nUSHORT
;
1334 case 0x0028: // LongText
1335 aTextPosition
=ReadPoint();
1336 nDataSize
=4+ReadAndDrawText();
1339 case 0x0029: // DHText
1340 aTextPosition
=ReadUnsignedDeltaH(aTextPosition
);
1341 nDataSize
=1+ReadAndDrawText();
1344 case 0x002a: // DVText
1345 aTextPosition
=ReadUnsignedDeltaV(aTextPosition
);
1346 nDataSize
=1+ReadAndDrawText();
1349 case 0x002b: // DHDVText
1350 aTextPosition
=ReadUnsignedDeltaH(aTextPosition
);
1351 aTextPosition
=ReadUnsignedDeltaV(aTextPosition
);
1352 nDataSize
=2+ReadAndDrawText();
1355 case 0x002c: { // fontName
1356 char sFName
[ 256 ], nByteLen
;
1358 *pPict
>> nUSHORT
; nDataSize
=nUSHORT
+2;
1360 if (nUSHORT
<= 1) aActFont
.SetFamily(FAMILY_SWISS
);
1361 else if (nUSHORT
<= 12) aActFont
.SetFamily(FAMILY_DECORATIVE
);
1362 else if (nUSHORT
<= 20) aActFont
.SetFamily(FAMILY_ROMAN
);
1363 else if (nUSHORT
== 21) aActFont
.SetFamily(FAMILY_SWISS
);
1364 else if (nUSHORT
== 22) aActFont
.SetFamily(FAMILY_MODERN
);
1365 else if (nUSHORT
<= 1023) aActFont
.SetFamily(FAMILY_SWISS
);
1366 else aActFont
.SetFamily(FAMILY_ROMAN
);
1367 if (nUSHORT
==23) aActFont
.SetCharSet( RTL_TEXTENCODING_SYMBOL
);
1368 else aActFont
.SetCharSet( gsl_getSystemTextEncoding() );
1369 *pPict
>> nByteLen
; nLen
=((USHORT
)nByteLen
)&0x00ff;
1370 pPict
->Read( &sFName
, nLen
);
1372 String
aString( (const sal_Char
*)&sFName
, gsl_getSystemTextEncoding() );
1373 aActFont
.SetName( aString
);
1374 eActMethod
=PDM_UNDEFINED
;
1377 case 0x002d: // lineJustify
1381 case 0x002e: // glyphState
1383 nDataSize
=2+nUSHORT
;
1386 case 0x002f: // Reserved (n Bytes)
1388 nDataSize
=2+nUSHORT
;
1391 case 0x0030: // frameRect
1392 nDataSize
=ReadAndDrawRect(PDM_FRAME
);
1395 case 0x0031: // paintRect
1396 nDataSize
=ReadAndDrawRect(PDM_PAINT
);
1399 case 0x0032: // eraseRect
1400 nDataSize
=ReadAndDrawRect(PDM_ERASE
);
1403 case 0x0033: // invertRect
1404 nDataSize
=ReadAndDrawRect(PDM_INVERT
);
1407 case 0x0034: // fillRect
1408 nDataSize
=ReadAndDrawRect(PDM_FILL
);
1411 case 0x0035: // Reserved (8 Bytes)
1412 case 0x0036: // Reserved (8 Bytes)
1413 case 0x0037: // Reserved (8 Bytes)
1417 case 0x0038: // frameSameRect
1418 nDataSize
=ReadAndDrawSameRect(PDM_FRAME
);
1421 case 0x0039: // paintSameRect
1422 nDataSize
=ReadAndDrawSameRect(PDM_PAINT
);
1425 case 0x003a: // eraseSameRect
1426 nDataSize
=ReadAndDrawSameRect(PDM_ERASE
);
1429 case 0x003b: // invertSameRect
1430 nDataSize
=ReadAndDrawSameRect(PDM_INVERT
);
1433 case 0x003c: // fillSameRect
1434 nDataSize
=ReadAndDrawSameRect(PDM_FILL
);
1437 case 0x003d: // Reserved (0 Bytes)
1438 case 0x003e: // Reserved (0 Bytes)
1439 case 0x003f: // Reserved (0 Bytes)
1443 case 0x0040: // frameRRect
1444 nDataSize
=ReadAndDrawRoundRect(PDM_FRAME
);
1447 case 0x0041: // paintRRect
1448 nDataSize
=ReadAndDrawRoundRect(PDM_PAINT
);
1451 case 0x0042: // eraseRRect
1452 nDataSize
=ReadAndDrawRoundRect(PDM_ERASE
);
1455 case 0x0043: // invertRRect
1456 nDataSize
=ReadAndDrawRoundRect(PDM_INVERT
);
1459 case 0x0044: // fillRRect
1460 nDataSize
=ReadAndDrawRoundRect(PDM_FILL
);
1463 case 0x0045: // Reserved (8 Bytes)
1464 case 0x0046: // Reserved (8 Bytes)
1465 case 0x0047: // Reserved (8 Bytes)
1469 case 0x0048: // frameSameRRect
1470 nDataSize
=ReadAndDrawSameRoundRect(PDM_FRAME
);
1473 case 0x0049: // paintSameRRect
1474 nDataSize
=ReadAndDrawSameRoundRect(PDM_PAINT
);
1477 case 0x004a: // eraseSameRRect
1478 nDataSize
=ReadAndDrawSameRoundRect(PDM_ERASE
);
1481 case 0x004b: // invertSameRRect
1482 nDataSize
=ReadAndDrawSameRoundRect(PDM_INVERT
);
1485 case 0x004c: // fillSameRRect
1486 nDataSize
=ReadAndDrawSameRoundRect(PDM_FILL
);
1489 case 0x004d: // Reserved (0 Bytes)
1490 case 0x004e: // Reserved (0 Bytes)
1491 case 0x004f: // Reserved (0 Bytes)
1495 case 0x0050: // frameOval
1496 nDataSize
=ReadAndDrawOval(PDM_FRAME
);
1499 case 0x0051: // paintOval
1500 nDataSize
=ReadAndDrawOval(PDM_PAINT
);
1503 case 0x0052: // eraseOval
1504 nDataSize
=ReadAndDrawOval(PDM_ERASE
);
1507 case 0x0053: // invertOval
1508 nDataSize
=ReadAndDrawOval(PDM_INVERT
);
1511 case 0x0054: // fillOval
1512 nDataSize
=ReadAndDrawOval(PDM_FILL
);
1515 case 0x0055: // Reserved (8 Bytes)
1516 case 0x0056: // Reserved (8 Bytes)
1517 case 0x0057: // Reserved (8 Bytes)
1521 case 0x0058: // frameSameOval
1522 nDataSize
=ReadAndDrawSameOval(PDM_FRAME
);
1525 case 0x0059: // paintSameOval
1526 nDataSize
=ReadAndDrawSameOval(PDM_PAINT
);
1529 case 0x005a: // eraseSameOval
1530 nDataSize
=ReadAndDrawSameOval(PDM_ERASE
);
1533 case 0x005b: // invertSameOval
1534 nDataSize
=ReadAndDrawSameOval(PDM_INVERT
);
1537 case 0x005c: // fillSameOval
1538 nDataSize
=ReadAndDrawSameOval(PDM_FILL
);
1541 case 0x005d: // Reserved (0 Bytes)
1542 case 0x005e: // Reserved (0 Bytes)
1543 case 0x005f: // Reserved (0 Bytes)
1547 case 0x0060: // frameArc
1548 nDataSize
=ReadAndDrawArc(PDM_FRAME
);
1551 case 0x0061: // paintArc
1552 nDataSize
=ReadAndDrawArc(PDM_PAINT
);
1555 case 0x0062: // eraseArc
1556 nDataSize
=ReadAndDrawArc(PDM_ERASE
);
1559 case 0x0063: // invertArc
1560 nDataSize
=ReadAndDrawArc(PDM_INVERT
);
1563 case 0x0064: // fillArc
1564 nDataSize
=ReadAndDrawArc(PDM_FILL
);
1567 case 0x0065: // Reserved (12 Bytes)
1568 case 0x0066: // Reserved (12 Bytes)
1569 case 0x0067: // Reserved (12 Bytes)
1573 case 0x0068: // frameSameArc
1574 nDataSize
=ReadAndDrawSameArc(PDM_FRAME
);
1577 case 0x0069: // paintSameArc
1578 nDataSize
=ReadAndDrawSameArc(PDM_PAINT
);
1581 case 0x006a: // eraseSameArc
1582 nDataSize
=ReadAndDrawSameArc(PDM_ERASE
);
1585 case 0x006b: // invertSameArc
1586 nDataSize
=ReadAndDrawSameArc(PDM_INVERT
);
1589 case 0x006c: // fillSameArc
1590 nDataSize
=ReadAndDrawSameArc(PDM_FILL
);
1593 case 0x006d: // Reserved (4 Bytes)
1594 case 0x006e: // Reserved (4 Bytes)
1595 case 0x006f: // Reserved (4 Bytes)
1599 case 0x0070: // framePoly
1600 nDataSize
=ReadAndDrawPolygon(PDM_FRAME
);
1603 case 0x0071: // paintPoly
1604 nDataSize
=ReadAndDrawPolygon(PDM_PAINT
);
1607 case 0x0072: // erasePoly
1608 nDataSize
=ReadAndDrawPolygon(PDM_ERASE
);
1611 case 0x0073: // invertPoly
1612 nDataSize
=ReadAndDrawPolygon(PDM_INVERT
);
1615 case 0x0074: // fillPoly
1616 nDataSize
=ReadAndDrawPolygon(PDM_FILL
);
1619 case 0x0075: // Reserved (Polygon-Size)
1620 case 0x0076: // Reserved (Polygon-Size)
1621 case 0x0077: // Reserved (Polygon-Size)
1622 *pPict
>> nUSHORT
; nDataSize
=nUSHORT
;
1625 case 0x0078: // frameSamePoly
1626 nDataSize
=ReadAndDrawSamePolygon(PDM_FRAME
);
1629 case 0x0079: // paintSamePoly
1630 nDataSize
=ReadAndDrawSamePolygon(PDM_PAINT
);
1633 case 0x007a: // eraseSamePoly
1634 nDataSize
=ReadAndDrawSamePolygon(PDM_ERASE
);
1637 case 0x007b: // invertSamePoly
1638 nDataSize
=ReadAndDrawSamePolygon(PDM_INVERT
);
1641 case 0x007c: // fillSamePoly
1642 nDataSize
=ReadAndDrawSamePolygon(PDM_FILL
);
1645 case 0x007d: // Reserved (0 Bytes)
1646 case 0x007e: // Reserved (0 Bytes)
1647 case 0x007f: // Reserved (0 Bytes)
1651 case 0x0080: // frameRgn
1652 nDataSize
=ReadAndDrawRgn(PDM_FILL
);
1655 case 0x0081: // paintRgn
1656 nDataSize
=ReadAndDrawRgn(PDM_PAINT
);
1659 case 0x0082: // eraseRgn
1660 nDataSize
=ReadAndDrawRgn(PDM_ERASE
);
1663 case 0x0083: // invertRgn
1664 nDataSize
=ReadAndDrawRgn(PDM_INVERT
);
1667 case 0x0084: // fillRgn
1668 nDataSize
=ReadAndDrawRgn(PDM_FILL
);
1671 case 0x0085: // Reserved (Region-Size)
1672 case 0x0086: // Reserved (Region-Size)
1673 case 0x0087: // Reserved (Region-Size)
1674 *pPict
>> nUSHORT
; nDataSize
=nUSHORT
;
1677 case 0x0088: // frameSameRgn
1678 nDataSize
=ReadAndDrawSameRgn(PDM_FRAME
);
1681 case 0x0089: // paintSameRgn
1682 nDataSize
=ReadAndDrawSameRgn(PDM_PAINT
);
1685 case 0x008a: // eraseSameRgn
1686 nDataSize
=ReadAndDrawSameRgn(PDM_ERASE
);
1689 case 0x008b: // invertSameRgn
1690 nDataSize
=ReadAndDrawSameRgn(PDM_INVERT
);
1693 case 0x008c: // fillSameRgn
1694 nDataSize
=ReadAndDrawSameRgn(PDM_FILL
);
1697 case 0x008d: // Reserved (0 Bytes)
1698 case 0x008e: // Reserved (0 Bytes)
1699 case 0x008f: // Reserved (0 Bytes)
1703 case 0x0090: { // BitsRect
1705 Rectangle aSrcRect
, aDestRect
;
1706 nDataSize
=ReadPixMapEtc(aBmp
, FALSE
, TRUE
, &aSrcRect
, &aDestRect
, TRUE
, FALSE
);
1707 DrawingMethod(PDM_PAINT
);
1708 pVirDev
->DrawBitmap(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1711 case 0x0091: { // BitsRgn
1713 Rectangle aSrcRect
, aDestRect
;
1714 nDataSize
=ReadPixMapEtc(aBmp
, FALSE
, TRUE
, &aSrcRect
, &aDestRect
, TRUE
, TRUE
);
1715 DrawingMethod(PDM_PAINT
);
1716 pVirDev
->DrawBitmap(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1719 case 0x0092: // Reserved (n Bytes)
1720 case 0x0093: // Reserved (n Bytes)
1721 case 0x0094: // Reserved (n Bytes)
1722 case 0x0095: // Reserved (n Bytes)
1723 case 0x0096: // Reserved (n Bytes)
1724 case 0x0097: // Reserved (n Bytes)
1725 *pPict
>> nUSHORT
; nDataSize
=2+nUSHORT
;
1728 case 0x0098: { // PackBitsRect
1730 Rectangle aSrcRect
, aDestRect
;
1731 nDataSize
=ReadPixMapEtc(aBmp
, FALSE
, TRUE
, &aSrcRect
, &aDestRect
, TRUE
, FALSE
);
1732 DrawingMethod(PDM_PAINT
);
1733 pVirDev
->DrawBitmap(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1736 case 0x0099: { // PackBitsRgn
1738 Rectangle aSrcRect
, aDestRect
;
1739 nDataSize
=ReadPixMapEtc(aBmp
, FALSE
, TRUE
, &aSrcRect
, &aDestRect
, TRUE
, TRUE
);
1740 DrawingMethod(PDM_PAINT
);
1741 pVirDev
->DrawBitmap(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1744 case 0x009a: { // DirectBitsRect
1746 Rectangle aSrcRect
, aDestRect
;
1747 nDataSize
=ReadPixMapEtc(aBmp
, TRUE
, FALSE
, &aSrcRect
, &aDestRect
, TRUE
, FALSE
);
1748 DrawingMethod(PDM_PAINT
);
1749 pVirDev
->DrawBitmap(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1752 case 0x009b: { // DirectBitsRgn
1754 Rectangle aSrcRect
, aDestRect
;
1755 nDataSize
=ReadPixMapEtc(aBmp
, TRUE
, FALSE
, &aSrcRect
, &aDestRect
, TRUE
, TRUE
);
1756 DrawingMethod(PDM_PAINT
);
1757 pVirDev
->DrawBitmap(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1760 case 0x009c: // Reserved (n Bytes)
1761 case 0x009d: // Reserved (n Bytes)
1762 case 0x009e: // Reserved (n Bytes)
1763 case 0x009f: // Reserved (n Bytes)
1764 *pPict
>> nUSHORT
; nDataSize
=2+nUSHORT
;
1767 case 0x00a0: // ShortComment
1771 case 0x00a1: // LongComment
1772 pPict
->SeekRel(2); *pPict
>> nUSHORT
; nDataSize
=4+nUSHORT
;
1775 default: // 0x00a2 bis 0xffff (zumeist Reserved)
1776 if (nOpcode
<=0x00af) { *pPict
>> nUSHORT
; nDataSize
=2+nUSHORT
; }
1777 else if (nOpcode
<=0x00cf) { nDataSize
=0; }
1778 else if (nOpcode
<=0x00fe) { sal_uInt32 nTemp
; *pPict
>> nTemp
; nDataSize
= nTemp
; nDataSize
+=4; }
1779 else if (nOpcode
==0x00ff) { nDataSize
=2; } // OpEndPic
1780 else if (nOpcode
<=0x01ff) { nDataSize
=2; }
1781 else if (nOpcode
<=0x0bfe) { nDataSize
=4; }
1782 else if (nOpcode
<=0x0bff) { nDataSize
=22; }
1783 else if (nOpcode
==0x0c00) { nDataSize
=24; } // HeaderOp
1784 else if (nOpcode
<=0x7eff) { nDataSize
=24; }
1785 else if (nOpcode
<=0x7fff) { nDataSize
=254; }
1786 else if (nOpcode
<=0x80ff) { nDataSize
=0; }
1787 else { sal_uInt32 nTemp
; *pPict
>> nTemp
; nDataSize
= nTemp
; nDataSize
+=4; }
1790 if (nDataSize
==0xffffffff) {
1791 pPict
->SetError(SVSTREAM_FILEFORMAT_ERROR
);
1797 void PictReader::ReadPict( SvStream
& rStreamPict
, GDIMetaFile
& rGDIMetaFile
)
1800 BYTE nOneByteOpcode
;
1801 ULONG nSize
, nPos
, nStartPos
, nEndPos
, nPercent
, nLastPercent
;
1803 pPict
= &rStreamPict
;
1804 nOrigPos
= pPict
->Tell();
1805 nOrigNumberFormat
= pPict
->GetNumberFormatInt();
1807 aActForeColor
= Color(COL_BLACK
);
1808 aActBackColor
= Color(COL_WHITE
);
1809 eActPenPenStyle
= PEN_SOLID
;
1810 eActPenBrushStyle
= BRUSH_SOLID
;
1811 eActFillStyle
= BRUSH_SOLID
;
1812 eActBackStyle
= BRUSH_SOLID
;
1814 eActROP
= ROP_OVERPAINT
;
1815 eActMethod
= PDM_UNDEFINED
;
1816 aActOvalSize
= Size(1,1);
1818 aActFont
.SetCharSet( gsl_getSystemTextEncoding() );
1819 aActFont
.SetFamily(FAMILY_SWISS
);
1820 aActFont
.SetSize(Size(0,12));
1821 aActFont
.SetAlign(ALIGN_BASELINE
);
1823 aHRes
= aVRes
= Fraction( 1, 1 );
1825 pVirDev
= new VirtualDevice();
1826 pVirDev
->EnableOutput(FALSE
);
1827 rGDIMetaFile
.Record(pVirDev
);
1829 pPict
->SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN
);
1831 nStartPos
=pPict
->Tell();
1832 nEndPos
=pPict
->Seek(STREAM_SEEK_TO_END
); pPict
->Seek(nStartPos
);
1833 Callback(0); nLastPercent
=0;
1837 aPenPosition
=Point(-aBoundingRect
.Left(),-aBoundingRect
.Top());
1838 aTextPosition
=aPenPosition
;
1844 nPercent
=(nPos
-nStartPos
)*100/(nEndPos
-nStartPos
);
1845 if (nLastPercent
+4<=nPercent
) {
1846 if (Callback((USHORT
)nPercent
)==TRUE
) break;
1847 nLastPercent
=nPercent
;
1854 *pPict
>> nOneByteOpcode
;
1855 nOpcode
=(USHORT
)nOneByteOpcode
;
1858 if (pPict
->GetError())
1863 pPict
->SetError(SVSTREAM_FILEFORMAT_ERROR
);
1867 if (nOpcode
==0x00ff)
1870 nSize
=ReadData(nOpcode
);
1885 rGDIMetaFile
.Stop();
1888 rGDIMetaFile
.SetPrefMapMode( MapMode( MAP_INCH
, Point(), aHRes
, aVRes
) );
1889 rGDIMetaFile
.SetPrefSize( aBoundingRect
.GetSize() );
1891 pPict
->SetNumberFormatInt(nOrigNumberFormat
);
1893 if (pPict
->GetError()) pPict
->Seek(nOrigPos
);
1896 //================== GraphicImport - die exportierte Funktion ================
1898 extern "C" BOOL __LOADONCALLAPI
GraphicImport( SvStream
& rIStm
, Graphic
& rGraphic
, FilterConfigItem
*, BOOL
)
1901 PictReader aPictReader
;
1904 aPictReader
.ReadPict( rIStm
, aMTF
);
1906 if ( !rIStm
.GetError() )
1908 rGraphic
= Graphic( aMTF
);
1915 //================== ein bischen Muell fuer Windows ==========================
1921 static HINSTANCE hDLLInst
= 0; // HANDLE der DLL
1923 extern "C" int CALLBACK
LibMain( HINSTANCE hDLL
, WORD
, WORD nHeap
, LPSTR
)
1935 extern "C" int CALLBACK
WEP( int )