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