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