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 .
20 #include <filter/PictReader.hxx>
22 #include <osl/thread.h>
23 #include <sal/log.hxx>
24 #include <vcl/BitmapTools.hxx>
25 #include <vcl/graph.hxx>
26 #include <vcl/gdimtf.hxx>
27 #include <tools/poly.hxx>
28 #include <tools/fract.hxx>
29 #include <tools/stream.hxx>
30 #include <vcl/virdev.hxx>
35 #include <vcl/FilterConfigItem.hxx>
36 // complete FilterConfigItem for GraphicImport under -fsanitize=function
38 namespace PictReaderInternal
{
41 //! utilitary class to store a pattern, ...
45 Pattern() : penStyle(PEN_SOLID
),
46 brushStyle(BRUSH_SOLID
),
52 //! reads black/white pattern from SvStream
53 sal_uInt8
read(SvStream
&stream
);
55 void setColor(Color col
) { isColor
= true; color
= col
; }
56 /** returns a color which can be "used" to replace the pattern,
57 * created from ForeColor and BackColor, ...
59 * note: maybe, we must also use some mode PatCopy, ... to define the color
61 Color
getColor(Color bkColor
, Color fgColor
) const {
62 if (isColor
) return color
;
63 // we create a gray pattern from nBitCount
64 double alpha
= nBitCount
/ 64.0;
65 return Color(sal_uInt8(alpha
*fgColor
.GetRed()+(1.0-alpha
)*bkColor
.GetRed()),
66 sal_uInt8(alpha
*fgColor
.GetGreen()+(1.0-alpha
)*bkColor
.GetGreen()),
67 sal_uInt8(alpha
*fgColor
.GetBlue()+(1.0-alpha
)*bkColor
.GetBlue()));
70 //! returns true if this is the default pattern
71 bool isDefault() const { return !isRead
; }
73 enum PenStyle
{ PEN_NULL
, PEN_SOLID
, PEN_DOT
, PEN_DASH
, PEN_DASHDOT
};
74 enum BrushStyle
{ BRUSH_SOLID
, BRUSH_HORZ
, BRUSH_VERT
,
75 BRUSH_CROSS
, BRUSH_DIAGCROSS
, BRUSH_UPDIAG
, BRUSH_DOWNDIAG
,
76 BRUSH_25
, BRUSH_50
, BRUSH_75
};
78 enum PenStyle penStyle
;
79 enum BrushStyle brushStyle
;
82 bool isColor
; // true if it is a color pattern
86 // flag to know if the pattern came from reading the picture, or if it is the default pattern
92 sal_uInt8
Pattern::read(SvStream
&stream
) {
93 unsigned char nbyte
[8] = {0};
96 // count the no of bits in pattern which are set to 1:
98 for (unsigned char & ny
: nbyte
) {
99 stream
.ReadChar( reinterpret_cast<char&>(ny
) );
100 for (short nx
=0; nx
<8; nx
++) {
101 if ( (ny
& (1<<nx
)) != 0 ) nBitCount
++;
105 // store pattern in 2 long words:
106 sal_uInt32 nHiBytes
= (((((static_cast<sal_uInt32
>(nbyte
[0])<<8)|
107 static_cast<sal_uInt32
>(nbyte
[1]))<<8)|
108 static_cast<sal_uInt32
>(nbyte
[2]))<<8)|
109 static_cast<sal_uInt32
>(nbyte
[3]);
110 sal_uInt32 nLoBytes
= (((((static_cast<sal_uInt32
>(nbyte
[4])<<8)|
111 static_cast<sal_uInt32
>(nbyte
[5]))<<8)|
112 static_cast<sal_uInt32
>(nbyte
[6]))<<8)|
113 static_cast<sal_uInt32
>(nbyte
[7]);
115 // create a PenStyle:
116 if (nBitCount
<=0) penStyle
=PEN_NULL
;
117 else if (nBitCount
<=16) penStyle
=PEN_DOT
;
118 else if (nBitCount
<=32) penStyle
=PEN_DASHDOT
;
119 else if (nBitCount
<=48) penStyle
=PEN_DASH
;
120 else penStyle
=PEN_SOLID
;
122 // create a BrushStyle:
123 if (nHiBytes
==0xffffffff && nLoBytes
==0xffffffff) brushStyle
=BRUSH_SOLID
;
124 else if (nHiBytes
==0xff000000 && nLoBytes
==0x00000000) brushStyle
=BRUSH_HORZ
;
125 else if (nHiBytes
==0x80808080 && nLoBytes
==0x80808080) brushStyle
=BRUSH_VERT
;
126 else if (nHiBytes
==0xff808080 && nLoBytes
==0x80808080) brushStyle
=BRUSH_CROSS
;
127 else if (nHiBytes
==0x01824428 && nLoBytes
==0x10284482) brushStyle
=BRUSH_DIAGCROSS
;
128 else if (nHiBytes
==0x80402010 && nLoBytes
==0x08040201) brushStyle
=BRUSH_UPDIAG
;
129 else if (nHiBytes
==0x01020408 && nLoBytes
==0x10204080) brushStyle
=BRUSH_DOWNDIAG
;
130 else if (nBitCount
<=24) brushStyle
=BRUSH_25
;
131 else if (nBitCount
<=40) brushStyle
=BRUSH_50
;
132 else if (nBitCount
<=56) brushStyle
=BRUSH_75
;
133 else brushStyle
=BRUSH_SOLID
;
141 //============================ PictReader ==================================
145 enum class PictDrawingMethod
{
146 FRAME
, PAINT
, ERASE
, INVERT
, FILL
,
151 typedef class PictReaderInternal::Pattern Pattern
;
154 SvStream
* pPict
; // The Pict file to read.
155 VclPtr
<VirtualDevice
> pVirDev
; // Here the drawing method will be called.
156 // A recording into the GDIMetaFile will take place.
158 sal_uInt64 nOrigPos
; // Initial position in pPict.
159 bool IsVersion2
; // If it is a version 2 Pictfile.
160 tools::Rectangle aBoundingRect
; // Min/Max-Rectangle for the whole drawing.
166 Pattern eActPenPattern
;
167 Pattern eActFillPattern
;
168 Pattern eActBackPattern
;
170 // Note: Postscript mode is stored by setting eActRop to RasterOp::N1
172 PictDrawingMethod eActMethod
;
181 Point
ReadDeltaH(Point aBase
);
182 Point
ReadDeltaV(Point aBase
);
184 Point
ReadUnsignedDeltaH(Point aBase
);
185 Point
ReadUnsignedDeltaV(Point aBase
);
191 Color
ReadRGBColor();
193 void ReadRectangle(tools::Rectangle
& rRect
);
195 sal_uInt64
ReadPolygon(tools::Polygon
& rPoly
);
197 sal_uInt64
ReadPixPattern(Pattern
&pattern
);
199 tools::Rectangle aLastRect
;
200 sal_uInt8
ReadAndDrawRect(PictDrawingMethod eMethod
);
201 sal_uInt8
ReadAndDrawSameRect(PictDrawingMethod eMethod
);
203 tools::Rectangle aLastRoundRect
;
204 sal_uInt8
ReadAndDrawRoundRect(PictDrawingMethod eMethod
);
205 sal_uInt8
ReadAndDrawSameRoundRect(PictDrawingMethod eMethod
);
207 tools::Rectangle aLastOval
;
208 sal_uInt8
ReadAndDrawOval(PictDrawingMethod eMethod
);
209 sal_uInt8
ReadAndDrawSameOval(PictDrawingMethod eMethod
);
211 tools::Polygon aLastPolygon
;
212 sal_uInt64
ReadAndDrawPolygon(PictDrawingMethod eMethod
);
213 sal_uInt8
ReadAndDrawSamePolygon(PictDrawingMethod eMethod
);
215 tools::Rectangle aLastArcRect
;
216 sal_uInt8
ReadAndDrawArc(PictDrawingMethod eMethod
);
217 sal_uInt8
ReadAndDrawSameArc(PictDrawingMethod eMethod
);
219 sal_uInt64
ReadAndDrawRgn(PictDrawingMethod eMethod
);
220 sal_uInt8
ReadAndDrawSameRgn(PictDrawingMethod eMethod
);
222 // returns true if there's no need to print the shape/text/frame
223 bool IsInvisible( PictDrawingMethod eMethod
) const {
224 if ( eActROP
== RasterOp::N1
) return true;
225 if ( eMethod
== PictDrawingMethod::FRAME
&& nActPenSize
.IsEmpty() ) return true;
229 void DrawingMethod(PictDrawingMethod eMethod
);
231 sal_uInt64
ReadAndDrawText();
233 sal_uInt64
ReadPixMapEtc(BitmapEx
& rBitmap
, bool bBaseAddr
, bool bColorTable
,
234 tools::Rectangle
* pSrcRect
, tools::Rectangle
* pDestRect
,
235 bool bMode
, bool bMaskRgn
);
238 // Reads the header of the Pict file, set IsVersion and aBoundingRect
240 sal_uInt64
ReadData(sal_uInt16 nOpcode
);
241 // Reads the date of anOopcode and executes the operation.
242 // The number of data bytes belonging to the opcode will be returned
245 void SetLineColor( const Color
& rColor
);
246 void SetFillColor( const Color
& rColor
);
248 // OSNOLA: returns the text encoding which must be used for system id
249 static rtl_TextEncoding
GetTextEncoding (sal_uInt16 fId
= 0xFFFF);
258 , eActROP(RasterOp::OverPaint
)
259 , eActMethod(PictDrawingMethod::UNDEFINED
)
261 aActFont
.SetCharSet(GetTextEncoding());
264 void ReadPict( SvStream
& rStreamPict
, GDIMetaFile
& rGDIMetaFile
);
265 // reads a pict file from the stream and fills the GDIMetaFile
271 static void SetByte(sal_uInt16
& nx
, sal_uInt16 ny
, vcl::bitmap::RawBitmap
& rBitmap
, sal_uInt16 nPixelSize
, sal_uInt8 nDat
, sal_uInt16 nWidth
, std::vector
<Color
> const & rvPalette
)
276 rBitmap
.SetPixel(ny
, nx
++, rvPalette
[(nDat
>> 7) & 1]);
277 if ( nx
== nWidth
) break;
278 rBitmap
.SetPixel(ny
, nx
++, rvPalette
[(nDat
>> 6) & 1]);
279 if ( nx
== nWidth
) break;
280 rBitmap
.SetPixel(ny
, nx
++, rvPalette
[(nDat
>> 5) & 1]);
281 if ( nx
== nWidth
) break;
282 rBitmap
.SetPixel(ny
, nx
++, rvPalette
[(nDat
>> 4) & 1]);
283 if ( nx
== nWidth
) break;
284 rBitmap
.SetPixel(ny
, nx
++, rvPalette
[(nDat
>> 3) & 1]);
285 if ( nx
== nWidth
) break;
286 rBitmap
.SetPixel(ny
, nx
++, rvPalette
[(nDat
>> 2) & 1]);
287 if ( nx
== nWidth
) break;
288 rBitmap
.SetPixel(ny
, nx
++, rvPalette
[(nDat
>> 1) & 1]);
289 if ( nx
== nWidth
) break;
290 rBitmap
.SetPixel(ny
, nx
++, rvPalette
[nDat
& 1]);
293 rBitmap
.SetPixel(ny
, nx
++, rvPalette
[nDat
>> 6]);
294 if ( nx
== nWidth
) break;
295 rBitmap
.SetPixel(ny
, nx
++, rvPalette
[(nDat
>>4)&3]);
296 if ( nx
== nWidth
) break;
297 rBitmap
.SetPixel(ny
, nx
++, rvPalette
[(nDat
>>2)&3]);
298 if ( nx
== nWidth
) break;
299 rBitmap
.SetPixel(ny
, nx
++, rvPalette
[nDat
& 3]);
302 rBitmap
.SetPixel(ny
, nx
++, rvPalette
[nDat
>> 4]);
303 if ( nx
== nWidth
) break;
304 rBitmap
.SetPixel(ny
, nx
++, rvPalette
[nDat
& 0x0f]);
307 rBitmap
.SetPixel(ny
, nx
++, rvPalette
[nDat
]);
312 //=================== methods of PictReader ==============================
313 rtl_TextEncoding
PictReader::GetTextEncoding (sal_uInt16 fId
) {
314 static rtl_TextEncoding enc
= []()
316 rtl_TextEncoding def
= osl_getThreadTextEncoding();
317 // we keep osl_getThreadTextEncoding only if it is a mac encoding
319 case RTL_TEXTENCODING_APPLE_ROMAN
:
320 case RTL_TEXTENCODING_APPLE_ARABIC
:
321 case RTL_TEXTENCODING_APPLE_CENTEURO
:
322 case RTL_TEXTENCODING_APPLE_CROATIAN
:
323 case RTL_TEXTENCODING_APPLE_CYRILLIC
:
324 case RTL_TEXTENCODING_APPLE_DEVANAGARI
:
325 case RTL_TEXTENCODING_APPLE_FARSI
:
326 case RTL_TEXTENCODING_APPLE_GREEK
:
327 case RTL_TEXTENCODING_APPLE_GUJARATI
:
328 case RTL_TEXTENCODING_APPLE_GURMUKHI
:
329 case RTL_TEXTENCODING_APPLE_HEBREW
:
330 case RTL_TEXTENCODING_APPLE_ICELAND
:
331 case RTL_TEXTENCODING_APPLE_ROMANIAN
:
332 case RTL_TEXTENCODING_APPLE_THAI
:
333 case RTL_TEXTENCODING_APPLE_TURKISH
:
334 case RTL_TEXTENCODING_APPLE_UKRAINIAN
:
335 case RTL_TEXTENCODING_APPLE_CHINSIMP
:
336 case RTL_TEXTENCODING_APPLE_CHINTRAD
:
337 case RTL_TEXTENCODING_APPLE_JAPANESE
:
338 case RTL_TEXTENCODING_APPLE_KOREAN
:
343 return RTL_TEXTENCODING_APPLE_ROMAN
;
345 if (fId
== 13) return RTL_TEXTENCODING_ADOBE_DINGBATS
; // CHECKME
346 if (fId
== 23) return RTL_TEXTENCODING_ADOBE_SYMBOL
;
350 void PictReader::SetLineColor( const Color
& rColor
)
352 pVirDev
->SetLineColor( rColor
);
355 void PictReader::SetFillColor( const Color
& rColor
)
357 pVirDev
->SetFillColor( rColor
);
360 Point
PictReader::ReadPoint()
364 pPict
->ReadInt16( ny
).ReadInt16( nx
);
366 Point
aPoint(nx
- aBoundingRect
.Left(), ny
- aBoundingRect
.Top());
368 SAL_INFO("filter.pict", "ReadPoint: " << aPoint
);
372 Point
PictReader::ReadDeltaH(Point aBase
)
376 pPict
->ReadChar( reinterpret_cast<char&>(ndh
) );
378 return Point( aBase
.X() + static_cast<tools::Long
>(ndh
), aBase
.Y() );
381 Point
PictReader::ReadDeltaV(Point aBase
)
385 pPict
->ReadChar( reinterpret_cast<char&>(ndv
) );
387 return Point( aBase
.X(), aBase
.Y() + static_cast<tools::Long
>(ndv
) );
390 Point
PictReader::ReadUnsignedDeltaH(Point aBase
)
394 pPict
->ReadUChar( ndh
);
396 return Point( aBase
.X() + static_cast<tools::Long
>(ndh
), aBase
.Y() );
399 Point
PictReader::ReadUnsignedDeltaV(Point aBase
)
403 pPict
->ReadUChar( ndv
);
405 return Point( aBase
.X(), aBase
.Y() + static_cast<tools::Long
>(ndv
) );
408 Size
PictReader::ReadSize()
412 pPict
->ReadInt16( ny
).ReadInt16( nx
);
417 Color
PictReader::ReadColor()
422 pPict
->ReadUInt32( nCol
);
425 case 33: aCol
=COL_BLACK
; break;
426 case 30: aCol
=COL_WHITE
; break;
427 case 205: aCol
=COL_LIGHTRED
; break;
428 case 341: aCol
=COL_LIGHTGREEN
; break;
429 case 409: aCol
=COL_LIGHTBLUE
; break;
430 case 273: aCol
=COL_LIGHTCYAN
; break;
431 case 137: aCol
=COL_LIGHTMAGENTA
; break;
432 case 69: aCol
=COL_YELLOW
; break;
433 default: aCol
=COL_LIGHTGRAY
;
438 Color
PictReader::ReadRGBColor()
440 sal_uInt16
nR(0), nG(0), nB(0);
442 pPict
->ReadUInt16( nR
).ReadUInt16( nG
).ReadUInt16( nB
);
443 return Color( static_cast<sal_uInt8
>( nR
>> 8 ), static_cast<sal_uInt8
>( nG
>> 8 ), static_cast<sal_uInt8
>( nB
>> 8 ) );
446 void PictReader::ReadRectangle(tools::Rectangle
& rRect
)
448 Point aTopLeft
= ReadPoint();
449 Point aBottomRight
= ReadPoint();
450 if (!pPict
->good() || aTopLeft
.X() > aBottomRight
.X() || aTopLeft
.Y() > aBottomRight
.Y())
452 SAL_WARN("filter.pict", "broken rectangle");
453 pPict
->SetError( SVSTREAM_FILEFORMAT_ERROR
);
454 rRect
= tools::Rectangle();
457 rRect
=tools::Rectangle(aTopLeft
,aBottomRight
);
459 SAL_INFO("filter.pict", "ReadRectangle: " << rRect
);
462 sal_uInt64
PictReader::ReadPolygon(tools::Polygon
& rPoly
)
465 pPict
->ReadUInt16(nSize
);
467 sal_uInt64 nDataSize
= static_cast<sal_uInt64
>(nSize
);
469 const size_t nMaxPossiblePoints
= pPict
->remainingSize() / 2 * sizeof(sal_uInt16
);
470 if (nSize
> nMaxPossiblePoints
)
472 SAL_WARN("filter.pict", "pict record claims to have: " << nSize
<< " points, but only " << nMaxPossiblePoints
<< " possible, clamping");
473 nSize
= nMaxPossiblePoints
;
475 rPoly
.SetSize(nSize
);
476 for (sal_uInt16 i
= 0; i
< nSize
; ++i
)
478 rPoly
.SetPoint(ReadPoint(), i
);
488 sal_uInt64
PictReader::ReadPixPattern(PictReader::Pattern
&pattern
)
490 // Don't know if this is correct because no picture which contains PixPatterns found.
491 // Here again the attempt to calculate the size of the date to create simple StarView-Styles
492 // from them. Luckily a PixPattern always contains a normal pattern.
494 sal_uInt64 nDataSize
;
496 sal_uInt16
nPatType(0);
497 pPict
->ReadUInt16(nPatType
);
499 pattern
.read(*pPict
);
501 nDataSize
=ReadPixMapEtc(aBMP
,false,true,nullptr,nullptr,false,false);
502 // CHANGEME: use average pixmap colors to update the pattern, ...
503 if (nDataSize
!=0xffffffff) nDataSize
+=10;
505 else if (nPatType
==2) {
506 pattern
.read(*pPict
);
508 sal_uInt16 nR
, nG
, nB
;
509 pPict
->ReadUInt16( nR
).ReadUInt16( nG
).ReadUInt16( nB
);
510 Color
col(static_cast<sal_uInt8
>( nR
>> 8 ), static_cast<sal_uInt8
>( nG
>> 8 ), static_cast<sal_uInt8
>( nB
>> 8 ) );
511 pattern
.setColor(col
);
514 else nDataSize
=0xffffffff;
519 sal_uInt8
PictReader::ReadAndDrawRect(PictDrawingMethod eMethod
)
521 ReadRectangle(aLastRect
);
522 ReadAndDrawSameRect(eMethod
);
526 sal_uInt8
PictReader::ReadAndDrawSameRect(PictDrawingMethod eMethod
)
528 if (IsInvisible(eMethod
)) return 0;
529 DrawingMethod(eMethod
);
530 PictReaderShape::drawRectangle( pVirDev
, eMethod
== PictDrawingMethod::FRAME
, aLastRect
, nActPenSize
);
534 sal_uInt8
PictReader::ReadAndDrawRoundRect(PictDrawingMethod eMethod
)
536 ReadRectangle(aLastRoundRect
);
537 ReadAndDrawSameRoundRect(eMethod
);
541 sal_uInt8
PictReader::ReadAndDrawSameRoundRect(PictDrawingMethod eMethod
)
543 if (IsInvisible(eMethod
)) return 0;
544 DrawingMethod(eMethod
);
545 PictReaderShape::drawRoundRectangle( pVirDev
, eMethod
== PictDrawingMethod::FRAME
, aLastRoundRect
, aActOvalSize
, nActPenSize
);
549 sal_uInt8
PictReader::ReadAndDrawOval(PictDrawingMethod eMethod
)
551 ReadRectangle(aLastOval
);
552 ReadAndDrawSameOval(eMethod
);
556 sal_uInt8
PictReader::ReadAndDrawSameOval(PictDrawingMethod eMethod
)
558 if (IsInvisible(eMethod
)) return 0;
559 DrawingMethod(eMethod
);
560 PictReaderShape::drawEllipse( pVirDev
, eMethod
== PictDrawingMethod::FRAME
, aLastOval
, nActPenSize
);
564 sal_uInt64
PictReader::ReadAndDrawPolygon(PictDrawingMethod eMethod
)
566 sal_uInt64 nDataSize
;
567 nDataSize
=ReadPolygon(aLastPolygon
);
568 ReadAndDrawSamePolygon(eMethod
);
572 sal_uInt8
PictReader::ReadAndDrawSamePolygon(PictDrawingMethod eMethod
)
574 if (IsInvisible(eMethod
)) return 0;
575 DrawingMethod(eMethod
);
576 PictReaderShape::drawPolygon( pVirDev
, eMethod
== PictDrawingMethod::FRAME
, aLastPolygon
, nActPenSize
);
581 sal_uInt8
PictReader::ReadAndDrawArc(PictDrawingMethod eMethod
)
583 ReadRectangle(aLastArcRect
);
584 ReadAndDrawSameArc(eMethod
);
588 sal_uInt8
PictReader::ReadAndDrawSameArc(PictDrawingMethod eMethod
)
590 short nstartAngle
, narcAngle
;
592 pPict
->ReadInt16( nstartAngle
).ReadInt16( narcAngle
);
593 if (!pPict
->good() || IsInvisible(eMethod
)) return 4;
594 DrawingMethod(eMethod
);
597 nstartAngle
= nstartAngle
+ narcAngle
;
598 narcAngle
=-narcAngle
;
600 double fAng1
= basegfx::deg2rad(nstartAngle
);
601 double fAng2
= basegfx::deg2rad(nstartAngle
+ narcAngle
);
602 PictReaderShape::drawArc( pVirDev
, eMethod
== PictDrawingMethod::FRAME
, aLastArcRect
, fAng1
, fAng2
, nActPenSize
);
606 sal_uInt64
PictReader::ReadAndDrawRgn(PictDrawingMethod eMethod
)
609 pPict
->ReadUInt16( nSize
);
613 // a region data is a mask and is probably coded as
614 // - the first 8 bytes: bdbox ( which can be read by ReadRectangle )
615 // - then a list of line modifiers: y_i, a_0, b_0, a_1, b_1, ..., a_{n_i}, b_{n_i}, 0x7fff
617 // where y_i is the increasing sequences of line coordinates
618 // and on each line: a0 < b0 < a1 < b1 < ... < a_{n_i} < b_{n_i}
620 // it can be probably decoded as :
621 // M=an empty mask: ie. (0, 0, ... ) with (left_box-right_box+1) zeroes
622 // then for each line (y_i):
623 // - takes M and inverts all values in [a_0,b_0-1], in [a_1,b_1-1] ...
624 // - sets M = new y_i line mask
625 ReadAndDrawSameRgn(eMethod
);
626 return static_cast<sal_uInt64
>(nSize
);
629 sal_uInt8
PictReader::ReadAndDrawSameRgn(PictDrawingMethod eMethod
)
631 if (IsInvisible(eMethod
)) return 0;
632 DrawingMethod(eMethod
);
633 // DISPLAY: ...???...
637 void PictReader::DrawingMethod(PictDrawingMethod eMethod
)
639 if( eActMethod
==eMethod
) return;
641 case PictDrawingMethod::FRAME
:
642 if (eActPenPattern
.isDefault())
643 SetLineColor( aActForeColor
);
645 SetLineColor(eActPenPattern
.getColor(aActBackColor
, aActForeColor
));
646 SetFillColor( COL_TRANSPARENT
);
647 pVirDev
->SetRasterOp(eActROP
);
649 case PictDrawingMethod::PAINT
:
650 SetLineColor( COL_TRANSPARENT
);
651 if (eActPenPattern
.isDefault())
652 SetFillColor( aActForeColor
);
654 SetFillColor(eActPenPattern
.getColor(aActBackColor
, aActForeColor
));
655 pVirDev
->SetRasterOp(eActROP
);
657 case PictDrawingMethod::ERASE
:
658 SetLineColor( COL_TRANSPARENT
);
659 if (eActBackPattern
.isDefault())
660 SetFillColor( aActBackColor
);// Osnola: previously aActForeColor
662 SetFillColor(eActBackPattern
.getColor(COL_BLACK
, aActBackColor
));
663 pVirDev
->SetRasterOp(RasterOp::OverPaint
);
665 case PictDrawingMethod::INVERT
: // checkme
666 SetLineColor( COL_TRANSPARENT
);
667 SetFillColor( COL_BLACK
);
668 pVirDev
->SetRasterOp(RasterOp::Invert
);
670 case PictDrawingMethod::FILL
:
671 SetLineColor( COL_TRANSPARENT
);
672 if (eActFillPattern
.isDefault())
673 SetFillColor( aActForeColor
);
675 SetFillColor(eActFillPattern
.getColor(aActBackColor
, aActForeColor
));
676 pVirDev
->SetRasterOp(RasterOp::OverPaint
);
678 case PictDrawingMethod::TEXT
:
679 aActFont
.SetColor(aActForeColor
);
680 aActFont
.SetFillColor(aActBackColor
);
681 aActFont
.SetTransparent(true);
682 pVirDev
->SetFont(aActFont
);
683 pVirDev
->SetRasterOp(RasterOp::OverPaint
);
686 break; // -Wall undefined not handled...
691 sal_uInt64
PictReader::ReadAndDrawText()
696 pPict
->ReadChar(nByteLen
);
697 sal_uInt32 nLen
= static_cast<sal_uInt32
>(nByteLen
)&0x000000ff;
698 sal_uInt32 nDataLen
= nLen
+ 1;
699 nLen
= pPict
->ReadBytes(&sText
, nLen
);
701 if (IsInvisible( PictDrawingMethod::TEXT
)) return nDataLen
;
702 DrawingMethod( PictDrawingMethod::TEXT
);
704 // remove annoying control characters:
705 while ( nLen
> 0 && static_cast<unsigned char>(sText
[ nLen
- 1 ]) < 32 )
708 OUString
aString( sText
, strlen(sText
), aActFont
.GetCharSet());
709 pVirDev
->DrawText( Point( aTextPosition
.X(), aTextPosition
.Y() ), aString
);
713 sal_uInt64
PictReader::ReadPixMapEtc( BitmapEx
&rBitmap
, bool bBaseAddr
, bool bColorTable
, tools::Rectangle
* pSrcRect
,
714 tools::Rectangle
* pDestRect
, bool bMode
, bool bMaskRgn
)
716 std::unique_ptr
<vcl::bitmap::RawBitmap
> pBitmap
;
717 sal_uInt16
nPackType(0), nPixelSize(0), nCmpCount(0), nCmpSize(0);
718 sal_uInt8
nDat(0), nRed(0), nGreen(0), nBlue(0);
720 // The calculation of nDataSize is considering the size of the whole data.
721 size_t nDataSize
= 0;
723 // conditionally skip BaseAddr
730 // Read PixMap or Bitmap structure;
731 sal_uInt16
nRowBytes(0), nBndX(0), nBndY(0), nWidth(0), nHeight(0);
732 pPict
->ReadUInt16(nRowBytes
).ReadUInt16(nBndY
).ReadUInt16(nBndX
).ReadUInt16(nHeight
).ReadUInt16(nWidth
);
735 nHeight
= nHeight
- nBndY
;
740 nWidth
= nWidth
- nBndX
;
744 std::vector
<Color
> aPalette
;
745 const bool bNotMonoChrome
= (nRowBytes
& 0x8000) != 0;
750 sal_uInt32 nPackSize
;
751 sal_uInt16 nPixelType
;
752 sal_uInt32 nPlaneBytes
;
753 sal_uInt32 nHRes
, nVRes
;
754 pPict
->ReadUInt16( nVersion
).ReadUInt16( nPackType
).ReadUInt32( nPackSize
).ReadUInt32( nHRes
).ReadUInt32( nVRes
).ReadUInt16( nPixelType
).ReadUInt16( nPixelSize
).ReadUInt16( nCmpCount
).ReadUInt16( nCmpSize
).ReadUInt32( nPlaneBytes
);
762 sal_uInt16
nColTabSize(0);
763 pPict
->ReadUInt16(nColTabSize
);
765 if (nColTabSize
> 255)
770 aPalette
.resize(nColTabSize
);
772 for (size_t i
= 0; i
< nColTabSize
; ++i
)
776 pPict
->ReadUChar( nRed
).ReadUChar( nDummy
).ReadUChar( nGreen
).ReadUChar( nDummy
).ReadUChar( nBlue
).ReadUChar( nDummy
);
777 aPalette
[i
] = Color(nRed
, nGreen
, nBlue
);
780 nDataSize
+= 8 + nColTabSize
* 8;
786 nPixelSize
= nCmpCount
= 1;
789 aPalette
[0] = Color(0xff, 0xff, 0xff);
790 aPalette
[1] = Color(0, 0, 0);
793 // conditionally read source rectangle:
794 if ( pSrcRect
!= nullptr)
796 sal_uInt16 nTop
, nLeft
, nBottom
, nRight
;
797 pPict
->ReadUInt16( nTop
).ReadUInt16( nLeft
).ReadUInt16( nBottom
).ReadUInt16( nRight
);
798 *pSrcRect
= tools::Rectangle(nLeft
, nTop
, nRight
, nBottom
);
802 // conditionally read destination rectangle:
803 if ( pDestRect
!= nullptr )
805 Point aTL
= ReadPoint();
806 Point aBR
= ReadPoint();
807 *pDestRect
= tools::Rectangle( aTL
, aBR
);
811 // conditionally read mode (or skip it):
818 // conditionally read region (or skip it):
822 pPict
->ReadUInt16( nSize
);
823 pPict
->SeekRel( nSize
- 2 );
827 // read and write Bitmap bits:
828 if ( nPixelSize
== 1 || nPixelSize
== 2 || nPixelSize
== 4 || nPixelSize
== 8 )
830 sal_uInt16 nSrcBPL
, nDestBPL
;
833 if ( nPixelSize
== 1 ) nSrcBPL
= ( nWidth
+ 7 ) >> 3;
834 else if ( nPixelSize
== 2 ) nSrcBPL
= ( nWidth
+ 3 ) >> 2;
835 else if ( nPixelSize
== 4 ) nSrcBPL
= ( nWidth
+ 1 ) >> 1;
836 else nSrcBPL
= nWidth
;
837 nDestBPL
= ( nSrcBPL
+ 3 ) & 0xfffc;
838 if (!nRowBytes
|| nRowBytes
< nSrcBPL
|| nRowBytes
> nDestBPL
)
841 if (nRowBytes
< 8 || nPackType
== 1)
843 if (nHeight
> pPict
->remainingSize() / (sizeof(sal_uInt8
) * nRowBytes
))
848 size_t nByteCountSize
= nRowBytes
> 250 ? sizeof(sal_uInt16
) : sizeof(sal_uInt8
);
849 if (nHeight
> pPict
->remainingSize() / nByteCountSize
)
853 pBitmap
.reset(new vcl::bitmap::RawBitmap( Size(nWidth
, nHeight
), 24 ));
855 for (sal_uInt16 ny
= 0; ny
< nHeight
; ++ny
)
858 if ( nRowBytes
< 8 || nPackType
== 1 )
860 for (size_t i
= 0; i
< nRowBytes
; ++i
)
862 pPict
->ReadUChar( nDat
);
864 SetByte(nx
, ny
, *pBitmap
, nPixelSize
, nDat
, nWidth
, aPalette
);
866 nDataSize
+= nRowBytes
;
870 sal_uInt16
nByteCount(0);
871 if ( nRowBytes
> 250 )
873 pPict
->ReadUInt16( nByteCount
);
874 nDataSize
+= 2 + static_cast<sal_uInt32
>(nByteCount
);
878 sal_uInt8
nByteCountAsByte(0);
879 pPict
->ReadUChar( nByteCountAsByte
);
880 nByteCount
= static_cast<sal_uInt16
>(nByteCountAsByte
) & 0x00ff;
881 nDataSize
+= 1 + nByteCount
;
884 while (pPict
->good() && nByteCount
)
886 sal_uInt8
nFlagCounterByte(0);
887 pPict
->ReadUChar(nFlagCounterByte
);
888 if ( ( nFlagCounterByte
& 0x80 ) == 0 )
890 nCount
= static_cast<sal_uInt16
>(nFlagCounterByte
) + 1;
891 for (size_t i
= 0; i
< nCount
; ++i
)
893 pPict
->ReadUChar( nDat
);
895 SetByte(nx
, ny
, *pBitmap
, nPixelSize
, nDat
, nWidth
, aPalette
);
897 nByteCount
-= 1 + nCount
;
901 nCount
= static_cast<sal_uInt16
>( 1 - sal_Int16( static_cast<sal_uInt16
>(nFlagCounterByte
) | 0xff00 ) );
902 pPict
->ReadUChar( nDat
);
903 for (size_t i
= 0; i
< nCount
; ++i
)
906 SetByte(nx
, ny
, *pBitmap
, nPixelSize
, nDat
, nWidth
, aPalette
);
914 else if ( nPixelSize
== 16 )
916 sal_uInt8 nByteCountAsByte
, nFlagCounterByte
;
917 sal_uInt16 nByteCount
, nCount
, nD
;
918 sal_uInt64 nSrcBitsPos
;
920 if (nWidth
> nRowBytes
/ 2)
923 if (nRowBytes
< 8 || nPackType
== 1)
925 if (nHeight
> pPict
->remainingSize() / (sizeof(sal_uInt8
) * nRowBytes
))
930 size_t nByteCountSize
= nRowBytes
> 250 ? sizeof(sal_uInt16
) : sizeof(sal_uInt8
);
931 if (nHeight
> pPict
->remainingSize() / nByteCountSize
)
935 pBitmap
.reset(new vcl::bitmap::RawBitmap( Size(nWidth
, nHeight
), 24 ));
937 for (sal_uInt16 ny
= 0; ny
< nHeight
; ++ny
)
940 if ( nRowBytes
< 8 || nPackType
== 1 )
942 for (size_t i
= 0; i
< nWidth
; ++i
)
944 pPict
->ReadUInt16( nD
);
945 nRed
= static_cast<sal_uInt8
>( nD
>> 7 );
946 nGreen
= static_cast<sal_uInt8
>( nD
>> 2 );
947 nBlue
= static_cast<sal_uInt8
>( nD
<< 3 );
948 pBitmap
->SetPixel(ny
, nx
++, Color(nRed
, nGreen
, nBlue
));
950 nDataSize
+= static_cast<sal_uInt32
>(nWidth
) * 2;
954 nSrcBitsPos
= pPict
->Tell();
955 if ( nRowBytes
> 250 )
957 pPict
->ReadUInt16( nByteCount
);
962 pPict
->ReadUChar( nByteCountAsByte
);
963 nByteCount
= static_cast<sal_uInt16
>(nByteCountAsByte
) & 0x00ff;
966 while ( nx
!= nWidth
)
968 pPict
->ReadUChar( nFlagCounterByte
);
969 if ( (nFlagCounterByte
& 0x80) == 0)
971 nCount
=static_cast<sal_uInt16
>(nFlagCounterByte
)+1;
972 if ( nCount
+ nx
> nWidth
)
973 nCount
= nWidth
- nx
;
974 if (pPict
->remainingSize() < sizeof(sal_uInt16
) * nCount
)
976 /* SJ: the RLE decoding seems not to be correct here,
977 I don't want to change this until I have a bugdoc for
978 this case. Have a look at 32bit, there I changed the
979 encoding, so that it is used a straight forward array
981 for (size_t i
= 0; i
< nCount
; ++i
)
983 pPict
->ReadUInt16( nD
);
984 nRed
= static_cast<sal_uInt8
>( nD
>> 7 );
985 nGreen
= static_cast<sal_uInt8
>( nD
>> 2 );
986 nBlue
= static_cast<sal_uInt8
>( nD
<< 3 );
987 pBitmap
->SetPixel(ny
, nx
++, Color(nRed
, nGreen
, nBlue
));
992 if (pPict
->remainingSize() < sizeof(sal_uInt16
))
994 nCount
=(1-sal_Int16(static_cast<sal_uInt16
>(nFlagCounterByte
)|0xff00));
995 if ( nCount
+ nx
> nWidth
)
996 nCount
= nWidth
- nx
;
997 pPict
->ReadUInt16( nD
);
998 nRed
= static_cast<sal_uInt8
>( nD
>> 7 );
999 nGreen
= static_cast<sal_uInt8
>( nD
>> 2 );
1000 nBlue
= static_cast<sal_uInt8
>( nD
<< 3 );
1001 for (size_t i
= 0; i
< nCount
; ++i
)
1003 pBitmap
->SetPixel(ny
, nx
++, Color(nRed
, nGreen
, nBlue
));
1007 nDataSize
+= nByteCount
;
1008 pPict
->Seek(nSrcBitsPos
+nByteCount
);
1012 else if ( nPixelSize
== 32 )
1014 sal_uInt16 nByteCount
;
1016 sal_uInt64 nSrcBitsPos
;
1017 if ( nRowBytes
!= 4*nWidth
)
1020 if ( nRowBytes
< 8 || nPackType
== 1 )
1022 const size_t nMaxPixels
= pPict
->remainingSize() / 4;
1023 const size_t nMaxRows
= nMaxPixels
/ nWidth
;
1024 if (nHeight
> nMaxRows
)
1026 const size_t nMaxCols
= nMaxPixels
/ nHeight
;
1027 if (nWidth
> nMaxCols
)
1030 pBitmap
.reset(new vcl::bitmap::RawBitmap( Size(nWidth
, nHeight
), 24 ));
1032 for (sal_uInt16 ny
= 0; ny
< nHeight
; ++ny
)
1034 for (sal_uInt16 nx
= 0; nx
< nWidth
; ++nx
)
1037 pPict
->ReadUChar( nDummy
).ReadUChar( nRed
).ReadUChar( nGreen
).ReadUChar( nBlue
);
1038 pBitmap
->SetPixel(ny
, nx
, Color(nRed
, nGreen
, nBlue
));
1040 nDataSize
+= static_cast<sal_uInt32
>(nWidth
) * 4;
1043 else if ( nPackType
== 2 )
1045 const size_t nMaxPixels
= pPict
->remainingSize() / 3;
1046 const size_t nMaxRows
= nMaxPixels
/ nWidth
;
1047 if (nHeight
> nMaxRows
)
1049 const size_t nMaxCols
= nMaxPixels
/ nHeight
;
1050 if (nWidth
> nMaxCols
)
1053 pBitmap
.reset(new vcl::bitmap::RawBitmap( Size(nWidth
, nHeight
), 24 ));
1055 for (sal_uInt16 ny
= 0; ny
< nHeight
; ++ny
)
1057 for (sal_uInt16 nx
= 0; nx
< nWidth
; ++nx
)
1059 pPict
->ReadUChar( nRed
).ReadUChar( nGreen
).ReadUChar( nBlue
);
1060 pBitmap
->SetPixel(ny
, nx
, Color(nRed
, nGreen
, nBlue
));
1062 nDataSize
+= static_cast<sal_uInt32
>(nWidth
) * 3;
1067 sal_uInt8 nByteCountAsByte
;
1068 sal_uInt8 nFlagCounterByte
;
1069 if ( ( nCmpCount
== 3 ) || ( nCmpCount
== 4 ) )
1071 size_t nByteCountSize
= nRowBytes
> 250 ? sizeof(sal_uInt16
) : sizeof(sal_uInt8
);
1072 if (nHeight
> pPict
->remainingSize() / nByteCountSize
)
1075 pBitmap
.reset(new vcl::bitmap::RawBitmap( Size(nWidth
, nHeight
), 24 ));
1077 // cid#1458434 to sanitize Untrusted loop bound
1078 nWidth
= pBitmap
->Width();
1080 size_t nByteWidth
= static_cast<size_t>(nWidth
) * nCmpCount
;
1081 std::vector
<sal_uInt8
> aScanline(nByteWidth
);
1082 for (sal_uInt16 ny
= 0; ny
< nHeight
; ++ny
)
1084 nSrcBitsPos
= pPict
->Tell();
1085 if ( nRowBytes
> 250 )
1087 pPict
->ReadUInt16( nByteCount
);
1092 pPict
->ReadUChar( nByteCountAsByte
);
1093 nByteCount
= nByteCountAsByte
;
1097 while (i
< aScanline
.size())
1099 pPict
->ReadUChar( nFlagCounterByte
);
1100 if ( ( nFlagCounterByte
& 0x80 ) == 0)
1102 nCount
= static_cast<sal_uInt16
>(nFlagCounterByte
) + 1;
1103 if ((i
+ nCount
) > aScanline
.size())
1104 nCount
= aScanline
.size() - i
;
1105 if (pPict
->remainingSize() < nCount
)
1109 pPict
->ReadUChar( nDat
);
1110 aScanline
[ i
++ ] = nDat
;
1115 if (pPict
->remainingSize() < 1)
1117 nCount
= ( 1 - sal_Int16( static_cast<sal_uInt16
>(nFlagCounterByte
) | 0xff00 ) );
1118 if (( i
+ nCount
) > aScanline
.size())
1119 nCount
= aScanline
.size() - i
;
1120 pPict
->ReadUChar( nDat
);
1122 aScanline
[ i
++ ] = nDat
;
1125 sal_uInt8
* pTmp
= aScanline
.data();
1126 if ( nCmpCount
== 4 )
1128 for (sal_uInt16 nx
= 0; nx
< nWidth
; pTmp
++)
1129 pBitmap
->SetPixel(ny
, nx
++, Color(*pTmp
, pTmp
[ nWidth
], pTmp
[ 2 * nWidth
]));
1130 nDataSize
+= nByteCount
;
1131 pPict
->Seek( nSrcBitsPos
+ nByteCount
);
1138 rBitmap
= vcl::bitmap::CreateFromData(std::move(*pBitmap
));
1142 void PictReader::ReadHeader()
1147 // previous code considers pPict->Tell() as the normal starting position,
1148 // nStartPos can be != 0 f.e. a pict embedded in a microsoft word document
1149 sal_uInt64 nStartPos
= pPict
->Tell();
1151 // a picture file begins by 512 bytes (reserved to the application) followed by the picture data
1152 // while clipboard, pictures stored in a document often contain only the picture data.
1155 // - some Pict v.1 use 0x00 0x11 0x01 ( instead of 0x11 0x01) to store the version op
1156 // (we consider here this as another standard for Pict. v.1 )
1157 // - some files seem to contain extra garbage data at the beginning
1158 // - some picture data seem to contain extra NOP opcode(0x00) between the bounding box and the version opcode
1160 // This code looks hard to find a picture header, ie. it looks at positions
1161 // - nStartPos+0, nStartPos+512 with potential extra NOP codes between bdbox and version (at most 9 extra NOP)
1162 // - 512..1024 with more strict bdbox checking and no extra NOP codes
1165 // - if the header can begin at nStartPos+0 and at nStartPos+512, we try to choose the more
1166 // <<probable>> ( using the variable confidence)
1167 // - svtools/source/filter.vcl/filter/{filter.cxx,filter2.cxx} only check for standard Pict,
1168 // this may cause future problems
1171 int confidence
[2] = { 0, 0};
1172 for ( st
= 0; st
< 3 + 513; st
++ )
1174 int actualConfid
= 20; // the actual confidence
1175 pPict
->ResetError();
1176 if (st
< 2) nOffset
= nStartPos
+st
*512;
1178 // choose nStartPos+0 or nStartPos+512 even if there are a little dubious
1179 int actPos
= -1, actConf
=0;
1180 if (confidence
[0] > 0) { actPos
= 0; actConf
= confidence
[0]; }
1181 if (confidence
[1] > 0 && confidence
[1] >= actConf
) actPos
= 1;
1182 if (actPos
< 0) continue;
1183 nOffset
= nStartPos
+actPos
*512;
1186 nOffset
= nStartPos
+509+st
;
1187 // a small test to check if versionOp code exists after the bdbox ( with no extra NOP codes)
1188 pPict
->Seek(nOffset
+10);
1189 pPict
->ReadBytes(sBuf
, 2);
1190 if (!pPict
->good()) break;
1191 if (sBuf
[0] == 0x11 || (sBuf
[0] == 0x00 && sBuf
[1] == 0x11)) ; // maybe ok
1194 pPict
->Seek(nOffset
);
1196 // 2 bytes to store size ( version 1 ) ignored
1197 pPict
->SeekRel( 2 );
1198 pPict
->ReadInt16( y1
).ReadInt16( x1
).ReadInt16( y2
).ReadInt16( x2
); // frame rectangle of the picture
1199 if (x1
> x2
|| y1
> y2
) continue; // bad bdbox
1200 if (x1
< -2048 || x2
> 2048 || y1
< -2048 || y2
> 2048 || // origin|dest is very small|large
1201 (x1
== x2
&& y1
== y2
) ) // 1 pixel pict is dubious
1203 else if (x2
< x1
+8 || y2
< y1
+8) // a little dubious
1205 if (st
>= 3 && actualConfid
!= 20) continue;
1206 aBoundingRect
=tools::Rectangle( x1
,y1
, x2
, y2
);
1208 if (!pPict
->good()) continue;
1210 pPict
->ReadBytes(sBuf
, 2);
1212 if ( sBuf
[ 0 ] == 0x11 && sBuf
[ 1 ] == 0x01 ) {
1213 // pict v1 must be rare and we do only few tests
1214 if (st
< 2) { confidence
[st
] = --actualConfid
; continue; }
1215 IsVersion2
= false; return;
1217 if (sBuf
[0] != 0x00) continue; // unrecoverable error
1223 pPict
->ReadBytes(sBuf
, 2);
1225 while ( sBuf
[0] == 0x00 && numZero
< 10);
1226 actualConfid
-= (numZero
-1); // extra nop are dubious
1227 if (!pPict
->good()) continue;
1228 if (sBuf
[0] != 0x11) continue; // not a version opcode
1229 // abnormal version 1 file
1230 if (sBuf
[1] == 0x01 ) {
1231 // pict v1 must be rare and we do only few tests
1232 if (st
< 2) { confidence
[st
] = --actualConfid
; continue; }
1233 IsVersion2
= false; return;
1235 if (sBuf
[1] != 0x02 ) continue; // not a version 2 file
1238 short nExtVer
, nReserved
;
1239 // 3 Bytes ignored : end of version arg 0x02FF (ie: 0xFF), HeaderOp : 0x0C00
1240 pPict
->SeekRel( 3 );
1241 pPict
->ReadInt16( nExtVer
).ReadInt16( nReserved
);
1242 if (!pPict
->good()) continue;
1244 if ( nExtVer
== -2 ) // extended version 2 picture
1246 sal_Int32 nHResFixed
, nVResFixed
;
1247 pPict
->ReadInt32( nHResFixed
).ReadInt32( nVResFixed
);
1248 pPict
->ReadInt16( y1
).ReadInt16( x1
).ReadInt16( y2
).ReadInt16( x2
); // reading the optimal bounding rect
1249 if (x1
> x2
|| y1
> y2
) continue; // bad bdbox
1250 if (st
< 2 && actualConfid
!= 20) { confidence
[st
] = actualConfid
; continue; }
1252 double fHRes
= nHResFixed
;
1254 double fVRes
= nVResFixed
;
1258 aBoundingRect
=tools::Rectangle( x1
,y1
, x2
, y2
);
1259 pPict
->SeekRel( 4 ); // 4 bytes reserved
1262 else if (nExtVer
== -1 ) { // basic version 2 picture
1263 if (st
< 2 && actualConfid
!= 20) { confidence
[st
] = actualConfid
; continue; }
1264 pPict
->SeekRel( 16); // bdbox(4 fixed number)
1265 pPict
->SeekRel(4); // 4 bytes reserved
1269 pPict
->SetError(SVSTREAM_FILEFORMAT_ERROR
);
1272 #if OSL_DEBUG_LEVEL > 0
1273 static const char* operationName(sal_uInt16 nOpcode
)
1275 // add here whatever makes the debugging easier for you, otherwise you'll
1276 // see only the operation's opcode
1279 case 0x0001: return "Clip";
1280 case 0x0003: return "TxFont";
1281 case 0x0004: return "TxFace";
1282 case 0x0008: return "PnMode";
1283 case 0x0009: return "PnPat";
1284 case 0x000d: return "TxSize";
1285 case 0x001a: return "RGBFgCol";
1286 case 0x001d: return "HiliteColor";
1287 case 0x0020: return "Line";
1288 case 0x0022: return "ShortLine";
1289 case 0x0028: return "LongText";
1290 case 0x0029: return "DHText";
1291 case 0x002a: return "DVText";
1292 case 0x002c: return "fontName";
1293 case 0x002e: return "glyphState";
1294 case 0x0031: return "paintRect";
1295 case 0x0038: return "frameSameRect";
1296 case 0x0070: return "framePoly";
1297 case 0x0071: return "paintPoly";
1298 case 0x00a1: return "LongComment";
1299 default: return "?";
1304 sal_uInt64
PictReader::ReadData(sal_uInt16 nOpcode
)
1307 sal_uInt64 nDataSize
=0;
1308 PictDrawingMethod shapeDMethod
= PictDrawingMethod::UNDEFINED
;
1309 switch (nOpcode
& 7) {
1310 case 0: shapeDMethod
= PictDrawingMethod::FRAME
; break;
1311 case 1: shapeDMethod
= PictDrawingMethod::PAINT
; break;
1312 case 2: shapeDMethod
= PictDrawingMethod::ERASE
; break;
1313 case 3: shapeDMethod
= PictDrawingMethod::INVERT
; break;
1314 case 4: shapeDMethod
= PictDrawingMethod::FILL
; break;
1318 #if OSL_DEBUG_LEVEL > 0
1319 SAL_INFO("filter.pict", "Operation: 0x" << OUString::number(nOpcode
, 16) << " [" << operationName(nOpcode
) << "]");
1328 case 0x0001: { // Clip
1329 sal_uInt16
nUSHORT(0);
1330 tools::Rectangle aRect
;
1331 pPict
->ReadUInt16( nUSHORT
);
1333 ReadRectangle(aRect
);
1334 // checkme: do we really want to extend the rectangle here ?
1335 // I do that because the clipping is often used to clean a region,
1336 // before drawing some text and also to draw this text.
1337 // So using a too small region can lead to clip the end of the text ;
1338 // but this can be discussable...
1339 aRect
.setWidth(aRect
.getOpenWidth()+1);
1340 aRect
.setHeight(aRect
.getOpenHeight()+1);
1341 pVirDev
->SetClipRegion( vcl::Region( aRect
) );
1344 case 0x0002: // BkPat
1345 nDataSize
= eActBackPattern
.read(*pPict
);
1346 eActMethod
= PictDrawingMethod::UNDEFINED
;
1349 case 0x0003: // TxFont
1351 sal_uInt16
nUSHORT(0);
1352 pPict
->ReadUInt16( nUSHORT
);
1353 if (nUSHORT
<= 1) aActFont
.SetFamily(FAMILY_SWISS
);
1354 else if (nUSHORT
<= 12) aActFont
.SetFamily(FAMILY_DECORATIVE
);
1355 else if (nUSHORT
<= 20) aActFont
.SetFamily(FAMILY_ROMAN
);
1356 else if (nUSHORT
== 21) aActFont
.SetFamily(FAMILY_SWISS
);
1357 else if (nUSHORT
== 22) aActFont
.SetFamily(FAMILY_MODERN
);
1358 else if (nUSHORT
<= 1023) aActFont
.SetFamily(FAMILY_SWISS
);
1359 else aActFont
.SetFamily(FAMILY_ROMAN
);
1360 aActFont
.SetCharSet(GetTextEncoding(nUSHORT
));
1361 eActMethod
= PictDrawingMethod::UNDEFINED
;
1365 case 0x0004: { // TxFace
1367 pPict
->ReadChar( nFace
);
1368 if ( (nFace
& 0x01)!=0 ) aActFont
.SetWeight(WEIGHT_BOLD
);
1369 else aActFont
.SetWeight(WEIGHT_NORMAL
);
1370 if ( (nFace
& 0x02)!=0 ) aActFont
.SetItalic(ITALIC_NORMAL
);
1371 else aActFont
.SetItalic(ITALIC_NONE
);
1372 if ( (nFace
& 0x04)!=0 ) aActFont
.SetUnderline(LINESTYLE_SINGLE
);
1373 else aActFont
.SetUnderline(LINESTYLE_NONE
);
1374 if ( (nFace
& 0x08)!=0 ) aActFont
.SetOutline(true);
1375 else aActFont
.SetOutline(false);
1376 if ( (nFace
& 0x10)!=0 ) aActFont
.SetShadow(true);
1377 else aActFont
.SetShadow(false);
1378 eActMethod
= PictDrawingMethod::UNDEFINED
;
1382 case 0x0005: // TxMode
1386 case 0x0006: // SpExtra
1390 case 0x0007: { // PnSize
1391 nActPenSize
=ReadSize();
1392 eActMethod
= PictDrawingMethod::UNDEFINED
;
1396 case 0x0008: // PnMode
1398 sal_uInt16
nUSHORT(0);
1399 pPict
->ReadUInt16( nUSHORT
);
1400 // internal code for postscript command (Quickdraw Reference Drawing B-30,B-34)
1401 if (nUSHORT
==23) eActROP
= RasterOp::N1
;
1403 switch (nUSHORT
& 0x0007) {
1404 case 0: eActROP
=RasterOp::OverPaint
; break; // Copy
1405 case 1: eActROP
=RasterOp::OverPaint
; break; // Or
1406 case 2: eActROP
=RasterOp::Xor
; break; // Xor
1407 case 3: eActROP
=RasterOp::OverPaint
; break; // Bic
1408 case 4: eActROP
=RasterOp::Invert
; break; // notCopy
1409 case 5: eActROP
=RasterOp::OverPaint
; break; // notOr
1410 case 6: eActROP
=RasterOp::Xor
; break; // notXor
1411 case 7: eActROP
=RasterOp::OverPaint
; break; // notBic
1414 eActMethod
= PictDrawingMethod::UNDEFINED
;
1418 case 0x0009: // PnPat
1419 nDataSize
=eActPenPattern
.read(*pPict
);
1420 eActMethod
= PictDrawingMethod::UNDEFINED
;
1423 case 0x000a: // FillPat
1424 nDataSize
=eActFillPattern
.read(*pPict
);
1425 eActMethod
= PictDrawingMethod::UNDEFINED
;
1428 case 0x000b: // OvSize
1429 aActOvalSize
=ReadSize();
1433 case 0x000c: // Origin
1437 case 0x000d: // TxSize
1439 sal_uInt16
nUSHORT(0);
1440 pPict
->ReadUInt16( nUSHORT
);
1441 aActFont
.SetFontSize( Size( 0, static_cast<tools::Long
>(nUSHORT
) ) );
1442 eActMethod
= PictDrawingMethod::UNDEFINED
;
1447 case 0x000e: // FgColor
1448 aActForeColor
=ReadColor();
1449 eActMethod
= PictDrawingMethod::UNDEFINED
;
1453 case 0x000f: // BkColor
1454 aActBackColor
=ReadColor();
1458 case 0x0010: // TxRatio
1462 case 0x0011: // VersionOp
1466 case 0x0012: // BkPixPat
1467 nDataSize
=ReadPixPattern(eActBackPattern
);
1468 eActMethod
= PictDrawingMethod::UNDEFINED
;
1471 case 0x0013: // PnPixPat
1472 nDataSize
=ReadPixPattern(eActPenPattern
);
1473 eActMethod
= PictDrawingMethod::UNDEFINED
;
1476 case 0x0014: // FillPixPat
1477 nDataSize
=ReadPixPattern(eActFillPattern
);
1478 eActMethod
= PictDrawingMethod::UNDEFINED
;
1481 case 0x0015: // PnLocHFrac
1485 case 0x0016: // ChExtra
1489 case 0x0017: // Reserved (0 Bytes)
1490 case 0x0018: // Reserved (0 Bytes)
1491 case 0x0019: // Reserved (0 Bytes)
1495 case 0x001a: // RGBFgCol
1496 aActForeColor
=ReadRGBColor();
1497 eActMethod
= PictDrawingMethod::UNDEFINED
;
1501 case 0x001b: // RGBBkCol
1502 aActBackColor
=ReadRGBColor();
1503 eActMethod
= PictDrawingMethod::UNDEFINED
;
1507 case 0x001c: // HiliteMode
1511 case 0x001d: // HiliteColor
1515 case 0x001e: // DefHilite
1519 case 0x001f: // OpColor
1523 case 0x0020: // Line
1524 aPoint
=ReadPoint(); aPenPosition
=ReadPoint();
1530 if (IsInvisible( PictDrawingMethod::FRAME
)) break;
1531 DrawingMethod( PictDrawingMethod::FRAME
);
1532 PictReaderShape::drawLine(pVirDev
, aPoint
,aPenPosition
, nActPenSize
);
1535 case 0x0021: // LineFrom
1536 aPoint
=aPenPosition
; aPenPosition
=ReadPoint();
1542 if (IsInvisible( PictDrawingMethod::FRAME
)) break;
1543 DrawingMethod( PictDrawingMethod::FRAME
);
1544 PictReaderShape::drawLine(pVirDev
, aPoint
,aPenPosition
, nActPenSize
);
1547 case 0x0022: // ShortLine
1549 aPenPosition
=ReadDeltaH(aPoint
);
1550 aPenPosition
=ReadDeltaV(aPenPosition
);
1556 if ( IsInvisible(PictDrawingMethod::FRAME
) ) break;
1557 DrawingMethod( PictDrawingMethod::FRAME
);
1558 PictReaderShape::drawLine(pVirDev
, aPoint
,aPenPosition
, nActPenSize
);
1561 case 0x0023: // ShortLineFrom
1562 aPoint
=aPenPosition
;
1563 aPenPosition
=ReadDeltaH(aPoint
);
1564 aPenPosition
=ReadDeltaV(aPenPosition
);
1570 if (IsInvisible( PictDrawingMethod::FRAME
)) break;
1571 DrawingMethod( PictDrawingMethod::FRAME
);
1572 PictReaderShape::drawLine(pVirDev
, aPoint
,aPenPosition
, nActPenSize
);
1575 case 0x0024: // Reserved (n Bytes)
1576 case 0x0025: // Reserved (n Bytes)
1577 case 0x0026: // Reserved (n Bytes)
1578 case 0x0027: // Reserved (n Bytes)
1580 sal_uInt16
nUSHORT(0);
1581 pPict
->ReadUInt16( nUSHORT
);
1582 nDataSize
=2+nUSHORT
;
1585 case 0x0028: // LongText
1586 aTextPosition
=ReadPoint();
1587 nDataSize
=4+ReadAndDrawText();
1590 case 0x0029: // DHText
1591 aTextPosition
=ReadUnsignedDeltaH(aTextPosition
);
1592 nDataSize
=1+ReadAndDrawText();
1595 case 0x002a: // DVText
1596 aTextPosition
=ReadUnsignedDeltaV(aTextPosition
);
1597 nDataSize
=1+ReadAndDrawText();
1600 case 0x002b: // DHDVText
1601 aTextPosition
=ReadUnsignedDeltaH(aTextPosition
);
1602 aTextPosition
=ReadUnsignedDeltaV(aTextPosition
);
1603 nDataSize
=2+ReadAndDrawText();
1606 case 0x002c: { // fontName
1607 sal_uInt16
nUSHORT(0);
1608 pPict
->ReadUInt16( nUSHORT
); nDataSize
=nUSHORT
+2;
1609 pPict
->ReadUInt16( nUSHORT
);
1610 if (nUSHORT
<= 1) aActFont
.SetFamily(FAMILY_SWISS
);
1611 else if (nUSHORT
<= 12) aActFont
.SetFamily(FAMILY_DECORATIVE
);
1612 else if (nUSHORT
<= 20) aActFont
.SetFamily(FAMILY_ROMAN
);
1613 else if (nUSHORT
== 21) aActFont
.SetFamily(FAMILY_SWISS
);
1614 else if (nUSHORT
== 22) aActFont
.SetFamily(FAMILY_MODERN
);
1615 else if (nUSHORT
<= 1023) aActFont
.SetFamily(FAMILY_SWISS
);
1616 else aActFont
.SetFamily(FAMILY_ROMAN
);
1617 aActFont
.SetCharSet(GetTextEncoding(nUSHORT
));
1619 pPict
->ReadChar( nByteLen
);
1620 sal_uInt16 nLen
= static_cast<sal_uInt16
>(nByteLen
)&0x00ff;
1622 sFName
[pPict
->ReadBytes(sFName
, nLen
)] = 0;
1623 OUString
aString( sFName
, strlen(sFName
), osl_getThreadTextEncoding() );
1624 aActFont
.SetFamilyName( aString
);
1625 eActMethod
= PictDrawingMethod::UNDEFINED
;
1628 case 0x002d: // lineJustify
1632 case 0x002e: // glyphState
1634 sal_uInt16
nUSHORT(0);
1635 pPict
->ReadUInt16( nUSHORT
);
1636 nDataSize
=2+nUSHORT
;
1639 case 0x002f: // Reserved (n Bytes)
1641 sal_uInt16
nUSHORT(0);
1642 pPict
->ReadUInt16( nUSHORT
);
1643 nDataSize
=2+nUSHORT
;
1646 case 0x0030: // frameRect
1647 case 0x0031: // paintRect
1648 case 0x0032: // eraseRect
1649 case 0x0033: // invertRect
1650 case 0x0034: // fillRect
1651 nDataSize
=ReadAndDrawRect(shapeDMethod
);
1654 case 0x0035: // Reserved (8 Bytes)
1655 case 0x0036: // Reserved (8 Bytes)
1656 case 0x0037: // Reserved (8 Bytes)
1660 case 0x0038: // frameSameRect
1661 case 0x0039: // paintSameRect
1662 case 0x003a: // eraseSameRect
1663 case 0x003b: // invertSameRect
1664 case 0x003c: // fillSameRect
1665 nDataSize
=ReadAndDrawSameRect(shapeDMethod
);
1668 case 0x003d: // Reserved (0 Bytes)
1669 case 0x003e: // Reserved (0 Bytes)
1670 case 0x003f: // Reserved (0 Bytes)
1674 case 0x0040: // frameRRect
1675 case 0x0041: // paintRRect
1676 case 0x0042: // eraseRRect
1677 case 0x0043: // invertRRect
1678 case 0x0044: // fillRRect
1679 nDataSize
=ReadAndDrawRoundRect(shapeDMethod
);
1682 case 0x0045: // Reserved (8 Bytes)
1683 case 0x0046: // Reserved (8 Bytes)
1684 case 0x0047: // Reserved (8 Bytes)
1688 case 0x0048: // frameSameRRect
1689 case 0x0049: // paintSameRRect
1690 case 0x004a: // eraseSameRRect
1691 case 0x004b: // invertSameRRect
1692 case 0x004c: // fillSameRRect
1693 nDataSize
=ReadAndDrawSameRoundRect(shapeDMethod
);
1696 case 0x004d: // Reserved (0 Bytes)
1697 case 0x004e: // Reserved (0 Bytes)
1698 case 0x004f: // Reserved (0 Bytes)
1702 case 0x0050: // frameOval
1703 case 0x0051: // paintOval
1704 case 0x0052: // eraseOval
1705 case 0x0053: // invertOval
1706 case 0x0054: // fillOval
1707 nDataSize
=ReadAndDrawOval(shapeDMethod
);
1710 case 0x0055: // Reserved (8 Bytes)
1711 case 0x0056: // Reserved (8 Bytes)
1712 case 0x0057: // Reserved (8 Bytes)
1716 case 0x0058: // frameSameOval
1717 case 0x0059: // paintSameOval
1718 case 0x005a: // eraseSameOval
1719 case 0x005b: // invertSameOval
1720 case 0x005c: // fillSameOval
1721 nDataSize
=ReadAndDrawSameOval(shapeDMethod
);
1724 case 0x005d: // Reserved (0 Bytes)
1725 case 0x005e: // Reserved (0 Bytes)
1726 case 0x005f: // Reserved (0 Bytes)
1730 case 0x0060: // frameArc
1731 case 0x0061: // paintArc
1732 case 0x0062: // eraseArc
1733 case 0x0063: // invertArc
1734 case 0x0064: // fillArc
1735 nDataSize
=ReadAndDrawArc(shapeDMethod
);
1738 case 0x0065: // Reserved (12 Bytes)
1739 case 0x0066: // Reserved (12 Bytes)
1740 case 0x0067: // Reserved (12 Bytes)
1744 case 0x0068: // frameSameArc
1745 case 0x0069: // paintSameArc
1746 case 0x006a: // eraseSameArc
1747 case 0x006b: // invertSameArc
1748 case 0x006c: // fillSameArc
1749 nDataSize
=ReadAndDrawSameArc(shapeDMethod
);
1752 case 0x006d: // Reserved (4 Bytes)
1753 case 0x006e: // Reserved (4 Bytes)
1754 case 0x006f: // Reserved (4 Bytes)
1758 case 0x0070: // framePoly
1759 case 0x0071: // paintPoly
1760 case 0x0072: // erasePoly
1761 case 0x0073: // invertPoly
1762 case 0x0074: // fillPoly
1763 nDataSize
=ReadAndDrawPolygon(shapeDMethod
);
1766 case 0x0075: // Reserved (Polygon-Size)
1767 case 0x0076: // Reserved (Polygon-Size)
1768 case 0x0077: // Reserved (Polygon-Size)
1770 sal_uInt16
nUSHORT(0);
1771 pPict
->ReadUInt16( nUSHORT
); nDataSize
=nUSHORT
;
1774 case 0x0078: // frameSamePoly
1775 case 0x0079: // paintSamePoly
1776 case 0x007a: // eraseSamePoly
1777 case 0x007b: // invertSamePoly
1778 case 0x007c: // fillSamePoly
1779 nDataSize
=ReadAndDrawSamePolygon(shapeDMethod
);
1782 case 0x007d: // Reserved (0 Bytes)
1783 case 0x007e: // Reserved (0 Bytes)
1784 case 0x007f: // Reserved (0 Bytes)
1788 case 0x0080: // frameRgn
1789 case 0x0081: // paintRgn
1790 case 0x0082: // eraseRgn
1791 case 0x0083: // invertRgn
1792 case 0x0084: // fillRgn
1793 nDataSize
=ReadAndDrawRgn(shapeDMethod
);
1796 case 0x0085: // Reserved (Region-Size)
1797 case 0x0086: // Reserved (Region-Size)
1798 case 0x0087: // Reserved (Region-Size)
1800 sal_uInt16
nUSHORT(0);
1801 pPict
->ReadUInt16( nUSHORT
); nDataSize
=nUSHORT
;
1804 case 0x0088: // frameSameRgn
1805 case 0x0089: // paintSameRgn
1806 case 0x008a: // eraseSameRgn
1807 case 0x008b: // invertSameRgn
1808 case 0x008c: // fillSameRgn
1809 nDataSize
=ReadAndDrawSameRgn(shapeDMethod
);
1812 case 0x008d: // Reserved (0 Bytes)
1813 case 0x008e: // Reserved (0 Bytes)
1814 case 0x008f: // Reserved (0 Bytes)
1818 case 0x0090: { // BitsRect
1820 tools::Rectangle aSrcRect
, aDestRect
;
1821 nDataSize
=ReadPixMapEtc(aBmp
, false, true, &aSrcRect
, &aDestRect
, true, false);
1822 DrawingMethod( PictDrawingMethod::PAINT
);
1823 pVirDev
->DrawBitmapEx(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1826 case 0x0091: { // BitsRgn
1828 tools::Rectangle aSrcRect
, aDestRect
;
1829 nDataSize
=ReadPixMapEtc(aBmp
, false, true, &aSrcRect
, &aDestRect
, true, true);
1830 DrawingMethod( PictDrawingMethod::PAINT
);
1831 pVirDev
->DrawBitmapEx(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1834 case 0x0092: // Reserved (n Bytes)
1835 case 0x0093: // Reserved (n Bytes)
1836 case 0x0094: // Reserved (n Bytes)
1837 case 0x0095: // Reserved (n Bytes)
1838 case 0x0096: // Reserved (n Bytes)
1839 case 0x0097: // Reserved (n Bytes)
1841 sal_uInt16
nUSHORT(0);
1842 pPict
->ReadUInt16( nUSHORT
); nDataSize
=2+nUSHORT
;
1845 case 0x0098: { // PackBitsRect
1847 tools::Rectangle aSrcRect
, aDestRect
;
1848 nDataSize
=ReadPixMapEtc(aBmp
, false, true, &aSrcRect
, &aDestRect
, true, false);
1849 DrawingMethod( PictDrawingMethod::PAINT
);
1850 pVirDev
->DrawBitmapEx(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1853 case 0x0099: { // PackBitsRgn
1855 tools::Rectangle aSrcRect
, aDestRect
;
1856 nDataSize
=ReadPixMapEtc(aBmp
, false, true, &aSrcRect
, &aDestRect
, true, true);
1857 DrawingMethod( PictDrawingMethod::PAINT
);
1858 pVirDev
->DrawBitmapEx(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1861 case 0x009a: { // DirectBitsRect
1863 tools::Rectangle aSrcRect
, aDestRect
;
1864 nDataSize
=ReadPixMapEtc(aBmp
, true, false, &aSrcRect
, &aDestRect
, true, false);
1865 DrawingMethod( PictDrawingMethod::PAINT
);
1866 pVirDev
->DrawBitmapEx(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1869 case 0x009b: { // DirectBitsRgn
1871 tools::Rectangle aSrcRect
, aDestRect
;
1872 nDataSize
=ReadPixMapEtc(aBmp
, true, false, &aSrcRect
, &aDestRect
, true, true);
1873 DrawingMethod( PictDrawingMethod::PAINT
);
1874 pVirDev
->DrawBitmapEx(aDestRect
.TopLeft(),aDestRect
.GetSize(),aBmp
);
1877 case 0x009c: // Reserved (n Bytes)
1878 case 0x009d: // Reserved (n Bytes)
1879 case 0x009e: // Reserved (n Bytes)
1880 case 0x009f: // Reserved (n Bytes)
1882 sal_uInt16
nUSHORT(0);
1883 pPict
->ReadUInt16( nUSHORT
); nDataSize
=2+nUSHORT
;
1886 case 0x00a0: // ShortComment
1890 case 0x00a1: // LongComment
1892 sal_uInt16
nUSHORT(0);
1893 pPict
->SeekRel(2); pPict
->ReadUInt16( nUSHORT
); nDataSize
=4+nUSHORT
;
1896 default: // 0x00a2 bis 0xffff (most times reserved)
1897 sal_uInt16
nUSHORT(0);
1898 if (nOpcode
<=0x00af) { pPict
->ReadUInt16( nUSHORT
); nDataSize
=2+nUSHORT
; }
1899 else if (nOpcode
<=0x00cf) { nDataSize
=0; }
1900 else if (nOpcode
<=0x00fe) { sal_uInt32
nTemp(0); pPict
->ReadUInt32(nTemp
) ; nDataSize
= nTemp
; nDataSize
+=4; }
1901 // Osnola: checkme: in the Quickdraw Ref examples ( for pict v2)
1902 // 0x00ff(EndOfPict) is also not followed by any data...
1903 else if (nOpcode
==0x00ff) { nDataSize
=IsVersion2
? 2 : 0; } // OpEndPic
1904 else if (nOpcode
<=0x01ff) { nDataSize
=2; }
1905 else if (nOpcode
<=0x0bfe) { nDataSize
=4; }
1906 else if (nOpcode
<=0x0bff) { nDataSize
=22; }
1907 else if (nOpcode
==0x0c00) { nDataSize
=24; } // HeaderOp
1908 else if (nOpcode
<=0x7eff) { nDataSize
=24; }
1909 else if (nOpcode
<=0x7fff) { nDataSize
=254; }
1910 else if (nOpcode
<=0x80ff) { nDataSize
=0; }
1911 else { sal_uInt32
nTemp(0); pPict
->ReadUInt32(nTemp
) ; nDataSize
= nTemp
; nDataSize
+=4; }
1914 if (nDataSize
==0xffffffff) {
1915 pPict
->SetError(SVSTREAM_FILEFORMAT_ERROR
);
1921 void PictReader::ReadPict( SvStream
& rStreamPict
, GDIMetaFile
& rGDIMetaFile
)
1925 sal_uInt8 nOneByteOpcode
;
1928 pPict
= &rStreamPict
;
1929 nOrigPos
= pPict
->Tell();
1930 SvStreamEndian nOrigNumberFormat
= pPict
->GetEndian();
1932 aActForeColor
= COL_BLACK
;
1933 aActBackColor
= COL_WHITE
;
1934 nActPenSize
= Size(1,1);
1935 eActROP
= RasterOp::OverPaint
;
1936 eActMethod
= PictDrawingMethod::UNDEFINED
;
1937 aActOvalSize
= Size(1,1);
1939 aActFont
.SetCharSet( GetTextEncoding());
1940 aActFont
.SetFamily(FAMILY_SWISS
);
1941 aActFont
.SetFontSize(Size(0,12));
1942 aActFont
.SetAlignment(ALIGN_BASELINE
);
1944 aHRes
= aVRes
= Fraction( 1, 1 );
1946 pVirDev
= VclPtr
<VirtualDevice
>::Create();
1947 pVirDev
->EnableOutput(false);
1948 rGDIMetaFile
.Record(pVirDev
);
1950 pPict
->SetEndian(SvStreamEndian::BIG
);
1954 aPenPosition
=Point(-aBoundingRect
.Left(),-aBoundingRect
.Top());
1955 aTextPosition
=aPenPosition
;
1957 sal_uInt64 nPos
=pPict
->Tell();
1962 pPict
->ReadUInt16( nOpcode
);
1965 pPict
->ReadUChar( nOneByteOpcode
);
1966 nOpcode
=static_cast<sal_uInt16
>(nOneByteOpcode
);
1969 if (pPict
->GetError())
1974 pPict
->SetError(SVSTREAM_FILEFORMAT_ERROR
);
1978 if (nOpcode
==0x00ff)
1981 nSize
=ReadData(nOpcode
);
1993 if (!checkSeek(*pPict
, nPos
))
1995 pPict
->SetError(SVSTREAM_FILEFORMAT_ERROR
);
2000 pVirDev
->SetClipRegion();
2001 rGDIMetaFile
.Stop();
2002 pVirDev
.disposeAndClear();
2004 rGDIMetaFile
.SetPrefMapMode( MapMode( MapUnit::MapInch
, Point(), aHRes
, aVRes
) );
2005 rGDIMetaFile
.SetPrefSize( aBoundingRect
.GetSize() );
2007 pPict
->SetEndian(nOrigNumberFormat
);
2009 if (pPict
->GetError()) pPict
->Seek(nOrigPos
);
2012 rStreamPict
.SetError(SVSTREAM_FILEFORMAT_ERROR
);
2016 void ReadPictFile(SvStream
&rStreamPict
, GDIMetaFile
& rGDIMetaFile
)
2018 PictReader aPictReader
;
2019 aPictReader
.ReadPict(rStreamPict
, rGDIMetaFile
);
2022 //================== GraphicImport - the exported function ================
2024 bool ImportPictGraphic( SvStream
& rIStm
, Graphic
& rGraphic
)
2029 ReadPictFile(rIStm
, aMTF
);
2031 if ( !rIStm
.GetError() )
2033 rGraphic
= Graphic( aMTF
);
2040 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */