merge the formfield patch from ooo-build
[ooovba.git] / goodies / source / filter.vcl / eos2met / eos2met.cxx
blobace201905d18d18aec973a4ea950f049e2d1abac
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: eos2met.cxx,v $
10 * $Revision: 1.21 $
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 <svtools/fltcall.hxx>
36 #include <math.h>
37 #include <tools/stream.hxx>
38 #include <tools/bigint.hxx>
39 #include <vcl/metaact.hxx>
40 #include <vcl/salbtype.hxx>
41 #include <tools/poly.hxx>
42 #include <vcl/graph.hxx>
43 #include <vcl/gradient.hxx>
44 #include <vcl/hatch.hxx>
45 #include <vcl/metric.hxx>
46 #include <vcl/font.hxx>
47 #include <vcl/virdev.hxx>
48 #include <vcl/svapp.hxx>
49 #include <vcl/msgbox.hxx>
50 #include <svtools/solar.hrc>
51 #include "strings.hrc"
52 #include "dlgeos2.hxx"
54 // -----------------------------Feld-Typen-------------------------------
56 #define BegDocumnMagic 0xA8A8 /* Begin Document */
57 #define EndDocumnMagic 0xA8A9 /* End Document */
59 #define BegResGrpMagic 0xC6A8 /* Begin Resource Group */
60 #define EndResGrpMagic 0xC6A9 /* End Resource Group */
62 #define BegColAtrMagic 0x77A8 /* Begin Color Attribute Table */
63 #define EndColAtrMagic 0x77A9 /* End Color Attribute Table */
64 #define BlkColAtrMagic 0x77B0 /* Color Attribute Table */
65 #define MapColAtrMagic 0x77AB /* Map Color Attribute Table */
67 #define BegImgObjMagic 0xFBA8 /* Begin Image Object */
68 #define EndImgObjMagic 0xFBA9 /* End Image Object */
69 #define DscImgObjMagic 0xFBA6 /* Image Data Descriptor */
70 #define DatImgObjMagic 0xFBEE /* Image Picture Data */
72 #define BegObjEnvMagic 0xC7A8 /* Begin Object Environment Group */
73 #define EndObjEnvMagic 0xC7A9 /* End Object Environment Group */
75 #define BegGrfObjMagic 0xBBA8 /* Begin Graphics Object */
76 #define EndGrfObjMagic 0xBBA9 /* End Graphics Object */
77 #define DscGrfObjMagic 0xBBA6 /* Graphics Data Descritor */
78 #define DatGrfObjMagic 0xBBEE /* Graphics Data */
80 #define MapCodFntMagic 0x8AAB /* Map Coded Font */
81 #define MapDatResMagic 0xC3AB /* Map Data Resource */
83 // Struktur des Metafiles
84 // BegDocumn
85 // BegResGrp
86 // BegColAtr
87 // BlkColAtr
88 // EndColAtr
89 // BegImgObj[0..n]
90 // BegResGrp[]
91 // BegColAtr[]
92 // BlkColAtr
93 // EndColAtr
94 // EndResGrp
95 // BegObjEnv[]
96 // MapColAtr
97 // EndObjEnv
98 // DscImgObj
99 // DatImgOb1
100 // DatImgOb2[1..n]
101 // EndImgObj
102 // BegGrfObj
103 // BegObjEnv[]
104 // MapColAtr
105 // MapCodFnt1
106 // MapCodFnt2[0..n]
107 // MapDatRes[0..n]
108 // EndObjEnv
109 // DscGrfObj
110 // DatGrfObj[0..n]
111 // EndGrfObj
112 // EndResGrp
113 // EndDocumn
115 //============================== METWriter ===================================
117 struct METChrSet
119 struct METChrSet * pSucc;
120 BYTE nSet;
121 String aName;
122 FontWeight eWeight;
125 struct METGDIStackMember
127 struct METGDIStackMember * pSucc;
128 Color aLineColor;
129 Color aFillColor;
130 RasterOp eRasterOp;
131 Font aFont;
132 MapMode aMapMode;
133 Rectangle aClipRect;
136 class METWriter
138 private:
140 BOOL bStatus;
141 ULONG nLastPercent; // Mit welcher Zahl pCallback zuletzt aufgerufen wurde.
142 SvStream* pMET;
143 Rectangle aPictureRect;
144 MapMode aPictureMapMode;
145 MapMode aTargetMapMode;
146 ULONG nActualFieldStartPos; // Anfangs-Position des aktuellen 'Field'
147 ULONG nNumberOfDataFields; // Anzahl der angefangenen 'Graphcis Data Fields'
148 Color aGDILineColor;
149 Color aGDIFillColor;
150 RasterOp eGDIRasterOp;
151 Font aGDIFont;
152 MapMode aGDIMapMode; // derzeit unbenutzt!
153 Rectangle aGDIClipRect; // derzeit unbenutzt!
154 METGDIStackMember* pGDIStack;
155 Color aMETColor;
156 Color aMETBackgroundColor;
157 Color aMETPatternSymbol;
158 RasterOp eMETMix ;
159 long nMETStrokeLineWidth;
160 Size aMETChrCellSize;
161 short nMETChrAngle;
162 BYTE nMETChrSet;
163 METChrSet* pChrSetList; // Liste der Character-Sets
164 BYTE nNextChrSetId; // die erste unbenutzte ChrSet-Id
165 ULONG nActBitmapId; // Field-Id der naechsten Bitmap
166 ULONG nNumberOfActions; // Anzahl der Actions im GDIMetafile
167 ULONG nNumberOfBitmaps; // Anzahl der Bitmaps
168 ULONG nWrittenActions; // Anzahl der bereits verarbeiteten Actions beim Schreiben der Orders
169 ULONG nWrittenBitmaps; // Anzahl der bereits geschriebenen Bitmaps
170 ULONG nActBitmapPercent; // Wieviel Prozent die naechste Bitmap schon geschrieben ist.
172 com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;
174 void MayCallback();
175 // Berechnet anhand der obigen 5 Parameter eine Prozentzahl
176 // und macht dann ggf. einen Callback. Setzt bStatus auf FALSE wenn User abbrechen
177 // moechte.
179 void CountActionsAndBitmaps(const GDIMetaFile * pMTF);
180 // Zaehlt die Bitmaps und Actions (nNumberOfActions und nNumberOfBitmaps muessen
181 // zu Anfang auf 0 gesetzt werden, weil diese Methode rekursiv ist)
183 void WriteBigEndianShort(USHORT nWord);
184 void WriteBigEndianLong(ULONG nLong);
186 void WritePoint(Point aPt);
187 void WriteClipRect( const Rectangle& rRect );
188 void WriteFieldIntroducer(USHORT nFieldSize, USHORT nFieldType,
189 BYTE nFlags, USHORT nSegSeqNum);
190 void UpdateFieldSize();
192 void WriteFieldId(ULONG nId);
194 void CreateChrSets(const GDIMetaFile * pMTF);
195 void CreateChrSet(const Font & rFont);
196 void WriteChrSets();
197 BYTE FindChrSet(const Font & rFont);
199 void WriteColorAttributeTable(ULONG nFieldId=4, BitmapPalette* pPalette=NULL,
200 BYTE nBasePartFlags=0x40, BYTE nBasePartLCTID=0);
202 void WriteImageObject(const Bitmap & rBitmap);
203 void WriteImageObjects(const GDIMetaFile * pMTF);
205 void WriteDataDescriptor(const GDIMetaFile * pMTF);
207 void WillWriteOrder(ULONG nNextOrderMaximumLength);
209 void METSetAndPushLineInfo( const LineInfo& rLineInfo );
210 void METPopLineInfo( const LineInfo& rLineInfo );
211 void METBitBlt(Point aPt, Size aSize, const Bitmap & rBitmap);
212 void METBeginArea(BOOL bBoundaryLine);
213 void METEndArea();
214 void METBeginPath(sal_uInt32 nPathId);
215 void METEndPath();
216 void METFillPath(sal_uInt32 nPathId);
217 void METOutlinePath(sal_uInt32 nPathId);
218 void METCloseFigure();
219 void METMove(Point aPt);
220 void METLine(Point aPt1, Point aPt2);
221 void METLine(const Polygon & rPolygon);
222 void METLine(const PolyPolygon & rPolyPolygon);
223 void METLineAtCurPos(Point aPt);
224 void METBox(BOOL bFill, BOOL bBoundary,
225 Rectangle aRect, sal_uInt32 nHAxis, sal_uInt32 nVAxis);
226 void METFullArc(Point aCenter, double fMultiplier);
227 void METPartialArcAtCurPos(Point aCenter, double fMultiplier,
228 double fStartAngle, double fSweepAngle);
229 void METChrStr(Point aPt, String aStr);
230 void METSetArcParams(long nP, long nQ, long nR, long nS);
231 void METSetColor(Color aColor);
232 void METSetBackgroundColor(Color aColor);
233 void METSetMix(RasterOp eROP);
234 void METSetChrCellSize(Size aSize);
235 void METSetChrAngle(short nAngle);
236 void METSetChrSet(BYTE nSet);
238 void WriteOrders(const GDIMetaFile * pMTF);
240 void WriteObjectEnvironmentGroup(const GDIMetaFile * pMTF);
242 void WriteGraphicsObject(const GDIMetaFile * pMTF);
244 void WriteResourceGroup(const GDIMetaFile * pMTF);
246 void WriteDocument(const GDIMetaFile * pMTF);
248 public:
250 METWriter() {}
252 BOOL WriteMET( const GDIMetaFile & rMTF, SvStream & rTargetStream,
253 FilterConfigItem* pConfigItem );
257 //========================== Methoden von METWriter ==========================
259 void METWriter::MayCallback()
261 if ( xStatusIndicator.is() )
263 ULONG nPercent;
264 nPercent=((nWrittenBitmaps<<14)+(nActBitmapPercent<<14)/100+nWrittenActions)
265 *100/((nNumberOfBitmaps<<14)+nNumberOfActions);
267 if (nPercent>=nLastPercent+3)
269 nLastPercent = nPercent;
270 if ( nPercent <= 100 )
271 xStatusIndicator->setValue( nPercent );
276 void METWriter::WriteClipRect( const Rectangle& rRect )
278 aGDIClipRect = rRect;
279 sal_uInt32 nPathId = ( rRect.IsEmpty() ) ? 0 : 1;
280 if ( nPathId )
282 Polygon aPoly( rRect );
283 METBeginPath( nPathId );
284 METLine( aPoly );
285 METEndPath();
287 WillWriteOrder(8);
288 *pMET << (BYTE)0xb4 << (BYTE)6
289 << (BYTE)0x00 << (BYTE)0 << nPathId;
292 void METWriter::CountActionsAndBitmaps(const GDIMetaFile * pMTF)
294 const MetaAction* pMA;
296 for( ULONG nAction = 0, nActionCount=pMTF->GetActionCount(); nAction < nActionCount; nAction++ )
298 pMA = pMTF->GetAction(nAction);
300 switch (pMA->GetType())
302 case META_EPS_ACTION :
304 const GDIMetaFile aGDIMetaFile( ((const MetaEPSAction*)pMA)->GetSubstitute() );
305 INT32 nCount = aGDIMetaFile.GetActionCount();
306 INT32 i;
307 for ( i = 0; i < nCount; i++ )
308 if ( ((const MetaAction*)aGDIMetaFile.GetAction( i ))->GetType() == META_BMPSCALE_ACTION )
309 break;
310 if ( i == nCount)
311 break;
313 case META_BMP_ACTION:
314 case META_BMPSCALE_ACTION:
315 case META_BMPSCALEPART_ACTION:
316 case META_BMPEX_ACTION:
317 case META_BMPEXSCALE_ACTION:
318 case META_BMPEXSCALEPART_ACTION:
319 nNumberOfBitmaps++;
320 break;
322 nNumberOfActions++;
327 void METWriter::WriteBigEndianShort(USHORT nWord)
329 *pMET << ((BYTE)(nWord>>8)) << ((BYTE)(nWord&0x00ff));
333 void METWriter::WriteBigEndianLong(ULONG nLong)
335 WriteBigEndianShort((USHORT)(nLong>>16));
336 WriteBigEndianShort((USHORT)(nLong&0x0000ffff));
340 void METWriter::WritePoint(Point aPt)
342 Point aNewPt = OutputDevice::LogicToLogic( aPt, aPictureMapMode, aTargetMapMode );
344 *pMET << (long) ( aNewPt.X() - aPictureRect.Left() )
345 << (long) ( aPictureRect.Bottom() - aNewPt.Y() );
349 void METWriter::WriteFieldIntroducer(USHORT nFieldSize, USHORT nFieldType,
350 BYTE nFlags, USHORT nSegSeqNum)
352 nActualFieldStartPos=pMET->Tell();
353 WriteBigEndianShort(nFieldSize);
354 *pMET << (BYTE)0xd3 << nFieldType << nFlags << nSegSeqNum;
358 void METWriter::UpdateFieldSize()
360 ULONG nPos;
362 nPos=pMET->Tell();
363 pMET->Seek(nActualFieldStartPos);
364 WriteBigEndianShort((USHORT)(nPos-nActualFieldStartPos));
365 pMET->Seek(nPos);
369 void METWriter::WriteFieldId(ULONG nId)
371 BYTE nbyte;
372 short i;
374 for (i=1; i<=8; i++) {
375 nbyte= '0' + (BYTE)((nId >> (32-i*4)) & 0x0f);
376 *pMET << nbyte;
381 void METWriter::CreateChrSets(const GDIMetaFile * pMTF)
383 ULONG nAction, nActionCount;
384 const MetaAction * pMA;
386 if (bStatus==FALSE)
387 return;
389 nActionCount=pMTF->GetActionCount();
391 for (nAction=0; nAction<nActionCount; nAction++)
393 pMA = pMTF->GetAction(nAction);
395 switch (pMA->GetType())
397 case META_FONT_ACTION:
399 const MetaFontAction* pA = (const MetaFontAction*) pMA;
400 CreateChrSet( pA->GetFont() );
402 break;
408 void METWriter::CreateChrSet(const Font & rFont)
410 METChrSet * pCS;
412 if ( FindChrSet( rFont ) == 0 )
414 pCS = new METChrSet;
415 pCS->pSucc = pChrSetList; pChrSetList=pCS;
416 pCS->nSet = nNextChrSetId++;
417 pCS->aName = rFont.GetName();
418 pCS->eWeight = rFont.GetWeight();
423 BYTE METWriter::FindChrSet(const Font & rFont)
425 METChrSet* pCS;
427 for (pCS=pChrSetList; pCS!=NULL; pCS=pCS->pSucc)
429 if (pCS->aName==rFont.GetName() && pCS->eWeight==rFont.GetWeight() )
430 return pCS->nSet;
433 return 0;
437 void METWriter::WriteChrSets()
439 USHORT i;
440 char c = 0;
441 METChrSet * pCS;
442 BYTE nbyte;
444 for (pCS=pChrSetList; pCS!=NULL; pCS=pCS->pSucc)
447 WriteFieldIntroducer(0x58,MapCodFntMagic,0,0);
449 WriteBigEndianShort(0x0050);
451 *pMET << (BYTE)0x0c << (BYTE)0x02 << (BYTE)0x84 << (BYTE)0x00;
452 *pMET << (BYTE)0xa4 << (BYTE)0x00 << (BYTE)0x00 << (BYTE)0x01;
453 *pMET << (BYTE)0x01 << (BYTE)0x00 << (BYTE)0x00 << (BYTE)0x00;
455 *pMET << (BYTE)0x04 << (BYTE)0x24 << (BYTE)0x05 << (BYTE)pCS->nSet;
457 *pMET << (BYTE)0x14 << (BYTE)0x1f;
458 switch (pCS->eWeight)
460 case WEIGHT_THIN: nbyte=1; break;
461 case WEIGHT_ULTRALIGHT: nbyte=2; break;
462 case WEIGHT_LIGHT: nbyte=3; break;
463 case WEIGHT_SEMILIGHT: nbyte=4; break;
464 case WEIGHT_NORMAL: nbyte=5; break;
465 case WEIGHT_SEMIBOLD: nbyte=6; break;
466 case WEIGHT_BOLD: nbyte=7; break;
467 case WEIGHT_ULTRABOLD: nbyte=8; break;
468 case WEIGHT_BLACK: nbyte=9; break;
469 default: nbyte=5;
471 *pMET << nbyte;
472 *pMET << (BYTE)0x05;
473 *pMET << (BYTE)0x00 << (BYTE)0x00 << (BYTE)0x00 << (BYTE)0x00;
474 *pMET << (BYTE)0x00 << (BYTE)0x00 << (BYTE)0x00 << (BYTE)0x00;
475 *pMET << (BYTE)0x00 << (BYTE)0x00 << (BYTE)0x00 << (BYTE)0x00;
476 *pMET << (BYTE)0x00 << (BYTE)0x00 << (BYTE)0x00 << (BYTE)0x0c;
478 *pMET << (BYTE)0x06 << (BYTE)0x20 << (BYTE)0x03 << (BYTE)0xd4;
479 *pMET << (BYTE)0x03 << (BYTE)0x52;
481 *pMET << (BYTE)0x24 << (BYTE)0x02 << (BYTE)0x08 << (BYTE)0x00;
482 ByteString n(pCS->aName, gsl_getSystemTextEncoding());
483 for (i=0; i<32; i++)
485 if ( i == 0 || c != 0 )
486 c = n.GetChar( i );
487 *pMET << c;
493 void METWriter::WriteColorAttributeTable(ULONG nFieldId, BitmapPalette* pPalette, BYTE nBasePartFlags, BYTE nBasePartLCTID)
495 USHORT nIndex,nNumI,i;
497 if (bStatus==FALSE) return;
499 //--- Das Feld 'Begin Color Attribute Table':
500 WriteFieldIntroducer(16,BegColAtrMagic,0,0);
501 WriteFieldId(nFieldId);
503 //--- Das Feld 'Color Attribute Table':
504 WriteFieldIntroducer(0,BlkColAtrMagic,0,0);
505 *pMET << nBasePartFlags << (BYTE)0x00 << nBasePartLCTID; // 'Base Part'
506 if (pPalette!=NULL)
508 nIndex=0;
509 while (nIndex<pPalette->GetEntryCount())
511 nNumI=pPalette->GetEntryCount()-nIndex;
512 if (nNumI>81) nNumI=81;
513 *pMET << (BYTE)(11+nNumI*3); // Laenge des Parameters
514 *pMET << (BYTE)1 << (BYTE)0 << (BYTE)1; // typ: element list, Reserved, Format: RGB
515 *pMET << (BYTE)0; WriteBigEndianShort(nIndex); // Start-Index (3 Bytes)
516 *pMET << (BYTE)8 << (BYTE)8 << (BYTE)8; // Bits je Komponente R,G,B
517 *pMET << (BYTE)3; // Anzahl Bytes je Eintrag
518 for (i=0; i<nNumI; i++)
520 const BitmapColor& rCol = (*pPalette)[ nIndex ];
522 *pMET << (BYTE) rCol.GetRed();
523 *pMET << (BYTE) rCol.GetGreen();
524 *pMET << (BYTE) rCol.GetBlue();
525 nIndex++;
529 else
531 // 'Trible Generating'
532 *pMET << (BYTE)0x0a << (BYTE)0x02 << (BYTE)0x00 << (BYTE)0x01 << (BYTE)0x00;
533 *pMET << (BYTE)0x00 << (BYTE)0x00 << (BYTE)0x08 << (BYTE)0x08 << (BYTE)0x08;
535 UpdateFieldSize();
537 //--- Das Feld 'End Color Attribute Table':
538 WriteFieldIntroducer(16,EndColAtrMagic,0,0);
539 WriteFieldId(nFieldId);
541 if (pMET->GetError())
542 bStatus=FALSE;
546 void METWriter::WriteImageObject(const Bitmap & rBitmap)
548 SvMemoryStream aTemp(0x00010000,0x00010000);
549 sal_uInt32 nWidth,nHeight,nResX,nResY;
550 ULONG nBytesPerLine,i,j,nNumColors,ny,nLines;
551 ULONG nActColMapId;
552 USHORT nBitsPerPixel;
553 BYTE nbyte, * pBuf;
555 if (bStatus==FALSE)
556 return;
558 nActColMapId=((nActBitmapId>>24)&0x000000ff) | ((nActBitmapId>> 8)&0x0000ff00) |
559 ((nActBitmapId<< 8)&0x00ff0000) | ((nActBitmapId<<24)&0xff000000);
561 //--- Das Feld 'Begin Image Object':
562 WriteFieldIntroducer(16,BegImgObjMagic,0,0);
563 WriteFieldId(nActBitmapId);
565 // Windows-BMP-Datei erzeugen:
566 aTemp << rBitmap;
568 // Header der Windows-BMP-Datei einlesen:
569 aTemp.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
570 aTemp.Seek(18);
571 aTemp >> nWidth >> nHeight;
572 aTemp.SeekRel(2);
573 aTemp >> nBitsPerPixel;
574 aTemp.SeekRel(8);
575 aTemp >> nResX >> nResY;
576 aTemp.SeekRel(8);
578 nNumColors=1<<nBitsPerPixel;
579 nBytesPerLine=((nWidth*nBitsPerPixel+0x0000001f) & 0xffffffe0 ) >> 3;
581 // ggf. Farbpalette einlesen und in die MET-Datei schreiben:
582 if (nBitsPerPixel<=8)
584 BitmapPalette aPal( (USHORT) nNumColors );
585 BYTE nr,ng,nb;
587 for (i=0; i<nNumColors; i++)
589 aTemp >> nb >> ng >> nr; aTemp.SeekRel(1);
590 aPal[ (USHORT) i ] = BitmapColor( nr, ng, nb );
593 //--- Das Feld 'Begin Resource Group':
594 WriteFieldIntroducer(16,BegResGrpMagic,0,0);
595 WriteFieldId(nActColMapId);
597 //--- Farbtabelle schreiben:
598 WriteColorAttributeTable(nActColMapId,&aPal,0,1);
600 //--- Das Feld 'End Resource Group':
601 WriteFieldIntroducer(16,EndResGrpMagic,0,0);
602 WriteFieldId(nActColMapId);
604 //--- Das Feld 'Begin Object Environment Group':
605 WriteFieldIntroducer(16,BegObjEnvMagic,0,0);
606 WriteFieldId(nActBitmapId);
608 //--- Das Feld 'Map Color Attribute Table':
609 WriteFieldIntroducer(26,MapColAtrMagic,0,0);
610 WriteBigEndianShort(0x0012);
611 *pMET << (BYTE)0x0c << (BYTE)0x02 << (BYTE)0x84 << (BYTE)0x00;
612 WriteFieldId(nActColMapId);
613 *pMET << (BYTE)0x04 << (BYTE)0x24 << (BYTE)0x07 << (BYTE)0x01;
615 //--- Das Feld 'End Object Environment Group':
616 WriteFieldIntroducer(16,EndObjEnvMagic,0,0);
617 WriteFieldId(nActBitmapId);
620 //--- Das Feld 'Image Data Descriptor':
621 WriteFieldIntroducer(17,DscImgObjMagic,0,0);
622 *pMET << (BYTE)0x01; // Unit of measure: tens of centimeters
623 WriteBigEndianShort((USHORT)nResX);
624 WriteBigEndianShort((USHORT)nResY);
625 WriteBigEndianShort((USHORT)nWidth);
626 WriteBigEndianShort((USHORT)nHeight);
628 //--- Das erste Feld 'Image Picture Data':
629 WriteFieldIntroducer(0,DatImgObjMagic,0,0);
631 // Begin Segment:
632 *pMET << (BYTE)0x70 << (BYTE)0x00;
634 // Begin Image Content:
635 *pMET << (BYTE)0x91 << (BYTE)0x01 << (BYTE)0xff;
637 // Image Size:
638 *pMET << (BYTE)0x94 << (BYTE)0x09 << (BYTE)0x02;
639 *pMET << (USHORT) 0 << (USHORT) 0;
640 WriteBigEndianShort((USHORT)nHeight);
641 WriteBigEndianShort((USHORT)nWidth);
643 // Image Encoding:
644 *pMET << (BYTE)0x95 << (BYTE)0x02 << (BYTE)0x03 << (BYTE)0x03;
646 // Image IDE-Size:
647 *pMET << (BYTE)0x96 << (BYTE)0x01 << (BYTE)nBitsPerPixel;
649 if (nBitsPerPixel<=8) {
650 // Image LUT-ID
651 *pMET << (BYTE)0x97 << (BYTE)0x01 << (BYTE)0x01;
653 else {
654 // IDE Structure
655 *pMET << (BYTE)0x9b << (BYTE)0x08 << (BYTE)0x00 << (BYTE)0x01;
656 *pMET << (BYTE)0x00 << (BYTE)0x00 << (BYTE)0x00 << (BYTE)0x08;
657 *pMET << (BYTE)0x08 << (BYTE)0x08;
660 pBuf=new BYTE[nBytesPerLine];
661 ny=0;
662 while (ny<nHeight) {
664 // Abschliessen des vorherigen Feldes 'Image Picture Data':
665 UpdateFieldSize();
667 // Und ein neues Feld 'Image Picture Data' anfangen:
668 WriteFieldIntroducer(0,DatImgObjMagic,0,0);
670 // Einige Scanlines lesen und schreiben:
671 nLines=nHeight-ny;
672 if (nLines*nBytesPerLine>30000) nLines=30000/nBytesPerLine;
673 if (nLines<1) nLines=1;
674 WriteBigEndianShort(0xfe92);
675 WriteBigEndianShort((USHORT)(nLines*nBytesPerLine));
676 for (i=0; i<nLines; i++) {
677 aTemp.Read(pBuf,nBytesPerLine);
678 if (nBitsPerPixel==24) {
679 for (j=2; j<nBytesPerLine; j+=3) {
680 nbyte=pBuf[j]; pBuf[j]=pBuf[j-2]; pBuf[j-2]=nbyte;
683 pMET->Write(pBuf,nBytesPerLine);
684 ny++;
686 if (aTemp.GetError() || pMET->GetError()) bStatus=FALSE;
687 nActBitmapPercent=(ny+1)*100/nHeight;
688 MayCallback();
689 if (bStatus==FALSE) { delete[] pBuf; return; }
691 delete[] pBuf;
693 // End Image Content:
694 *pMET << (BYTE)0x93 << (BYTE)0x00;
696 // End Segment:
697 *pMET << (BYTE)0x71 << (BYTE)0x00;
699 // Abschliessen des letzten Feldes 'Image Picture Data':
700 UpdateFieldSize();
702 //--- Das Feld 'End Image Object':
703 WriteFieldIntroducer(16,EndImgObjMagic,0,0);
704 WriteFieldId(nActBitmapId);
706 // Ids erhoehen:
707 nActBitmapId++;
709 // Bitmaps zaehlen:
710 nWrittenBitmaps++;
711 nActBitmapPercent=0;
713 if (pMET->GetError()) bStatus=FALSE;
717 void METWriter::WriteImageObjects(const GDIMetaFile * pMTF)
719 const MetaAction* pMA;
721 if (bStatus==FALSE)
722 return;
724 for ( ULONG nAction = 0, nActionCount = pMTF->GetActionCount(); nAction < nActionCount; nAction++)
726 pMA = pMTF->GetAction(nAction);
728 switch (pMA->GetType())
730 case META_BMP_ACTION:
732 METSetMix( eGDIRasterOp );
733 WriteImageObject( ( (MetaBmpAction*) pMA )->GetBitmap() );
735 break;
737 case META_BMPSCALE_ACTION:
739 METSetMix( eGDIRasterOp );
740 WriteImageObject( ( (MetaBmpScaleAction*) pMA )->GetBitmap() );
742 break;
744 case META_BMPSCALEPART_ACTION:
746 METSetMix( eGDIRasterOp );
747 WriteImageObject( ( (MetaBmpScalePartAction*) pMA )->GetBitmap() );
749 break;
751 case META_BMPEX_ACTION:
753 METSetMix( eGDIRasterOp );
754 WriteImageObject( Graphic( ( (MetaBmpExAction*) pMA )->GetBitmapEx() ).GetBitmap() );
756 break;
758 case META_BMPEXSCALE_ACTION:
760 METSetMix( eGDIRasterOp );
761 WriteImageObject( Graphic( ( (MetaBmpExScaleAction*) pMA )->GetBitmapEx() ).GetBitmap() );
763 break;
765 case META_BMPEXSCALEPART_ACTION:
767 METSetMix( eGDIRasterOp );
768 WriteImageObject( Graphic( ( (MetaBmpExScalePartAction*) pMA )->GetBitmapEx() ).GetBitmap() );
770 break;
772 case META_EPS_ACTION :
774 const MetaEPSAction* pA = (const MetaEPSAction*)pMA;
775 const GDIMetaFile aGDIMetaFile( pA->GetSubstitute() );
777 INT32 nCount = aGDIMetaFile.GetActionCount();
778 for ( INT32 i = 0; i < nCount; i++ )
780 const MetaAction* pMetaAct = aGDIMetaFile.GetAction( i );
781 if ( pMetaAct->GetType() == META_BMPSCALE_ACTION )
783 const MetaBmpScaleAction* pBmpScaleAction = (const MetaBmpScaleAction*)pMetaAct;
784 METSetMix( eGDIRasterOp );
785 WriteImageObject( pBmpScaleAction->GetBitmap() );
786 break;
790 break;
793 if (bStatus==FALSE)
794 break;
797 if (pMET->GetError())
798 bStatus=FALSE;
801 void METWriter::WriteDataDescriptor(const GDIMetaFile *)
803 if (bStatus==FALSE)
804 return;
806 WriteFieldIntroducer(0,DscGrfObjMagic,0,0);
808 //------------------------------------------------------------------------------
809 // Im Folgenden die OS2-Orginal-Dokumentation und die Implementation dazu (uff)
810 //------------------------------------------------------------------------------
812 // Parameters (all required and in this order)
814 // 0 0xF7 Specify GVM Subset
815 // 1 Length of following data 0x07
816 // 2 0xB0 drawing order subset
817 // 3-4 0x0000
818 // 5 0x23 Level 3.2
819 // 6 0x01 Version 1
820 // 7 Length of following field 0x01
821 // 8 Coordinate types in data
822 // 0x04Intel16
823 // 0x05Intel32
824 *pMET << (BYTE)0xf7 << (BYTE)0x07 << (BYTE)0xb0 << (BYTE)0x00
825 << (BYTE)0x00 << (BYTE)0x23 << (BYTE)0x01 << (BYTE)0x01
826 << (BYTE)0x05;
828 // 0 0xF6 Set Picture Descriptor
829 // 1 Length of following data
830 // 2 Flags
831 // 0 B'0' Picture in 2D
832 // 1 Picture Dimensions
833 // B'0' Not absolute (PU_ARBITRARY PS)
834 // B'1' Absolute (example: PU_TWIPS PS)
835 // 2 Picture Elements
836 // B'0' Not pels
837 // B'1' Pels (PU_PELS PS)
838 // (Bit 1 must also be set)
839 // 3-7 B'00000'
840 // 3 0x00 Reserved
841 // 4 Picture frame size coordinate type
842 // 0x04 Intel16
843 // 0x05 Intel32
844 // 5 UnitsOfMeasure
845 // 0x00 Ten inches
846 // 0x01 Decimeter
847 // 6-11 or 6-17(2 or 4 bytes) Resolution.
848 // GPS Units / UOM on x axis
849 // GPS Units / UOM on y axis
850 // GPS Units / UOM on z axis
851 // 12-23 or 18-41(2 or 4 bytes) Window Size.
852 // GPS X left, X right
853 // GPS Y bottom, Y top
854 // GPS Z near, Z far
855 Size aUnitsPerDecimeter=OutputDevice::LogicToLogic(Size(10,10),MapMode(MAP_CM),aPictureMapMode);
856 *pMET << (BYTE)0xf6 << (BYTE)0x28 << (BYTE)0x40 << (BYTE)0x00
857 << (BYTE)0x05 << (BYTE)0x01
858 << (sal_uInt32)(aUnitsPerDecimeter.Width())
859 << (sal_uInt32)(aUnitsPerDecimeter.Height())
860 << (sal_uInt32)0
861 << (sal_uInt32)0 << (sal_uInt32)aPictureRect.GetWidth()
862 << (sal_uInt32)0 << (sal_uInt32)aPictureRect.GetHeight()
863 << (sal_uInt32)0 << (sal_uInt32)0;
865 // 0 0x21 Set Current Defaults
866 // 1 Length of following data
867 // 2 Set Default Parameter Format 0x08
868 // 3-4 Mask 0xE000
869 // 5 Names 0x8F
870 // 6 Coordinates
871 // 0x00 Picture in 2D
872 // 7 Transforms
873 // 0x04 Intel16
874 // 0x05 Intel32
875 // 8 Geometrics
876 // 0x04 Intel16
877 // 0x05 Intel32
878 *pMET << (BYTE)0x21 << (BYTE)0x07 << (BYTE)0x08 << (BYTE)0xe0
879 << (BYTE)0x00 << (BYTE)0x8f << (BYTE)0x00 << (BYTE)0x05
880 << (BYTE)0x05;
882 // 0 0x21 Set Current Defaults
883 // 1 Length of following data
884 // 2 Set default viewing transform 0x07
885 // 3-4 Mask 0xCC0C
886 // 5 Names 0x8F
887 // 6-n M11, M12, M21, M22, M41, M42 Matrix elements
888 *pMET << (BYTE)0x21 << (BYTE)0x1c << (BYTE)0x07 << (BYTE)0xcc
889 << (BYTE)0x0c << (BYTE)0x8f
890 << (sal_uInt32)0x00010000 << (sal_uInt32)0x00000000 << (sal_uInt32)0x00000000
891 << (sal_uInt32)0x00010000 << (sal_uInt32)0x00000000 << (sal_uInt32)0x00000000;
893 // 0 0x21 Set Current Defaults
894 // 1 Length of following data
895 // 2 Set default line attributes 0x01
896 // 3-4 Mask - OR of as many of the following bits as are required:
897 // 0x8000 Line type
898 // 0x4000 Line width
899 // 0x2000 Line end
900 // 0x1000 Line join
901 // 0x0800 Stroke width
902 // 0x0008 Line color
903 // 0x0002 Line mix
904 // 5 Flags
906 // 0x0F Set indicated default attributes to initial values. (Data field is not present in this
907 // instance).
908 // 0x8F Set indicated default attributes to specified values.
909 // 6-n Data - data values as required, in the following order if present.
910 // No space is reserved for attributes for which the corresponding mask flag was not
911 // set.
913 // (1 byte) - Line type
914 // (1 byte) - Line width
915 // (1 byte) - Line end
916 // (1 byte) - Line join
917 // (G bytes) - Stroke width
918 // (4 bytes) - Line color
919 // (1 byte) - Line mix (G=2 or 4 depending on the Geometrics parameter of Set Default
920 // Parameter Format)
921 // Nanu! witziger-weise fehlt obiger Abschnitt in den Metadateien. Also lassen wir ihn auch weg
923 // 0 0x21 Set Current Defaults
924 // 1 Length of following data
925 // 2 Set Default Character Attributes 0x02
926 // 3-4 Mask - OR of as many of the following bits as are required:
928 // 0x8000 Character angle
929 // 0x4000 Character box
930 // 0x2000 Character direction
931 // 0x1000 Character precision
932 // 0x0800 Character set
933 // 0x0400 Character shear
934 // 0x0040 Character break extra
935 // 0x0020 Character extra
936 // 0x0008 Character color
937 // 0x0004 Character background color
938 // 0x0002 Character mix
939 // 0x0001 Character background mix
940 // 5 Flags
941 // 0x0FSet indicated default attributes to initial values. (Data field is not present in this
942 // case).
943 // 0x8FSet indicated default attributes to specified values.
944 // 6-n Data - data values as required, in the following order if present.
945 // No space is reserved for attributes for which the corresponding Mask flag was not
946 // set.
947 // (2*G bytes) - Character angle
948 // (2*G + 4 bytes)- Character box
949 // (1 byte) - Character direction
950 // (1 byte) - Character precision
951 // (1 byte) - Character set
952 // (2*G bytes) - Character shear
953 // (4 bytes) - Character break extra
954 // (4 bytes) - Character extra
955 // (4 bytes) - Character color
956 // (4 bytes) - Character background color
957 // (1 byte) - Character mix
958 // (1 byte) - Character background mix (G=2 or 4 depending on the Geometrics
959 // parameter of Set Default Parameter Format)
960 *pMET << (BYTE)0x21 << (BYTE)0x10 << (BYTE)0x02 << (BYTE)0x40
961 << (BYTE)0x00 << (BYTE)0x8f
962 << (BYTE)0xaa << (BYTE)0x02 << (BYTE)0x00 << (BYTE)0x00
963 << (BYTE)0x44 << (BYTE)0x04 << (BYTE)0x00 << (BYTE)0x00
964 << (BYTE)0xa8 << (BYTE)0xaa << (BYTE)0x40 << (BYTE)0x44;
966 // 0 0x21 Set Current Defaults
967 // 1 Length of following data
968 // 2 Set Default Marker Attributes 0x03
969 // 3-4 Mask - OR of as many of the following bits as are required:
970 // 0x4000 Marker box
971 // 0x1000 Marker precision
972 // 0x0800 Marker set
973 // 0x0100 Marker symbol
974 // 0x0008 Marker color
975 // 0x0004 Marker background color
976 // 0x0002 Marker mix
977 // 0x0001 Marker background mix
978 // 5 Flags
979 // 0x0F Set indicated default attributes to initial values.
980 // (Data field is not present in this instance)
981 // 0x8F Set indicated default attributes to specified values.
982 // 6-n Data - data values as required, in this order if present.
983 // No space is reserved for attributes for which the corresponding Mask flag was not
984 // set.
985 // (2*G bytes) - Marker box
986 // (1 byte) - Marker precision
987 // (1 byte) - Marker set
988 // (1 byte) - Marker symbol
989 // (4 bytes) - Marker color
990 // (4 bytes) - Marker background color
991 // (1 byte) - Marker mix
992 // (1 byte) - Marker background mix (G=2 or 4 depending on the Geometrics
993 // parameter of Set Default Parameter Format)
994 *pMET << (BYTE)0x21 << (BYTE)0x0c << (BYTE)0x03 << (BYTE)0x40
995 << (BYTE)0x00 << (BYTE)0x8f
996 << (BYTE)0x66 << (BYTE)0x02 << (BYTE)0x00 << (BYTE)0x00
997 << (BYTE)0x66 << (BYTE)0x02 << (BYTE)0x00 << (BYTE)0x00;
999 // 0 0x21 Set Current Defaults
1000 // 1 Length of following data
1001 // 2 Set Default Pattern Attributes 0x04
1002 // 3-4 Mask - OR of as many of the following bits as are required:
1003 // 0x0800 Pattern set
1004 // 0x0100 Pattern symbol
1005 // 0x0080 Pattern reference point
1006 // 0x0008 Pattern color
1007 // 0x0004 Pattern background color
1008 // 0x0002 Pattern mix
1009 // 0x0001 Pattern background mix
1010 // 5 Flags
1012 // 0x0F Set indicated default attributes to initial values.
1013 // (Data field is not present in this instance)
1014 // 0x8F Set indicated default attributes to specified values.
1015 // 6-n Data - data values as required, in this order if present.
1016 // No space is reserved for attributes for which the corresponding Mask flag was
1017 // not set.
1019 // (1 byte) - Pattern set
1020 // (1 byte) - Pattern symbol
1021 // (2*G bytes) - Pattern reference point
1022 // (4 bytes) - Pattern color
1023 // (4 bytes) - Pattern background color
1024 // (1 byte) - Pattern mix
1025 // (1 byte) - Pattern background mix (G=2 or 4 depending on the Geometrics
1026 // parameter of Set Default Parameter Format)
1027 // 0 0x21 Set Current Defaults
1028 // 1 Length of following data
1029 // 2 Set Default Image Attributes 0x06
1030 // 3-4 Mask - OR of as many of these bits as are required:
1031 // 0x0008 Image color
1032 // 0x0004 Image background color
1033 // 0x0002 Image mix
1034 // 0x0001 Image background mix
1035 // 5 Flags
1036 // 0x0F Set indicated default attributes to initial values. (Data field is not present in
1037 // this instance)
1038 // 0x8F Set indicated default attributes to specified values.
1039 // 6-n Data - data values as required, in this order if present.
1040 // No space is reserved for attributes for which the corresponding Mask flag was
1041 // not set.
1042 // (4 bytes) - Image color
1043 // (4 bytes) - Image background color
1044 // (1 byte) - Image mix
1045 // (1 byte) - Image background mix
1046 // 0 0x21 Set Current Defaults
1047 // 1 Length of following data
1048 // 2 Set Default Viewing Window 0x05
1049 // 3-4 Mask - OR of as many of the following bits as are required:
1050 // 0x8000 x left limit
1051 // 0x4000 x right limit
1052 // 0x2000 y bottom limit
1053 // 0x1000 y top limit
1054 // 5 Flags
1055 // 0x0F Set indicated default attributes to initial values.
1056 // (Data field is not present in this case).
1057 // 0x8F Set indicated default attributes to specified values.
1058 // 6-n Data - data values as required, in the following order if present.
1059 // No space is reserved for attributes for which the corresponding Mask flag was
1060 // not set.
1061 // (2*G bytes) - x left limit
1062 // (2*G bytes) - x right limit
1063 // (2*G bytes) - y bottom limit
1064 // (2*G bytes) - y top limit (G=2 or 4 depending on the Geometrics parameter of Set
1065 // Default Parameter Format)
1066 // 0 0x21 Set Current Defaults
1067 // 1 Length of following data
1068 // 2 Set Default Arc Parameters 0x0B
1069 // 3-4 Mask - OR of as many of the following bits as are required:
1070 // 0x8000 P value
1071 // 0x4000 Q value
1072 // 0x2000 R value
1073 // 0x1000 S value
1074 // 5 Flags
1075 // 0x0F Set indicated default attributes to initial values.
1076 // (Data field is not present in this case).
1077 // 0x8F Set indicated default attributes to specified values.
1078 // 6-n Data - data values as required, in the following order if present.
1079 // No space is reserved for attributes for which the corresponding Mask flag was
1080 // not set.
1081 // (G bytes) - P value
1082 // (G bytes) - Q value
1083 // (G bytes) - R value
1084 // (G bytes) - S value (G=2 or 4 depending on the Geometrics parameter of Set
1085 // Default Parameter Format)
1086 // 0 0x21 Set Current Defaults
1087 // 1 Length of following data
1088 // 2 Set Default Pick Identifier 0x0C
1089 // 3-4 Mask - OR of as many of the following bits as are required:
1090 // 0x8000 Pick identifier
1091 // 5 Flags
1092 // 0x0F Set indicated default attributes to initial values.
1093 // (Data field is not present in this case).
1094 // 0x8F Set indicated default attributes to specified values.
1095 // 6-n Data - data values as required, in the following order if present.
1096 // No space is reserved for attributes for which the corresponding Mask flag was
1097 // not set.
1098 // (4 bytes) - Pick identifier
1100 // 0 0xE7 Set Bit-map Identifier
1101 // 1 Length of following data 0x07
1102 // 2-3 Usage Flags 0x8000
1103 // 4-7 Bit-map handle
1104 // 8 Lcid
1105 if (nNumberOfBitmaps>0) {
1106 *pMET << (BYTE)0xe7 << (BYTE)0x07 << (BYTE)0x80 << (BYTE)0x00;
1107 WriteBigEndianLong(nActBitmapId);
1108 *pMET << (BYTE)0xfe;
1111 UpdateFieldSize();
1113 if (pMET->GetError()) bStatus=FALSE;
1117 void METWriter::WillWriteOrder(ULONG nNextOrderMaximumLength)
1119 // Die Parameter eines 'Graphics Data Fields' duerfen (laut OS2-Doku)
1120 // hoechstens 32759 Bytes umfassen. Gemeint ist die Laenge des Feldes minus
1121 // dem 'Structured Field Introducer' (groesse: 8). Also darf die Groesse
1122 // des ganzen Fields hoechstens 8+32759=32767=0x7fff sein.
1123 // Zur Sicherheit nehmen wir lieber 30000 als Grenze.
1125 if (pMET->Tell()-nActualFieldStartPos+nNextOrderMaximumLength>30000)
1127 UpdateFieldSize();
1128 WriteFieldIntroducer(0,DatGrfObjMagic,0,0);
1129 nNumberOfDataFields++;
1135 void METWriter::METBitBlt(Point aPt, Size aSize, const Bitmap & rBitmap)
1137 WillWriteOrder(46);
1138 *pMET << (BYTE)0xd6 << (BYTE)44 << (USHORT)0 << (USHORT) 0x00cc;
1139 WriteBigEndianLong(nActBitmapId++);
1140 *pMET << (BYTE)0x02 << (BYTE)0x00 << (BYTE)0x00 << (BYTE)0x00;
1141 WritePoint(Point(aPt.X(),aPt.Y()+aSize.Height()));
1142 WritePoint(Point(aPt.X()+aSize.Width(),aPt.Y()));
1143 *pMET << (sal_uInt32)0 << (sal_uInt32)0
1144 << (sal_uInt32)(rBitmap.GetSizePixel().Width())
1145 << (sal_uInt32)(rBitmap.GetSizePixel().Height());
1148 void METWriter::METSetAndPushLineInfo( const LineInfo& rLineInfo )
1150 INT32 nWidth = OutputDevice::LogicToLogic( Size( rLineInfo.GetWidth(),0 ), aPictureMapMode, aTargetMapMode ).Width();
1152 WillWriteOrder( 8 ); // set stroke linewidth
1153 *pMET << (BYTE)0x15
1154 << (BYTE)6
1155 << (BYTE)0 // Flags
1156 << (BYTE)0
1157 << nWidth;
1159 if ( rLineInfo.GetStyle() != LINE_SOLID )
1161 BYTE nStyle = 0; // LineDefault;
1163 switch ( rLineInfo.GetStyle() )
1165 case LINE_NONE :
1166 nStyle = 8;
1167 break;
1169 case LINE_DASH :
1171 if ( rLineInfo.GetDotCount() )
1173 if ( !rLineInfo.GetDashCount() )
1174 nStyle = 1; // LINE_DOT
1175 else
1176 nStyle = 3; // LINE_DASH_DOT
1178 else
1179 nStyle = 2; // LINE_DASH
1181 break;
1182 case LineStyle_SOLID:
1183 case LineStyle_FORCE_EQUAL_SIZE:
1184 break; // not handled -Wall
1186 WillWriteOrder( 2 );
1187 *pMET << (BYTE)0x18 << nStyle; // set LineType
1191 void METWriter::METPopLineInfo( const LineInfo& rLineInfo )
1193 WillWriteOrder( 8 ); // set stroke linewidth
1194 *pMET << (BYTE)0x15
1195 << (BYTE)6
1196 << (BYTE)0 // Flags
1197 << (BYTE)0
1198 << (UINT32)1;
1200 if ( rLineInfo.GetStyle() != LINE_SOLID )
1202 WillWriteOrder( 2 );
1203 *pMET << (BYTE)0x18 << (BYTE)0; // set LineType
1207 void METWriter::METBeginArea(BOOL bBoundaryLine)
1209 WillWriteOrder(2);
1210 *pMET << (BYTE)0x68;
1211 if (bBoundaryLine) *pMET << (BYTE)0xc0;
1212 else *pMET << (BYTE)0x80;
1216 void METWriter::METEndArea()
1218 WillWriteOrder(2);
1219 *pMET << (BYTE)0x60 << (BYTE)0;
1223 void METWriter::METBeginPath(sal_uInt32 nPathId)
1225 WillWriteOrder(8);
1226 *pMET << (BYTE)0xd0 << (BYTE)6 << (USHORT) 0 << nPathId;
1230 void METWriter::METEndPath()
1232 WillWriteOrder(2);
1233 *pMET << (BYTE)0x7f << (BYTE)0;
1237 void METWriter::METFillPath(sal_uInt32 nPathId)
1239 WillWriteOrder(8);
1240 *pMET << (BYTE)0xd7 << (BYTE)6
1241 << (BYTE)0x00 << (BYTE)0 << nPathId;
1245 void METWriter::METOutlinePath(sal_uInt32 nPathId)
1247 WillWriteOrder(8);
1248 *pMET << (BYTE)0xd4 << (BYTE)6
1249 << (BYTE)0 << (BYTE)0 << nPathId;
1253 void METWriter::METCloseFigure()
1255 WillWriteOrder(2);
1256 *pMET << (BYTE)0x7d << (BYTE)0;
1260 void METWriter::METMove(Point aPt)
1262 WillWriteOrder(10);
1263 *pMET << (BYTE)0x21 << (BYTE)8;
1264 WritePoint(aPt);
1268 void METWriter::METLine(Point aPt1, Point aPt2)
1270 WillWriteOrder(18);
1271 *pMET << (BYTE)0xc1 << (BYTE)16;
1272 WritePoint(aPt1); WritePoint(aPt2);
1276 void METWriter::METLine(const Polygon & rPolygon)
1278 USHORT nNumPoints,i,j,nOrderPoints;
1279 BOOL bFirstOrder;
1281 bFirstOrder=TRUE;
1282 i=0; nNumPoints=rPolygon.GetSize();
1283 while (i<nNumPoints) {
1284 nOrderPoints=nNumPoints-i;
1285 if (nOrderPoints>30) nOrderPoints=30;
1286 WillWriteOrder(nOrderPoints*8+2);
1287 if (bFirstOrder==TRUE) {
1288 *pMET << (BYTE)0xc1; // Line at given pos
1289 bFirstOrder=FALSE;
1291 else {
1292 *pMET << (BYTE)0x81; // Line at current pos
1294 *pMET << (BYTE)(nOrderPoints*8);
1295 for (j=0; j<nOrderPoints; j++) WritePoint(rPolygon.GetPoint(i++));
1300 void METWriter::METLine(const PolyPolygon & rPolyPolygon)
1302 USHORT i,nCount;
1303 nCount=rPolyPolygon.Count();
1304 for (i=0; i<nCount; i++) {
1305 METLine(rPolyPolygon.GetObject(i));
1306 METCloseFigure();
1311 void METWriter::METLineAtCurPos(Point aPt)
1313 WillWriteOrder(10);
1314 *pMET << (BYTE)0x81 << (BYTE)8;
1315 WritePoint(aPt);
1319 void METWriter::METBox(BOOL bFill, BOOL bBoundary,
1320 Rectangle aRect, sal_uInt32 nHAxis, sal_uInt32 nVAxis)
1322 BYTE nFlags=0;
1323 if (bFill) nFlags|=0x40;
1324 if (bBoundary) nFlags|=0x20;
1326 WillWriteOrder(28);
1327 *pMET << (BYTE)0xc0 << (BYTE)26 << nFlags << (BYTE)0;
1328 WritePoint(aRect.BottomLeft());
1329 WritePoint(aRect.TopRight());
1330 *pMET << nHAxis << nVAxis;
1334 void METWriter::METFullArc(Point aCenter, double fMultiplier)
1336 WillWriteOrder(14);
1337 *pMET << (BYTE)0xc7 << (BYTE)12;
1338 WritePoint(aCenter);
1339 *pMET << (long)(fMultiplier*65536.0+0.5);
1343 void METWriter::METPartialArcAtCurPos(Point aCenter, double fMultiplier,
1344 double fStartAngle, double fSweepAngle)
1346 fStartAngle*=180.0/3.14159265359;
1347 while (fStartAngle>360.0) fStartAngle-=360.0;
1348 while (fStartAngle<0.0) fStartAngle+=360.0;
1349 fSweepAngle*=180.0/3.14159265359;
1350 while (fSweepAngle>360.0) fSweepAngle-=360.0;
1351 while (fSweepAngle<.00) fSweepAngle+=360.0;
1352 WillWriteOrder(22);
1353 *pMET << (BYTE)0xa3 << (BYTE)20;
1354 WritePoint(aCenter);
1355 *pMET << (long)(fMultiplier*65536.0+0.5);
1356 *pMET << (long)(fStartAngle*65536.0+0.5);
1357 *pMET << (long)(fSweepAngle*65536.0+0.5);
1361 void METWriter::METChrStr( Point aPt, String aUniStr )
1363 USHORT nLen,i;
1364 ByteString aStr( aUniStr, gsl_getSystemTextEncoding() );
1365 nLen = aStr.Len();
1366 WillWriteOrder( 11 + nLen );
1367 *pMET << (BYTE)0xc3 << (BYTE)( 9 + nLen );
1368 WritePoint(aPt);
1369 for ( i = 0; i < nLen; i++ )
1370 *pMET << aStr.GetChar( i );
1371 *pMET << (BYTE)0;
1375 void METWriter::METSetArcParams(long nP, long nQ, long nR, long nS)
1377 WillWriteOrder(18);
1378 *pMET << (BYTE)0x22 << (BYTE)16 << nP << nQ << nR << nS;
1382 void METWriter::METSetColor(Color aColor)
1384 if (aColor==aMETColor) return;
1385 aMETColor=aColor;
1387 WillWriteOrder(6);
1388 *pMET << (BYTE)0xa6 << (BYTE)4 << (BYTE)0
1389 << (BYTE)(aColor.GetBlue())
1390 << (BYTE)(aColor.GetGreen())
1391 << (BYTE)(aColor.GetRed());
1395 void METWriter::METSetBackgroundColor(Color aColor)
1397 if (aColor==aMETBackgroundColor) return;
1398 aMETBackgroundColor=aColor;
1400 WillWriteOrder(6);
1401 *pMET << (BYTE)0xa7 << (BYTE)4 << (BYTE)0
1402 << (BYTE)(aColor.GetBlue())
1403 << (BYTE)(aColor.GetGreen())
1404 << (BYTE)(aColor.GetRed());
1407 void METWriter::METSetMix(RasterOp eROP)
1409 BYTE nMix;
1411 if (eMETMix==eROP)
1412 return;
1414 eMETMix=eROP;
1416 switch (eROP)
1418 case ROP_INVERT: nMix=0x0c; break;
1419 case ROP_XOR: nMix=0x04; break;
1420 default: nMix=0x02;
1423 WillWriteOrder(2);
1424 *pMET << (BYTE)0x0c << nMix;
1428 void METWriter::METSetChrCellSize(Size aSize)
1430 if (aMETChrCellSize==aSize)
1431 return;
1433 aMETChrCellSize=aSize;
1434 WillWriteOrder(10);
1435 if (aSize.Width()==0) aSize.Width()=aSize.Height();
1436 *pMET << (BYTE)0x33 << (BYTE)8 << (long)aSize.Width() << (long)aSize.Height();
1440 void METWriter::METSetChrAngle(short nAngle)
1442 double fa;
1443 long nax,nay;
1445 if (nMETChrAngle==nAngle) return;
1446 nMETChrAngle=nAngle;
1448 if (nAngle==0)
1450 nax=256;
1451 nay=0;
1453 else
1455 fa=((double)nAngle)/1800.0*3.14159265359;
1456 nax=(long)(256.0*cos(fa)+0.5);
1457 nay=(long)(256.0*sin(fa)+0.5);
1460 WillWriteOrder(10);
1461 *pMET << (BYTE)0x34 << (BYTE)8 << nax << nay;
1465 void METWriter::METSetChrSet(BYTE nSet)
1467 if (nMETChrSet==nSet)
1468 return;
1470 nMETChrSet=nSet;
1471 WillWriteOrder(2);
1472 *pMET << (BYTE)0x38 << nSet;
1476 void METWriter::WriteOrders( const GDIMetaFile* pMTF )
1478 if(bStatus==FALSE)
1479 return;
1481 for( ULONG nA = 0, nACount = pMTF->GetActionCount(); nA < nACount; nA++ )
1483 const MetaAction* pMA = pMTF->GetAction( nA );
1485 switch (pMA->GetType())
1487 case META_PIXEL_ACTION:
1489 const MetaPixelAction* pA = (const MetaPixelAction*) pMA;
1490 METSetMix( eGDIRasterOp );
1491 METSetColor( pA->GetColor() );
1492 METLine( pA->GetPoint(),pA->GetPoint() );
1494 break;
1496 case META_POINT_ACTION:
1498 const MetaPointAction* pA = (const MetaPointAction*) pMA;
1500 METSetArcParams(1,1,0,0);
1501 METSetMix(eGDIRasterOp);
1502 METSetColor(aGDILineColor);
1503 METBeginArea(FALSE);
1504 METFullArc(pA->GetPoint(),0.5);
1505 METEndArea();
1507 break;
1509 case META_LINE_ACTION:
1511 const MetaLineAction* pA = (const MetaLineAction*) pMA;
1513 if( aGDILineColor != Color( COL_TRANSPARENT ) )
1515 LineInfo aLineInfo( pA->GetLineInfo() );
1516 if ( ! ( aLineInfo.IsDefault() ) )
1517 METSetAndPushLineInfo( aLineInfo );
1519 METSetMix( eGDIRasterOp );
1520 METSetColor(aGDILineColor);
1521 METBeginPath( 1 );
1522 METLine( pA->GetStartPoint(), pA->GetEndPoint() );
1523 METEndPath();
1524 METOutlinePath( 1 );
1526 if ( ! ( aLineInfo.IsDefault() ) )
1527 METPopLineInfo( aLineInfo );
1530 break;
1532 case META_RECT_ACTION:
1534 const MetaRectAction* pA = (const MetaRectAction*) pMA;
1536 if( aGDIFillColor != Color( COL_TRANSPARENT ) )
1538 METSetMix( eGDIRasterOp );
1539 METSetColor( aGDIFillColor );
1540 METSetBackgroundColor( aGDIFillColor );
1541 METBox( TRUE, FALSE, pA->GetRect(), 0, 0 );
1544 if( aGDILineColor != Color( COL_TRANSPARENT ) )
1546 METSetMix( eGDIRasterOp );
1547 METSetColor( aGDILineColor );
1548 METBox( FALSE, TRUE, pA->GetRect(), 0, 0 );
1551 break;
1553 case META_ROUNDRECT_ACTION:
1555 const MetaRoundRectAction* pA = (const MetaRoundRectAction*) pMA;
1557 if( aGDIFillColor != Color( COL_TRANSPARENT ) )
1559 METSetMix( eGDIRasterOp );
1560 METSetColor( aGDIFillColor );
1561 METSetBackgroundColor( aGDIFillColor );
1562 METBox( TRUE, FALSE, pA->GetRect(), pA->GetHorzRound(), pA->GetVertRound() );
1565 if( aGDILineColor != Color( COL_TRANSPARENT ) )
1567 METSetMix( eGDIRasterOp );
1568 METSetColor( aGDILineColor );
1569 METBox( FALSE, TRUE, pA->GetRect(), pA->GetHorzRound(), pA->GetVertRound() );
1572 break;
1574 case META_ELLIPSE_ACTION:
1576 const MetaEllipseAction* pA = (const MetaEllipseAction*) pMA;
1577 Point aCenter;
1579 aCenter.X()=(pA->GetRect().Left()+pA->GetRect().Right())/2;
1580 aCenter.Y()=(pA->GetRect().Top()+pA->GetRect().Bottom())/2;
1582 METSetArcParams(pA->GetRect().GetWidth(), pA->GetRect().GetHeight(),0,0);
1584 if( aGDIFillColor != Color( COL_TRANSPARENT ) )
1586 METSetMix( eGDIRasterOp );
1587 METSetColor( aGDIFillColor );
1588 METSetBackgroundColor( aGDIFillColor );
1589 METBeginArea(FALSE);
1590 METFullArc(aCenter,0.5);
1591 METEndArea();
1594 if( aGDILineColor != Color( COL_TRANSPARENT ) )
1596 METSetMix( eGDIRasterOp );
1597 METSetColor( aGDILineColor );
1598 METFullArc( aCenter,0.5 );
1601 break;
1603 case META_ARC_ACTION:
1605 const MetaArcAction* pA = (const MetaArcAction*) pMA;
1606 Point aStartPos,aCenter;
1607 double fdx,fdy,fa1,fa2;
1609 aCenter.X()=(pA->GetRect().Left()+pA->GetRect().Right())/2;
1610 aCenter.Y()=(pA->GetRect().Top()+pA->GetRect().Bottom())/2;
1611 fdx=(double)(pA->GetStartPoint().X()-aCenter.X());
1612 fdy=(double)(pA->GetStartPoint().Y()-aCenter.Y());
1613 fdx*=(double)pA->GetRect().GetHeight();
1614 fdy*=(double)pA->GetRect().GetWidth();
1615 if (fdx==0.0 && fdy==0.0) fdx=1.0;
1616 fa1=atan2(-fdy,fdx);
1617 fdx=(double)(pA->GetEndPoint().X()-aCenter.X());
1618 fdy=(double)(pA->GetEndPoint().Y()-aCenter.Y());
1619 fdx*=(double)pA->GetRect().GetHeight();
1620 fdy*=(double)pA->GetRect().GetWidth();
1621 if (fdx==0.0 && fdy==0.0) fdx=1.0;
1622 fa2=atan2(-fdy,fdx);
1623 aStartPos.X()=aCenter.X()+(long)(((double)pA->GetRect().GetWidth())*cos(fa1)/2.0+0.5);
1624 aStartPos.Y()=aCenter.Y()-(long)(((double)pA->GetRect().GetHeight())*sin(fa1)/2.0+0.5);
1626 if( aGDILineColor != Color( COL_TRANSPARENT ) )
1628 METSetMix( eGDIRasterOp );
1629 METSetColor( aGDILineColor );
1630 METSetArcParams(pA->GetRect().GetWidth(), pA->GetRect().GetHeight(),0,0);
1631 METBeginPath(1);
1632 METMove(aStartPos);
1633 METPartialArcAtCurPos(aCenter,0.5,fa1,fa2-fa1);
1634 METEndPath();
1635 METOutlinePath(1);
1638 break;
1640 case META_PIE_ACTION:
1642 const MetaPieAction* pA = (const MetaPieAction*) pMA;
1643 Point aCenter;
1644 double fdx,fdy,fa1,fa2;
1646 aCenter.X()=(pA->GetRect().Left()+pA->GetRect().Right())/2;
1647 aCenter.Y()=(pA->GetRect().Top()+pA->GetRect().Bottom())/2;
1648 fdx=(double)(pA->GetStartPoint().X()-aCenter.X());
1649 fdy=(double)(pA->GetStartPoint().Y()-aCenter.Y());
1650 fdx*=(double)pA->GetRect().GetHeight();
1651 fdy*=(double)pA->GetRect().GetWidth();
1652 if (fdx==0.0 && fdy==0.0) fdx=1.0;
1653 fa1=atan2(-fdy,fdx);
1654 fdx=(double)(pA->GetEndPoint().X()-aCenter.X());
1655 fdy=(double)(pA->GetEndPoint().Y()-aCenter.Y());
1656 fdx*=(double)pA->GetRect().GetHeight();
1657 fdy*=(double)pA->GetRect().GetWidth();
1658 if (fdx==0.0 && fdy==0.0) fdx=1.0;
1659 fa2=atan2(-fdy,fdx);
1661 METSetArcParams(pA->GetRect().GetWidth(), pA->GetRect().GetHeight(),0,0);
1663 if( aGDIFillColor != Color( COL_TRANSPARENT ) )
1665 METSetMix( eGDIRasterOp );
1666 METSetColor( aGDIFillColor );
1667 METSetBackgroundColor( aGDIFillColor );
1668 METBeginPath(1);
1669 METMove(aCenter);
1670 METPartialArcAtCurPos(aCenter,0.5,fa1,fa2-fa1);
1671 METLineAtCurPos(aCenter);
1672 METEndPath();
1673 METFillPath(1);
1676 if( aGDILineColor != Color( COL_TRANSPARENT ) )
1678 METSetMix( eGDIRasterOp );
1679 METSetColor( aGDILineColor );
1680 METBeginPath(1);
1681 METMove(aCenter);
1682 METPartialArcAtCurPos(aCenter,0.5,fa1,fa2-fa1);
1683 METLineAtCurPos(aCenter);
1684 METEndPath();
1685 METOutlinePath(1);
1688 break;
1690 case META_CHORD_ACTION:
1692 const MetaChordAction* pA = (const MetaChordAction*) pMA;
1693 Point aStartPos,aCenter;
1694 double fdx,fdy,fa1,fa2;
1696 aCenter.X()=(pA->GetRect().Left()+pA->GetRect().Right())/2;
1697 aCenter.Y()=(pA->GetRect().Top()+pA->GetRect().Bottom())/2;
1698 fdx=(double)(pA->GetStartPoint().X()-aCenter.X());
1699 fdy=(double)(pA->GetStartPoint().Y()-aCenter.Y());
1700 fdx*=(double)pA->GetRect().GetHeight();
1701 fdy*=(double)pA->GetRect().GetWidth();
1702 if (fdx==0.0 && fdy==0.0) fdx=1.0;
1703 fa1=atan2(-fdy,fdx);
1704 fdx=(double)(pA->GetEndPoint().X()-aCenter.X());
1705 fdy=(double)(pA->GetEndPoint().Y()-aCenter.Y());
1706 fdx*=(double)pA->GetRect().GetHeight();
1707 fdy*=(double)pA->GetRect().GetWidth();
1708 if (fdx==0.0 && fdy==0.0) fdx=1.0;
1709 fa2=atan2(-fdy,fdx);
1710 aStartPos.X()=aCenter.X()+(long)(((double)pA->GetRect().GetWidth())*cos(fa1)/2.0+0.5);
1711 aStartPos.Y()=aCenter.Y()-(long)(((double)pA->GetRect().GetHeight())*sin(fa1)/2.0+0.5);
1713 if( aGDIFillColor != Color( COL_TRANSPARENT ) )
1715 METSetMix( eGDIRasterOp );
1716 METSetColor( aGDIFillColor );
1717 METSetBackgroundColor( aGDIFillColor );
1718 METBeginPath(1);
1719 METMove(aStartPos);
1720 METPartialArcAtCurPos(aCenter,0.5,fa1,fa2-fa1);
1721 METLineAtCurPos(aStartPos);
1722 METEndPath();
1723 METFillPath(1);
1726 if( aGDILineColor != Color( COL_TRANSPARENT ) )
1728 METSetMix( eGDIRasterOp );
1729 METSetColor( aGDILineColor );
1730 METBeginPath(1);
1731 METMove(aStartPos);
1732 METPartialArcAtCurPos(aCenter,0.5,fa1,fa2-fa1);
1733 METLineAtCurPos(aStartPos);
1734 METEndPath();
1735 METOutlinePath(1);
1738 break;
1740 case META_POLYLINE_ACTION:
1742 const MetaPolyLineAction* pA = (const MetaPolyLineAction*) pMA;
1744 if( aGDILineColor != Color( COL_TRANSPARENT ) )
1746 LineInfo aLineInfo( pA->GetLineInfo() );
1747 if ( ! ( aLineInfo.IsDefault() ) )
1748 METSetAndPushLineInfo( aLineInfo );
1750 METSetMix(eGDIRasterOp);
1751 METSetColor(aGDILineColor);
1752 METBeginPath(1);
1753 Polygon aSimplePoly;
1754 const Polygon& rPoly = pA->GetPolygon();
1755 if ( rPoly.HasFlags() )
1756 rPoly.GetSimple( aSimplePoly );
1757 else
1758 aSimplePoly = rPoly;
1759 METLine( aSimplePoly );
1760 METEndPath();
1761 METOutlinePath(1);
1763 if ( ! ( aLineInfo.IsDefault() ) )
1764 METPopLineInfo( aLineInfo );
1767 break;
1769 case META_POLYGON_ACTION:
1771 const MetaPolygonAction* pA = (const MetaPolygonAction*) pMA;
1772 Polygon aSimplePoly;
1773 const Polygon& rPoly = pA->GetPolygon();
1774 if ( rPoly.HasFlags() )
1775 rPoly.GetSimple( aSimplePoly );
1776 else
1777 aSimplePoly = rPoly;
1778 if( aGDIFillColor != Color( COL_TRANSPARENT ) )
1780 METSetMix(eGDIRasterOp);
1781 METSetColor(aGDIFillColor );
1782 METSetBackgroundColor(aGDIFillColor );
1783 METBeginPath(1);
1784 METLine( aSimplePoly );
1785 METEndPath();
1786 METFillPath(1);
1789 if( aGDILineColor != Color( COL_TRANSPARENT ) )
1791 METSetMix(eGDIRasterOp);
1792 METSetColor(aGDILineColor );
1793 METBeginPath(1);
1794 METLine( aSimplePoly );
1795 METEndPath();
1796 METOutlinePath(1);
1799 break;
1801 case META_POLYPOLYGON_ACTION:
1803 const MetaPolyPolygonAction* pA = (const MetaPolyPolygonAction*) pMA;
1805 PolyPolygon aSimplePolyPoly( pA->GetPolyPolygon() );
1806 sal_uInt16 i, nCount = aSimplePolyPoly.Count();
1807 for ( i = 0; i < nCount; i++ )
1809 if ( aSimplePolyPoly[ i ].HasFlags() )
1811 Polygon aSimplePoly;
1812 aSimplePolyPoly[ i ].GetSimple( aSimplePoly );
1813 aSimplePolyPoly[ i ] = aSimplePoly;
1816 if( aGDIFillColor != Color( COL_TRANSPARENT ) )
1818 METSetMix(eGDIRasterOp);
1819 METSetColor(aGDIFillColor);
1820 METSetBackgroundColor(aGDIFillColor);
1821 METBeginPath(1);
1822 METLine( aSimplePolyPoly );
1823 METEndPath();
1824 METFillPath(1);
1827 if( aGDILineColor != Color( COL_TRANSPARENT ) )
1829 METSetMix(eGDIRasterOp);
1830 METSetColor(aGDILineColor);
1831 METBeginPath(1);
1832 METLine( aSimplePolyPoly );
1833 METEndPath();
1834 METOutlinePath(1);
1837 break;
1839 case META_TEXT_ACTION:
1841 const MetaTextAction* pA = (const MetaTextAction*) pMA;
1842 Point aPt( pA->GetPoint() );
1844 if( aGDIFont.GetAlign() != ALIGN_BASELINE)
1846 VirtualDevice aVDev;
1848 if( aGDIFont.GetAlign()==ALIGN_TOP )
1849 aPt.Y()+=(long)aVDev.GetFontMetric( aGDIFont ).GetAscent();
1850 else
1851 aPt.Y()-=(long)aVDev.GetFontMetric( aGDIFont ).GetDescent();
1854 METSetMix(eGDIRasterOp);
1855 METSetColor(aGDIFont.GetColor());
1856 METSetBackgroundColor(aGDIFont.GetFillColor());
1857 METSetChrCellSize(aGDIFont.GetSize());
1858 METSetChrAngle(aGDIFont.GetOrientation());
1859 METSetChrSet(FindChrSet(aGDIFont));
1860 METChrStr(aPt, String(pA->GetText(),pA->GetIndex(),pA->GetLen()));
1862 break;
1864 case META_TEXTARRAY_ACTION:
1866 const MetaTextArrayAction* pA = (const MetaTextArrayAction*) pMA;
1867 USHORT i;
1868 String aStr;
1869 Polygon aPolyDummy(1);
1870 short nOrientation;
1871 Point aPt( pA->GetPoint() );
1873 if( aGDIFont.GetAlign() != ALIGN_BASELINE )
1875 VirtualDevice aVDev;
1876 if( aGDIFont.GetAlign() == ALIGN_TOP )
1877 aPt.Y()+=(long)aVDev.GetFontMetric(aGDIFont).GetAscent();
1878 else
1879 aPt.Y()-=(long)aVDev.GetFontMetric(aGDIFont).GetDescent();
1882 METSetMix(eGDIRasterOp);
1883 METSetColor(aGDIFont.GetColor());
1884 METSetBackgroundColor(aGDIFont.GetFillColor());
1885 METSetChrCellSize(aGDIFont.GetSize());
1886 METSetChrAngle( nOrientation = aGDIFont.GetOrientation() );
1887 METSetChrSet(FindChrSet(aGDIFont));
1888 aStr=String(pA->GetText(),pA->GetIndex(),pA->GetLen());
1890 if( pA->GetDXArray()!=NULL )
1892 Point aPt2;
1894 for( i=0; i < aStr.Len(); i++ )
1896 aPt2 = aPt;
1897 if ( i > 0 )
1899 aPt2.X() += pA->GetDXArray()[i-1];
1900 if ( nOrientation )
1902 aPolyDummy.SetPoint( aPt2, 0 );
1903 aPolyDummy.Rotate( aPt, nOrientation );
1904 aPt2 = aPolyDummy.GetPoint( 0 );
1907 METChrStr( aPt2, String( aStr.GetChar( i ) ) );
1910 else
1911 METChrStr( aPt, aStr );
1913 break;
1915 case META_STRETCHTEXT_ACTION:
1917 const MetaStretchTextAction* pA = (const MetaStretchTextAction*) pMA;
1918 VirtualDevice aVDev;
1919 USHORT i;
1920 sal_Int32* pDXAry;
1921 sal_Int32 nNormSize;
1922 String aStr;
1923 Polygon aPolyDummy(1);
1924 short nOrientation;
1925 Point aPt( pA->GetPoint() );
1926 Point aPt2;
1928 aVDev.SetFont( aGDIFont );
1930 if( aGDIFont.GetAlign() != ALIGN_BASELINE)
1932 if( aGDIFont.GetAlign() == ALIGN_TOP )
1933 aPt.Y()+=(long)aVDev.GetFontMetric().GetAscent();
1934 else
1935 aPt.Y()-=(long)aVDev.GetFontMetric().GetDescent();
1938 METSetMix(eGDIRasterOp);
1939 METSetColor(aGDIFont.GetColor());
1940 METSetBackgroundColor(aGDIFont.GetFillColor());
1941 METSetChrCellSize(aGDIFont.GetSize());
1942 METSetChrAngle( nOrientation = aGDIFont.GetOrientation() );
1943 METSetChrSet(FindChrSet(aGDIFont));
1944 aStr=String(pA->GetText(),pA->GetIndex(),pA->GetLen());
1945 pDXAry=new sal_Int32[aStr.Len()];
1946 nNormSize = aVDev.GetTextArray( aStr, pDXAry );
1948 for ( i = 0; i < aStr.Len(); i++ )
1950 aPt2 = aPt;
1951 if ( i > 0 )
1953 aPt2.X() += pDXAry[i-1]*((long)pA->GetWidth())/ nNormSize;
1954 if ( nOrientation )
1956 aPolyDummy.SetPoint( aPt2, 0 );
1957 aPolyDummy.Rotate( aPt, nOrientation );
1958 aPt2 = aPolyDummy.GetPoint( 0 );
1961 METChrStr( aPt2, String( aStr.GetChar( i ) ) );
1964 delete[] pDXAry;
1966 break;
1968 case META_TEXTRECT_ACTION:
1970 // DBG_ERROR( "Unsupported MET-Action: META_TEXTRECT_ACTION!" );
1972 break;
1974 case META_BMP_ACTION:
1976 const MetaBmpAction* pA = (const MetaBmpAction*) pMA;
1978 METSetMix(eGDIRasterOp);
1979 METBitBlt( pA->GetPoint(), pA->GetBitmap().GetSizePixel(), pA->GetBitmap() );
1981 break;
1983 case META_BMPSCALE_ACTION:
1985 const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pMA;
1987 METSetMix(eGDIRasterOp);
1988 METBitBlt( pA->GetPoint(), pA->GetSize(), pA->GetBitmap() );
1990 break;
1992 case META_BMPSCALEPART_ACTION:
1994 const MetaBmpScalePartAction* pA = (const MetaBmpScalePartAction*) pMA;
1995 Bitmap aTmp( pA->GetBitmap() );
1997 aTmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
1998 METSetMix( eGDIRasterOp );
1999 METBitBlt( pA->GetDestPoint(), pA->GetDestSize(), aTmp );
2001 break;
2003 case META_BMPEX_ACTION:
2005 const MetaBmpExAction* pA = (const MetaBmpExAction*) pMA;
2006 Bitmap aTmp( Graphic( pA->GetBitmapEx() ).GetBitmap() );
2008 METSetMix(eGDIRasterOp);
2009 METBitBlt( pA->GetPoint(), aTmp.GetSizePixel(), aTmp );
2011 break;
2013 case META_BMPEXSCALE_ACTION:
2015 const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pMA;
2016 Bitmap aTmp( Graphic( pA->GetBitmapEx() ).GetBitmap() );
2018 METSetMix(eGDIRasterOp);
2019 METBitBlt( pA->GetPoint(), pA->GetSize(), aTmp );
2021 break;
2023 case META_BMPEXSCALEPART_ACTION:
2025 const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*) pMA;
2026 Bitmap aTmp( Graphic( pA->GetBitmapEx() ).GetBitmap() );
2028 aTmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
2029 METSetMix(eGDIRasterOp);
2030 METBitBlt( pA->GetDestPoint(), pA->GetDestSize(), aTmp );
2032 break;
2034 case META_EPS_ACTION :
2036 const MetaEPSAction* pA = (const MetaEPSAction*)pMA;
2037 const GDIMetaFile aGDIMetaFile( pA->GetSubstitute() );
2039 INT32 nCount = aGDIMetaFile.GetActionCount();
2040 for ( INT32 i = 0; i < nCount; i++ )
2042 const MetaAction* pMetaAct = aGDIMetaFile.GetAction( i );
2043 if ( pMetaAct->GetType() == META_BMPSCALE_ACTION )
2045 const MetaBmpScaleAction* pBmpScaleAction = (const MetaBmpScaleAction*)pMetaAct;
2046 METSetMix(eGDIRasterOp);
2047 METBitBlt( pA->GetPoint(), pA->GetSize(), pBmpScaleAction->GetBitmap() );
2048 break;
2052 break;
2054 case META_MASK_ACTION:
2056 // DBG_ERROR( "Unsupported MET-Action: META_MASK_ACTION!" );
2058 break;
2060 case META_MASKSCALE_ACTION:
2062 // DBG_ERROR( "Unsupported MET-Action: META_MASKSCALE_ACTION!" );
2064 break;
2066 case META_MASKSCALEPART_ACTION:
2068 // DBG_ERROR( "Unsupported MET-Action: META_MASKSCALEPART_ACTION!" );
2070 break;
2072 case META_GRADIENT_ACTION:
2074 VirtualDevice aVDev;
2075 GDIMetaFile aTmpMtf;
2076 const MetaGradientAction* pA = (const MetaGradientAction*) pMA;
2078 aVDev.SetMapMode( aTargetMapMode );
2079 aVDev.AddGradientActions( pA->GetRect(), pA->GetGradient(), aTmpMtf );
2080 WriteOrders( &aTmpMtf );
2082 break;
2084 case META_HATCH_ACTION:
2086 VirtualDevice aVDev;
2087 GDIMetaFile aTmpMtf;
2088 const MetaHatchAction* pA = (const MetaHatchAction*) pMA;
2090 aVDev.SetMapMode( aTargetMapMode );
2091 aVDev.AddHatchActions( pA->GetPolyPolygon(), pA->GetHatch(), aTmpMtf );
2092 WriteOrders( &aTmpMtf );
2094 break;
2096 case META_WALLPAPER_ACTION:
2098 // DBG_ERROR( "Unsupported MET-Action: META_WALLPAPER_ACTION!" );
2100 break;
2102 case META_CLIPREGION_ACTION:
2104 // DBG_ERROR( "Unsupported MET-Action: META_CLIPREGION_ACTION!" );
2106 break;
2108 case META_ISECTRECTCLIPREGION_ACTION:
2110 const MetaISectRectClipRegionAction* pA = (const MetaISectRectClipRegionAction*) pMA;
2111 WriteClipRect( pA->GetRect() );
2113 break;
2115 case META_ISECTREGIONCLIPREGION_ACTION:
2117 // DBG_ERROR( "Unsupported MET-Action: META_ISECTREGIONCLIPREGION_ACTION!" );
2119 break;
2121 case META_MOVECLIPREGION_ACTION:
2123 // DBG_ERROR( "Unsupported MET-Action: META_MOVECLIPREGION_ACTION!" );
2125 break;
2127 case META_LINECOLOR_ACTION:
2129 const MetaLineColorAction* pA = (const MetaLineColorAction*) pMA;
2131 if( pA->IsSetting() )
2132 aGDILineColor = pA->GetColor();
2133 else
2134 aGDILineColor = Color( COL_TRANSPARENT );
2136 break;
2138 case META_FILLCOLOR_ACTION:
2140 const MetaFillColorAction* pA = (const MetaFillColorAction*) pMA;
2142 if( pA->IsSetting() )
2143 aGDIFillColor = pA->GetColor();
2144 else
2145 aGDIFillColor = Color( COL_TRANSPARENT );
2147 break;
2149 case META_TEXTCOLOR_ACTION:
2151 const MetaTextColorAction* pA = (const MetaTextColorAction*) pMA;
2152 aGDIFont.SetColor( pA->GetColor() );
2154 break;
2156 case META_TEXTFILLCOLOR_ACTION:
2158 const MetaTextFillColorAction* pA = (const MetaTextFillColorAction*) pMA;
2160 if( pA->IsSetting() )
2161 aGDIFont.SetFillColor( pA->GetColor() );
2162 else
2163 aGDIFont.SetFillColor( Color( COL_TRANSPARENT ) );
2165 break;
2167 case META_TEXTALIGN_ACTION:
2169 // DBG_ERROR( "Unsupported MET-Action: META_TEXTALIGN_ACTION!" );
2171 break;
2173 case META_MAPMODE_ACTION:
2175 const MetaMapModeAction* pA = (const MetaMapModeAction*) pMA;
2177 if( aPictureMapMode != pA->GetMapMode() )
2179 if ( pA->GetMapMode().GetMapUnit() == MAP_RELATIVE )
2181 MapMode aMM = pA->GetMapMode();
2182 Fraction aScaleX = aMM.GetScaleX();
2183 Fraction aScaleY = aMM.GetScaleY();
2185 Point aOrigin = aPictureMapMode.GetOrigin();
2186 BigInt aX( aOrigin.X() );
2187 aX *= BigInt( aScaleX.GetDenominator() );
2189 if( aOrigin.X() >= 0 )
2191 if( aScaleX.GetNumerator() >= 0 )
2192 aX += BigInt( aScaleX.GetNumerator()/2 );
2193 else
2194 aX -= BigInt( (aScaleX.GetNumerator()+1)/2 );
2196 else
2198 if( aScaleX.GetNumerator() >= 0 )
2199 aX -= BigInt( (aScaleX.GetNumerator()-1)/2 );
2200 else
2201 aX += BigInt( aScaleX.GetNumerator()/2 );
2204 aX /= BigInt( aScaleX.GetNumerator() );
2205 aOrigin.X() = (long) aX + aMM.GetOrigin().X();
2207 BigInt aY( aOrigin.Y() );
2208 aY *= BigInt( aScaleY.GetDenominator() );
2210 if( aOrigin.Y() >= 0 )
2212 if( aScaleY.GetNumerator() >= 0 )
2213 aY += BigInt( aScaleY.GetNumerator()/2 );
2214 else
2215 aY -= BigInt( (aScaleY.GetNumerator()+1)/2 );
2217 else
2219 if( aScaleY.GetNumerator() >= 0 )
2220 aY -= BigInt( (aScaleY.GetNumerator()-1)/2 );
2221 else
2222 aY += BigInt( aScaleY.GetNumerator()/2 );
2225 aY /= BigInt( aScaleY.GetNumerator() );
2226 aOrigin.Y() = (long)aY + aMM.GetOrigin().Y();
2227 aPictureMapMode.SetOrigin( aOrigin );
2229 aScaleX *= aPictureMapMode.GetScaleX();
2230 aScaleY *= aPictureMapMode.GetScaleY();
2231 aPictureMapMode.SetScaleX( aScaleX );
2232 aPictureMapMode.SetScaleY( aScaleY );
2234 else
2235 aPictureMapMode=pA->GetMapMode();
2238 break;
2240 case META_FONT_ACTION:
2242 aGDIFont = ( (const MetaFontAction*) pMA )->GetFont();
2244 break;
2246 case META_PUSH_ACTION:
2248 METGDIStackMember* pGS = new METGDIStackMember;
2250 pGS->pSucc=pGDIStack; pGDIStack=pGS;
2251 pGS->aLineColor=aGDILineColor;
2252 pGS->aFillColor=aGDIFillColor;
2253 pGS->eRasterOp=eGDIRasterOp;
2254 pGS->aFont=aGDIFont;
2255 pGS->aMapMode=aPictureMapMode;
2256 pGS->aClipRect=aGDIClipRect;
2258 break;
2260 case META_POP_ACTION:
2262 METGDIStackMember* pGS;
2264 if( pGDIStack )
2266 pGS=pGDIStack; pGDIStack=pGS->pSucc;
2267 aGDILineColor=pGS->aLineColor;
2268 aGDIFillColor=pGS->aFillColor;
2269 eGDIRasterOp=pGS->eRasterOp;
2270 aGDIFont=pGS->aFont;
2271 if ( pGS->aClipRect != aGDIClipRect )
2272 WriteClipRect( pGS->aClipRect );
2273 aPictureMapMode=pGS->aMapMode;
2274 delete pGS;
2277 break;
2279 case META_RASTEROP_ACTION:
2281 eGDIRasterOp = ( (const MetaRasterOpAction*) pMA )->GetRasterOp();
2283 break;
2285 case META_TRANSPARENT_ACTION:
2287 if( aGDIFillColor != Color( COL_TRANSPARENT ) )
2289 METSetMix(eGDIRasterOp);
2290 METSetColor(aGDIFillColor);
2291 METSetBackgroundColor(aGDIFillColor);
2292 METBeginPath(1);
2293 METLine(( (const MetaTransparentAction*) pMA )->GetPolyPolygon());
2294 METEndPath();
2295 METFillPath(1);
2298 if( aGDILineColor != Color( COL_TRANSPARENT ) )
2300 METSetMix(eGDIRasterOp);
2301 METSetColor(aGDILineColor);
2302 METBeginPath(1);
2303 METLine(( (const MetaTransparentAction*) pMA )->GetPolyPolygon());
2304 METEndPath();
2305 METOutlinePath(1);
2308 break;
2310 case META_FLOATTRANSPARENT_ACTION:
2312 const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pMA;
2314 GDIMetaFile aTmpMtf( pA->GetGDIMetaFile() );
2315 Point aSrcPt( aTmpMtf.GetPrefMapMode().GetOrigin() );
2316 const Size aSrcSize( aTmpMtf.GetPrefSize() );
2317 const Point aDestPt( pA->GetPoint() );
2318 const Size aDestSize( pA->GetSize() );
2319 const double fScaleX = aSrcSize.Width() ? (double) aDestSize.Width() / aSrcSize.Width() : 1.0;
2320 const double fScaleY = aSrcSize.Height() ? (double) aDestSize.Height() / aSrcSize.Height() : 1.0;
2321 long nMoveX, nMoveY;
2323 if( fScaleX != 1.0 || fScaleY != 1.0 )
2325 aTmpMtf.Scale( fScaleX, fScaleY );
2326 aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
2329 nMoveX = aDestPt.X() - aSrcPt.X(), nMoveY = aDestPt.Y() - aSrcPt.Y();
2331 if( nMoveX || nMoveY )
2332 aTmpMtf.Move( nMoveX, nMoveY );
2334 WriteOrders( &aTmpMtf );
2336 break;
2339 nWrittenActions++;
2340 MayCallback();
2342 if( pMET->GetError() )
2343 bStatus=FALSE;
2345 if( bStatus == FALSE )
2346 break;
2350 void METWriter::WriteObjectEnvironmentGroup(const GDIMetaFile * pMTF)
2352 ULONG i, nId;
2354 //--- Das Feld 'Begin Object Environment Group':
2355 WriteFieldIntroducer(16,BegObjEnvMagic,0,0);
2356 WriteFieldId(7);
2358 //--- Das Feld 'Map Color Attribute Table':
2359 WriteFieldIntroducer(22,MapColAtrMagic,0,0);
2360 WriteBigEndianShort(0x000e);
2361 *pMET << (BYTE)0x0c << (BYTE)0x02 << (BYTE)0x84 << (BYTE)0x00;
2362 WriteFieldId(4);
2364 //--- Das erste Feld 'Map Coded Font':
2365 WriteFieldIntroducer(32,MapCodFntMagic,0,0);
2366 WriteBigEndianShort(0x0018);
2367 *pMET << (BYTE)0x0c << (BYTE)0x02 << (BYTE)0x84 << (BYTE)0x00;
2368 *pMET << (BYTE)0xff << (BYTE)0x00 << (BYTE)0x00 << (BYTE)0x00;
2369 *pMET << (BYTE)0x00 << (BYTE)0x00 << (BYTE)0x00 << (BYTE)0x00;
2370 *pMET << (BYTE)0x04 << (BYTE)0x24 << (BYTE)0x05 << (BYTE)0x00;
2371 *pMET << (BYTE)0x06 << (BYTE)0x20;
2372 *pMET << (BYTE)0x03 << (BYTE)0x97 << (BYTE)0x01 << (BYTE)0xb5;
2374 //--- Die weiteren Felder 'Map Coded Font':
2375 CreateChrSets(pMTF);
2376 WriteChrSets();
2378 //--- Die Felder 'Map Data Resource':
2379 nId=nActBitmapId;
2380 for (i=0; i<nNumberOfBitmaps; i++)
2382 WriteFieldIntroducer(29,MapDatResMagic,0,0);
2383 WriteBigEndianShort(0x0015);
2384 *pMET << (BYTE)0x0c << (BYTE)0x02 << (BYTE)0x84 << (BYTE)0x00;
2385 WriteFieldId(nId);
2386 *pMET << (BYTE)0x07 << (BYTE)0x22 << (BYTE)0x10;
2387 *pMET << (sal_uInt32)nId;
2388 nId++;
2391 //--- Das Feld 'End Object Environment Group':
2392 WriteFieldIntroducer(16,EndObjEnvMagic,0,0);
2393 WriteFieldId(7);
2397 void METWriter::WriteGraphicsObject(const GDIMetaFile * pMTF)
2399 ULONG nSegmentSize,nPos,nDataFieldsStartPos;
2401 if( bStatus==FALSE )
2402 return;
2404 //--- Das Feld 'Begin Graphics Object':
2405 WriteFieldIntroducer(16,BegGrfObjMagic,0,0);
2406 WriteFieldId(7);
2408 // Map Color Attribute Table, Fonts und anderes:
2409 WriteObjectEnvironmentGroup(pMTF);
2411 //--- Das Feld 'Graphics Data Descriptor':
2412 WriteDataDescriptor(pMTF);
2414 // Zaehler fuer Data Fields initialisieren:
2415 nNumberOfDataFields=0;
2417 // Und Position des ersten Data Fields merken:
2418 nDataFieldsStartPos=pMET->Tell();
2420 //--- Anfang des ersten Feldes 'Graphics Data'
2421 WriteFieldIntroducer(0,DatGrfObjMagic,0,0);
2422 nNumberOfDataFields++;
2424 // Nun schreiben wir zunaechst den Kopf des Segments:
2425 *pMET << (BYTE)0x70 << (BYTE)0x0e << (sal_uInt32)0;
2426 *pMET << (BYTE)0x70 << (BYTE)0x10; // Flags
2427 *pMET << (USHORT)0; // Lo-Wort der Laenge der Segementdaten (Big Endian)
2428 *pMET << (sal_uInt32)0; // Reserved
2429 *pMET << (USHORT)0; // Hi-Wort der Laenge der Segementdaten (Big Endian) (Ohh Ohh OS2)
2430 // Anmerkung: die richtige Daten-Laenge schreiben wir weiter unten nochmal
2432 // Jetzt werden alle Orders rausgeschrieben:
2433 // (wobei die Sache ggf. in mehrere 'Graphics Data Fields' aufgeteilt
2434 // wird, per Methode WillWriteOrder(..))
2435 WriteOrders(pMTF);
2437 //--- Das letzte Feld 'Graphic Data' beenden:
2438 UpdateFieldSize();
2440 //--- Und schliesslich die Segmentgroesse richtigstellen:
2441 nPos=pMET->Tell();
2442 nSegmentSize=nPos-nDataFieldsStartPos;
2443 nSegmentSize-=nNumberOfDataFields*8; // Structured Field Introducers zaehlen nicht mit
2444 pMET->Seek(nDataFieldsStartPos+16); // Zum Lo-Wort der Segmentgroesse seeken
2445 WriteBigEndianShort((USHORT)(nSegmentSize&0x0000ffff)); // Und schreiben
2446 pMET->Seek(nDataFieldsStartPos+22); // Zum Hi-Wort der Segmentgroesse seeken
2447 WriteBigEndianShort((USHORT)(nSegmentSize>>16)); // Und schreiben
2448 pMET->Seek(nPos); // Zurueck zur Tagesordnung
2450 //--- Das Feld 'End Graphic Objects':
2451 WriteFieldIntroducer(16,EndGrfObjMagic,0,0);
2452 WriteFieldId(7);
2454 if( pMET->GetError() )
2455 bStatus=FALSE;
2459 void METWriter::WriteResourceGroup(const GDIMetaFile * pMTF)
2461 if( bStatus==FALSE )
2462 return;
2464 //--- Das Feld 'Begin Resource Group':
2465 WriteFieldIntroducer(16,BegResGrpMagic,0,0);
2466 WriteFieldId(2);
2468 //--- Der Inhalt:
2469 WriteColorAttributeTable();
2470 nActBitmapId=0x77777700;
2471 WriteImageObjects(pMTF);
2472 nActBitmapId=0x77777700;
2473 WriteGraphicsObject(pMTF);
2475 //--- Das Feld 'End Resource Group':
2476 WriteFieldIntroducer(16,EndResGrpMagic,0,0);
2477 WriteFieldId(2);
2479 if( pMET->GetError() )
2480 bStatus=FALSE;
2484 void METWriter::WriteDocument(const GDIMetaFile * pMTF)
2486 if( bStatus==FALSE )
2487 return;
2489 //--- Das Feld 'Begin Document':
2490 WriteFieldIntroducer(0,BegDocumnMagic,0,0);
2491 WriteFieldId(1);
2492 *pMET << (BYTE)0x00 << (BYTE)0x00;
2493 *pMET << (BYTE)0x05 << (BYTE)0x18 << (BYTE)0x03 << (BYTE)0x0c << (BYTE)0x00;
2494 *pMET << (BYTE)0x06 << (BYTE)0x01 << (BYTE)0x03 << (BYTE)0xd4 << (BYTE)0x03 << (BYTE)0x52;
2495 *pMET << (BYTE)0x03 << (BYTE)0x65 << (BYTE)0x00;
2496 UpdateFieldSize();
2498 //--- Der Inhalt:
2499 WriteResourceGroup(pMTF);
2501 //--- Das Feld 'End Document':
2502 WriteFieldIntroducer(16,EndDocumnMagic,0,0);
2503 WriteFieldId(1);
2505 if( pMET->GetError() )
2506 bStatus=FALSE;
2509 BOOL METWriter::WriteMET( const GDIMetaFile& rMTF, SvStream& rTargetStream, FilterConfigItem* pFilterConfigItem )
2511 if ( pFilterConfigItem )
2513 xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
2514 if ( xStatusIndicator.is() )
2516 rtl::OUString aMsg;
2517 xStatusIndicator->start( aMsg, 100 );
2521 METChrSet* pCS;
2522 METGDIStackMember* pGS;
2524 bStatus=TRUE;
2525 nLastPercent=0;
2527 pMET=&rTargetStream;
2528 pMET->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
2530 aPictureRect = Rectangle( Point(), rMTF.GetPrefSize() );
2531 aTargetMapMode = aPictureMapMode = rMTF.GetPrefMapMode();
2533 aGDILineColor=Color( COL_BLACK );
2534 aGDIFillColor=Color( COL_WHITE );
2535 eGDIRasterOp=ROP_OVERPAINT;
2536 aGDIFont=Font();
2537 aGDIMapMode=MapMode();
2538 aGDIClipRect=Rectangle();
2539 pGDIStack=NULL;
2540 aMETColor=Color(COL_BLACK);
2541 aMETBackgroundColor=Color(COL_WHITE);
2542 eMETMix=ROP_OVERPAINT;
2543 nMETStrokeLineWidth=1;
2544 aMETChrCellSize=Size(0,0);
2545 nMETChrAngle=0;
2546 nMETChrSet=0x00;
2547 pChrSetList=NULL;
2548 nNextChrSetId=1;
2549 nNumberOfActions=0;
2550 nNumberOfBitmaps=0;
2551 nWrittenActions=0;
2552 nWrittenBitmaps=0;
2553 nActBitmapPercent=0;
2555 CountActionsAndBitmaps(&rMTF);
2557 WriteDocument(&rMTF);
2559 while( pChrSetList )
2561 pCS=pChrSetList;
2562 pChrSetList=pCS->pSucc;
2563 delete pCS;
2566 while( pGDIStack )
2568 pGS=pGDIStack;
2569 pGDIStack=pGS->pSucc;
2570 delete pGS;
2573 if ( xStatusIndicator.is() )
2574 xStatusIndicator->end();
2576 return bStatus;
2579 //================== GraphicExport - die exportierte Funktion ================
2581 extern "C" BOOL __LOADONCALLAPI GraphicExport( SvStream & rStream, Graphic & rGraphic, FilterConfigItem* pFilterConfigItem, BOOL )
2582 { METWriter aMETWriter;
2584 if ( rGraphic.GetType() == GRAPHIC_GDIMETAFILE )
2585 return aMETWriter.WriteMET( rGraphic.GetGDIMetaFile(), rStream, pFilterConfigItem );
2586 else
2588 Bitmap aBmp=rGraphic.GetBitmap();
2589 GDIMetaFile aMTF;
2590 VirtualDevice aVirDev;
2592 aMTF.Record(&aVirDev);
2593 aVirDev.DrawBitmap(Point(),aBmp);
2594 aMTF.Stop();
2595 aMTF.SetPrefSize(aBmp.GetSizePixel());
2596 return aMETWriter.WriteMET( aMTF, rStream, pFilterConfigItem );
2600 //================== GraphicDialog - die exportierte Funktion ================
2602 extern "C" BOOL SAL_CALL DoExportDialog( FltCallDialogParameter& rPara )
2604 BOOL bRet = FALSE;
2606 if ( rPara.pWindow )
2608 ByteString aResMgrName( "eme" );
2609 ResMgr* pResMgr;
2611 pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
2613 if( pResMgr )
2615 rPara.pResMgr = pResMgr;
2616 bRet = ( DlgExportEMET( rPara ).Execute() == RET_OK );
2617 delete pResMgr;
2619 else
2620 bRet = TRUE;
2623 return bRet;
2626 //================== ein bischen Muell fuer Windows ==========================
2627 #ifndef GCC
2628 #endif
2630 #ifdef WIN
2632 static HINSTANCE hDLLInst = 0; // HANDLE der DLL
2634 extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR )
2636 #ifndef WNT
2637 if ( nHeap )
2638 UnlockData( 0 );
2639 #endif
2641 hDLLInst = hDLL;
2643 return TRUE;
2646 extern "C" int CALLBACK WEP( int )
2648 return 1;
2651 #endif