1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: eos2met.cxx,v $
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>
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
115 //============================== METWriter ===================================
119 struct METChrSet
* pSucc
;
125 struct METGDIStackMember
127 struct METGDIStackMember
* pSucc
;
141 ULONG nLastPercent
; // Mit welcher Zahl pCallback zuletzt aufgerufen wurde.
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'
150 RasterOp eGDIRasterOp
;
152 MapMode aGDIMapMode
; // derzeit unbenutzt!
153 Rectangle aGDIClipRect
; // derzeit unbenutzt!
154 METGDIStackMember
* pGDIStack
;
156 Color aMETBackgroundColor
;
157 Color aMETPatternSymbol
;
159 long nMETStrokeLineWidth
;
160 Size aMETChrCellSize
;
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
;
175 // Berechnet anhand der obigen 5 Parameter eine Prozentzahl
176 // und macht dann ggf. einen Callback. Setzt bStatus auf FALSE wenn User abbrechen
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
);
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
);
214 void METBeginPath(sal_uInt32 nPathId
);
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
);
252 BOOL
WriteMET( const GDIMetaFile
& rMTF
, SvStream
& rTargetStream
,
253 FilterConfigItem
* pConfigItem
);
257 //========================== Methoden von METWriter ==========================
259 void METWriter::MayCallback()
261 if ( xStatusIndicator
.is() )
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;
282 Polygon
aPoly( rRect
);
283 METBeginPath( nPathId
);
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();
307 for ( i
= 0; i
< nCount
; i
++ )
308 if ( ((const MetaAction
*)aGDIMetaFile
.GetAction( i
))->GetType() == META_BMPSCALE_ACTION
)
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
:
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()
363 pMET
->Seek(nActualFieldStartPos
);
364 WriteBigEndianShort((USHORT
)(nPos
-nActualFieldStartPos
));
369 void METWriter::WriteFieldId(ULONG nId
)
374 for (i
=1; i
<=8; i
++) {
375 nbyte
= '0' + (BYTE
)((nId
>> (32-i
*4)) & 0x0f);
381 void METWriter::CreateChrSets(const GDIMetaFile
* pMTF
)
383 ULONG nAction
, nActionCount
;
384 const MetaAction
* pMA
;
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() );
408 void METWriter::CreateChrSet(const Font
& rFont
)
412 if ( FindChrSet( rFont
) == 0 )
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
)
427 for (pCS
=pChrSetList
; pCS
!=NULL
; pCS
=pCS
->pSucc
)
429 if (pCS
->aName
==rFont
.GetName() && pCS
->eWeight
==rFont
.GetWeight() )
437 void METWriter::WriteChrSets()
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;
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());
485 if ( i
== 0 || c
!= 0 )
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'
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();
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;
537 //--- Das Feld 'End Color Attribute Table':
538 WriteFieldIntroducer(16,EndColAtrMagic
,0,0);
539 WriteFieldId(nFieldId
);
541 if (pMET
->GetError())
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
;
552 USHORT nBitsPerPixel
;
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:
568 // Header der Windows-BMP-Datei einlesen:
569 aTemp
.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN
);
571 aTemp
>> nWidth
>> nHeight
;
573 aTemp
>> nBitsPerPixel
;
575 aTemp
>> nResX
>> nResY
;
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
);
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);
632 *pMET
<< (BYTE
)0x70 << (BYTE
)0x00;
634 // Begin Image Content:
635 *pMET
<< (BYTE
)0x91 << (BYTE
)0x01 << (BYTE
)0xff;
638 *pMET
<< (BYTE
)0x94 << (BYTE
)0x09 << (BYTE
)0x02;
639 *pMET
<< (USHORT
) 0 << (USHORT
) 0;
640 WriteBigEndianShort((USHORT
)nHeight
);
641 WriteBigEndianShort((USHORT
)nWidth
);
644 *pMET
<< (BYTE
)0x95 << (BYTE
)0x02 << (BYTE
)0x03 << (BYTE
)0x03;
647 *pMET
<< (BYTE
)0x96 << (BYTE
)0x01 << (BYTE
)nBitsPerPixel
;
649 if (nBitsPerPixel
<=8) {
651 *pMET
<< (BYTE
)0x97 << (BYTE
)0x01 << (BYTE
)0x01;
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
];
664 // Abschliessen des vorherigen Feldes 'Image Picture Data':
667 // Und ein neues Feld 'Image Picture Data' anfangen:
668 WriteFieldIntroducer(0,DatImgObjMagic
,0,0);
670 // Einige Scanlines lesen und schreiben:
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
);
686 if (aTemp
.GetError() || pMET
->GetError()) bStatus
=FALSE
;
687 nActBitmapPercent
=(ny
+1)*100/nHeight
;
689 if (bStatus
==FALSE
) { delete[] pBuf
; return; }
693 // End Image Content:
694 *pMET
<< (BYTE
)0x93 << (BYTE
)0x00;
697 *pMET
<< (BYTE
)0x71 << (BYTE
)0x00;
699 // Abschliessen des letzten Feldes 'Image Picture Data':
702 //--- Das Feld 'End Image Object':
703 WriteFieldIntroducer(16,EndImgObjMagic
,0,0);
704 WriteFieldId(nActBitmapId
);
713 if (pMET
->GetError()) bStatus
=FALSE
;
717 void METWriter::WriteImageObjects(const GDIMetaFile
* pMTF
)
719 const MetaAction
* pMA
;
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() );
737 case META_BMPSCALE_ACTION
:
739 METSetMix( eGDIRasterOp
);
740 WriteImageObject( ( (MetaBmpScaleAction
*) pMA
)->GetBitmap() );
744 case META_BMPSCALEPART_ACTION
:
746 METSetMix( eGDIRasterOp
);
747 WriteImageObject( ( (MetaBmpScalePartAction
*) pMA
)->GetBitmap() );
751 case META_BMPEX_ACTION
:
753 METSetMix( eGDIRasterOp
);
754 WriteImageObject( Graphic( ( (MetaBmpExAction
*) pMA
)->GetBitmapEx() ).GetBitmap() );
758 case META_BMPEXSCALE_ACTION
:
760 METSetMix( eGDIRasterOp
);
761 WriteImageObject( Graphic( ( (MetaBmpExScaleAction
*) pMA
)->GetBitmapEx() ).GetBitmap() );
765 case META_BMPEXSCALEPART_ACTION
:
767 METSetMix( eGDIRasterOp
);
768 WriteImageObject( Graphic( ( (MetaBmpExScalePartAction
*) pMA
)->GetBitmapEx() ).GetBitmap() );
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() );
797 if (pMET
->GetError())
801 void METWriter::WriteDataDescriptor(const GDIMetaFile
*)
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
820 // 7 Length of following field 0x01
821 // 8 Coordinate types in data
824 *pMET
<< (BYTE
)0xf7 << (BYTE
)0x07 << (BYTE
)0xb0 << (BYTE
)0x00
825 << (BYTE
)0x00 << (BYTE
)0x23 << (BYTE
)0x01 << (BYTE
)0x01
828 // 0 0xF6 Set Picture Descriptor
829 // 1 Length of following data
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
837 // B'1' Pels (PU_PELS PS)
838 // (Bit 1 must also be set)
841 // 4 Picture frame size coordinate type
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
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())
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
871 // 0x00 Picture in 2D
878 *pMET
<< (BYTE
)0x21 << (BYTE
)0x07 << (BYTE
)0x08 << (BYTE
)0xe0
879 << (BYTE
)0x00 << (BYTE
)0x8f << (BYTE
)0x00 << (BYTE
)0x05
882 // 0 0x21 Set Current Defaults
883 // 1 Length of following data
884 // 2 Set default viewing transform 0x07
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:
901 // 0x0800 Stroke width
906 // 0x0F Set indicated default attributes to initial values. (Data field is not present in this
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
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
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
941 // 0x0FSet indicated default attributes to initial values. (Data field is not present in this
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
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:
971 // 0x1000 Marker precision
973 // 0x0100 Marker symbol
974 // 0x0008 Marker color
975 // 0x0004 Marker background color
977 // 0x0001 Marker background mix
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
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
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
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
1034 // 0x0001 Image background mix
1036 // 0x0F Set indicated default attributes to initial values. (Data field is not present in
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
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
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
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:
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
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
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
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
1105 if (nNumberOfBitmaps
>0) {
1106 *pMET
<< (BYTE
)0xe7 << (BYTE
)0x07 << (BYTE
)0x80 << (BYTE
)0x00;
1107 WriteBigEndianLong(nActBitmapId
);
1108 *pMET
<< (BYTE
)0xfe;
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)
1128 WriteFieldIntroducer(0,DatGrfObjMagic
,0,0);
1129 nNumberOfDataFields
++;
1135 void METWriter::METBitBlt(Point aPt
, Size aSize
, const Bitmap
& rBitmap
)
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
1159 if ( rLineInfo
.GetStyle() != LINE_SOLID
)
1161 BYTE nStyle
= 0; // LineDefault;
1163 switch ( rLineInfo
.GetStyle() )
1171 if ( rLineInfo
.GetDotCount() )
1173 if ( !rLineInfo
.GetDashCount() )
1174 nStyle
= 1; // LINE_DOT
1176 nStyle
= 3; // LINE_DASH_DOT
1179 nStyle
= 2; // LINE_DASH
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
1200 if ( rLineInfo
.GetStyle() != LINE_SOLID
)
1202 WillWriteOrder( 2 );
1203 *pMET
<< (BYTE
)0x18 << (BYTE
)0; // set LineType
1207 void METWriter::METBeginArea(BOOL bBoundaryLine
)
1210 *pMET
<< (BYTE
)0x68;
1211 if (bBoundaryLine
) *pMET
<< (BYTE
)0xc0;
1212 else *pMET
<< (BYTE
)0x80;
1216 void METWriter::METEndArea()
1219 *pMET
<< (BYTE
)0x60 << (BYTE
)0;
1223 void METWriter::METBeginPath(sal_uInt32 nPathId
)
1226 *pMET
<< (BYTE
)0xd0 << (BYTE
)6 << (USHORT
) 0 << nPathId
;
1230 void METWriter::METEndPath()
1233 *pMET
<< (BYTE
)0x7f << (BYTE
)0;
1237 void METWriter::METFillPath(sal_uInt32 nPathId
)
1240 *pMET
<< (BYTE
)0xd7 << (BYTE
)6
1241 << (BYTE
)0x00 << (BYTE
)0 << nPathId
;
1245 void METWriter::METOutlinePath(sal_uInt32 nPathId
)
1248 *pMET
<< (BYTE
)0xd4 << (BYTE
)6
1249 << (BYTE
)0 << (BYTE
)0 << nPathId
;
1253 void METWriter::METCloseFigure()
1256 *pMET
<< (BYTE
)0x7d << (BYTE
)0;
1260 void METWriter::METMove(Point aPt
)
1263 *pMET
<< (BYTE
)0x21 << (BYTE
)8;
1268 void METWriter::METLine(Point aPt1
, Point aPt2
)
1271 *pMET
<< (BYTE
)0xc1 << (BYTE
)16;
1272 WritePoint(aPt1
); WritePoint(aPt2
);
1276 void METWriter::METLine(const Polygon
& rPolygon
)
1278 USHORT nNumPoints
,i
,j
,nOrderPoints
;
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
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
)
1303 nCount
=rPolyPolygon
.Count();
1304 for (i
=0; i
<nCount
; i
++) {
1305 METLine(rPolyPolygon
.GetObject(i
));
1311 void METWriter::METLineAtCurPos(Point aPt
)
1314 *pMET
<< (BYTE
)0x81 << (BYTE
)8;
1319 void METWriter::METBox(BOOL bFill
, BOOL bBoundary
,
1320 Rectangle aRect
, sal_uInt32 nHAxis
, sal_uInt32 nVAxis
)
1323 if (bFill
) nFlags
|=0x40;
1324 if (bBoundary
) nFlags
|=0x20;
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
)
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;
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
)
1364 ByteString
aStr( aUniStr
, gsl_getSystemTextEncoding() );
1366 WillWriteOrder( 11 + nLen
);
1367 *pMET
<< (BYTE
)0xc3 << (BYTE
)( 9 + nLen
);
1369 for ( i
= 0; i
< nLen
; i
++ )
1370 *pMET
<< aStr
.GetChar( i
);
1375 void METWriter::METSetArcParams(long nP
, long nQ
, long nR
, long nS
)
1378 *pMET
<< (BYTE
)0x22 << (BYTE
)16 << nP
<< nQ
<< nR
<< nS
;
1382 void METWriter::METSetColor(Color aColor
)
1384 if (aColor
==aMETColor
) return;
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
;
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
)
1418 case ROP_INVERT
: nMix
=0x0c; break;
1419 case ROP_XOR
: nMix
=0x04; break;
1424 *pMET
<< (BYTE
)0x0c << nMix
;
1428 void METWriter::METSetChrCellSize(Size aSize
)
1430 if (aMETChrCellSize
==aSize
)
1433 aMETChrCellSize
=aSize
;
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
)
1445 if (nMETChrAngle
==nAngle
) return;
1446 nMETChrAngle
=nAngle
;
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);
1461 *pMET
<< (BYTE
)0x34 << (BYTE
)8 << nax
<< nay
;
1465 void METWriter::METSetChrSet(BYTE nSet
)
1467 if (nMETChrSet
==nSet
)
1472 *pMET
<< (BYTE
)0x38 << nSet
;
1476 void METWriter::WriteOrders( const GDIMetaFile
* pMTF
)
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() );
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);
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
);
1522 METLine( pA
->GetStartPoint(), pA
->GetEndPoint() );
1524 METOutlinePath( 1 );
1526 if ( ! ( aLineInfo
.IsDefault() ) )
1527 METPopLineInfo( aLineInfo
);
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 );
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() );
1574 case META_ELLIPSE_ACTION
:
1576 const MetaEllipseAction
* pA
= (const MetaEllipseAction
*) pMA
;
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);
1594 if( aGDILineColor
!= Color( COL_TRANSPARENT
) )
1596 METSetMix( eGDIRasterOp
);
1597 METSetColor( aGDILineColor
);
1598 METFullArc( aCenter
,0.5 );
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);
1633 METPartialArcAtCurPos(aCenter
,0.5,fa1
,fa2
-fa1
);
1640 case META_PIE_ACTION
:
1642 const MetaPieAction
* pA
= (const MetaPieAction
*) pMA
;
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
);
1670 METPartialArcAtCurPos(aCenter
,0.5,fa1
,fa2
-fa1
);
1671 METLineAtCurPos(aCenter
);
1676 if( aGDILineColor
!= Color( COL_TRANSPARENT
) )
1678 METSetMix( eGDIRasterOp
);
1679 METSetColor( aGDILineColor
);
1682 METPartialArcAtCurPos(aCenter
,0.5,fa1
,fa2
-fa1
);
1683 METLineAtCurPos(aCenter
);
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
);
1720 METPartialArcAtCurPos(aCenter
,0.5,fa1
,fa2
-fa1
);
1721 METLineAtCurPos(aStartPos
);
1726 if( aGDILineColor
!= Color( COL_TRANSPARENT
) )
1728 METSetMix( eGDIRasterOp
);
1729 METSetColor( aGDILineColor
);
1732 METPartialArcAtCurPos(aCenter
,0.5,fa1
,fa2
-fa1
);
1733 METLineAtCurPos(aStartPos
);
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
);
1753 Polygon aSimplePoly
;
1754 const Polygon
& rPoly
= pA
->GetPolygon();
1755 if ( rPoly
.HasFlags() )
1756 rPoly
.GetSimple( aSimplePoly
);
1758 aSimplePoly
= rPoly
;
1759 METLine( aSimplePoly
);
1763 if ( ! ( aLineInfo
.IsDefault() ) )
1764 METPopLineInfo( aLineInfo
);
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
);
1777 aSimplePoly
= rPoly
;
1778 if( aGDIFillColor
!= Color( COL_TRANSPARENT
) )
1780 METSetMix(eGDIRasterOp
);
1781 METSetColor(aGDIFillColor
);
1782 METSetBackgroundColor(aGDIFillColor
);
1784 METLine( aSimplePoly
);
1789 if( aGDILineColor
!= Color( COL_TRANSPARENT
) )
1791 METSetMix(eGDIRasterOp
);
1792 METSetColor(aGDILineColor
);
1794 METLine( aSimplePoly
);
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
);
1822 METLine( aSimplePolyPoly
);
1827 if( aGDILineColor
!= Color( COL_TRANSPARENT
) )
1829 METSetMix(eGDIRasterOp
);
1830 METSetColor(aGDILineColor
);
1832 METLine( aSimplePolyPoly
);
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();
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()));
1864 case META_TEXTARRAY_ACTION
:
1866 const MetaTextArrayAction
* pA
= (const MetaTextArrayAction
*) pMA
;
1869 Polygon
aPolyDummy(1);
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();
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
)
1894 for( i
=0; i
< aStr
.Len(); i
++ )
1899 aPt2
.X() += pA
->GetDXArray()[i
-1];
1902 aPolyDummy
.SetPoint( aPt2
, 0 );
1903 aPolyDummy
.Rotate( aPt
, nOrientation
);
1904 aPt2
= aPolyDummy
.GetPoint( 0 );
1907 METChrStr( aPt2
, String( aStr
.GetChar( i
) ) );
1911 METChrStr( aPt
, aStr
);
1915 case META_STRETCHTEXT_ACTION
:
1917 const MetaStretchTextAction
* pA
= (const MetaStretchTextAction
*) pMA
;
1918 VirtualDevice aVDev
;
1921 sal_Int32 nNormSize
;
1923 Polygon
aPolyDummy(1);
1925 Point
aPt( pA
->GetPoint() );
1928 aVDev
.SetFont( aGDIFont
);
1930 if( aGDIFont
.GetAlign() != ALIGN_BASELINE
)
1932 if( aGDIFont
.GetAlign() == ALIGN_TOP
)
1933 aPt
.Y()+=(long)aVDev
.GetFontMetric().GetAscent();
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
++ )
1953 aPt2
.X() += pDXAry
[i
-1]*((long)pA
->GetWidth())/ nNormSize
;
1956 aPolyDummy
.SetPoint( aPt2
, 0 );
1957 aPolyDummy
.Rotate( aPt
, nOrientation
);
1958 aPt2
= aPolyDummy
.GetPoint( 0 );
1961 METChrStr( aPt2
, String( aStr
.GetChar( i
) ) );
1968 case META_TEXTRECT_ACTION
:
1970 // DBG_ERROR( "Unsupported MET-Action: META_TEXTRECT_ACTION!" );
1974 case META_BMP_ACTION
:
1976 const MetaBmpAction
* pA
= (const MetaBmpAction
*) pMA
;
1978 METSetMix(eGDIRasterOp
);
1979 METBitBlt( pA
->GetPoint(), pA
->GetBitmap().GetSizePixel(), pA
->GetBitmap() );
1983 case META_BMPSCALE_ACTION
:
1985 const MetaBmpScaleAction
* pA
= (const MetaBmpScaleAction
*) pMA
;
1987 METSetMix(eGDIRasterOp
);
1988 METBitBlt( pA
->GetPoint(), pA
->GetSize(), pA
->GetBitmap() );
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
);
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
);
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
);
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
);
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() );
2054 case META_MASK_ACTION
:
2056 // DBG_ERROR( "Unsupported MET-Action: META_MASK_ACTION!" );
2060 case META_MASKSCALE_ACTION
:
2062 // DBG_ERROR( "Unsupported MET-Action: META_MASKSCALE_ACTION!" );
2066 case META_MASKSCALEPART_ACTION
:
2068 // DBG_ERROR( "Unsupported MET-Action: META_MASKSCALEPART_ACTION!" );
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
);
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
);
2096 case META_WALLPAPER_ACTION
:
2098 // DBG_ERROR( "Unsupported MET-Action: META_WALLPAPER_ACTION!" );
2102 case META_CLIPREGION_ACTION
:
2104 // DBG_ERROR( "Unsupported MET-Action: META_CLIPREGION_ACTION!" );
2108 case META_ISECTRECTCLIPREGION_ACTION
:
2110 const MetaISectRectClipRegionAction
* pA
= (const MetaISectRectClipRegionAction
*) pMA
;
2111 WriteClipRect( pA
->GetRect() );
2115 case META_ISECTREGIONCLIPREGION_ACTION
:
2117 // DBG_ERROR( "Unsupported MET-Action: META_ISECTREGIONCLIPREGION_ACTION!" );
2121 case META_MOVECLIPREGION_ACTION
:
2123 // DBG_ERROR( "Unsupported MET-Action: META_MOVECLIPREGION_ACTION!" );
2127 case META_LINECOLOR_ACTION
:
2129 const MetaLineColorAction
* pA
= (const MetaLineColorAction
*) pMA
;
2131 if( pA
->IsSetting() )
2132 aGDILineColor
= pA
->GetColor();
2134 aGDILineColor
= Color( COL_TRANSPARENT
);
2138 case META_FILLCOLOR_ACTION
:
2140 const MetaFillColorAction
* pA
= (const MetaFillColorAction
*) pMA
;
2142 if( pA
->IsSetting() )
2143 aGDIFillColor
= pA
->GetColor();
2145 aGDIFillColor
= Color( COL_TRANSPARENT
);
2149 case META_TEXTCOLOR_ACTION
:
2151 const MetaTextColorAction
* pA
= (const MetaTextColorAction
*) pMA
;
2152 aGDIFont
.SetColor( pA
->GetColor() );
2156 case META_TEXTFILLCOLOR_ACTION
:
2158 const MetaTextFillColorAction
* pA
= (const MetaTextFillColorAction
*) pMA
;
2160 if( pA
->IsSetting() )
2161 aGDIFont
.SetFillColor( pA
->GetColor() );
2163 aGDIFont
.SetFillColor( Color( COL_TRANSPARENT
) );
2167 case META_TEXTALIGN_ACTION
:
2169 // DBG_ERROR( "Unsupported MET-Action: META_TEXTALIGN_ACTION!" );
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 );
2194 aX
-= BigInt( (aScaleX
.GetNumerator()+1)/2 );
2198 if( aScaleX
.GetNumerator() >= 0 )
2199 aX
-= BigInt( (aScaleX
.GetNumerator()-1)/2 );
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 );
2215 aY
-= BigInt( (aScaleY
.GetNumerator()+1)/2 );
2219 if( aScaleY
.GetNumerator() >= 0 )
2220 aY
-= BigInt( (aScaleY
.GetNumerator()-1)/2 );
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
);
2235 aPictureMapMode
=pA
->GetMapMode();
2240 case META_FONT_ACTION
:
2242 aGDIFont
= ( (const MetaFontAction
*) pMA
)->GetFont();
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
;
2260 case META_POP_ACTION
:
2262 METGDIStackMember
* pGS
;
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
;
2279 case META_RASTEROP_ACTION
:
2281 eGDIRasterOp
= ( (const MetaRasterOpAction
*) pMA
)->GetRasterOp();
2285 case META_TRANSPARENT_ACTION
:
2287 if( aGDIFillColor
!= Color( COL_TRANSPARENT
) )
2289 METSetMix(eGDIRasterOp
);
2290 METSetColor(aGDIFillColor
);
2291 METSetBackgroundColor(aGDIFillColor
);
2293 METLine(( (const MetaTransparentAction
*) pMA
)->GetPolyPolygon());
2298 if( aGDILineColor
!= Color( COL_TRANSPARENT
) )
2300 METSetMix(eGDIRasterOp
);
2301 METSetColor(aGDILineColor
);
2303 METLine(( (const MetaTransparentAction
*) pMA
)->GetPolyPolygon());
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
);
2342 if( pMET
->GetError() )
2345 if( bStatus
== FALSE
)
2350 void METWriter::WriteObjectEnvironmentGroup(const GDIMetaFile
* pMTF
)
2354 //--- Das Feld 'Begin Object Environment Group':
2355 WriteFieldIntroducer(16,BegObjEnvMagic
,0,0);
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;
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
);
2378 //--- Die Felder 'Map Data Resource':
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;
2386 *pMET
<< (BYTE
)0x07 << (BYTE
)0x22 << (BYTE
)0x10;
2387 *pMET
<< (sal_uInt32
)nId
;
2391 //--- Das Feld 'End Object Environment Group':
2392 WriteFieldIntroducer(16,EndObjEnvMagic
,0,0);
2397 void METWriter::WriteGraphicsObject(const GDIMetaFile
* pMTF
)
2399 ULONG nSegmentSize
,nPos
,nDataFieldsStartPos
;
2401 if( bStatus
==FALSE
)
2404 //--- Das Feld 'Begin Graphics Object':
2405 WriteFieldIntroducer(16,BegGrfObjMagic
,0,0);
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(..))
2437 //--- Das letzte Feld 'Graphic Data' beenden:
2440 //--- Und schliesslich die Segmentgroesse richtigstellen:
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);
2454 if( pMET
->GetError() )
2459 void METWriter::WriteResourceGroup(const GDIMetaFile
* pMTF
)
2461 if( bStatus
==FALSE
)
2464 //--- Das Feld 'Begin Resource Group':
2465 WriteFieldIntroducer(16,BegResGrpMagic
,0,0);
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);
2479 if( pMET
->GetError() )
2484 void METWriter::WriteDocument(const GDIMetaFile
* pMTF
)
2486 if( bStatus
==FALSE
)
2489 //--- Das Feld 'Begin Document':
2490 WriteFieldIntroducer(0,BegDocumnMagic
,0,0);
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;
2499 WriteResourceGroup(pMTF
);
2501 //--- Das Feld 'End Document':
2502 WriteFieldIntroducer(16,EndDocumnMagic
,0,0);
2505 if( pMET
->GetError() )
2509 BOOL
METWriter::WriteMET( const GDIMetaFile
& rMTF
, SvStream
& rTargetStream
, FilterConfigItem
* pFilterConfigItem
)
2511 if ( pFilterConfigItem
)
2513 xStatusIndicator
= pFilterConfigItem
->GetStatusIndicator();
2514 if ( xStatusIndicator
.is() )
2517 xStatusIndicator
->start( aMsg
, 100 );
2522 METGDIStackMember
* pGS
;
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
;
2537 aGDIMapMode
=MapMode();
2538 aGDIClipRect
=Rectangle();
2540 aMETColor
=Color(COL_BLACK
);
2541 aMETBackgroundColor
=Color(COL_WHITE
);
2542 eMETMix
=ROP_OVERPAINT
;
2543 nMETStrokeLineWidth
=1;
2544 aMETChrCellSize
=Size(0,0);
2553 nActBitmapPercent
=0;
2555 CountActionsAndBitmaps(&rMTF
);
2557 WriteDocument(&rMTF
);
2559 while( pChrSetList
)
2562 pChrSetList
=pCS
->pSucc
;
2569 pGDIStack
=pGS
->pSucc
;
2573 if ( xStatusIndicator
.is() )
2574 xStatusIndicator
->end();
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
);
2588 Bitmap aBmp
=rGraphic
.GetBitmap();
2590 VirtualDevice aVirDev
;
2592 aMTF
.Record(&aVirDev
);
2593 aVirDev
.DrawBitmap(Point(),aBmp
);
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
)
2606 if ( rPara
.pWindow
)
2608 ByteString
aResMgrName( "eme" );
2611 pResMgr
= ResMgr::CreateResMgr( aResMgrName
.GetBuffer(), Application::GetSettings().GetUILocale() );
2615 rPara
.pResMgr
= pResMgr
;
2616 bRet
= ( DlgExportEMET( rPara
).Execute() == RET_OK
);
2626 //================== ein bischen Muell fuer Windows ==========================
2632 static HINSTANCE hDLLInst
= 0; // HANDLE der DLL
2634 extern "C" int CALLBACK
LibMain( HINSTANCE hDLL
, WORD
, WORD nHeap
, LPSTR
)
2646 extern "C" int CALLBACK
WEP( int )