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