bump product version to 4.1.6.2
[LibreOffice.git] / filter / source / graphicfilter / ipict / ipict.cxx
blob9acd4c96be2f96d3c0e88b4cd42e41bcdfa714d7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
28 #include "shape.hxx"
30 class FilterConfigItem;
32 namespace PictReaderInternal {
33 //! utilitary class to store a pattern, ...
34 class Pattern {
35 public:
36 //! constructor
37 Pattern() {
38 isColor = false; isRead = false;
39 penStyle=PEN_SOLID; brushStyle = BRUSH_SOLID;
40 nBitCount = 64;
43 //! reads black/white pattern from SvStream
44 sal_uLong read(SvStream &stream);
45 //! sets the color
46 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, ...
50 * note: maybe, we must also use some mode PatCopy, ... to define the color
52 Color getColor(Color bkColor=COL_WHITE, Color fgColor = COL_BLACK) const {
53 if (isColor) return color;
54 // we create a gray pattern from nBitCount
55 double alpha = nBitCount / 64.0;
56 return Color(sal_uInt8(alpha*fgColor.GetRed()+(1.0-alpha)*bkColor.GetRed()),
57 sal_uInt8(alpha*fgColor.GetGreen()+(1.0-alpha)*bkColor.GetGreen()),
58 sal_uInt8(alpha*fgColor.GetBlue()+(1.0-alpha)*bkColor.GetBlue()));
61 //! returns true if this is the default pattern
62 bool isDefault() const { return isRead == false; }
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;
75 bool isColor; // true if it is a color pattern
76 Color color;
78 protected:
79 // flag to know if the pattern came from reading the picture, or if it is the default pattern
80 bool isRead;
83 sal_uLong Pattern::read(SvStream &stream) {
84 short nx,ny;
85 unsigned char nbyte[8];
86 sal_uLong nHiBytes, nLoBytes;
87 isColor = false;
89 // count the no of bits in pattern which are set to 1:
90 nBitCount=0;
91 for (ny=0; ny<8; ny++) {
92 stream >> ((char&)nbyte[ny]);
93 for (nx=0; nx<8; nx++) {
94 if ( (nbyte[ny] & (1<<nx)) != 0 ) nBitCount++;
98 // store pattern in 2 long words:
99 nHiBytes=(((((((sal_uLong)nbyte[0])<<8)|
100 (sal_uLong)nbyte[1])<<8)|
101 (sal_uLong)nbyte[2])<<8)|
102 (sal_uLong)nbyte[3];
103 nLoBytes=(((((((sal_uLong)nbyte[4])<<8)|
104 (sal_uLong)nbyte[5])<<8)|
105 (sal_uLong)nbyte[6])<<8)|
106 (sal_uLong)nbyte[7];
108 // create a PenStyle:
109 if (nBitCount<=0) penStyle=PEN_NULL;
110 else if (nBitCount<=16) penStyle=PEN_DOT;
111 else if (nBitCount<=32) penStyle=PEN_DASHDOT;
112 else if (nBitCount<=48) penStyle=PEN_DASH;
113 else penStyle=PEN_SOLID;
115 // create a BrushStyle:
116 if (nHiBytes==0xffffffff && nLoBytes==0xffffffff) brushStyle=BRUSH_SOLID;
117 else if (nHiBytes==0xff000000 && nLoBytes==0x00000000) brushStyle=BRUSH_HORZ;
118 else if (nHiBytes==0x80808080 && nLoBytes==0x80808080) brushStyle=BRUSH_VERT;
119 else if (nHiBytes==0xff808080 && nLoBytes==0x80808080) brushStyle=BRUSH_CROSS;
120 else if (nHiBytes==0x01824428 && nLoBytes==0x10284482) brushStyle=BRUSH_DIAGCROSS;
121 else if (nHiBytes==0x80402010 && nLoBytes==0x08040201) brushStyle=BRUSH_UPDIAG;
122 else if (nHiBytes==0x01020408 && nLoBytes==0x10204080) brushStyle=BRUSH_DOWNDIAG;
123 else if (nBitCount<=24) brushStyle=BRUSH_25;
124 else if (nBitCount<=40) brushStyle=BRUSH_50;
125 else if (nBitCount<=56) brushStyle=BRUSH_75;
126 else brushStyle=BRUSH_SOLID;
128 isRead = true;
130 return 8;
134 //============================ PictReader ==================================
136 enum PictDrawingMethod {
137 PDM_FRAME, PDM_PAINT, PDM_ERASE, PDM_INVERT, PDM_FILL,
138 PDM_TEXT, PDM_UNDEFINED
141 class PictReader {
142 typedef class PictReaderInternal::Pattern Pattern;
143 private:
145 SvStream * pPict; // The Pict file to read.
146 VirtualDevice * pVirDev; // Here the drawing methos will be called.
147 // A recording into the GDIMetaFile will take place.
149 sal_uLong nOrigPos; // Initial position in pPict.
150 sal_uInt16 nOrigNumberFormat; // Initial number format von pPict.
151 sal_Bool IsVersion2; // If it is a version 2 Pictfile.
152 Rectangle aBoundingRect; // Min/Max-Rectangle for the whole drawing.
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;
168 Fraction aHRes;
169 Fraction aVRes;
171 sal_Bool Callback(sal_uInt16 nPercent);
173 Point ReadPoint();
175 Point ReadDeltaH(Point aBase);
176 Point ReadDeltaV(Point aBase);
178 Point ReadUnsignedDeltaH(Point aBase);
179 Point ReadUnsignedDeltaV(Point aBase);
181 Size ReadSize();
183 Color ReadColor();
185 Color ReadRGBColor();
187 void ReadRectangle(Rectangle & rRect);
189 sal_uLong ReadPolygon(Polygon & rPoly);
191 sal_uLong ReadPixPattern(Pattern &pattern);
193 Rectangle aLastRect;
194 sal_uLong ReadAndDrawRect(PictDrawingMethod eMethod);
195 sal_uLong ReadAndDrawSameRect(PictDrawingMethod eMethod);
197 Rectangle aLastRoundRect;
198 sal_uLong ReadAndDrawRoundRect(PictDrawingMethod eMethod);
199 sal_uLong ReadAndDrawSameRoundRect(PictDrawingMethod eMethod);
201 Rectangle aLastOval;
202 sal_uLong ReadAndDrawOval(PictDrawingMethod eMethod);
203 sal_uLong ReadAndDrawSameOval(PictDrawingMethod eMethod);
205 Polygon aLastPolygon;
206 sal_uLong ReadAndDrawPolygon(PictDrawingMethod eMethod);
207 sal_uLong ReadAndDrawSamePolygon(PictDrawingMethod eMethod);
209 Rectangle aLastArcRect;
210 sal_uLong ReadAndDrawArc(PictDrawingMethod eMethod);
211 sal_uLong ReadAndDrawSameArc(PictDrawingMethod eMethod);
213 sal_uLong ReadAndDrawRgn(PictDrawingMethod eMethod);
214 sal_uLong ReadAndDrawSameRgn(PictDrawingMethod eMethod);
216 // returns true, if we do not need to print the shape/text/frame
217 bool IsInvisible(PictDrawingMethod eMethod) const {
218 if (eActROP == ROP_1) return true;
219 if (eMethod==PDM_FRAME && (nActPenSize.Width() == 0 || nActPenSize.Height() == 0)) return true;
220 return false;
222 void DrawingMethod(PictDrawingMethod eMethod);
224 sal_uLong ReadAndDrawText();
226 sal_uLong ReadPixMapEtc(Bitmap & rBitmap, sal_Bool bBaseAddr, sal_Bool bColorTable,
227 Rectangle * pSrcRect, Rectangle * pDestRect,
228 sal_Bool bMode, sal_Bool bMaskRgn);
230 void ReadHeader();
231 // Reads the header of the Pict file, set IsVersion and aBoundingRect
233 sal_uLong ReadData(sal_uInt16 nOpcode);
234 // Reads the date of anOopcode and executes the operation.
235 // The number of data bytes belonging to the opcode will be returned
236 // in any case.
238 void SetLineColor( const Color& rColor );
239 void SetFillColor( const Color& rColor );
241 // OSNOLA: returns the text encoding which must be used for system id
242 static rtl_TextEncoding GetTextEncoding (sal_uInt16 fId = 0xFFFF);
243 public:
245 PictReader() { aActFont.SetCharSet(GetTextEncoding()); }
247 void ReadPict( SvStream & rStreamPict, GDIMetaFile & rGDIMetaFile );
248 // reads a pict file from the stream and fills the GDIMetaFile
252 //------------------------------------------------------------------------------------------------
254 #define SETBYTE \
255 switch ( nPixelSize ) \
257 case 1 : \
258 pAcc->SetPixelIndex( ny, nx++, nDat >> 7 ); \
259 if ( nx == nWidth ) break; \
260 pAcc->SetPixelIndex( ny, nx++, nDat >> 6 ); \
261 if ( nx == nWidth ) break; \
262 pAcc->SetPixelIndex( ny, nx++, nDat >> 5 ); \
263 if ( nx == nWidth ) break; \
264 pAcc->SetPixelIndex( ny, nx++, nDat >> 4 ); \
265 if ( nx == nWidth ) break; \
266 pAcc->SetPixelIndex( ny, nx++, nDat >> 3 ); \
267 if ( nx == nWidth ) break; \
268 pAcc->SetPixelIndex( ny, nx++, nDat >> 2 ); \
269 if ( nx == nWidth ) break; \
270 pAcc->SetPixelIndex( ny, nx++, nDat >> 1 ); \
271 if ( nx == nWidth ) break; \
272 pAcc->SetPixelIndex( ny, nx++, nDat ); \
273 break; \
274 case 2 : \
275 pAcc->SetPixelIndex( ny, nx++, nDat >> 6 ); \
276 if ( nx == nWidth ) break; \
277 pAcc->SetPixelIndex( ny, nx++, (nDat>>4)&3);\
278 if ( nx == nWidth ) break; \
279 pAcc->SetPixelIndex( ny, nx++, (nDat>>2)&3 );\
280 if ( nx == nWidth ) break; \
281 pAcc->SetPixelIndex( ny, nx++, nDat & 3); \
282 break; \
283 case 4 : \
284 pAcc->SetPixelIndex( ny, nx++, nDat >> 4 ); \
285 if ( nx == nWidth ) break; \
286 pAcc->SetPixelIndex( ny, nx++, nDat ); \
287 break; \
288 case 8 : \
289 pAcc->SetPixelIndex( ny, nx++, nDat ); \
290 break; \
293 //------------------------------------------------------------------------------------------------
295 #define BITMAPERROR \
297 if ( pAcc ) \
298 aBitmap.ReleaseAccess( pAcc ); \
299 if ( pReadAcc ) \
300 aBitmap.ReleaseAccess( pReadAcc ); \
301 return 0xffffffff; \
304 //=================== methods of PictReader ==============================
305 rtl_TextEncoding PictReader::GetTextEncoding (sal_uInt16 fId) {
306 static bool first = true;
307 static rtl_TextEncoding enc = RTL_TEXTENCODING_APPLE_ROMAN;
308 if (first) {
309 rtl_TextEncoding def = osl_getThreadTextEncoding();
310 // we keep osl_getThreadTextEncoding only if it is a mac encoding
311 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 enc = def; break;
333 default: break;
335 first = false;
337 if (fId == 13) return RTL_TEXTENCODING_ADOBE_DINGBATS; // CHECKME
338 if (fId == 23) return RTL_TEXTENCODING_ADOBE_SYMBOL;
339 return enc;
342 void PictReader::SetLineColor( const Color& rColor )
344 pVirDev->SetLineColor( rColor );
347 void PictReader::SetFillColor( const Color& rColor )
349 pVirDev->SetFillColor( rColor );
352 sal_Bool PictReader::Callback(sal_uInt16 /*nPercent*/)
354 return sal_False;
357 Point PictReader::ReadPoint()
359 short nx,ny;
361 *pPict >> ny >> nx;
363 return Point( (long)nx - aBoundingRect.Left(),
364 (long)ny - aBoundingRect.Top() );
367 Point PictReader::ReadDeltaH(Point aBase)
369 signed char ndh;
371 *pPict >> ((char&)ndh);
373 return Point( aBase.X() + (long)ndh, aBase.Y() );
376 Point PictReader::ReadDeltaV(Point aBase)
378 signed char ndv;
380 *pPict >> ((char&)ndv);
382 return Point( aBase.X(), aBase.Y() + (long)ndv );
385 Point PictReader::ReadUnsignedDeltaH(Point aBase)
387 sal_uInt8 ndh;
389 *pPict >> ndh;
391 return Point( aBase.X() + (long)ndh, aBase.Y() );
394 Point PictReader::ReadUnsignedDeltaV(Point aBase)
396 sal_uInt8 ndv;
398 *pPict >> ndv;
400 return Point( aBase.X(), aBase.Y() + (long)ndv );
403 Size PictReader::ReadSize()
405 short nx,ny;
407 *pPict >> ny >> nx;
409 return Size( (long)nx, (long)ny );
412 Color PictReader::ReadColor()
414 sal_uInt32 nCol;
415 Color aCol;
417 *pPict >> nCol;
418 switch (nCol)
420 case 33: aCol=Color( COL_BLACK ); break;
421 case 30: aCol=Color( COL_WHITE ); break;
422 case 205: aCol=Color( COL_LIGHTRED ); break;
423 case 341: aCol=Color( COL_LIGHTGREEN ); break;
424 case 409: aCol=Color( COL_LIGHTBLUE ); break;
425 case 273: aCol=Color( COL_LIGHTCYAN ); break;
426 case 137: aCol=Color( COL_LIGHTMAGENTA ); break;
427 case 69: aCol=Color( COL_YELLOW ); break;
428 default: aCol=Color( COL_LIGHTGRAY );
430 return aCol;
434 Color PictReader::ReadRGBColor()
436 sal_uInt16 nR, nG, nB;
438 *pPict >> nR >> nG >> nB;
439 return Color( (sal_uInt8) ( nR >> 8 ), (sal_uInt8) ( nG >> 8 ), (sal_uInt8) ( nB >> 8 ) );
443 void PictReader::ReadRectangle(Rectangle & rRect)
445 Point aTopLeft, aBottomRight;
447 aTopLeft=ReadPoint();
448 aBottomRight=ReadPoint();
449 rRect=Rectangle(aTopLeft,aBottomRight);
453 sal_uLong PictReader::ReadPolygon(Polygon & rPoly)
455 sal_uInt16 nSize,i;
456 sal_uLong nDataSize;
458 *pPict >> nSize;
459 pPict->SeekRel(8);
460 nDataSize=(sal_uLong)nSize;
461 nSize=(nSize-10)/4;
462 rPoly.SetSize(nSize);
463 for (i=0; i<nSize; i++) rPoly.SetPoint(ReadPoint(),i);
464 return nDataSize;
467 sal_uLong PictReader::ReadPixPattern(PictReader::Pattern &pattern)
469 // Don't know if this is correct because no picture which contains PixPatterns found.
470 // Here again the attempt to calculate the size of the date to create simple StarView-Styles
471 // from them. Luckily a PixPattern always contains a normal pattern.
474 sal_uLong nDataSize;
475 sal_uInt16 nPatType;
476 Bitmap aBMP;
478 *pPict >> nPatType;
479 if (nPatType==1) {
480 pattern.read(*pPict);
481 nDataSize=ReadPixMapEtc(aBMP,sal_False,sal_True,NULL,NULL,sal_False,sal_False);
482 // CHANGEME: use average pixmap colors to update the pattern, ...
483 if (nDataSize!=0xffffffff) nDataSize+=10;
485 else if (nPatType==2) {
486 pattern.read(*pPict);
487 // RGBColor
488 sal_uInt16 nR, nG, nB;
489 *pPict >> nR >> nG >> nB;
490 Color col((sal_uInt8) ( nR >> 8 ), (sal_uInt8) ( nG >> 8 ), (sal_uInt8) ( nB >> 8 ) );
491 pattern.setColor(col);
492 nDataSize=16;
494 else nDataSize=0xffffffff;
496 return nDataSize;
499 sal_uLong PictReader::ReadAndDrawRect(PictDrawingMethod eMethod)
501 ReadRectangle(aLastRect);
502 ReadAndDrawSameRect(eMethod);
503 return 8;
506 sal_uLong PictReader::ReadAndDrawSameRect(PictDrawingMethod eMethod)
508 if (IsInvisible(eMethod)) return 0;
509 DrawingMethod(eMethod);
510 PictReaderShape::drawRectangle(pVirDev, eMethod==PDM_FRAME, aLastRect, nActPenSize);
511 return 0;
514 sal_uLong PictReader::ReadAndDrawRoundRect(PictDrawingMethod eMethod)
516 ReadRectangle(aLastRoundRect);
517 ReadAndDrawSameRoundRect(eMethod);
518 return 8;
521 sal_uLong PictReader::ReadAndDrawSameRoundRect(PictDrawingMethod eMethod)
523 if (IsInvisible(eMethod)) return 0;
524 DrawingMethod(eMethod);
525 PictReaderShape::drawRoundRectangle(pVirDev, eMethod==PDM_FRAME, aLastRoundRect, aActOvalSize, nActPenSize);
526 return 0;
529 sal_uLong PictReader::ReadAndDrawOval(PictDrawingMethod eMethod)
531 ReadRectangle(aLastOval);
532 ReadAndDrawSameOval(eMethod);
533 return 8;
536 sal_uLong PictReader::ReadAndDrawSameOval(PictDrawingMethod eMethod)
538 if (IsInvisible(eMethod)) return 0;
539 DrawingMethod(eMethod);
540 PictReaderShape::drawEllipse(pVirDev, eMethod==PDM_FRAME, aLastOval, nActPenSize);
541 return 0;
544 sal_uLong PictReader::ReadAndDrawPolygon(PictDrawingMethod eMethod)
546 sal_uLong nDataSize;
547 nDataSize=ReadPolygon(aLastPolygon);
548 ReadAndDrawSamePolygon(eMethod);
549 return nDataSize;
552 sal_uLong PictReader::ReadAndDrawSamePolygon(PictDrawingMethod eMethod)
554 if (IsInvisible(eMethod)) return 0;
555 DrawingMethod(eMethod);
556 PictReaderShape::drawPolygon(pVirDev, eMethod==PDM_FRAME, aLastPolygon, nActPenSize);
557 return 0;
561 sal_uLong PictReader::ReadAndDrawArc(PictDrawingMethod eMethod)
563 ReadRectangle(aLastArcRect);
564 ReadAndDrawSameArc(eMethod);
565 return 12;
568 sal_uLong PictReader::ReadAndDrawSameArc(PictDrawingMethod eMethod)
570 short nstartAngle, narcAngle;
571 double fAng1, fAng2;
573 *pPict >> nstartAngle >> narcAngle;
574 if (IsInvisible(eMethod)) return 4;
575 DrawingMethod(eMethod);
577 if (narcAngle<0) {
578 nstartAngle = nstartAngle + narcAngle;
579 narcAngle=-narcAngle;
581 fAng1=((double)nstartAngle)/180.0*3.14159265359;
582 fAng2=((double)(nstartAngle+narcAngle))/180.0*3.14159265359;
583 PictReaderShape::drawArc(pVirDev, eMethod==PDM_FRAME, aLastArcRect,fAng1,fAng2, nActPenSize);
584 return 4;
587 sal_uLong PictReader::ReadAndDrawRgn(PictDrawingMethod eMethod)
589 sal_uInt16 nSize;
591 *pPict >> nSize;
592 // read the DATA
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}
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 ReadAndDrawSameRgn(eMethod);
607 return (sal_uLong)nSize;
610 sal_uLong PictReader::ReadAndDrawSameRgn(PictDrawingMethod eMethod)
612 if (IsInvisible(eMethod)) return 0;
613 DrawingMethod(eMethod);
614 // DISPLAY: ...???...
615 return 0;
618 void PictReader::DrawingMethod(PictDrawingMethod eMethod)
620 if( eActMethod==eMethod ) return;
621 switch (eMethod) {
622 case PDM_FRAME:
623 if (eActPenPattern.isDefault())
624 SetLineColor( aActForeColor );
625 else
626 SetLineColor(eActPenPattern.getColor(aActBackColor, aActForeColor));
627 SetFillColor( Color(COL_TRANSPARENT) );
628 pVirDev->SetRasterOp(eActROP);
629 break;
630 case PDM_PAINT:
631 SetLineColor( Color(COL_TRANSPARENT) );
632 if (eActPenPattern.isDefault())
633 SetFillColor( aActForeColor );
634 else
635 SetFillColor(eActPenPattern.getColor(aActBackColor, aActForeColor));
636 pVirDev->SetRasterOp(eActROP);
637 break;
638 case PDM_ERASE:
639 SetLineColor( Color(COL_TRANSPARENT) );
640 if (eActBackPattern.isDefault())
641 SetFillColor( aActBackColor );// Osnola: previously aActForeColor
642 else // checkMe
643 SetFillColor(eActBackPattern.getColor(COL_BLACK, aActBackColor));
644 pVirDev->SetRasterOp(ROP_OVERPAINT);
645 break;
646 case PDM_INVERT: // checkme
647 SetLineColor( Color(COL_TRANSPARENT));
648 SetFillColor( Color( COL_BLACK ) );
649 pVirDev->SetRasterOp(ROP_INVERT);
650 break;
651 case PDM_FILL:
652 SetLineColor( Color(COL_TRANSPARENT) );
653 if (eActFillPattern.isDefault())
654 SetFillColor( aActForeColor );
655 else
656 SetFillColor(eActFillPattern.getColor(aActBackColor, aActForeColor));
657 pVirDev->SetRasterOp(ROP_OVERPAINT);
658 break;
659 case PDM_TEXT:
660 aActFont.SetColor(aActForeColor);
661 aActFont.SetFillColor(aActBackColor);
662 aActFont.SetTransparent(sal_True);
663 pVirDev->SetFont(aActFont);
664 pVirDev->SetRasterOp(ROP_OVERPAINT);
665 break;
666 default:
667 break; // -Wall undefined not handled...
669 eActMethod=eMethod;
672 sal_uLong PictReader::ReadAndDrawText()
674 char nByteLen;
675 sal_uInt32 nLen, nDataLen;
676 sal_Char sText[256];
678 *pPict >> nByteLen; nLen=((sal_uLong)nByteLen)&0x000000ff;
679 nDataLen = nLen + 1;
680 pPict->Read( &sText, nLen );
682 if (IsInvisible(PDM_TEXT)) return nDataLen;
683 DrawingMethod(PDM_TEXT);
685 // remove annoying control characters:
686 while ( nLen > 0 && ( (unsigned char)sText[ nLen - 1 ] ) < 32 )
687 nLen--;
688 sText[ nLen ] = 0;
689 String aString( (const sal_Char*)&sText, aActFont.GetCharSet());
690 pVirDev->DrawText( Point( aTextPosition.X(), aTextPosition.Y() ), aString );
691 return nDataLen;
694 sal_uLong PictReader::ReadPixMapEtc( Bitmap &rBitmap, sal_Bool bBaseAddr, sal_Bool bColorTable, Rectangle* pSrcRect,
695 Rectangle* pDestRect, sal_Bool bMode, sal_Bool bMaskRgn )
697 Bitmap aBitmap;
698 BitmapWriteAccess* pAcc = NULL;
699 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 sal_uLong i, nDataSize = 0;
707 // The calculation of nDataSize is considering the size of the whole data.
708 nDataSize = 0;
710 // condionally skip BaseAddr
711 if ( bBaseAddr )
713 pPict->SeekRel( 4 );
714 nDataSize += 4;
717 // Read PixMap or Bitmap structure;
718 *pPict >> nRowBytes >> nBndY >> nBndX >> nHeight >> nWidth;
719 nHeight = nHeight - nBndY;
720 nWidth = nWidth - nBndX;
722 if ( ( nRowBytes & 0x8000 ) != 0 )
723 { // it is a PixMap
724 nRowBytes &= 0x3fff;
725 *pPict >> nVersion >> nPackType >> nPackSize >> nHRes >> nVRes >> nPixelType >>
726 nPixelSize >> nCmpCount >> nCmpSize >> nPlaneBytes;
728 pPict->SeekRel( 8 );
729 nDataSize += 46;
731 sal_uInt16 nDstBitCount = nPixelSize;
732 if ( nDstBitCount > 8 )
733 nDstBitCount = 24;
734 else if ( nDstBitCount == 2 )
735 nDstBitCount = 4;
736 aBitmap = Bitmap( Size( nWidth, nHeight ), nDstBitCount );
738 if ( ( pAcc = aBitmap.AcquireWriteAccess() ) == NULL )
739 BITMAPERROR;
741 if ( bColorTable )
743 pPict->SeekRel( 6 );
744 *pPict >> nColTabSize;
746 if ( ++nColTabSize > 256 )
747 BITMAPERROR;
749 pAcc->SetPaletteEntryCount( nColTabSize );
751 for ( i = 0; i < nColTabSize; i++ )
753 pPict->SeekRel(2);
754 *pPict >> nRed >> nDummy >> nGreen >> nDummy >> nBlue >> nDummy;
755 pAcc->SetPaletteColor( (sal_uInt16) i, BitmapColor( nRed, nGreen, nBlue ) );
757 nDataSize += 8 + nColTabSize * 8;
760 else
762 nRowBytes &= 0x3fff;
763 nVersion = 0;
764 nPackType = 0;
765 nPackSize = nHRes = nVRes = nPlaneBytes = 0;
766 nPixelType = 0;
767 nPixelSize = nCmpCount = nCmpSize = 1;
768 nDataSize += 10;
769 aBitmap = Bitmap( Size( nWidth, nHeight ), 1 );
770 if ( ( pAcc = aBitmap.AcquireWriteAccess() ) == NULL )
771 BITMAPERROR;
772 pAcc->SetPaletteEntryCount( 2 );
773 pAcc->SetPaletteColor( 0, BitmapColor( 0xff, 0xff, 0xff ) );
774 pAcc->SetPaletteColor( 1, BitmapColor( 0, 0, 0 ) );
777 // conditionally read source rectangle:
778 if ( pSrcRect != 0)
780 sal_uInt16 nTop, nLeft, nBottom, nRight;
781 *pPict >> nTop >> nLeft >> nBottom >> nRight;
782 *pSrcRect = Rectangle( (sal_uLong)nLeft, (sal_uLong)nTop, (sal_uLong)nRight, (sal_uLong)nBottom );
783 nDataSize += 8;
786 // conditionally read destination rectangle:
787 if ( pDestRect != 0 )
789 Point aTL, aBR;
790 aTL = ReadPoint();
791 aBR = ReadPoint();
792 *pDestRect = Rectangle( aTL, aBR );
793 nDataSize += 8;
796 // conditionally read mode (or skip it):
797 if ( bMode )
799 pPict->SeekRel(2);
800 nDataSize += 2;
803 // conditionally read region (or skip it):
804 if ( bMaskRgn )
806 sal_uInt16 nSize;
807 *pPict >> nSize;
808 pPict->SeekRel( nSize - 2 );
809 nDataSize += (sal_uLong)nSize;
812 // aSMem << (nHRes/1665L) << (nVRes/1665L) << ((sal_uLong)0) << ((sal_uLong)0);
814 // read and write Bitmap bits:
815 if ( nPixelSize == 1 || nPixelSize == 2 || nPixelSize == 4 || nPixelSize == 8 )
817 sal_uInt8 nByteCountAsByte, nFlagCounterByte;
818 sal_uInt16 nByteCount, nCount, nSrcBPL, nDestBPL;
820 if ( nPixelSize == 1 ) nSrcBPL = ( nWidth + 7 ) >> 3;
821 else if ( nPixelSize == 2 ) nSrcBPL = ( nWidth + 3 ) >> 2;
822 else if ( nPixelSize == 4 ) nSrcBPL = ( nWidth + 1 ) >> 1;
823 else nSrcBPL = nWidth;
824 nDestBPL = ( nSrcBPL + 3 ) & 0xfffc;
825 if ( nRowBytes < nSrcBPL || nRowBytes > nDestBPL )
826 BITMAPERROR;
828 for ( ny = 0; ny < nHeight; ny++ )
830 nx = 0;
831 if ( nRowBytes < 8 || nPackType == 1 )
833 for ( i = 0; i < nRowBytes; i++ )
835 *pPict >> nDat;
836 if ( nx < nWidth )
837 SETBYTE;
839 nDataSize += nRowBytes;
841 else
843 if ( nRowBytes > 250 )
845 *pPict >> nByteCount;
846 nDataSize += 2 + (sal_uLong)nByteCount;
848 else
850 *pPict >> nByteCountAsByte;
851 nByteCount = ( (sal_uInt16)nByteCountAsByte ) & 0x00ff;
852 nDataSize += 1 + (sal_uLong)nByteCount;
855 while ( nByteCount )
857 *pPict >> nFlagCounterByte;
858 if ( ( nFlagCounterByte & 0x80 ) == 0 )
860 nCount = ( (sal_uInt16)nFlagCounterByte ) + 1;
861 for ( i = 0; i < nCount; i++ )
863 *pPict >> nDat;
864 if ( nx < nWidth )
865 SETBYTE;
867 nByteCount -= 1 + nCount;
869 else
871 nCount = ( 1 - ( ( (sal_uInt16)nFlagCounterByte ) | 0xff00 ) );
872 *pPict >> nDat;
873 for ( i = 0; i < nCount; i++ )
875 if ( nx < nWidth )
876 SETBYTE;
878 nByteCount -= 2;
884 else if ( nPixelSize == 16 )
886 sal_uInt8 nByteCountAsByte, nFlagCounterByte;
887 sal_uInt16 nByteCount, nCount, nD;
888 sal_uLong nSrcBitsPos;
890 if ( nRowBytes < 2 * nWidth )
891 BITMAPERROR;
893 for ( ny = 0; ny < nHeight; ny++ )
895 nx = 0;
896 if ( nRowBytes < 8 || nPackType == 1 )
898 for ( i = 0; i < nWidth; i++ )
900 *pPict >> nD;
901 nRed = (sal_uInt8)( nD >> 7 );
902 nGreen = (sal_uInt8)( nD >> 2 );
903 nBlue = (sal_uInt8)( nD << 3 );
904 pAcc->SetPixel( ny, nx++, BitmapColor( nRed, nGreen, nBlue ) );
906 nDataSize += ( (sal_uLong)nWidth ) * 2;
908 else
910 nSrcBitsPos = pPict->Tell();
911 if ( nRowBytes > 250 )
913 *pPict >> nByteCount;
914 nByteCount += 2;
916 else
918 *pPict >> nByteCountAsByte;
919 nByteCount = ( (sal_uInt16)nByteCountAsByte ) & 0x00ff;
920 nByteCount++;
922 while ( nx != nWidth )
924 *pPict >> nFlagCounterByte;
925 if ( (nFlagCounterByte & 0x80) == 0)
927 nCount=((sal_uInt16)nFlagCounterByte)+1;
928 if ( nCount + nx > nWidth) // SJ: the RLE decoding seems not to be correct here,
929 nCount = nWidth - nx; // I don't want to change this until I have a bugdoc for
930 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 *pPict >> nD;
933 nRed = (sal_uInt8)( nD >> 7 );
934 nGreen = (sal_uInt8)( nD >> 2 );
935 nBlue = (sal_uInt8)( nD << 3 );
936 pAcc->SetPixel( ny, nx++, BitmapColor( nRed, nGreen, nBlue ) );
939 else
941 nCount=(1-(((sal_uInt16)nFlagCounterByte)|0xff00));
942 if ( nCount + nx > nWidth )
943 nCount = nWidth - nx;
944 *pPict >> nD;
945 nRed = (sal_uInt8)( nD >> 7 );
946 nGreen = (sal_uInt8)( nD >> 2 );
947 nBlue = (sal_uInt8)( nD << 3 );
948 for (i=0; i<nCount; i++)
950 pAcc->SetPixel( ny, nx++, BitmapColor( nRed, nGreen, nBlue ) );
954 nDataSize+=(sal_uLong)nByteCount;
955 pPict->Seek(nSrcBitsPos+(sal_uLong)nByteCount);
959 else if (nPixelSize==32)
961 sal_uInt8 nByteCountAsByte, nFlagCounterByte;
962 sal_uInt16 nByteCount, nCount;
963 sal_uLong nSrcBitsPos;
964 BitmapColor aBitmapColor;
965 if ( ( pReadAcc = aBitmap.AcquireReadAccess() ) == NULL )
966 BITMAPERROR;
967 if ( nRowBytes != 4*nWidth )
968 BITMAPERROR;
970 if ( nRowBytes < 8 || nPackType == 1 )
972 for ( ny = 0; ny < nHeight; ny++ )
974 if ( nRowBytes < 8 || nPackType == 1 )
976 for ( nx = 0; nx < nWidth; nx++ )
978 *pPict >> nDummy >> nRed >> nGreen >> nBlue;
979 pAcc->SetPixel( ny, nx, BitmapColor( nRed, nGreen, nBlue) );
981 nDataSize += ( (sal_uLong)nWidth ) * 4;
985 else if ( nPackType == 2 )
987 for ( ny = 0; ny < nHeight; ny++ )
989 for ( nx = 0; nx < nWidth; nx++ )
991 *pPict >> nRed >> nGreen >> nBlue;
992 pAcc->SetPixel( ny, nx, BitmapColor( nRed, nGreen, nBlue ) );
994 nDataSize += ( (sal_uLong)nWidth ) * 3;
997 else
999 if ( ( nCmpCount == 3 ) || ( nCmpCount == 4 ) )
1001 sal_uInt8* pScanline = new sal_uInt8[ nWidth * nCmpCount ];
1002 for ( ny = 0; ny < nHeight; ny++ )
1004 nSrcBitsPos = pPict->Tell();
1005 if ( nRowBytes > 250 )
1007 *pPict >> nByteCount;
1008 nByteCount += 2;
1010 else
1012 *pPict >> nByteCountAsByte;
1013 nByteCount = (sal_uInt8)nByteCountAsByte;
1014 nByteCount++;
1016 i = 0;
1017 while( i < (sal_uInt32)( nWidth * nCmpCount ) )
1019 *pPict >> nFlagCounterByte;
1020 if ( ( nFlagCounterByte & 0x80 ) == 0)
1022 nCount = ( (sal_uInt16)nFlagCounterByte ) + 1;
1023 if ( ( i + nCount ) > (sal_uInt32)( nWidth * nCmpCount ) )
1024 nCount = (sal_uInt16)( nWidth * nCmpCount - i );
1025 while( nCount-- )
1027 *pPict >> nDat;
1028 pScanline[ i++ ] = nDat;
1031 else
1033 nCount = ( 1 - ( ( (sal_uInt16)nFlagCounterByte ) | 0xff00 ) );
1034 if ( ( i + nCount ) > (sal_uInt32)( nWidth * nCmpCount ) )
1035 nCount = (sal_uInt16)( nWidth * nCmpCount - i );
1036 *pPict >> nDat;
1037 while( nCount-- )
1038 pScanline[ i++ ] = nDat;
1041 sal_uInt8* pTmp = pScanline;
1042 if ( nCmpCount == 4 )
1043 pTmp += nWidth;
1044 for ( nx = 0; nx < nWidth; pTmp++ )
1045 pAcc->SetPixel( ny, nx++, BitmapColor( *pTmp, pTmp[ nWidth ], pTmp[ 2 * nWidth ] ) );
1046 nDataSize += (sal_uLong)nByteCount;
1047 pPict->Seek( nSrcBitsPos + (sal_uLong)nByteCount );
1049 delete[] pScanline;
1053 else
1054 BITMAPERROR;
1055 if ( pReadAcc )
1056 aBitmap.ReleaseAccess( pReadAcc );
1057 aBitmap.ReleaseAccess( pAcc );
1058 rBitmap = aBitmap;
1059 return nDataSize;
1062 void PictReader::ReadHeader()
1064 short y1,x1,y2,x2;
1066 sal_Char sBuf[ 2 ];
1067 // previous code considers pPict->Tell() as the normal starting position,
1068 // can we have nStartPos != 0 ?
1069 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.
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
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
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 int confidence[2] = { 0, 0};
1092 for ( st = 0; st < 3 + 513; st++ )
1094 int actualConfid = 20; // the actual confidence
1095 pPict->ResetError();
1096 if (st < 2) nOffset = nStartPos+st*512;
1097 else if (st == 2) {
1098 // choose nStartPos+0 or nStartPos+512 even if there are a little dubious
1099 int actPos = -1, actConf=0;
1100 if (confidence[0] > 0) { actPos = 0; actConf = confidence[0]; }
1101 if (confidence[1] > 0 && confidence[1] >= actConf) actPos = 1;
1102 if (actPos < 0) continue;
1103 nOffset = nStartPos+actPos*512;
1105 else {
1106 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 pPict->Seek(nOffset+10);
1109 pPict->Read( sBuf, 2 );
1110 if (pPict->IsEof() || pPict->GetError()) break;
1111 if (sBuf[0] == 0x11 || (sBuf[0] == 0x00 && sBuf[1] == 0x11)) ; // maybe ok
1112 else continue;
1114 pPict->Seek(nOffset);
1116 // 2 bytes to store size ( version 1 ) ignored
1117 pPict->SeekRel( 2 );
1118 *pPict >> y1 >> x1 >> y2 >> x2; // frame rectangle of the picture
1119 if (x1 > x2 || y1 > y2) continue; // bad bdbox
1120 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 actualConfid-=3;
1123 else if (x2 < x1+8 || y2 < y1+8) // a little dubious
1124 actualConfid-=1;
1125 if (st >= 3 && actualConfid != 20) continue;
1126 aBoundingRect=Rectangle( x1,y1, x2, y2 );
1128 if (pPict->IsEof() || pPict->GetError()) continue;
1129 // read version
1130 pPict->Read( sBuf, 2 );
1131 // version 1 file
1132 if ( sBuf[ 0 ] == 0x11 && sBuf[ 1 ] == 0x01 ) {
1133 // pict v1 must be rare and we do only few tests
1134 if (st < 2) { confidence[st] = --actualConfid; continue; }
1135 IsVersion2 = sal_False; return;
1137 if (sBuf[0] != 0x00) continue; // unrecovable error
1138 int numZero = 0;
1141 numZero++;
1142 pPict->SeekRel(-1);
1143 pPict->Read( sBuf, 2 );
1145 while ( sBuf[0] == 0x00 && numZero < 10);
1146 actualConfid -= (numZero-1); // extra nop are dubious
1147 if (pPict->IsEof() || pPict->GetError()) continue;
1148 if (sBuf[0] != 0x11) continue; // not a version opcode
1149 // abnormal version 1 file
1150 if (sBuf[1] == 0x01 ) {
1151 // pict v1 must be rare and we do only few tests
1152 if (st < 2) { confidence[st] = --actualConfid; continue; }
1153 IsVersion2 = sal_False; return;
1155 if (sBuf[1] != 0x02 ) continue; // not a version 2 file
1157 IsVersion2=sal_True;
1158 short nExtVer, nReserved;
1159 // 3 Bytes ignored : end of version arg 0x02FF (ie: 0xFF), HeaderOp : 0x0C00
1160 pPict->SeekRel( 3 );
1161 *pPict >> nExtVer >> nReserved;
1162 if (pPict->IsEof() || pPict->GetError()) continue;
1164 if ( nExtVer == -2 ) // extended version 2 picture
1166 sal_Int32 nHResFixed, nVResFixed;
1167 *pPict >> nHResFixed >> nVResFixed;
1168 *pPict >> y1 >> x1 >> y2 >> x2; // reading the optimal bounding rect
1169 if (x1 > x2 || y1 > y2) continue; // bad bdbox
1170 if (st < 2 && actualConfid != 20) { confidence[st] = actualConfid; continue; }
1172 double fHRes = nHResFixed;
1173 fHRes /= 65536;
1174 double fVRes = nVResFixed;
1175 fVRes /= 65536;
1176 aHRes /= fHRes;
1177 aVRes /= fVRes;
1178 aBoundingRect=Rectangle( x1,y1, x2, y2 );
1179 pPict->SeekRel( 4 ); // 4 bytes reserved
1180 return;
1182 else if (nExtVer == -1 ) { // basic version 2 picture
1183 if (st < 2 && actualConfid != 20) { confidence[st] = actualConfid; continue; }
1184 pPict->SeekRel( 16); // bdbox(4 fixed number)
1185 pPict->SeekRel(4); // 4 bytes reserved
1186 return;
1189 pPict->SetError(SVSTREAM_FILEFORMAT_ERROR);
1192 sal_uLong PictReader::ReadData(sal_uInt16 nOpcode)
1194 sal_uInt16 nUSHORT;
1195 Point aPoint;
1196 sal_uLong nDataSize=0;
1197 PictDrawingMethod shapeDMethod = PDM_UNDEFINED;
1198 switch (nOpcode & 7) {
1199 case 0: shapeDMethod = PDM_FRAME; break;
1200 case 1: shapeDMethod = PDM_PAINT; break;
1201 case 2: shapeDMethod = PDM_ERASE; break;
1202 case 3: shapeDMethod = PDM_INVERT; break;
1203 case 4: shapeDMethod = PDM_FILL; break;
1204 default: break;
1207 switch(nOpcode) {
1209 case 0x0000: // NOP
1210 nDataSize=0;
1211 break;
1213 case 0x0001: { // Clip
1214 Rectangle aRect;
1215 *pPict >> nUSHORT;
1216 nDataSize=nUSHORT;
1217 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 aRect.setWidth(aRect.getWidth()+1);
1224 aRect.setHeight(aRect.getHeight()+1);
1225 pVirDev->SetClipRegion( Region( aRect ) );
1226 break;
1228 case 0x0002: // BkPat
1229 nDataSize=eActBackPattern.read(*pPict);
1230 eActMethod=PDM_UNDEFINED;
1231 break;
1233 case 0x0003: // TxFont
1234 *pPict >> nUSHORT;
1235 if (nUSHORT <= 1) aActFont.SetFamily(FAMILY_SWISS);
1236 else if (nUSHORT <= 12) aActFont.SetFamily(FAMILY_DECORATIVE);
1237 else if (nUSHORT <= 20) aActFont.SetFamily(FAMILY_ROMAN);
1238 else if (nUSHORT == 21) aActFont.SetFamily(FAMILY_SWISS);
1239 else if (nUSHORT == 22) aActFont.SetFamily(FAMILY_MODERN);
1240 else if (nUSHORT <= 1023) aActFont.SetFamily(FAMILY_SWISS);
1241 else aActFont.SetFamily(FAMILY_ROMAN);
1242 aActFont.SetCharSet(GetTextEncoding(nUSHORT));
1243 eActMethod=PDM_UNDEFINED;
1244 nDataSize=2;
1245 break;
1247 case 0x0004: { // TxFace
1248 char nFace;
1249 *pPict >> nFace;
1250 if ( (nFace & 0x01)!=0 ) aActFont.SetWeight(WEIGHT_BOLD);
1251 else aActFont.SetWeight(WEIGHT_NORMAL);
1252 if ( (nFace & 0x02)!=0 ) aActFont.SetItalic(ITALIC_NORMAL);
1253 else aActFont.SetItalic(ITALIC_NONE);
1254 if ( (nFace & 0x04)!=0 ) aActFont.SetUnderline(UNDERLINE_SINGLE);
1255 else aActFont.SetUnderline(UNDERLINE_NONE);
1256 if ( (nFace & 0x08)!=0 ) aActFont.SetOutline(sal_True);
1257 else aActFont.SetOutline(sal_False);
1258 if ( (nFace & 0x10)!=0 ) aActFont.SetShadow(sal_True);
1259 else aActFont.SetShadow(sal_False);
1260 eActMethod=PDM_UNDEFINED;
1261 nDataSize=1;
1262 break;
1264 case 0x0005: // TxMode
1265 nDataSize=2;
1266 break;
1268 case 0x0006: // SpExtra
1269 nDataSize=4;
1270 break;
1272 case 0x0007: { // PnSize
1273 nActPenSize=ReadSize();
1274 eActMethod=PDM_UNDEFINED;
1275 nDataSize=4;
1276 break;
1278 case 0x0008: // PnMode
1279 *pPict >> nUSHORT;
1280 // internal code for postscript command (Quickdraw Reference Drawing B-30,B-34)
1281 if (nUSHORT==23) eActROP = ROP_1;
1282 else {
1283 switch (nUSHORT & 0x0007) {
1284 case 0: eActROP=ROP_OVERPAINT; break; // Copy
1285 case 1: eActROP=ROP_OVERPAINT; break; // Or
1286 case 2: eActROP=ROP_XOR; break; // Xor
1287 case 3: eActROP=ROP_OVERPAINT; break; // Bic
1288 case 4: eActROP=ROP_INVERT; break; // notCopy
1289 case 5: eActROP=ROP_OVERPAINT; break; // notOr
1290 case 6: eActROP=ROP_XOR; break; // notXor
1291 case 7: eActROP=ROP_OVERPAINT; break; // notBic
1294 eActMethod=PDM_UNDEFINED;
1295 nDataSize=2;
1296 break;
1298 case 0x0009: // PnPat
1299 nDataSize=eActPenPattern.read(*pPict);
1300 eActMethod=PDM_UNDEFINED;
1301 break;
1303 case 0x000a: // FillPat
1304 nDataSize=eActFillPattern.read(*pPict);
1305 eActMethod=PDM_UNDEFINED;
1306 break;
1308 case 0x000b: // OvSize
1309 aActOvalSize=ReadSize();
1310 nDataSize=4;
1311 break;
1313 case 0x000c: // Origin
1314 nDataSize=4;
1315 break;
1317 case 0x000d: // TxSize
1319 *pPict >> nUSHORT;
1320 aActFont.SetSize( Size( 0, (long)nUSHORT ) );
1321 eActMethod=PDM_UNDEFINED;
1322 nDataSize=2;
1324 break;
1326 case 0x000e: // FgColor
1327 aActForeColor=ReadColor();
1328 eActMethod=PDM_UNDEFINED;
1329 nDataSize=4;
1330 break;
1332 case 0x000f: // BkColor
1333 aActBackColor=ReadColor();
1334 nDataSize=4;
1335 break;
1337 case 0x0010: // TxRatio
1338 nDataSize=8;
1339 break;
1341 case 0x0011: // VersionOp
1342 nDataSize=1;
1343 break;
1345 case 0x0012: // BkPixPat
1346 nDataSize=ReadPixPattern(eActBackPattern);
1347 eActMethod=PDM_UNDEFINED;
1348 break;
1350 case 0x0013: // PnPixPat
1351 nDataSize=ReadPixPattern(eActPenPattern);
1352 eActMethod=PDM_UNDEFINED;
1353 break;
1355 case 0x0014: // FillPixPat
1356 nDataSize=ReadPixPattern(eActFillPattern);
1357 eActMethod=PDM_UNDEFINED;
1358 break;
1360 case 0x0015: // PnLocHFrac
1361 nDataSize=2;
1362 break;
1364 case 0x0016: // ChExtra
1365 nDataSize=2;
1366 break;
1368 case 0x0017: // Reserved (0 Bytes)
1369 case 0x0018: // Reserved (0 Bytes)
1370 case 0x0019: // Reserved (0 Bytes)
1371 nDataSize=0;
1372 break;
1374 case 0x001a: // RGBFgCol
1375 aActForeColor=ReadRGBColor();
1376 eActMethod=PDM_UNDEFINED;
1377 nDataSize=6;
1378 break;
1380 case 0x001b: // RGBBkCol
1381 aActBackColor=ReadRGBColor();
1382 eActMethod=PDM_UNDEFINED;
1383 nDataSize=6;
1384 break;
1386 case 0x001c: // HiliteMode
1387 nDataSize=0;
1388 break;
1390 case 0x001d: // HiliteColor
1391 nDataSize=6;
1392 break;
1394 case 0x001e: // DefHilite
1395 nDataSize=0;
1396 break;
1398 case 0x001f: // OpColor
1399 nDataSize=6;
1400 break;
1402 case 0x0020: // Line
1403 aPoint=ReadPoint(); aPenPosition=ReadPoint();
1404 nDataSize=8;
1406 if (IsInvisible(PDM_FRAME)) break;
1407 DrawingMethod(PDM_FRAME);
1408 PictReaderShape::drawLine(pVirDev, aPoint,aPenPosition, nActPenSize);
1409 break;
1411 case 0x0021: // LineFrom
1412 aPoint=aPenPosition; aPenPosition=ReadPoint();
1413 nDataSize=4;
1415 if (IsInvisible(PDM_FRAME)) break;
1416 DrawingMethod(PDM_FRAME);
1417 PictReaderShape::drawLine(pVirDev, aPoint,aPenPosition, nActPenSize);
1418 break;
1420 case 0x0022: // ShortLine
1421 aPoint=ReadPoint();
1422 aPenPosition=ReadDeltaH(aPoint);
1423 aPenPosition=ReadDeltaV(aPenPosition);
1424 nDataSize=6;
1426 if (IsInvisible(PDM_FRAME)) break;
1427 DrawingMethod(PDM_FRAME);
1428 PictReaderShape::drawLine(pVirDev, aPoint,aPenPosition, nActPenSize);
1429 break;
1431 case 0x0023: // ShortLineFrom
1432 aPoint=aPenPosition;
1433 aPenPosition=ReadDeltaH(aPoint);
1434 aPenPosition=ReadDeltaV(aPenPosition);
1435 nDataSize=2;
1437 if (IsInvisible(PDM_FRAME)) break;
1438 DrawingMethod(PDM_FRAME);
1439 PictReaderShape::drawLine(pVirDev, aPoint,aPenPosition, nActPenSize);
1440 break;
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 *pPict >> nUSHORT;
1447 nDataSize=2+nUSHORT;
1448 break;
1450 case 0x0028: // LongText
1451 aTextPosition=ReadPoint();
1452 nDataSize=4+ReadAndDrawText();
1453 break;
1455 case 0x0029: // DHText
1456 aTextPosition=ReadUnsignedDeltaH(aTextPosition);
1457 nDataSize=1+ReadAndDrawText();
1458 break;
1460 case 0x002a: // DVText
1461 aTextPosition=ReadUnsignedDeltaV(aTextPosition);
1462 nDataSize=1+ReadAndDrawText();
1463 break;
1465 case 0x002b: // DHDVText
1466 aTextPosition=ReadUnsignedDeltaH(aTextPosition);
1467 aTextPosition=ReadUnsignedDeltaV(aTextPosition);
1468 nDataSize=2+ReadAndDrawText();
1469 break;
1471 case 0x002c: { // fontName
1472 char sFName[ 256 ], nByteLen;
1473 sal_uInt16 nLen;
1474 *pPict >> nUSHORT; nDataSize=nUSHORT+2;
1475 *pPict >> nUSHORT;
1476 if (nUSHORT <= 1) aActFont.SetFamily(FAMILY_SWISS);
1477 else if (nUSHORT <= 12) aActFont.SetFamily(FAMILY_DECORATIVE);
1478 else if (nUSHORT <= 20) aActFont.SetFamily(FAMILY_ROMAN);
1479 else if (nUSHORT == 21) aActFont.SetFamily(FAMILY_SWISS);
1480 else if (nUSHORT == 22) aActFont.SetFamily(FAMILY_MODERN);
1481 else if (nUSHORT <= 1023) aActFont.SetFamily(FAMILY_SWISS);
1482 else aActFont.SetFamily(FAMILY_ROMAN);
1483 aActFont.SetCharSet(GetTextEncoding(nUSHORT));
1484 *pPict >> nByteLen; nLen=((sal_uInt16)nByteLen)&0x00ff;
1485 pPict->Read( &sFName, nLen );
1486 sFName[ nLen ] = 0;
1487 String aString( (const sal_Char*)&sFName, osl_getThreadTextEncoding() );
1488 aActFont.SetName( aString );
1489 eActMethod=PDM_UNDEFINED;
1490 break;
1492 case 0x002d: // lineJustify
1493 nDataSize=10;
1494 break;
1496 case 0x002e: // glyphState
1497 *pPict >> nUSHORT;
1498 nDataSize=2+nUSHORT;
1499 break;
1501 case 0x002f: // Reserved (n Bytes)
1502 *pPict >> nUSHORT;
1503 nDataSize=2+nUSHORT;
1504 break;
1506 case 0x0030: // frameRect
1507 case 0x0031: // paintRect
1508 case 0x0032: // eraseRect
1509 case 0x0033: // invertRect
1510 case 0x0034: // fillRect
1511 nDataSize=ReadAndDrawRect(shapeDMethod);
1512 break;
1514 case 0x0035: // Reserved (8 Bytes)
1515 case 0x0036: // Reserved (8 Bytes)
1516 case 0x0037: // Reserved (8 Bytes)
1517 nDataSize=8;
1518 break;
1520 case 0x0038: // frameSameRect
1521 case 0x0039: // paintSameRect
1522 case 0x003a: // eraseSameRect
1523 case 0x003b: // invertSameRect
1524 case 0x003c: // fillSameRect
1525 nDataSize=ReadAndDrawSameRect(shapeDMethod);
1526 break;
1528 case 0x003d: // Reserved (0 Bytes)
1529 case 0x003e: // Reserved (0 Bytes)
1530 case 0x003f: // Reserved (0 Bytes)
1531 nDataSize=0;
1532 break;
1534 case 0x0040: // frameRRect
1535 case 0x0041: // paintRRect
1536 case 0x0042: // eraseRRect
1537 case 0x0043: // invertRRect
1538 case 0x0044: // fillRRect
1539 nDataSize=ReadAndDrawRoundRect(shapeDMethod);
1540 break;
1542 case 0x0045: // Reserved (8 Bytes)
1543 case 0x0046: // Reserved (8 Bytes)
1544 case 0x0047: // Reserved (8 Bytes)
1545 nDataSize=8;
1546 break;
1548 case 0x0048: // frameSameRRect
1549 case 0x0049: // paintSameRRect
1550 case 0x004a: // eraseSameRRect
1551 case 0x004b: // invertSameRRect
1552 case 0x004c: // fillSameRRect
1553 nDataSize=ReadAndDrawSameRoundRect(shapeDMethod);
1554 break;
1556 case 0x004d: // Reserved (0 Bytes)
1557 case 0x004e: // Reserved (0 Bytes)
1558 case 0x004f: // Reserved (0 Bytes)
1559 nDataSize=0;
1560 break;
1562 case 0x0050: // frameOval
1563 case 0x0051: // paintOval
1564 case 0x0052: // eraseOval
1565 case 0x0053: // invertOval
1566 case 0x0054: // fillOval
1567 nDataSize=ReadAndDrawOval(shapeDMethod);
1568 break;
1570 case 0x0055: // Reserved (8 Bytes)
1571 case 0x0056: // Reserved (8 Bytes)
1572 case 0x0057: // Reserved (8 Bytes)
1573 nDataSize=8;
1574 break;
1576 case 0x0058: // frameSameOval
1577 case 0x0059: // paintSameOval
1578 case 0x005a: // eraseSameOval
1579 case 0x005b: // invertSameOval
1580 case 0x005c: // fillSameOval
1581 nDataSize=ReadAndDrawSameOval(shapeDMethod);
1582 break;
1584 case 0x005d: // Reserved (0 Bytes)
1585 case 0x005e: // Reserved (0 Bytes)
1586 case 0x005f: // Reserved (0 Bytes)
1587 nDataSize=0;
1588 break;
1590 case 0x0060: // frameArc
1591 case 0x0061: // paintArc
1592 case 0x0062: // eraseArc
1593 case 0x0063: // invertArc
1594 case 0x0064: // fillArc
1595 nDataSize=ReadAndDrawArc(shapeDMethod);
1596 break;
1598 case 0x0065: // Reserved (12 Bytes)
1599 case 0x0066: // Reserved (12 Bytes)
1600 case 0x0067: // Reserved (12 Bytes)
1601 nDataSize=12;
1602 break;
1604 case 0x0068: // frameSameArc
1605 case 0x0069: // paintSameArc
1606 case 0x006a: // eraseSameArc
1607 case 0x006b: // invertSameArc
1608 case 0x006c: // fillSameArc
1609 nDataSize=ReadAndDrawSameArc(shapeDMethod);
1610 break;
1612 case 0x006d: // Reserved (4 Bytes)
1613 case 0x006e: // Reserved (4 Bytes)
1614 case 0x006f: // Reserved (4 Bytes)
1615 nDataSize=4;
1616 break;
1618 case 0x0070: // framePoly
1619 case 0x0071: // paintPoly
1620 case 0x0072: // erasePoly
1621 case 0x0073: // invertPoly
1622 case 0x0074: // fillPoly
1623 nDataSize=ReadAndDrawPolygon(shapeDMethod);
1624 break;
1626 case 0x0075: // Reserved (Polygon-Size)
1627 case 0x0076: // Reserved (Polygon-Size)
1628 case 0x0077: // Reserved (Polygon-Size)
1629 *pPict >> nUSHORT; nDataSize=nUSHORT;
1630 break;
1632 case 0x0078: // frameSamePoly
1633 case 0x0079: // paintSamePoly
1634 case 0x007a: // eraseSamePoly
1635 case 0x007b: // invertSamePoly
1636 case 0x007c: // fillSamePoly
1637 nDataSize=ReadAndDrawSamePolygon(shapeDMethod);
1638 break;
1640 case 0x007d: // Reserved (0 Bytes)
1641 case 0x007e: // Reserved (0 Bytes)
1642 case 0x007f: // Reserved (0 Bytes)
1643 nDataSize=0;
1644 break;
1646 case 0x0080: // frameRgn
1647 case 0x0081: // paintRgn
1648 case 0x0082: // eraseRgn
1649 case 0x0083: // invertRgn
1650 case 0x0084: // fillRgn
1651 nDataSize=ReadAndDrawRgn(shapeDMethod);
1652 break;
1654 case 0x0085: // Reserved (Region-Size)
1655 case 0x0086: // Reserved (Region-Size)
1656 case 0x0087: // Reserved (Region-Size)
1657 *pPict >> nUSHORT; nDataSize=nUSHORT;
1658 break;
1660 case 0x0088: // frameSameRgn
1661 case 0x0089: // paintSameRgn
1662 case 0x008a: // eraseSameRgn
1663 case 0x008b: // invertSameRgn
1664 case 0x008c: // fillSameRgn
1665 nDataSize=ReadAndDrawSameRgn(shapeDMethod);
1666 break;
1668 case 0x008d: // Reserved (0 Bytes)
1669 case 0x008e: // Reserved (0 Bytes)
1670 case 0x008f: // Reserved (0 Bytes)
1671 nDataSize=0;
1672 break;
1674 case 0x0090: { // BitsRect
1675 Bitmap aBmp;
1676 Rectangle aSrcRect, aDestRect;
1677 nDataSize=ReadPixMapEtc(aBmp, sal_False, sal_True, &aSrcRect, &aDestRect, sal_True, sal_False);
1678 DrawingMethod(PDM_PAINT);
1679 pVirDev->DrawBitmap(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp);
1680 break;
1682 case 0x0091: { // BitsRgn
1683 Bitmap aBmp;
1684 Rectangle aSrcRect, aDestRect;
1685 nDataSize=ReadPixMapEtc(aBmp, sal_False, sal_True, &aSrcRect, &aDestRect, sal_True, sal_True);
1686 DrawingMethod(PDM_PAINT);
1687 pVirDev->DrawBitmap(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp);
1688 break;
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 *pPict >> nUSHORT; nDataSize=2+nUSHORT;
1697 break;
1699 case 0x0098: { // PackBitsRect
1700 Bitmap aBmp;
1701 Rectangle aSrcRect, aDestRect;
1702 nDataSize=ReadPixMapEtc(aBmp, sal_False, sal_True, &aSrcRect, &aDestRect, sal_True, sal_False);
1703 DrawingMethod(PDM_PAINT);
1704 pVirDev->DrawBitmap(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp);
1705 break;
1707 case 0x0099: { // PackBitsRgn
1708 Bitmap aBmp;
1709 Rectangle aSrcRect, aDestRect;
1710 nDataSize=ReadPixMapEtc(aBmp, sal_False, sal_True, &aSrcRect, &aDestRect, sal_True, sal_True);
1711 DrawingMethod(PDM_PAINT);
1712 pVirDev->DrawBitmap(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp);
1713 break;
1715 case 0x009a: { // DirectBitsRect
1716 Bitmap aBmp;
1717 Rectangle aSrcRect, aDestRect;
1718 nDataSize=ReadPixMapEtc(aBmp, sal_True, sal_False, &aSrcRect, &aDestRect, sal_True, sal_False);
1719 DrawingMethod(PDM_PAINT);
1720 pVirDev->DrawBitmap(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp);
1721 break;
1723 case 0x009b: { // DirectBitsRgn
1724 Bitmap aBmp;
1725 Rectangle aSrcRect, aDestRect;
1726 nDataSize=ReadPixMapEtc(aBmp, sal_True, sal_False, &aSrcRect, &aDestRect, sal_True, sal_True);
1727 DrawingMethod(PDM_PAINT);
1728 pVirDev->DrawBitmap(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp);
1729 break;
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 *pPict >> nUSHORT; nDataSize=2+nUSHORT;
1736 break;
1738 case 0x00a0: // ShortComment
1739 nDataSize=2;
1740 break;
1742 case 0x00a1: // LongComment
1743 pPict->SeekRel(2); *pPict >> nUSHORT; nDataSize=4+nUSHORT;
1744 break;
1746 default: // 0x00a2 bis 0xffff (most times reserved)
1747 if (nOpcode<=0x00af) { *pPict >> nUSHORT; nDataSize=2+nUSHORT; }
1748 else if (nOpcode<=0x00cf) { nDataSize=0; }
1749 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 else if (nOpcode==0x00ff) { nDataSize=IsVersion2 ? 2 : 0; } // OpEndPic
1753 else if (nOpcode<=0x01ff) { nDataSize=2; }
1754 else if (nOpcode<=0x0bfe) { nDataSize=4; }
1755 else if (nOpcode<=0x0bff) { nDataSize=22; }
1756 else if (nOpcode==0x0c00) { nDataSize=24; } // HeaderOp
1757 else if (nOpcode<=0x7eff) { nDataSize=24; }
1758 else if (nOpcode<=0x7fff) { nDataSize=254; }
1759 else if (nOpcode<=0x80ff) { nDataSize=0; }
1760 else { sal_uInt32 nTemp; *pPict >> nTemp ; nDataSize = nTemp; nDataSize+=4; }
1763 if (nDataSize==0xffffffff) {
1764 pPict->SetError(SVSTREAM_FILEFORMAT_ERROR);
1765 return 0;
1767 return nDataSize;
1770 void PictReader::ReadPict( SvStream & rStreamPict, GDIMetaFile & rGDIMetaFile )
1772 sal_uInt16 nOpcode;
1773 sal_uInt8 nOneByteOpcode;
1774 sal_uLong nSize, nPos, nStartPos, nEndPos, nPercent, nLastPercent;
1776 pPict = &rStreamPict;
1777 nOrigPos = pPict->Tell();
1778 nOrigNumberFormat = pPict->GetNumberFormatInt();
1780 aActForeColor = Color(COL_BLACK);
1781 aActBackColor = Color(COL_WHITE);
1782 nActPenSize = Size(1,1);
1783 eActROP = ROP_OVERPAINT;
1784 eActMethod = PDM_UNDEFINED;
1785 aActOvalSize = Size(1,1);
1787 aActFont.SetCharSet( GetTextEncoding());
1788 aActFont.SetFamily(FAMILY_SWISS);
1789 aActFont.SetSize(Size(0,12));
1790 aActFont.SetAlign(ALIGN_BASELINE);
1792 aHRes = aVRes = Fraction( 1, 1 );
1794 pVirDev = new VirtualDevice();
1795 pVirDev->EnableOutput(sal_False);
1796 rGDIMetaFile.Record(pVirDev);
1798 pPict->SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN);
1800 nStartPos=pPict->Tell();
1801 nEndPos=pPict->Seek(STREAM_SEEK_TO_END); pPict->Seek(nStartPos);
1802 Callback(0); nLastPercent=0;
1804 ReadHeader();
1806 aPenPosition=Point(-aBoundingRect.Left(),-aBoundingRect.Top());
1807 aTextPosition=aPenPosition;
1809 nPos=pPict->Tell();
1811 for (;;) {
1813 nPercent=(nPos-nStartPos)*100/(nEndPos-nStartPos);
1814 if (nLastPercent+4<=nPercent) {
1815 if (Callback((sal_uInt16)nPercent)==sal_True) break;
1816 nLastPercent=nPercent;
1819 if (IsVersion2 )
1820 *pPict >> nOpcode;
1821 else
1823 *pPict >> nOneByteOpcode;
1824 nOpcode=(sal_uInt16)nOneByteOpcode;
1827 if (pPict->GetError())
1828 break;
1830 if (pPict->IsEof())
1832 pPict->SetError(SVSTREAM_FILEFORMAT_ERROR);
1833 break;
1836 if (nOpcode==0x00ff)
1837 break;
1839 nSize=ReadData(nOpcode);
1841 if ( IsVersion2 )
1843 if ( nSize & 1 )
1844 nSize++;
1846 nPos+=2+nSize;
1848 else
1849 nPos+=1+nSize;
1851 pPict->Seek(nPos);
1854 rGDIMetaFile.Stop();
1855 delete pVirDev;
1857 rGDIMetaFile.SetPrefMapMode( MapMode( MAP_INCH, Point(), aHRes, aVRes ) );
1858 rGDIMetaFile.SetPrefSize( aBoundingRect.GetSize() );
1860 pPict->SetNumberFormatInt(nOrigNumberFormat);
1862 if (pPict->GetError()) pPict->Seek(nOrigPos);
1865 //================== GraphicImport - the exported function ================
1867 // this needs to be kept in sync with
1868 // ImpFilterLibCacheEntry::GetImportFunction() from
1869 // vcl/source/filter/graphicfilter.cxx
1870 #if defined(DISABLE_DYNLOADING)
1871 #define GraphicImport iptGraphicImport
1872 #endif
1874 extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL
1875 GraphicImport( SvStream& rIStm, Graphic & rGraphic, FilterConfigItem*, sal_Bool)
1877 GDIMetaFile aMTF;
1878 PictReader aPictReader;
1879 sal_Bool bRet = sal_False;
1881 aPictReader.ReadPict( rIStm, aMTF );
1883 if ( !rIStm.GetError() )
1885 rGraphic = Graphic( aMTF );
1886 bRet = sal_True;
1889 return bRet;
1893 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */