update dev300-m57
[ooovba.git] / lotuswordpro / source / filter / lwpoleobject.cxx
blob85eefc0682b967f9b6287f94e926e0935dfd3c21
1 /*************************************************************************
3 * The Contents of this file are made available subject to the terms of
4 * either of the following licenses
6 * - GNU Lesser General Public License Version 2.1
7 * - Sun Industry Standards Source License Version 1.1
9 * Sun Microsystems Inc., October, 2000
11 * GNU Lesser General Public License Version 2.1
12 * =============================================
13 * Copyright 2000 by Sun Microsystems, Inc.
14 * 901 San Antonio Road, Palo Alto, CA 94303, USA
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License version 2.1, as published by the Free Software Foundation.
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 * MA 02111-1307 USA
31 * Sun Industry Standards Source License Version 1.1
32 * =================================================
33 * The contents of this file are subject to the Sun Industry Standards
34 * Source License Version 1.1 (the "License"); You may not use this file
35 * except in compliance with the License. You may obtain a copy of the
36 * License at http://www.openoffice.org/license.html.
38 * Software provided under this License is provided on an "AS IS" basis,
39 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
40 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
41 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
42 * See the License for the specific provisions governing your rights and
43 * obligations concerning the Software.
45 * The Initial Developer of the Original Code is: IBM Corporation
47 * Copyright: 2008 by IBM Corporation
49 * All Rights Reserved.
51 * Contributor(s): _______________________________________
54 ************************************************************************/
55 /**
56 * @file
57 * For LWP filter architecture prototype - OLE object
59 /*************************************************************************
60 * Change History
61 Feb 2005 Created
62 ************************************************************************/
63 #include <stdio.h>
64 #include <tools/stream.hxx>
65 #include "lwpglobalmgr.hxx"
66 #include "lwpoleobject.hxx"
67 #include "lwpobjfactory.hxx"
68 #include "lwpidxmgr.hxx"
69 #include "lwp9reader.hxx"
70 #include "xfilter/xfoleobj.hxx"
71 #include "xfilter/xfparagraph.hxx"
72 #include "lwpframelayout.hxx"
73 #include "xfilter/xfstylemanager.hxx"
74 #include "bento.hxx"
76 /**
77 * @descr: construction function
78 * @param: objHdr - object header, read before entering this function
79 * @param: pStrm - file stream
80 * @return: None
81 * @date: 2/22/2005
83 LwpGraphicOleObject::LwpGraphicOleObject(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
84 : LwpContent(objHdr, pStrm)
86 /**
87 * @descr: Read GraphicOleObject part
88 * @param: None
89 * @return: None
90 * @date: 2/22/2005
92 void LwpGraphicOleObject::Read()
94 LwpContent::Read();
96 if (LwpFileHeader::m_nFileRevision >= 0x000b)
98 // I'm not sure about the read method
99 m_pNextObj.ReadIndexed(m_pObjStrm);
100 m_pPrevObj.ReadIndexed(m_pObjStrm);
102 m_pObjStrm->SkipExtra();
106 void LwpGraphicOleObject::GetGrafOrgSize(double & rWidth, double & rHeight)
108 rWidth = 0;
109 rHeight = 0;
112 void LwpGraphicOleObject::GetGrafScaledSize(double & fWidth, double & fHeight)
114 GetGrafOrgSize(fWidth, fHeight);
115 // scaled image size
116 double fSclGrafWidth = fWidth;//LwpTools::ConvertFromUnitsToMetric(pMyScale->GetScaleWidth());
117 double fSclGrafHeight = fHeight;//LwpTools::ConvertFromUnitsToMetric(pMyScale->GetScaleHeight());
120 LwpVirtualLayout* pLayout = GetLayout(NULL);
121 if (pLayout && pLayout->IsFrame())
123 LwpFrameLayout* pMyFrameLayout = static_cast<LwpFrameLayout*>(pLayout);
124 LwpLayoutScale* pMyScale = pMyFrameLayout->GetLayoutScale();
125 LwpLayoutGeometry* pFrameGeo = pMyFrameLayout->GetGeometry();
127 // original image size
128 //double fOrgGrafWidth = (double)m_Cache.Width/TWIPS_PER_CM;
129 //double fOrgGrafHeight = (double)m_Cache.Height/TWIPS_PER_CM;
131 // get margin values
132 double fLeftMargin = pMyFrameLayout->GetMarginsValue(MARGIN_LEFT);
133 double fRightMargin = pMyFrameLayout->GetMarginsValue(MARGIN_RIGHT);
134 double fTopMargin = pMyFrameLayout->GetMarginsValue(MARGIN_TOP);
135 double fBottomMargin = pMyFrameLayout->GetMarginsValue(MARGIN_BOTTOM);
137 if (pMyScale && pFrameGeo)
139 // frame size
140 double fFrameWidth = LwpTools::ConvertFromUnitsToMetric(pFrameGeo->GetWidth());
141 double fFrameHeight = LwpTools::ConvertFromUnitsToMetric(pFrameGeo->GetHeight());
143 // calculate the displayed size of the frame
144 double fDisFrameWidth = fFrameWidth - (fLeftMargin+fRightMargin);
145 double fDisFrameHeight = fFrameHeight - (fTopMargin+fBottomMargin);
147 // get scale mode
148 sal_uInt16 nScalemode = pMyScale->GetScaleMode();
149 if (nScalemode & LwpLayoutScale::CUSTOM)
151 fSclGrafWidth = LwpTools::ConvertFromUnitsToMetric(pMyScale->GetScaleWidth());
152 fSclGrafHeight = LwpTools::ConvertFromUnitsToMetric(pMyScale->GetScaleHeight());
154 else if (nScalemode & LwpLayoutScale::PERCENTAGE)
156 double fScalePercentage = (double)pMyScale->GetScalePercentage() / 1000;
157 fSclGrafWidth = fScalePercentage * fWidth;
158 fSclGrafHeight = fScalePercentage * fHeight;
160 else if (nScalemode & LwpLayoutScale::FIT_IN_FRAME)
162 if (pMyFrameLayout->IsFitGraphic())
164 fSclGrafWidth = fWidth;
165 fSclGrafHeight = fHeight;
167 else if (nScalemode & LwpLayoutScale::MAINTAIN_ASPECT_RATIO)
169 if (fWidth/fHeight >= fDisFrameWidth/fDisFrameHeight)
171 fSclGrafWidth = fDisFrameWidth;
172 fSclGrafHeight = (fDisFrameWidth/fWidth) * fHeight;
174 else
176 fSclGrafHeight = fDisFrameHeight;
177 fSclGrafWidth = (fDisFrameHeight/fHeight) * fWidth;
180 else
182 fSclGrafWidth = fDisFrameWidth;
183 fSclGrafHeight = fDisFrameHeight;
188 fWidth = fSclGrafWidth ;
189 fHeight = fSclGrafHeight ;
194 * @descr: construction function
195 * @param: objHdr - object header, read before entering this function
196 * @param: pStrm - file stream
197 * @return: None
198 * @date: 2/22/2005
200 LwpOleObject::LwpOleObject(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
201 : LwpGraphicOleObject(objHdr, pStrm),m_SizeRect(0,0,5,5)
205 * @descr: Read VO_OLEOBJECT record
206 * @param: None
207 * @return: None
208 * @date: 2/22/2005
210 void LwpOleObject::Read()
212 LwpGraphicOleObject::Read();
214 cPersistentFlags = m_pObjStrm->QuickReaduInt16();
216 sal_uInt16 nNonVersionedPersistentFlags = 0;
217 sal_uInt32 nFormat = 0;
218 sal_uInt16 nNumberOfPages = 0;
219 // qCMarker read
220 LwpObjectID ID;
222 if (LwpFileHeader::m_nFileRevision >= 0x0004)
224 nNonVersionedPersistentFlags = m_pObjStrm->QuickReaduInt16();
226 OUString sFormat = m_pObjStrm->QuickReadStringPtr();
228 if (LwpFileHeader::m_nFileRevision < 0x000B)
230 // null pointers have a VO_INVALID type
231 //if (VO_INVALID == m_pObjStrm->QuickReaduInt16())
232 // return;
234 ID.Read(m_pObjStrm);
235 //return m_pObjStrm->Locate(ID);
237 else
239 ID.ReadIndexed(m_pObjStrm);
240 //if (ID.IsNull())
241 // return;
243 //return m_pObjStrm->Locate(ID);
247 if (m_pObjStrm->CheckExtra())
249 nNumberOfPages = m_pObjStrm->QuickReaduInt16();
250 m_pObjStrm->SkipExtra();
255 * @descr: Construct ole-storage name by ObjectID
256 * @param: pObjName - input&output string of object name, spaces allocated outside and at least length should be MAX_STREAMORSTORAGENAME
257 * @return: None
258 * @date: 2/22/2005
260 void LwpOleObject::GetChildStorageName(char *pObjName)
262 /*LwpObjectFactory * pObjMgr = LwpObjectFactory::Instance();
263 LwpIndexManager * pIdxMgr = pObjMgr->GetIndexManager();
264 sal_uInt32 nLowID = pIdxMgr->GetObjTime(static_cast<sal_uInt16>(GetObjectID()->GetLow()));*/
266 char sName[MAX_STREAMORSTORAGENAME];
267 //LwpObjectID ID(nLowID, GetObjectID()->GetHigh());
268 sprintf( sName, "%s%lX,%lX", "Ole",
269 GetObjectID()->GetHigh(), GetObjectID()->GetLow());
271 strcpy( pObjName, sName);
272 return;
275 * @descr: Parse VO_OLEOBJECT and dump to XML stream only on WIN32 platform
276 * @param: pOutputStream - stream to dump OLE object
277 * @param: pFrameLayout - framlayout object used to dump OLE object
278 * @return: None
279 * @date: 2/22/2005
281 void LwpOleObject::Parse(IXFStream* pOutputStream)
283 #if 0
284 #ifdef WIN32
287 // Construct OLE object storage name
289 char sObjectName[MAX_STREAMORSTORAGENAME];
290 GetChildStorageName(sObjectName);
291 String aObjName= String::CreateFromAscii(sObjectName);
294 // Get OLE objects information
296 LwpGlobalMgr* pGlobal = LwpGlobalMgr::GetInstance();
297 LwpObjectFactory* pObjMgr = pGlobal->GetLwpObjFactory();
298 SvStorageRef objStor;
299 SvStorageInfoList * pInfoList;
300 pObjMgr->GetOleObjInfo(objStor, &pInfoList);
302 if(pInfoList == NULL)
304 assert(sal_False);
305 return;
309 // Get ole object buffer
311 BYTE * pBuf = NULL;
312 sal_uInt32 nSize = 0;
313 for (sal_uInt32 j=0; j<pInfoList->Count(); j++)
316 SvStorageInfo& rInfo = pInfoList->GetObject(j);
317 String aName = rInfo.GetName();
319 if(aName == aObjName)
321 SvStorageRef childStor;
322 childStor = objStor->OpenStorage(rInfo.GetName());
323 SvStorage * aEleStor;
324 aEleStor = objStor->OpenOLEStorage( rInfo.GetName() );
325 SvInPlaceObjectRef xInplaceObj( ((SvFactory*)SvInPlaceObject::ClassFactory())->CreateAndLoad( childStor ) );
326 SvOutPlaceObjectRef xOutplaceObj(xInplaceObj);
327 aEleStor->SetVersion( SOFFICE_FILEFORMAT_60 );
328 SvStream *pStream=xOutplaceObj->GetOLEObjectStream(aEleStor);
330 //Get Ole original size
331 m_SizeRect = xOutplaceObj->GetVisSize(xOutplaceObj->GetViewAspect());
333 nSize = pStream->Seek( STREAM_SEEK_TO_END );
334 pBuf = new BYTE[nSize];
335 if (pBuf == NULL)
337 assert(sal_False);
338 return;
340 pStream->Seek(0);
341 pStream->Read(pBuf, nSize);
343 delete pStream;
344 break;
349 // dump the buffer by XFilter
351 if(pBuf != NULL)
353 // set ole buffer
354 XFOleObject *pOleObj = new XFOleObject();
355 pOleObj->SetOleData(pBuf, nSize);
357 // set frame attributes
358 pOleObj->SetAnchorType(enumXFAnchorPara);
359 double fWidth = 0;
360 double fHeight = 0;
361 GetGrafScaledSize( fWidth, fHeight);
362 if(fWidth < 0.001 || fHeight < 0.001)
364 fWidth = 5.0;
365 fHeight = 5.0;
367 pOleObj->SetWidth(fWidth);
368 pOleObj->SetHeight(fHeight);
370 pOleObj->SetName(A2OUSTR("TestOle"));
371 pOleObj->SetX(5);
372 pOleObj->SetY(5);
373 pOleObj->SetWidth(5);
374 pOleObj->SetHeight(5);
377 // To XML
378 XFParagraph *pPara = new XFParagraph();
379 pPara->Add(pOleObj);
380 pPara->ToXml(pOutputStream);
382 delete pPara; // pOleObj will be deleted inside
384 #if 0
385 // dump to file
386 String aTempDir( SvtPathOptions().GetTempPath() );
387 sal_Int32 nLength = aTempDir.Len();
388 if ( aTempDir.GetChar(nLength-1 ) !=UChar32( '/' ) )
389 aTempDir += String::CreateFromAscii("/");
391 aTempDir += aObjName;
392 SvFileStream aStream(aTempDir, STREAM_WRITE);
393 aStream.Write(pBuf, nSize);
394 aStream.Close();
395 #endif
396 delete []pBuf;
398 // dump attributes to
401 return;
402 #endif
403 #endif
406 void LwpOleObject::XFConvert(XFContentContainer * pCont)
408 #if 0
409 //Add by 10/24/2005
410 //Get ole object stream with the object name;
412 // modified by
413 // if small file, use the compressed stream for BENTO
414 LwpSvStream* pStream = m_pStrm->GetCompressedStream() ? m_pStrm->GetCompressedStream(): m_pStrm;
415 // end modified by
417 OpenStormBento::LtcBenContainer* pBentoContainer;
418 ULONG ulRet = OpenStormBento::BenOpenContainer(pStream, &pBentoContainer);
420 char sObjectName[MAX_STREAMORSTORAGENAME];
421 GetChildStorageName(sObjectName);
422 std::string aObjName(sObjectName);
423 SotStorageStreamRef xOleObjStm = pBentoContainer->ConvertAswStorageToOLE2Stream(aObjName.c_str());
425 //Get stream size and data
426 if(!xOleObjStm.Is() || xOleObjStm->GetError())
427 return;
430 BYTE * pBuf = NULL;
431 sal_uInt32 nSize = 0;
433 SvStorageRef xOleObjStor = new SvStorage( *xOleObjStm );
434 //SvStorageRef xOleObjStor = pBentoContainer->CreateOLEStorageWithObjectName(aObjName.c_str());
435 if( !xOleObjStor.Is())
436 return ;
438 SvInPlaceObjectRef xInplaceObj( ((SvFactory*)SvInPlaceObject::ClassFactory())->CreateAndLoad( xOleObjStor ) );
441 //when the OLE object is converted into native object.
442 // SvOutPlaceObjectRef xOutplaceObj(xInplaceObj);
443 // xOutplaceObj->SetVersion( SOFFICE_FILEFORMAT_60 );
444 // SvStream *pOleStream=xOutplaceObj->GetOLEObjectStream(xOleObjStor);
445 //Get Ole original size
446 m_SizeRect = GetOLEObjectSize(xOleObjStor);
447 //End by
449 nSize = xOleObjStm->Seek( STREAM_SEEK_TO_END );
450 pBuf = new BYTE[nSize];
451 if (pBuf == NULL)
453 assert(sal_False);
454 return;
456 xOleObjStm->Seek(0);
457 xOleObjStm->Read(pBuf, nSize);
459 //delete pOleStream;
462 //End by
465 // dump the buffer by XFilter
467 if(pBuf != NULL)
469 // set ole buffer
470 XFOleObject *pOleObj = new XFOleObject();
471 pOleObj->SetOleData(pBuf, nSize);
473 // set frame attributes
474 pOleObj->SetAnchorType(enumXFAnchorFrame);
475 pOleObj->SetStyleName( m_strStyleName);
476 LwpFrameLayout* pMyFrameLayout = static_cast<LwpFrameLayout*>(GetLayout(NULL));
477 if(pMyFrameLayout)
479 pOleObj->SetX(pMyFrameLayout->GetMarginsValue(MARGIN_LEFT));
480 pOleObj->SetY(pMyFrameLayout->GetMarginsValue(MARGIN_TOP));
483 double fWidth = 0;
484 double fHeight = 0;
485 GetGrafScaledSize( fWidth, fHeight);
486 if(fWidth < 0.001 || fHeight < 0.001)
488 fWidth = 5.0;
489 fHeight = 5.0;
493 pOleObj->SetWidth(fWidth);
494 pOleObj->SetHeight(fHeight);
497 //delete pPara; // pOleObj will be deleted inside
498 pCont->Add(pOleObj);
500 #if 0
501 // dump to file
502 String aTempDir( SvtPathOptions().GetTempPath() );
503 sal_Int32 nLength = aTempDir.Len();
504 if ( aTempDir.GetChar(nLength-1 ) !=UChar32( '/' ) )
505 aTempDir += String::CreateFromAscii("/");
507 aTempDir += aObjName;
508 SvFileStream aStream(aTempDir, STREAM_WRITE);
509 aStream.Write(pBuf, nSize);
510 aStream.Close();
511 #endif
512 delete []pBuf;
514 // dump attributes to
516 #endif
517 return;
520 void LwpOleObject::GetGrafOrgSize(double & rWidth, double & rHeight)
522 rWidth = (double)m_SizeRect.GetWidth()/1000;//cm unit
523 rHeight = (double)m_SizeRect.GetHeight()/1000;//cm unit
526 void LwpOleObject::RegisterStyle()
528 #if 0
529 #ifdef WIN32
530 LwpVirtualLayout* pMyLayout = GetLayout(NULL);
531 if(pMyLayout->IsFrame())
533 XFFrameStyle* pXFFrameStyle = new XFFrameStyle();
534 pXFFrameStyle->SetXPosType(enumXFFrameXPosFromLeft, enumXFFrameXRelFrame);
535 pXFFrameStyle->SetYPosType(enumXFFrameYPosFromTop, enumXFFrameYRelPara);
536 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
537 m_strStyleName = pXFStyleManager->AddStyle(pXFFrameStyle)->GetStyleName();
539 #endif
540 #endif
544 #include <sot/exchange.hxx>
545 #include <sot/storinfo.hxx>
546 #include <svtools/wmf.hxx>
548 * @descr: For SODC_2667, To get the OLE object size by reading OLE object picture information.
550 Rectangle LwpOleObject::GetOLEObjectSize( SotStorage * pStor ) const
552 Rectangle aSize(0,0,0,0);
553 String aStreamName;
554 if( pStor->IsContained( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres000" ) ) ) )
555 aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres000" ) );
556 else if( pStor->IsContained( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ) ) )
557 aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) );
559 if( aStreamName.Len() == 0 )
560 return aSize;
563 for( USHORT i = 1; i < 10; i++ )
565 SotStorageStreamRef xStm = pStor->OpenSotStream( aStreamName,
566 STREAM_READ | STREAM_NOCREATE );
567 if( xStm->GetError() )
568 break;
570 xStm->SetBufferSize( 8192 );
571 LwpOlePres * pEle = new LwpOlePres( 0 );
572 if( pEle->Read( *xStm ) && !xStm->GetError() )
574 if( pEle->GetFormat() == FORMAT_GDIMETAFILE || pEle->GetFormat() == FORMAT_BITMAP )
576 aSize = Rectangle( Point(), pEle->GetSize());
577 delete pEle;
578 break;
581 delete pEle;
582 pEle = NULL;
583 aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres00" ) );
584 aStreamName += String( i );
587 return aSize;
590 * @descr: Read OLE object picture information
592 BOOL LwpOlePres::Read( SvStream & rStm )
594 #if 0
595 ULONG nBeginPos = rStm.Tell();
596 INT32 n;
597 rStm >> n;
598 if( n != -1 )
600 pBmp = new Bitmap;
601 rStm >> *pBmp;
602 if( rStm.GetError() == SVSTREAM_OK )
604 nFormat = FORMAT_BITMAP;
605 aSize = pBmp->GetPrefSize();
606 MapMode aMMSrc;
607 if( !aSize.Width() || !aSize.Height() )
609 // letzte Chance
610 aSize = pBmp->GetSizePixel();
611 aMMSrc = MAP_PIXEL;
613 else
614 aMMSrc = pBmp->GetPrefMapMode();
615 MapMode aMMDst( MAP_100TH_MM );
616 aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
617 return TRUE;
619 else
621 delete pBmp;
622 pBmp = NULL;
624 pMtf = new GDIMetaFile();
625 rStm.ResetError();
626 rStm >> *pMtf;
627 if( rStm.GetError() == SVSTREAM_OK )
629 nFormat = FORMAT_GDIMETAFILE;
630 aSize = pMtf->GetPrefSize();
631 MapMode aMMSrc = pMtf->GetPrefMapMode();
632 MapMode aMMDst( MAP_100TH_MM );
633 aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
634 return TRUE;
636 else
638 delete pMtf;
639 pMtf = NULL;
645 rStm.ResetError();
646 rStm.Seek( nBeginPos );
647 nFormat = ReadClipboardFormat( rStm );
648 // JobSetup, bzw. TargetDevice ueberlesen
649 // Information aufnehmen, um sie beim Schreiben nicht zu verlieren
650 nJobLen = 0;
651 rStm >> nJobLen;
652 if( nJobLen >= 4 )
654 nJobLen -= 4;
655 if( nJobLen )
657 pJob = new BYTE[ nJobLen ];
658 rStm.Read( pJob, nJobLen );
661 else
663 rStm.SetError( SVSTREAM_GENERALERROR );
664 return FALSE;
666 UINT32 nAsp;
667 rStm >> nAsp;
668 USHORT nSvAsp = USHORT( nAsp );
669 SetAspect( nSvAsp );
670 rStm.SeekRel( 4 ); //L-Index ueberlesen
671 rStm >> nAdvFlags;
672 rStm.SeekRel( 4 ); //Compression
673 UINT32 nWidth = 0;
674 UINT32 nHeight = 0;
675 UINT32 nSize = 0;
676 rStm >> nWidth >> nHeight >> nSize;
677 aSize.Width() = nWidth;
678 aSize.Height() = nHeight;
680 if( nFormat == FORMAT_GDIMETAFILE )
682 pMtf = new GDIMetaFile();
683 ReadWindowMetafile( rStm, *pMtf );
685 else if( nFormat == FORMAT_BITMAP )
687 pBmp = new Bitmap();
688 rStm >> *pBmp;
690 else
692 void * p = new BYTE[ nSize ];
693 rStm.Read( p, nSize );
694 delete p;
695 return FALSE;
697 #endif
698 return TRUE;
702 * @descr: Write OLE object picture information.
704 void LwpOlePres::Write( SvStream & rStm )
706 WriteClipboardFormat( rStm, FORMAT_GDIMETAFILE );
707 rStm << (INT32)(nJobLen +4); // immer leeres TargetDevice
708 if( nJobLen )
709 rStm.Write( pJob, nJobLen );
710 rStm << (UINT32)nAspect;
711 rStm << (INT32)-1; //L-Index immer -1
712 rStm << (INT32)nAdvFlags;
713 rStm << (INT32)0; //Compression
714 rStm << (INT32)aSize.Width();
715 rStm << (INT32)aSize.Height();
716 ULONG nPos = rStm.Tell();
717 rStm << (INT32)0;
719 if( GetFormat() == FORMAT_GDIMETAFILE && pMtf )
721 // Immer auf 1/100 mm, bis Mtf-Loesung gefunden
722 // Annahme (keine Skalierung, keine Org-Verschiebung)
723 DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleX() == Fraction( 1, 1 ),
724 "X-Skalierung im Mtf" );
725 DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleY() == Fraction( 1, 1 ),
726 "Y-Skalierung im Mtf" );
727 DBG_ASSERT( pMtf->GetPrefMapMode().GetOrigin() == Point(),
728 "Origin-Verschiebung im Mtf" );
729 MapUnit nMU = pMtf->GetPrefMapMode().GetMapUnit();
730 if( MAP_100TH_MM != nMU )
732 Size aPrefS( pMtf->GetPrefSize() );
733 Size aS( aPrefS );
734 aS = OutputDevice::LogicToLogic( aS, nMU, MAP_100TH_MM );
736 pMtf->Scale( Fraction( aS.Width(), aPrefS.Width() ),
737 Fraction( aS.Height(), aPrefS.Height() ) );
738 pMtf->SetPrefMapMode( MAP_100TH_MM );
739 pMtf->SetPrefSize( aS );
741 WriteWindowMetafileBits( rStm, *pMtf );
743 else
745 DBG_ERROR( "unknown format" );
747 ULONG nEndPos = rStm.Tell();
748 rStm.Seek( nPos );
749 rStm << (UINT32)(nEndPos - nPos - 4);
750 rStm.Seek( nEndPos );
752 //End by