merge the formfield patch from ooo-build
[ooovba.git] / goodies / source / filter.vcl / epict / epict.cxx
blob160eaae25373368448b22eb5d1314b17bc30a0a0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: epict.cxx,v $
10 * $Revision: 1.23 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_goodies.hxx"
34 #include <vcl/metaact.hxx>
35 #include <svtools/filter.hxx>
36 #include <svtools/solar.hrc>
37 #include <svtools/fltcall.hxx>
39 #include <math.h>
40 #include <vcl/bmpacc.hxx>
41 #include <vcl/metaact.hxx>
42 #include <vcl/graph.hxx>
43 #include <vcl/bmpacc.hxx>
44 #include <vcl/gradient.hxx>
45 #include <vcl/hatch.hxx>
46 #include <vcl/metric.hxx>
47 #include <vcl/font.hxx>
48 #include <vcl/virdev.hxx>
49 #include <vcl/svapp.hxx>
50 #include <vcl/msgbox.hxx>
51 #include <vcl/gdimtf.hxx>
53 #include <tools/bigint.hxx>
54 #include "strings.hrc"
55 #include "dlgepct.hrc"
56 #include "dlgepct.hxx"
58 //============================== PictWriter ===================================
60 struct PictWriterAttrStackMember {
61 struct PictWriterAttrStackMember * pSucc;
62 Color aLineColor;
63 Color aFillColor;
64 RasterOp eRasterOp;
65 Font aFont;
66 MapMode aMapMode;
67 Rectangle aClipRect;
71 enum PictDrawingMethod {
72 PDM_FRAME, PDM_PAINT, PDM_ERASE, PDM_INVERT, PDM_FILL
76 struct PictPattern {
77 sal_uInt32 nLo, nHi;
81 class PictWriter {
83 private:
85 BOOL bStatus;
86 ULONG nLastPercent; // Mit welcher Zahl pCallback zuletzt aufgerufen wurde.
87 com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;
89 SvStream * pPict;
91 // Aktuelle Attribute im Quell-Metafile:
92 Color aLineColor;
93 Color aFillColor;
94 RasterOp eSrcRasterOp;
95 Font aSrcFont;
96 MapMode aSrcMapMode;
97 MapMode aTargetMapMode;
98 Rectangle aClipRect;
99 PictWriterAttrStackMember * pAttrStack;
101 // Aktuelle Attribute im Ziel-Metafile, und ob sie gueltig sind
102 BOOL bDstBkPatVisible; BOOL bDstBkPatValid;
103 BYTE nDstTxFace; BOOL bDstTxFaceValid;
104 RasterOp eDstTxMode; BOOL bDstTxModeValid;
105 USHORT nDstPnSize; BOOL bDstPnSizeValid;
106 RasterOp eDstPnMode; BOOL bDstPnModeValid;
107 PictPattern aDstPnPat; BOOL bDstPnPatValid;
108 BOOL bDstFillPatVisible; BOOL bDstFillPatValid;
109 USHORT nDstTxSize; BOOL bDstTxSizeValid;
110 Color aDstFgCol; BOOL bDstFgColValid;
111 Color aDstBkCol; BOOL bDstBkColValid;
112 Point aDstPenPosition; BOOL bDstPenPositionValid;
113 Point aDstTextPosition; BOOL bDstTextPositionValid;
114 String aDstFontName; USHORT nDstFontNameId; BOOL bDstFontNameValid;
116 ULONG nNumberOfActions; // Anzahl der Actions im GDIMetafile
117 ULONG nNumberOfBitmaps; // Anzahl der Bitmaps
118 ULONG nWrittenActions; // Anzahl der bereits verarbeiteten Actions beim Schreiben der Opcodes
119 ULONG nWrittenBitmaps; // Anzahl der bereits geschriebenen Bitmaps
120 ULONG nActBitmapPercent; // Wieviel Prozent die naechste Bitmap schon geschrieben ist.
122 void MayCallback();
123 // Berechnet anhand der obigen 5 Parameter eine Prozentzahl
124 // und macht dann ggf. einen Callback. Setzt bStatus auf FALSE wenn User abbrechen
125 // moechte.
127 void CountActionsAndBitmaps(const GDIMetaFile & rMTF);
128 // Zaehlt die Bitmaps und Actions (nNumberOfActions und nNumberOfBitmaps muessen
129 // zu Anfang auf 0 gesetzt werden, weil diese Methode rekursiv ist)
131 Polygon PolyPolygonToPolygon(const PolyPolygon & rPoly);
132 // Macht aus einem PolyPolygon ein halbwegs vernuenftiges Polygon
134 Rectangle MapRectangle( const Rectangle& rRect );
135 void WritePoint(const Point & rPoint);
136 void WriteSize(const Size & rSize);
137 void WriteRGBColor(const Color & rColor);
138 void WriteString( const String & rString );
139 void WriteRectangle(const Rectangle & rRect);
140 void WritePolygon(const Polygon & rPoly);
141 void WriteArcAngles(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt);
143 void ConvertLinePattern(PictPattern & rPat, BOOL bVisible);
144 void ConvertFillPattern(PictPattern & rPat, BOOL bVisible);
146 void WriteOpcode_TxFace(const Font & rFont);
147 void WriteOpcode_TxMode(RasterOp eMode);
148 void WriteOpcode_PnSize(USHORT nSize);
149 void WriteOpcode_PnMode(RasterOp eMode);
150 void WriteOpcode_PnLinePat(BOOL bVisible);
151 void WriteOpcode_PnFillPat(BOOL bVisible);
152 void WriteOpcode_OvSize(const Size & rSize);
153 void WriteOpcode_TxSize(USHORT nSize);
154 void WriteOpcode_RGBFgCol(const Color & rColor);
155 void WriteOpcode_RGBBkCol(const Color & rColor);
156 void WriteOpcode_Line(const Point & rLocPt, const Point & rNewPt);
157 void WriteOpcode_LineFrom(const Point & rNewPt);
158 void WriteOpcode_Text(const Point & rPoint, const String& rString, BOOL bDelta);
159 void WriteOpcode_FontName(const Font & rFont);
160 void WriteOpcode_ClipRect( const Rectangle& rRect );
161 void WriteOpcode_Rect(PictDrawingMethod eMethod, const Rectangle & rRect);
162 void WriteOpcode_SameRect(PictDrawingMethod eMethod);
163 void WriteOpcode_RRect(PictDrawingMethod eMethod, const Rectangle & rRect);
164 void WriteOpcode_SameRRect(PictDrawingMethod eMethod);
165 void WriteOpcode_Oval(PictDrawingMethod eMethod, const Rectangle & rRect);
166 void WriteOpcode_SameOval(PictDrawingMethod eMethod);
167 void WriteOpcode_Arc(PictDrawingMethod eMethod, const Rectangle & rRect,
168 const Point & rStartPt, const Point & rEndPt);
169 void WriteOpcode_SameArc(PictDrawingMethod eMethod, const Rectangle & rRect,
170 const Point & rStartPt, const Point & rEndPt);
171 void WriteOpcode_Poly(PictDrawingMethod eMethod, const Polygon & rPoly);
172 void WriteOpcode_BitsRect(const Point & rPoint, const Size & rSize, const Bitmap & rBitmap);
173 void WriteOpcode_EndOfFile();
175 void SetAttrForPaint();
176 void SetAttrForFrame();
177 void SetAttrForText();
179 void WriteTextArray(Point & rPoint, const String& rString, const sal_Int32 * pDXAry);
181 void WriteOpcodes(const GDIMetaFile & rMTF);
183 void WriteHeader(const GDIMetaFile & rMTF);
184 void UpdateHeader();
186 public:
188 BOOL WritePict( const GDIMetaFile & rMTF, SvStream & rTargetStream, FilterConfigItem* pFilterConfigItem );
192 //========================== Methoden von PictWriter ==========================
195 void PictWriter::MayCallback()
197 if ( xStatusIndicator.is() )
199 ULONG nPercent;
200 nPercent=((nWrittenBitmaps<<14)+(nActBitmapPercent<<14)/100+nWrittenActions)
201 *100
202 /((nNumberOfBitmaps<<14)+nNumberOfActions);
204 if (nPercent>=nLastPercent+3)
206 nLastPercent=nPercent;
207 if( nPercent<=100 )
208 xStatusIndicator->setValue( nPercent );
213 void PictWriter::CountActionsAndBitmaps(const GDIMetaFile & rMTF)
215 ULONG nAction, nActionCount;
216 const MetaAction* pMA;
218 nActionCount = rMTF.GetActionCount();
220 for (nAction=0; nAction<nActionCount; nAction++)
222 pMA = rMTF.GetAction( nAction );
224 switch( pMA->GetType() )
226 case META_BMP_ACTION:
227 case META_BMPSCALE_ACTION:
228 case META_BMPSCALEPART_ACTION:
229 case META_BMPEX_ACTION:
230 case META_BMPEXSCALE_ACTION:
231 case META_BMPEXSCALEPART_ACTION:
232 nNumberOfBitmaps++;
233 break;
236 nNumberOfActions++;
241 Polygon PictWriter::PolyPolygonToPolygon(const PolyPolygon & rPolyPoly)
243 USHORT nCount,nSize1,nSize2,np,i1,i2,i3,nBestIdx1,nBestIdx2;
244 long nDistSqr,nBestDistSqr, nCountdownTests;
245 Point aP1,aPRel;
246 Polygon aPoly1, aPoly2, aPoly3;
248 nCount=rPolyPoly.Count();
249 if (nCount==0) return Polygon(0);
251 aPoly1=rPolyPoly.GetObject(0);
252 for (np=1; np<nCount; np++) {
253 aPoly2=rPolyPoly.GetObject(np);
255 //-----------------Folgendes verschmilzt aPoly1 und aPoly2 zu aPoly1-----------------
257 nSize1=aPoly1.GetSize();
258 nSize2=aPoly2.GetSize();
260 // Zunaechst werden ein Punkt in aPoly1 (referenziert durch nBestIdx1) und ein
261 // Punkt in aPoly2 (referenziert durch nBestIdx2) gesucht, die moeglichst dicht
262 // beieinander liegen. Da dies mit quadratischem Aufwand einher geht, und somit
263 // manche Bilder Ewigkeiten benoetigen, um exportiert zu werden, begrenzen wir
264 // die Anzahl der Tests auf 1000, und brechen die Suche ggf. schon vorher ab.
265 // Dadruch wird das Ergebnis nicht falsch, sondern eventuell nicht so schoen.
266 nCountdownTests=1000;
267 nBestDistSqr=0x7fffffff;
268 nBestIdx1=0;
269 nBestIdx2=0;
270 for (i1=0; i1<nSize1; i1++) {
271 aP1=aPoly1.GetPoint(i1);
272 for (i2=0; i2<nSize2; i2++) {
273 aPRel=aPoly2.GetPoint(i2); aPRel-=aP1;
274 nDistSqr=aPRel.X()*aPRel.X()+aPRel.Y()*aPRel.Y();
275 if (nDistSqr<nBestDistSqr) {
276 nBestIdx1=i1;
277 nBestIdx2=i2;
278 nBestDistSqr=nDistSqr;
280 if (nCountdownTests<=0) break;
281 nCountdownTests--;
283 if (nCountdownTests<=0) break;
286 // Nun werden aPoly1 und aPoly2 zu einem Polygon aPoly3 (spaeter aPoly1) zusammengefuegt.
287 // Die beiden Polygone werden verbunden durch zwei zusaetzliche Kanten zwischen den oben
288 // gefundenen Punkten.
289 aPoly3.Clear();
290 aPoly3.SetSize(nSize1+nSize2+2);
291 i3=0;
292 for (i1=nBestIdx1; i1<nSize1; i1++) aPoly3.SetPoint(aPoly1.GetPoint(i1),i3++);
293 for (i1=0; i1<=nBestIdx1; i1++) aPoly3.SetPoint(aPoly1.GetPoint(i1),i3++);
294 for (i2=nBestIdx2; i2<nSize2; i2++) aPoly3.SetPoint(aPoly2.GetPoint(i2),i3++);
295 for (i2=0; i2<=nBestIdx2; i2++) aPoly3.SetPoint(aPoly2.GetPoint(i2),i3++);
297 aPoly1=aPoly3;
299 //-----------------------------------------------------------------------------------
302 return aPoly1;
306 void PictWriter::WritePoint(const Point & rPoint)
308 Point aPoint = OutputDevice::LogicToLogic( rPoint, aSrcMapMode, aTargetMapMode );
309 *pPict << ((short)aPoint.Y()) << ((short)aPoint.X());
313 void PictWriter::WriteSize(const Size & rSize)
315 OutputDevice::LogicToLogic( rSize, aSrcMapMode, aTargetMapMode ); // -Wall is this needed.
316 *pPict << ((short)rSize.Height()) << ((short)rSize.Width());
320 void PictWriter::WriteRGBColor(const Color & rColor)
322 const UINT16 nR = ( (UINT16) rColor.GetRed() << 8 ) | (UINT16) rColor.GetRed();
323 const UINT16 nG = ( (UINT16) rColor.GetGreen() << 8 ) | (UINT16) rColor.GetGreen();
324 const UINT16 nB = ( (UINT16) rColor.GetBlue() << 8 ) | (UINT16) rColor.GetBlue();
326 *pPict << nR << nG << nB;
330 void PictWriter::WriteString( const String & rString )
332 USHORT i,nLen;
334 ByteString aByteString( rString, gsl_getSystemTextEncoding() );
335 nLen = aByteString.Len();
336 if ( nLen > 255 )
337 nLen = 255;
338 *pPict << ( (BYTE)nLen );
339 for ( i = 0; i < nLen; i++ )
340 *pPict << aByteString.GetChar( i );
343 Rectangle PictWriter::MapRectangle( const Rectangle& rRect )
345 Point aPoint = OutputDevice::LogicToLogic( rRect.TopLeft(), aSrcMapMode, aTargetMapMode );
346 Size aSize = OutputDevice::LogicToLogic( rRect.GetSize(), aSrcMapMode, aTargetMapMode );
347 Rectangle aRect( aPoint, aSize );
348 aRect.Justify();
349 aRect.nBottom++;
350 aRect.nRight++;
351 return aRect;
354 void PictWriter::WriteRectangle(const Rectangle & rRect)
356 Rectangle aRect( MapRectangle( rRect ) );
357 *pPict << (sal_Int16)aRect.Top() << (sal_Int16)aRect.Left()
358 << (sal_Int16)aRect.Bottom() << (sal_Int16)aRect.Right();
361 void PictWriter::WritePolygon(const Polygon & rPoly)
363 USHORT nDataSize,i,nSize;
364 short nMinX = 0, nMinY = 0, nMaxX = 0, nMaxY = 0;
365 short nx,ny;
366 Polygon aPoly(rPoly);
368 nSize=aPoly.GetSize();
370 if (aPoly.GetPoint(0) != aPoly.GetPoint(nSize-1))
372 nSize++;
373 aPoly.SetSize(nSize);
374 aPoly.SetPoint(aPoly.GetPoint(0),nSize-1);
377 nDataSize=nSize*4+10;
378 for (i=0; i<nSize; i++)
380 Point aPoint = OutputDevice::LogicToLogic( aPoly.GetPoint( i ),
381 aSrcMapMode,
382 aTargetMapMode );
384 nx = (short) aPoint.X();
385 ny = (short) aPoint.Y();
387 if ( i==0 || nMinX>nx )
388 nMinX=nx;
389 if ( i==0 || nMinY>ny )
390 nMinY=ny;
391 if ( i==0 || nMaxX<nx )
392 nMaxX=nx;
393 if ( i==0 || nMaxY<ny )
394 nMaxY=ny;
397 *pPict << nDataSize << nMinY << nMinX << nMaxY << nMaxX;
399 for (i=0; i<nSize; i++)
400 WritePoint( aPoly.GetPoint(i) );
404 void PictWriter::WriteArcAngles(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt)
406 Point aStartPt = OutputDevice::LogicToLogic( rStartPt,
407 aSrcMapMode,
408 aTargetMapMode );
409 Point aEndPt = OutputDevice::LogicToLogic( rEndPt,
410 aSrcMapMode,
411 aTargetMapMode );
412 Rectangle aRect( OutputDevice::LogicToLogic( rRect.TopLeft(),
413 aSrcMapMode,
414 aTargetMapMode ),
415 OutputDevice::LogicToLogic( rRect.GetSize(),
416 aSrcMapMode,
417 aTargetMapMode ) );
418 Point aCenter;
419 double fAngS, fAngE, fdx, fdy;
420 short nStartAngle, nArcAngle;
423 aCenter=Point( ( aRect.Left() + aRect.Right() ) >> 1,
424 ( aRect.Top() + aRect.Bottom() ) >> 1 );
426 fdx=(double)(aStartPt.X()-aCenter.X());
427 fdy=(double)(aStartPt.Y()-aCenter.Y());
428 if ( fdx==0.0 && fdy==0.0 )
429 fdx=1.0;
430 fAngE=atan2(fdx,-fdy);
432 fdx=(double)(aEndPt.X()-aCenter.X());
433 fdy=(double)(aEndPt.Y()-aCenter.Y());
434 if ( fdx==0.0 && fdy==0.0 )
435 fdx=1.0;
436 fAngS=atan2(fdx,-fdy);
438 nStartAngle=(short)(fAngS*180.0/3.14159265359);
439 nArcAngle=((short)(fAngE*180.0/3.14159265359))-nStartAngle;
440 if (nArcAngle<0)
441 nArcAngle += 360;
442 *pPict << nStartAngle << nArcAngle;
446 void PictWriter::ConvertLinePattern(PictPattern & rPat, BOOL bVisible)
448 if( bVisible )
450 rPat.nHi=0xffffffff;
451 rPat.nLo=0xffffffff;
453 else
455 rPat.nHi=0x00000000;
456 rPat.nLo=0x00000000;
460 void PictWriter::ConvertFillPattern(PictPattern & rPat, BOOL bVisible)
462 if( bVisible )
464 rPat.nHi=0xffffffff;
465 rPat.nLo=0xffffffff;
467 else
469 rPat.nHi=0x00000000;
470 rPat.nLo=0x00000000;
475 void PictWriter::WriteOpcode_TxFace(const Font & rFont)
477 BYTE nFace;
478 FontWeight eWeight;
480 nFace=0;
481 eWeight=rFont.GetWeight();
482 if (eWeight==WEIGHT_BOLD ||
483 eWeight==WEIGHT_SEMIBOLD ||
484 eWeight==WEIGHT_ULTRABOLD ||
485 eWeight==WEIGHT_BLACK) nFace|=0x01;
486 if (rFont.GetItalic()!=ITALIC_NONE) nFace|=0x02;
487 if (rFont.GetUnderline()!=UNDERLINE_NONE) nFace|=0x04;
488 if (rFont.IsOutline()==TRUE) nFace|=0x08;
489 if (rFont.IsShadow()==TRUE) nFace|=0x10;
491 if (bDstTxFaceValid==FALSE || nDstTxFace!=nFace) {
492 *pPict << (USHORT)0x0004 << nFace << (BYTE)0;
493 nDstTxFace=nFace;
494 bDstTxFaceValid=TRUE;
499 void PictWriter::WriteOpcode_TxMode(RasterOp eMode)
501 USHORT nVal;
503 if (bDstTxModeValid==FALSE || eDstTxMode!=eMode) {
504 switch (eMode) {
505 case ROP_INVERT: nVal=0x000c; break;
506 case ROP_XOR: nVal=0x000a; break;
507 default: nVal=0x0008;
509 *pPict << (USHORT)0x0005 << nVal;
510 eDstTxMode=eMode;
511 bDstTxModeValid=TRUE;
516 void PictWriter::WriteOpcode_PnSize(USHORT nSize)
518 if (nSize==0) nSize=1;
519 if (bDstPnSizeValid==FALSE || nDstPnSize!=nSize) {
520 *pPict << (USHORT)0x0007 << nSize << nSize;
521 nDstPnSize=nSize;
522 bDstPnSizeValid=TRUE;
527 void PictWriter::WriteOpcode_PnMode(RasterOp eMode)
529 USHORT nVal;
531 if (bDstPnModeValid==FALSE || eDstPnMode!=eMode) {
532 switch (eMode)
534 case ROP_INVERT: nVal=0x000c; break;
535 case ROP_XOR: nVal=0x000a; break;
536 default: nVal=0x0008;
538 *pPict << (USHORT)0x0008 << nVal;
539 eDstPnMode=eMode;
540 bDstPnModeValid=TRUE;
545 void PictWriter::WriteOpcode_PnLinePat(BOOL bVisible)
547 PictPattern aPat;
549 ConvertLinePattern(aPat,bVisible);
550 if (bDstPnPatValid==FALSE || aDstPnPat.nHi!=aPat.nHi || aDstPnPat.nLo!=aPat.nLo) {
551 *pPict << (USHORT)0x0009 << aPat.nHi << aPat.nLo;
552 aDstPnPat=aPat;
553 bDstPnPatValid=TRUE;
558 void PictWriter::WriteOpcode_PnFillPat(BOOL bVisible)
560 PictPattern aPat;
562 ConvertFillPattern(aPat,bVisible);
563 if (bDstPnPatValid==FALSE || aDstPnPat.nHi!=aPat.nHi || aDstPnPat.nLo!=aPat.nLo) {
564 *pPict << (USHORT)0x0009 << aPat.nHi << aPat.nLo;
565 aDstPnPat=aPat;
566 bDstPnPatValid=TRUE;
571 void PictWriter::WriteOpcode_OvSize(const Size & rSize)
573 *pPict << (USHORT)0x000b;
574 WriteSize(rSize);
578 void PictWriter::WriteOpcode_TxSize(USHORT nSize)
580 if (bDstTxSizeValid==FALSE || nDstTxSize!=nSize) {
582 nDstTxSize = (USHORT) OutputDevice::LogicToLogic( Size( 0, nSize ),
583 aSrcMapMode, aTargetMapMode ).Height();
585 *pPict << (USHORT)0x000d << nDstTxSize;
586 bDstTxSizeValid=TRUE;
591 void PictWriter::WriteOpcode_RGBFgCol(const Color & rColor)
593 if (bDstFgColValid==FALSE || aDstFgCol!=rColor) {
594 *pPict << (USHORT)0x001a;
595 WriteRGBColor(rColor);
596 aDstFgCol=rColor;
597 bDstFgColValid=TRUE;
602 void PictWriter::WriteOpcode_RGBBkCol(const Color & rColor)
604 if (bDstBkColValid==FALSE || aDstBkCol!=rColor) {
605 *pPict << (USHORT)0x001b;
606 WriteRGBColor(rColor);
607 aDstBkCol=rColor;
608 bDstBkColValid=TRUE;
613 void PictWriter::WriteOpcode_Line(const Point & rLocPt, const Point & rNewPt)
615 Point aLocPt = OutputDevice::LogicToLogic( rLocPt,
616 aSrcMapMode,
617 aTargetMapMode );
618 Point aNewPt = OutputDevice::LogicToLogic( rNewPt,
619 aSrcMapMode,
620 aTargetMapMode );
621 long dh,dv;
623 dh=aNewPt.X()-aLocPt.X();
624 dv=aNewPt.Y()-aLocPt.Y();
625 if (dh<=127 && dh>=-128 && dv<=127 && dv>=-128)
626 { // ShortLine
627 *pPict << (USHORT)0x0022;
628 WritePoint(rLocPt);
629 *pPict << (char)dh << (char)dv;
631 else
633 *pPict << (USHORT)0x0020;
634 WritePoint(rLocPt);
635 WritePoint(rNewPt);
637 aDstPenPosition=rNewPt;
638 bDstPenPositionValid=TRUE;
642 void PictWriter::WriteOpcode_LineFrom(const Point & rNewPt)
644 Point aNewPt = OutputDevice::LogicToLogic( rNewPt,
645 aSrcMapMode,
646 aTargetMapMode );
647 long dh,dv;
649 dh = aNewPt.X()-aDstPenPosition.X();
650 dv = aNewPt.Y()-aDstPenPosition.Y();
652 if (dh<=127 && dh>=-128 && dv<=127 && dv>=-128)
653 { // ShortLine
654 *pPict << (USHORT)0x0023;
655 *pPict << (char)dh << (char)dv;
657 else
659 *pPict << (USHORT)0x0021;
660 WritePoint(rNewPt);
662 aDstPenPosition=rNewPt;
663 bDstPenPositionValid=TRUE;
667 void PictWriter::WriteOpcode_Text(const Point & rPoint, const String& rString, BOOL bDelta)
669 Point aPoint = OutputDevice::LogicToLogic( rPoint,
670 aSrcMapMode,
671 aTargetMapMode );
672 long dh,dv;
673 ULONG nPos;
675 nPos = pPict->Tell();
676 dh = aPoint.X()-aDstTextPosition.X();
677 dv = aPoint.Y()-aDstTextPosition.Y();
679 if (bDstTextPositionValid==FALSE || dh<0 || dh>255 || dv<0 || dv>0 || bDelta==FALSE)
681 *pPict << (USHORT)0x0028;
682 WritePoint(rPoint);
684 else if (dv==0)
686 *pPict << (USHORT)0x0029 << (BYTE)dh;
688 else if (dh==0)
690 *pPict << (USHORT)0x002a << (BYTE)dv;
692 else
694 *pPict << (USHORT)0x002b << (BYTE)dh << (BYTE)dv;
697 WriteString( rString );
698 if (((pPict->Tell()-nPos)&1)!=0)
699 *pPict << (BYTE)0;
701 aDstTextPosition = aPoint;
702 bDstTextPositionValid=TRUE;
706 void PictWriter::WriteOpcode_FontName(const Font & rFont)
708 USHORT nDataLen,nFontId;
710 switch (rFont.GetFamily()) {
711 case FAMILY_MODERN: nFontId=22; break;
712 case FAMILY_ROMAN: nFontId=20; break;
713 case FAMILY_SWISS: nFontId=21; break;
714 default: nFontId=1;
717 if (bDstFontNameValid==FALSE || nDstFontNameId!=nFontId || aDstFontName!=rFont.GetName())
719 ByteString aByteString( rFont.GetName(), gsl_getSystemTextEncoding() );
720 sal_uInt16 nFontNameLen = aByteString.Len();
721 if ( nFontNameLen )
723 nDataLen = 3 + nFontNameLen;
724 *pPict << (USHORT)0x002c << nDataLen << nFontId;
725 WriteString( rFont.GetName() );
726 if ( ( nFontNameLen & 1 ) == 0 )
727 *pPict << (BYTE)0;
729 *pPict << (USHORT)0x0003 << nFontId;
730 aDstFontName=rFont.GetName();
731 nDstFontNameId=nFontId;
732 bDstFontNameValid=TRUE;
736 void PictWriter::WriteOpcode_ClipRect( const Rectangle& rRect )
738 Rectangle aRect( MapRectangle( rRect ) );
739 aRect.nBottom++;
740 aRect.nRight++;
741 *pPict << (sal_uInt16)1 // opcode 1
742 << (sal_uInt16)10 // data size
743 << (sal_Int16)aRect.Top() << (sal_Int16)aRect.Left()
744 << (sal_Int16)aRect.Bottom() << (sal_Int16)aRect.Right();
745 aClipRect = aRect;
748 void PictWriter::WriteOpcode_Rect(PictDrawingMethod eMethod, const Rectangle & rRect)
750 USHORT oc;
751 switch (eMethod) {
752 case PDM_FRAME: oc=0x0030; break;
753 case PDM_PAINT: oc=0x0031; break;
754 case PDM_ERASE: oc=0x0032; break;
755 case PDM_INVERT: oc=0x0033; break;
756 case PDM_FILL: oc=0x0034; break;
757 default: oc=0; break; // -Wall a default for oc...
759 *pPict << oc;
760 WriteRectangle(rRect);
764 void PictWriter::WriteOpcode_SameRect(PictDrawingMethod eMethod)
766 USHORT oc;
767 switch (eMethod) {
768 case PDM_FRAME: oc=0x0038; break;
769 case PDM_PAINT: oc=0x0039; break;
770 case PDM_ERASE: oc=0x003a; break;
771 case PDM_INVERT: oc=0x003b; break;
772 case PDM_FILL: oc=0x003c; break;
773 default: oc=0; break; // -Wall a default for oc...
775 *pPict << oc;
779 void PictWriter::WriteOpcode_RRect(PictDrawingMethod eMethod, const Rectangle & rRect)
781 USHORT oc;
782 switch (eMethod) {
783 case PDM_FRAME: oc=0x0040; break;
784 case PDM_PAINT: oc=0x0041; break;
785 case PDM_ERASE: oc=0x0042; break;
786 case PDM_INVERT: oc=0x0043; break;
787 case PDM_FILL: oc=0x0044; break;
788 default: oc=0; break; // -Wall a default for oc...
790 *pPict << oc;
791 WriteRectangle(rRect);
795 void PictWriter::WriteOpcode_SameRRect(PictDrawingMethod eMethod)
797 USHORT oc;
798 switch (eMethod) {
799 case PDM_FRAME: oc=0x0048; break;
800 case PDM_PAINT: oc=0x0049; break;
801 case PDM_ERASE: oc=0x004a; break;
802 case PDM_INVERT: oc=0x004b; break;
803 case PDM_FILL: oc=0x004c; break;
804 default: oc=0; break; // -Wall a default for oc...
806 *pPict << oc;
810 void PictWriter::WriteOpcode_Oval(PictDrawingMethod eMethod, const Rectangle & rRect)
812 USHORT oc;
813 switch (eMethod) {
814 case PDM_FRAME: oc=0x0050; break;
815 case PDM_PAINT: oc=0x0051; break;
816 case PDM_ERASE: oc=0x0052; break;
817 case PDM_INVERT: oc=0x0053; break;
818 case PDM_FILL: oc=0x0054; break;
819 default: oc=0; break; // -Wall a default for oc...
821 *pPict << oc;
822 WriteRectangle(rRect);
826 void PictWriter::WriteOpcode_SameOval(PictDrawingMethod eMethod)
828 USHORT oc;
829 switch (eMethod) {
830 case PDM_FRAME: oc=0x0058; break;
831 case PDM_PAINT: oc=0x0059; break;
832 case PDM_ERASE: oc=0x005a; break;
833 case PDM_INVERT: oc=0x005b; break;
834 case PDM_FILL: oc=0x005c; break;
835 default: oc=0; break; // -Wall a default for oc...
837 *pPict << oc;
841 void PictWriter::WriteOpcode_Arc(PictDrawingMethod eMethod, const Rectangle & rRect,
842 const Point & rStartPt, const Point & rEndPt)
844 USHORT oc;
845 switch (eMethod) {
846 case PDM_FRAME: oc=0x0060; break;
847 case PDM_PAINT: oc=0x0061; break;
848 case PDM_ERASE: oc=0x0062; break;
849 case PDM_INVERT: oc=0x0063; break;
850 case PDM_FILL: oc=0x0064; break;
851 default: oc=0; break; // -Wall a default for oc...
853 *pPict << oc;
854 WriteRectangle(rRect);
855 WriteArcAngles(rRect,rStartPt,rEndPt);
859 void PictWriter::WriteOpcode_SameArc(PictDrawingMethod eMethod, const Rectangle & rRect,
860 const Point & rStartPt, const Point & rEndPt)
862 USHORT oc;
863 switch (eMethod) {
864 case PDM_FRAME: oc=0x0068; break;
865 case PDM_PAINT: oc=0x0069; break;
866 case PDM_ERASE: oc=0x006a; break;
867 case PDM_INVERT: oc=0x006b; break;
868 case PDM_FILL: oc=0x006c; break;
869 default: oc=0; break; // -Wall a default for oc...
871 *pPict << oc;
872 WriteArcAngles(rRect,rStartPt,rEndPt);
876 void PictWriter::WriteOpcode_Poly(PictDrawingMethod eMethod, const Polygon & rPoly)
878 USHORT oc;
880 if (rPoly.GetSize()<3) return;
881 switch (eMethod) {
882 case PDM_FRAME: oc=0x0070; break;
883 case PDM_PAINT: oc=0x0071; break;
884 case PDM_ERASE: oc=0x0072; break;
885 case PDM_INVERT: oc=0x0073; break;
886 case PDM_FILL: oc=0x0074; break;
887 default: oc=0; break; // -Wall a default for oc...
889 *pPict << oc;
890 WritePolygon(rPoly);
894 void PictWriter::WriteOpcode_BitsRect(const Point & rPoint, const Size & rSize, const Bitmap & rBitmap)
896 BitmapReadAccess* pAcc = NULL;
897 Bitmap aBitmap( rBitmap );
899 ULONG nWidth, nHeight, nDstRowBytes, nx, nc, ny, nCount, nColTabSize, i;
900 ULONG nDstRowPos, nSrcRowBytes, nEqu3, nPos, nDstMapPos;
901 USHORT nBitsPerPixel, nPackType;
902 BYTE *pComp[4], *pPix, *pTemp;
903 BYTE nEquData = 0;
904 BYTE nFlagCounterByte, nRed, nGreen, nBlue;
906 SetAttrForPaint();
908 // temopraere Windows-BMP-Datei erzeugen:
909 nActBitmapPercent=30;
910 MayCallback();
912 if ( bStatus == FALSE )
913 return;
914 if ( ( pAcc = aBitmap.AcquireReadAccess() ) == NULL )
915 return;
917 nBitsPerPixel = aBitmap.GetBitCount();
919 // export code below only handles four discrete cases
920 nBitsPerPixel =
921 nBitsPerPixel <= 1 ? 1 : nBitsPerPixel <= 4 ? 4 : nBitsPerPixel <= 8 ? 8 : 24;
923 nWidth = pAcc->Width();
924 nHeight = pAcc->Height();
926 // Wenn 24-Bit, dann den Opcode 'DirectBitsRect' erzeugen:
927 if ( nBitsPerPixel == 24 )
930 // Anzahl Bytes einer (ungepackten) Zeile in Quelle und Ziel berechnen:
931 nSrcRowBytes =( ( 3 * nWidth ) + 0x0003 ) & 0xfffc;
932 nDstRowBytes = nWidth * 4;
934 // Opcode und BaseAddr (?) schreiben:
935 *pPict << (USHORT)0x009a << (sal_uInt32)0x000000ff;
937 // Normalerweise wollen wir den Packing-Type 4 (Run length encoding
938 // for 32-Bit Pixels) erzeugen. Wenn aber RowBytes<8 gilt, sind die Daten
939 // grundsaetzlich ungepackt, auch wenn der Packing-Type 4 angegeben ist,
940 // was etwas komisch erscheint. Daher wollen wir in so einem Fall lieber
941 // gleich den Packing-Type 1 (ungepackt) angeben:
943 if ( nDstRowBytes < 8 )
944 nPackType = 1;
945 else
946 nPackType = 4;
948 // PixMap-Struktur schreiben:
949 *pPict << (USHORT)(nDstRowBytes|0x8000) // Bytes pro Zeile und dass es eine 'PixMap' ist
950 << (USHORT)0x0000 // Y1-Position der Bitmap in der Quelle
951 << (USHORT)0x0000 // X1-Position der Bitmap in der Quelle
952 << (USHORT)nHeight // Y2-Position der Bitmap in der Quelle
953 << (USHORT)nWidth // X2-Position der Bitmap in der Quelle
954 << (USHORT)0x0000 // Version
955 << (USHORT)nPackType // Packing type
956 << (sal_uInt32) 0x00000000 // Packing size (?)
957 << (sal_uInt32) 0x00480000 // H-Res
958 << (sal_uInt32) 0x00480000 // V-Res
959 << (USHORT)0x0010 // Pixel type (?)
960 << (USHORT)0x0020 // Pixel size: 32 bit
961 << (USHORT)0x0004 // CmpCount: 4 Komponenten
962 << (USHORT)0x0008 // CmpSize: 8 Bits
963 << (sal_uInt32) 0x00000000 // PlaneBytes (?)
964 << (sal_uInt32) 0x00000000 // (?)
965 << (sal_uInt32) 0x00000000; // (?)
967 // Source-Rectangle schreiben:
968 *pPict << (USHORT)0x0000 // Y1-Position auf der Bitmap
969 << (USHORT)0x0000 // X1-Position auf der Bitmap
970 << (USHORT)nHeight // Y2-Position auf der Bitmap
971 << (USHORT)nWidth; // X2-Position auf der Bitmap
973 // Destination-Rectangle schreiben:
974 WritePoint( rPoint );
975 WritePoint( Point( rPoint.X() + rSize.Width(), rPoint.Y() + rSize.Height() ) );
977 // Transfer mode schreiben:
978 *pPict << (USHORT)0x0000; // (?)
980 // Position der Map-Daten in Ziel merken:
981 nDstMapPos=pPict->Tell();
983 if ( nPackType == 1 ) // bei 24 bits nWidth == 1 !!
984 { // nicht packen
985 for ( ny = 0; ny < nHeight; ny++ )
987 *pPict << (BYTE)0;
988 *pPict << (BYTE)pAcc->GetPixel( ny, 0 ).GetRed();
989 *pPict << (BYTE)pAcc->GetPixel( ny, 0 ).GetGreen();
990 *pPict << (BYTE)pAcc->GetPixel( ny, 0 ).GetBlue();
991 // Prozente zaehlen, Callback, Fehler pruefen:
992 nActBitmapPercent = ( ny * 70 / nHeight ) + 30; // (30% machten schon das Schreiben der Win-BMP-Datei aus)
993 MayCallback();
996 else // packen ( PackType == 4 )
998 // Speicher fuer Zeilen-Zwischen-Datenstruktur allozieren:
999 for ( nc = 0; nc < 4; nc++ )
1000 pComp[ nc ] = new BYTE[ nWidth ];
1002 // Schleife ueber Zeilen:
1003 for ( ny = 0; ny < nHeight; ny++ )
1005 // Zeil ny der Quelle in die Zwischen-Datenstrktur einlesen:
1007 for ( nx = 0; nx < nWidth; nx++ )
1009 pComp[ 1 ][ nx ] = (BYTE)pAcc->GetPixel( ny, nx ) .GetRed();
1010 pComp[ 2 ][ nx ] = (BYTE)pAcc->GetPixel( ny, nx ) .GetGreen();
1011 pComp[ 3 ][ nx ] = (BYTE)pAcc->GetPixel( ny, nx ) .GetBlue();
1012 pComp[ 0 ][ nx ] = 0;
1015 // Anfang der Zeile im Ziel merken:
1016 nDstRowPos = pPict->Tell();
1018 // ByteCount (das ist die Groesse der gepackten Zeile) zunaechst 0 (wird spaeter berichtigt):
1019 if ( nDstRowBytes > 250 )
1020 *pPict << (USHORT)0;
1021 else
1022 *pPict << (BYTE)0;
1024 // Schleife ueber Componenten:
1025 for ( nc = 0; nc < 4; nc++ )
1027 // Schleife ueber x:
1028 nx = 0;
1029 while ( nx < nWidth )
1031 // Die Position von 3 gleichen Bytes suchen und in nEqu3 merken.
1032 // wenn nicht gefunden, dann nEqu3=nWidth setzten.
1033 // Wenn doch gefunden, dann in nEquData den Wert der Bytes merken.
1034 nEqu3 = nx;
1035 for (;;)
1037 if ( nEqu3 + 2 >= nWidth )
1039 nEqu3 = nWidth;
1040 break;
1042 nEquData = pComp[nc][nEqu3];
1043 if ( nEquData == pComp[nc][nEqu3+1] && nEquData==pComp[nc][nEqu3+2] )
1044 break;
1045 nEqu3++;
1048 // Die Daten von nx bis nEqu3 unkomprimiert schreiben (ggf. in mehreren Records):
1049 while ( nEqu3 > nx )
1051 nCount = nEqu3 - nx;
1052 if ( nCount > 128 )
1053 nCount=128;
1054 nFlagCounterByte = (BYTE)(nCount-1);
1055 *pPict << nFlagCounterByte;
1058 *pPict << pComp[nc][nx++];
1059 nCount--;
1061 while ( nCount > 0 );
1064 // Jetzt einen Komprimierungs-Record erzeugen (falls oben mindestens 3
1065 // gleiche Bytes gefunden):
1066 if ( nx < nWidth )
1067 { // Hinweis: es gilt nx==nEqu3 (hoffentlich)
1068 nCount=3; // Drei Bytes sind gleich, wie weiter oben herausgefunden.
1069 // Pruefen, ob es weitere gleiche Bytes gibts (dabei Max.-Record-Groesse beachten):
1070 while ( nx + nCount < nWidth && nCount < 128 )
1072 if ( nEquData != pComp[ nc ][ nx + nCount ] )
1073 break;
1074 nCount++;
1076 // nCount gleiche Bytes komprimiert schreiben:
1077 nFlagCounterByte = (BYTE)( 1 - (long)nCount );
1078 *pPict << nFlagCounterByte << nEquData;
1079 nx += nCount;
1083 // ByteCount berichtigen:
1084 nPos = pPict->Tell();
1085 pPict->Seek( nDstRowPos );
1086 if ( nDstRowBytes > 250 )
1087 *pPict << ( (USHORT)( nPos - nDstRowPos - 2 ) );
1088 else
1089 *pPict << ( (BYTE)( nPos - nDstRowPos - 1 ) );
1090 pPict->Seek( nPos );
1092 // Prozente zaehlen, Callback, Fehler pruefen:
1093 nActBitmapPercent = ( ny * 70 / nHeight ) + 30; // (30% machten schon das Schreiben der Win-BMP-Datei aus)
1094 MayCallback();
1096 // Aufraeumen:
1097 for ( nc = 0; nc < 4; nc++ )
1098 delete pComp[ nc ];
1101 else
1102 { // nicht 24-Bit also Opcode 'PackBitsRect' erzeugen:
1104 // Bei 1-Bit-Bildern ignorieren manche Import-Filter die Palette und nehmen statt
1105 // dessen die Vorder- und Hintergrundfarbe:
1106 if ( nBitsPerPixel == 1 )
1108 WriteOpcode_RGBBkCol( pAcc->GetPaletteColor( 0 ) );
1109 WriteOpcode_RGBFgCol( pAcc->GetPaletteColor( 1 ) );
1111 else
1113 WriteOpcode_RGBBkCol( Color( COL_BLACK ) );
1114 WriteOpcode_RGBFgCol( Color( COL_WHITE ) );
1117 // Anzahl Bytes einer (ungepackten) Zeile in Ziel und Quelle berechnen:
1118 nDstRowBytes = ( nWidth * nBitsPerPixel + 7 ) >> 3;
1119 nSrcRowBytes = ( nDstRowBytes + 3 ) & 0xfffffffc;
1121 // Opcode schreiben:
1122 *pPict << (USHORT)0x0098;
1124 // Normalerweise wollen wir den Packing-Type 0 (default Packing) erzeugen.
1125 // Wenn aber RowBytes<8 gilt, sind die Daten grundsaetzlich ungepackt,
1126 // auch wenn der Packing-Type 0 angegeben ist, was etwas komisch erscheint.
1127 // Daher wollen wir in so einem Fall lieber gleich den Packing-Type 1 (ungepackt)
1128 // angeben:
1129 if ( nDstRowBytes < 8 )
1130 nPackType = 1;
1131 else
1132 nPackType = 0;
1134 // PixMap-Struktur schreiben:
1135 *pPict << (USHORT)(nDstRowBytes|0x8000) // Bytes pro Zeile und dass es eine 'PixMap' ist
1136 << (USHORT)0x0000 // Y1-Position der Bitmap in der Quelle
1137 << (USHORT)0x0000 // X1-Position der Bitmap in der Quelle
1138 << (USHORT)nHeight // Y2-Position der Bitmap in der Quelle
1139 << (USHORT)nWidth // X2-Position der Bitmap in der Quelle
1140 << (USHORT)0x0000 // Version
1141 << (USHORT)nPackType // Packing type
1142 << (sal_uInt32) 0x00000000 // Packing size (?)
1143 << (sal_uInt32) 0x00480000 // H-Res
1144 << (sal_uInt32) 0x00480000 // V-Res
1145 << (USHORT)0x0000 // Pixel type (?)
1146 << (USHORT)nBitsPerPixel // Pixel size
1147 << (USHORT)0x0001 // CmpCount: 1 Komponente
1148 << (USHORT)nBitsPerPixel // CmpSize
1149 << (sal_uInt32) 0x00000000 // PlaneBytes (?)
1150 << (sal_uInt32) 0x00000000 // (?)
1151 << (sal_uInt32) 0x00000000; // (?)
1153 // Palette lesen und schreiben:
1154 nColTabSize = pAcc->GetPaletteEntryCount();
1155 *pPict << (sal_uInt32)0 << (USHORT)0x8000 << (USHORT)( nColTabSize - 1 );
1157 for ( i = 0; i < nColTabSize; i++ )
1159 nRed = (BYTE)pAcc->GetPaletteColor( (USHORT)i ).GetRed();
1160 nGreen = (BYTE)pAcc->GetPaletteColor( (USHORT)i ).GetGreen();
1161 nBlue = (BYTE)pAcc->GetPaletteColor( (USHORT)i ).GetBlue();
1162 *pPict << (UINT16)0 << nRed << nRed << nGreen << nGreen << nBlue << nBlue;
1165 // Source-Rectangle schreiben:
1166 *pPict << (USHORT)0 << (USHORT)0 << (USHORT)nHeight << (USHORT)nWidth;
1168 // Destination-Rectangle schreiben:
1169 WritePoint( rPoint );
1170 WritePoint( Point( rPoint.X() + rSize.Width(), rPoint.Y() + rSize.Height() ) );
1172 // Transfer mode schreiben:
1173 *pPict << (USHORT)0; // (?)
1175 // Speicher fuer eine Zeile allozieren:
1176 pPix = new BYTE[ nSrcRowBytes ];
1178 // Position der Map-Daten in Ziel merken:
1179 nDstMapPos=pPict->Tell();
1181 // Schleife ueber Zeilen:
1182 for ( ny = 0; ny < nHeight; ny++ )
1185 // Zeile ny der Quelle in den Zwischenspeicher einlesen:
1187 switch ( nBitsPerPixel )
1189 case 1 :
1190 for ( pTemp = pPix, i = 0; i < nSrcRowBytes; i++ )
1191 *pTemp++ = (BYTE)0;
1192 for ( i = 0; i < nWidth; i++ )
1193 pPix[ ( i >> 3 ) ] |= (BYTE)( pAcc->GetPixel( ny, i ) & 1 ) << ( ( i & 7 ) ^ 7 );
1194 break;
1195 case 4 :
1196 for ( pTemp = pPix, i = 0; i < nSrcRowBytes; i++ )
1197 *pTemp++ = (BYTE)0;
1198 for ( i = 0; i < nWidth; i++ )
1199 pPix[ ( i >> 1 ) ] |= (BYTE)( pAcc->GetPixel( ny, i ) & 15 ) << ( ( i & 1 ) << 2 ) ;
1200 break;
1201 case 8 :
1202 for ( i = 0; i < nWidth; i++ )
1203 pPix[ i ] = (BYTE)pAcc->GetPixel( ny, i );
1204 break;
1207 if ( nPackType == 1 )
1208 { // nicht packen
1209 pPict->Write( pPix, nDstRowBytes );
1211 else
1212 { // Packen (nPackType==0)
1214 // Anfang der Zeile im Ziel merken:
1215 nDstRowPos = pPict->Tell();
1217 // ByteCount (das ist die Groesse der gepackten Zeile) zunaechst 0 (wird spaeter berichtigt):
1218 if ( nDstRowBytes > 250 )
1219 *pPict << (USHORT)0;
1220 else
1221 *pPict << (BYTE)0;
1223 // Schleife ueber Bytes der Zeile:
1224 nx=0;
1225 while ( nx < nDstRowBytes && bStatus )
1227 // Die Position von 3 gleichen Bytes suchen und in nEqu3 merken.
1228 // wenn nicht gefunden, dann nEqu3=nDstRowBytes setzten.
1229 // Wenn doch gefunden, dann in nEquData den Wert der Bytes merken.
1230 nEqu3 = nx;
1231 for (;;)
1233 if ( nEqu3 + 2 >= nDstRowBytes )
1235 nEqu3 = nDstRowBytes;
1236 break;
1238 nEquData = pPix[ nEqu3 ];
1239 if ( nEquData == pPix[ nEqu3 + 1 ] && nEquData == pPix[ nEqu3 + 2 ] )
1240 break;
1241 nEqu3++;
1244 // Die Daten von nx bis nEqu3 unkomprimiert schreiben (ggf. in mehreren Records):
1245 while ( nEqu3 > nx )
1247 nCount = nEqu3 - nx;
1248 if ( nCount > 128 )
1249 nCount = 128;
1250 nFlagCounterByte = (BYTE)( nCount - 1 );
1251 *pPict << nFlagCounterByte;
1254 *pPict << pPix[ nx++ ];
1255 nCount--;
1256 } while ( nCount > 0 );
1259 // Jetzt einen Komprimierungs-Record erzeugen (falls oben mindestens 3
1260 // gleiche Bytes gefunden):
1261 if ( nx < nDstRowBytes )
1262 { // Hinweis: es gilt nx==nEqu3 (hoffentlich)
1263 nCount = 3; // Drei Bytes sind gleich, wie weiter oben herausgefunden.
1264 // Pruefen, ob es weitere gleiche Bytes gibts (dabei Max.-Record-Groesse beachten):
1265 while ( nx + nCount < nDstRowBytes && nCount < 128 )
1267 if ( nEquData != pPix[ nx + nCount ] )
1268 break;
1269 nCount++;
1271 // nCount gleiche Bytes komprimiert schreiben:
1272 nFlagCounterByte = (BYTE)( 1 - (long)nCount );
1273 *pPict << nFlagCounterByte << nEquData;
1274 nx += nCount;
1278 // ByteCount berichtigen:
1279 nPos = pPict->Tell();
1280 pPict->Seek( nDstRowPos );
1281 if ( nDstRowBytes > 250 )
1282 *pPict << ( (USHORT)( nPos - nDstRowPos - 2 ) );
1283 else
1284 *pPict << ( (BYTE)( nPos - nDstRowPos - 1 ) );
1285 pPict->Seek( nPos );
1288 // Prozente zaehlen, Callback, Fehler pruefen:
1289 nActBitmapPercent =( ny * 70 / nHeight ) + 30; // (30% machten schon das Schreiben der Win-BMP-Datei aus)
1290 MayCallback();
1291 if ( pPict->GetError() )
1292 bStatus = FALSE;
1294 // Aufraeumen:
1295 delete[] pPix;
1298 // Map-Daten muessen gerade Anzahl von Bytes sein:
1299 if ( ( ( pPict->Tell() - nDstMapPos ) & 1 ) != 0 )
1300 *pPict << (BYTE)0;
1302 // Bitmaps zaehlen:
1303 nWrittenBitmaps++;
1304 nActBitmapPercent = 0;
1305 if ( pAcc )
1306 aBitmap.ReleaseAccess( pAcc );
1309 void PictWriter::WriteOpcode_EndOfFile()
1311 *pPict << (USHORT)0x00ff;
1315 void PictWriter::SetAttrForPaint()
1317 WriteOpcode_PnMode(eSrcRasterOp);
1318 WriteOpcode_RGBFgCol(aFillColor);
1319 WriteOpcode_RGBBkCol(aFillColor);
1320 WriteOpcode_PnFillPat(aFillColor!=Color( COL_TRANSPARENT ));
1324 void PictWriter::SetAttrForFrame()
1326 WriteOpcode_PnMode(eSrcRasterOp);
1327 WriteOpcode_PnSize(0);
1328 WriteOpcode_RGBFgCol(aLineColor);
1329 WriteOpcode_PnLinePat(aLineColor!=Color( COL_TRANSPARENT ));
1333 void PictWriter::SetAttrForText()
1335 WriteOpcode_RGBFgCol(aSrcFont.GetColor());
1336 WriteOpcode_RGBBkCol(aSrcFont.GetFillColor());
1337 WriteOpcode_PnLinePat(TRUE);
1338 WriteOpcode_FontName(aSrcFont);
1339 WriteOpcode_TxSize((USHORT)(aSrcFont.GetSize().Height()));
1340 WriteOpcode_TxMode(eSrcRasterOp);
1341 WriteOpcode_TxFace(aSrcFont);
1345 void PictWriter::WriteTextArray(Point & rPoint, const String& rString, const sal_Int32 * pDXAry)
1347 USHORT i,nLen;
1348 sal_Unicode c;
1349 BOOL bDelta;
1350 Point aPt;
1352 if ( pDXAry == NULL )
1353 WriteOpcode_Text( rPoint, rString, FALSE );
1354 else
1356 bDelta = FALSE;
1357 nLen = rString.Len();
1358 for ( i = 0; i < nLen; i++ )
1360 c = rString.GetChar( i );
1361 if ( c && ( c != 0x20 ) )
1363 aPt = rPoint;
1364 if ( i > 0 )
1365 aPt.X() += pDXAry[ i - 1 ];
1367 WriteOpcode_Text( aPt, String( c ), bDelta );
1368 bDelta = TRUE;
1375 void PictWriter::WriteOpcodes( const GDIMetaFile & rMTF )
1377 ULONG nA, nACount;
1378 const MetaAction* pMA;
1380 if( !bStatus)
1381 return;
1383 nACount=rMTF.GetActionCount();
1385 for (nA=0; nA<nACount; nA++)
1387 pMA = rMTF.GetAction(nA);
1389 switch (pMA->GetType())
1391 case META_PIXEL_ACTION:
1393 const MetaPixelAction* pA = (const MetaPixelAction*) pMA;
1394 WriteOpcode_PnMode(eSrcRasterOp);
1395 WriteOpcode_PnSize(1);
1396 WriteOpcode_RGBFgCol(pA->GetColor());
1397 WriteOpcode_PnLinePat(TRUE);
1398 WriteOpcode_Line(pA->GetPoint(),pA->GetPoint());
1400 break;
1402 case META_POINT_ACTION:
1404 const MetaPointAction* pA = (const MetaPointAction*) pMA;
1406 if( aLineColor != Color( COL_TRANSPARENT ) )
1408 SetAttrForFrame();
1409 WriteOpcode_Line( pA->GetPoint(),pA->GetPoint() );
1412 break;
1414 case META_LINE_ACTION:
1416 const MetaLineAction* pA = (const MetaLineAction*) pMA;
1418 if( aLineColor != Color( COL_TRANSPARENT ) )
1420 SetAttrForFrame();
1421 WriteOpcode_Line( pA->GetStartPoint(),pA->GetEndPoint() );
1423 break;
1426 case META_RECT_ACTION:
1428 const MetaRectAction* pA = (const MetaRectAction*) pMA;
1430 if (aFillColor!=Color( COL_TRANSPARENT ))
1432 SetAttrForPaint();
1433 WriteOpcode_Rect(PDM_PAINT,pA->GetRect());
1434 if (aLineColor!=Color( COL_TRANSPARENT ))
1436 SetAttrForFrame();
1437 WriteOpcode_SameRect(PDM_FRAME);
1440 else if (aLineColor!=Color( COL_TRANSPARENT ))
1442 SetAttrForFrame();
1443 WriteOpcode_Rect(PDM_FRAME,pA->GetRect());
1446 break;
1448 case META_ROUNDRECT_ACTION:
1450 const MetaRoundRectAction* pA = (const MetaRoundRectAction*) pMA;
1452 WriteOpcode_OvSize( Size( pA->GetHorzRound(), pA->GetVertRound() ) );
1454 if (aFillColor!=Color( COL_TRANSPARENT ))
1456 SetAttrForPaint();
1457 WriteOpcode_RRect(PDM_PAINT,pA->GetRect());
1458 if (aLineColor!=Color( COL_TRANSPARENT ))
1460 SetAttrForFrame();
1461 WriteOpcode_SameRRect(PDM_FRAME);
1464 else if (aLineColor!=Color( COL_TRANSPARENT ))
1466 SetAttrForFrame();
1467 WriteOpcode_RRect(PDM_FRAME,pA->GetRect());
1470 break;
1472 case META_ELLIPSE_ACTION:
1474 const MetaEllipseAction* pA = (const MetaEllipseAction*) pMA;
1476 if (aFillColor!=Color( COL_TRANSPARENT ))
1478 SetAttrForPaint();
1479 WriteOpcode_Oval(PDM_PAINT,pA->GetRect());
1480 if (aLineColor!=Color( COL_TRANSPARENT ))
1482 SetAttrForFrame();
1483 WriteOpcode_SameOval(PDM_FRAME);
1486 else if (aLineColor!=Color( COL_TRANSPARENT ))
1488 SetAttrForFrame();
1489 WriteOpcode_Oval(PDM_FRAME,pA->GetRect());
1492 break;
1494 case META_ARC_ACTION:
1496 const MetaArcAction* pA = (const MetaArcAction*) pMA;
1498 if (aLineColor!=Color( COL_TRANSPARENT ))
1500 SetAttrForFrame();
1501 WriteOpcode_Arc(PDM_FRAME,pA->GetRect(),pA->GetStartPoint(),pA->GetEndPoint());
1504 break;
1506 case META_PIE_ACTION:
1508 const MetaPieAction* pA = (const MetaPieAction *) pMA;
1510 if (aFillColor!=Color( COL_TRANSPARENT ))
1512 SetAttrForPaint();
1513 WriteOpcode_Arc(PDM_PAINT,pA->GetRect(),pA->GetStartPoint(),pA->GetEndPoint());
1515 if (aLineColor!=Color( COL_TRANSPARENT ))
1517 SetAttrForFrame();
1518 WriteOpcode_SameArc(PDM_FRAME,pA->GetRect(),pA->GetStartPoint(),pA->GetEndPoint());
1521 else if (aLineColor!=Color( COL_TRANSPARENT ))
1523 SetAttrForFrame();
1524 WriteOpcode_Arc(PDM_FRAME,pA->GetRect(),pA->GetStartPoint(),pA->GetEndPoint());
1527 if (aLineColor!=Color( COL_TRANSPARENT ))
1529 double fxc,fyc,fxr,fyr,fx1,fy1,fx2,fy2,l1,l2;
1531 fxc=((double)(pA->GetRect().Left()+pA->GetRect().Right()))/2.0;
1532 fyc=((double)(pA->GetRect().Top()+pA->GetRect().Bottom()))/2.0;
1533 fxr=((double)pA->GetRect().GetWidth())/2.0;
1534 fyr=((double)pA->GetRect().GetHeight())/2.0;
1535 fx1=((double)pA->GetStartPoint().X())-fxc;
1536 fy1=((double)pA->GetStartPoint().Y())-fyc;
1537 fx2=((double)pA->GetEndPoint().X())-fxc;
1538 fy2=((double)pA->GetEndPoint().Y())-fyc;
1539 l1=sqrt(fx1*fx1+fy1*fy1);
1540 l2=sqrt(fx2*fx2+fy2*fy2);
1542 if (l1>0)
1544 fx1=fx1/l1*fxr;
1545 fy1=fy1/l1*fyr;
1548 if (l2>0)
1550 fx2=fx2/l2*fxr;
1551 fy2=fy2/l2*fyr;
1553 fx1+=fxc; fy1+=fyc; fx2+=fxc; fy2+=fyc;
1554 WriteOpcode_Line(Point((long)(fx1+0.5),(long)(fy1+0.5)), Point((long)(fxc+0.5),(long)(fyc+0.5)));
1555 WriteOpcode_LineFrom(Point((long)(fx2+0.5),(long)(fy2+0.5)));
1558 break;
1560 case META_CHORD_ACTION:
1562 // DBG_ERROR( "Unsupported PICT-Action: META_CHORD_ACTION!" );
1564 break;
1566 case META_POLYLINE_ACTION:
1568 const MetaPolyLineAction* pA = (const MetaPolyLineAction*) pMA;
1570 if( aLineColor!=Color( COL_TRANSPARENT ) )
1572 const Polygon& rPoly = pA->GetPolygon();
1574 Polygon aSimplePoly;
1575 if ( rPoly.HasFlags() )
1576 rPoly.GetSimple( aSimplePoly );
1577 else
1578 aSimplePoly = rPoly;
1580 const USHORT nSize = aSimplePoly.GetSize();
1581 Point aLast;
1583 if ( nSize )
1585 SetAttrForFrame();
1586 aLast = aSimplePoly[0];
1588 for ( USHORT i = 1; i < nSize; i++ )
1590 WriteOpcode_Line( aLast, aSimplePoly[i] );
1591 aLast = aSimplePoly[i];
1596 break;
1598 case META_POLYGON_ACTION:
1600 const MetaPolygonAction* pA = (const MetaPolygonAction*) pMA;
1602 const Polygon& rPoly = pA->GetPolygon();
1604 Polygon aSimplePoly;
1605 if ( rPoly.HasFlags() )
1606 rPoly.GetSimple( aSimplePoly );
1607 else
1608 aSimplePoly = rPoly;
1610 if (aFillColor!=Color( COL_TRANSPARENT ))
1612 SetAttrForPaint();
1613 WriteOpcode_Poly( PDM_PAINT, aSimplePoly );
1615 if (aLineColor!=Color( COL_TRANSPARENT ))
1617 SetAttrForFrame();
1618 WriteOpcode_Poly( PDM_FRAME, aSimplePoly );
1621 break;
1623 case META_POLYPOLYGON_ACTION:
1625 const MetaPolyPolygonAction* pA = (const MetaPolyPolygonAction*) pMA;
1627 const PolyPolygon& rPolyPoly = pA->GetPolyPolygon();
1628 sal_uInt16 nPolyCount = rPolyPoly.Count();
1629 PolyPolygon aSimplePolyPoly( rPolyPoly );
1630 for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
1632 if ( aSimplePolyPoly[ i ].HasFlags() )
1634 Polygon aSimplePoly;
1635 aSimplePolyPoly[ i ].GetSimple( aSimplePoly );
1636 aSimplePolyPoly[ i ] = aSimplePoly;
1639 if (aFillColor!=Color( COL_TRANSPARENT ))
1641 SetAttrForPaint();
1642 WriteOpcode_Poly( PDM_PAINT, PolyPolygonToPolygon( aSimplePolyPoly ));
1645 if (aLineColor!=Color( COL_TRANSPARENT ))
1647 USHORT nCount,i;
1648 SetAttrForFrame();
1649 nCount = aSimplePolyPoly.Count();
1650 for ( i = 0; i < nCount; i++ )
1651 WriteOpcode_Poly( PDM_FRAME, aSimplePolyPoly.GetObject( i ) );
1654 break;
1656 case META_TEXT_ACTION:
1658 const MetaTextAction* pA = (const MetaTextAction*) pMA;
1659 Point aPt( pA->GetPoint() );
1661 if ( aSrcFont.GetAlign() != ALIGN_BASELINE )
1663 VirtualDevice aVirDev;
1665 if (aSrcFont.GetAlign()==ALIGN_TOP)
1666 aPt.Y()+=(long)aVirDev.GetFontMetric(aSrcFont).GetAscent();
1667 else
1668 aPt.Y()-=(long)aVirDev.GetFontMetric(aSrcFont).GetDescent();
1671 SetAttrForText();
1672 String aStr( pA->GetText(),pA->GetIndex(),pA->GetLen() );
1673 WriteOpcode_Text( aPt, aStr, FALSE );
1675 break;
1677 case META_TEXTARRAY_ACTION:
1679 const MetaTextArrayAction* pA = (const MetaTextArrayAction*) pMA;
1680 Point aPt( pA->GetPoint() );
1682 if (aSrcFont.GetAlign()!=ALIGN_BASELINE)
1684 VirtualDevice aVirDev;
1686 if (aSrcFont.GetAlign()==ALIGN_TOP)
1687 aPt.Y()+=(long)aVirDev.GetFontMetric(aSrcFont).GetAscent();
1688 else
1689 aPt.Y()-=(long)aVirDev.GetFontMetric(aSrcFont).GetDescent();
1691 SetAttrForText();
1692 String aStr( pA->GetText(),pA->GetIndex(),pA->GetLen() );
1693 WriteTextArray( aPt, aStr, pA->GetDXArray() );
1694 break;
1697 case META_STRETCHTEXT_ACTION:
1699 const MetaStretchTextAction* pA = (const MetaStretchTextAction*) pMA;
1700 Point aPt( pA->GetPoint() );
1701 String aStr( pA->GetText(),pA->GetIndex(),pA->GetLen() );
1702 VirtualDevice aVirDev;
1703 sal_Int32* pDXAry = new sal_Int32[ aStr.Len() ];
1704 sal_Int32 nNormSize( aVirDev.GetTextArray( aStr,pDXAry ) );
1705 USHORT i;
1707 if (aSrcFont.GetAlign()!=ALIGN_BASELINE)
1709 if (aSrcFont.GetAlign()==ALIGN_TOP)
1710 aPt.Y()+=(long)aVirDev.GetFontMetric(aSrcFont).GetAscent();
1711 else
1712 aPt.Y()-=(long)aVirDev.GetFontMetric(aSrcFont).GetDescent();
1715 for ( i = 0; i < aStr.Len() - 1; i++ )
1716 pDXAry[ i ] = pDXAry[ i ] * ( (long)pA->GetWidth() ) / nNormSize;
1718 SetAttrForText();
1719 WriteTextArray( aPt, aStr, pDXAry );
1720 delete[] pDXAry;
1722 break;
1724 case META_TEXTRECT_ACTION:
1726 // DBG_ERROR( "Unsupported PICT-Action: META_TEXTRECT_ACTION!" );
1728 break;
1730 case META_BMP_ACTION:
1732 const MetaBmpAction* pA = (const MetaBmpAction*) pMA;
1733 WriteOpcode_BitsRect( pA->GetPoint(),pA->GetBitmap().GetSizePixel(), pA->GetBitmap() );
1735 break;
1737 case META_BMPSCALE_ACTION:
1739 const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pMA;
1740 WriteOpcode_BitsRect( pA->GetPoint(), pA->GetSize(), pA->GetBitmap() );
1742 break;
1744 case META_BMPSCALEPART_ACTION:
1746 const MetaBmpScalePartAction* pA = (const MetaBmpScalePartAction*) pMA;
1747 Bitmap aBmp( pA->GetBitmap() );
1749 aBmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
1750 WriteOpcode_BitsRect( pA->GetDestPoint(), pA->GetDestSize(), aBmp );
1752 break;
1754 case META_BMPEX_ACTION:
1756 const MetaBmpExAction* pA = (const MetaBmpExAction*) pMA;
1757 const Bitmap aBmp( Graphic( pA->GetBitmapEx() ).GetBitmap() );
1759 WriteOpcode_BitsRect( pA->GetPoint(), aBmp.GetSizePixel(), aBmp );
1761 break;
1763 case META_BMPEXSCALE_ACTION:
1765 const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pMA;
1766 const Bitmap aBmp( Graphic( pA->GetBitmapEx() ).GetBitmap() );
1768 WriteOpcode_BitsRect( pA->GetPoint(), pA->GetSize(), aBmp );
1770 break;
1772 case META_BMPEXSCALEPART_ACTION:
1774 const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*) pMA;
1775 Bitmap aBmp( Graphic( pA->GetBitmapEx() ).GetBitmap() );
1777 aBmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
1778 WriteOpcode_BitsRect( pA->GetDestPoint(), pA->GetDestSize(), aBmp );
1780 break;
1782 case META_EPS_ACTION :
1784 const MetaEPSAction* pA = (const MetaEPSAction*)pMA;
1785 const GDIMetaFile aGDIMetaFile( pA->GetSubstitute() );
1787 INT32 nCount = aGDIMetaFile.GetActionCount();
1788 for ( INT32 i = 0; i < nCount; i++ )
1790 const MetaAction* pMetaAct = aGDIMetaFile.GetAction( i );
1791 if ( pMetaAct->GetType() == META_BMPSCALE_ACTION )
1793 const MetaBmpScaleAction* pBmpScaleAction = (const MetaBmpScaleAction*)pMetaAct;
1794 WriteOpcode_BitsRect( pA->GetPoint(), pA->GetSize(), pBmpScaleAction->GetBitmap() );
1795 break;
1799 break;
1801 case META_MASK_ACTION:
1802 case META_MASKSCALE_ACTION:
1803 case META_MASKSCALEPART_ACTION:
1805 // DBG_ERROR( "Unsupported PICT-Action: META_MASK..._ACTION!" );
1807 break;
1809 case META_GRADIENT_ACTION:
1811 VirtualDevice aVDev;
1812 GDIMetaFile aTmpMtf;
1813 const MetaGradientAction* pA = (const MetaGradientAction*) pMA;
1815 aVDev.SetMapMode( aTargetMapMode );
1816 aVDev.AddGradientActions( pA->GetRect(), pA->GetGradient(), aTmpMtf );
1817 WriteOpcodes( aTmpMtf );
1819 break;
1821 case META_HATCH_ACTION:
1823 VirtualDevice aVDev;
1824 GDIMetaFile aTmpMtf;
1825 const MetaHatchAction* pA = (const MetaHatchAction*) pMA;
1827 aVDev.SetMapMode( aTargetMapMode );
1828 aVDev.AddHatchActions( pA->GetPolyPolygon(), pA->GetHatch(), aTmpMtf );
1829 WriteOpcodes( aTmpMtf );
1831 break;
1833 case META_WALLPAPER_ACTION:
1835 // DBG_ERROR( "Unsupported PICT-Action: META_WALLPAPER_ACTION!" );
1837 break;
1839 case META_CLIPREGION_ACTION:
1841 // DBG_ERROR( "Unsupported PICT-Action: META_CLIPREGION_ACTION!" );
1843 break;
1845 case META_ISECTRECTCLIPREGION_ACTION:
1847 const MetaISectRectClipRegionAction* pA = (const MetaISectRectClipRegionAction*) pMA;
1848 WriteOpcode_ClipRect( pA->GetRect() );
1850 break;
1852 case META_ISECTREGIONCLIPREGION_ACTION:
1854 // DBG_ERROR( "Unsupported PICT-Action: META_ISECTREGIONCLIPREGION_ACTION!" );
1856 break;
1858 case META_MOVECLIPREGION_ACTION:
1860 // DBG_ERROR( "Unsupported PICT-Action: META_MOVECLIPREGION_ACTION!" );
1862 break;
1864 case META_LINECOLOR_ACTION:
1866 const MetaLineColorAction* pA = (const MetaLineColorAction*) pMA;
1868 if( pA->IsSetting() )
1869 aLineColor = pA->GetColor();
1870 else
1871 aLineColor = Color( COL_TRANSPARENT );
1873 break;
1875 case META_FILLCOLOR_ACTION:
1877 const MetaFillColorAction* pA = (const MetaFillColorAction*) pMA;
1879 if( pA->IsSetting() )
1880 aFillColor = pA->GetColor();
1881 else
1882 aFillColor = Color( COL_TRANSPARENT );
1884 break;
1886 case META_TEXTCOLOR_ACTION:
1888 const MetaTextColorAction* pA = (const MetaTextColorAction*) pMA;
1889 aSrcFont.SetColor( pA->GetColor() );
1891 break;
1893 case META_TEXTFILLCOLOR_ACTION:
1895 const MetaTextFillColorAction* pA = (const MetaTextFillColorAction*) pMA;
1897 if( pA->IsSetting() )
1898 aSrcFont.SetFillColor( pA->GetColor() );
1899 else
1900 aSrcFont.SetFillColor( Color( COL_TRANSPARENT ) );
1902 break;
1904 case META_TEXTALIGN_ACTION:
1906 // DBG_ERROR( "Unsupported PICT-Action: META_TEXTALIGN_ACTION!" );
1908 break;
1910 case META_MAPMODE_ACTION:
1912 const MetaMapModeAction* pA = (const MetaMapModeAction*) pMA;
1914 if (aSrcMapMode!=pA->GetMapMode())
1916 if( pA->GetMapMode().GetMapUnit() == MAP_RELATIVE )
1918 MapMode aMM = pA->GetMapMode();
1919 Fraction aScaleX = aMM.GetScaleX();
1920 Fraction aScaleY = aMM.GetScaleY();
1922 Point aOrigin = aSrcMapMode.GetOrigin();
1923 BigInt aX( aOrigin.X() );
1924 aX *= BigInt( aScaleX.GetDenominator() );
1925 if( aOrigin.X() >= 0 )
1927 if( aScaleX.GetNumerator() >= 0 )
1928 aX += BigInt( aScaleX.GetNumerator()/2 );
1929 else
1930 aX -= BigInt( (aScaleX.GetNumerator()+1)/2 );
1932 else
1934 if( aScaleX.GetNumerator() >= 0 )
1935 aX -= BigInt( (aScaleX.GetNumerator()-1)/2 );
1936 else
1937 aX += BigInt( aScaleX.GetNumerator()/2 );
1940 aX /= BigInt( aScaleX.GetNumerator() );
1941 aOrigin.X() = (long)aX + aMM.GetOrigin().X();
1942 BigInt aY( aOrigin.Y() );
1943 aY *= BigInt( aScaleY.GetDenominator() );
1945 if( aOrigin.Y() >= 0 )
1947 if( aScaleY.GetNumerator() >= 0 )
1948 aY += BigInt( aScaleY.GetNumerator()/2 );
1949 else
1950 aY -= BigInt( (aScaleY.GetNumerator()+1)/2 );
1952 else
1954 if( aScaleY.GetNumerator() >= 0 )
1955 aY -= BigInt( (aScaleY.GetNumerator()-1)/2 );
1956 else
1957 aY += BigInt( aScaleY.GetNumerator()/2 );
1960 aY /= BigInt( aScaleY.GetNumerator() );
1961 aOrigin.Y() = (long)aY + aMM.GetOrigin().Y();
1962 aSrcMapMode.SetOrigin( aOrigin );
1964 aScaleX *= aSrcMapMode.GetScaleX();
1965 aScaleY *= aSrcMapMode.GetScaleY();
1966 aSrcMapMode.SetScaleX( aScaleX );
1967 aSrcMapMode.SetScaleY( aScaleY );
1969 else
1970 aSrcMapMode = pA->GetMapMode();
1973 break;
1975 case META_FONT_ACTION:
1977 const MetaFontAction* pA = (const MetaFontAction*) pMA;
1978 aSrcFont=pA->GetFont();
1980 break;
1982 case META_PUSH_ACTION:
1984 PictWriterAttrStackMember * pAt = new PictWriterAttrStackMember;
1985 pAt->aLineColor=aLineColor;
1986 pAt->aFillColor=aFillColor;
1987 pAt->eRasterOp=eSrcRasterOp;
1988 pAt->aFont=aSrcFont;
1989 pAt->aMapMode=aSrcMapMode;
1990 pAt->aClipRect=aClipRect;
1991 pAt->pSucc=pAttrStack;
1992 pAttrStack=pAt;
1994 break;
1996 case META_POP_ACTION:
1998 PictWriterAttrStackMember* pAt=pAttrStack;
2000 if( pAt )
2002 aLineColor=pAt->aLineColor;
2003 aFillColor=pAt->aFillColor;
2004 eSrcRasterOp=pAt->eRasterOp;
2005 aSrcFont=pAt->aFont;
2006 aSrcMapMode=pAt->aMapMode;
2007 if ( pAt->aClipRect != aClipRect )
2009 Rectangle aRect( pAt->aClipRect );
2010 *pPict << (sal_uInt16)1 // opcode 1
2011 << (sal_uInt16)10 // data size
2012 << (sal_Int16)aRect.Top() << (sal_Int16)aRect.Left()
2013 << (sal_Int16)aRect.Bottom() << (sal_Int16)aRect.Right();
2015 aClipRect=pAt->aClipRect;
2016 pAttrStack=pAt->pSucc;
2017 delete pAt;
2020 break;
2022 case META_RASTEROP_ACTION:
2024 const MetaRasterOpAction* pA = (const MetaRasterOpAction*) pMA;
2025 eSrcRasterOp=pA->GetRasterOp();
2027 break;
2029 case META_TRANSPARENT_ACTION:
2031 const PolyPolygon& rPolyPoly = ( (const MetaTransparentAction*) pMA )->GetPolyPolygon();
2033 if (aFillColor!=Color( COL_TRANSPARENT ))
2035 SetAttrForPaint();
2036 WriteOpcode_Poly( PDM_PAINT, PolyPolygonToPolygon( rPolyPoly ) );
2039 if (aLineColor!=Color( COL_TRANSPARENT ))
2041 SetAttrForFrame();
2042 for( USHORT i = 0, nCount = rPolyPoly.Count(); i < nCount; i++ )
2043 WriteOpcode_Poly( PDM_FRAME, rPolyPoly.GetObject( i ) );
2046 break;
2048 case META_FLOATTRANSPARENT_ACTION:
2050 const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pMA;
2052 GDIMetaFile aTmpMtf( pA->GetGDIMetaFile() );
2053 Point aSrcPt( aTmpMtf.GetPrefMapMode().GetOrigin() );
2054 const Size aSrcSize( aTmpMtf.GetPrefSize() );
2055 const Point aDestPt( pA->GetPoint() );
2056 const Size aDestSize( pA->GetSize() );
2057 const double fScaleX = aSrcSize.Width() ? (double) aDestSize.Width() / aSrcSize.Width() : 1.0;
2058 const double fScaleY = aSrcSize.Height() ? (double) aDestSize.Height() / aSrcSize.Height() : 1.0;
2059 long nMoveX, nMoveY;
2061 if( fScaleX != 1.0 || fScaleY != 1.0 )
2063 aTmpMtf.Scale( fScaleX, fScaleY );
2064 aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
2067 nMoveX = aDestPt.X() - aSrcPt.X(), nMoveY = aDestPt.Y() - aSrcPt.Y();
2069 if( nMoveX || nMoveY )
2070 aTmpMtf.Move( nMoveX, nMoveY );
2072 WriteOpcodes( aTmpMtf );
2074 break;
2077 nWrittenActions++;
2078 MayCallback();
2080 if (pPict->GetError())
2081 bStatus=FALSE;
2083 if (bStatus==FALSE)
2084 break;
2089 void PictWriter::WriteHeader(const GDIMetaFile & rMTF)
2091 USHORT i;
2092 Size aSize( rMTF.GetPrefSize() );
2093 Point aPoint;
2094 Rectangle aRect( aPoint, aSize );
2096 // 512 Bytes "Muell" am Anfang:
2097 for (i=0;i<128;i++) *pPict << (sal_uInt32)0;
2099 // Lo-16-Bits der Groesse der Datei ohne die 512 Bytes Muell:
2100 *pPict << (USHORT)0; // wird spaeter durch UpdateHeader() berichtigt
2102 // Das Bounding-Rectangle (y1,x1,y2,x2 !):
2103 WriteRectangle( aRect );
2105 // Version 2:
2106 *pPict << (sal_uInt32)0x001102ff;
2108 // Extended-Version-2-Header:
2109 *pPict << (USHORT)0x0c00 // Opcode
2110 << (USHORT)0xfffe // Version (?)
2111 << (USHORT)0x0000 // Reserved
2112 << (sal_uInt32) 0x00480000 // hRes
2113 << (sal_uInt32) 0x00480000;
2114 WriteRectangle( aRect );
2115 *pPict << (sal_uInt32)0x00000000; // Reserved
2117 // viele Import-Filter verlangen die Angabe eines
2118 // Clipping-Bereichs am Anfang
2120 WriteOpcode_ClipRect( aRect );
2124 void PictWriter::UpdateHeader()
2126 ULONG nPos;
2128 // Lo-16-Bits der Groesse der Datei ohne die 512 Bytes Muell berichtigen:
2129 nPos=pPict->Tell();
2130 pPict->Seek(512);
2131 *pPict << (USHORT)((nPos-512)&0x0000ffff);
2132 pPict->Seek(nPos);
2136 BOOL PictWriter::WritePict(const GDIMetaFile & rMTF, SvStream & rTargetStream, FilterConfigItem* pFilterConfigItem )
2138 PictWriterAttrStackMember* pAt;
2139 MapMode aMap72( MAP_INCH );
2140 Fraction aDPIFrac( 1, 72 );
2142 bStatus=TRUE;
2143 nLastPercent=0;
2145 if ( pFilterConfigItem )
2147 xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
2148 if ( xStatusIndicator.is() )
2150 rtl::OUString aMsg;
2151 xStatusIndicator->start( aMsg, 100 );
2155 pPict=&rTargetStream;
2156 pPict->SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN);
2158 aLineColor=Color( COL_BLACK );
2159 aFillColor=Color( COL_WHITE );
2160 eSrcRasterOp=ROP_OVERPAINT;
2161 aSrcFont=Font();
2162 aSrcMapMode = rMTF.GetPrefMapMode();
2164 aMap72.SetScaleX( aDPIFrac );
2165 aMap72.SetScaleY( aDPIFrac );
2166 aTargetMapMode = aMap72;
2168 pAttrStack=NULL;
2170 bDstBkPatValid=FALSE;
2171 bDstTxFaceValid=FALSE;
2172 bDstTxModeValid=FALSE;
2173 bDstPnSizeValid=FALSE;
2174 bDstPnModeValid=FALSE;
2175 bDstPnPatValid=FALSE;
2176 bDstFillPatValid=FALSE;
2177 bDstTxSizeValid=FALSE;
2178 bDstFgColValid=FALSE;
2179 bDstBkColValid=FALSE;
2180 bDstPenPositionValid=FALSE;
2181 bDstTextPositionValid=FALSE;
2182 bDstFontNameValid=FALSE;
2184 nNumberOfActions=0;
2185 nNumberOfBitmaps=0;
2186 nWrittenActions=0;
2187 nWrittenBitmaps=0;
2188 nActBitmapPercent=0;
2190 CountActionsAndBitmaps(rMTF);
2192 WriteHeader(rMTF);
2193 WriteOpcodes(rMTF);
2194 WriteOpcode_EndOfFile();
2195 UpdateHeader();
2197 while (pAttrStack!=NULL) {
2198 pAt=pAttrStack;
2199 pAttrStack=pAt->pSucc;
2200 delete pAt;
2203 if ( xStatusIndicator.is() )
2204 xStatusIndicator->end();
2206 return bStatus;
2209 //================== GraphicExport - die exportierte Funktion ================
2211 extern "C" BOOL __LOADONCALLAPI GraphicExport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem* pFilterConfigItem, BOOL)
2213 PictWriter aPictWriter;
2215 if (rGraphic.GetType()==GRAPHIC_GDIMETAFILE)
2217 GDIMetaFile aScaledMtf( rGraphic.GetGDIMetaFile() );
2220 MapMode aMap72( MAP_INCH );
2221 Fraction aDPIFrac( 1, 72 );
2222 Size aOldSize = aScaledMtf.GetPrefSize();
2224 aMap72.SetScaleX( aDPIFrac );
2225 aMap72.SetScaleY( aDPIFrac );
2227 Size aNewSize = OutputDevice::LogicToLogic( aOldSize,
2228 aScaledMtf.GetPrefMapMode(),
2229 aMap72 );
2231 aScaledMtf.Scale( Fraction( aNewSize.Width(), aOldSize.Width() ),
2232 Fraction( aNewSize.Height(), aOldSize.Height() ) );
2233 aScaledMtf.SetPrefMapMode( aMap72 );
2234 aScaledMtf.SetPrefSize( aNewSize );
2237 return aPictWriter.WritePict( aScaledMtf, rStream, pFilterConfigItem );
2239 else
2241 Bitmap aBmp=rGraphic.GetBitmap();
2242 GDIMetaFile aMTF;
2243 VirtualDevice aVirDev;
2245 aMTF.Record(&aVirDev);
2246 aVirDev.DrawBitmap(Point(),aBmp);
2247 aMTF.Stop();
2248 aMTF.SetPrefSize(aBmp.GetSizePixel());
2249 return aPictWriter.WritePict( aMTF, rStream, pFilterConfigItem );
2253 //================== GraphicDialog - die exportierte Funktion ================
2255 extern "C" BOOL SAL_CALL DoExportDialog( FltCallDialogParameter& rPara )
2257 BOOL bRet = FALSE;
2259 if ( rPara.pWindow )
2261 ByteString aResMgrName( "ept" );
2262 ResMgr* pResMgr;
2264 pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
2266 if( pResMgr )
2268 rPara.pResMgr = pResMgr;
2269 bRet = ( DlgExportEPCT( rPara ).Execute() == RET_OK );
2270 delete pResMgr;
2272 else
2273 bRet = TRUE;
2276 return bRet;
2280 //=============================== fuer Windows ==============================
2281 #ifndef GCC
2282 #endif
2284 #ifdef WIN
2286 static HINSTANCE hDLLInst = 0; // HANDLE der DLL
2288 extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR )
2290 #ifndef WNT
2291 if ( nHeap )
2292 UnlockData( 0 );
2293 #endif
2295 hDLLInst = hDLL;
2297 return TRUE;
2300 extern "C" int CALLBACK WEP( int )
2302 return 1;
2305 #endif