1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <vcl/bmpacc.hxx>
23 #include <vcl/graph.hxx>
24 #include <tools/poly.hxx>
25 #include <vcl/virdev.hxx>
30 class FilterConfigItem
;
32 namespace PictReaderInternal
{
33 //! utilitary class to store a pattern, ...
38 isColor
= false; isRead
= false;
39 penStyle
=PEN_SOLID
; brushStyle
= BRUSH_SOLID
;
43 //! reads black/white pattern from SvStream
44 sal_uLong
read(SvStream
&stream
);
46 void setColor(Color
&col
) { isColor
= true; color
= col
; }
47 /** returns a color which can be "used" to replace the pattern,
48 * created from ForeColor and BackColor, ...
50 * note: maybe, we must also use some mode PatCopy, ... to define the color
52 Color
getColor(Color bkColor
=COL_WHITE
, Color fgColor
= COL_BLACK
) const {
53 if (isColor
) return color
;
54 // we create a gray pattern from nBitCount
55 double alpha
= nBitCount
/ 64.0;
56 return Color(sal_uInt8(alpha
*fgColor
.GetRed()+(1.0-alpha
)*bkColor
.GetRed()),
57 sal_uInt8(alpha
*fgColor
.GetGreen()+(1.0-alpha
)*bkColor
.GetGreen()),
58 sal_uInt8(alpha
*fgColor
.GetBlue()+(1.0-alpha
)*bkColor
.GetBlue()));
61 //! returns true if this is the default pattern
62 bool isDefault() const { return isRead
== false; }
64 // MT: NOOLDSV, someone should change the code...
65 enum PenStyle
{ PEN_NULL
, PEN_SOLID
, PEN_DOT
, PEN_DASH
, PEN_DASHDOT
};
66 enum BrushStyle
{ BRUSH_NULL
, BRUSH_SOLID
, BRUSH_HORZ
, BRUSH_VERT
,
67 BRUSH_CROSS
, BRUSH_DIAGCROSS
, BRUSH_UPDIAG
, BRUSH_DOWNDIAG
,
68 BRUSH_25
, BRUSH_50
, BRUSH_75
,
71 enum PenStyle penStyle
;
72 enum BrushStyle brushStyle
;
75 bool isColor
; // true if it is a color pattern
79 // flag to know if the pattern came from reading the picture, or if it is the default pattern
83 sal_uLong
Pattern::read(SvStream
&stream
) {
85 unsigned char nbyte
[8];
86 sal_uLong nHiBytes
, nLoBytes
;
89 // count the no of bits in pattern which are set to 1:
91 for (ny
=0; ny
<8; ny
++) {
92 stream
>> ((char&)nbyte
[ny
]);
93 for (nx
=0; nx
<8; nx
++) {
94 if ( (nbyte
[ny
] & (1<<nx
)) != 0 ) nBitCount
++;
98 // store pattern in 2 long words:
99 nHiBytes
=(((((((sal_uLong
)nbyte
[0])<<8)|
100 (sal_uLong
)nbyte
[1])<<8)|
101 (sal_uLong
)nbyte
[2])<<8)|
103 nLoBytes
=(((((((sal_uLong
)nbyte
[4])<<8)|
104 (sal_uLong
)nbyte
[5])<<8)|
105 (sal_uLong
)nbyte
[6])<<8)|
108 // create a PenStyle:
109 if (nBitCount
<=0) penStyle
=PEN_NULL
;
110 else if (nBitCount
<=16) penStyle
=PEN_DOT
;
111 else if (nBitCount
<=32) penStyle
=PEN_DASHDOT
;
112 else if (nBitCount
<=48) penStyle
=PEN_DASH
;
113 else penStyle
=PEN_SOLID
;
115 // create a BrushStyle:
116 if (nHiBytes
==0xffffffff && nLoBytes
==0xffffffff) brushStyle
=BRUSH_SOLID
;
117 else if (nHiBytes
==0xff000000 && nLoBytes
==0x00000000) brushStyle
=BRUSH_HORZ
;
118 else if (nHiBytes
==0x80808080 && nLoBytes
==0x80808080) brushStyle
=BRUSH_VERT
;
119 else if (nHiBytes
==0xff808080 && nLoBytes
==0x80808080) brushStyle
=BRUSH_CROSS
;
120 else if (nHiBytes
==0x01824428 && nLoBytes
==0x10284482) brushStyle
=BRUSH_DIAGCROSS
;
121 else if (nHiBytes
==0x80402010 && nLoBytes
==0x08040201) brushStyle
=BRUSH_UPDIAG
;
122 else if (nHiBytes
==0x01020408 && nLoBytes
==0x10204080) brushStyle
=BRUSH_DOWNDIAG
;
123 else if (nBitCount
<=24) brushStyle
=BRUSH_25
;
124 else if (nBitCount
<=40) brushStyle
=BRUSH_50
;
125 else if (nBitCount
<=56) brushStyle
=BRUSH_75
;
126 else brushStyle
=BRUSH_SOLID
;
134 //============================ PictReader ==================================
136 enum PictDrawingMethod
{
137 PDM_FRAME
, PDM_PAINT
, PDM_ERASE
, PDM_INVERT
, PDM_FILL
,
138 PDM_TEXT
, PDM_UNDEFINED
142 typedef class PictReaderInternal::Pattern Pattern
;
145 SvStream
* pPict
; // The Pict file to read.
146 VirtualDevice
* pVirDev
; // Here the drawing methos will be called.
147 // A recording into the GDIMetaFile will take place.
149 sal_uLong nOrigPos
; // Initial position in pPict.
150 sal_uInt16 nOrigNumberFormat
; // Initial number format von pPict.
151 sal_Bool IsVersion2
; // If it is a version 2 Pictfile.
152 Rectangle aBoundingRect
; // Min/Max-Rectangle for the whole drawing.
158 Pattern eActPenPattern
;
159 Pattern eActFillPattern
;
160 Pattern eActBackPattern
;
162 // Note: Postscript mode is stored by setting eActRop to ROP_1
164 PictDrawingMethod eActMethod
;
171 sal_Bool
Callback(sal_uInt16 nPercent
);
175 Point
ReadDeltaH(Point aBase
);
176 Point
ReadDeltaV(Point aBase
);
178 Point
ReadUnsignedDeltaH(Point aBase
);
179 Point
ReadUnsignedDeltaV(Point aBase
);
185 Color
ReadRGBColor();
187 void ReadRectangle(Rectangle
& rRect
);
189 sal_uLong
ReadPolygon(Polygon
& rPoly
);
191 sal_uLong
ReadPixPattern(Pattern
&pattern
);
194 sal_uLong
ReadAndDrawRect(PictDrawingMethod eMethod
);
195 sal_uLong
ReadAndDrawSameRect(PictDrawingMethod eMethod
);
197 Rectangle aLastRoundRect
;
198 sal_uLong
ReadAndDrawRoundRect(PictDrawingMethod eMethod
);
199 sal_uLong
ReadAndDrawSameRoundRect(PictDrawingMethod eMethod
);
202 sal_uLong
ReadAndDrawOval(PictDrawingMethod eMethod
);
203 sal_uLong
ReadAndDrawSameOval(PictDrawingMethod eMethod
);
205 Polygon aLastPolygon
;
206 sal_uLong
ReadAndDrawPolygon(PictDrawingMethod eMethod
);
207 sal_uLong
ReadAndDrawSamePolygon(PictDrawingMethod eMethod
);
209 Rectangle aLastArcRect
;
210 sal_uLong
ReadAndDrawArc(PictDrawingMethod eMethod
);
211 sal_uLong
ReadAndDrawSameArc(PictDrawingMethod eMethod
);
213 sal_uLong
ReadAndDrawRgn(PictDrawingMethod eMethod
);
214 sal_uLong
ReadAndDrawSameRgn(PictDrawingMethod eMethod
);
216 // returns true, if we do not need to print the shape/text/frame
217 bool IsInvisible(PictDrawingMethod eMethod
) const {
218 if (eActROP
== ROP_1
) return true;
219 if (eMethod
==PDM_FRAME
&& (nActPenSize
.Width() == 0 || nActPenSize
.Height() == 0)) return true;
222 void DrawingMethod(PictDrawingMethod eMethod
);
224 sal_uLong
ReadAndDrawText();
226 sal_uLong
ReadPixMapEtc(Bitmap
& rBitmap
, sal_Bool bBaseAddr
, sal_Bool bColorTable
,
227 Rectangle
* pSrcRect
, Rectangle
* pDestRect
,
228 sal_Bool bMode
, sal_Bool bMaskRgn
);
231 // Reads the header of the Pict file, set IsVersion and aBoundingRect
233 sal_uLong
ReadData(sal_uInt16 nOpcode
);
234 // Reads the date of anOopcode and executes the operation.
235 // The number of data bytes belonging to the opcode will be returned
238 void SetLineColor( const Color
& rColor
);
239 void SetFillColor( const Color
& rColor
);
241 // OSNOLA: returns the text encoding which must be used for system id
242 static rtl_TextEncoding
GetTextEncoding (sal_uInt16 fId
= 0xFFFF);
245 PictReader() { aActFont
.SetCharSet(GetTextEncoding()); }
247 void ReadPict( SvStream
& rStreamPict
, GDIMetaFile
& rGDIMetaFile
);
248 // reads a pict file from the stream and fills the GDIMetaFile
252 //------------------------------------------------------------------------------------------------
255 switch ( nPixelSize ) \
258 pAcc->SetPixelIndex( ny, nx++, nDat >> 7 ); \
259 if ( nx == nWidth ) break; \
260 pAcc->SetPixelIndex( ny, nx++, nDat >> 6 ); \
261 if ( nx == nWidth ) break; \
262 pAcc->SetPixelIndex( ny, nx++, nDat >> 5 ); \
263 if ( nx == nWidth ) break; \
264 pAcc->SetPixelIndex( ny, nx++, nDat >> 4 ); \
265 if ( nx == nWidth ) break; \
266 pAcc->SetPixelIndex( ny, nx++, nDat >> 3 ); \
267 if ( nx == nWidth ) break; \
268 pAcc->SetPixelIndex( ny, nx++, nDat >> 2 ); \
269 if ( nx == nWidth ) break; \
270 pAcc->SetPixelIndex( ny, nx++, nDat >> 1 ); \
271 if ( nx == nWidth ) break; \
272 pAcc->SetPixelIndex( ny, nx++, nDat ); \
275 pAcc->SetPixelIndex( ny, nx++, nDat >> 6 ); \
276 if ( nx == nWidth ) break; \
277 pAcc->SetPixelIndex( ny, nx++, (nDat>>4)&3);\
278 if ( nx == nWidth ) break; \
279 pAcc->SetPixelIndex( ny, nx++, (nDat>>2)&3 );\
280 if ( nx == nWidth ) break; \
281 pAcc->SetPixelIndex( ny, nx++, nDat & 3); \
284 pAcc->SetPixelIndex( ny, nx++, nDat >> 4 ); \
285 if ( nx == nWidth ) break; \
286 pAcc->SetPixelIndex( ny, nx++, nDat ); \
289 pAcc->SetPixelIndex( ny, nx++, nDat ); \
293 //------------------------------------------------------------------------------------------------
295 #define BITMAPERROR \
298 aBitmap.ReleaseAccess( pAcc ); \
300 aBitmap.ReleaseAccess( pReadAcc ); \
304 //=================== methods of PictReader ==============================
305 rtl_TextEncoding
PictReader::GetTextEncoding (sal_uInt16 fId
) {
306 static bool first
= true;
307 static rtl_TextEncoding enc
= RTL_TEXTENCODING_APPLE_ROMAN
;
309 rtl_TextEncoding def
= osl_getThreadTextEncoding();
310 // we keep osl_getThreadTextEncoding only if it is a mac encoding
312 case RTL_TEXTENCODING_APPLE_ROMAN
:
313 case RTL_TEXTENCODING_APPLE_ARABIC
:
314 case RTL_TEXTENCODING_APPLE_CENTEURO
:
315 case RTL_TEXTENCODING_APPLE_CROATIAN
:
316 case RTL_TEXTENCODING_APPLE_CYRILLIC
:
317 case RTL_TEXTENCODING_APPLE_DEVANAGARI
:
318 case RTL_TEXTENCODING_APPLE_FARSI
:
319 case RTL_TEXTENCODING_APPLE_GREEK
:
320 case RTL_TEXTENCODING_APPLE_GUJARATI
:
321 case RTL_TEXTENCODING_APPLE_GURMUKHI
:
322 case RTL_TEXTENCODING_APPLE_HEBREW
:
323 case RTL_TEXTENCODING_APPLE_ICELAND
:
324 case RTL_TEXTENCODING_APPLE_ROMANIAN
:
325 case RTL_TEXTENCODING_APPLE_THAI
:
326 case RTL_TEXTENCODING_APPLE_TURKISH
:
327 case RTL_TEXTENCODING_APPLE_UKRAINIAN
:
328 case RTL_TEXTENCODING_APPLE_CHINSIMP
:
329 case RTL_TEXTENCODING_APPLE_CHINTRAD
:
330 case RTL_TEXTENCODING_APPLE_JAPANESE
:
331 case RTL_TEXTENCODING_APPLE_KOREAN
:
337 if (fId
== 13) return RTL_TEXTENCODING_ADOBE_DINGBATS
; // CHECKME
338 if (fId
== 23) return RTL_TEXTENCODING_ADOBE_SYMBOL
;
342 void PictReader::SetLineColor( const Color
& rColor
)
344 pVirDev
->SetLineColor( rColor
);
347 void PictReader::SetFillColor( const Color
& rColor
)
349 pVirDev
->SetFillColor( rColor
);
352 sal_Bool
PictReader::Callback(sal_uInt16
/*nPercent*/)
357 Point
PictReader::ReadPoint()
363 return Point( (long)nx
- aBoundingRect
.Left(),
364 (long)ny
- aBoundingRect
.Top() );
367 Point
PictReader::ReadDeltaH(Point aBase
)
371 *pPict
>> ((char&)ndh
);
373 return Point( aBase
.X() + (long)ndh
, aBase
.Y() );
376 Point
PictReader::ReadDeltaV(Point aBase
)
380 *pPict
>> ((char&)ndv
);
382 return Point( aBase
.X(), aBase
.Y() + (long)ndv
);
385 Point
PictReader::ReadUnsignedDeltaH(Point aBase
)
391 return Point( aBase
.X() + (long)ndh
, aBase
.Y() );
394 Point
PictReader::ReadUnsignedDeltaV(Point aBase
)
400 return Point( aBase
.X(), aBase
.Y() + (long)ndv
);
403 Size
PictReader::ReadSize()
409 return Size( (long)nx
, (long)ny
);
412 Color
PictReader::ReadColor()
420 case 33: aCol
=Color( COL_BLACK
); break;
421 case 30: aCol
=Color( COL_WHITE
); break;
422 case 205: aCol
=Color( COL_LIGHTRED
); break;
423 case 341: aCol
=Color( COL_LIGHTGREEN
); break;
424 case 409: aCol
=Color( COL_LIGHTBLUE
); break;
425 case 273: aCol
=Color( COL_LIGHTCYAN
); break;
426 case 137: aCol
=Color( COL_LIGHTMAGENTA
); break;
427 case 69: aCol
=Color( COL_YELLOW
); break;
428 default: aCol
=Color( COL_LIGHTGRAY
);
434 Color
PictReader::ReadRGBColor()
436 sal_uInt16 nR
, nG
, nB
;
438 *pPict
>> nR
>> nG
>> nB
;
439 return Color( (sal_uInt8
) ( nR
>> 8 ), (sal_uInt8
) ( nG
>> 8 ), (sal_uInt8
) ( nB
>> 8 ) );
443 void PictReader::ReadRectangle(Rectangle
& rRect
)
445 Point aTopLeft
, aBottomRight
;
447 aTopLeft
=ReadPoint();
448 aBottomRight
=ReadPoint();
449 rRect
=Rectangle(aTopLeft
,aBottomRight
);
453 sal_uLong
PictReader::ReadPolygon(Polygon
& rPoly
)
460 nDataSize
=(sal_uLong
)nSize
;
462 rPoly
.SetSize(nSize
);
463 for (i
=0; i
<nSize
; i
++) rPoly
.SetPoint(ReadPoint(),i
);
467 sal_uLong
PictReader::ReadPixPattern(PictReader::Pattern
&pattern
)
469 // Don't know if this is correct because no picture which contains PixPatterns found.
470 // Here again the attempt to calculate the size of the date to create simple StarView-Styles
471 // from them. Luckily a PixPattern always contains a normal pattern.
480 pattern
.read(*pPict
);
481 nDataSize
=ReadPixMapEtc(aBMP
,sal_False
,sal_True
,NULL
,NULL
,sal_False
,sal_False
);
482 // CHANGEME: use average pixmap colors to update the pattern, ...
483 if (nDataSize
!=0xffffffff) nDataSize
+=10;
485 else if (nPatType
==2) {
486 pattern
.read(*pPict
);
488 sal_uInt16 nR
, nG
, nB
;
489 *pPict
>> nR
>> nG
>> nB
;
490 Color
col((sal_uInt8
) ( nR
>> 8 ), (sal_uInt8
) ( nG
>> 8 ), (sal_uInt8
) ( nB
>> 8 ) );
491 pattern
.setColor(col
);
494 else nDataSize
=0xffffffff;
499 sal_uLong
PictReader::ReadAndDrawRect(PictDrawingMethod eMethod
)
501 ReadRectangle(aLastRect
);
502 ReadAndDrawSameRect(eMethod
);
506 sal_uLong
PictReader::ReadAndDrawSameRect(PictDrawingMethod eMethod
)
508 if (IsInvisible(eMethod
)) return 0;
509 DrawingMethod(eMethod
);
510 PictReaderShape::drawRectangle(pVirDev
, eMethod
==PDM_FRAME
, aLastRect
, nActPenSize
);
514 sal_uLong
PictReader::ReadAndDrawRoundRect(PictDrawingMethod eMethod
)
516 ReadRectangle(aLastRoundRect
);
517 ReadAndDrawSameRoundRect(eMethod
);
521 sal_uLong
PictReader::ReadAndDrawSameRoundRect(PictDrawingMethod eMethod
)
523 if (IsInvisible(eMethod
)) return 0;
524 DrawingMethod(eMethod
);
525 PictReaderShape::drawRoundRectangle(pVirDev
, eMethod
==PDM_FRAME
, aLastRoundRect
, aActOvalSize
, nActPenSize
);
529 sal_uLong
PictReader::ReadAndDrawOval(PictDrawingMethod eMethod
)
531 ReadRectangle(aLastOval
);
532 ReadAndDrawSameOval(eMethod
);
536 sal_uLong
PictReader::ReadAndDrawSameOval(PictDrawingMethod eMethod
)
538 if (IsInvisible(eMethod
)) return 0;
539 DrawingMethod(eMethod
);
540 PictReaderShape::drawEllipse(pVirDev
, eMethod
==PDM_FRAME
, aLastOval
, nActPenSize
);
544 sal_uLong
PictReader::ReadAndDrawPolygon(PictDrawingMethod eMethod
)
547 nDataSize
=ReadPolygon(aLastPolygon
);
548 ReadAndDrawSamePolygon(eMethod
);
552 sal_uLong
PictReader::ReadAndDrawSamePolygon(PictDrawingMethod eMethod
)
554 if (IsInvisible(eMethod
)) return 0;
555 DrawingMethod(eMethod
);
556 PictReaderShape::drawPolygon(pVirDev
, eMethod
==PDM_FRAME
, aLastPolygon
, nActPenSize
);
561 sal_uLong
PictReader::ReadAndDrawArc(PictDrawingMethod eMethod
)
563 ReadRectangle(aLastArcRect
);
564 ReadAndDrawSameArc(eMethod
);
568 sal_uLong
PictReader::ReadAndDrawSameArc(PictDrawingMethod eMethod
)
570 short nstartAngle
, narcAngle
;
573 *pPict
>> nstartAngle
>> narcAngle
;
574 if (IsInvisible(eMethod
)) return 4;
575 DrawingMethod(eMethod
);
578 nstartAngle
= nstartAngle
+ narcAngle
;
579 narcAngle
=-narcAngle
;
581 fAng1
=((double)nstartAngle
)/180.0*3.14159265359;
582 fAng2
=((double)(nstartAngle
+narcAngle
))/180.0*3.14159265359;
583 PictReaderShape::drawArc(pVirDev
, eMethod
==PDM_FRAME
, aLastArcRect
,fAng1
,fAng2
, nActPenSize
);
587 sal_uLong
PictReader::ReadAndDrawRgn(PictDrawingMethod eMethod
)
594 // a region data is a mask and is probably coded as
595 // - the first 8 bytes: bdbox ( which can be read by ReadRectangle )
596 // - then a list of line modifiers: y_i, a_0, b_0, a_1, b_1, ..., a_{n_i}, b_{n_i}, 0x7fff
598 // where y_i is the increasing sequences of line coordinates
599 // and on each line: a0 < b0 < a1 < b1 < ... < a_{n_i} < b_{n_i}
601 // it can be probably decoded as :
602 // M=an empty mask: ie. (0, 0, ... ) with (left_box-right_box+1) zeroes
603 // then for each line (y_i):
604 // - takes M and inverts all values in [a_0,b_0-1], in [a_1,b_1-1] ...
605 // - sets M = new y_i line mask
606 ReadAndDrawSameRgn(eMethod
);
607 return (sal_uLong
)nSize
;
610 sal_uLong
PictReader::ReadAndDrawSameRgn(PictDrawingMethod eMethod
)
612 if (IsInvisible(eMethod
)) return 0;
613 DrawingMethod(eMethod
);
614 // DISPLAY: ...???...
618 void PictReader::DrawingMethod(PictDrawingMethod eMethod
)
620 if( eActMethod
==eMethod
) return;
623 if (eActPenPattern
.isDefault())
624 SetLineColor( aActForeColor
);
626 SetLineColor(eActPenPattern
.getColor(aActBackColor
, aActForeColor
));
627 SetFillColor( Color(COL_TRANSPARENT
) );
628 pVirDev
->SetRasterOp(eActROP
);
631 SetLineColor( Color(COL_TRANSPARENT
) );
632 if (eActPenPattern
.isDefault())
633 SetFillColor( aActForeColor
);
635 SetFillColor(eActPenPattern
.getColor(aActBackColor
, aActForeColor
));
636 pVirDev
->SetRasterOp(eActROP
);
639 SetLineColor( Color(COL_TRANSPARENT
) );
640 if (eActBackPattern
.isDefault())
641 SetFillColor( aActBackColor
);// Osnola: previously aActForeColor
643 SetFillColor(eActBackPattern
.getColor(COL_BLACK
, aActBackColor
));
644 pVirDev
->SetRasterOp(ROP_OVERPAINT
);
646 case PDM_INVERT
: // checkme
647 SetLineColor( Color(COL_TRANSPARENT
));
648 SetFillColor( Color( COL_BLACK
) );
649 pVirDev
->SetRasterOp(ROP_INVERT
);
652 SetLineColor( Color(COL_TRANSPARENT
) );
653 if (eActFillPattern
.isDefault())
654 SetFillColor( aActForeColor
);
656 SetFillColor(eActFillPattern
.getColor(aActBackColor
, aActForeColor
));
657 pVirDev
->SetRasterOp(ROP_OVERPAINT
);
660 aActFont
.SetColor(aActForeColor
);
661 aActFont
.SetFillColor(aActBackColor
);
662 aActFont
.SetTransparent(sal_True
);
663 pVirDev
->SetFont(aActFont
);
664 pVirDev
->SetRasterOp(ROP_OVERPAINT
);
667 break; // -Wall undefined not handled...
672 sal_uLong
PictReader::ReadAndDrawText()
675 sal_uInt32 nLen
, nDataLen
;
678 *pPict
>> nByteLen
; nLen
=((sal_uLong
)nByteLen
)&0x000000ff;
680 pPict
->Read( &sText
, nLen
);
682 if (IsInvisible(PDM_TEXT
)) return nDataLen
;
683 DrawingMethod(PDM_TEXT
);
685 // remove annoying control characters:
686 while ( nLen
> 0 && ( (unsigned char)sText
[ nLen
- 1 ] ) < 32 )
689 String
aString( (const sal_Char
*)&sText
, aActFont
.GetCharSet());
690 pVirDev
->DrawText( Point( aTextPosition
.X(), aTextPosition
.Y() ), aString
);
694 sal_uLong
PictReader::ReadPixMapEtc( Bitmap
&rBitmap
, sal_Bool bBaseAddr
, sal_Bool bColorTable
, Rectangle
* pSrcRect
,
695 Rectangle
* pDestRect
, sal_Bool bMode
, sal_Bool bMaskRgn
)
698 BitmapWriteAccess
* pAcc
= NULL
;
699 BitmapReadAccess
* pReadAcc
= NULL
;
700 sal_uInt16 ny
, nx
, nColTabSize
;
701 sal_uInt16 nRowBytes
, nBndX
, nBndY
, nWidth
, nHeight
, nVersion
, nPackType
, nPixelType
,
702 nPixelSize
, nCmpCount
, nCmpSize
;
703 sal_uInt32 nPackSize
, nPlaneBytes
, nHRes
, nVRes
;
704 sal_uInt8 nDat
, nRed
, nGreen
, nBlue
, nDummy
;
705 sal_uLong i
, nDataSize
= 0;
707 // The calculation of nDataSize is considering the size of the whole data.
710 // condionally skip BaseAddr
717 // Read PixMap or Bitmap structure;
718 *pPict
>> nRowBytes
>> nBndY
>> nBndX
>> nHeight
>> nWidth
;
719 nHeight
= nHeight
- nBndY
;
720 nWidth
= nWidth
- nBndX
;
722 if ( ( nRowBytes
& 0x8000 ) != 0 )
725 *pPict
>> nVersion
>> nPackType
>> nPackSize
>> nHRes
>> nVRes
>> nPixelType
>>
726 nPixelSize
>> nCmpCount
>> nCmpSize
>> nPlaneBytes
;
731 sal_uInt16 nDstBitCount
= nPixelSize
;
732 if ( nDstBitCount
> 8 )
734 else if ( nDstBitCount
== 2 )
736 aBitmap
= Bitmap( Size( nWidth
, nHeight
), nDstBitCount
);
738 if ( ( pAcc
= aBitmap
.AcquireWriteAccess() ) == NULL
)
744 *pPict
>> nColTabSize
;
746 if ( ++nColTabSize
> 256 )
749 pAcc
->SetPaletteEntryCount( nColTabSize
);
751 for ( i
= 0; i
< nColTabSize
; i
++ )
754 *pPict
>> nRed
>> nDummy
>> nGreen
>> nDummy
>> nBlue
>> nDummy
;
755 pAcc
->SetPaletteColor( (sal_uInt16
) i
, BitmapColor( nRed
, nGreen
, nBlue
) );
757 nDataSize
+= 8 + nColTabSize
* 8;
765 nPackSize
= nHRes
= nVRes
= nPlaneBytes
= 0;
767 nPixelSize
= nCmpCount
= nCmpSize
= 1;
769 aBitmap
= Bitmap( Size( nWidth
, nHeight
), 1 );
770 if ( ( pAcc
= aBitmap
.AcquireWriteAccess() ) == NULL
)
772 pAcc
->SetPaletteEntryCount( 2 );
773 pAcc
->SetPaletteColor( 0, BitmapColor( 0xff, 0xff, 0xff ) );
774 pAcc
->SetPaletteColor( 1, BitmapColor( 0, 0, 0 ) );
777 // conditionally read source rectangle:
780 sal_uInt16 nTop
, nLeft
, nBottom
, nRight
;
781 *pPict
>> nTop
>> nLeft
>> nBottom
>> nRight
;
782 *pSrcRect
= Rectangle( (sal_uLong
)nLeft
, (sal_uLong
)nTop
, (sal_uLong
)nRight
, (sal_uLong
)nBottom
);
786 // conditionally read destination rectangle:
787 if ( pDestRect
!= 0 )
792 *pDestRect
= Rectangle( aTL
, aBR
);
796 // conditionally read mode (or skip it):
803 // conditionally read region (or skip it):
808 pPict
->SeekRel( nSize
- 2 );
809 nDataSize
+= (sal_uLong
)nSize
;
812 // aSMem << (nHRes/1665L) << (nVRes/1665L) << ((sal_uLong)0) << ((sal_uLong)0);
814 // read and write Bitmap bits:
815 if ( nPixelSize
== 1 || nPixelSize
== 2 || nPixelSize
== 4 || nPixelSize
== 8 )
817 sal_uInt8 nByteCountAsByte
, nFlagCounterByte
;
818 sal_uInt16 nByteCount
, nCount
, nSrcBPL
, nDestBPL
;
820 if ( nPixelSize
== 1 ) nSrcBPL
= ( nWidth
+ 7 ) >> 3;
821 else if ( nPixelSize
== 2 ) nSrcBPL
= ( nWidth
+ 3 ) >> 2;
822 else if ( nPixelSize
== 4 ) nSrcBPL
= ( nWidth
+ 1 ) >> 1;
823 else nSrcBPL
= nWidth
;
824 nDestBPL
= ( nSrcBPL
+ 3 ) & 0xfffc;
825 if ( nRowBytes
< nSrcBPL
|| nRowBytes
> nDestBPL
)
828 for ( ny
= 0; ny
< nHeight
; ny
++ )
831 if ( nRowBytes
< 8 || nPackType
== 1 )
833 for ( i
= 0; i
< nRowBytes
; i
++ )
839 nDataSize
+= nRowBytes
;
843 if ( nRowBytes
> 250 )
845 *pPict
>> nByteCount
;
846 nDataSize
+= 2 + (sal_uLong
)nByteCount
;
850 *pPict
>> nByteCountAsByte
;
851 nByteCount
= ( (sal_uInt16
)nByteCountAsByte
) & 0x00ff;
852 nDataSize
+= 1 + (sal_uLong
)nByteCount
;
857 *pPict
>> nFlagCounterByte
;
858 if ( ( nFlagCounterByte
& 0x80 ) == 0 )
860 nCount
= ( (sal_uInt16
)nFlagCounterByte
) + 1;
861 for ( i
= 0; i
< nCount
; i
++ )
867 nByteCount
-= 1 + nCount
;
871 nCount
= ( 1 - ( ( (sal_uInt16
)nFlagCounterByte
) | 0xff00 ) );
873 for ( i
= 0; i
< nCount
; i
++ )
884 else if ( nPixelSize
== 16 )
886 sal_uInt8 nByteCountAsByte
, nFlagCounterByte
;
887 sal_uInt16 nByteCount
, nCount
, nD
;
888 sal_uLong nSrcBitsPos
;
890 if ( nRowBytes
< 2 * nWidth
)
893 for ( ny
= 0; ny
< nHeight
; ny
++ )
896 if ( nRowBytes
< 8 || nPackType
== 1 )
898 for ( i
= 0; i
< nWidth
; i
++ )
901 nRed
= (sal_uInt8
)( nD
>> 7 );
902 nGreen
= (sal_uInt8
)( nD
>> 2 );
903 nBlue
= (sal_uInt8
)( nD
<< 3 );
904 pAcc
->SetPixel( ny
, nx
++, BitmapColor( nRed
, nGreen
, nBlue
) );
906 nDataSize
+= ( (sal_uLong
)nWidth
) * 2;
910 nSrcBitsPos
= pPict
->Tell();
911 if ( nRowBytes
> 250 )
913 *pPict
>> nByteCount
;
918 *pPict
>> nByteCountAsByte
;
919 nByteCount
= ( (sal_uInt16
)nByteCountAsByte
) & 0x00ff;
922 while ( nx
!= nWidth
)
924 *pPict
>> nFlagCounterByte
;
925 if ( (nFlagCounterByte
& 0x80) == 0)
927 nCount
=((sal_uInt16
)nFlagCounterByte
)+1;
928 if ( nCount
+ nx
> nWidth
) // SJ: the RLE decoding seems not to be correct here,
929 nCount
= nWidth
- nx
; // I don't want to change this until I have a bugdoc for
930 for (i
=0; i
<nCount
; i
++) // this case. Have a look at 32bit, there I changed the
931 { // encoding, so that it is used a straight forward array
933 nRed
= (sal_uInt8
)( nD
>> 7 );
934 nGreen
= (sal_uInt8
)( nD
>> 2 );
935 nBlue
= (sal_uInt8
)( nD
<< 3 );
936 pAcc
->SetPixel( ny
, nx
++, BitmapColor( nRed
, nGreen
, nBlue
) );
941 nCount
=(1-(((sal_uInt16
)nFlagCounterByte
)|0xff00));
942 if ( nCount
+ nx
> nWidth
)
943 nCount
= nWidth
- nx
;
945 nRed
= (sal_uInt8
)( nD
>> 7 );
946 nGreen
= (sal_uInt8
)( nD
>> 2 );
947 nBlue
= (sal_uInt8
)( nD
<< 3 );
948 for (i
=0; i
<nCount
; i
++)
950 pAcc
->SetPixel( ny
, nx
++, BitmapColor( nRed
, nGreen
, nBlue
) );
954 nDataSize
+=(sal_uLong
)nByteCount
;
955 pPict
->Seek(nSrcBitsPos
+(sal_uLong
)nByteCount
);
959 else if (nPixelSize
==32)
961 sal_uInt8 nByteCountAsByte
, nFlagCounterByte
;
962 sal_uInt16 nByteCount
, nCount
;
963 sal_uLong nSrcBitsPos
;
964 BitmapColor aBitmapColor
;
965 if ( ( pReadAcc
= aBitmap
.AcquireReadAccess() ) == NULL
)
967 if ( nRowBytes
!= 4*nWidth
)
970 if ( nRowBytes
< 8 || nPackType
== 1 )
972 for ( ny
= 0; ny
< nHeight
; ny
++ )
974 if ( nRowBytes
< 8 || nPackType
== 1 )
976 for ( nx
= 0; nx
< nWidth
; nx
++ )
978 *pPict
>> nDummy
>> nRed
>> nGreen
>> nBlue
;
979 pAcc
->SetPixel( ny
, nx
, BitmapColor( nRed
, nGreen
, nBlue
) );
981 nDataSize
+= ( (sal_uLong
)nWidth
) * 4;
985 else if ( nPackType
== 2 )
987 for ( ny
= 0; ny
< nHeight
; ny
++ )
989 for ( nx
= 0; nx
< nWidth
; nx
++ )
991 *pPict
>> nRed
>> nGreen
>> nBlue
;
992 pAcc
->SetPixel( ny
, nx
, BitmapColor( nRed
, nGreen
, nBlue
) );
994 nDataSize
+= ( (sal_uLong
)nWidth
) * 3;
999 if ( ( nCmpCount
== 3 ) || ( nCmpCount
== 4 ) )
1001 sal_uInt8
* pScanline
= new sal_uInt8
[ nWidth
* nCmpCount
];
1002 for ( ny
= 0; ny
< nHeight
; ny
++ )
1004 nSrcBitsPos
= pPict
->Tell();
1005 if ( nRowBytes
> 250 )
1007 *pPict
>> nByteCount
;
1012 *pPict
>> nByteCountAsByte
;
1013 nByteCount
= (sal_uInt8
)nByteCountAsByte
;
1017 while( i
< (sal_uInt32
)( nWidth
* nCmpCount
) )
1019 *pPict
>> nFlagCounterByte
;
1020 if ( ( nFlagCounterByte
& 0x80 ) == 0)
1022 nCount
= ( (sal_uInt16
)nFlagCounterByte
) + 1;
1023 if ( ( i
+ nCount
) > (sal_uInt32
)( nWidth
* nCmpCount
) )
1024 nCount
= (sal_uInt16
)( nWidth
* nCmpCount
- i
);
1028 pScanline
[ i
++ ] = nDat
;
1033 nCount
= ( 1 - ( ( (sal_uInt16
)nFlagCounterByte
) | 0xff00 ) );
1034 if ( ( i
+ nCount
) > (sal_uInt32
)( nWidth
* nCmpCount
) )
1035 nCount
= (sal_uInt16
)( nWidth
* nCmpCount
- i
);
1038 pScanline
[ i
++ ] = nDat
;
1041 sal_uInt8
* pTmp
= pScanline
;
1042 if ( nCmpCount
== 4 )
1044 for ( nx
= 0; nx
< nWidth
; pTmp
++ )
1045 pAcc
->SetPixel( ny
, nx
++, BitmapColor( *pTmp
, pTmp
[ nWidth
], pTmp
[ 2 * nWidth
] ) );
1046 nDataSize
+= (sal_uLong
)nByteCount
;
1047 pPict
->Seek( nSrcBitsPos
+ (sal_uLong
)nByteCount
);
1056 aBitmap
.ReleaseAccess( pReadAcc
);
1057 aBitmap
.ReleaseAccess( pAcc
);
1062 void PictReader::ReadHeader()
1067 // previous code considers pPict->Tell() as the normal starting position,
1068 // can we have nStartPos != 0 ?
1069 sal_uLong nStartPos
= pPict
->Tell();
1071 // a picture file begins by 512 bytes (reserved to the application) followed by the picture data
1072 // while clipboard, pictures stored in a document often contain only the picture data.
1075 // - some Pict v.1 use 0x00 0x11 0x01 ( instead of 0x11 0x01) to store the version op
1076 // (we consider here this as another standard for Pict. v.1 )
1077 // - some files seem to contain extra garbage data at the beginning
1078 // - some picture data seem to contain extra NOP opcode(0x00) between the bounding box and the version opcode
1080 // This code looks hard to find a picture header, ie. it looks at positions
1081 // - nStartPos+0, nStartPos+512 with potential extra NOP codes between bdbox and version (at most 9 extra NOP)
1082 // - 512..1024 with more strict bdbox checking and no extra NOP codes
1085 // - if the header can begin at nStartPos+0 and at nStartPos+512, we try to choose the more
1086 // <<probable>> ( using the variable confidence)
1087 // - svtools/source/filter.vcl/filter/{filter.cxx,filter2.cxx} only check for standard Pict,
1088 // this may cause future problems
1091 int confidence
[2] = { 0, 0};
1092 for ( st
= 0; st
< 3 + 513; st
++ )
1094 int actualConfid
= 20; // the actual confidence
1095 pPict
->ResetError();
1096 if (st
< 2) nOffset
= nStartPos
+st
*512;
1098 // choose nStartPos+0 or nStartPos+512 even if there are a little dubious
1099 int actPos
= -1, actConf
=0;
1100 if (confidence
[0] > 0) { actPos
= 0; actConf
= confidence
[0]; }
1101 if (confidence
[1] > 0 && confidence
[1] >= actConf
) actPos
= 1;
1102 if (actPos
< 0) continue;
1103 nOffset
= nStartPos
+actPos
*512;
1106 nOffset
= 509+st
; // illogical : more logical will be nStartPos+509+st or to consider that nStartPos=0
1107 // a small test to check if versionOp code exists after the bdbox ( with no extra NOP codes)
1108 pPict
->Seek(nOffset
+10);
1109 pPict
->Read( sBuf
, 2 );
1110 if (pPict
->IsEof() || pPict
->GetError()) break;
1111 if (sBuf
[0] == 0x11 || (sBuf
[0] == 0x00 && sBuf
[1] == 0x11)) ; // maybe ok
1114 pPict
->Seek(nOffset
);
1116 // 2 bytes to store size ( version 1 ) ignored
1117 pPict
->SeekRel( 2 );
1118 *pPict
>> y1
>> x1
>> y2
>> x2
; // frame rectangle of the picture
1119 if (x1
> x2
|| y1
> y2
) continue; // bad bdbox
1120 if (x1
< -2048 || x2
> 2048 || y1
< -2048 || y2
> 2048 || // origin|dest is very small|large
1121 (x1
== x2
&& y1
== y2
) ) // 1 pixel pict is dubious
1123 else if (x2
< x1
+8 || y2
< y1
+8) // a little dubious
1125 if (st
>= 3 && actualConfid
!= 20) continue;
1126 aBoundingRect
=Rectangle( x1
,y1
, x2
, y2
);
1128 if (pPict
->IsEof() || pPict
->GetError()) continue;
1130 pPict
->Read( sBuf
, 2 );
1132 if ( sBuf
[ 0 ] == 0x11 && sBuf
[ 1 ] == 0x01 ) {
1133 // pict v1 must be rare and we do only few tests
1134 if (st
< 2) { confidence
[st
] = --actualConfid
; continue; }
1135 IsVersion2
= sal_False
; return;
1137 if (sBuf
[0] != 0x00) continue; // unrecovable error
1143 pPict
->Read( sBuf
, 2 );
1145 while ( sBuf
[0] == 0x00 && numZero
< 10);
1146 actualConfid
-= (numZero
-1); // extra nop are dubious
1147 if (pPict
->IsEof() || pPict
->GetError()) continue;
1148 if (sBuf
[0] != 0x11) continue; // not a version opcode
1149 // abnormal version 1 file
1150 if (sBuf
[1] == 0x01 ) {
1151 // pict v1 must be rare and we do only few tests
1152 if (st
< 2) { confidence
[st
] = --actualConfid
; continue; }
1153 IsVersion2
= sal_False
; return;
1155 if (sBuf
[1] != 0x02 ) continue; // not a version 2 file
1157 IsVersion2
=sal_True
;
1158 short nExtVer
, nReserved
;
1159 // 3 Bytes ignored : end of version arg 0x02FF (ie: 0xFF), HeaderOp : 0x0C00
1160 pPict
->SeekRel( 3 );
1161 *pPict
>> nExtVer
>> nReserved
;
1162 if (pPict
->IsEof() || pPict
->GetError()) continue;
1164 if ( nExtVer
== -2 ) // extended version 2 picture
1166 sal_Int32 nHResFixed
, nVResFixed
;
1167 *pPict
>> nHResFixed
>> nVResFixed
;
1168 *pPict
>> y1
>> x1
>> y2
>> x2
; // reading the optimal bounding rect
1169 if (x1
> x2
|| y1
> y2
) continue; // bad bdbox
1170 if (st
< 2 && actualConfid
!= 20) { confidence
[st
] = actualConfid
; continue; }
1172 double fHRes
= nHResFixed
;
1174 double fVRes
= nVResFixed
;
1178 aBoundingRect
=Rectangle( x1
,y1
, x2
, y2
);
1179 pPict
->SeekRel( 4 ); // 4 bytes reserved
1182 else if (nExtVer
== -1 ) { // basic version 2 picture
1183 if (st
< 2 && actualConfid
!= 20) { confidence
[st
] = actualConfid
; continue; }
1184 pPict
->SeekRel( 16); // bdbox(4 fixed number)
1185 pPict
->SeekRel(4); // 4 bytes reserved
1189 pPict
->SetError(SVSTREAM_FILEFORMAT_ERROR
);
1192 sal_uLong
PictReader::ReadData(sal_uInt16 nOpcode
)
1196 sal_uLong nDataSize
=0;
1197 PictDrawingMethod shapeDMethod
= PDM_UNDEFINED
;
1198 switch (nOpcode
& 7) {
1199 case 0: shapeDMethod
= PDM_FRAME
; break;
1200 case 1: shapeDMethod
= PDM_PAINT
; break;
1201 case 2: shapeDMethod
= PDM_ERASE
; break;
1202 case 3: shapeDMethod
= PDM_INVERT
; break;
1203 case 4: shapeDMethod
= PDM_FILL
; break;
1213 case 0x0001: { // Clip
1217 ReadRectangle(aRect
);
1218 // checkme: do we really want to extend the rectangle here ?
1219 // I do that because the clipping is often used to clean a region,
1220 // before drawing some text and also to draw this text.
1221 // So using a too small region can lead to clip the end of the text ;
1222 // but this can be discutable...
1223 aRect
.setWidth(aRect
.getWidth()+1);
1224 aRect
.setHeight(aRect
.getHeight()+1);
1225 pVirDev
->SetClipRegion( Region( aRect
) );
1228 case 0x0002: // BkPat
1229 nDataSize
=eActBackPattern
.read(*pPict
);
1230 eActMethod
=PDM_UNDEFINED
;
1233 case 0x0003: // TxFont
1235 if (nUSHORT
<= 1) aActFont
.SetFamily(FAMILY_SWISS
);
1236 else if (nUSHORT
<= 12) aActFont
.SetFamily(FAMILY_DECORATIVE
);
1237 else if (nUSHORT
<= 20) aActFont
.SetFamily(FAMILY_ROMAN
);
1238 else if (nUSHORT
== 21) aActFont
.SetFamily(FAMILY_SWISS
);
1239 else if (nUSHORT
== 22) aActFont
.SetFamily(FAMILY_MODERN
);
1240 else if (nUSHORT
<= 1023) aActFont
.SetFamily(FAMILY_SWISS
);
1241 else aActFont
.SetFamily(FAMILY_ROMAN
);
1242 aActFont
.SetCharSet(GetTextEncoding(nUSHORT
));
1243 eActMethod
=PDM_UNDEFINED
;
1247 case 0x0004: { // TxFace
1250 if ( (nFace
& 0x01)!=0 ) aActFont
.SetWeight(WEIGHT_BOLD
);
1251 else aActFont
.SetWeight(WEIGHT_NORMAL
);
1252 if ( (nFace
& 0x02)!=0 ) aActFont
.SetItalic(ITALIC_NORMAL
);
1253 else aActFont
.SetItalic(ITALIC_NONE
);
1254 if ( (nFace
& 0x04)!=0 ) aActFont
.SetUnderline(UNDERLINE_SINGLE
);
1255 else aActFont
.SetUnderline(UNDERLINE_NONE
);
1256 if ( (nFace
& 0x08)!=0 ) aActFont
.SetOutline(sal_True
);
1257 else aActFont
.SetOutline(sal_False
);
1258 if ( (nFace
& 0x10)!=0 ) aActFont
.SetShadow(sal_True
);
1259 else aActFont
.SetShadow(sal_False
);
1260 eActMethod
=PDM_UNDEFINED
;
1264 case 0x0005: // TxMode
1268 case 0x0006: // SpExtra
1272 case 0x0007: { // PnSize
1273 nActPenSize
=ReadSize();
1274 eActMethod
=PDM_UNDEFINED
;
1278 case 0x0008: // PnMode
1280 // internal code for postscript command (Quickdraw Reference Drawing B-30,B-34)
1281 if (nUSHORT
==23) eActROP
= ROP_1
;
1283 switch (nUSHORT
& 0x0007) {
1284 case 0: eActROP
=ROP_OVERPAINT
; break; // Copy
1285 case 1: eActROP
=ROP_OVERPAINT
; break; // Or
1286 case 2: eActROP
=ROP_XOR
; break; // Xor
1287 case 3: eActROP
=ROP_OVERPAINT
; break; // Bic
1288 case 4: eActROP
=ROP_INVERT
; break; // notCopy
1289 case 5: eActROP
=ROP_OVERPAINT
; break; // notOr
1290 case 6: eActROP
=ROP_XOR
; break; // notXor
1291 case 7: eActROP
=ROP_OVERPAINT
; break; // notBic
1294 eActMethod
=PDM_UNDEFINED
;
1298 case 0x0009: // PnPat
1299 nDataSize
=eActPenPattern
.read(*pPict
);
1300 eActMethod
=PDM_UNDEFINED
;
1303 case 0x000a: // FillPat
1304 nDataSize
=eActFillPattern
.read(*pPict
);
1305 eActMethod
=PDM_UNDEFINED
;
1308 case 0x000b: // OvSize
1309 aActOvalSize
=ReadSize();
1313 case 0x000c: // Origin
1317 case 0x000d: // TxSize
1320 aActFont
.SetSize( Size( 0, (long)nUSHORT
) );
1321 eActMethod
=PDM_UNDEFINED
;
1326 case 0x000e: // FgColor
1327 aActForeColor
=ReadColor();
1328 eActMethod
=PDM_UNDEFINED
;
1332 case 0x000f: // BkColor
1333 aActBackColor
=ReadColor();
1337 case 0x0010: // TxRatio
1341 case 0x0011: // VersionOp
1345 case 0x0012: // BkPixPat
1346 nDataSize
=ReadPixPattern(eActBackPattern
);
1347 eActMethod
=PDM_UNDEFINED
;
1350 case 0x0013: // PnPixPat
1351 nDataSize
=ReadPixPattern(eActPenPattern
);
1352 eActMethod
=PDM_UNDEFINED
;
1355 case 0x0014: // FillPixPat
1356 nDataSize
=ReadPixPattern(eActFillPattern
);
1357 eActMethod
=PDM_UNDEFINED
;
1360 case 0x0015: // PnLocHFrac
1364 case 0x0016: // ChExtra
1368 case 0x0017: // Reserved (0 Bytes)
1369 case 0x0018: // Reserved (0 Bytes)
1370 case 0x0019: // Reserved (0 Bytes)
1374 case 0x001a: // RGBFgCol
1375 aActForeColor
=ReadRGBColor();
1376 eActMethod
=PDM_UNDEFINED
;
1380 case 0x001b: // RGBBkCol
1381 aActBackColor
=ReadRGBColor();
1382 eActMethod
=PDM_UNDEFINED
;
1386 case 0x001c: // HiliteMode
1390 case 0x001d: // HiliteColor
1394 case 0x001e: // DefHilite
1398 case 0x001f: // OpColor
1402 case 0x0020: // Line
1403 aPoint
=ReadPoint(); aPenPosition
=ReadPoint();
1406 if (IsInvisible(PDM_FRAME
)) break;
1407 DrawingMethod(PDM_FRAME
);
1408 PictReaderShape::drawLine(pVirDev
, aPoint
,aPenPosition
, nActPenSize
);
1411 case 0x0021: // LineFrom
1412 aPoint
=aPenPosition
; aPenPosition
=ReadPoint();
1415 if (IsInvisible(PDM_FRAME
)) break;
1416 DrawingMethod(PDM_FRAME
);
1417 PictReaderShape::drawLine(pVirDev
, aPoint
,aPenPosition
, nActPenSize
);
1420 case 0x0022: // ShortLine
1422 aPenPosition
=ReadDeltaH(aPoint
);
1423 aPenPosition
=ReadDeltaV(aPenPosition
);
1426 if (IsInvisible(PDM_FRAME
)) break;
1427 DrawingMethod(PDM_FRAME
);
1428 PictReaderShape::drawLine(pVirDev
, aPoint
,aPenPosition
, nActPenSize
);
1431 case 0x0023: // ShortLineFrom
1432 aPoint
=aPenPosition
;
1433 aPenPosition
=ReadDeltaH(aPoint
);
1434 aPenPosition
=ReadDeltaV(aPenPosition
);
1437 if (IsInvisible(PDM_FRAME
)) break;
1438 DrawingMethod(PDM_FRAME
);
1439 PictReaderShape::drawLine(pVirDev
, aPoint
,aPenPosition
, nActPenSize
);
1442 case 0x0024: // Reserved (n Bytes)
1443 case 0x0025: // Reserved (n Bytes)
1444 case 0x0026: // Reserved (n Bytes)
1445 case 0x0027: // Reserved (n Bytes)
1447 nDataSize
=2+nUSHORT
;
1450 case 0x0028: // LongText
1451 aTextPosition
=ReadPoint();
1452 nDataSize
=4+ReadAndDrawText();
1455 case 0x0029: // DHText
1456 aTextPosition
=ReadUnsignedDeltaH(aTextPosition
);
1457 nDataSize
=1+ReadAndDrawText();
1460 case 0x002a: // DVText
1461 aTextPosition
=ReadUnsignedDeltaV(aTextPosition
);
1462 nDataSize
=1+ReadAndDrawText();
1465 case 0x002b: // DHDVText
1466 aTextPosition
=ReadUnsignedDeltaH(aTextPosition
);
1467 aTextPosition
=ReadUnsignedDeltaV(aTextPosition
);
1468 nDataSize
=2+ReadAndDrawText();
1471 case 0x002c: { // fontName
1472 char sFName
[ 256 ], nByteLen
;
1474 *pPict
>> nUSHORT
; nDataSize
=nUSHORT
+2;
1476 if (nUSHORT
<= 1) aActFont
.SetFamily(FAMILY_SWISS
);
1477 else if (nUSHORT
<= 12) aActFont
.SetFamily(FAMILY_DECORATIVE
);
1478 else if (nUSHORT
<= 20) aActFont
.SetFamily(FAMILY_ROMAN
);
1479 else if (nUSHORT
== 21) aActFont
.SetFamily(FAMILY_SWISS
);
1480 else if (nUSHORT
== 22) aActFont
.SetFamily(FAMILY_MODERN
);
1481 else if (nUSHORT
<= 1023) aActFont
.SetFamily(FAMILY_SWISS
);
1482 else aActFont
.SetFamily(FAMILY_ROMAN
);
1483 aActFont
.SetCharSet(GetTextEncoding(nUSHORT
));
1484 *pPict
>> nByteLen
; nLen
=((sal_uInt16
)nByteLen
)&0x00ff;
1485 pPict
->Read( &sFName
, nLen
);
1487 String
aString( (const sal_Char
*)&sFName
, osl_getThreadTextEncoding() );
1488 aActFont
.SetName( aString
);
1489 eActMethod
=PDM_UNDEFINED
;
1492 case 0x002d: // lineJustify
1496 case 0x002e: // glyphState
1498 nDataSize
=2+nUSHORT
;
1501 case 0x002f: // Reserved (n Bytes)
1503 nDataSize
=2+nUSHORT
;
1506 case 0x0030: // frameRect
1507 case 0x0031: // paintRect
1508 case 0x0032: // eraseRect
1509 case 0x0033: // invertRect
1510 case 0x0034: // fillRect
1511 nDataSize
=ReadAndDrawRect(shapeDMethod
);
1514 case 0x0035: // Reserved (8 Bytes)
1515 case 0x0036: // Reserved (8 Bytes)
1516 case 0x0037: // Reserved (8 Bytes)
1520 case 0x0038: // frameSameRect
1521 case 0x0039: // paintSameRect
1522 case 0x003a: // eraseSameRect
1523 case 0x003b: // invertSameRect
1524 case 0x003c: // fillSameRect
1525 nDataSize
=ReadAndDrawSameRect(shapeDMethod
);
1528 case 0x003d: // Reserved (0 Bytes)
1529 case 0x003e: // Reserved (0 Bytes)
1530 case 0x003f: // Reserved (0 Bytes)
1534 case 0x0040: // frameRRect
1535 case 0x0041: // paintRRect
1536 case 0x0042: // eraseRRect
1537 case 0x0043: // invertRRect
1538 case 0x0044: // fillRRect
1539 nDataSize
=ReadAndDrawRoundRect(shapeDMethod
);
1542 case 0x0045: // Reserved (8 Bytes)
1543 case 0x0046: // Reserved (8 Bytes)
1544 case 0x0047: // Reserved (8 Bytes)
1548 case 0x0048: // frameSameRRect
1549 case 0x0049: // paintSameRRect
1550 case 0x004a: // eraseSameRRect
1551 case 0x004b: // invertSameRRect
1552 case 0x004c: // fillSameRRect
1553 nDataSize
=ReadAndDrawSameRoundRect(shapeDMethod
);
1556 case 0x004d: // Reserved (0 Bytes)
1557 case 0x004e: // Reserved (0 Bytes)
1558 case 0x004f: // Reserved (0 Bytes)
1562 case 0x0050: // frameOval
1563 case 0x0051: // paintOval
1564 case 0x0052: // eraseOval
1565 case 0x0053: // invertOval
1566 case 0x0054: // fillOval
1567 nDataSize
=ReadAndDrawOval(shapeDMethod
);
1570 case 0x0055: // Reserved (8 Bytes)
1571 case 0x0056: // Reserved (8 Bytes)
1572 case 0x0057: // Reserved (8 Bytes)
1576 case 0x0058: // frameSameOval
1577 case 0x0059: // paintSameOval
1578 case 0x005a: // eraseSameOval
1579 case 0x005b: // invertSameOval
1580 case 0x005c: // fillSameOval
1581 nDataSize
=ReadAndDrawSameOval(shapeDMethod
);
1584 case 0x005d: // Reserved (0 Bytes)
1585 case 0x005e: // Reserved (0 Bytes)
1586 case 0x005f: // Reserved (0 Bytes)
1590 case 0x0060: // frameArc
1591 case 0x0061: // paintArc
1592 case 0x0062: // eraseArc
1593 case 0x0063: // invertArc
1594 case 0x0064: // fillArc
1595 nDataSize
=ReadAndDrawArc(shapeDMethod
);
1598 case 0x0065: // Reserved (12 Bytes)
1599 case 0x0066: // Reserved (12 Bytes)
1600 case 0x0067: // Reserved (12 Bytes)
1604 case 0x0068: // frameSameArc
1605 case 0x0069: // paintSameArc
1606 case 0x006a: // eraseSameArc
1607 case 0x006b: // invertSameArc
1608 case 0x006c: // fillSameArc
1609 nDataSize
=ReadAndDrawSameArc(shapeDMethod
);
1612 case 0x006d: // Reserved (4 Bytes)
1613 case 0x006e: // Reserved (4 Bytes)
1614 case 0x006f: // Reserved (4 Bytes)
1618 case 0x0070: // framePoly
1619 case 0x0071: // paintPoly
1620 case 0x0072: // erasePoly
1621 case 0x0073: // invertPoly
1622 case 0x0074: // fillPoly
1623 nDataSize
=ReadAndDrawPolygon(shapeDMethod
);
1626 case 0x0075: // Reserved (Polygon-Size)
1627 case 0x0076: // Reserved (Polygon-Size)
1628 case 0x0077: // Reserved (Polygon-Size)
1629 *pPict
>> nUSHORT
; nDataSize
=nUSHORT
;
1632 case 0x0078: // frameSamePoly
1633 case 0x0079: // paintSamePoly
1634 case 0x007a: // eraseSamePoly
1635 case 0x007b: // invertSamePoly
1636 case 0x007c: // fillSamePoly
1637 nDataSize
=ReadAndDrawSamePolygon(shapeDMethod
);
1640 case 0x007d: // Reserved (0 Bytes)
1641 case 0x007e: // Reserved (0 Bytes)
1642 case 0x007f: // Reserved (0 Bytes)
1646 case 0x0080: // frameRgn
1647 case 0x0081: // paintRgn
1648 case 0x0082: // eraseRgn
1649 case 0x0083: // invertRgn
1650 case 0x0084: // fillRgn
1651 nDataSize
=ReadAndDrawRgn(shapeDMethod
);
1654 case 0x0085: // Reserved (Region-Size)
1655 case 0x0086: // Reserved (Region-Size)
1656 case 0x0087: // Reserved (Region-Size)
1657 *pPict
>> nUSHORT
; nDataSize
=nUSHORT
;
1660 case 0x0088: // frameSameRgn
1661 case 0x0089: // paintSameRgn
1662 case 0x008a: // eraseSameRgn
1663 case 0x008b: // invertSameRgn
1664 case 0x008c: // fillSameRgn
1665 nDataSize
=ReadAndDrawSameRgn(shapeDMethod
);
1668 case 0x008d: // Reserved (0 Bytes)
1669 case 0x008e: // Reserved (0 Bytes)
1670 case 0x008f: // Reserved (0 Bytes)
1674 case 0x0090: { // BitsRect
1676 Rectangle aSrcRect
, aDestRect
;
1677 nDataSize
=ReadPixMapEtc(aBmp
, sal_False
, sal_True
, &aSrcRect
, &aDestRect
, sal_True
, sal_False
);
1678 DrawingMethod(PDM_PAINT
);
1679 pVirDev
->DrawBitmap(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1682 case 0x0091: { // BitsRgn
1684 Rectangle aSrcRect
, aDestRect
;
1685 nDataSize
=ReadPixMapEtc(aBmp
, sal_False
, sal_True
, &aSrcRect
, &aDestRect
, sal_True
, sal_True
);
1686 DrawingMethod(PDM_PAINT
);
1687 pVirDev
->DrawBitmap(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1690 case 0x0092: // Reserved (n Bytes)
1691 case 0x0093: // Reserved (n Bytes)
1692 case 0x0094: // Reserved (n Bytes)
1693 case 0x0095: // Reserved (n Bytes)
1694 case 0x0096: // Reserved (n Bytes)
1695 case 0x0097: // Reserved (n Bytes)
1696 *pPict
>> nUSHORT
; nDataSize
=2+nUSHORT
;
1699 case 0x0098: { // PackBitsRect
1701 Rectangle aSrcRect
, aDestRect
;
1702 nDataSize
=ReadPixMapEtc(aBmp
, sal_False
, sal_True
, &aSrcRect
, &aDestRect
, sal_True
, sal_False
);
1703 DrawingMethod(PDM_PAINT
);
1704 pVirDev
->DrawBitmap(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1707 case 0x0099: { // PackBitsRgn
1709 Rectangle aSrcRect
, aDestRect
;
1710 nDataSize
=ReadPixMapEtc(aBmp
, sal_False
, sal_True
, &aSrcRect
, &aDestRect
, sal_True
, sal_True
);
1711 DrawingMethod(PDM_PAINT
);
1712 pVirDev
->DrawBitmap(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1715 case 0x009a: { // DirectBitsRect
1717 Rectangle aSrcRect
, aDestRect
;
1718 nDataSize
=ReadPixMapEtc(aBmp
, sal_True
, sal_False
, &aSrcRect
, &aDestRect
, sal_True
, sal_False
);
1719 DrawingMethod(PDM_PAINT
);
1720 pVirDev
->DrawBitmap(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1723 case 0x009b: { // DirectBitsRgn
1725 Rectangle aSrcRect
, aDestRect
;
1726 nDataSize
=ReadPixMapEtc(aBmp
, sal_True
, sal_False
, &aSrcRect
, &aDestRect
, sal_True
, sal_True
);
1727 DrawingMethod(PDM_PAINT
);
1728 pVirDev
->DrawBitmap(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1731 case 0x009c: // Reserved (n Bytes)
1732 case 0x009d: // Reserved (n Bytes)
1733 case 0x009e: // Reserved (n Bytes)
1734 case 0x009f: // Reserved (n Bytes)
1735 *pPict
>> nUSHORT
; nDataSize
=2+nUSHORT
;
1738 case 0x00a0: // ShortComment
1742 case 0x00a1: // LongComment
1743 pPict
->SeekRel(2); *pPict
>> nUSHORT
; nDataSize
=4+nUSHORT
;
1746 default: // 0x00a2 bis 0xffff (most times reserved)
1747 if (nOpcode
<=0x00af) { *pPict
>> nUSHORT
; nDataSize
=2+nUSHORT
; }
1748 else if (nOpcode
<=0x00cf) { nDataSize
=0; }
1749 else if (nOpcode
<=0x00fe) { sal_uInt32 nTemp
; *pPict
>> nTemp
; nDataSize
= nTemp
; nDataSize
+=4; }
1750 // Osnola: checkme: in the Quickdraw Ref examples ( for pict v2)
1751 // 0x00ff(EndOfPict) is also not followed by any data...
1752 else if (nOpcode
==0x00ff) { nDataSize
=IsVersion2
? 2 : 0; } // OpEndPic
1753 else if (nOpcode
<=0x01ff) { nDataSize
=2; }
1754 else if (nOpcode
<=0x0bfe) { nDataSize
=4; }
1755 else if (nOpcode
<=0x0bff) { nDataSize
=22; }
1756 else if (nOpcode
==0x0c00) { nDataSize
=24; } // HeaderOp
1757 else if (nOpcode
<=0x7eff) { nDataSize
=24; }
1758 else if (nOpcode
<=0x7fff) { nDataSize
=254; }
1759 else if (nOpcode
<=0x80ff) { nDataSize
=0; }
1760 else { sal_uInt32 nTemp
; *pPict
>> nTemp
; nDataSize
= nTemp
; nDataSize
+=4; }
1763 if (nDataSize
==0xffffffff) {
1764 pPict
->SetError(SVSTREAM_FILEFORMAT_ERROR
);
1770 void PictReader::ReadPict( SvStream
& rStreamPict
, GDIMetaFile
& rGDIMetaFile
)
1773 sal_uInt8 nOneByteOpcode
;
1774 sal_uLong nSize
, nPos
, nStartPos
, nEndPos
, nPercent
, nLastPercent
;
1776 pPict
= &rStreamPict
;
1777 nOrigPos
= pPict
->Tell();
1778 nOrigNumberFormat
= pPict
->GetNumberFormatInt();
1780 aActForeColor
= Color(COL_BLACK
);
1781 aActBackColor
= Color(COL_WHITE
);
1782 nActPenSize
= Size(1,1);
1783 eActROP
= ROP_OVERPAINT
;
1784 eActMethod
= PDM_UNDEFINED
;
1785 aActOvalSize
= Size(1,1);
1787 aActFont
.SetCharSet( GetTextEncoding());
1788 aActFont
.SetFamily(FAMILY_SWISS
);
1789 aActFont
.SetSize(Size(0,12));
1790 aActFont
.SetAlign(ALIGN_BASELINE
);
1792 aHRes
= aVRes
= Fraction( 1, 1 );
1794 pVirDev
= new VirtualDevice();
1795 pVirDev
->EnableOutput(sal_False
);
1796 rGDIMetaFile
.Record(pVirDev
);
1798 pPict
->SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN
);
1800 nStartPos
=pPict
->Tell();
1801 nEndPos
=pPict
->Seek(STREAM_SEEK_TO_END
); pPict
->Seek(nStartPos
);
1802 Callback(0); nLastPercent
=0;
1806 aPenPosition
=Point(-aBoundingRect
.Left(),-aBoundingRect
.Top());
1807 aTextPosition
=aPenPosition
;
1813 nPercent
=(nPos
-nStartPos
)*100/(nEndPos
-nStartPos
);
1814 if (nLastPercent
+4<=nPercent
) {
1815 if (Callback((sal_uInt16
)nPercent
)==sal_True
) break;
1816 nLastPercent
=nPercent
;
1823 *pPict
>> nOneByteOpcode
;
1824 nOpcode
=(sal_uInt16
)nOneByteOpcode
;
1827 if (pPict
->GetError())
1832 pPict
->SetError(SVSTREAM_FILEFORMAT_ERROR
);
1836 if (nOpcode
==0x00ff)
1839 nSize
=ReadData(nOpcode
);
1854 rGDIMetaFile
.Stop();
1857 rGDIMetaFile
.SetPrefMapMode( MapMode( MAP_INCH
, Point(), aHRes
, aVRes
) );
1858 rGDIMetaFile
.SetPrefSize( aBoundingRect
.GetSize() );
1860 pPict
->SetNumberFormatInt(nOrigNumberFormat
);
1862 if (pPict
->GetError()) pPict
->Seek(nOrigPos
);
1865 //================== GraphicImport - the exported function ================
1867 // this needs to be kept in sync with
1868 // ImpFilterLibCacheEntry::GetImportFunction() from
1869 // vcl/source/filter/graphicfilter.cxx
1870 #if defined(DISABLE_DYNLOADING)
1871 #define GraphicImport iptGraphicImport
1874 extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL
1875 GraphicImport( SvStream
& rIStm
, Graphic
& rGraphic
, FilterConfigItem
*, sal_Bool
)
1878 PictReader aPictReader
;
1879 sal_Bool bRet
= sal_False
;
1881 aPictReader
.ReadPict( rIStm
, aMTF
);
1883 if ( !rIStm
.GetError() )
1885 rGraphic
= Graphic( aMTF
);
1893 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */