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