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