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