Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <vcl/fltcall.hxx>
21 :
22 : #include <math.h>
23 : #include <tools/stream.hxx>
24 : #include <tools/bigint.hxx>
25 : #include <vcl/metaact.hxx>
26 : #include <vcl/salbtype.hxx>
27 : #include <tools/poly.hxx>
28 : #include <vcl/graph.hxx>
29 : #include <vcl/gradient.hxx>
30 : #include <vcl/hatch.hxx>
31 : #include <vcl/metric.hxx>
32 : #include <vcl/font.hxx>
33 : #include <vcl/virdev.hxx>
34 : #include <vcl/svapp.hxx>
35 : #include <vcl/msgbox.hxx>
36 : #include <svl/solar.hrc>
37 : #include <vcl/gdimetafiletools.hxx>
38 : #include <vcl/dibtools.hxx>
39 : #include <boost/scoped_array.hpp>
40 :
41 : // -----------------------------Field Types-------------------------------
42 :
43 : #define BegDocumnMagic 0xA8A8 /* Begin Document */
44 : #define EndDocumnMagic 0xA8A9 /* End Document */
45 :
46 : #define BegResGrpMagic 0xC6A8 /* Begin Resource Group */
47 : #define EndResGrpMagic 0xC6A9 /* End Resource Group */
48 :
49 : #define BegColAtrMagic 0x77A8 /* Begin Color Attribute Table */
50 : #define EndColAtrMagic 0x77A9 /* End Color Attribute Table */
51 : #define BlkColAtrMagic 0x77B0 /* Color Attribute Table */
52 : #define MapColAtrMagic 0x77AB /* Map Color Attribute Table */
53 :
54 : #define BegImgObjMagic 0xFBA8 /* Begin Image Object */
55 : #define EndImgObjMagic 0xFBA9 /* End Image Object */
56 : #define DscImgObjMagic 0xFBA6 /* Image Data Descriptor */
57 : #define DatImgObjMagic 0xFBEE /* Image Picture Data */
58 :
59 : #define BegObjEnvMagic 0xC7A8 /* Begin Object Environment Group */
60 : #define EndObjEnvMagic 0xC7A9 /* End Object Environment Group */
61 :
62 : #define BegGrfObjMagic 0xBBA8 /* Begin Graphics Object */
63 : #define EndGrfObjMagic 0xBBA9 /* End Graphics Object */
64 : #define DscGrfObjMagic 0xBBA6 /* Graphics Data Descritor */
65 : #define DatGrfObjMagic 0xBBEE /* Graphics Data */
66 :
67 : #define MapCodFntMagic 0x8AAB /* Map Coded Font */
68 : #define MapDatResMagic 0xC3AB /* Map Data Resource */
69 :
70 : // Struktur des Metafiles
71 : // BegDocumn
72 : // BegResGrp
73 : // BegColAtr
74 : // BlkColAtr
75 : // EndColAtr
76 : // BegImgObj[0..n]
77 : // BegResGrp[]
78 : // BegColAtr[]
79 : // BlkColAtr
80 : // EndColAtr
81 : // EndResGrp
82 : // BegObjEnv[]
83 : // MapColAtr
84 : // EndObjEnv
85 : // DscImgObj
86 : // DatImgOb1
87 : // DatImgOb2[1..n]
88 : // EndImgObj
89 : // BegGrfObj
90 : // BegObjEnv[]
91 : // MapColAtr
92 : // MapCodFnt1
93 : // MapCodFnt2[0..n]
94 : // MapDatRes[0..n]
95 : // EndObjEnv
96 : // DscGrfObj
97 : // DatGrfObj[0..n]
98 : // EndGrfObj
99 : // EndResGrp
100 : // EndDocumn
101 :
102 : //============================== METWriter ===================================
103 :
104 0 : struct METChrSet
105 : {
106 : struct METChrSet * pSucc;
107 : sal_uInt8 nSet;
108 : OUString aName;
109 : FontWeight eWeight;
110 : };
111 :
112 0 : struct METGDIStackMember
113 : {
114 : struct METGDIStackMember * pSucc;
115 : Color aLineColor;
116 : Color aFillColor;
117 : RasterOp eRasterOp;
118 : Font aFont;
119 : MapMode aMapMode;
120 : Rectangle aClipRect;
121 : };
122 :
123 0 : class METWriter
124 : {
125 : private:
126 :
127 : sal_Bool bStatus;
128 : sal_uLong nLastPercent; // with which number pCallback has been called the last time
129 : SvStream* pMET;
130 : Rectangle aPictureRect;
131 : MapMode aPictureMapMode;
132 : MapMode aTargetMapMode;
133 : sal_uLong nActualFieldStartPos; // start position of the current 'Field'
134 : sal_uLong nNumberOfDataFields; // number of commenced 'Graphcis Data Fields'
135 : Color aGDILineColor;
136 : Color aGDIFillColor;
137 : RasterOp eGDIRasterOp;
138 : Font aGDIFont;
139 : MapMode aGDIMapMode; // currently ununsed!
140 : Rectangle aGDIClipRect; // currently ununsed!
141 : METGDIStackMember* pGDIStack;
142 : Color aMETColor;
143 : Color aMETBackgroundColor;
144 : Color aMETPatternSymbol;
145 : RasterOp eMETMix ;
146 : long nMETStrokeLineWidth;
147 : Size aMETChrCellSize;
148 : short nMETChrAngle;
149 : sal_uInt8 nMETChrSet;
150 : METChrSet* pChrSetList; // list of Character-Sets
151 : sal_uInt8 nNextChrSetId; // the first unused ChrSet-Id
152 : sal_uLong nActBitmapId; // Field-Id of the next Bitmap
153 : sal_uLong nNumberOfActions; // number of Actions in the GDIMetafile
154 : sal_uLong nNumberOfBitmaps; // number of Bitmaps
155 : sal_uLong nWrittenActions; // number of already processed actions during the writing of the orders
156 : sal_uLong nWrittenBitmaps; // number of already written Bitmaps
157 : sal_uLong nActBitmapPercent; // percentage of the next bitmap that's already written
158 :
159 : ::std::auto_ptr< VirtualDevice > apDummyVDev;
160 : OutputDevice* pCompDev;
161 :
162 : com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;
163 :
164 : void MayCallback();
165 : // calculates a percentage based on the 5 parameters above and then does a
166 : // Callback as the case may be. Sets bStatus to sal_False if the user wants to cancel
167 :
168 : void CountActionsAndBitmaps(const GDIMetaFile * pMTF);
169 : // Counts the bitmaps and actions (nNumberOfActions and nNumberOfBitmaps have to
170 : // be set to 0 at the beginning, since this method is recursive)
171 :
172 : void WriteBigEndianShort(sal_uInt16 nWord);
173 : void WriteBigEndianLong(sal_uLong nLong);
174 :
175 : void WritePoint(Point aPt);
176 : void WriteClipRect( const Rectangle& rRect );
177 : void WriteFieldIntroducer(sal_uInt16 nFieldSize, sal_uInt16 nFieldType,
178 : sal_uInt8 nFlags, sal_uInt16 nSegSeqNum);
179 : void UpdateFieldSize();
180 :
181 : void WriteFieldId(sal_uLong nId);
182 :
183 : void CreateChrSets(const GDIMetaFile * pMTF);
184 : void CreateChrSet(const Font & rFont);
185 : void WriteChrSets();
186 : sal_uInt8 FindChrSet(const Font & rFont);
187 :
188 : void WriteColorAttributeTable(sal_uLong nFieldId=4, BitmapPalette* pPalette=NULL,
189 : sal_uInt8 nBasePartFlags=0x40, sal_uInt8 nBasePartLCTID=0);
190 :
191 : void WriteImageObject(const Bitmap & rBitmap);
192 : void WriteImageObjects(const GDIMetaFile * pMTF);
193 :
194 : void WriteDataDescriptor(const GDIMetaFile * pMTF);
195 :
196 : void WillWriteOrder(sal_uLong nNextOrderMaximumLength);
197 :
198 : void METSetAndPushLineInfo( const LineInfo& rLineInfo );
199 : void METPopLineInfo( const LineInfo& rLineInfo );
200 : void METBitBlt(Point aPt, Size aSize, const Size& rSizePixel);
201 : void METBeginArea(sal_Bool bBoundaryLine);
202 : void METEndArea();
203 : void METBeginPath(sal_uInt32 nPathId);
204 : void METEndPath();
205 : void METFillPath(sal_uInt32 nPathId);
206 : void METOutlinePath(sal_uInt32 nPathId);
207 : void METCloseFigure();
208 : void METMove(Point aPt);
209 : void METLine(Point aPt1, Point aPt2);
210 : void METLine(const Polygon & rPolygon);
211 : void METLine(const PolyPolygon & rPolyPolygon);
212 : void METLineAtCurPos(Point aPt);
213 : void METBox(sal_Bool bFill, sal_Bool bBoundary,
214 : Rectangle aRect, sal_uInt32 nHAxis, sal_uInt32 nVAxis);
215 : void METFullArc(Point aCenter, double fMultiplier);
216 : void METPartialArcAtCurPos(Point aCenter, double fMultiplier,
217 : double fStartAngle, double fSweepAngle);
218 : void METChrStr(Point aPt, const OUString& aStr);
219 : void METSetArcParams(sal_Int32 nP, sal_Int32 nQ, sal_Int32 nR, sal_Int32 nS);
220 : void METSetColor(Color aColor);
221 : void METSetBackgroundColor(Color aColor);
222 : void METSetMix(RasterOp eROP);
223 : void METSetChrCellSize(Size aSize);
224 : void METSetChrAngle(short nAngle);
225 : void METSetChrSet(sal_uInt8 nSet);
226 :
227 : void WriteOrders(const GDIMetaFile * pMTF);
228 :
229 : void WriteObjectEnvironmentGroup(const GDIMetaFile * pMTF);
230 :
231 : void WriteGraphicsObject(const GDIMetaFile * pMTF);
232 :
233 : void WriteResourceGroup(const GDIMetaFile * pMTF);
234 :
235 : void WriteDocument(const GDIMetaFile * pMTF);
236 :
237 : public:
238 :
239 0 : METWriter()
240 : : bStatus(sal_False)
241 : , nLastPercent( 0 )
242 : , pMET(NULL)
243 : , nActualFieldStartPos( 0 )
244 : , nNumberOfDataFields( 0 )
245 : , eGDIRasterOp( ROP_OVERPAINT )
246 : , pGDIStack(NULL)
247 : , eMETMix( ROP_OVERPAINT )
248 : , nMETStrokeLineWidth(0)
249 : , nMETChrAngle(0)
250 : , nMETChrSet( 0 )
251 : , pChrSetList(NULL)
252 : , nNextChrSetId( 0 )
253 : , nActBitmapId( 0 )
254 : , nNumberOfActions( 0 )
255 : , nNumberOfBitmaps( 0 )
256 : , nWrittenActions( 0 )
257 : , nWrittenBitmaps( 0 )
258 : , nActBitmapPercent( 0 )
259 0 : , pCompDev(NULL)
260 : {
261 0 : pCompDev = reinterpret_cast< OutputDevice* >( Application::GetAppWindow() );
262 0 : if( !pCompDev )
263 : {
264 0 : apDummyVDev.reset( new VirtualDevice );
265 0 : pCompDev = apDummyVDev.get();
266 : }
267 0 : }
268 :
269 : sal_Bool WriteMET( const GDIMetaFile & rMTF, SvStream & rTargetStream,
270 : FilterConfigItem* pConfigItem );
271 : };
272 :
273 :
274 : //========================== Methods of METWriter ==========================
275 :
276 0 : void METWriter::MayCallback()
277 : {
278 0 : if ( xStatusIndicator.is() )
279 : {
280 : sal_uLong nPercent;
281 0 : nPercent=((nWrittenBitmaps<<14)+(nActBitmapPercent<<14)/100+nWrittenActions)
282 0 : *100/((nNumberOfBitmaps<<14)+nNumberOfActions);
283 :
284 0 : if (nPercent>=nLastPercent+3)
285 : {
286 0 : nLastPercent = nPercent;
287 0 : if ( nPercent <= 100 )
288 0 : xStatusIndicator->setValue( nPercent );
289 : }
290 : }
291 0 : }
292 :
293 0 : void METWriter::WriteClipRect( const Rectangle& rRect )
294 : {
295 0 : aGDIClipRect = rRect;
296 0 : sal_uInt32 nPathId = ( rRect.IsEmpty() ) ? 0 : 1;
297 0 : if ( nPathId )
298 : {
299 0 : Polygon aPoly( rRect );
300 0 : METBeginPath( nPathId );
301 0 : METLine( aPoly );
302 0 : METEndPath();
303 : }
304 0 : WillWriteOrder(8);
305 0 : pMET->WriteUChar( (sal_uInt8)0xb4 ).WriteUChar( (sal_uInt8)6 )
306 0 : .WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0 ).WriteUInt32( nPathId );
307 0 : }
308 :
309 0 : void METWriter::CountActionsAndBitmaps(const GDIMetaFile * pMTF)
310 : {
311 : const MetaAction* pMA;
312 :
313 0 : for( size_t nAction = 0, nActionCount=pMTF->GetActionSize(); nAction < nActionCount; nAction++ )
314 : {
315 0 : pMA = pMTF->GetAction(nAction);
316 :
317 0 : switch (pMA->GetType())
318 : {
319 : case META_EPS_ACTION :
320 : {
321 0 : const GDIMetaFile aGDIMetaFile( ((const MetaEPSAction*)pMA)->GetSubstitute() );
322 0 : size_t nCount = aGDIMetaFile.GetActionSize();
323 : size_t i;
324 0 : for ( i = 0; i < nCount; i++ )
325 0 : if ( ((const MetaAction*)aGDIMetaFile.GetAction( i ))->GetType() == META_BMPSCALE_ACTION )
326 0 : break;
327 0 : if ( i == nCount)
328 0 : break;
329 : }
330 : case META_BMP_ACTION:
331 : case META_BMPSCALE_ACTION:
332 : case META_BMPSCALEPART_ACTION:
333 : case META_BMPEX_ACTION:
334 : case META_BMPEXSCALE_ACTION:
335 : case META_BMPEXSCALEPART_ACTION:
336 0 : nNumberOfBitmaps++;
337 0 : break;
338 : }
339 0 : nNumberOfActions++;
340 : }
341 0 : }
342 :
343 :
344 0 : void METWriter::WriteBigEndianShort(sal_uInt16 nWord)
345 : {
346 0 : pMET->WriteUChar( (sal_uInt8)(nWord>>8) ).WriteUChar( (sal_uInt8)(nWord&0x00ff) );
347 0 : }
348 :
349 :
350 0 : void METWriter::WriteBigEndianLong(sal_uLong nLong)
351 : {
352 0 : WriteBigEndianShort((sal_uInt16)(nLong>>16));
353 0 : WriteBigEndianShort((sal_uInt16)(nLong&0x0000ffff));
354 0 : }
355 :
356 :
357 0 : void METWriter::WritePoint(Point aPt)
358 : {
359 0 : Point aNewPt = pCompDev->LogicToLogic( aPt, aPictureMapMode, aTargetMapMode );
360 :
361 0 : pMET->WriteInt32( (sal_Int32) ( aNewPt.X() - aPictureRect.Left() ) )
362 0 : .WriteInt32( (sal_Int32) ( aPictureRect.Bottom() - aNewPt.Y() ) );
363 0 : }
364 :
365 :
366 0 : void METWriter::WriteFieldIntroducer(sal_uInt16 nFieldSize, sal_uInt16 nFieldType,
367 : sal_uInt8 nFlags, sal_uInt16 nSegSeqNum)
368 : {
369 0 : nActualFieldStartPos=pMET->Tell();
370 0 : WriteBigEndianShort(nFieldSize);
371 0 : pMET->WriteUChar( (sal_uInt8)0xd3 ).WriteUInt16( nFieldType ).WriteUChar( nFlags ).WriteUInt16( nSegSeqNum );
372 0 : }
373 :
374 :
375 0 : void METWriter::UpdateFieldSize()
376 : {
377 : sal_uLong nPos;
378 :
379 0 : nPos=pMET->Tell();
380 0 : pMET->Seek(nActualFieldStartPos);
381 0 : WriteBigEndianShort((sal_uInt16)(nPos-nActualFieldStartPos));
382 0 : pMET->Seek(nPos);
383 0 : }
384 :
385 :
386 0 : void METWriter::WriteFieldId(sal_uLong nId)
387 : {
388 : sal_uInt8 nbyte;
389 : short i;
390 :
391 0 : for (i=1; i<=8; i++) {
392 0 : nbyte= '0' + (sal_uInt8)((nId >> (32-i*4)) & 0x0f);
393 0 : pMET->WriteUChar( nbyte );
394 : }
395 0 : }
396 :
397 :
398 0 : void METWriter::CreateChrSets(const GDIMetaFile * pMTF)
399 : {
400 : size_t nAction, nActionCount;
401 : const MetaAction * pMA;
402 :
403 0 : if (bStatus==sal_False)
404 0 : return;
405 :
406 0 : nActionCount = pMTF->GetActionSize();
407 :
408 0 : for (nAction = 0; nAction < nActionCount; nAction++)
409 : {
410 0 : pMA = pMTF->GetAction(nAction);
411 :
412 0 : switch (pMA->GetType())
413 : {
414 : case META_FONT_ACTION:
415 : {
416 0 : const MetaFontAction* pA = (const MetaFontAction*) pMA;
417 0 : CreateChrSet( pA->GetFont() );
418 : }
419 0 : break;
420 : }
421 : }
422 : }
423 :
424 :
425 0 : void METWriter::CreateChrSet(const Font & rFont)
426 : {
427 : METChrSet * pCS;
428 :
429 0 : if ( FindChrSet( rFont ) == 0 )
430 : {
431 0 : pCS = new METChrSet;
432 0 : pCS->pSucc = pChrSetList; pChrSetList=pCS;
433 0 : pCS->nSet = nNextChrSetId++;
434 0 : pCS->aName = rFont.GetName();
435 0 : pCS->eWeight = rFont.GetWeight();
436 : }
437 0 : }
438 :
439 :
440 0 : sal_uInt8 METWriter::FindChrSet(const Font & rFont)
441 : {
442 : METChrSet* pCS;
443 :
444 0 : for (pCS=pChrSetList; pCS!=NULL; pCS=pCS->pSucc)
445 : {
446 0 : if (pCS->aName==rFont.GetName() && pCS->eWeight==rFont.GetWeight() )
447 0 : return pCS->nSet;
448 : }
449 :
450 0 : return 0;
451 : }
452 :
453 :
454 0 : void METWriter::WriteChrSets()
455 : {
456 : sal_uInt16 i;
457 0 : char c = 0;
458 : METChrSet * pCS;
459 : sal_uInt8 nbyte;
460 :
461 0 : for (pCS=pChrSetList; pCS!=NULL; pCS=pCS->pSucc)
462 : {
463 :
464 0 : WriteFieldIntroducer(0x58,MapCodFntMagic,0,0);
465 :
466 0 : WriteBigEndianShort(0x0050);
467 :
468 0 : pMET->WriteUChar( (sal_uInt8)0x0c ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x84 ).WriteUChar( (sal_uInt8)0x00 );
469 0 : pMET->WriteUChar( (sal_uInt8)0xa4 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x01 );
470 0 : pMET->WriteUChar( (sal_uInt8)0x01 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
471 :
472 0 : pMET->WriteUChar( (sal_uInt8)0x04 ).WriteUChar( (sal_uInt8)0x24 ).WriteUChar( (sal_uInt8)0x05 ).WriteUChar( (sal_uInt8)pCS->nSet );
473 :
474 0 : pMET->WriteUChar( (sal_uInt8)0x14 ).WriteUChar( (sal_uInt8)0x1f );
475 0 : switch (pCS->eWeight)
476 : {
477 0 : case WEIGHT_THIN: nbyte=1; break;
478 0 : case WEIGHT_ULTRALIGHT: nbyte=2; break;
479 0 : case WEIGHT_LIGHT: nbyte=3; break;
480 0 : case WEIGHT_SEMILIGHT: nbyte=4; break;
481 0 : case WEIGHT_NORMAL: nbyte=5; break;
482 0 : case WEIGHT_SEMIBOLD: nbyte=6; break;
483 0 : case WEIGHT_BOLD: nbyte=7; break;
484 0 : case WEIGHT_ULTRABOLD: nbyte=8; break;
485 0 : case WEIGHT_BLACK: nbyte=9; break;
486 0 : default: nbyte=5;
487 : }
488 0 : pMET->WriteUChar( nbyte );
489 0 : pMET->WriteUChar( (sal_uInt8)0x05 );
490 0 : pMET->WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
491 0 : pMET->WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
492 0 : pMET->WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
493 0 : pMET->WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x0c );
494 :
495 0 : pMET->WriteUChar( (sal_uInt8)0x06 ).WriteUChar( (sal_uInt8)0x20 ).WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0xd4 );
496 0 : pMET->WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0x52 );
497 :
498 0 : pMET->WriteUChar( (sal_uInt8)0x24 ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x08 ).WriteUChar( (sal_uInt8)0x00 );
499 : OString n(OUStringToOString(pCS->aName,
500 0 : osl_getThreadTextEncoding()));
501 0 : for (i=0; i<32; i++)
502 : {
503 0 : if ( i == 0 || c != 0 )
504 0 : c = n[i];
505 0 : pMET->WriteChar( c );
506 : }
507 0 : }
508 0 : }
509 :
510 :
511 0 : void METWriter::WriteColorAttributeTable(sal_uLong nFieldId, BitmapPalette* pPalette, sal_uInt8 nBasePartFlags, sal_uInt8 nBasePartLCTID)
512 : {
513 : sal_uInt16 nIndex,nNumI,i;
514 :
515 0 : if (bStatus==sal_False) return;
516 :
517 : //--- The Field 'Begin Color Attribute Table':
518 0 : WriteFieldIntroducer(16,BegColAtrMagic,0,0);
519 0 : WriteFieldId(nFieldId);
520 :
521 : //--- The Field 'Color Attribute Table':
522 0 : WriteFieldIntroducer(0,BlkColAtrMagic,0,0);
523 0 : pMET->WriteUChar( nBasePartFlags ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( nBasePartLCTID ); // 'Base Part'
524 0 : if (pPalette!=NULL)
525 : {
526 0 : nIndex=0;
527 0 : while (nIndex<pPalette->GetEntryCount())
528 : {
529 0 : nNumI=pPalette->GetEntryCount()-nIndex;
530 0 : if (nNumI>81) nNumI=81;
531 0 : pMET->WriteUChar( (sal_uInt8)(11+nNumI*3) ); // length of the parameter
532 0 : pMET->WriteUChar( (sal_uInt8)1 ).WriteUChar( (sal_uInt8)0 ).WriteUChar( (sal_uInt8)1 ); // typ: element list, Reserved, Format: RGB
533 0 : pMET->WriteUChar( (sal_uInt8)0 ); WriteBigEndianShort(nIndex); // start-Index (3 Bytes)
534 0 : pMET->WriteUChar( (sal_uInt8)8 ).WriteUChar( (sal_uInt8)8 ).WriteUChar( (sal_uInt8)8 ); // Bits per component R,G,B
535 0 : pMET->WriteUChar( (sal_uInt8)3 ); // number of bytes per entry
536 0 : for (i=0; i<nNumI; i++)
537 : {
538 0 : const BitmapColor& rCol = (*pPalette)[ nIndex ];
539 :
540 0 : pMET->WriteUChar( (sal_uInt8) rCol.GetRed() );
541 0 : pMET->WriteUChar( (sal_uInt8) rCol.GetGreen() );
542 0 : pMET->WriteUChar( (sal_uInt8) rCol.GetBlue() );
543 0 : nIndex++;
544 : }
545 : }
546 : }
547 : else
548 : {
549 : // 'Trible Generating'
550 0 : pMET->WriteUChar( (sal_uInt8)0x0a ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x01 ).WriteUChar( (sal_uInt8)0x00 );
551 0 : pMET->WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x08 ).WriteUChar( (sal_uInt8)0x08 ).WriteUChar( (sal_uInt8)0x08 );
552 : }
553 0 : UpdateFieldSize();
554 :
555 : //--- The Field 'End Color Attribute Table':
556 0 : WriteFieldIntroducer(16,EndColAtrMagic,0,0);
557 0 : WriteFieldId(nFieldId);
558 :
559 0 : if (pMET->GetError())
560 0 : bStatus=sal_False;
561 : }
562 :
563 :
564 0 : void METWriter::WriteImageObject(const Bitmap & rBitmap)
565 : {
566 0 : SvMemoryStream aTemp(0x00010000,0x00010000);
567 : sal_uInt32 nWidth,nHeight,nResX,nResY;
568 : sal_uLong nBytesPerLine,i,j,nNumColors,ny,nLines;
569 : sal_uLong nActColMapId;
570 : sal_uInt16 nBitsPerPixel;
571 : sal_uInt8 nbyte;
572 :
573 0 : if (bStatus==sal_False)
574 0 : return;
575 :
576 0 : nActColMapId=((nActBitmapId>>24)&0x000000ff) | ((nActBitmapId>> 8)&0x0000ff00) |
577 0 : ((nActBitmapId<< 8)&0x00ff0000) | ((nActBitmapId<<24)&0xff000000);
578 :
579 : //--- The Field 'Begin Image Object':
580 0 : WriteFieldIntroducer(16,BegImgObjMagic,0,0);
581 0 : WriteFieldId(nActBitmapId);
582 :
583 : // generate Windows-BMP file
584 0 : WriteDIB(rBitmap, aTemp, false, true);
585 :
586 : // read header of the Windows-BMP file:
587 0 : aTemp.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
588 0 : aTemp.Seek(18);
589 0 : aTemp.ReadUInt32( nWidth ).ReadUInt32( nHeight );
590 0 : aTemp.SeekRel(2);
591 0 : aTemp.ReadUInt16( nBitsPerPixel );
592 0 : aTemp.SeekRel(8);
593 0 : aTemp.ReadUInt32( nResX ).ReadUInt32( nResY );
594 0 : aTemp.SeekRel(8);
595 :
596 0 : nNumColors=1<<nBitsPerPixel;
597 0 : nBytesPerLine=((nWidth*nBitsPerPixel+0x0000001f) & 0xffffffe0 ) >> 3;
598 :
599 : // read color palette as the case may be and write it to the MET file:
600 0 : if (nBitsPerPixel<=8)
601 : {
602 0 : BitmapPalette aPal( (sal_uInt16) nNumColors );
603 : sal_uInt8 nr,ng,nb;
604 :
605 0 : for (i=0; i<nNumColors; i++)
606 : {
607 0 : aTemp.ReadUChar( nb ).ReadUChar( ng ).ReadUChar( nr ); aTemp.SeekRel(1);
608 0 : aPal[ (sal_uInt16) i ] = BitmapColor( nr, ng, nb );
609 : }
610 :
611 : //--- The Field 'Begin Resource Group':
612 0 : WriteFieldIntroducer(16,BegResGrpMagic,0,0);
613 0 : WriteFieldId(nActColMapId);
614 :
615 : //--- writer color table:
616 0 : WriteColorAttributeTable(nActColMapId,&aPal,0,1);
617 :
618 : //--- The Field 'End Resource Group':
619 0 : WriteFieldIntroducer(16,EndResGrpMagic,0,0);
620 0 : WriteFieldId(nActColMapId);
621 :
622 : //--- The Field 'Begin Object Environment Group':
623 0 : WriteFieldIntroducer(16,BegObjEnvMagic,0,0);
624 0 : WriteFieldId(nActBitmapId);
625 :
626 : //--- The Field 'Map Color Attribute Table':
627 0 : WriteFieldIntroducer(26,MapColAtrMagic,0,0);
628 0 : WriteBigEndianShort(0x0012);
629 0 : pMET->WriteUChar( (sal_uInt8)0x0c ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x84 ).WriteUChar( (sal_uInt8)0x00 );
630 0 : WriteFieldId(nActColMapId);
631 0 : pMET->WriteUChar( (sal_uInt8)0x04 ).WriteUChar( (sal_uInt8)0x24 ).WriteUChar( (sal_uInt8)0x07 ).WriteUChar( (sal_uInt8)0x01 );
632 :
633 : //--- The Field 'End Object Environment Group':
634 0 : WriteFieldIntroducer(16,EndObjEnvMagic,0,0);
635 0 : WriteFieldId(nActBitmapId);
636 : }
637 :
638 : //--- The Field 'Image Data Descriptor':
639 0 : WriteFieldIntroducer(17,DscImgObjMagic,0,0);
640 0 : pMET->WriteUChar( (sal_uInt8)0x01 ); // Unit of measure: tens of centimeters
641 0 : WriteBigEndianShort((sal_uInt16)nResX);
642 0 : WriteBigEndianShort((sal_uInt16)nResY);
643 0 : WriteBigEndianShort((sal_uInt16)nWidth);
644 0 : WriteBigEndianShort((sal_uInt16)nHeight);
645 :
646 : //--- The first Field 'Image Picture Data':
647 0 : WriteFieldIntroducer(0,DatImgObjMagic,0,0);
648 :
649 : // Begin Segment:
650 0 : pMET->WriteUChar( (sal_uInt8)0x70 ).WriteUChar( (sal_uInt8)0x00 );
651 :
652 : // Begin Image Content:
653 0 : pMET->WriteUChar( (sal_uInt8)0x91 ).WriteUChar( (sal_uInt8)0x01 ).WriteUChar( (sal_uInt8)0xff );
654 :
655 : // Image Size:
656 0 : pMET->WriteUChar( (sal_uInt8)0x94 ).WriteUChar( (sal_uInt8)0x09 ).WriteUChar( (sal_uInt8)0x02 );
657 0 : pMET->WriteUInt16( (sal_uInt16) 0 ).WriteUInt16( (sal_uInt16) 0 );
658 0 : WriteBigEndianShort((sal_uInt16)nHeight);
659 0 : WriteBigEndianShort((sal_uInt16)nWidth);
660 :
661 : // Image Encoding:
662 0 : pMET->WriteUChar( (sal_uInt8)0x95 ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0x03 );
663 :
664 : // Image IDE-Size:
665 0 : pMET->WriteUChar( (sal_uInt8)0x96 ).WriteUChar( (sal_uInt8)0x01 ).WriteUChar( (sal_uInt8)nBitsPerPixel );
666 :
667 0 : if (nBitsPerPixel<=8) {
668 : // Image LUT-ID
669 0 : pMET->WriteUChar( (sal_uInt8)0x97 ).WriteUChar( (sal_uInt8)0x01 ).WriteUChar( (sal_uInt8)0x01 );
670 : }
671 : else {
672 : // IDE Structure
673 0 : pMET->WriteUChar( (sal_uInt8)0x9b ).WriteUChar( (sal_uInt8)0x08 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x01 );
674 0 : pMET->WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x08 );
675 0 : pMET->WriteUChar( (sal_uInt8)0x08 ).WriteUChar( (sal_uInt8)0x08 );
676 : }
677 :
678 0 : boost::scoped_array<sal_uInt8> pBuf(new sal_uInt8[nBytesPerLine]);
679 0 : ny=0;
680 0 : while (ny<nHeight) {
681 :
682 : // finalize the previous field 'Image Picture Data':
683 0 : UpdateFieldSize();
684 :
685 : // and start a new field 'Image Picture Data':
686 0 : WriteFieldIntroducer(0,DatImgObjMagic,0,0);
687 :
688 : // read and write several Scanlines:
689 0 : nLines=nHeight-ny;
690 0 : if (nLines*nBytesPerLine>30000) nLines=30000/nBytesPerLine;
691 0 : if (nLines<1) nLines=1;
692 0 : WriteBigEndianShort(0xfe92);
693 0 : WriteBigEndianShort((sal_uInt16)(nLines*nBytesPerLine));
694 0 : for (i=0; i<nLines; i++) {
695 0 : aTemp.Read(pBuf.get(),nBytesPerLine);
696 0 : if (nBitsPerPixel==24) {
697 0 : for (j=2; j<nBytesPerLine; j+=3) {
698 0 : nbyte=pBuf[j]; pBuf[j]=pBuf[j-2]; pBuf[j-2]=nbyte;
699 : }
700 : }
701 0 : pMET->Write(pBuf.get(),nBytesPerLine);
702 0 : ny++;
703 : }
704 0 : if (aTemp.GetError() || pMET->GetError()) bStatus=sal_False;
705 0 : nActBitmapPercent=(ny+1)*100/nHeight;
706 0 : MayCallback();
707 0 : if (bStatus==sal_False) return;
708 : }
709 0 : pBuf.reset();
710 :
711 : // End Image Content:
712 0 : pMET->WriteUChar( (sal_uInt8)0x93 ).WriteUChar( (sal_uInt8)0x00 );
713 :
714 : // End Segment:
715 0 : pMET->WriteUChar( (sal_uInt8)0x71 ).WriteUChar( (sal_uInt8)0x00 );
716 :
717 : // finalize the last field 'Image Picture Data':
718 0 : UpdateFieldSize();
719 :
720 : //--- The Field 'End Image Object':
721 0 : WriteFieldIntroducer(16,EndImgObjMagic,0,0);
722 0 : WriteFieldId(nActBitmapId);
723 :
724 : // increase Ids:
725 0 : nActBitmapId++;
726 :
727 : // count Bitmaps:
728 0 : nWrittenBitmaps++;
729 0 : nActBitmapPercent=0;
730 :
731 0 : if (pMET->GetError()) bStatus=sal_False;
732 : }
733 :
734 :
735 0 : void METWriter::WriteImageObjects(const GDIMetaFile * pMTF)
736 : {
737 : const MetaAction* pMA;
738 :
739 0 : if (bStatus==sal_False)
740 0 : return;
741 :
742 0 : for ( size_t nAction = 0, nActionCount = pMTF->GetActionSize(); nAction < nActionCount; nAction++)
743 : {
744 0 : pMA = pMTF->GetAction(nAction);
745 :
746 0 : switch (pMA->GetType())
747 : {
748 : case META_BMP_ACTION:
749 : {
750 0 : METSetMix( eGDIRasterOp );
751 0 : WriteImageObject( ( (MetaBmpAction*) pMA )->GetBitmap() );
752 : }
753 0 : break;
754 :
755 : case META_BMPSCALE_ACTION:
756 : {
757 0 : METSetMix( eGDIRasterOp );
758 0 : WriteImageObject( ( (MetaBmpScaleAction*) pMA )->GetBitmap() );
759 : }
760 0 : break;
761 :
762 : case META_BMPSCALEPART_ACTION:
763 : {
764 0 : METSetMix( eGDIRasterOp );
765 0 : WriteImageObject( ( (MetaBmpScalePartAction*) pMA )->GetBitmap() );
766 : }
767 0 : break;
768 :
769 : case META_BMPEX_ACTION:
770 : {
771 0 : METSetMix( eGDIRasterOp );
772 0 : WriteImageObject( Graphic( ( (MetaBmpExAction*) pMA )->GetBitmapEx() ).GetBitmap() );
773 : }
774 0 : break;
775 :
776 : case META_BMPEXSCALE_ACTION:
777 : {
778 0 : METSetMix( eGDIRasterOp );
779 0 : WriteImageObject( Graphic( ( (MetaBmpExScaleAction*) pMA )->GetBitmapEx() ).GetBitmap() );
780 : }
781 0 : break;
782 :
783 : case META_BMPEXSCALEPART_ACTION:
784 : {
785 0 : METSetMix( eGDIRasterOp );
786 0 : WriteImageObject( Graphic( ( (MetaBmpExScalePartAction*) pMA )->GetBitmapEx() ).GetBitmap() );
787 : }
788 0 : break;
789 :
790 : case META_EPS_ACTION :
791 : {
792 0 : const MetaEPSAction* pA = (const MetaEPSAction*)pMA;
793 0 : const GDIMetaFile aGDIMetaFile( pA->GetSubstitute() );
794 :
795 0 : size_t nCount = aGDIMetaFile.GetActionSize();
796 0 : for ( size_t i = 0; i < nCount; i++ )
797 : {
798 0 : const MetaAction* pMetaAct = aGDIMetaFile.GetAction( i );
799 0 : if ( pMetaAct->GetType() == META_BMPSCALE_ACTION )
800 : {
801 0 : const MetaBmpScaleAction* pBmpScaleAction = (const MetaBmpScaleAction*)pMetaAct;
802 0 : METSetMix( eGDIRasterOp );
803 0 : WriteImageObject( pBmpScaleAction->GetBitmap() );
804 0 : break;
805 : }
806 0 : }
807 : }
808 0 : break;
809 : }
810 :
811 0 : if (bStatus==sal_False)
812 0 : break;
813 : }
814 :
815 0 : if (pMET->GetError())
816 0 : bStatus=sal_False;
817 : }
818 :
819 0 : void METWriter::WriteDataDescriptor(const GDIMetaFile *)
820 : {
821 0 : if (bStatus==sal_False)
822 0 : return;
823 :
824 0 : WriteFieldIntroducer(0,DscGrfObjMagic,0,0);
825 :
826 :
827 : // The following is the OS2 original documentation and the associated implementation
828 :
829 :
830 : // Parameters (all required and in this order)
831 :
832 : // 0 0xF7 Specify GVM Subset
833 : // 1 Length of following data 0x07
834 : // 2 0xB0 drawing order subset
835 : // 3-4 0x0000
836 : // 5 0x23 Level 3.2
837 : // 6 0x01 Version 1
838 : // 7 Length of following field 0x01
839 : // 8 Coordinate types in data
840 : // 0x04Intel16
841 : // 0x05Intel32
842 0 : pMET->WriteUChar( (sal_uInt8)0xf7 ).WriteUChar( (sal_uInt8)0x07 ).WriteUChar( (sal_uInt8)0xb0 ).WriteUChar( (sal_uInt8)0x00 )
843 0 : .WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x23 ).WriteUChar( (sal_uInt8)0x01 ).WriteUChar( (sal_uInt8)0x01 )
844 0 : .WriteUChar( (sal_uInt8)0x05 );
845 :
846 : // 0 0xF6 Set Picture Descriptor
847 : // 1 Length of following data
848 : // 2 Flags
849 : // 0 B'0' Picture in 2D
850 : // 1 Picture Dimensions
851 : // B'0' Not absolute (PU_ARBITRARY PS)
852 : // B'1' Absolute (example: PU_TWIPS PS)
853 : // 2 Picture Elements
854 : // B'0' Not pels
855 : // B'1' Pels (PU_PELS PS)
856 : // (Bit 1 must also be set)
857 : // 3-7 B'00000'
858 : // 3 0x00 Reserved
859 : // 4 Picture frame size coordinate type
860 : // 0x04 Intel16
861 : // 0x05 Intel32
862 : // 5 UnitsOfMeasure
863 : // 0x00 Ten inches
864 : // 0x01 Decimeter
865 : // 6-11 or 6-17(2 or 4 bytes) Resolution.
866 : // GPS Units / UOM on x axis
867 : // GPS Units / UOM on y axis
868 : // GPS Units / UOM on z axis
869 : // 12-23 or 18-41(2 or 4 bytes) Window Size.
870 : // GPS X left, X right
871 : // GPS Y bottom, Y top
872 : // GPS Z near, Z far
873 0 : Size aUnitsPerDecimeter=OutputDevice::LogicToLogic(Size(10,10),MapMode(MAP_CM),aPictureMapMode);
874 0 : pMET->WriteUChar( (sal_uInt8)0xf6 ).WriteUChar( (sal_uInt8)0x28 ).WriteUChar( (sal_uInt8)0x40 ).WriteUChar( (sal_uInt8)0x00 )
875 0 : .WriteUChar( (sal_uInt8)0x05 ).WriteUChar( (sal_uInt8)0x01 )
876 0 : .WriteUInt32( (sal_uInt32)(aUnitsPerDecimeter.Width()) )
877 0 : .WriteUInt32( (sal_uInt32)(aUnitsPerDecimeter.Height()) )
878 0 : .WriteUInt32( (sal_uInt32)0 )
879 0 : .WriteUInt32( (sal_uInt32)0 ).WriteUInt32( (sal_uInt32)aPictureRect.GetWidth() )
880 0 : .WriteUInt32( (sal_uInt32)0 ).WriteUInt32( (sal_uInt32)aPictureRect.GetHeight() )
881 0 : .WriteUInt32( (sal_uInt32)0 ).WriteUInt32( (sal_uInt32)0 );
882 :
883 : // 0 0x21 Set Current Defaults
884 : // 1 Length of following data
885 : // 2 Set Default Parameter Format 0x08
886 : // 3-4 Mask 0xE000
887 : // 5 Names 0x8F
888 : // 6 Coordinates
889 : // 0x00 Picture in 2D
890 : // 7 Transforms
891 : // 0x04 Intel16
892 : // 0x05 Intel32
893 : // 8 Geometrics
894 : // 0x04 Intel16
895 : // 0x05 Intel32
896 0 : pMET->WriteUChar( (sal_uInt8)0x21 ).WriteUChar( (sal_uInt8)0x07 ).WriteUChar( (sal_uInt8)0x08 ).WriteUChar( (sal_uInt8)0xe0 )
897 0 : .WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x8f ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x05 )
898 0 : .WriteUChar( (sal_uInt8)0x05 );
899 :
900 : // 0 0x21 Set Current Defaults
901 : // 1 Length of following data
902 : // 2 Set default viewing transform 0x07
903 : // 3-4 Mask 0xCC0C
904 : // 5 Names 0x8F
905 : // 6-n M11, M12, M21, M22, M41, M42 Matrix elements
906 0 : pMET->WriteUChar( (sal_uInt8)0x21 ).WriteUChar( (sal_uInt8)0x1c ).WriteUChar( (sal_uInt8)0x07 ).WriteUChar( (sal_uInt8)0xcc )
907 0 : .WriteUChar( (sal_uInt8)0x0c ).WriteUChar( (sal_uInt8)0x8f )
908 0 : .WriteUInt32( (sal_uInt32)0x00010000 ).WriteUInt32( (sal_uInt32)0x00000000 ).WriteUInt32( (sal_uInt32)0x00000000 )
909 0 : .WriteUInt32( (sal_uInt32)0x00010000 ).WriteUInt32( (sal_uInt32)0x00000000 ).WriteUInt32( (sal_uInt32)0x00000000 );
910 :
911 : // 0 0x21 Set Current Defaults
912 : // 1 Length of following data
913 : // 2 Set default line attributes 0x01
914 : // 3-4 Mask - OR of as many of the following bits as are required:
915 : // 0x8000 Line type
916 : // 0x4000 Line width
917 : // 0x2000 Line end
918 : // 0x1000 Line join
919 : // 0x0800 Stroke width
920 : // 0x0008 Line color
921 : // 0x0002 Line mix
922 : // 5 Flags
923 : //
924 : // 0x0F Set indicated default attributes to initial values. (Data field is not present in this
925 : // instance).
926 : // 0x8F Set indicated default attributes to specified values.
927 : // 6-n Data - data values as required, in the following order if present.
928 : // No space is reserved for attributes for which the corresponding mask flag was not
929 : // set.
930 : //
931 : // (1 byte) - Line type
932 : // (1 byte) - Line width
933 : // (1 byte) - Line end
934 : // (1 byte) - Line join
935 : // (G bytes) - Stroke width
936 : // (4 bytes) - Line color
937 : // (1 byte) - Line mix (G=2 or 4 depending on the Geometrics parameter of Set Default
938 : // Parameter Format)
939 : // Nanu! witziger-weise fehlt obiger Abschnitt in den Metadateien. Also lassen wir ihn auch weg
940 :
941 : // 0 0x21 Set Current Defaults
942 : // 1 Length of following data
943 : // 2 Set Default Character Attributes 0x02
944 : // 3-4 Mask - OR of as many of the following bits as are required:
945 : //
946 : // 0x8000 Character angle
947 : // 0x4000 Character box
948 : // 0x2000 Character direction
949 : // 0x1000 Character precision
950 : // 0x0800 Character set
951 : // 0x0400 Character shear
952 : // 0x0040 Character break extra
953 : // 0x0020 Character extra
954 : // 0x0008 Character color
955 : // 0x0004 Character background color
956 : // 0x0002 Character mix
957 : // 0x0001 Character background mix
958 : // 5 Flags
959 : // 0x0FSet indicated default attributes to initial values. (Data field is not present in this
960 : // case).
961 : // 0x8FSet indicated default attributes to specified values.
962 : // 6-n Data - data values as required, in the following order if present.
963 : // No space is reserved for attributes for which the corresponding Mask flag was not
964 : // set.
965 : // (2*G bytes) - Character angle
966 : // (2*G + 4 bytes)- Character box
967 : // (1 byte) - Character direction
968 : // (1 byte) - Character precision
969 : // (1 byte) - Character set
970 : // (2*G bytes) - Character shear
971 : // (4 bytes) - Character break extra
972 : // (4 bytes) - Character extra
973 : // (4 bytes) - Character color
974 : // (4 bytes) - Character background color
975 : // (1 byte) - Character mix
976 : // (1 byte) - Character background mix (G=2 or 4 depending on the Geometrics
977 : // parameter of Set Default Parameter Format)
978 0 : pMET->WriteUChar( (sal_uInt8)0x21 ).WriteUChar( (sal_uInt8)0x10 ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x40 )
979 0 : .WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x8f )
980 0 : .WriteUChar( (sal_uInt8)0xaa ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 )
981 0 : .WriteUChar( (sal_uInt8)0x44 ).WriteUChar( (sal_uInt8)0x04 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 )
982 0 : .WriteUChar( (sal_uInt8)0xa8 ).WriteUChar( (sal_uInt8)0xaa ).WriteUChar( (sal_uInt8)0x40 ).WriteUChar( (sal_uInt8)0x44 );
983 :
984 : // 0 0x21 Set Current Defaults
985 : // 1 Length of following data
986 : // 2 Set Default Marker Attributes 0x03
987 : // 3-4 Mask - OR of as many of the following bits as are required:
988 : // 0x4000 Marker box
989 : // 0x1000 Marker precision
990 : // 0x0800 Marker set
991 : // 0x0100 Marker symbol
992 : // 0x0008 Marker color
993 : // 0x0004 Marker background color
994 : // 0x0002 Marker mix
995 : // 0x0001 Marker background mix
996 : // 5 Flags
997 : // 0x0F Set indicated default attributes to initial values.
998 : // (Data field is not present in this instance)
999 : // 0x8F Set indicated default attributes to specified values.
1000 : // 6-n Data - data values as required, in this order if present.
1001 : // No space is reserved for attributes for which the corresponding Mask flag was not
1002 : // set.
1003 : // (2*G bytes) - Marker box
1004 : // (1 byte) - Marker precision
1005 : // (1 byte) - Marker set
1006 : // (1 byte) - Marker symbol
1007 : // (4 bytes) - Marker color
1008 : // (4 bytes) - Marker background color
1009 : // (1 byte) - Marker mix
1010 : // (1 byte) - Marker background mix (G=2 or 4 depending on the Geometrics
1011 : // parameter of Set Default Parameter Format)
1012 0 : pMET->WriteUChar( (sal_uInt8)0x21 ).WriteUChar( (sal_uInt8)0x0c ).WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0x40 )
1013 0 : .WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x8f )
1014 0 : .WriteUChar( (sal_uInt8)0x66 ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 )
1015 0 : .WriteUChar( (sal_uInt8)0x66 ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
1016 :
1017 : // 0 0x21 Set Current Defaults
1018 : // 1 Length of following data
1019 : // 2 Set Default Pattern Attributes 0x04
1020 : // 3-4 Mask - OR of as many of the following bits as are required:
1021 : // 0x0800 Pattern set
1022 : // 0x0100 Pattern symbol
1023 : // 0x0080 Pattern reference point
1024 : // 0x0008 Pattern color
1025 : // 0x0004 Pattern background color
1026 : // 0x0002 Pattern mix
1027 : // 0x0001 Pattern background mix
1028 : // 5 Flags
1029 : //
1030 : // 0x0F Set indicated default attributes to initial values.
1031 : // (Data field is not present in this instance)
1032 : // 0x8F Set indicated default attributes to specified values.
1033 : // 6-n Data - data values as required, in this order if present.
1034 : // No space is reserved for attributes for which the corresponding Mask flag was
1035 : // not set.
1036 : //
1037 : // (1 byte) - Pattern set
1038 : // (1 byte) - Pattern symbol
1039 : // (2*G bytes) - Pattern reference point
1040 : // (4 bytes) - Pattern color
1041 : // (4 bytes) - Pattern background color
1042 : // (1 byte) - Pattern mix
1043 : // (1 byte) - Pattern background mix (G=2 or 4 depending on the Geometrics
1044 : // parameter of Set Default Parameter Format)
1045 : // 0 0x21 Set Current Defaults
1046 : // 1 Length of following data
1047 : // 2 Set Default Image Attributes 0x06
1048 : // 3-4 Mask - OR of as many of these bits as are required:
1049 : // 0x0008 Image color
1050 : // 0x0004 Image background color
1051 : // 0x0002 Image mix
1052 : // 0x0001 Image background mix
1053 : // 5 Flags
1054 : // 0x0F Set indicated default attributes to initial values. (Data field is not present in
1055 : // this instance)
1056 : // 0x8F Set indicated default attributes to specified values.
1057 : // 6-n Data - data values as required, in this order if present.
1058 : // No space is reserved for attributes for which the corresponding Mask flag was
1059 : // not set.
1060 : // (4 bytes) - Image color
1061 : // (4 bytes) - Image background color
1062 : // (1 byte) - Image mix
1063 : // (1 byte) - Image background mix
1064 : // 0 0x21 Set Current Defaults
1065 : // 1 Length of following data
1066 : // 2 Set Default Viewing Window 0x05
1067 : // 3-4 Mask - OR of as many of the following bits as are required:
1068 : // 0x8000 x left limit
1069 : // 0x4000 x right limit
1070 : // 0x2000 y bottom limit
1071 : // 0x1000 y top limit
1072 : // 5 Flags
1073 : // 0x0F Set indicated default attributes to initial values.
1074 : // (Data field is not present in this case).
1075 : // 0x8F Set indicated default attributes to specified values.
1076 : // 6-n Data - data values as required, in the following order if present.
1077 : // No space is reserved for attributes for which the corresponding Mask flag was
1078 : // not set.
1079 : // (2*G bytes) - x left limit
1080 : // (2*G bytes) - x right limit
1081 : // (2*G bytes) - y bottom limit
1082 : // (2*G bytes) - y top limit (G=2 or 4 depending on the Geometrics parameter of Set
1083 : // Default Parameter Format)
1084 : // 0 0x21 Set Current Defaults
1085 : // 1 Length of following data
1086 : // 2 Set Default Arc Parameters 0x0B
1087 : // 3-4 Mask - OR of as many of the following bits as are required:
1088 : // 0x8000 P value
1089 : // 0x4000 Q value
1090 : // 0x2000 R value
1091 : // 0x1000 S value
1092 : // 5 Flags
1093 : // 0x0F Set indicated default attributes to initial values.
1094 : // (Data field is not present in this case).
1095 : // 0x8F Set indicated default attributes to specified values.
1096 : // 6-n Data - data values as required, in the following order if present.
1097 : // No space is reserved for attributes for which the corresponding Mask flag was
1098 : // not set.
1099 : // (G bytes) - P value
1100 : // (G bytes) - Q value
1101 : // (G bytes) - R value
1102 : // (G bytes) - S value (G=2 or 4 depending on the Geometrics parameter of Set
1103 : // Default Parameter Format)
1104 : // 0 0x21 Set Current Defaults
1105 : // 1 Length of following data
1106 : // 2 Set Default Pick Identifier 0x0C
1107 : // 3-4 Mask - OR of as many of the following bits as are required:
1108 : // 0x8000 Pick identifier
1109 : // 5 Flags
1110 : // 0x0F Set indicated default attributes to initial values.
1111 : // (Data field is not present in this case).
1112 : // 0x8F Set indicated default attributes to specified values.
1113 : // 6-n Data - data values as required, in the following order if present.
1114 : // No space is reserved for attributes for which the corresponding Mask flag was
1115 : // not set.
1116 : // (4 bytes) - Pick identifier
1117 :
1118 : // 0 0xE7 Set Bit-map Identifier
1119 : // 1 Length of following data 0x07
1120 : // 2-3 Usage Flags 0x8000
1121 : // 4-7 Bit-map handle
1122 : // 8 Lcid
1123 0 : if (nNumberOfBitmaps>0) {
1124 0 : pMET->WriteUChar( (sal_uInt8)0xe7 ).WriteUChar( (sal_uInt8)0x07 ).WriteUChar( (sal_uInt8)0x80 ).WriteUChar( (sal_uInt8)0x00 );
1125 0 : WriteBigEndianLong(nActBitmapId);
1126 0 : pMET->WriteUChar( (sal_uInt8)0xfe );
1127 : }
1128 :
1129 0 : UpdateFieldSize();
1130 :
1131 0 : if (pMET->GetError()) bStatus=sal_False;
1132 : }
1133 :
1134 :
1135 0 : void METWriter::WillWriteOrder(sal_uLong nNextOrderMaximumLength)
1136 : {
1137 : // The parameters of a 'Graphics Data Fields' can be (according to OS2
1138 : // documentation) at most 32759 bytes long. Meant by this is the size
1139 : // of the field minus the 'Structured Field Introducer' (size 8).
1140 : // So the size of the whole field can be at most 8+32759=32767=0x7fff.
1141 : // To be on the safe side whe use 30000 as the limit.
1142 0 : if (pMET->Tell()-nActualFieldStartPos+nNextOrderMaximumLength>30000)
1143 : {
1144 0 : UpdateFieldSize();
1145 0 : WriteFieldIntroducer(0,DatGrfObjMagic,0,0);
1146 0 : nNumberOfDataFields++;
1147 : }
1148 0 : }
1149 :
1150 :
1151 :
1152 0 : void METWriter::METBitBlt(Point aPt, Size aSize, const Size& rBmpSizePixel)
1153 : {
1154 0 : WillWriteOrder(46);
1155 0 : pMET->WriteUChar( (sal_uInt8)0xd6 ).WriteUChar( (sal_uInt8)44 ).WriteUInt16( (sal_uInt16)0 ).WriteUInt16( (sal_uInt16) 0x00cc );
1156 0 : WriteBigEndianLong(nActBitmapId++);
1157 0 : pMET->WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
1158 0 : WritePoint(Point(aPt.X(),aPt.Y()+aSize.Height()));
1159 0 : WritePoint(Point(aPt.X()+aSize.Width(),aPt.Y()));
1160 0 : pMET->WriteUInt32( (sal_uInt32)0 ).WriteUInt32( (sal_uInt32)0 )
1161 0 : .WriteUInt32( (sal_uInt32)(rBmpSizePixel.Width()) )
1162 0 : .WriteUInt32( (sal_uInt32)(rBmpSizePixel.Height()) );
1163 0 : }
1164 :
1165 0 : void METWriter::METSetAndPushLineInfo( const LineInfo& rLineInfo )
1166 : {
1167 0 : sal_Int32 nWidth = pCompDev->LogicToLogic( Size( rLineInfo.GetWidth(),0 ), aPictureMapMode, aTargetMapMode ).Width();
1168 :
1169 0 : WillWriteOrder( 8 ); // set stroke linewidth
1170 0 : pMET ->WriteUChar( (sal_uInt8)0x15 )
1171 0 : .WriteUChar( (sal_uInt8)6 )
1172 0 : .WriteUChar( (sal_uInt8)0 ) // Flags
1173 0 : .WriteUChar( (sal_uInt8)0 )
1174 0 : .WriteInt32( nWidth );
1175 :
1176 0 : if ( rLineInfo.GetStyle() != LINE_SOLID )
1177 : {
1178 0 : sal_uInt8 nStyle = 0; // LineDefault;
1179 :
1180 0 : switch ( rLineInfo.GetStyle() )
1181 : {
1182 : case LINE_NONE :
1183 0 : nStyle = 8;
1184 0 : break;
1185 :
1186 : case LINE_DASH :
1187 : {
1188 0 : if ( rLineInfo.GetDotCount() )
1189 : {
1190 0 : if ( !rLineInfo.GetDashCount() )
1191 0 : nStyle = 1; // LINE_DOT
1192 : else
1193 0 : nStyle = 3; // LINE_DASH_DOT
1194 : }
1195 : else
1196 0 : nStyle = 2; // LINE_DASH
1197 : }
1198 0 : break;
1199 : case LineStyle_SOLID:
1200 : case LineStyle_FORCE_EQUAL_SIZE:
1201 0 : break; // not handled -Wall
1202 : }
1203 0 : WillWriteOrder( 2 );
1204 0 : pMET->WriteUChar( (sal_uInt8)0x18 ).WriteUChar( nStyle ); // set LineType
1205 : }
1206 0 : }
1207 :
1208 0 : void METWriter::METPopLineInfo( const LineInfo& rLineInfo )
1209 : {
1210 0 : WillWriteOrder( 8 ); // set stroke linewidth
1211 0 : pMET ->WriteUChar( (sal_uInt8)0x15 )
1212 0 : .WriteUChar( (sal_uInt8)6 )
1213 0 : .WriteUChar( (sal_uInt8)0 ) // Flags
1214 0 : .WriteUChar( (sal_uInt8)0 )
1215 0 : .WriteUInt32( (sal_uInt32)1 );
1216 :
1217 0 : if ( rLineInfo.GetStyle() != LINE_SOLID )
1218 : {
1219 0 : WillWriteOrder( 2 );
1220 0 : pMET->WriteUChar( (sal_uInt8)0x18 ).WriteUChar( (sal_uInt8)0 ); // set LineType
1221 : }
1222 0 : }
1223 :
1224 0 : void METWriter::METBeginArea(sal_Bool bBoundaryLine)
1225 : {
1226 0 : WillWriteOrder(2);
1227 0 : pMET->WriteUChar( (sal_uInt8)0x68 );
1228 0 : if (bBoundaryLine) pMET->WriteUChar( (sal_uInt8)0xc0 );
1229 0 : else pMET->WriteUChar( (sal_uInt8)0x80 );
1230 0 : }
1231 :
1232 :
1233 0 : void METWriter::METEndArea()
1234 : {
1235 0 : WillWriteOrder(2);
1236 0 : pMET->WriteUChar( (sal_uInt8)0x60 ).WriteUChar( (sal_uInt8)0 );
1237 0 : }
1238 :
1239 :
1240 0 : void METWriter::METBeginPath(sal_uInt32 nPathId)
1241 : {
1242 0 : WillWriteOrder(8);
1243 0 : pMET->WriteUChar( (sal_uInt8)0xd0 ).WriteUChar( (sal_uInt8)6 ).WriteUInt16( (sal_uInt16) 0 ).WriteUInt32( nPathId );
1244 0 : }
1245 :
1246 :
1247 0 : void METWriter::METEndPath()
1248 : {
1249 0 : WillWriteOrder(2);
1250 0 : pMET->WriteUChar( (sal_uInt8)0x7f ).WriteUChar( (sal_uInt8)0 );
1251 0 : }
1252 :
1253 :
1254 0 : void METWriter::METFillPath(sal_uInt32 nPathId)
1255 : {
1256 0 : WillWriteOrder(8);
1257 0 : pMET->WriteUChar( (sal_uInt8)0xd7 ).WriteUChar( (sal_uInt8)6 )
1258 0 : .WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0 ).WriteUInt32( nPathId );
1259 0 : }
1260 :
1261 :
1262 0 : void METWriter::METOutlinePath(sal_uInt32 nPathId)
1263 : {
1264 0 : WillWriteOrder(8);
1265 0 : pMET->WriteUChar( (sal_uInt8)0xd4 ).WriteUChar( (sal_uInt8)6 )
1266 0 : .WriteUChar( (sal_uInt8)0 ).WriteUChar( (sal_uInt8)0 ).WriteUInt32( nPathId );
1267 0 : }
1268 :
1269 :
1270 0 : void METWriter::METCloseFigure()
1271 : {
1272 0 : WillWriteOrder(2);
1273 0 : pMET->WriteUChar( (sal_uInt8)0x7d ).WriteUChar( (sal_uInt8)0 );
1274 0 : }
1275 :
1276 :
1277 0 : void METWriter::METMove(Point aPt)
1278 : {
1279 0 : WillWriteOrder(10);
1280 0 : pMET->WriteUChar( (sal_uInt8)0x21 ).WriteUChar( (sal_uInt8)8 );
1281 0 : WritePoint(aPt);
1282 0 : }
1283 :
1284 :
1285 0 : void METWriter::METLine(Point aPt1, Point aPt2)
1286 : {
1287 0 : WillWriteOrder(18);
1288 0 : pMET->WriteUChar( (sal_uInt8)0xc1 ).WriteUChar( (sal_uInt8)16 );
1289 0 : WritePoint(aPt1); WritePoint(aPt2);
1290 0 : }
1291 :
1292 :
1293 0 : void METWriter::METLine(const Polygon & rPolygon)
1294 : {
1295 : sal_uInt16 nNumPoints,i,j,nOrderPoints;
1296 : sal_Bool bFirstOrder;
1297 :
1298 0 : bFirstOrder=sal_True;
1299 0 : i=0; nNumPoints=rPolygon.GetSize();
1300 0 : while (i<nNumPoints) {
1301 0 : nOrderPoints=nNumPoints-i;
1302 0 : if (nOrderPoints>30) nOrderPoints=30;
1303 0 : WillWriteOrder(nOrderPoints*8+2);
1304 0 : if (bFirstOrder==sal_True) {
1305 0 : pMET->WriteUChar( (sal_uInt8)0xc1 ); // Line at given pos
1306 0 : bFirstOrder=sal_False;
1307 : }
1308 : else {
1309 0 : pMET->WriteUChar( (sal_uInt8)0x81 ); // Line at current pos
1310 : }
1311 0 : pMET->WriteUChar( (sal_uInt8)(nOrderPoints*8) );
1312 0 : for (j=0; j<nOrderPoints; j++) WritePoint(rPolygon.GetPoint(i++));
1313 : }
1314 0 : }
1315 :
1316 :
1317 0 : void METWriter::METLine(const PolyPolygon & rPolyPolygon)
1318 : {
1319 : sal_uInt16 i,nCount;
1320 0 : nCount=rPolyPolygon.Count();
1321 0 : for (i=0; i<nCount; i++) {
1322 0 : METLine(rPolyPolygon.GetObject(i));
1323 0 : METCloseFigure();
1324 : }
1325 0 : }
1326 :
1327 :
1328 0 : void METWriter::METLineAtCurPos(Point aPt)
1329 : {
1330 0 : WillWriteOrder(10);
1331 0 : pMET->WriteUChar( (sal_uInt8)0x81 ).WriteUChar( (sal_uInt8)8 );
1332 0 : WritePoint(aPt);
1333 0 : }
1334 :
1335 :
1336 0 : void METWriter::METBox(sal_Bool bFill, sal_Bool bBoundary,
1337 : Rectangle aRect, sal_uInt32 nHAxis, sal_uInt32 nVAxis)
1338 : {
1339 0 : sal_uInt8 nFlags=0;
1340 0 : if (bFill) nFlags|=0x40;
1341 0 : if (bBoundary) nFlags|=0x20;
1342 :
1343 0 : WillWriteOrder(28);
1344 0 : pMET->WriteUChar( (sal_uInt8)0xc0 ).WriteUChar( (sal_uInt8)26 ).WriteUChar( nFlags ).WriteUChar( (sal_uInt8)0 );
1345 0 : WritePoint(aRect.BottomLeft());
1346 0 : WritePoint(aRect.TopRight());
1347 0 : pMET->WriteUInt32( nHAxis ).WriteUInt32( nVAxis );
1348 0 : }
1349 :
1350 :
1351 0 : void METWriter::METFullArc(Point aCenter, double fMultiplier)
1352 : {
1353 0 : WillWriteOrder(14);
1354 0 : pMET->WriteUChar( (sal_uInt8)0xc7 ).WriteUChar( (sal_uInt8)12 );
1355 0 : WritePoint(aCenter);
1356 0 : pMET->WriteInt32( (sal_Int32)(fMultiplier*65536.0+0.5) );
1357 0 : }
1358 :
1359 :
1360 0 : void METWriter::METPartialArcAtCurPos(Point aCenter, double fMultiplier,
1361 : double fStartAngle, double fSweepAngle)
1362 : {
1363 0 : fStartAngle*=180.0/3.14159265359;
1364 0 : while (fStartAngle>360.0) fStartAngle-=360.0;
1365 0 : while (fStartAngle<0.0) fStartAngle+=360.0;
1366 0 : fSweepAngle*=180.0/3.14159265359;
1367 0 : while (fSweepAngle>360.0) fSweepAngle-=360.0;
1368 0 : while (fSweepAngle<.00) fSweepAngle+=360.0;
1369 0 : WillWriteOrder(22);
1370 0 : pMET->WriteUChar( (sal_uInt8)0xa3 ).WriteUChar( (sal_uInt8)20 );
1371 0 : WritePoint(aCenter);
1372 0 : pMET->WriteInt32( (sal_Int32)(fMultiplier*65536.0+0.5) );
1373 0 : pMET->WriteInt32( (sal_Int32)(fStartAngle*65536.0+0.5) );
1374 0 : pMET->WriteInt32( (sal_Int32)(fSweepAngle*65536.0+0.5) );
1375 0 : }
1376 :
1377 :
1378 0 : void METWriter::METChrStr( Point aPt, const OUString& aUniStr )
1379 : {
1380 : OString aStr(OUStringToOString(aUniStr,
1381 0 : osl_getThreadTextEncoding()));
1382 0 : sal_uInt16 nLen = aStr.getLength();
1383 0 : WillWriteOrder( 11 + nLen );
1384 0 : pMET->WriteUChar( (sal_uInt8)0xc3 ).WriteUChar( (sal_uInt8)( 9 + nLen ) );
1385 0 : WritePoint(aPt);
1386 0 : for (sal_uInt16 i = 0; i < nLen; ++i)
1387 0 : pMET->WriteChar( aStr[i] );
1388 0 : pMET->WriteUChar( (sal_uInt8)0 );
1389 0 : }
1390 :
1391 :
1392 0 : void METWriter::METSetArcParams(sal_Int32 nP, sal_Int32 nQ, sal_Int32 nR, sal_Int32 nS)
1393 : {
1394 0 : WillWriteOrder(18);
1395 0 : pMET->WriteUChar( (sal_uInt8)0x22 ).WriteUChar( (sal_uInt8)16 ).WriteInt32( nP ).WriteInt32( nQ ).WriteInt32( nR ).WriteInt32( nS );
1396 0 : }
1397 :
1398 :
1399 0 : void METWriter::METSetColor(Color aColor)
1400 : {
1401 0 : if (aColor==aMETColor) return;
1402 0 : aMETColor=aColor;
1403 :
1404 0 : WillWriteOrder(6);
1405 0 : pMET->WriteUChar( (sal_uInt8)0xa6 ).WriteUChar( (sal_uInt8)4 ).WriteUChar( (sal_uInt8)0 )
1406 0 : .WriteUChar( (sal_uInt8)(aColor.GetBlue()) )
1407 0 : .WriteUChar( (sal_uInt8)(aColor.GetGreen()) )
1408 0 : .WriteUChar( (sal_uInt8)(aColor.GetRed()) );
1409 : }
1410 :
1411 :
1412 0 : void METWriter::METSetBackgroundColor(Color aColor)
1413 : {
1414 0 : if (aColor==aMETBackgroundColor) return;
1415 0 : aMETBackgroundColor=aColor;
1416 :
1417 0 : WillWriteOrder(6);
1418 0 : pMET->WriteUChar( (sal_uInt8)0xa7 ).WriteUChar( (sal_uInt8)4 ).WriteUChar( (sal_uInt8)0 )
1419 0 : .WriteUChar( (sal_uInt8)(aColor.GetBlue()) )
1420 0 : .WriteUChar( (sal_uInt8)(aColor.GetGreen()) )
1421 0 : .WriteUChar( (sal_uInt8)(aColor.GetRed()) );
1422 : }
1423 :
1424 0 : void METWriter::METSetMix(RasterOp eROP)
1425 : {
1426 : sal_uInt8 nMix;
1427 :
1428 0 : if (eMETMix==eROP)
1429 0 : return;
1430 :
1431 0 : eMETMix=eROP;
1432 :
1433 0 : switch (eROP)
1434 : {
1435 0 : case ROP_INVERT: nMix=0x0c; break;
1436 0 : case ROP_XOR: nMix=0x04; break;
1437 0 : default: nMix=0x02;
1438 : }
1439 :
1440 0 : WillWriteOrder(2);
1441 0 : pMET->WriteUChar( (sal_uInt8)0x0c ).WriteUChar( nMix );
1442 : }
1443 :
1444 :
1445 0 : void METWriter::METSetChrCellSize(Size aSize)
1446 : {
1447 0 : if (aMETChrCellSize==aSize)
1448 0 : return;
1449 :
1450 0 : aMETChrCellSize=aSize;
1451 0 : WillWriteOrder(10);
1452 0 : if (aSize.Width()==0) aSize.Width()=aSize.Height();
1453 0 : pMET->WriteUChar( (sal_uInt8)0x33 ).WriteUChar( (sal_uInt8)8 ).WriteInt32( (sal_Int32)aSize.Width() ).WriteInt32( (sal_Int32)aSize.Height() );
1454 : }
1455 :
1456 :
1457 0 : void METWriter::METSetChrAngle(short nAngle)
1458 : {
1459 : sal_Int32 nax, nay;
1460 :
1461 0 : if (nMETChrAngle==nAngle) return;
1462 0 : nMETChrAngle=nAngle;
1463 :
1464 0 : if (nAngle==0)
1465 : {
1466 0 : nax=256;
1467 0 : nay=0;
1468 : }
1469 : else
1470 : {
1471 0 : double fa=((double)nAngle)/1800.0*3.14159265359;
1472 0 : nax=(long)(256.0*cos(fa)+0.5);
1473 0 : nay=(long)(256.0*sin(fa)+0.5);
1474 : }
1475 :
1476 0 : WillWriteOrder(10);
1477 0 : pMET->WriteUChar( (sal_uInt8)0x34 ).WriteUChar( (sal_uInt8)8 ).WriteInt32( nax ).WriteInt32( nay );
1478 : }
1479 :
1480 :
1481 0 : void METWriter::METSetChrSet(sal_uInt8 nSet)
1482 : {
1483 0 : if (nMETChrSet==nSet)
1484 0 : return;
1485 :
1486 0 : nMETChrSet=nSet;
1487 0 : WillWriteOrder(2);
1488 0 : pMET->WriteUChar( (sal_uInt8)0x38 ).WriteUChar( nSet );
1489 : }
1490 :
1491 :
1492 0 : void METWriter::WriteOrders( const GDIMetaFile* pMTF )
1493 : {
1494 0 : if(bStatus==sal_False)
1495 0 : return;
1496 :
1497 0 : for( size_t nA = 0, nACount = pMTF->GetActionSize(); nA < nACount; nA++ )
1498 : {
1499 0 : const MetaAction* pMA = pMTF->GetAction( nA );
1500 :
1501 0 : switch (pMA->GetType())
1502 : {
1503 : case META_PIXEL_ACTION:
1504 : {
1505 0 : const MetaPixelAction* pA = (const MetaPixelAction*) pMA;
1506 0 : METSetMix( eGDIRasterOp );
1507 0 : METSetColor( pA->GetColor() );
1508 0 : METLine( pA->GetPoint(),pA->GetPoint() );
1509 : }
1510 0 : break;
1511 :
1512 : case META_POINT_ACTION:
1513 : {
1514 0 : const MetaPointAction* pA = (const MetaPointAction*) pMA;
1515 :
1516 0 : METSetArcParams(1,1,0,0);
1517 0 : METSetMix(eGDIRasterOp);
1518 0 : METSetColor(aGDILineColor);
1519 0 : METBeginArea(sal_False);
1520 0 : METFullArc(pA->GetPoint(),0.5);
1521 0 : METEndArea();
1522 : }
1523 0 : break;
1524 :
1525 : case META_LINE_ACTION:
1526 : {
1527 0 : const MetaLineAction* pA = (const MetaLineAction*) pMA;
1528 :
1529 0 : if( aGDILineColor != Color( COL_TRANSPARENT ) )
1530 : {
1531 0 : LineInfo aLineInfo( pA->GetLineInfo() );
1532 0 : if ( ! ( aLineInfo.IsDefault() ) )
1533 0 : METSetAndPushLineInfo( aLineInfo );
1534 :
1535 0 : METSetMix( eGDIRasterOp );
1536 0 : METSetColor(aGDILineColor);
1537 0 : METBeginPath( 1 );
1538 0 : METLine( pA->GetStartPoint(), pA->GetEndPoint() );
1539 0 : METEndPath();
1540 0 : METOutlinePath( 1 );
1541 :
1542 0 : if ( ! ( aLineInfo.IsDefault() ) )
1543 0 : METPopLineInfo( aLineInfo );
1544 : }
1545 : }
1546 0 : break;
1547 :
1548 : case META_RECT_ACTION:
1549 : {
1550 0 : const MetaRectAction* pA = (const MetaRectAction*) pMA;
1551 :
1552 0 : if( aGDIFillColor != Color( COL_TRANSPARENT ) )
1553 : {
1554 0 : METSetMix( eGDIRasterOp );
1555 0 : METSetColor( aGDIFillColor );
1556 0 : METSetBackgroundColor( aGDIFillColor );
1557 0 : METBox( sal_True, sal_False, pA->GetRect(), 0, 0 );
1558 : }
1559 :
1560 0 : if( aGDILineColor != Color( COL_TRANSPARENT ) )
1561 : {
1562 0 : METSetMix( eGDIRasterOp );
1563 0 : METSetColor( aGDILineColor );
1564 0 : METBox( sal_False, sal_True, pA->GetRect(), 0, 0 );
1565 : }
1566 : }
1567 0 : break;
1568 :
1569 : case META_ROUNDRECT_ACTION:
1570 : {
1571 0 : const MetaRoundRectAction* pA = (const MetaRoundRectAction*) pMA;
1572 :
1573 0 : if( aGDIFillColor != Color( COL_TRANSPARENT ) )
1574 : {
1575 0 : METSetMix( eGDIRasterOp );
1576 0 : METSetColor( aGDIFillColor );
1577 0 : METSetBackgroundColor( aGDIFillColor );
1578 0 : METBox( sal_True, sal_False, pA->GetRect(), pA->GetHorzRound(), pA->GetVertRound() );
1579 : }
1580 :
1581 0 : if( aGDILineColor != Color( COL_TRANSPARENT ) )
1582 : {
1583 0 : METSetMix( eGDIRasterOp );
1584 0 : METSetColor( aGDILineColor );
1585 0 : METBox( sal_False, sal_True, pA->GetRect(), pA->GetHorzRound(), pA->GetVertRound() );
1586 : }
1587 : }
1588 0 : break;
1589 :
1590 : case META_ELLIPSE_ACTION:
1591 : {
1592 0 : const MetaEllipseAction* pA = (const MetaEllipseAction*) pMA;
1593 0 : Point aCenter;
1594 :
1595 0 : aCenter.X()=(pA->GetRect().Left()+pA->GetRect().Right())/2;
1596 0 : aCenter.Y()=(pA->GetRect().Top()+pA->GetRect().Bottom())/2;
1597 :
1598 0 : METSetArcParams(pA->GetRect().GetWidth(), pA->GetRect().GetHeight(),0,0);
1599 :
1600 0 : if( aGDIFillColor != Color( COL_TRANSPARENT ) )
1601 : {
1602 0 : METSetMix( eGDIRasterOp );
1603 0 : METSetColor( aGDIFillColor );
1604 0 : METSetBackgroundColor( aGDIFillColor );
1605 0 : METBeginArea(sal_False);
1606 0 : METFullArc(aCenter,0.5);
1607 0 : METEndArea();
1608 : }
1609 :
1610 0 : if( aGDILineColor != Color( COL_TRANSPARENT ) )
1611 : {
1612 0 : METSetMix( eGDIRasterOp );
1613 0 : METSetColor( aGDILineColor );
1614 0 : METFullArc( aCenter,0.5 );
1615 : }
1616 : }
1617 0 : break;
1618 :
1619 : case META_ARC_ACTION:
1620 : {
1621 0 : const MetaArcAction* pA = (const MetaArcAction*) pMA;
1622 0 : Point aStartPos,aCenter;
1623 : double fdx,fdy,fa1,fa2;
1624 :
1625 0 : aCenter.X()=(pA->GetRect().Left()+pA->GetRect().Right())/2;
1626 0 : aCenter.Y()=(pA->GetRect().Top()+pA->GetRect().Bottom())/2;
1627 0 : fdx=(double)(pA->GetStartPoint().X()-aCenter.X());
1628 0 : fdy=(double)(pA->GetStartPoint().Y()-aCenter.Y());
1629 0 : fdx*=(double)pA->GetRect().GetHeight();
1630 0 : fdy*=(double)pA->GetRect().GetWidth();
1631 0 : if (fdx==0.0 && fdy==0.0) fdx=1.0;
1632 0 : fa1=atan2(-fdy,fdx);
1633 0 : fdx=(double)(pA->GetEndPoint().X()-aCenter.X());
1634 0 : fdy=(double)(pA->GetEndPoint().Y()-aCenter.Y());
1635 0 : fdx*=(double)pA->GetRect().GetHeight();
1636 0 : fdy*=(double)pA->GetRect().GetWidth();
1637 0 : if (fdx==0.0 && fdy==0.0) fdx=1.0;
1638 0 : fa2=atan2(-fdy,fdx);
1639 0 : aStartPos.X()=aCenter.X()+(long)(((double)pA->GetRect().GetWidth())*cos(fa1)/2.0+0.5);
1640 0 : aStartPos.Y()=aCenter.Y()-(long)(((double)pA->GetRect().GetHeight())*sin(fa1)/2.0+0.5);
1641 :
1642 0 : if( aGDILineColor != Color( COL_TRANSPARENT ) )
1643 : {
1644 0 : METSetMix( eGDIRasterOp );
1645 0 : METSetColor( aGDILineColor );
1646 0 : METSetArcParams(pA->GetRect().GetWidth(), pA->GetRect().GetHeight(),0,0);
1647 0 : METBeginPath(1);
1648 0 : METMove(aStartPos);
1649 0 : METPartialArcAtCurPos(aCenter,0.5,fa1,fa2-fa1);
1650 0 : METEndPath();
1651 0 : METOutlinePath(1);
1652 : }
1653 : }
1654 0 : break;
1655 :
1656 : case META_PIE_ACTION:
1657 : {
1658 0 : const MetaPieAction* pA = (const MetaPieAction*) pMA;
1659 0 : Point aCenter;
1660 : double fdx,fdy,fa1,fa2;
1661 :
1662 0 : aCenter.X()=(pA->GetRect().Left()+pA->GetRect().Right())/2;
1663 0 : aCenter.Y()=(pA->GetRect().Top()+pA->GetRect().Bottom())/2;
1664 0 : fdx=(double)(pA->GetStartPoint().X()-aCenter.X());
1665 0 : fdy=(double)(pA->GetStartPoint().Y()-aCenter.Y());
1666 0 : fdx*=(double)pA->GetRect().GetHeight();
1667 0 : fdy*=(double)pA->GetRect().GetWidth();
1668 0 : if (fdx==0.0 && fdy==0.0) fdx=1.0;
1669 0 : fa1=atan2(-fdy,fdx);
1670 0 : fdx=(double)(pA->GetEndPoint().X()-aCenter.X());
1671 0 : fdy=(double)(pA->GetEndPoint().Y()-aCenter.Y());
1672 0 : fdx*=(double)pA->GetRect().GetHeight();
1673 0 : fdy*=(double)pA->GetRect().GetWidth();
1674 0 : if (fdx==0.0 && fdy==0.0) fdx=1.0;
1675 0 : fa2=atan2(-fdy,fdx);
1676 :
1677 0 : METSetArcParams(pA->GetRect().GetWidth(), pA->GetRect().GetHeight(),0,0);
1678 :
1679 0 : if( aGDIFillColor != Color( COL_TRANSPARENT ) )
1680 : {
1681 0 : METSetMix( eGDIRasterOp );
1682 0 : METSetColor( aGDIFillColor );
1683 0 : METSetBackgroundColor( aGDIFillColor );
1684 0 : METBeginPath(1);
1685 0 : METMove(aCenter);
1686 0 : METPartialArcAtCurPos(aCenter,0.5,fa1,fa2-fa1);
1687 0 : METLineAtCurPos(aCenter);
1688 0 : METEndPath();
1689 0 : METFillPath(1);
1690 : }
1691 :
1692 0 : if( aGDILineColor != Color( COL_TRANSPARENT ) )
1693 : {
1694 0 : METSetMix( eGDIRasterOp );
1695 0 : METSetColor( aGDILineColor );
1696 0 : METBeginPath(1);
1697 0 : METMove(aCenter);
1698 0 : METPartialArcAtCurPos(aCenter,0.5,fa1,fa2-fa1);
1699 0 : METLineAtCurPos(aCenter);
1700 0 : METEndPath();
1701 0 : METOutlinePath(1);
1702 : }
1703 : }
1704 0 : break;
1705 :
1706 : case META_CHORD_ACTION:
1707 : {
1708 0 : const MetaChordAction* pA = (const MetaChordAction*) pMA;
1709 0 : Point aStartPos,aCenter;
1710 : double fdx,fdy,fa1,fa2;
1711 :
1712 0 : aCenter.X()=(pA->GetRect().Left()+pA->GetRect().Right())/2;
1713 0 : aCenter.Y()=(pA->GetRect().Top()+pA->GetRect().Bottom())/2;
1714 0 : fdx=(double)(pA->GetStartPoint().X()-aCenter.X());
1715 0 : fdy=(double)(pA->GetStartPoint().Y()-aCenter.Y());
1716 0 : fdx*=(double)pA->GetRect().GetHeight();
1717 0 : fdy*=(double)pA->GetRect().GetWidth();
1718 0 : if (fdx==0.0 && fdy==0.0) fdx=1.0;
1719 0 : fa1=atan2(-fdy,fdx);
1720 0 : fdx=(double)(pA->GetEndPoint().X()-aCenter.X());
1721 0 : fdy=(double)(pA->GetEndPoint().Y()-aCenter.Y());
1722 0 : fdx*=(double)pA->GetRect().GetHeight();
1723 0 : fdy*=(double)pA->GetRect().GetWidth();
1724 0 : if (fdx==0.0 && fdy==0.0) fdx=1.0;
1725 0 : fa2=atan2(-fdy,fdx);
1726 0 : aStartPos.X()=aCenter.X()+(long)(((double)pA->GetRect().GetWidth())*cos(fa1)/2.0+0.5);
1727 0 : aStartPos.Y()=aCenter.Y()-(long)(((double)pA->GetRect().GetHeight())*sin(fa1)/2.0+0.5);
1728 :
1729 0 : if( aGDIFillColor != Color( COL_TRANSPARENT ) )
1730 : {
1731 0 : METSetMix( eGDIRasterOp );
1732 0 : METSetColor( aGDIFillColor );
1733 0 : METSetBackgroundColor( aGDIFillColor );
1734 0 : METBeginPath(1);
1735 0 : METMove(aStartPos);
1736 0 : METPartialArcAtCurPos(aCenter,0.5,fa1,fa2-fa1);
1737 0 : METLineAtCurPos(aStartPos);
1738 0 : METEndPath();
1739 0 : METFillPath(1);
1740 : }
1741 :
1742 0 : if( aGDILineColor != Color( COL_TRANSPARENT ) )
1743 : {
1744 0 : METSetMix( eGDIRasterOp );
1745 0 : METSetColor( aGDILineColor );
1746 0 : METBeginPath(1);
1747 0 : METMove(aStartPos);
1748 0 : METPartialArcAtCurPos(aCenter,0.5,fa1,fa2-fa1);
1749 0 : METLineAtCurPos(aStartPos);
1750 0 : METEndPath();
1751 0 : METOutlinePath(1);
1752 : }
1753 : }
1754 0 : break;
1755 :
1756 : case META_POLYLINE_ACTION:
1757 : {
1758 0 : const MetaPolyLineAction* pA = (const MetaPolyLineAction*) pMA;
1759 :
1760 0 : if( aGDILineColor != Color( COL_TRANSPARENT ) )
1761 : {
1762 0 : LineInfo aLineInfo( pA->GetLineInfo() );
1763 0 : if ( ! ( aLineInfo.IsDefault() ) )
1764 0 : METSetAndPushLineInfo( aLineInfo );
1765 :
1766 0 : METSetMix(eGDIRasterOp);
1767 0 : METSetColor(aGDILineColor);
1768 0 : METBeginPath(1);
1769 0 : Polygon aSimplePoly;
1770 0 : const Polygon& rPoly = pA->GetPolygon();
1771 0 : if ( rPoly.HasFlags() )
1772 0 : rPoly.AdaptiveSubdivide( aSimplePoly );
1773 : else
1774 0 : aSimplePoly = rPoly;
1775 0 : METLine( aSimplePoly );
1776 0 : METEndPath();
1777 0 : METOutlinePath(1);
1778 :
1779 0 : if ( ! ( aLineInfo.IsDefault() ) )
1780 0 : METPopLineInfo( aLineInfo );
1781 : }
1782 : }
1783 0 : break;
1784 :
1785 : case META_POLYGON_ACTION:
1786 : {
1787 0 : const MetaPolygonAction* pA = (const MetaPolygonAction*) pMA;
1788 0 : Polygon aSimplePoly;
1789 0 : const Polygon& rPoly = pA->GetPolygon();
1790 0 : if ( rPoly.HasFlags() )
1791 0 : rPoly.AdaptiveSubdivide( aSimplePoly );
1792 : else
1793 0 : aSimplePoly = rPoly;
1794 0 : if( aGDIFillColor != Color( COL_TRANSPARENT ) )
1795 : {
1796 0 : METSetMix(eGDIRasterOp);
1797 0 : METSetColor(aGDIFillColor );
1798 0 : METSetBackgroundColor(aGDIFillColor );
1799 0 : METBeginPath(1);
1800 0 : METLine( aSimplePoly );
1801 0 : METEndPath();
1802 0 : METFillPath(1);
1803 : }
1804 :
1805 0 : if( aGDILineColor != Color( COL_TRANSPARENT ) )
1806 : {
1807 0 : METSetMix(eGDIRasterOp);
1808 0 : METSetColor(aGDILineColor );
1809 0 : METBeginPath(1);
1810 0 : METLine( aSimplePoly );
1811 0 : METEndPath();
1812 0 : METOutlinePath(1);
1813 0 : }
1814 : }
1815 0 : break;
1816 :
1817 : case META_POLYPOLYGON_ACTION:
1818 : {
1819 0 : const MetaPolyPolygonAction* pA = (const MetaPolyPolygonAction*) pMA;
1820 :
1821 0 : PolyPolygon aSimplePolyPoly( pA->GetPolyPolygon() );
1822 0 : sal_uInt16 i, nCount = aSimplePolyPoly.Count();
1823 0 : for ( i = 0; i < nCount; i++ )
1824 : {
1825 0 : if ( aSimplePolyPoly[ i ].HasFlags() )
1826 : {
1827 0 : Polygon aSimplePoly;
1828 0 : aSimplePolyPoly[ i ].AdaptiveSubdivide( aSimplePoly );
1829 0 : aSimplePolyPoly[ i ] = aSimplePoly;
1830 : }
1831 : }
1832 0 : if( aGDIFillColor != Color( COL_TRANSPARENT ) )
1833 : {
1834 0 : METSetMix(eGDIRasterOp);
1835 0 : METSetColor(aGDIFillColor);
1836 0 : METSetBackgroundColor(aGDIFillColor);
1837 0 : METBeginPath(1);
1838 0 : METLine( aSimplePolyPoly );
1839 0 : METEndPath();
1840 0 : METFillPath(1);
1841 : }
1842 :
1843 0 : if( aGDILineColor != Color( COL_TRANSPARENT ) )
1844 : {
1845 0 : METSetMix(eGDIRasterOp);
1846 0 : METSetColor(aGDILineColor);
1847 0 : METBeginPath(1);
1848 0 : METLine( aSimplePolyPoly );
1849 0 : METEndPath();
1850 0 : METOutlinePath(1);
1851 0 : }
1852 : }
1853 0 : break;
1854 :
1855 : case META_TEXT_ACTION:
1856 : {
1857 0 : const MetaTextAction* pA = (const MetaTextAction*) pMA;
1858 0 : Point aPt( pA->GetPoint() );
1859 :
1860 0 : if( aGDIFont.GetAlign() != ALIGN_BASELINE)
1861 : {
1862 0 : VirtualDevice aVDev;
1863 :
1864 0 : if( aGDIFont.GetAlign()==ALIGN_TOP )
1865 0 : aPt.Y()+=(long)aVDev.GetFontMetric( aGDIFont ).GetAscent();
1866 : else
1867 0 : aPt.Y()-=(long)aVDev.GetFontMetric( aGDIFont ).GetDescent();
1868 : }
1869 :
1870 0 : METSetMix(eGDIRasterOp);
1871 0 : METSetColor(aGDIFont.GetColor());
1872 0 : METSetBackgroundColor(aGDIFont.GetFillColor());
1873 0 : METSetChrCellSize(aGDIFont.GetSize());
1874 0 : METSetChrAngle(aGDIFont.GetOrientation());
1875 0 : METSetChrSet(FindChrSet(aGDIFont));
1876 0 : METChrStr(aPt, pA->GetText().copy(pA->GetIndex(),pA->GetLen()));
1877 : }
1878 0 : break;
1879 :
1880 : case META_TEXTARRAY_ACTION:
1881 : {
1882 0 : const MetaTextArrayAction* pA = (const MetaTextArrayAction*) pMA;
1883 : sal_uInt16 i;
1884 0 : OUString aStr;
1885 0 : Polygon aPolyDummy(1);
1886 : short nOrientation;
1887 0 : Point aPt( pA->GetPoint() );
1888 :
1889 0 : if( aGDIFont.GetAlign() != ALIGN_BASELINE )
1890 : {
1891 0 : VirtualDevice aVDev;
1892 0 : if( aGDIFont.GetAlign() == ALIGN_TOP )
1893 0 : aPt.Y()+=(long)aVDev.GetFontMetric(aGDIFont).GetAscent();
1894 : else
1895 0 : aPt.Y()-=(long)aVDev.GetFontMetric(aGDIFont).GetDescent();
1896 : }
1897 :
1898 0 : METSetMix(eGDIRasterOp);
1899 0 : METSetColor(aGDIFont.GetColor());
1900 0 : METSetBackgroundColor(aGDIFont.GetFillColor());
1901 0 : METSetChrCellSize(aGDIFont.GetSize());
1902 0 : METSetChrAngle( nOrientation = aGDIFont.GetOrientation() );
1903 0 : METSetChrSet(FindChrSet(aGDIFont));
1904 0 : aStr = pA->GetText().copy(pA->GetIndex(),pA->GetLen());
1905 :
1906 0 : if( pA->GetDXArray()!=NULL )
1907 : {
1908 0 : Point aPt2;
1909 :
1910 0 : for( i=0; i < aStr.getLength(); i++ )
1911 : {
1912 0 : aPt2 = aPt;
1913 0 : if ( i > 0 )
1914 : {
1915 0 : aPt2.X() += pA->GetDXArray()[i-1];
1916 0 : if ( nOrientation )
1917 : {
1918 0 : aPolyDummy.SetPoint( aPt2, 0 );
1919 0 : aPolyDummy.Rotate( aPt, nOrientation );
1920 0 : aPt2 = aPolyDummy.GetPoint( 0 );
1921 : }
1922 : }
1923 0 : METChrStr( aPt2, OUString( aStr[ i ] ) );
1924 : }
1925 : }
1926 : else
1927 0 : METChrStr( aPt, aStr );
1928 : }
1929 0 : break;
1930 :
1931 : case META_STRETCHTEXT_ACTION:
1932 : {
1933 0 : const MetaStretchTextAction* pA = (const MetaStretchTextAction*) pMA;
1934 0 : VirtualDevice aVDev;
1935 : sal_uInt16 i;
1936 : sal_Int32 nNormSize;
1937 0 : OUString aStr;
1938 0 : Polygon aPolyDummy(1);
1939 : short nOrientation;
1940 0 : Point aPt( pA->GetPoint() );
1941 0 : Point aPt2;
1942 :
1943 0 : aVDev.SetFont( aGDIFont );
1944 :
1945 0 : if( aGDIFont.GetAlign() != ALIGN_BASELINE)
1946 : {
1947 0 : if( aGDIFont.GetAlign() == ALIGN_TOP )
1948 0 : aPt.Y()+=(long)aVDev.GetFontMetric().GetAscent();
1949 : else
1950 0 : aPt.Y()-=(long)aVDev.GetFontMetric().GetDescent();
1951 : }
1952 :
1953 0 : METSetMix(eGDIRasterOp);
1954 0 : METSetColor(aGDIFont.GetColor());
1955 0 : METSetBackgroundColor(aGDIFont.GetFillColor());
1956 0 : METSetChrCellSize(aGDIFont.GetSize());
1957 0 : METSetChrAngle( nOrientation = aGDIFont.GetOrientation() );
1958 0 : METSetChrSet(FindChrSet(aGDIFont));
1959 0 : aStr = pA->GetText().copy(pA->GetIndex(),pA->GetLen());
1960 0 : boost::scoped_array<sal_Int32> pDXAry(new sal_Int32[aStr.getLength()]);
1961 0 : nNormSize = aVDev.GetTextArray( aStr, pDXAry.get() );
1962 :
1963 0 : for ( i = 0; i < aStr.getLength(); i++ )
1964 : {
1965 0 : aPt2 = aPt;
1966 0 : if ( i > 0 )
1967 : {
1968 0 : aPt2.X() += pDXAry[i-1]*((long)pA->GetWidth())/ nNormSize;
1969 0 : if ( nOrientation )
1970 : {
1971 0 : aPolyDummy.SetPoint( aPt2, 0 );
1972 0 : aPolyDummy.Rotate( aPt, nOrientation );
1973 0 : aPt2 = aPolyDummy.GetPoint( 0 );
1974 : }
1975 : }
1976 0 : METChrStr( aPt2, OUString( aStr[ i ] ) );
1977 0 : }
1978 : }
1979 0 : break;
1980 :
1981 : case META_TEXTRECT_ACTION:
1982 : {
1983 : // OSL_FAIL( "Unsupported MET-Action: META_TEXTRECT_ACTION!" );
1984 : }
1985 0 : break;
1986 :
1987 : case META_BMP_ACTION:
1988 : {
1989 0 : const MetaBmpAction* pA = (const MetaBmpAction*) pMA;
1990 0 : const Size aSizePixel( pA->GetBitmap().GetSizePixel() );
1991 :
1992 0 : METSetMix(eGDIRasterOp);
1993 0 : METBitBlt( pA->GetPoint(), pCompDev->PixelToLogic( aSizePixel, aPictureMapMode ), aSizePixel );
1994 : }
1995 0 : break;
1996 :
1997 : case META_BMPSCALE_ACTION:
1998 : {
1999 0 : const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pMA;
2000 :
2001 0 : METSetMix(eGDIRasterOp);
2002 0 : METBitBlt( pA->GetPoint(), pA->GetSize(), pA->GetBitmap().GetSizePixel() );
2003 : }
2004 0 : break;
2005 :
2006 : case META_BMPSCALEPART_ACTION:
2007 : {
2008 0 : const MetaBmpScalePartAction* pA = (const MetaBmpScalePartAction*) pMA;
2009 0 : Bitmap aTmp( pA->GetBitmap() );
2010 :
2011 0 : aTmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
2012 0 : METSetMix( eGDIRasterOp );
2013 0 : METBitBlt( pA->GetDestPoint(), pA->GetDestSize(), pA->GetBitmap().GetSizePixel() );
2014 : }
2015 0 : break;
2016 :
2017 : case META_BMPEX_ACTION:
2018 : {
2019 0 : const MetaBmpExAction* pA = (const MetaBmpExAction*) pMA;
2020 0 : const Size aSizePixel( pA->GetBitmapEx().GetSizePixel() );
2021 :
2022 0 : METSetMix( eGDIRasterOp );
2023 0 : METBitBlt( pA->GetPoint(), pCompDev->PixelToLogic( aSizePixel, aPictureMapMode ), aSizePixel );
2024 : }
2025 0 : break;
2026 :
2027 : case META_BMPEXSCALE_ACTION:
2028 : {
2029 0 : const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pMA;
2030 0 : const Size aSizePixel( pA->GetBitmapEx().GetSizePixel() );
2031 :
2032 0 : METSetMix( eGDIRasterOp );
2033 0 : METBitBlt( pA->GetPoint(), pA->GetSize(), aSizePixel );
2034 : }
2035 0 : break;
2036 :
2037 : case META_BMPEXSCALEPART_ACTION:
2038 : {
2039 0 : const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*) pMA;
2040 0 : Bitmap aTmp( Graphic( pA->GetBitmapEx() ).GetBitmap() );
2041 :
2042 0 : aTmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
2043 0 : METSetMix( eGDIRasterOp );
2044 0 : METBitBlt( pA->GetDestPoint(), pA->GetDestSize(), aTmp.GetSizePixel() );
2045 : }
2046 0 : break;
2047 :
2048 : case META_EPS_ACTION :
2049 : {
2050 0 : const MetaEPSAction* pA = (const MetaEPSAction*)pMA;
2051 0 : const GDIMetaFile aGDIMetaFile( pA->GetSubstitute() );
2052 :
2053 0 : size_t nCount = aGDIMetaFile.GetActionSize();
2054 0 : for ( size_t i = 0; i < nCount; i++ )
2055 : {
2056 0 : const MetaAction* pMetaAct = aGDIMetaFile.GetAction( i );
2057 0 : if ( pMetaAct->GetType() == META_BMPSCALE_ACTION )
2058 : {
2059 0 : const MetaBmpScaleAction* pBmpScaleAction = (const MetaBmpScaleAction*)pMetaAct;
2060 0 : METSetMix(eGDIRasterOp);
2061 0 : METBitBlt( pA->GetPoint(), pA->GetSize(), pBmpScaleAction->GetBitmap().GetSizePixel() );
2062 0 : break;
2063 : }
2064 0 : }
2065 : }
2066 0 : break;
2067 :
2068 : case META_MASK_ACTION:
2069 0 : break;
2070 :
2071 : case META_MASKSCALE_ACTION:
2072 0 : break;
2073 :
2074 : case META_MASKSCALEPART_ACTION:
2075 0 : break;
2076 :
2077 : case META_GRADIENT_ACTION:
2078 : {
2079 0 : VirtualDevice aVDev;
2080 0 : GDIMetaFile aTmpMtf;
2081 0 : const MetaGradientAction* pA = (const MetaGradientAction*) pMA;
2082 :
2083 0 : aVDev.SetMapMode( aTargetMapMode );
2084 0 : aVDev.AddGradientActions( pA->GetRect(), pA->GetGradient(), aTmpMtf );
2085 0 : WriteOrders( &aTmpMtf );
2086 : }
2087 0 : break;
2088 :
2089 : case META_HATCH_ACTION:
2090 : {
2091 0 : VirtualDevice aVDev;
2092 0 : GDIMetaFile aTmpMtf;
2093 0 : const MetaHatchAction* pA = (const MetaHatchAction*) pMA;
2094 :
2095 0 : aVDev.SetMapMode( aTargetMapMode );
2096 0 : aVDev.AddHatchActions( pA->GetPolyPolygon(), pA->GetHatch(), aTmpMtf );
2097 0 : WriteOrders( &aTmpMtf );
2098 : }
2099 0 : break;
2100 :
2101 : case META_WALLPAPER_ACTION:
2102 0 : break;
2103 :
2104 : case META_CLIPREGION_ACTION:
2105 0 : break;
2106 :
2107 : case META_ISECTRECTCLIPREGION_ACTION:
2108 : {
2109 0 : const MetaISectRectClipRegionAction* pA = (const MetaISectRectClipRegionAction*) pMA;
2110 0 : WriteClipRect( pA->GetRect() );
2111 : }
2112 0 : break;
2113 :
2114 : case META_ISECTREGIONCLIPREGION_ACTION:
2115 0 : break;
2116 :
2117 : case META_MOVECLIPREGION_ACTION:
2118 0 : break;
2119 :
2120 : case META_LINECOLOR_ACTION:
2121 : {
2122 0 : const MetaLineColorAction* pA = (const MetaLineColorAction*) pMA;
2123 :
2124 0 : if( pA->IsSetting() )
2125 0 : aGDILineColor = pA->GetColor();
2126 : else
2127 0 : aGDILineColor = Color( COL_TRANSPARENT );
2128 : }
2129 0 : break;
2130 :
2131 : case META_FILLCOLOR_ACTION:
2132 : {
2133 0 : const MetaFillColorAction* pA = (const MetaFillColorAction*) pMA;
2134 :
2135 0 : if( pA->IsSetting() )
2136 0 : aGDIFillColor = pA->GetColor();
2137 : else
2138 0 : aGDIFillColor = Color( COL_TRANSPARENT );
2139 : }
2140 0 : break;
2141 :
2142 : case META_TEXTCOLOR_ACTION:
2143 : {
2144 0 : const MetaTextColorAction* pA = (const MetaTextColorAction*) pMA;
2145 0 : aGDIFont.SetColor( pA->GetColor() );
2146 : }
2147 0 : break;
2148 :
2149 : case META_TEXTFILLCOLOR_ACTION:
2150 : {
2151 0 : const MetaTextFillColorAction* pA = (const MetaTextFillColorAction*) pMA;
2152 :
2153 0 : if( pA->IsSetting() )
2154 0 : aGDIFont.SetFillColor( pA->GetColor() );
2155 : else
2156 0 : aGDIFont.SetFillColor( Color( COL_TRANSPARENT ) );
2157 : }
2158 0 : break;
2159 :
2160 : case META_TEXTALIGN_ACTION:
2161 0 : break;
2162 :
2163 : case META_MAPMODE_ACTION:
2164 : {
2165 0 : const MetaMapModeAction* pA = (const MetaMapModeAction*) pMA;
2166 :
2167 0 : if( aPictureMapMode != pA->GetMapMode() )
2168 : {
2169 0 : if ( pA->GetMapMode().GetMapUnit() == MAP_RELATIVE )
2170 : {
2171 0 : MapMode aMM = pA->GetMapMode();
2172 0 : Fraction aScaleX = aMM.GetScaleX();
2173 0 : Fraction aScaleY = aMM.GetScaleY();
2174 :
2175 0 : Point aOrigin = aPictureMapMode.GetOrigin();
2176 0 : BigInt aX( aOrigin.X() );
2177 0 : aX *= BigInt( aScaleX.GetDenominator() );
2178 :
2179 0 : if( aOrigin.X() >= 0 )
2180 : {
2181 0 : if( aScaleX.GetNumerator() >= 0 )
2182 0 : aX += BigInt( aScaleX.GetNumerator()/2 );
2183 : else
2184 0 : aX -= BigInt( (aScaleX.GetNumerator()+1)/2 );
2185 : }
2186 : else
2187 : {
2188 0 : if( aScaleX.GetNumerator() >= 0 )
2189 0 : aX -= BigInt( (aScaleX.GetNumerator()-1)/2 );
2190 : else
2191 0 : aX += BigInt( aScaleX.GetNumerator()/2 );
2192 : }
2193 :
2194 0 : aX /= BigInt( aScaleX.GetNumerator() );
2195 0 : aOrigin.X() = (long) aX + aMM.GetOrigin().X();
2196 :
2197 0 : BigInt aY( aOrigin.Y() );
2198 0 : aY *= BigInt( aScaleY.GetDenominator() );
2199 :
2200 0 : if( aOrigin.Y() >= 0 )
2201 : {
2202 0 : if( aScaleY.GetNumerator() >= 0 )
2203 0 : aY += BigInt( aScaleY.GetNumerator()/2 );
2204 : else
2205 0 : aY -= BigInt( (aScaleY.GetNumerator()+1)/2 );
2206 : }
2207 : else
2208 : {
2209 0 : if( aScaleY.GetNumerator() >= 0 )
2210 0 : aY -= BigInt( (aScaleY.GetNumerator()-1)/2 );
2211 : else
2212 0 : aY += BigInt( aScaleY.GetNumerator()/2 );
2213 : }
2214 :
2215 0 : aY /= BigInt( aScaleY.GetNumerator() );
2216 0 : aOrigin.Y() = (long)aY + aMM.GetOrigin().Y();
2217 0 : aPictureMapMode.SetOrigin( aOrigin );
2218 :
2219 0 : aScaleX *= aPictureMapMode.GetScaleX();
2220 0 : aScaleY *= aPictureMapMode.GetScaleY();
2221 0 : aPictureMapMode.SetScaleX( aScaleX );
2222 0 : aPictureMapMode.SetScaleY( aScaleY );
2223 : }
2224 : else
2225 0 : aPictureMapMode=pA->GetMapMode();
2226 : }
2227 : }
2228 0 : break;
2229 :
2230 : case META_FONT_ACTION:
2231 : {
2232 0 : aGDIFont = ( (const MetaFontAction*) pMA )->GetFont();
2233 : }
2234 0 : break;
2235 :
2236 : case META_PUSH_ACTION:
2237 : {
2238 0 : METGDIStackMember* pGS = new METGDIStackMember;
2239 :
2240 0 : pGS->pSucc=pGDIStack; pGDIStack=pGS;
2241 0 : pGS->aLineColor=aGDILineColor;
2242 0 : pGS->aFillColor=aGDIFillColor;
2243 0 : pGS->eRasterOp=eGDIRasterOp;
2244 0 : pGS->aFont=aGDIFont;
2245 0 : pGS->aMapMode=aPictureMapMode;
2246 0 : pGS->aClipRect=aGDIClipRect;
2247 : }
2248 0 : break;
2249 :
2250 : case META_POP_ACTION:
2251 : {
2252 : METGDIStackMember* pGS;
2253 :
2254 0 : if( pGDIStack )
2255 : {
2256 0 : pGS=pGDIStack; pGDIStack=pGS->pSucc;
2257 0 : aGDILineColor=pGS->aLineColor;
2258 0 : aGDIFillColor=pGS->aFillColor;
2259 0 : eGDIRasterOp=pGS->eRasterOp;
2260 0 : aGDIFont=pGS->aFont;
2261 0 : if ( pGS->aClipRect != aGDIClipRect )
2262 0 : WriteClipRect( pGS->aClipRect );
2263 0 : aPictureMapMode=pGS->aMapMode;
2264 0 : delete pGS;
2265 : }
2266 : }
2267 0 : break;
2268 :
2269 : case META_RASTEROP_ACTION:
2270 : {
2271 0 : eGDIRasterOp = ( (const MetaRasterOpAction*) pMA )->GetRasterOp();
2272 : }
2273 0 : break;
2274 :
2275 : case META_TRANSPARENT_ACTION:
2276 : {
2277 0 : if( aGDIFillColor != Color( COL_TRANSPARENT ) )
2278 : {
2279 0 : METSetMix(eGDIRasterOp);
2280 0 : METSetColor(aGDIFillColor);
2281 0 : METSetBackgroundColor(aGDIFillColor);
2282 0 : METBeginPath(1);
2283 0 : METLine(( (const MetaTransparentAction*) pMA )->GetPolyPolygon());
2284 0 : METEndPath();
2285 0 : METFillPath(1);
2286 : }
2287 :
2288 0 : if( aGDILineColor != Color( COL_TRANSPARENT ) )
2289 : {
2290 0 : METSetMix(eGDIRasterOp);
2291 0 : METSetColor(aGDILineColor);
2292 0 : METBeginPath(1);
2293 0 : METLine(( (const MetaTransparentAction*) pMA )->GetPolyPolygon());
2294 0 : METEndPath();
2295 0 : METOutlinePath(1);
2296 : }
2297 : }
2298 0 : break;
2299 :
2300 : case META_FLOATTRANSPARENT_ACTION:
2301 : {
2302 0 : const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pMA;
2303 :
2304 0 : GDIMetaFile aTmpMtf( pA->GetGDIMetaFile() );
2305 0 : Point aSrcPt( aTmpMtf.GetPrefMapMode().GetOrigin() );
2306 0 : const Size aSrcSize( aTmpMtf.GetPrefSize() );
2307 0 : const Point aDestPt( pA->GetPoint() );
2308 0 : const Size aDestSize( pA->GetSize() );
2309 0 : const double fScaleX = aSrcSize.Width() ? (double) aDestSize.Width() / aSrcSize.Width() : 1.0;
2310 0 : const double fScaleY = aSrcSize.Height() ? (double) aDestSize.Height() / aSrcSize.Height() : 1.0;
2311 : long nMoveX, nMoveY;
2312 :
2313 0 : if( fScaleX != 1.0 || fScaleY != 1.0 )
2314 : {
2315 0 : aTmpMtf.Scale( fScaleX, fScaleY );
2316 0 : aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
2317 : }
2318 :
2319 0 : nMoveX = aDestPt.X() - aSrcPt.X(), nMoveY = aDestPt.Y() - aSrcPt.Y();
2320 :
2321 0 : if( nMoveX || nMoveY )
2322 0 : aTmpMtf.Move( nMoveX, nMoveY );
2323 :
2324 0 : WriteOrders( &aTmpMtf );
2325 : }
2326 0 : break;
2327 : }
2328 :
2329 0 : nWrittenActions++;
2330 0 : MayCallback();
2331 :
2332 0 : if( pMET->GetError() )
2333 0 : bStatus=sal_False;
2334 :
2335 0 : if( bStatus == sal_False )
2336 0 : break;
2337 : }
2338 : }
2339 :
2340 0 : void METWriter::WriteObjectEnvironmentGroup(const GDIMetaFile * pMTF)
2341 : {
2342 : sal_uLong i, nId;
2343 :
2344 : //--- The Field 'Begin Object Environment Group':
2345 0 : WriteFieldIntroducer(16,BegObjEnvMagic,0,0);
2346 0 : WriteFieldId(7);
2347 :
2348 : //--- The Field 'Map Color Attribute Table':
2349 0 : WriteFieldIntroducer(22,MapColAtrMagic,0,0);
2350 0 : WriteBigEndianShort(0x000e);
2351 0 : pMET->WriteUChar( (sal_uInt8)0x0c ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x84 ).WriteUChar( (sal_uInt8)0x00 );
2352 0 : WriteFieldId(4);
2353 :
2354 : //--- The first Field 'Map Coded Font':
2355 0 : WriteFieldIntroducer(32,MapCodFntMagic,0,0);
2356 0 : WriteBigEndianShort(0x0018);
2357 0 : pMET->WriteUChar( (sal_uInt8)0x0c ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x84 ).WriteUChar( (sal_uInt8)0x00 );
2358 0 : pMET->WriteUChar( (sal_uInt8)0xff ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
2359 0 : pMET->WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
2360 0 : pMET->WriteUChar( (sal_uInt8)0x04 ).WriteUChar( (sal_uInt8)0x24 ).WriteUChar( (sal_uInt8)0x05 ).WriteUChar( (sal_uInt8)0x00 );
2361 0 : pMET->WriteUChar( (sal_uInt8)0x06 ).WriteUChar( (sal_uInt8)0x20 );
2362 0 : pMET->WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0x97 ).WriteUChar( (sal_uInt8)0x01 ).WriteUChar( (sal_uInt8)0xb5 );
2363 :
2364 : //--- The additional Fields 'Map Coded Font':
2365 0 : CreateChrSets(pMTF);
2366 0 : WriteChrSets();
2367 :
2368 : //--- The Fields 'Map Data Resource':
2369 0 : nId=nActBitmapId;
2370 0 : for (i=0; i<nNumberOfBitmaps; i++)
2371 : {
2372 0 : WriteFieldIntroducer(29,MapDatResMagic,0,0);
2373 0 : WriteBigEndianShort(0x0015);
2374 0 : pMET->WriteUChar( (sal_uInt8)0x0c ).WriteUChar( (sal_uInt8)0x02 ).WriteUChar( (sal_uInt8)0x84 ).WriteUChar( (sal_uInt8)0x00 );
2375 0 : WriteFieldId(nId);
2376 0 : pMET->WriteUChar( (sal_uInt8)0x07 ).WriteUChar( (sal_uInt8)0x22 ).WriteUChar( (sal_uInt8)0x10 );
2377 0 : pMET->WriteUInt32( (sal_uInt32)nId );
2378 0 : nId++;
2379 : }
2380 :
2381 : //--- Das Feld 'End Object Environment Group':
2382 0 : WriteFieldIntroducer(16,EndObjEnvMagic,0,0);
2383 0 : WriteFieldId(7);
2384 0 : }
2385 :
2386 :
2387 0 : void METWriter::WriteGraphicsObject(const GDIMetaFile * pMTF)
2388 : {
2389 : sal_uLong nSegmentSize,nPos,nDataFieldsStartPos;
2390 :
2391 0 : if( bStatus==sal_False )
2392 0 : return;
2393 :
2394 : //--- Das Feld 'Begin Graphics Object':
2395 0 : WriteFieldIntroducer(16,BegGrfObjMagic,0,0);
2396 0 : WriteFieldId(7);
2397 :
2398 : // Map Color Attribute Table, Fonts and other stuff:
2399 0 : WriteObjectEnvironmentGroup(pMTF);
2400 :
2401 : //--- The Field 'Graphics Data Descriptor':
2402 0 : WriteDataDescriptor(pMTF);
2403 :
2404 : // initialise the counter for Data Fields:
2405 0 : nNumberOfDataFields=0;
2406 :
2407 : // and remember the position of the first Data Field:
2408 0 : nDataFieldsStartPos=pMET->Tell();
2409 :
2410 : //--- start of the first Field 'Graphics Data'
2411 0 : WriteFieldIntroducer(0,DatGrfObjMagic,0,0);
2412 0 : nNumberOfDataFields++;
2413 :
2414 : // now at first we write the head of the segment:
2415 0 : pMET->WriteUChar( (sal_uInt8)0x70 ).WriteUChar( (sal_uInt8)0x0e ).WriteUInt32( (sal_uInt32)0 );
2416 0 : pMET->WriteUChar( (sal_uInt8)0x70 ).WriteUChar( (sal_uInt8)0x10 ); // Flags
2417 0 : pMET->WriteUInt16( (sal_uInt16)0 ); // Lo-Word of the length of the segment data (Big Endian)
2418 0 : pMET->WriteUInt32( (sal_uInt32)0 ); // Reserved
2419 0 : pMET->WriteUInt16( (sal_uInt16)0 ); // Hi-Word of the length of the segment (Big Endian) (Ohh Ohh OS2)
2420 : // Annotation: we're writing the correct data length again below
2421 :
2422 : // now all orders are being written out:
2423 : // (wobei die Sache ggf. in mehrere 'Graphics Data Fields' aufgeteilt
2424 : // wird, per Methode WillWriteOrder(..))
2425 0 : WriteOrders(pMTF);
2426 :
2427 : //--- terminate the last Field 'Graphic Data':
2428 0 : UpdateFieldSize();
2429 :
2430 : //--- and finally correct the segment size:
2431 0 : nPos=pMET->Tell();
2432 0 : nSegmentSize=nPos-nDataFieldsStartPos;
2433 0 : nSegmentSize-=nNumberOfDataFields*8; // Structured Field Introducers are not counted
2434 0 : pMET->Seek(nDataFieldsStartPos+16); // seek to the Lo-Word of the segment size
2435 0 : WriteBigEndianShort((sal_uInt16)(nSegmentSize&0x0000ffff)); // Und schreiben
2436 0 : pMET->Seek(nDataFieldsStartPos+22); // seek to the Hi-Word of the segment size
2437 0 : WriteBigEndianShort((sal_uInt16)(nSegmentSize>>16)); // and writing it
2438 0 : pMET->Seek(nPos); // back to business as usual
2439 :
2440 : //--- The Field 'End Graphic Objects':
2441 0 : WriteFieldIntroducer(16,EndGrfObjMagic,0,0);
2442 0 : WriteFieldId(7);
2443 :
2444 0 : if( pMET->GetError() )
2445 0 : bStatus=sal_False;
2446 : }
2447 :
2448 :
2449 0 : void METWriter::WriteResourceGroup(const GDIMetaFile * pMTF)
2450 : {
2451 0 : if( bStatus==sal_False )
2452 0 : return;
2453 :
2454 : //--- The Field 'Begin Resource Group':
2455 0 : WriteFieldIntroducer(16,BegResGrpMagic,0,0);
2456 0 : WriteFieldId(2);
2457 :
2458 : //--- The Content:
2459 0 : WriteColorAttributeTable();
2460 0 : nActBitmapId=0x77777700;
2461 0 : WriteImageObjects(pMTF);
2462 0 : nActBitmapId=0x77777700;
2463 0 : WriteGraphicsObject(pMTF);
2464 :
2465 : //--- The Field 'End Resource Group':
2466 0 : WriteFieldIntroducer(16,EndResGrpMagic,0,0);
2467 0 : WriteFieldId(2);
2468 :
2469 0 : if( pMET->GetError() )
2470 0 : bStatus=sal_False;
2471 : }
2472 :
2473 :
2474 0 : void METWriter::WriteDocument(const GDIMetaFile * pMTF)
2475 : {
2476 0 : if( bStatus==sal_False )
2477 0 : return;
2478 :
2479 : //--- The Field 'Begin Document':
2480 0 : WriteFieldIntroducer(0,BegDocumnMagic,0,0);
2481 0 : WriteFieldId(1);
2482 0 : pMET->WriteUChar( (sal_uInt8)0x00 ).WriteUChar( (sal_uInt8)0x00 );
2483 0 : pMET->WriteUChar( (sal_uInt8)0x05 ).WriteUChar( (sal_uInt8)0x18 ).WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0x0c ).WriteUChar( (sal_uInt8)0x00 );
2484 0 : pMET->WriteUChar( (sal_uInt8)0x06 ).WriteUChar( (sal_uInt8)0x01 ).WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0xd4 ).WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0x52 );
2485 0 : pMET->WriteUChar( (sal_uInt8)0x03 ).WriteUChar( (sal_uInt8)0x65 ).WriteUChar( (sal_uInt8)0x00 );
2486 0 : UpdateFieldSize();
2487 :
2488 : //--- The Content:
2489 0 : WriteResourceGroup(pMTF);
2490 :
2491 : //--- The Field 'End Document':
2492 0 : WriteFieldIntroducer(16,EndDocumnMagic,0,0);
2493 0 : WriteFieldId(1);
2494 :
2495 0 : if( pMET->GetError() )
2496 0 : bStatus=sal_False;
2497 : }
2498 :
2499 0 : sal_Bool METWriter::WriteMET( const GDIMetaFile& rMTF, SvStream& rTargetStream, FilterConfigItem* pFilterConfigItem )
2500 : {
2501 0 : if ( pFilterConfigItem )
2502 : {
2503 0 : xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
2504 0 : if ( xStatusIndicator.is() )
2505 : {
2506 0 : OUString aMsg;
2507 0 : xStatusIndicator->start( aMsg, 100 );
2508 : }
2509 : }
2510 :
2511 : METChrSet* pCS;
2512 : METGDIStackMember* pGS;
2513 :
2514 0 : bStatus=sal_True;
2515 0 : nLastPercent=0;
2516 :
2517 0 : pMET=&rTargetStream;
2518 0 : pMET->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
2519 :
2520 0 : aPictureRect = Rectangle( Point(), rMTF.GetPrefSize() );
2521 0 : aTargetMapMode = aPictureMapMode = rMTF.GetPrefMapMode();
2522 :
2523 0 : aGDILineColor=Color( COL_BLACK );
2524 0 : aGDIFillColor=Color( COL_WHITE );
2525 0 : eGDIRasterOp=ROP_OVERPAINT;
2526 0 : aGDIFont=Font();
2527 0 : aGDIMapMode=MapMode();
2528 0 : aGDIClipRect=Rectangle();
2529 0 : pGDIStack=NULL;
2530 0 : aMETColor=Color(COL_BLACK);
2531 0 : aMETBackgroundColor=Color(COL_WHITE);
2532 0 : eMETMix=ROP_OVERPAINT;
2533 0 : nMETStrokeLineWidth=1;
2534 0 : aMETChrCellSize=Size(0,0);
2535 0 : nMETChrAngle=0;
2536 0 : nMETChrSet=0x00;
2537 0 : pChrSetList=NULL;
2538 0 : nNextChrSetId=1;
2539 0 : nNumberOfActions=0;
2540 0 : nNumberOfBitmaps=0;
2541 0 : nWrittenActions=0;
2542 0 : nWrittenBitmaps=0;
2543 0 : nActBitmapPercent=0;
2544 :
2545 0 : CountActionsAndBitmaps(&rMTF);
2546 :
2547 0 : WriteDocument(&rMTF);
2548 :
2549 0 : while( pChrSetList )
2550 : {
2551 0 : pCS=pChrSetList;
2552 0 : pChrSetList=pCS->pSucc;
2553 0 : delete pCS;
2554 : }
2555 :
2556 0 : while( pGDIStack )
2557 : {
2558 0 : pGS=pGDIStack;
2559 0 : pGDIStack=pGS->pSucc;
2560 0 : delete pGS;
2561 : }
2562 :
2563 0 : if ( xStatusIndicator.is() )
2564 0 : xStatusIndicator->end();
2565 :
2566 0 : return bStatus;
2567 : }
2568 :
2569 : //================== GraphicExport - the exported Function ================
2570 :
2571 : // this needs to be kept in sync with
2572 : // ImpFilterLibCacheEntry::GetImportFunction() from
2573 : // vcl/source/filter/graphicfilter.cxx
2574 : #if defined(DISABLE_DYNLOADING)
2575 : #define GraphicExport emeGraphicExport
2576 : #endif
2577 :
2578 : extern "C" SAL_DLLPUBLIC_EXPORT bool SAL_CALL
2579 0 : GraphicExport( SvStream & rStream, Graphic & rGraphic, FilterConfigItem* pFilterConfigItem )
2580 : {
2581 0 : METWriter aMETWriter;
2582 :
2583 : // #119735# just use GetGDIMetaFile, it will create a buffered version of contained bitmap now automatically
2584 0 : GDIMetaFile aMetafile(rGraphic.GetGDIMetaFile());
2585 :
2586 0 : if(usesClipActions(aMetafile))
2587 : {
2588 : // #i121267# It is necessary to prepare the metafile since the export does *not* support
2589 : // clip regions. This tooling method clips the geometry content of the metafile internally
2590 : // against it's own clip regions, so that the export is safe to ignore clip regions
2591 0 : clipMetafileContentAgainstOwnRegions(aMetafile);
2592 : }
2593 :
2594 0 : return aMETWriter.WriteMET( aMetafile, rStream, pFilterConfigItem );
2595 : }
2596 :
2597 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|