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