merge the formfield patch from ooo-build
[ooovba.git] / goodies / source / filter.vcl / ipict / ipict.cxx
blob3031ecd192add8f12fbb12b07aa6abf6ab999616
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ipict.cxx,v $
10 * $Revision: 1.18 $
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"
34 #include <string.h>
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>
40 #include <math.h>
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,
47 BRUSH_BITMAP };
49 //============================ PictReader ==================================
51 enum PictDrawingMethod {
52 PDM_FRAME, PDM_PAINT, PDM_ERASE, PDM_INVERT, PDM_FILL,
53 PDM_TEXT, PDM_UNDEFINED
56 class PictReader {
58 private:
60 SvStream * pPict; // Die einzulesende Pict-Datei
61 VirtualDevice * pVirDev; // Hier werden die Drawing-Methoden aufgerufen.
62 // Dabei findet ein Recording in das GDIMetaFile
63 // statt.
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
69 Point aPenPosition;
70 Point aTextPosition;
71 Color aActForeColor;
72 Color aActBackColor;
73 PenStyle eActPenPenStyle;
74 BrushStyle eActPenBrushStyle;
75 BrushStyle eActFillStyle;
76 BrushStyle eActBackStyle;
77 USHORT nActPenSize;
78 RasterOp eActROP;
79 PictDrawingMethod eActMethod;
80 Size aActOvalSize;
81 Font aActFont;
83 Fraction aHRes;
84 Fraction aVRes;
86 BOOL Callback(USHORT nPercent);
88 Point ReadPoint();
90 Point ReadDeltaH(Point aBase);
91 Point ReadDeltaV(Point aBase);
93 Point ReadUnsignedDeltaH(Point aBase);
94 Point ReadUnsignedDeltaV(Point aBase);
96 Size ReadSize();
98 Color ReadColor();
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);
110 Rectangle aLastRect;
111 ULONG ReadAndDrawRect(PictDrawingMethod eMethod);
112 ULONG ReadAndDrawSameRect(PictDrawingMethod eMethod);
114 Rectangle aLastRoundRect;
115 ULONG ReadAndDrawRoundRect(PictDrawingMethod eMethod);
116 ULONG ReadAndDrawSameRoundRect(PictDrawingMethod eMethod);
118 Rectangle aLastOval;
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);
141 void ReadHeader();
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
147 // zurueckgeliefert.
149 void SetLineColor( const Color& rColor );
150 void SetFillColor( const Color& rColor );
152 public:
154 PictReader() {}
156 void ReadPict( SvStream & rStreamPict, GDIMetaFile & rGDIMetaFile );
157 // Liesst aus dem Stream eine Pict-Datei und fuellt das GDIMetaFile
161 //------------------------------------------------------------------------------------------------
163 #define SETBYTE \
164 switch ( nPixelSize ) \
166 case 1 : \
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 ); \
182 break; \
183 case 2 : \
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); \
191 break; \
192 case 4 : \
193 pAcc->SetPixel( ny, nx++, nDat >> 4 ); \
194 if ( nx == nWidth ) break; \
195 pAcc->SetPixel( ny, nx++, nDat ); \
196 break; \
197 case 8 : \
198 pAcc->SetPixel( ny, nx++, nDat ); \
199 break; \
202 //------------------------------------------------------------------------------------------------
204 #define BITMAPERROR \
206 if ( pAcc ) \
207 aBitmap.ReleaseAccess( pAcc ); \
208 if ( pReadAcc ) \
209 aBitmap.ReleaseAccess( pReadAcc ); \
210 return 0xffffffff; \
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);
231 return TRUE;
235 return FALSE;
238 Point PictReader::ReadPoint()
240 short nx,ny;
242 *pPict >> ny >> nx;
244 return Point( (long)nx - aBoundingRect.Left(),
245 (long)ny - aBoundingRect.Top() );
248 Point PictReader::ReadDeltaH(Point aBase)
250 signed char ndh;
252 *pPict >> ((char&)ndh);
254 return Point( aBase.X() + (long)ndh, aBase.Y() );
257 Point PictReader::ReadDeltaV(Point aBase)
259 signed char ndv;
261 *pPict >> ((char&)ndv);
263 return Point( aBase.X(), aBase.Y() + (long)ndv );
266 Point PictReader::ReadUnsignedDeltaH(Point aBase)
268 sal_uInt8 ndh;
270 *pPict >> ndh;
272 return Point( aBase.X() + (long)ndh, aBase.Y() );
275 Point PictReader::ReadUnsignedDeltaV(Point aBase)
277 sal_uInt8 ndv;
279 *pPict >> ndv;
281 return Point( aBase.X(), aBase.Y() + (long)ndv );
284 Size PictReader::ReadSize()
286 short nx,ny;
288 *pPict >> ny >> nx;
290 return Size( (long)nx, (long)ny );
293 Color PictReader::ReadColor()
295 sal_uInt32 nCol;
296 Color aCol;
298 *pPict >> nCol;
299 switch (nCol)
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 );
311 return aCol;
315 Color PictReader::ReadRGBColor()
317 USHORT nR, nG, nB;
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)
338 USHORT nSize,i;
339 ULONG nDataSize;
341 *pPict >> nSize;
342 pPict->SeekRel(8);
343 nDataSize=(ULONG)nSize;
344 nSize=(nSize-10)/4;
345 rPoly.SetSize(nSize);
346 for (i=0; i<nSize; i++) rPoly.SetPoint(ReadPoint(),i);
347 return nDataSize;
350 ULONG PictReader::ReadPattern(PenStyle * pPenStyle, BrushStyle * pBrushStyle)
352 short nx,ny,nBitCount;
353 unsigned char nbyte[8];
354 BrushStyle eBrStyle;
355 PenStyle ePnStyle;
356 ULONG nHiBytes, nLoBytes;
358 // Anzahl der Bits im Pattern zaehlen, die auf 1 gesetzt sind:
359 nBitCount=0;
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)|
371 (ULONG)nbyte[3];
372 nLoBytes=(((((((ULONG)nbyte[4])<<8)|
373 (ULONG)nbyte[5])<<8)|
374 (ULONG)nbyte[6])<<8)|
375 (ULONG)nbyte[7];
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;
401 return 8;
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.
411 ULONG nDataSize;
412 USHORT nPatType;
413 Bitmap aBMP;
415 *pPict >> nPatType;
416 if (nPatType==1) {
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
424 nDataSize=16;
426 else nDataSize=0xffffffff;
428 return nDataSize;
431 ULONG PictReader::ReadAndDrawRect(PictDrawingMethod eMethod)
433 ReadRectangle(aLastRect);
434 DrawingMethod(eMethod);
435 pVirDev->DrawRect(aLastRect);
436 return 8;
439 ULONG PictReader::ReadAndDrawSameRect(PictDrawingMethod eMethod)
441 DrawingMethod(eMethod);
442 pVirDev->DrawRect(aLastRect);
443 return 0;
446 ULONG PictReader::ReadAndDrawRoundRect(PictDrawingMethod eMethod)
448 ReadRectangle(aLastRoundRect);
449 DrawingMethod(eMethod);
450 pVirDev->DrawRect(aLastRoundRect,aActOvalSize.Width(),aActOvalSize.Height());
451 return 8;
454 ULONG PictReader::ReadAndDrawSameRoundRect(PictDrawingMethod eMethod)
456 DrawingMethod(eMethod);
457 pVirDev->DrawRect(aLastRoundRect,aActOvalSize.Width(),aActOvalSize.Height());
458 return 0;
461 ULONG PictReader::ReadAndDrawOval(PictDrawingMethod eMethod)
463 ReadRectangle(aLastOval);
464 DrawingMethod(eMethod);
465 pVirDev->DrawEllipse(aLastOval);
466 return 8;
469 ULONG PictReader::ReadAndDrawSameOval(PictDrawingMethod eMethod)
471 DrawingMethod(eMethod);
472 pVirDev->DrawEllipse(aLastOval);
473 return 0;
476 ULONG PictReader::ReadAndDrawPolygon(PictDrawingMethod eMethod)
478 ULONG nDataSize;
480 nDataSize=ReadPolygon(aLastPolygon);
481 DrawingMethod(eMethod);
482 if (eMethod==PDM_FRAME) pVirDev->DrawPolyLine(aLastPolygon);
483 else pVirDev->DrawPolygon(aLastPolygon);
484 return nDataSize;
487 ULONG PictReader::ReadAndDrawSamePolygon(PictDrawingMethod eMethod)
489 DrawingMethod(eMethod);
490 if (eMethod==PDM_FRAME) pVirDev->DrawPolyLine(aLastPolygon);
491 else pVirDev->DrawPolygon(aLastPolygon);
492 return 0;
496 ULONG PictReader::ReadAndDrawArc(PictDrawingMethod eMethod)
498 short nstartAngle, narcAngle;
499 double fAng1, fAng2;
500 Point aStartPt, aEndPt, aCenter;
502 ReadRectangle(aLastArcRect);
503 *pPict >> nstartAngle >> narcAngle;
504 if (narcAngle<0) {
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);
519 return 12;
522 ULONG PictReader::ReadAndDrawSameArc(PictDrawingMethod eMethod)
524 short nstartAngle, narcAngle;
525 double fAng1, fAng2;
526 Point aStartPt, aEndPt, aCenter;
528 *pPict >> nstartAngle >> narcAngle;
529 if (narcAngle<0) {
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);
544 return 4;
547 ULONG PictReader::ReadAndDrawRgn(PictDrawingMethod eMethod)
549 USHORT nSize;
551 DrawingMethod(eMethod);
552 *pPict >> nSize;
553 // ...???...
554 return (ULONG)nSize;
557 ULONG PictReader::ReadAndDrawSameRgn(PictDrawingMethod eMethod)
559 DrawingMethod(eMethod);
560 // ...???...
561 return 0;
564 void PictReader::DrawingMethod(PictDrawingMethod eMethod)
566 if( eActMethod==eMethod ) return;
567 switch (eMethod) {
568 case PDM_FRAME:
569 SetLineColor( aActForeColor );
570 SetFillColor( Color(COL_TRANSPARENT) );
571 pVirDev->SetRasterOp(eActROP);
572 break;
573 case PDM_PAINT:
574 SetLineColor( Color(COL_TRANSPARENT) );
575 SetFillColor( aActForeColor );
576 pVirDev->SetRasterOp(eActROP);
577 break;
578 case PDM_ERASE:
579 SetLineColor( Color(COL_TRANSPARENT) );
580 SetFillColor( aActForeColor );
581 pVirDev->SetRasterOp(ROP_OVERPAINT);
582 break;
583 case PDM_INVERT:
584 SetLineColor( Color(COL_TRANSPARENT));
585 SetFillColor( Color( COL_BLACK ) );
586 pVirDev->SetRasterOp(ROP_INVERT);
587 break;
588 case PDM_FILL:
589 SetLineColor( Color(COL_TRANSPARENT) );
590 SetFillColor( aActForeColor );
591 pVirDev->SetRasterOp(ROP_OVERPAINT);
592 break;
593 case PDM_TEXT:
594 aActFont.SetColor(aActForeColor);
595 aActFont.SetFillColor(aActBackColor);
596 aActFont.SetTransparent(TRUE);
597 pVirDev->SetFont(aActFont);
598 pVirDev->SetRasterOp(ROP_OVERPAINT);
599 break;
600 default:
601 break; // -Wall undefined not handled...
603 eActMethod=eMethod;
606 ULONG PictReader::ReadAndDrawText()
608 char nByteLen;
609 sal_uInt32 nLen, nDataLen;
610 sal_Char sText[256];
612 DrawingMethod(PDM_TEXT);
613 *pPict >> nByteLen; nLen=((ULONG)nByteLen)&0x000000ff;
614 nDataLen = nLen + 1;
615 pPict->Read( &sText, nLen );
617 // Stoerende Steuerzeuichen wegnehmen:
618 while ( nLen > 0 && ( (unsigned char)sText[ nLen - 1 ] ) < 32 )
619 nLen--;
620 sText[ nLen ] = 0;
621 String aString( (const sal_Char*)&sText, gsl_getSystemTextEncoding() );
622 pVirDev->DrawText( Point( aTextPosition.X(), aTextPosition.Y() ), aString );
623 return nDataLen;
626 ULONG PictReader::ReadPixMapEtc( Bitmap &rBitmap, BOOL bBaseAddr, BOOL bColorTable, Rectangle* pSrcRect,
627 Rectangle* pDestRect, BOOL bMode, BOOL bMaskRgn )
629 Bitmap aBitmap;
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.
640 nDataSize = 0;
642 // ggf. BaseAddr ueberlesen
643 if ( bBaseAddr )
645 pPict->SeekRel( 4 );
646 nDataSize += 4;
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 )
655 { // it is a PixMap
656 nRowBytes &= 0x3fff;
657 *pPict >> nVersion >> nPackType >> nPackSize >> nHRes >> nVRes >> nPixelType >>
658 nPixelSize >> nCmpCount >> nCmpSize >> nPlaneBytes;
660 pPict->SeekRel( 8 );
661 nDataSize += 46;
663 sal_uInt16 nDstBitCount = nPixelSize;
664 if ( nDstBitCount > 8 )
665 nDstBitCount = 24;
666 else if ( nDstBitCount == 2 )
667 nDstBitCount = 4;
668 aBitmap = Bitmap( Size( nWidth, nHeight ), nDstBitCount );
670 if ( ( pAcc = aBitmap.AcquireWriteAccess() ) == NULL )
671 BITMAPERROR;
673 if ( bColorTable )
675 pPict->SeekRel( 6 );
676 *pPict >> nColTabSize;
678 if ( ++nColTabSize > 256 )
679 BITMAPERROR;
681 pAcc->SetPaletteEntryCount( nColTabSize );
683 for ( i = 0; i < nColTabSize; i++ )
685 pPict->SeekRel(2);
686 *pPict >> nRed >> nDummy >> nGreen >> nDummy >> nBlue >> nDummy;
687 pAcc->SetPaletteColor( (USHORT) i, BitmapColor( nRed, nGreen, nBlue ) );
689 nDataSize += 8 + nColTabSize * 8;
692 else
694 nRowBytes &= 0x3fff;
695 nVersion = 0;
696 nPackType = 0;
697 nPackSize = nHRes = nVRes = nPlaneBytes = 0;
698 nPixelType = 0;
699 nPixelSize = nCmpCount = nCmpSize = 1;
700 nDataSize += 10;
701 aBitmap = Bitmap( Size( nWidth, nHeight ), 1 );
702 if ( ( pAcc = aBitmap.AcquireWriteAccess() ) == NULL )
703 BITMAPERROR;
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:
710 if ( pSrcRect != 0)
712 USHORT nTop, nLeft, nBottom, nRight;
713 *pPict >> nTop >> nLeft >> nBottom >> nRight;
714 *pSrcRect = Rectangle( (ULONG)nLeft, (ULONG)nTop, (ULONG)nRight, (ULONG)nBottom );
715 nDataSize += 8;
718 // ggf. Ziel-Rechteck einlesen:
719 if ( pDestRect != 0 )
721 Point aTL, aBR;
722 aTL = ReadPoint();
723 aBR = ReadPoint();
724 *pDestRect = Rectangle( aTL, aBR );
725 nDataSize += 8;
728 // ggf. Modus einlesen (bzw. ueberspringen):
729 if ( bMode )
731 pPict->SeekRel(2);
732 nDataSize += 2;
735 // ggf. Region einlesen (bzw. ueberspringen):
736 if ( bMaskRgn )
738 USHORT nSize;
739 *pPict >> nSize;
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 )
758 BITMAPERROR;
760 for ( ny = 0; ny < nHeight; ny++ )
762 nx = 0;
763 if ( nRowBytes < 8 || nPackType == 1 )
765 for ( i = 0; i < nRowBytes; i++ )
767 *pPict >> nDat;
768 if ( nx < nWidth )
769 SETBYTE;
771 nDataSize += nRowBytes;
773 else
775 if ( nRowBytes > 250 )
777 *pPict >> nByteCount;
778 nDataSize += 2 + (ULONG)nByteCount;
780 else
782 *pPict >> nByteCountAsByte;
783 nByteCount = ( (USHORT)nByteCountAsByte ) & 0x00ff;
784 nDataSize += 1 + (ULONG)nByteCount;
787 while ( nByteCount )
789 *pPict >> nFlagCounterByte;
790 if ( ( nFlagCounterByte & 0x80 ) == 0 )
792 nCount = ( (USHORT)nFlagCounterByte ) + 1;
793 for ( i = 0; i < nCount; i++ )
795 *pPict >> nDat;
796 if ( nx < nWidth )
797 SETBYTE;
799 nByteCount -= 1 + nCount;
801 else
803 nCount = ( 1 - ( ( (USHORT)nFlagCounterByte ) | 0xff00 ) );
804 *pPict >> nDat;
805 for ( i = 0; i < nCount; i++ )
807 if ( nx < nWidth )
808 SETBYTE;
810 nByteCount -= 2;
816 else if ( nPixelSize == 16 )
818 BYTE nByteCountAsByte, nFlagCounterByte;
819 USHORT nByteCount, nCount, nDestBPL,nD;
820 ULONG nSrcBitsPos;
822 if ( nRowBytes < 2 * nWidth )
823 BITMAPERROR;
825 nDestBPL = ( ( 3 * nWidth ) + 0x0003 ) & 0xfffc;
827 for ( ny = 0; ny < nHeight; ny++ )
829 nx = 0;
830 if ( nRowBytes < 8 || nPackType == 1 )
832 for ( i = 0; i < nWidth; i++ )
834 *pPict >> nD;
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;
842 else
844 nSrcBitsPos = pPict->Tell();
845 if ( nRowBytes > 250 )
847 *pPict >> nByteCount;
848 nByteCount += 2;
850 else
852 *pPict >> nByteCountAsByte;
853 nByteCount = ( (USHORT)nByteCountAsByte ) & 0x00ff;
854 nByteCount++;
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
866 *pPict >> nD;
867 nRed = (BYTE)( nD >> 7 );
868 nGreen = (BYTE)( nD >> 2 );
869 nBlue = (BYTE)( nD << 3 );
870 pAcc->SetPixel( ny, nx++, BitmapColor( nRed, nGreen, nBlue ) );
873 else
875 nCount=(1-(((USHORT)nFlagCounterByte)|0xff00));
876 if ( nCount + nx > nWidth )
877 nCount = nWidth - nx;
878 *pPict >> nD;
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;
897 ULONG nSrcBitsPos;
898 BitmapColor aBitmapColor;
899 if ( ( pReadAcc = aBitmap.AcquireReadAccess() ) == NULL )
900 BITMAPERROR;
901 if ( nRowBytes != 4*nWidth )
902 BITMAPERROR;
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;
931 else
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;
942 nByteCount += 2;
944 else
946 *pPict >> nByteCountAsByte;
947 nByteCount = (BYTE)nByteCountAsByte;
948 nByteCount++;
950 i = 0;
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 );
959 while( nCount-- )
961 *pPict >> nDat;
962 pScanline[ i++ ] = nDat;
965 else
967 nCount = ( 1 - ( ( (USHORT)nFlagCounterByte ) | 0xff00 ) );
968 if ( ( i + nCount ) > (sal_uInt32)( nWidth * nCmpCount ) )
969 nCount = (sal_uInt16)( nWidth * nCmpCount - i );
970 *pPict >> nDat;
971 while( nCount-- )
972 pScanline[ i++ ] = nDat;
975 sal_uInt8* pTmp = pScanline;
976 if ( nCmpCount == 4 )
977 pTmp += nWidth;
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 );
983 delete[] pScanline;
987 else
988 BITMAPERROR;
989 if ( pReadAcc )
990 aBitmap.ReleaseAccess( pReadAcc );
991 aBitmap.ReleaseAccess( pAcc );
992 rBitmap = aBitmap;
993 return nDataSize;
996 void PictReader::ReadHeader()
998 char nC;
999 short y1,x1,y2,x2;
1001 sal_Char sBuf[ 3 ];
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
1006 else
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:
1018 if (nC==0x11)
1020 *pPict >> nC;
1021 if ( nC == 0x01 )
1022 IsVersion2 = FALSE; // Version 1
1023 else // Version 2 oder hoeher
1025 short nExtVer;
1026 // 3 Bytes ueberspringen, um auf
1027 // ExtVersion2 oder Version2 zu kommen
1028 pPict->SeekRel( 3 );
1029 *pPict >> nExtVer;
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;
1040 fHRes /= 65536;
1041 double fVRes = nVResFixed;
1042 fVRes /= 65536;
1043 aHRes /= fHRes;
1044 aVRes /= fVRes;
1045 *pPict >> y1 >> x1 >> y2 >> x2; // reading the optimal bounding rect
1046 aBoundingRect=Rectangle( x1,y1, --x2, --y2 );
1047 pPict->SeekRel( -22 );
1049 else
1051 pPict->SeekRel( -4 );
1053 IsVersion2=TRUE;
1056 else {
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.
1070 BYTE n1,n2,n3;
1071 USHORT i,Found;
1072 pPict->Seek(522);
1073 Found=0;
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;
1079 if (Found!=0) {
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 );
1085 if (n3==0x01) {
1086 pPict->SeekRel(3);
1087 IsVersion2=FALSE;
1089 else {
1090 pPict->SeekRel(4);
1091 IsVersion2=TRUE;
1094 else pPict->SetError(SVSTREAM_FILEFORMAT_ERROR);
1096 else pPict->SetError(SVSTREAM_FILEFORMAT_ERROR);
1101 ULONG PictReader::ReadData(USHORT nOpcode)
1103 USHORT nUSHORT;
1104 Point aPoint;
1105 ULONG nDataSize=0;
1107 switch(nOpcode) {
1109 case 0x0000: // NOP
1110 nDataSize=0;
1111 break;
1113 case 0x0001: { // Clip
1114 Rectangle aRect;
1115 *pPict >> nUSHORT;
1116 nDataSize=nUSHORT;
1117 ReadRectangle(aRect);
1118 pVirDev->SetClipRegion( Region( aRect ) );
1119 break;
1121 case 0x0002: // BkPat
1122 nDataSize=ReadPattern(NULL,&eActBackStyle);
1123 eActMethod=PDM_UNDEFINED;
1124 break;
1126 case 0x0003: // TxFont
1127 *pPict >> nUSHORT;
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;
1138 nDataSize=2;
1139 break;
1141 case 0x0004: { // TxFace
1142 char nFace;
1143 *pPict >> nFace;
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;
1155 nDataSize=1;
1156 break;
1158 case 0x0005: // TxMode
1159 nDataSize=2;
1160 break;
1162 case 0x0006: // SpExtra
1163 nDataSize=4;
1164 break;
1166 case 0x0007: { // PnSize
1167 Size aSize;
1168 aSize=ReadSize();
1169 nActPenSize=(USHORT)((aSize.Width()+aSize.Height())/2);
1170 eActMethod=PDM_UNDEFINED;
1171 nDataSize=4;
1172 break;
1174 case 0x0008: // PnMode
1175 *pPict >> nUSHORT;
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;
1187 nDataSize=2;
1188 break;
1190 case 0x0009: // PnPat
1191 nDataSize=ReadPattern(&eActPenPenStyle,&eActPenBrushStyle);
1192 eActMethod=PDM_UNDEFINED;
1193 break;
1195 case 0x000a: // FillPat
1196 nDataSize=ReadPattern(NULL,&eActFillStyle);
1197 eActMethod=PDM_UNDEFINED;
1198 break;
1200 case 0x000b: // OvSize
1201 aActOvalSize=ReadSize();
1202 nDataSize=4;
1203 break;
1205 case 0x000c: // Origin
1206 nDataSize=4;
1207 break;
1209 case 0x000d: // TxSize
1211 *pPict >> nUSHORT;
1212 aActFont.SetSize( Size( 0, (long)nUSHORT ) );
1213 eActMethod=PDM_UNDEFINED;
1214 nDataSize=2;
1216 break;
1218 case 0x000e: // FgColor
1219 aActForeColor=ReadColor();
1220 eActMethod=PDM_UNDEFINED;
1221 nDataSize=4;
1222 break;
1224 case 0x000f: // BkColor
1225 aActBackColor=ReadColor();
1226 nDataSize=4;
1227 break;
1229 case 0x0010: // TxRatio
1230 nDataSize=8;
1231 break;
1233 case 0x0011: // VersionOp
1234 nDataSize=1;
1235 break;
1237 case 0x0012: // BkPixPat
1238 nDataSize=ReadPixPattern(NULL,&eActBackStyle);
1239 eActMethod=PDM_UNDEFINED;
1240 break;
1242 case 0x0013: // PnPixPat
1243 nDataSize=ReadPixPattern(&eActPenPenStyle,&eActPenBrushStyle);
1244 eActMethod=PDM_UNDEFINED;
1245 break;
1247 case 0x0014: // FillPixPat
1248 nDataSize=ReadPixPattern(NULL,&eActFillStyle);
1249 eActMethod=PDM_UNDEFINED;
1250 break;
1252 case 0x0015: // PnLocHFrac
1253 nDataSize=2;
1254 break;
1256 case 0x0016: // ChExtra
1257 nDataSize=2;
1258 break;
1260 case 0x0017: // Reserved (0 Bytes)
1261 case 0x0018: // Reserved (0 Bytes)
1262 case 0x0019: // Reserved (0 Bytes)
1263 nDataSize=0;
1264 break;
1266 case 0x001a: // RGBFgCol
1267 aActForeColor=ReadRGBColor();
1268 eActMethod=PDM_UNDEFINED;
1269 nDataSize=6;
1270 break;
1272 case 0x001b: // RGBBkCol
1273 aActBackColor=ReadRGBColor();
1274 eActMethod=PDM_UNDEFINED;
1275 nDataSize=6;
1276 break;
1278 case 0x001c: // HiliteMode
1279 nDataSize=0;
1280 break;
1282 case 0x001d: // HiliteColor
1283 nDataSize=6;
1284 break;
1286 case 0x001e: // DefHilite
1287 nDataSize=0;
1288 break;
1290 case 0x001f: // OpColor
1291 nDataSize=6;
1292 break;
1294 case 0x0020: // Line
1295 aPoint=ReadPoint(); aPenPosition=ReadPoint();
1296 DrawingMethod(PDM_FRAME);
1297 pVirDev->DrawLine(aPoint,aPenPosition);
1298 nDataSize=8;
1299 break;
1301 case 0x0021: // LineFrom
1302 aPoint=aPenPosition; aPenPosition=ReadPoint();
1303 DrawingMethod(PDM_FRAME);
1304 pVirDev->DrawLine(aPoint,aPenPosition);
1305 nDataSize=4;
1306 break;
1308 case 0x0022: // ShortLine
1309 aPoint=ReadPoint();
1310 aPenPosition=ReadDeltaH(aPoint);
1311 aPenPosition=ReadDeltaV(aPenPosition);
1312 DrawingMethod(PDM_FRAME);
1313 pVirDev->DrawLine(aPoint,aPenPosition);
1314 nDataSize=6;
1315 break;
1317 case 0x0023: // ShortLineFrom
1318 aPoint=aPenPosition;
1319 aPenPosition=ReadDeltaH(aPoint);
1320 aPenPosition=ReadDeltaV(aPenPosition);
1321 DrawingMethod(PDM_FRAME);
1322 pVirDev->DrawLine(aPoint,aPenPosition);
1323 nDataSize=2;
1324 break;
1326 case 0x0024: // Reserved (n Bytes)
1327 case 0x0025: // Reserved (n Bytes)
1328 case 0x0026: // Reserved (n Bytes)
1329 case 0x0027: // Reserved (n Bytes)
1330 *pPict >> nUSHORT;
1331 nDataSize=2+nUSHORT;
1332 break;
1334 case 0x0028: // LongText
1335 aTextPosition=ReadPoint();
1336 nDataSize=4+ReadAndDrawText();
1337 break;
1339 case 0x0029: // DHText
1340 aTextPosition=ReadUnsignedDeltaH(aTextPosition);
1341 nDataSize=1+ReadAndDrawText();
1342 break;
1344 case 0x002a: // DVText
1345 aTextPosition=ReadUnsignedDeltaV(aTextPosition);
1346 nDataSize=1+ReadAndDrawText();
1347 break;
1349 case 0x002b: // DHDVText
1350 aTextPosition=ReadUnsignedDeltaH(aTextPosition);
1351 aTextPosition=ReadUnsignedDeltaV(aTextPosition);
1352 nDataSize=2+ReadAndDrawText();
1353 break;
1355 case 0x002c: { // fontName
1356 char sFName[ 256 ], nByteLen;
1357 sal_uInt16 nLen;
1358 *pPict >> nUSHORT; nDataSize=nUSHORT+2;
1359 *pPict >> nUSHORT;
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 );
1371 sFName[ nLen ] = 0;
1372 String aString( (const sal_Char*)&sFName, gsl_getSystemTextEncoding() );
1373 aActFont.SetName( aString );
1374 eActMethod=PDM_UNDEFINED;
1375 break;
1377 case 0x002d: // lineJustify
1378 nDataSize=10;
1379 break;
1381 case 0x002e: // glyphState
1382 *pPict >> nUSHORT;
1383 nDataSize=2+nUSHORT;
1384 break;
1386 case 0x002f: // Reserved (n Bytes)
1387 *pPict >> nUSHORT;
1388 nDataSize=2+nUSHORT;
1389 break;
1391 case 0x0030: // frameRect
1392 nDataSize=ReadAndDrawRect(PDM_FRAME);
1393 break;
1395 case 0x0031: // paintRect
1396 nDataSize=ReadAndDrawRect(PDM_PAINT);
1397 break;
1399 case 0x0032: // eraseRect
1400 nDataSize=ReadAndDrawRect(PDM_ERASE);
1401 break;
1403 case 0x0033: // invertRect
1404 nDataSize=ReadAndDrawRect(PDM_INVERT);
1405 break;
1407 case 0x0034: // fillRect
1408 nDataSize=ReadAndDrawRect(PDM_FILL);
1409 break;
1411 case 0x0035: // Reserved (8 Bytes)
1412 case 0x0036: // Reserved (8 Bytes)
1413 case 0x0037: // Reserved (8 Bytes)
1414 nDataSize=8;
1415 break;
1417 case 0x0038: // frameSameRect
1418 nDataSize=ReadAndDrawSameRect(PDM_FRAME);
1419 break;
1421 case 0x0039: // paintSameRect
1422 nDataSize=ReadAndDrawSameRect(PDM_PAINT);
1423 break;
1425 case 0x003a: // eraseSameRect
1426 nDataSize=ReadAndDrawSameRect(PDM_ERASE);
1427 break;
1429 case 0x003b: // invertSameRect
1430 nDataSize=ReadAndDrawSameRect(PDM_INVERT);
1431 break;
1433 case 0x003c: // fillSameRect
1434 nDataSize=ReadAndDrawSameRect(PDM_FILL);
1435 break;
1437 case 0x003d: // Reserved (0 Bytes)
1438 case 0x003e: // Reserved (0 Bytes)
1439 case 0x003f: // Reserved (0 Bytes)
1440 nDataSize=0;
1441 break;
1443 case 0x0040: // frameRRect
1444 nDataSize=ReadAndDrawRoundRect(PDM_FRAME);
1445 break;
1447 case 0x0041: // paintRRect
1448 nDataSize=ReadAndDrawRoundRect(PDM_PAINT);
1449 break;
1451 case 0x0042: // eraseRRect
1452 nDataSize=ReadAndDrawRoundRect(PDM_ERASE);
1453 break;
1455 case 0x0043: // invertRRect
1456 nDataSize=ReadAndDrawRoundRect(PDM_INVERT);
1457 break;
1459 case 0x0044: // fillRRect
1460 nDataSize=ReadAndDrawRoundRect(PDM_FILL);
1461 break;
1463 case 0x0045: // Reserved (8 Bytes)
1464 case 0x0046: // Reserved (8 Bytes)
1465 case 0x0047: // Reserved (8 Bytes)
1466 nDataSize=8;
1467 break;
1469 case 0x0048: // frameSameRRect
1470 nDataSize=ReadAndDrawSameRoundRect(PDM_FRAME);
1471 break;
1473 case 0x0049: // paintSameRRect
1474 nDataSize=ReadAndDrawSameRoundRect(PDM_PAINT);
1475 break;
1477 case 0x004a: // eraseSameRRect
1478 nDataSize=ReadAndDrawSameRoundRect(PDM_ERASE);
1479 break;
1481 case 0x004b: // invertSameRRect
1482 nDataSize=ReadAndDrawSameRoundRect(PDM_INVERT);
1483 break;
1485 case 0x004c: // fillSameRRect
1486 nDataSize=ReadAndDrawSameRoundRect(PDM_FILL);
1487 break;
1489 case 0x004d: // Reserved (0 Bytes)
1490 case 0x004e: // Reserved (0 Bytes)
1491 case 0x004f: // Reserved (0 Bytes)
1492 nDataSize=0;
1493 break;
1495 case 0x0050: // frameOval
1496 nDataSize=ReadAndDrawOval(PDM_FRAME);
1497 break;
1499 case 0x0051: // paintOval
1500 nDataSize=ReadAndDrawOval(PDM_PAINT);
1501 break;
1503 case 0x0052: // eraseOval
1504 nDataSize=ReadAndDrawOval(PDM_ERASE);
1505 break;
1507 case 0x0053: // invertOval
1508 nDataSize=ReadAndDrawOval(PDM_INVERT);
1509 break;
1511 case 0x0054: // fillOval
1512 nDataSize=ReadAndDrawOval(PDM_FILL);
1513 break;
1515 case 0x0055: // Reserved (8 Bytes)
1516 case 0x0056: // Reserved (8 Bytes)
1517 case 0x0057: // Reserved (8 Bytes)
1518 nDataSize=8;
1519 break;
1521 case 0x0058: // frameSameOval
1522 nDataSize=ReadAndDrawSameOval(PDM_FRAME);
1523 break;
1525 case 0x0059: // paintSameOval
1526 nDataSize=ReadAndDrawSameOval(PDM_PAINT);
1527 break;
1529 case 0x005a: // eraseSameOval
1530 nDataSize=ReadAndDrawSameOval(PDM_ERASE);
1531 break;
1533 case 0x005b: // invertSameOval
1534 nDataSize=ReadAndDrawSameOval(PDM_INVERT);
1535 break;
1537 case 0x005c: // fillSameOval
1538 nDataSize=ReadAndDrawSameOval(PDM_FILL);
1539 break;
1541 case 0x005d: // Reserved (0 Bytes)
1542 case 0x005e: // Reserved (0 Bytes)
1543 case 0x005f: // Reserved (0 Bytes)
1544 nDataSize=0;
1545 break;
1547 case 0x0060: // frameArc
1548 nDataSize=ReadAndDrawArc(PDM_FRAME);
1549 break;
1551 case 0x0061: // paintArc
1552 nDataSize=ReadAndDrawArc(PDM_PAINT);
1553 break;
1555 case 0x0062: // eraseArc
1556 nDataSize=ReadAndDrawArc(PDM_ERASE);
1557 break;
1559 case 0x0063: // invertArc
1560 nDataSize=ReadAndDrawArc(PDM_INVERT);
1561 break;
1563 case 0x0064: // fillArc
1564 nDataSize=ReadAndDrawArc(PDM_FILL);
1565 break;
1567 case 0x0065: // Reserved (12 Bytes)
1568 case 0x0066: // Reserved (12 Bytes)
1569 case 0x0067: // Reserved (12 Bytes)
1570 nDataSize=12;
1571 break;
1573 case 0x0068: // frameSameArc
1574 nDataSize=ReadAndDrawSameArc(PDM_FRAME);
1575 break;
1577 case 0x0069: // paintSameArc
1578 nDataSize=ReadAndDrawSameArc(PDM_PAINT);
1579 break;
1581 case 0x006a: // eraseSameArc
1582 nDataSize=ReadAndDrawSameArc(PDM_ERASE);
1583 break;
1585 case 0x006b: // invertSameArc
1586 nDataSize=ReadAndDrawSameArc(PDM_INVERT);
1587 break;
1589 case 0x006c: // fillSameArc
1590 nDataSize=ReadAndDrawSameArc(PDM_FILL);
1591 break;
1593 case 0x006d: // Reserved (4 Bytes)
1594 case 0x006e: // Reserved (4 Bytes)
1595 case 0x006f: // Reserved (4 Bytes)
1596 nDataSize=4;
1597 break;
1599 case 0x0070: // framePoly
1600 nDataSize=ReadAndDrawPolygon(PDM_FRAME);
1601 break;
1603 case 0x0071: // paintPoly
1604 nDataSize=ReadAndDrawPolygon(PDM_PAINT);
1605 break;
1607 case 0x0072: // erasePoly
1608 nDataSize=ReadAndDrawPolygon(PDM_ERASE);
1609 break;
1611 case 0x0073: // invertPoly
1612 nDataSize=ReadAndDrawPolygon(PDM_INVERT);
1613 break;
1615 case 0x0074: // fillPoly
1616 nDataSize=ReadAndDrawPolygon(PDM_FILL);
1617 break;
1619 case 0x0075: // Reserved (Polygon-Size)
1620 case 0x0076: // Reserved (Polygon-Size)
1621 case 0x0077: // Reserved (Polygon-Size)
1622 *pPict >> nUSHORT; nDataSize=nUSHORT;
1623 break;
1625 case 0x0078: // frameSamePoly
1626 nDataSize=ReadAndDrawSamePolygon(PDM_FRAME);
1627 break;
1629 case 0x0079: // paintSamePoly
1630 nDataSize=ReadAndDrawSamePolygon(PDM_PAINT);
1631 break;
1633 case 0x007a: // eraseSamePoly
1634 nDataSize=ReadAndDrawSamePolygon(PDM_ERASE);
1635 break;
1637 case 0x007b: // invertSamePoly
1638 nDataSize=ReadAndDrawSamePolygon(PDM_INVERT);
1639 break;
1641 case 0x007c: // fillSamePoly
1642 nDataSize=ReadAndDrawSamePolygon(PDM_FILL);
1643 break;
1645 case 0x007d: // Reserved (0 Bytes)
1646 case 0x007e: // Reserved (0 Bytes)
1647 case 0x007f: // Reserved (0 Bytes)
1648 nDataSize=0;
1649 break;
1651 case 0x0080: // frameRgn
1652 nDataSize=ReadAndDrawRgn(PDM_FILL);
1653 break;
1655 case 0x0081: // paintRgn
1656 nDataSize=ReadAndDrawRgn(PDM_PAINT);
1657 break;
1659 case 0x0082: // eraseRgn
1660 nDataSize=ReadAndDrawRgn(PDM_ERASE);
1661 break;
1663 case 0x0083: // invertRgn
1664 nDataSize=ReadAndDrawRgn(PDM_INVERT);
1665 break;
1667 case 0x0084: // fillRgn
1668 nDataSize=ReadAndDrawRgn(PDM_FILL);
1669 break;
1671 case 0x0085: // Reserved (Region-Size)
1672 case 0x0086: // Reserved (Region-Size)
1673 case 0x0087: // Reserved (Region-Size)
1674 *pPict >> nUSHORT; nDataSize=nUSHORT;
1675 break;
1677 case 0x0088: // frameSameRgn
1678 nDataSize=ReadAndDrawSameRgn(PDM_FRAME);
1679 break;
1681 case 0x0089: // paintSameRgn
1682 nDataSize=ReadAndDrawSameRgn(PDM_PAINT);
1683 break;
1685 case 0x008a: // eraseSameRgn
1686 nDataSize=ReadAndDrawSameRgn(PDM_ERASE);
1687 break;
1689 case 0x008b: // invertSameRgn
1690 nDataSize=ReadAndDrawSameRgn(PDM_INVERT);
1691 break;
1693 case 0x008c: // fillSameRgn
1694 nDataSize=ReadAndDrawSameRgn(PDM_FILL);
1695 break;
1697 case 0x008d: // Reserved (0 Bytes)
1698 case 0x008e: // Reserved (0 Bytes)
1699 case 0x008f: // Reserved (0 Bytes)
1700 nDataSize=0;
1701 break;
1703 case 0x0090: { // BitsRect
1704 Bitmap aBmp;
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);
1709 break;
1711 case 0x0091: { // BitsRgn
1712 Bitmap aBmp;
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);
1717 break;
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;
1726 break;
1728 case 0x0098: { // PackBitsRect
1729 Bitmap aBmp;
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);
1734 break;
1736 case 0x0099: { // PackBitsRgn
1737 Bitmap aBmp;
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);
1742 break;
1744 case 0x009a: { // DirectBitsRect
1745 Bitmap aBmp;
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);
1750 break;
1752 case 0x009b: { // DirectBitsRgn
1753 Bitmap aBmp;
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);
1758 break;
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;
1765 break;
1767 case 0x00a0: // ShortComment
1768 nDataSize=2;
1769 break;
1771 case 0x00a1: // LongComment
1772 pPict->SeekRel(2); *pPict >> nUSHORT; nDataSize=4+nUSHORT;
1773 break;
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);
1792 return 0;
1794 return nDataSize;
1797 void PictReader::ReadPict( SvStream & rStreamPict, GDIMetaFile & rGDIMetaFile )
1799 USHORT nOpcode;
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;
1813 nActPenSize = 1;
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;
1835 ReadHeader();
1837 aPenPosition=Point(-aBoundingRect.Left(),-aBoundingRect.Top());
1838 aTextPosition=aPenPosition;
1840 nPos=pPict->Tell();
1842 for (;;) {
1844 nPercent=(nPos-nStartPos)*100/(nEndPos-nStartPos);
1845 if (nLastPercent+4<=nPercent) {
1846 if (Callback((USHORT)nPercent)==TRUE) break;
1847 nLastPercent=nPercent;
1850 if (IsVersion2 )
1851 *pPict >> nOpcode;
1852 else
1854 *pPict >> nOneByteOpcode;
1855 nOpcode=(USHORT)nOneByteOpcode;
1858 if (pPict->GetError())
1859 break;
1861 if (pPict->IsEof())
1863 pPict->SetError(SVSTREAM_FILEFORMAT_ERROR);
1864 break;
1867 if (nOpcode==0x00ff)
1868 break;
1870 nSize=ReadData(nOpcode);
1872 if ( IsVersion2 )
1874 if ( nSize & 1 )
1875 nSize++;
1877 nPos+=2+nSize;
1879 else
1880 nPos+=1+nSize;
1882 pPict->Seek(nPos);
1885 rGDIMetaFile.Stop();
1886 delete pVirDev;
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 )
1900 GDIMetaFile aMTF;
1901 PictReader aPictReader;
1902 BOOL bRet = FALSE;
1904 aPictReader.ReadPict( rIStm, aMTF );
1906 if ( !rIStm.GetError() )
1908 rGraphic = Graphic( aMTF );
1909 bRet = TRUE;
1912 return bRet;
1915 //================== ein bischen Muell fuer Windows ==========================
1916 #ifndef GCC
1917 #endif
1919 #ifdef WIN
1921 static HINSTANCE hDLLInst = 0; // HANDLE der DLL
1923 extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR )
1925 #ifndef WNT
1926 if ( nHeap )
1927 UnlockData( 0 );
1928 #endif
1930 hDLLInst = hDLL;
1932 return TRUE;
1935 extern "C" int CALLBACK WEP( int )
1937 return 1;
1940 #endif