merge the formfield patch from ooo-build
[ooovba.git] / svx / source / msfilter / msdffimp.cxx
blob4b7209eff95dbad8da219c2c328f8ad28a33ed92
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: msdffimp.cxx,v $
10 * $Revision: 1.157 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
34 #include <com/sun/star/embed/Aspects.hpp>
36 #include <math.h>
37 #include <limits.h>
38 #include <vector>
39 #include <osl/endian.h>
40 #include <tools/solar.h> // UINTXX
41 #include <rtl/math.hxx>
43 #include <sot/clsids.hxx>
44 #include <toolkit/helper/vclunohelper.hxx>
45 #include <unotools/streamwrap.hxx>
46 #include <comphelper/processfactory.hxx>
47 #include <sot/exchange.hxx>
48 #include <sot/storinfo.hxx>
49 #include <vcl/cvtgrf.hxx>
51 #include "viscache.hxx"
53 // SvxItem-Mapping. Wird benoetigt um die SvxItem-Header erfolgreich zu includen
54 #include <svx/eeitem.hxx>
55 #ifndef _EDITDATA_HXX
56 #include <svx/editdata.hxx>
57 #endif
59 #include <svtools/urihelper.hxx>
61 // textitem.hxx editdata.hxx
78 // paraitem.hxx editdata.hxx
81 #include <tools/stream.hxx>
82 #include <tools/debug.hxx>
83 #ifndef _TOOLS_ZCODEC_HXX
84 #include <tools/zcodec.hxx>
85 #endif
86 #ifndef _UNOTOOLS_UCBSTREAMHELPER_HXX
87 #include <unotools/ucbstreamhelper.hxx>
88 #endif
89 #include <unotools/localfilehelper.hxx>
90 #include <svx/escherex.hxx>
91 #include <basegfx/range/b2drange.hxx>
92 #include <com/sun/star/container/XIdentifierContainer.hpp>
93 #include <com/sun/star/drawing/XGluePointsSupplier.hpp>
94 #include <com/sun/star/drawing/Position3D.hpp>
95 #include <com/sun/star/drawing/Direction3D.hpp>
96 #include <com/sun/star/drawing/GluePoint2.hpp>
97 #include <com/sun/star/drawing/XShapes.hpp>
98 #include <svx/charscaleitem.hxx>
99 #include <svx/kernitem.hxx>
100 #include <svtools/filter.hxx>
101 #include <tools/string.hxx>
102 #ifndef _TOOLS_URLOBJ_HXX
103 #include <tools/urlobj.hxx>
104 #endif
105 #include <vcl/virdev.hxx>
106 #include <vcl/bmpacc.hxx>
107 #ifndef _SVSTOR_HXX //autogen
108 #include <sot/storage.hxx>
109 #endif
110 #include <sfx2/docfac.hxx>
111 #include <sfx2/docfilt.hxx>
112 #include <sfx2/docfile.hxx>
113 #include <sfx2/fcontnr.hxx>
114 #include <sfx2/module.hxx>
115 //#ifndef _SFX_INTERNO_HXX
116 //#include <sfx2/interno.hxx>
117 //#endif
119 #ifndef _SDGCPITM_HXX
121 //#endif
122 #include <svx/sdgcpitm.hxx>
123 #endif
124 #include <svx/sdgmoitm.hxx>
125 #include <svx/tstpitem.hxx>
126 #include <svx/fmmodel.hxx>
127 #include <svx/svdmodel.hxx>
128 #include <svx/svdobj.hxx>
129 #include <svx/svdpage.hxx>
130 #include <svx/svdogrp.hxx>
131 #include <svx/svdograf.hxx>
132 #include <svx/svdotext.hxx>
133 #include <svx/svdorect.hxx>
134 #ifndef _SVDOCAPT_HXX
135 #include <svx/svdocapt.hxx>
136 #endif
137 #include <svx/svdoedge.hxx>
138 #include <svx/svdocirc.hxx>
139 #include <svx/svdoutl.hxx>
140 #include <svx/svdoole2.hxx>
141 #include <svx/svdopath.hxx>
142 #include <svx/frmdir.hxx>
143 #include <svx/frmdiritem.hxx>
144 #include <svx/svdtrans.hxx>
145 #include <svx/sxenditm.hxx>
146 #include <svx/sdgluitm.hxx>
147 #include <svx/fhgtitem.hxx>
148 #include <svx/wghtitem.hxx>
149 #include <svx/postitem.hxx>
150 #include <svx/udlnitem.hxx>
151 #include <svx/crsditem.hxx>
152 #include <svx/shdditem.hxx>
153 #include <fontitem.hxx>
154 #include <svx/colritem.hxx>
155 #include <svx/sxekitm.hxx>
156 #include <bulitem.hxx>
157 #include <svx/polysc3d.hxx>
158 #include <svx/extrud3d.hxx>
159 #include "svditer.hxx"
160 #include <svx/xpoly.hxx>
161 #include "xattr.hxx"
163 #ifndef _IMPGRF_HXX //autogen
164 #include "impgrf.hxx"
165 #endif
166 #include <svx/msdffimp.hxx> // extern sichtbare Header-Datei
167 #include <svx/outliner.hxx>
168 #include <svx/outlobj.hxx>
169 #include <svx/editobj.hxx>
170 #include <svx/editeng.hxx>
171 #include "gallery.hxx"
172 #include <com/sun/star/drawing/ShadeMode.hpp>
173 #include <svtools/itempool.hxx>
174 #include <vcl/svapp.hxx>
175 #include <svx/svx3ditems.hxx>
176 #include <svx/svdoashp.hxx>
177 #include <svx/sdasaitm.hxx>
178 #ifndef _UCBHELPER_CONTENT_HXX_
179 #include <ucbhelper/content.hxx>
180 #endif
181 #ifndef _UCBHELPER_CONTENTBROKER_HXX_
182 #include <ucbhelper/contentbroker.hxx>
183 #endif
184 #include <vos/xception.hxx>
185 #ifndef _VOS_NO_NAMESPACE
186 using namespace vos;
187 #endif
188 #include "../customshapes/EnhancedCustomShapeTypeNames.hxx"
189 #include "../customshapes/EnhancedCustomShapeGeometry.hxx"
190 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
191 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
192 #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
193 #include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
194 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
195 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
196 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
197 #include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
198 #ifndef __com_sun_star_beans_PropertyValues_hpp__
199 #include <com/sun/star/beans/PropertyValues.hpp>
200 #endif
201 #include <com/sun/star/drawing/ProjectionMode.hpp>
202 #include "../customshapes/EnhancedCustomShape2d.hxx"
204 using namespace ::com::sun::star ;
205 using namespace ::com::sun::star::drawing;
206 using namespace uno ;
207 using namespace beans ;
208 using namespace drawing ;
209 using namespace container ;
211 #define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()
213 // static counter for OLE-Objects
214 static sal_uInt32 nMSOleObjCntr = 0;
215 #define MSO_OLE_Obj "MSO_OLE_Obj"
218 /*************************************************************************/
219 BOOL Impl_OlePres::Read( SvStream & rStm )
221 ULONG nBeginPos = rStm.Tell();
222 INT32 n;
223 rStm >> n;
224 if( n != -1 )
226 pBmp = new Bitmap;
227 rStm >> *pBmp;
228 if( rStm.GetError() == SVSTREAM_OK )
230 nFormat = FORMAT_BITMAP;
231 aSize = pBmp->GetPrefSize();
232 MapMode aMMSrc;
233 if( !aSize.Width() || !aSize.Height() )
235 // letzte Chance
236 aSize = pBmp->GetSizePixel();
237 aMMSrc = MAP_PIXEL;
239 else
240 aMMSrc = pBmp->GetPrefMapMode();
241 MapMode aMMDst( MAP_100TH_MM );
242 aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
243 return TRUE;
245 else
247 delete pBmp;
248 pBmp = NULL;
250 pMtf = new GDIMetaFile();
251 rStm.ResetError();
252 rStm >> *pMtf;
253 if( rStm.GetError() == SVSTREAM_OK )
255 nFormat = FORMAT_GDIMETAFILE;
256 aSize = pMtf->GetPrefSize();
257 MapMode aMMSrc = pMtf->GetPrefMapMode();
258 MapMode aMMDst( MAP_100TH_MM );
259 aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
260 return TRUE;
262 else
264 delete pMtf;
265 pMtf = NULL;
271 rStm.ResetError();
272 rStm.Seek( nBeginPos );
273 nFormat = ReadClipboardFormat( rStm );
274 // JobSetup, bzw. TargetDevice ueberlesen
275 // Information aufnehmen, um sie beim Schreiben nicht zu verlieren
276 nJobLen = 0;
277 rStm >> nJobLen;
278 if( nJobLen >= 4 )
280 nJobLen -= 4;
281 if( nJobLen )
283 pJob = new BYTE[ nJobLen ];
284 rStm.Read( pJob, nJobLen );
287 else
289 rStm.SetError( SVSTREAM_GENERALERROR );
290 return FALSE;
292 UINT32 nAsp;
293 rStm >> nAsp;
294 USHORT nSvAsp = USHORT( nAsp );
295 SetAspect( nSvAsp );
296 rStm.SeekRel( 4 ); //L-Index ueberlesen
297 rStm >> nAdvFlags;
298 rStm.SeekRel( 4 ); //Compression
299 UINT32 nWidth = 0;
300 UINT32 nHeight = 0;
301 UINT32 nSize = 0;
302 rStm >> nWidth >> nHeight >> nSize;
303 aSize.Width() = nWidth;
304 aSize.Height() = nHeight;
306 if( nFormat == FORMAT_GDIMETAFILE )
308 pMtf = new GDIMetaFile();
309 ReadWindowMetafile( rStm, *pMtf, NULL );
311 else if( nFormat == FORMAT_BITMAP )
313 pBmp = new Bitmap();
314 rStm >> *pBmp;
316 else
318 BYTE * p = new BYTE[ nSize ];
319 rStm.Read( p, nSize );
320 delete p;
321 return FALSE;
323 return TRUE;
326 /************************************************************************/
327 void Impl_OlePres::Write( SvStream & rStm )
329 WriteClipboardFormat( rStm, FORMAT_GDIMETAFILE );
330 rStm << (INT32)(nJobLen +4); // immer leeres TargetDevice
331 if( nJobLen )
332 rStm.Write( pJob, nJobLen );
333 rStm << (UINT32)nAspect;
334 rStm << (INT32)-1; //L-Index immer -1
335 rStm << (INT32)nAdvFlags;
336 rStm << (INT32)0; //Compression
337 rStm << (INT32)aSize.Width();
338 rStm << (INT32)aSize.Height();
339 ULONG nPos = rStm.Tell();
340 rStm << (INT32)0;
342 if( GetFormat() == FORMAT_GDIMETAFILE && pMtf )
344 // Immer auf 1/100 mm, bis Mtf-Loesung gefunden
345 // Annahme (keine Skalierung, keine Org-Verschiebung)
346 DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleX() == Fraction( 1, 1 ),
347 "X-Skalierung im Mtf" );
348 DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleY() == Fraction( 1, 1 ),
349 "Y-Skalierung im Mtf" );
350 DBG_ASSERT( pMtf->GetPrefMapMode().GetOrigin() == Point(),
351 "Origin-Verschiebung im Mtf" );
352 MapUnit nMU = pMtf->GetPrefMapMode().GetMapUnit();
353 if( MAP_100TH_MM != nMU )
355 Size aPrefS( pMtf->GetPrefSize() );
356 Size aS( aPrefS );
357 aS = OutputDevice::LogicToLogic( aS, nMU, MAP_100TH_MM );
359 pMtf->Scale( Fraction( aS.Width(), aPrefS.Width() ),
360 Fraction( aS.Height(), aPrefS.Height() ) );
361 pMtf->SetPrefMapMode( MAP_100TH_MM );
362 pMtf->SetPrefSize( aS );
364 WriteWindowMetafileBits( rStm, *pMtf );
366 else
368 DBG_ERROR( "unknown format" );
370 ULONG nEndPos = rStm.Tell();
371 rStm.Seek( nPos );
372 rStm << (UINT32)(nEndPos - nPos - 4);
373 rStm.Seek( nEndPos );
376 Impl_OlePres * CreateCache_Impl( SotStorage * pStor )
378 SotStorageStreamRef xOleObjStm =pStor->OpenSotStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Ole-Object" ) ),
379 STREAM_READ | STREAM_NOCREATE );
380 if( xOleObjStm->GetError() )
381 return NULL;
382 SotStorageRef xOleObjStor = new SotStorage( *xOleObjStm );
383 if( xOleObjStor->GetError() )
384 return NULL;
386 String aStreamName;
387 if( xOleObjStor->IsContained( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres000" ) ) ) )
388 aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres000" ) );
389 else if( xOleObjStor->IsContained( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ) ) )
390 aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) );
392 if( aStreamName.Len() == 0 )
393 return NULL;
396 for( USHORT i = 1; i < 10; i++ )
398 SotStorageStreamRef xStm = xOleObjStor->OpenSotStream( aStreamName,
399 STREAM_READ | STREAM_NOCREATE );
400 if( xStm->GetError() )
401 break;
403 xStm->SetBufferSize( 8192 );
404 Impl_OlePres * pEle = new Impl_OlePres( 0 );
405 if( pEle->Read( *xStm ) && !xStm->GetError() )
407 if( pEle->GetFormat() == FORMAT_GDIMETAFILE || pEle->GetFormat() == FORMAT_BITMAP )
408 return pEle;
410 delete pEle;
411 aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres00" ) );
412 aStreamName += String( i );
414 return NULL;
419 //---------------------------------------------------------------------------
420 // Hilfs Klassen aus MSDFFDEF.HXX
421 //---------------------------------------------------------------------------
423 SvStream& operator>>( SvStream& rIn, DffRecordHeader& rRec )
425 rRec.nFilePos = rIn.Tell();
426 UINT16 nTmp(0);
427 rIn >> nTmp;
428 rRec.nImpVerInst = nTmp;
429 rRec.nRecVer = sal::static_int_cast< BYTE >(nTmp & 0x000F);
430 rRec.nRecInstance = nTmp >> 4;
431 rIn >> rRec.nRecType;
432 rIn >> rRec.nRecLen;
433 return rIn;
436 // Masse fuer dashed lines
437 #define LLEN_MIDDLE (450)
438 #define LLEN_SPACE_MIDDLE (360)
439 #define LLEN_LONG (LLEN_MIDDLE * 2)
440 #define LLEN_SPACE_LONG (LLEN_SPACE_MIDDLE + 20)
441 #define LLEN_POINT (LLEN_MIDDLE / 4)
442 #define LLEN_SPACE_POINT (LLEN_SPACE_MIDDLE / 4)
444 SvStream& operator>>( SvStream& rIn, DffPropSet& rRec )
446 rRec.InitializePropSet();
448 DffRecordHeader aHd;
449 rIn >> aHd;
450 UINT32 nPropCount = aHd.nRecInstance;
452 // FilePos der ComplexData merken
453 UINT32 nComplexDataFilePos = rIn.Tell() + ( nPropCount * 6 );
455 for( UINT32 nPropNum = 0; nPropNum < nPropCount; nPropNum++ )
457 sal_uInt16 nTmp;
458 sal_uInt32 nRecType, nContent, nContentEx = 0xffff0000;
459 rIn >> nTmp
460 >> nContent;
462 nRecType = nTmp & 0x3fff;
464 if ( nRecType > 0x3ff )
465 break;
466 if ( ( nRecType & 0x3f ) == 0x3f )
467 { // clear flags that have to be cleared
468 rRec.mpContents[ nRecType ] &= ( ( nContent >> 16 ) ^ 0xffffffff );
469 // set flags that have to be set
470 rRec.mpContents[ nRecType ] |= nContent;
471 nContentEx |= ( nContent >> 16 );
472 rRec.Replace( nRecType, (void*)nContentEx );
474 else
476 DffPropFlags aPropFlag = { 1, 0, 0, 0 };
477 if ( nTmp & 0x4000 )
478 aPropFlag.bBlip = sal_True;
479 if ( nTmp & 0x8000 )
480 aPropFlag.bComplex = sal_True;
481 if ( aPropFlag.bComplex && nContent && ( nComplexDataFilePos < aHd.GetRecEndFilePos() ) )
483 // normally nContent is the complete size of the complex property,
484 // but this is not always true for IMsoArrays ( what the hell is a IMsoArray ? )
486 // I love special threatments :-(
487 if ( ( nRecType == DFF_Prop_pVertices ) || ( nRecType == DFF_Prop_pSegmentInfo )
488 || ( nRecType == DFF_Prop_fillShadeColors ) || ( nRecType == DFF_Prop_lineDashStyle )
489 || ( nRecType == DFF_Prop_pWrapPolygonVertices ) || ( nRecType == DFF_Prop_connectorPoints )
490 || ( nRecType == DFF_Prop_Handles ) || ( nRecType == DFF_Prop_pFormulas )
491 || ( nRecType == DFF_Prop_textRectangles ) )
493 // now check if the current content size is possible, or 6 bytes too small
494 sal_uInt32 nOldPos = rIn.Tell();
495 sal_Int16 nNumElem, nNumElemReserved, nSize;
497 rIn.Seek( nComplexDataFilePos );
498 rIn >> nNumElem >> nNumElemReserved >> nSize;
499 if ( nNumElemReserved >= nNumElem )
501 // the size of these array elements is nowhere defined,
502 // what if the size is negative ?
503 // ok, we will make it positive and shift it.
504 // for -16 this works
505 if ( nSize < 0 )
506 nSize = ( -nSize ) >> 2;
507 sal_uInt32 nDataSize = (sal_uInt32)( nSize * nNumElem );
509 // sometimes the content size is 6 bytes too small (array header information is missing )
510 if ( nDataSize == nContent )
511 nContent += 6;
513 // check if array fits into the PropertyContainer
514 if ( ( nComplexDataFilePos + nContent ) > aHd.GetRecEndFilePos() )
515 nContent = 0;
517 else
518 nContent = 0;
519 rIn.Seek( nOldPos );
521 if ( nContent )
523 nContentEx = nComplexDataFilePos; // insert the filepos of this property;
524 nComplexDataFilePos += nContent; // store filepos, that is used for the next complex property
526 else // a complex property needs content
527 aPropFlag.bSet = sal_False; // otherwise something is wrong
529 rRec.mpContents[ nRecType ] = nContent;
530 rRec.mpFlags[ nRecType ] = aPropFlag;
531 rRec.Insert( nRecType, (void*)nContentEx );
534 aHd.SeekToEndOfRecord( rIn );
535 return rIn;
538 void DffPropSet::InitializePropSet() const
541 cmc:
542 " Boolean properties are grouped in bitfields by property set; note that
543 the Boolean properties in each property set are contiguous. They are saved
544 under the property ID of the last Boolean property in the set, and are
545 placed in the value field in reverse order starting with the last property
546 in the low bit. "
548 e.g.
550 fEditedWrap
551 fBehindDocument
552 fOnDblClickNotify
553 fIsButton
554 fOneD
555 fHidden
556 fPrint
558 are all part of a group and all are by default false except for fPrint,
559 which equates to a default bit sequence for the group of 0000001 -> 0x1
561 If at a later stage word sets fBehindDocument away from the default it
562 will be done by having a property named fPrint whose bitsequence will have
563 the fBehindDocument bit set. e.g. a DFF_Prop_fPrint with value 0x200020
564 has set bit 6 on so as to enable fBehindDocument (as well as disabling
565 everything else)
568 memset( ( (DffPropSet*) this )->mpFlags, 0, 0x400 * sizeof(DffPropFlags) );
569 ( (DffPropSet*) this )->Clear();
571 DffPropFlags nFlags = { 1, 0, 0, 1 };
573 ( (DffPropSet*) this )->mpContents[ DFF_Prop_LockAgainstGrouping ] = 0x0000; //0x01ff0000;
574 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_LockAgainstGrouping ] = nFlags;
575 ( (DffPropSet*) this )->Insert( DFF_Prop_LockAgainstGrouping, (void*)0xffff0000 );
577 ( (DffPropSet*) this )->mpContents[ DFF_Prop_FitTextToShape ] = 0x0010; //0x001f0010;
578 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_FitTextToShape ] = nFlags;
579 ( (DffPropSet*) this )->Insert( DFF_Prop_FitTextToShape, (void*)0xffff0000 );
581 ( (DffPropSet*) this )->mpContents[ DFF_Prop_gtextFStrikethrough ] = 0x0000; //0xffff0000;
582 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_gtextFStrikethrough ] = nFlags;
583 ( (DffPropSet*) this )->Insert( DFF_Prop_gtextFStrikethrough, (void*)0xffff0000 );
585 ( (DffPropSet*) this )->mpContents[ DFF_Prop_pictureActive ] = 0x0000; //0x000f0000;
586 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_pictureActive ] = nFlags;
587 ( (DffPropSet*) this )->Insert( DFF_Prop_pictureActive, (void*)0xffff0000 );
589 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fFillOK ] = 0x0039; //0x003f0039;
590 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fFillOK ] = nFlags;
591 ( (DffPropSet*) this )->Insert( DFF_Prop_fFillOK, (void*)0xffff0000 );
593 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fNoFillHitTest ] = 0x001c; //0x001f001c;
594 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fNoFillHitTest ] = nFlags;
595 ( (DffPropSet*) this )->Insert( DFF_Prop_fNoFillHitTest, (void*)0xffff0000 );
597 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fNoLineDrawDash ] = 0x001e; //0x001f000e;
598 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fNoLineDrawDash ] = nFlags;
599 ( (DffPropSet*) this )->Insert( DFF_Prop_fNoLineDrawDash, (void*)0xffff0000 );
601 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fshadowObscured ] = 0x0000; //0x00030000;
602 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fshadowObscured ] = nFlags;
603 ( (DffPropSet*) this )->Insert( DFF_Prop_fshadowObscured, (void*)0xffff0000 );
605 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fPerspective ] = 0x0000; //0x00010000;
606 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fPerspective ] = nFlags;
607 ( (DffPropSet*) this )->Insert( DFF_Prop_fPerspective, (void*)0xffff0000 );
609 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fc3DLightFace ] = 0x0001; //0x000f0001;
610 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fc3DLightFace ] = nFlags;
611 ( (DffPropSet*) this )->Insert( DFF_Prop_fc3DLightFace, (void*)0xffff0000 );
613 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fc3DFillHarsh ] = 0x0016; //0x001f0016;
614 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fc3DFillHarsh ] = nFlags;
615 ( (DffPropSet*) this )->Insert( DFF_Prop_fc3DFillHarsh, (void*)0xffff0000 );
617 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fBackground ] = 0x0000; //0x001f0000;
618 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fBackground ] = nFlags;
619 ( (DffPropSet*) this )->Insert( DFF_Prop_fBackground, (void*)0xffff0000 );
621 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fCalloutLengthSpecified ] = 0x0010; //0x00ef0010;
622 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fCalloutLengthSpecified ] = nFlags;
623 ( (DffPropSet*) this )->Insert( DFF_Prop_fCalloutLengthSpecified, (void*)0xffff0000 );
625 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fPrint ] = 0x0001; //0x00ef0001;
626 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fPrint ] = nFlags;
627 ( (DffPropSet*) this )->Insert( DFF_Prop_fPrint, (void*)0xffff0000 );
629 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fillColor ] = 0xffffff;
630 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fillColor ] = nFlags;
631 ( (DffPropSet*) this )->Insert( DFF_Prop_fillColor, (void*)0xffff0000 );
634 void DffPropSet::Merge( DffPropSet& rMaster ) const
636 for ( void* pDummy = rMaster.First(); pDummy; pDummy = rMaster.Next() )
638 UINT32 nRecType = rMaster.GetCurKey();
639 if ( ( nRecType & 0x3f ) == 0x3f ) // this is something called FLAGS
641 UINT32 nCurrentFlags = mpContents[ nRecType ];
642 UINT32 nMergeFlags = rMaster.mpContents[ nRecType ];
643 nMergeFlags &= ( nMergeFlags >> 16 ) | 0xffff0000; // clearing low word
644 nMergeFlags &= ( ( nCurrentFlags & 0xffff0000 ) // remove allready hard set
645 | ( nCurrentFlags >> 16 ) ) ^ 0xffffffff; // attributes from mergeflags
646 nCurrentFlags &= ( ( nMergeFlags & 0xffff0000 ) // apply zero master bits
647 | ( nMergeFlags >> 16 ) ) ^ 0xffffffff;
648 nCurrentFlags |= (UINT16)nMergeFlags; // apply filled master bits
649 ( (DffPropSet*) this )->mpContents[ nRecType ] = nCurrentFlags;
652 sal_uInt32 nNewContentEx = (sal_uInt32)(sal_uIntPtr)rMaster.GetCurObject();
653 if ( ((DffPropSet*)this)->Seek( nRecType ) )
654 nNewContentEx |= (sal_uInt32)(sal_uIntPtr)GetCurObject();
655 ( (DffPropSet*) this )->Replace( nRecType, (void*)nNewContentEx );
657 else
659 if ( !IsProperty( nRecType ) || !IsHardAttribute( nRecType ) )
661 ( (DffPropSet*) this )->mpContents[ nRecType ] = rMaster.mpContents[ nRecType ];
662 DffPropFlags nFlags( rMaster.mpFlags[ nRecType ] );
663 nFlags.bSoftAttr = TRUE;
664 ( (DffPropSet*) this )->mpFlags[ nRecType ] = nFlags;
665 ( (DffPropSet*) this )->Insert( nRecType, pDummy );
671 BOOL DffPropSet::IsHardAttribute( UINT32 nId ) const
673 BOOL bRetValue = TRUE;
674 nId &= 0x3ff;
675 if ( ( nId & 0x3f ) >= 48 ) // is this a flag id
677 if ( ((DffPropSet*)this)->Seek( nId | 0x3f ) )
679 sal_uInt32 nContentEx = (sal_uInt32)(sal_uIntPtr)GetCurObject();
680 bRetValue = ( nContentEx & ( 1 << ( 0xf - ( nId & 0xf ) ) ) ) != 0;
683 else
684 bRetValue = ( mpFlags[ nId ].bSoftAttr == 0 );
685 return bRetValue;
688 UINT32 DffPropSet::GetPropertyValue( UINT32 nId, UINT32 nDefault ) const
690 nId &= 0x3ff;
691 return ( mpFlags[ nId ].bSet ) ? mpContents[ nId ] : nDefault;
694 bool DffPropSet::GetPropertyBool( UINT32 nId, bool bDefault ) const
696 UINT32 nBaseId = nId | 31; // base ID to get the UINT32 property value
697 UINT32 nMask = 1 << (nBaseId - nId); // bit mask of the boolean property
699 UINT32 nPropValue = GetPropertyValue( nBaseId, bDefault ? nMask : 0 );
700 return (nPropValue & nMask) != 0;
703 ::rtl::OUString DffPropSet::GetPropertyString( UINT32 nId, SvStream& rStrm ) const
705 sal_Size nOldPos = rStrm.Tell();
706 ::rtl::OUStringBuffer aBuffer;
707 sal_uInt32 nBufferSize = GetPropertyValue( nId );
708 if( (nBufferSize > 0) && SeekToContent( nId, rStrm ) )
710 sal_Int32 nStrLen = static_cast< sal_Int32 >( nBufferSize / 2 );
711 aBuffer.ensureCapacity( nStrLen );
712 for( sal_Int32 nCharIdx = 0; nCharIdx < nStrLen; ++nCharIdx )
714 sal_uInt16 nChar = 0;
715 rStrm >> nChar;
716 if( nChar > 0 )
717 aBuffer.append( static_cast< sal_Unicode >( nChar ) );
718 else
719 break;
722 rStrm.Seek( nOldPos );
723 return aBuffer.makeStringAndClear();
726 void DffPropSet::SetPropertyValue( UINT32 nId, UINT32 nValue ) const
728 if ( !mpFlags[ nId ].bSet )
730 ( (DffPropSet*) this )->Insert( nId, (void*)nValue );
731 ( (DffPropSet*) this )->mpFlags[ nId ].bSet = TRUE;
733 ( (DffPropSet*) this )->mpContents[ nId ] = nValue;
736 BOOL DffPropSet::SeekToContent( UINT32 nRecType, SvStream& rStrm ) const
738 nRecType &= 0x3ff;
739 if ( mpFlags[ nRecType ].bSet )
741 if ( mpFlags[ nRecType ].bComplex )
743 if ( ((DffPropSet*)this)->Seek( nRecType ) )
745 sal_uInt32 nOffset = (sal_uInt32)(sal_uIntPtr)GetCurObject();
746 if ( nOffset && ( ( nOffset & 0xffff0000 ) != 0xffff0000 ) )
748 rStrm.Seek( nOffset );
749 return TRUE;
754 return FALSE;
757 DffPropertyReader::DffPropertyReader( const SvxMSDffManager& rMan ) :
758 rManager( rMan ),
759 pDefaultPropSet( NULL )
761 InitializePropSet();
764 void DffPropertyReader::SetDefaultPropSet( SvStream& rStCtrl, UINT32 nOffsDgg ) const
766 delete pDefaultPropSet;
767 UINT32 nMerk = rStCtrl.Tell();
768 rStCtrl.Seek( nOffsDgg );
769 DffRecordHeader aRecHd;
770 rStCtrl >> aRecHd;
771 if ( aRecHd.nRecType == DFF_msofbtDggContainer )
773 if ( rManager.SeekToRec( rStCtrl, DFF_msofbtOPT, aRecHd.GetRecEndFilePos() ) )
775 ( (DffPropertyReader*) this )->pDefaultPropSet = new DffPropSet;
776 rStCtrl >> *pDefaultPropSet;
779 rStCtrl.Seek( nMerk );
782 #ifdef DBG_CUSTOMSHAPE
783 void DffPropertyReader::ReadPropSet( SvStream& rIn, void* pClientData, UINT32 nShapeId ) const
784 #else
785 void DffPropertyReader::ReadPropSet( SvStream& rIn, void* pClientData ) const
786 #endif
788 ULONG nFilePos = rIn.Tell();
789 rIn >> (DffPropertyReader&)*this;
791 if ( IsProperty( DFF_Prop_hspMaster ) )
793 if ( rManager.SeekToShape( rIn, pClientData, GetPropertyValue( DFF_Prop_hspMaster ) ) )
795 DffRecordHeader aRecHd;
796 rIn >> aRecHd;
797 if ( rManager.SeekToRec( rIn, DFF_msofbtOPT, aRecHd.GetRecEndFilePos() ) )
799 DffPropSet aMasterPropSet;
800 rIn >> aMasterPropSet;
801 Merge( aMasterPropSet );
805 // if ( pDefaultPropSet )
806 // Merge( *( pDefaultPropSet ) );
808 ( (DffPropertyReader*) this )->mnFix16Angle = Fix16ToAngle( GetPropertyValue( DFF_Prop_Rotation, 0 ) );
810 #ifdef DBG_CUSTOMSHAPE
812 String aURLStr;
814 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( String( RTL_CONSTASCII_STRINGPARAM( "d:\\ashape.dbg" ) ), aURLStr ) )
816 SvStream* pOut = ::utl::UcbStreamHelper::CreateStream( aURLStr, STREAM_WRITE );
818 if( pOut )
820 pOut->Seek( STREAM_SEEK_TO_END );
822 if ( IsProperty( DFF_Prop_adjustValue ) || IsProperty( DFF_Prop_pVertices ) )
824 pOut->WriteLine( "" );
825 ByteString aString( "ShapeId: " );
826 aString.Append( ByteString::CreateFromInt32( nShapeId ) );
827 pOut->WriteLine( aString );
829 for ( sal_uInt32 i = DFF_Prop_adjustValue; i <= DFF_Prop_adjust10Value; i++ )
831 if ( IsProperty( i ) )
833 ByteString aString( "Prop_adjustValue" );
834 aString.Append( ByteString::CreateFromInt32( ( i - DFF_Prop_adjustValue ) + 1 ) );
835 aString.Append( ":" );
836 aString.Append( ByteString::CreateFromInt32( GetPropertyValue( i ) ) );
837 pOut->WriteLine( aString );
840 sal_Int32 i;
841 for ( i = 320; i < 383; i++ )
843 if ( ( i >= DFF_Prop_adjustValue ) && ( i <= DFF_Prop_adjust10Value ) )
844 continue;
845 if ( IsProperty( i ) )
847 if ( SeekToContent( i, rIn ) )
849 INT32 nLen = (INT32)GetPropertyValue( i );
850 if ( nLen )
852 pOut->WriteLine( "" );
853 ByteString aDesc( "Property:" );
854 aDesc.Append( ByteString::CreateFromInt32( i ) );
855 aDesc.Append( ByteString( " Size:" ) );
856 aDesc.Append( ByteString::CreateFromInt32( nLen ) );
857 pOut->WriteLine( aDesc );
858 INT16 nNumElem, nNumElemMem, nNumSize;
859 rIn >> nNumElem >> nNumElemMem >> nNumSize;
860 aDesc = ByteString( "Entries: " );
861 aDesc.Append( ByteString::CreateFromInt32( nNumElem ) );
862 aDesc.Append( ByteString( " Size:" ) );
863 aDesc.Append( ByteString::CreateFromInt32( nNumSize ) );
864 pOut->WriteLine( aDesc );
865 if ( nNumSize < 0 )
866 nNumSize = ( ( -nNumSize ) >> 2 );
867 if ( !nNumSize )
868 nNumSize = 16;
869 nLen -= 6;
870 while ( nLen > 0 )
872 ByteString aString;
873 for ( UINT32 j = 0; nLen && ( j < ( nNumSize >> 1 ) ); j++ )
875 for ( UINT32 k = 0; k < 2; k++ )
877 if ( nLen )
879 BYTE nVal;
880 rIn >> nVal;
881 if ( ( nVal >> 4 ) > 9 )
882 *pOut << (BYTE)( ( nVal >> 4 ) + 'A' - 10 );
883 else
884 *pOut << (BYTE)( ( nVal >> 4 ) + '0' );
886 if ( ( nVal & 0xf ) > 9 )
887 *pOut << (BYTE)( ( nVal & 0xf ) + 'A' - 10 );
888 else
889 *pOut << (BYTE)( ( nVal & 0xf ) + '0' );
891 nLen--;
894 *pOut << (char)( ' ' );
896 pOut->WriteLine( aString );
900 else
902 ByteString aString( "Property" );
903 aString.Append( ByteString::CreateFromInt32( i ) );
904 aString.Append( ":" );
905 aString.Append( ByteString::CreateFromInt32( GetPropertyValue( i ) ) );
906 pOut->WriteLine( aString );
911 delete pOut;
915 #endif
917 rIn.Seek( nFilePos );
921 INT32 DffPropertyReader::Fix16ToAngle( INT32 nContent ) const
923 INT32 nAngle = 0;
924 if ( nContent )
926 nAngle = ( (INT16)( nContent >> 16) * 100L ) + ( ( ( nContent & 0x0000ffff) * 100L ) >> 16 );
927 nAngle = NormAngle360( -nAngle );
929 return nAngle;
932 DffPropertyReader::~DffPropertyReader()
934 delete pDefaultPropSet;
937 ////////////////////////////////////////////////////////////////////////////////////////////////////
939 SvStream& operator>>( SvStream& rIn, SvxMSDffConnectorRule& rRule )
941 rIn >> rRule.nRuleId
942 >> rRule.nShapeA
943 >> rRule.nShapeB
944 >> rRule.nShapeC
945 >> rRule.ncptiA
946 >> rRule.ncptiB;
948 return rIn;
951 SvxMSDffSolverContainer::SvxMSDffSolverContainer()
955 SvxMSDffSolverContainer::~SvxMSDffSolverContainer()
957 for ( SvxMSDffConnectorRule* pPtr = (SvxMSDffConnectorRule*)aCList.First();
958 pPtr; pPtr = (SvxMSDffConnectorRule*)aCList.Next() )
959 delete pPtr;
962 SvStream& operator>>( SvStream& rIn, SvxMSDffSolverContainer& rContainer )
964 DffRecordHeader aHd;
965 rIn >> aHd;
966 if ( aHd.nRecType == DFF_msofbtSolverContainer )
968 DffRecordHeader aCRule;
969 while ( ( rIn.GetError() == 0 ) && ( rIn.Tell() < aHd.GetRecEndFilePos() ) )
971 rIn >> aCRule;
972 if ( aCRule.nRecType == DFF_msofbtConnectorRule )
974 SvxMSDffConnectorRule* pRule = new SvxMSDffConnectorRule;
975 rIn >> *pRule;
976 rContainer.aCList.Insert( pRule, LIST_APPEND );
978 aCRule.SeekToEndOfRecord( rIn );
981 return rIn;
984 void SvxMSDffManager::SolveSolver( const SvxMSDffSolverContainer& rSolver )
986 sal_Int32 i, nCnt;
987 for ( i = 0, nCnt = rSolver.aCList.Count(); i < nCnt; i++ )
989 SvxMSDffConnectorRule* pPtr = (SvxMSDffConnectorRule*)rSolver.aCList.GetObject( i );
990 if ( pPtr->pCObj )
992 for ( int nN = 0; nN < 2; nN++ )
994 SdrObject* pO;
995 sal_uInt32 nC, nSpFlags;
996 sal_Bool bTail;
997 if ( !nN )
999 bTail = sal_True;
1000 pO = pPtr->pAObj;
1001 nC = pPtr->ncptiA;
1002 nSpFlags = pPtr->nSpFlagsA;
1004 else
1006 bTail = sal_False;
1007 pO = pPtr->pBObj;
1008 nC = pPtr->ncptiB;
1009 nSpFlags = pPtr->nSpFlagsB;
1011 if ( pO )
1013 Any aAny;
1014 SdrGluePoint aGluePoint;
1015 Reference< XShape > aXShape( pO->getUnoShape(), UNO_QUERY );
1016 Reference< XShape > aXConnector( pPtr->pCObj->getUnoShape(), UNO_QUERY );
1017 SdrGluePointList* pList = pO->ForceGluePointList();
1019 sal_Bool bValidGluePoint = sal_False;
1020 sal_Int32 nId = nC;
1021 sal_uInt32 nInventor = pO->GetObjInventor();
1023 if( nInventor == SdrInventor )
1025 sal_uInt32 nObjId = pO->GetObjIdentifier();
1026 switch( nObjId )
1028 case OBJ_GRUP :
1029 case OBJ_GRAF :
1030 case OBJ_RECT :
1031 case OBJ_TEXT :
1032 case OBJ_PAGE :
1033 case OBJ_TEXTEXT :
1034 case OBJ_wegFITTEXT :
1035 case OBJ_wegFITALLTEXT :
1036 case OBJ_TITLETEXT :
1037 case OBJ_OUTLINETEXT :
1039 if ( nC & 1 )
1041 if ( nSpFlags & SP_FFLIPH )
1042 nC ^= 2; // 1 <-> 3
1044 else
1046 if ( nSpFlags & SP_FFLIPV )
1047 nC ^= 1; // 0 <-> 2
1049 switch( nC )
1051 case 0 :
1052 nId = 0; // SDRVERTALIGN_TOP;
1053 break;
1054 case 1 :
1055 nId = 3; // SDRHORZALIGN_RIGHT;
1056 break;
1057 case 2 :
1058 nId = 2; // SDRVERTALIGN_BOTTOM;
1059 break;
1060 case 3 :
1061 nId = 1; // SDRHORZALIGN_LEFT;
1062 break;
1064 if ( nId <= 3 )
1065 bValidGluePoint = sal_True;
1067 break;
1068 case OBJ_POLY :
1069 case OBJ_PLIN :
1070 case OBJ_LINE :
1071 case OBJ_PATHLINE :
1072 case OBJ_PATHFILL :
1073 case OBJ_FREELINE :
1074 case OBJ_FREEFILL :
1075 case OBJ_SPLNLINE :
1076 case OBJ_SPLNFILL :
1077 case OBJ_PATHPOLY :
1078 case OBJ_PATHPLIN :
1080 if ( pList && ( pList->GetCount() > nC ) )
1082 bValidGluePoint = sal_True;
1083 nId = (sal_Int32)((*pList)[ (sal_uInt16)nC].GetId() + 3 );
1085 else
1087 sal_Bool bNotFound = sal_True;
1089 PolyPolygon aPolyPoly( EscherPropertyContainer::GetPolyPolygon( aXShape ) );
1090 sal_uInt16 k, j, nPolySize = aPolyPoly.Count();
1091 if ( nPolySize )
1093 sal_uInt32 nPointCount = 0;
1094 Rectangle aBoundRect( aPolyPoly.GetBoundRect() );
1095 if ( aBoundRect.GetWidth() && aBoundRect.GetHeight() )
1097 for ( k = 0; bNotFound && ( k < nPolySize ); k++ )
1099 const Polygon& rPolygon = aPolyPoly.GetObject( k );
1100 for ( j = 0; bNotFound && ( j < rPolygon.GetSize() ); j++ )
1102 PolyFlags eFlags = rPolygon.GetFlags( j );
1103 if ( eFlags == POLY_NORMAL )
1105 if ( nC == nPointCount )
1107 const Point& rPoint = rPolygon.GetPoint( j );
1108 double fXRel = rPoint.X() - aBoundRect.Left();
1109 double fYRel = rPoint.Y() - aBoundRect.Top();
1110 sal_Int32 nWidth = aBoundRect.GetWidth();
1111 if ( !nWidth )
1112 nWidth = 1;
1113 sal_Int32 nHeight= aBoundRect.GetHeight();
1114 if ( !nHeight )
1115 nHeight = 1;
1116 fXRel /= (double)nWidth;
1117 fXRel *= 10000;
1118 fYRel /= (double)nHeight;
1119 fYRel *= 10000;
1120 aGluePoint.SetPos( Point( (sal_Int32)fXRel, (sal_Int32)fYRel ) );
1121 aGluePoint.SetPercent( sal_True );
1122 aGluePoint.SetAlign( SDRVERTALIGN_TOP | SDRHORZALIGN_LEFT );
1123 aGluePoint.SetEscDir( SDRESC_SMART );
1124 nId = (sal_Int32)((*pList)[ pList->Insert( aGluePoint ) ].GetId() + 3 );
1125 bNotFound = sal_False;
1127 nPointCount++;
1133 if ( !bNotFound )
1135 bValidGluePoint = sal_True;
1139 break;
1141 case OBJ_CUSTOMSHAPE :
1143 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pO)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1144 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
1145 const rtl::OUString sGluePointType( RTL_CONSTASCII_USTRINGPARAM ( "GluePointType" ) );
1146 sal_Int16 nGluePointType = EnhancedCustomShapeGluePointType::SEGMENTS;
1147 com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sPath, sGluePointType );
1148 if ( pAny )
1149 *pAny >>= nGluePointType;
1150 else
1152 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
1153 rtl::OUString sShapeType;
1154 pAny = aGeometryItem.GetPropertyValueByName( sType );
1155 if ( pAny )
1156 *pAny >>= sShapeType;
1157 MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
1158 nGluePointType = GetCustomShapeConnectionTypeDefault( eSpType );
1160 if ( nGluePointType == EnhancedCustomShapeGluePointType::CUSTOM )
1162 if ( pList && ( pList->GetCount() > nC ) )
1164 bValidGluePoint = sal_True;
1165 nId = (sal_Int32)((*pList)[ (sal_uInt16)nC].GetId() + 3 );
1168 else if ( nGluePointType == EnhancedCustomShapeGluePointType::RECT )
1170 if ( nC & 1 )
1172 if ( nSpFlags & SP_FFLIPH )
1173 nC ^= 2; // 1 <-> 3
1175 else
1177 if ( nSpFlags & SP_FFLIPV )
1178 nC ^= 1; // 0 <-> 2
1180 switch( nC )
1182 case 0 :
1183 nId = 0; // SDRVERTALIGN_TOP;
1184 break;
1185 case 1 :
1186 nId = 3; // SDRHORZALIGN_RIGHT;
1187 break;
1188 case 2 :
1189 nId = 2; // SDRVERTALIGN_BOTTOM;
1190 break;
1191 case 3 :
1192 nId = 1; // SDRHORZALIGN_LEFT;
1193 break;
1195 if ( nId <= 3 )
1196 bValidGluePoint = sal_True;
1198 else if ( nGluePointType == EnhancedCustomShapeGluePointType::SEGMENTS )
1200 const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
1201 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
1203 sal_uInt32 k, nPt = nC;
1204 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments;
1205 pAny = aGeometryItem.GetPropertyValueByName( sPath, sSegments );
1206 if ( pAny )
1208 if ( *pAny >>= aSegments )
1210 for ( nPt = 0, k = 1; nC && ( k < (sal_uInt32)aSegments.getLength() ); k++ )
1212 sal_Int16 j, nCnt2 = aSegments[ k ].Count;
1213 if ( aSegments[ k ].Command != EnhancedCustomShapeSegmentCommand::UNKNOWN )
1215 for ( j = 0; nC && ( j < nCnt2 ); j++ )
1217 switch( aSegments[ k ].Command )
1219 case EnhancedCustomShapeSegmentCommand::ENDSUBPATH :
1220 case EnhancedCustomShapeSegmentCommand::CLOSESUBPATH :
1221 case EnhancedCustomShapeSegmentCommand::LINETO :
1222 case EnhancedCustomShapeSegmentCommand::MOVETO :
1224 nC--;
1225 nPt++;
1227 break;
1228 case EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX :
1229 case EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY :
1230 break;
1232 case EnhancedCustomShapeSegmentCommand::CURVETO :
1234 nC--;
1235 nPt += 3;
1237 break;
1239 case EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO :
1240 case EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE :
1242 nC--;
1243 nPt += 3;
1245 break;
1246 case EnhancedCustomShapeSegmentCommand::ARCTO :
1247 case EnhancedCustomShapeSegmentCommand::ARC :
1248 case EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO :
1249 case EnhancedCustomShapeSegmentCommand::CLOCKWISEARC :
1251 nC--;
1252 nPt += 4;
1254 break;
1261 pAny = aGeometryItem.GetPropertyValueByName( sPath, sCoordinates );
1262 if ( pAny )
1264 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
1265 *pAny >>= aCoordinates;
1266 if ( nPt < (sal_uInt32)aCoordinates.getLength() )
1268 nId = 4;
1269 com::sun::star::drawing::EnhancedCustomShapeParameterPair& rPara = aCoordinates[ nPt ];
1270 sal_Int32 nX = 0, nY = 0;
1271 if ( ( rPara.First.Value >>= nX ) && ( rPara.Second.Value >>= nY ) )
1273 const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
1274 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aGluePoints;
1275 pAny = aGeometryItem.GetPropertyValueByName( sPath, sGluePoints );
1276 if ( pAny )
1277 *pAny >>= aGluePoints;
1278 sal_Int32 nGluePoints = aGluePoints.getLength();
1279 aGluePoints.realloc( nGluePoints + 1 );
1280 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ nGluePoints ].First, nX );
1281 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ nGluePoints ].Second, nY );
1282 PropertyValue aProp;
1283 aProp.Name = sGluePoints;
1284 aProp.Value <<= aGluePoints;
1285 aGeometryItem.SetPropertyValue( sPath, aProp );
1286 bValidGluePoint = sal_True;
1287 ((SdrObjCustomShape*)pO)->SetMergedItem( aGeometryItem );
1288 SdrGluePointList* pLst = pO->ForceGluePointList();
1289 if ( pLst->GetCount() > nGluePoints )
1290 nId = (sal_Int32)((*pLst)[ (sal_uInt16)nGluePoints ].GetId() + 3 );
1296 break;
1298 if ( bValidGluePoint )
1300 Reference< XPropertySet > xPropSet( aXConnector, UNO_QUERY );
1301 if ( xPropSet.is() )
1303 if ( nN )
1305 String aPropName( RTL_CONSTASCII_USTRINGPARAM( "EndShape" ) );
1306 aAny <<= aXShape;
1307 SetPropValue( aAny, xPropSet, aPropName, sal_True );
1308 aPropName = String( RTL_CONSTASCII_USTRINGPARAM( "EndGluePointIndex" ) );
1309 aAny <<= nId;
1310 SetPropValue( aAny, xPropSet, aPropName, sal_True );
1312 else
1314 String aPropName( RTL_CONSTASCII_USTRINGPARAM( "StartShape" ) );
1315 aAny <<= aXShape;
1316 SetPropValue( aAny, xPropSet, aPropName, sal_True );
1317 aPropName = String( RTL_CONSTASCII_USTRINGPARAM( "StartGluePointIndex" ) );
1318 aAny <<= nId;
1319 SetPropValue( aAny, xPropSet, aPropName, sal_True );
1322 // Not sure what this is good for, repaint or broadcast of object change.
1323 //( Thus i am adding repaint here
1324 pO->SetChanged();
1325 pO->BroadcastObjectChange();
1335 ////////////////////////////////////////////////////////////////////////////////////////////////////
1337 static basegfx::B2DPolygon GetLineArrow( const sal_Int32 nLineWidth, const MSO_LineEnd eLineEnd,
1338 const MSO_LineEndWidth eLineWidth, const MSO_LineEndLength eLineLenght,
1339 sal_Int32& rnArrowWidth, sal_Bool& rbArrowCenter,
1340 String& rsArrowName, sal_Bool bScaleArrow )
1342 basegfx::B2DPolygon aRetval;
1343 double fLineWidth = nLineWidth < 70 ? 70.0 : nLineWidth;
1344 double fLenghtMul, fWidthMul;
1345 sal_Int32 nLineNumber;
1346 switch( eLineLenght )
1348 default :
1349 case mso_lineMediumLenArrow : fLenghtMul = 3.0; nLineNumber = 2; break;
1350 case mso_lineShortArrow : fLenghtMul = 2.0; nLineNumber = 1; break;
1351 case mso_lineLongArrow : fLenghtMul = 5.0; nLineNumber = 3; break;
1353 switch( eLineWidth )
1355 default :
1356 case mso_lineMediumWidthArrow : fWidthMul = 3.0; nLineNumber += 3; break;
1357 case mso_lineNarrowArrow : fWidthMul = 2.0; break;
1358 case mso_lineWideArrow : fWidthMul = 5.0; nLineNumber += 6; break;
1361 if ( bScaleArrow ) // #i33630 arrows imported from Word are too big
1363 fWidthMul /= 1.75;
1364 fLenghtMul/= 1.75;
1367 rbArrowCenter = sal_False;
1368 switch ( eLineEnd )
1370 case mso_lineArrowEnd :
1372 basegfx::B2DPolygon aTriangle;
1373 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50, 0.0 ));
1374 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth, fLenghtMul * fLineWidth ));
1375 aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth ));
1376 aTriangle.setClosed(true);
1377 aRetval = aTriangle;
1378 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowEnd " ), RTL_TEXTENCODING_UTF8 );
1380 break;
1382 case mso_lineArrowOpenEnd :
1384 switch( eLineLenght )
1386 default :
1387 case mso_lineMediumLenArrow : fLenghtMul = 4.5; break;
1388 case mso_lineShortArrow : fLenghtMul = 3.5; break;
1389 case mso_lineLongArrow : fLenghtMul = 6.0; break;
1391 switch( eLineWidth )
1393 default :
1394 case mso_lineMediumWidthArrow : fWidthMul = 4.5; break;
1395 case mso_lineNarrowArrow : fWidthMul = 3.5; break;
1396 case mso_lineWideArrow : fWidthMul = 6.0; break;
1398 basegfx::B2DPolygon aTriangle;
1399 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
1400 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth, fLenghtMul * fLineWidth * 0.91 ));
1401 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.85, fLenghtMul * fLineWidth ));
1402 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50, fLenghtMul * fLineWidth * 0.36 ));
1403 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.15, fLenghtMul * fLineWidth ));
1404 aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth * 0.91 ));
1405 aTriangle.setClosed(true);
1406 aRetval = aTriangle;
1407 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowOpenEnd " ), RTL_TEXTENCODING_UTF8 );
1409 break;
1410 case mso_lineArrowStealthEnd :
1412 basegfx::B2DPolygon aTriangle;
1413 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
1414 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth , fLenghtMul * fLineWidth ));
1415 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , fLenghtMul * fLineWidth * 0.60 ));
1416 aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth ));
1417 aTriangle.setClosed(true);
1418 aRetval = aTriangle;
1419 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowStealthEnd " ), RTL_TEXTENCODING_UTF8 );
1421 break;
1422 case mso_lineArrowDiamondEnd :
1424 basegfx::B2DPolygon aTriangle;
1425 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
1426 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth , fLenghtMul * fLineWidth * 0.50 ));
1427 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , fLenghtMul * fLineWidth ));
1428 aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth * 0.50 ));
1429 aTriangle.setClosed(true);
1430 aRetval = aTriangle;
1431 rbArrowCenter = sal_True;
1432 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowDiamondEnd " ), RTL_TEXTENCODING_UTF8 );
1434 break;
1435 case mso_lineArrowOvalEnd :
1437 aRetval = XPolygon( Point( (sal_Int32)( fWidthMul * fLineWidth * 0.50 ), 0 ),
1438 (sal_Int32)( fWidthMul * fLineWidth * 0.50 ),
1439 (sal_Int32)( fLenghtMul * fLineWidth * 0.50 ), 0, 3600 ).getB2DPolygon();
1440 rbArrowCenter = sal_True;
1441 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowOvalEnd " ), RTL_TEXTENCODING_UTF8 );
1443 break;
1444 default: break;
1446 rsArrowName.Append( String::CreateFromInt32( nLineNumber ) );
1447 rnArrowWidth = (sal_Int32)( fLineWidth * fWidthMul );
1449 return aRetval;
1452 void DffPropertyReader::ApplyLineAttributes( SfxItemSet& rSet, const MSO_SPT eShapeType ) const // #i28269#
1454 UINT32 nLineFlags(GetPropertyValue( DFF_Prop_fNoLineDrawDash ));
1456 if(!IsHardAttribute( DFF_Prop_fLine ) && !IsCustomShapeStrokedByDefault( eShapeType ))
1458 nLineFlags &= ~0x08;
1461 if ( nLineFlags & 8 )
1463 // Linienattribute
1464 sal_Int32 nLineWidth = (INT32)GetPropertyValue( DFF_Prop_lineWidth, 9525 );
1466 MSO_LineDashing eLineDashing = (MSO_LineDashing)GetPropertyValue( DFF_Prop_lineDashing, mso_lineSolid );
1467 if ( eLineDashing == mso_lineSolid )
1468 rSet.Put(XLineStyleItem( XLINE_SOLID ) );
1469 else
1471 // MSO_LineCap eLineCap = (MSO_LineCap)GetPropertyValue( DFF_Prop_lineEndCapStyle, mso_lineEndCapSquare );
1473 XDashStyle eDash = XDASH_RECT;
1474 sal_uInt16 nDots = 1;
1475 sal_uInt32 nDotLen = nLineWidth / 360;
1476 sal_uInt16 nDashes = 0;
1477 sal_uInt32 nDashLen = ( 8 * nLineWidth ) / 360;
1478 sal_uInt32 nDistance = ( 3 * nLineWidth ) / 360;;
1480 switch ( eLineDashing )
1482 default:
1483 case mso_lineDotSys :
1485 nDots = 1;
1486 nDashes = 0;
1487 nDistance = nDotLen;
1489 break;
1491 case mso_lineDashGEL :
1493 nDots = 0;
1494 nDashes = 1;
1495 nDashLen = ( 4 * nLineWidth ) / 360;
1497 break;
1499 case mso_lineDashDotGEL :
1501 nDots = 1;
1502 nDashes = 1;
1503 nDashLen = ( 4 * nLineWidth ) / 360;
1505 break;
1507 case mso_lineLongDashGEL :
1509 nDots = 0;
1510 nDashes = 1;
1512 break;
1514 case mso_lineLongDashDotGEL :
1516 nDots = 1;
1517 nDashes = 1;
1519 break;
1521 case mso_lineLongDashDotDotGEL:
1523 nDots = 2;
1524 nDashes = 1;
1526 break;
1529 rSet.Put( XLineDashItem( String(), XDash( eDash, nDots, nDotLen, nDashes, nDashLen, nDistance ) ) );
1530 rSet.Put( XLineStyleItem( XLINE_DASH ) );
1532 rSet.Put( XLineColorItem( String(), rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_lineColor ), DFF_Prop_lineColor ) ) );
1533 if ( IsProperty( DFF_Prop_lineOpacity ) )
1535 double nTrans = GetPropertyValue(DFF_Prop_lineOpacity, 0x10000);
1536 nTrans = (nTrans * 100) / 65536;
1537 rSet.Put(XLineTransparenceItem(
1538 sal_uInt16(100 - ::rtl::math::round(nTrans))));
1541 rManager.ScaleEmu( nLineWidth );
1542 rSet.Put( XLineWidthItem( nLineWidth ) );
1544 // SJ: LineJoint (setting each time a line is set, because our internal joint type has another default)
1545 MSO_LineJoin eLineJointDefault = mso_lineJoinMiter;
1546 if ( eShapeType == mso_sptMin )
1547 eLineJointDefault = mso_lineJoinRound;
1548 MSO_LineJoin eLineJoint = (MSO_LineJoin)GetPropertyValue( DFF_Prop_lineJoinStyle, eLineJointDefault );
1549 XLineJoint eXLineJoint( XLINEJOINT_MITER );
1550 if ( eLineJoint == mso_lineJoinBevel )
1551 eXLineJoint = XLINEJOINT_BEVEL;
1552 else if ( eLineJoint == mso_lineJoinRound )
1553 eXLineJoint = XLINEJOINT_ROUND;
1554 rSet.Put( XLineJointItem( eXLineJoint ) );
1556 if ( nLineFlags & 0x10 )
1558 sal_Bool bScaleArrows = rManager.pSdrModel->GetScaleUnit() == MAP_TWIP;
1559 ///////////////
1560 // LineStart //
1561 ///////////////
1562 if ( IsProperty( DFF_Prop_lineStartArrowhead ) )
1564 MSO_LineEnd eLineEnd = (MSO_LineEnd)GetPropertyValue( DFF_Prop_lineStartArrowhead );
1565 MSO_LineEndWidth eWidth = (MSO_LineEndWidth)GetPropertyValue( DFF_Prop_lineStartArrowWidth, mso_lineMediumWidthArrow );
1566 MSO_LineEndLength eLenght = (MSO_LineEndLength)GetPropertyValue( DFF_Prop_lineStartArrowLength, mso_lineMediumLenArrow );
1568 sal_Int32 nArrowWidth;
1569 sal_Bool bArrowCenter;
1570 String aArrowName;
1571 basegfx::B2DPolygon aPoly(GetLineArrow( nLineWidth, eLineEnd, eWidth, eLenght, nArrowWidth, bArrowCenter, aArrowName, bScaleArrows ));
1573 rSet.Put( XLineStartWidthItem( nArrowWidth ) );
1574 rSet.Put( XLineStartItem( aArrowName, basegfx::B2DPolyPolygon(aPoly) ) );
1575 rSet.Put( XLineStartCenterItem( bArrowCenter ) );
1577 /////////////
1578 // LineEnd //
1579 /////////////
1580 if ( IsProperty( DFF_Prop_lineEndArrowhead ) )
1582 MSO_LineEnd eLineEnd = (MSO_LineEnd)GetPropertyValue( DFF_Prop_lineEndArrowhead );
1583 MSO_LineEndWidth eWidth = (MSO_LineEndWidth)GetPropertyValue( DFF_Prop_lineEndArrowWidth, mso_lineMediumWidthArrow );
1584 MSO_LineEndLength eLenght = (MSO_LineEndLength)GetPropertyValue( DFF_Prop_lineEndArrowLength, mso_lineMediumLenArrow );
1586 sal_Int32 nArrowWidth;
1587 sal_Bool bArrowCenter;
1588 String aArrowName;
1589 basegfx::B2DPolygon aPoly(GetLineArrow( nLineWidth, eLineEnd, eWidth, eLenght, nArrowWidth, bArrowCenter, aArrowName, bScaleArrows ));
1591 rSet.Put( XLineEndWidthItem( nArrowWidth ) );
1592 rSet.Put( XLineEndItem( aArrowName, basegfx::B2DPolyPolygon(aPoly) ) );
1593 rSet.Put( XLineEndCenterItem( bArrowCenter ) );
1595 if ( IsProperty( DFF_Prop_lineEndCapStyle ) )
1597 MSO_LineCap eLineCap = (MSO_LineCap)GetPropertyValue( DFF_Prop_lineEndCapStyle );
1598 const SfxPoolItem* pPoolItem = NULL;
1599 if ( rSet.GetItemState( XATTR_LINEDASH, FALSE, &pPoolItem ) == SFX_ITEM_SET )
1601 XDashStyle eNewStyle = XDASH_RECT;
1602 if ( eLineCap == mso_lineEndCapRound )
1603 eNewStyle = XDASH_ROUND;
1604 const XDash& rOldDash = ( (const XLineDashItem*)pPoolItem )->GetDashValue();
1605 if ( rOldDash.GetDashStyle() != eNewStyle )
1607 XDash aNew( rOldDash );
1608 aNew.SetDashStyle( eNewStyle );
1609 rSet.Put( XLineDashItem( XubString(), aNew ) );
1615 else
1616 rSet.Put( XLineStyleItem( XLINE_NONE ) );
1619 struct ShadeColor
1621 Color aColor;
1622 double fDist;
1624 ShadeColor( const Color& rC, double fR ) : aColor( rC ), fDist( fR ) {};
1627 void GetShadeColors( const SvxMSDffManager& rManager, const DffPropertyReader& rProperties, SvStream& rIn, std::vector< ShadeColor >& rShadeColors )
1629 sal_uInt32 nPos = rIn.Tell();
1630 if ( rProperties.IsProperty( DFF_Prop_fillShadeColors ) )
1632 if ( rProperties.SeekToContent( DFF_Prop_fillShadeColors, rIn ) )
1634 sal_uInt16 i = 0, nNumElem = 0, nNumElemReserved = 0, nSize = 0;
1635 rIn >> nNumElem >> nNumElemReserved >> nSize;
1636 for ( ; i < nNumElem; i++ )
1638 sal_Int32 nColor;
1639 sal_Int32 nDist;
1641 rIn >> nColor >> nDist;
1642 rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( nColor, DFF_Prop_fillColor ), 1.0 - ( nDist / 65536.0 ) ) );
1646 if ( !rShadeColors.size() )
1648 rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( rProperties.GetPropertyValue( DFF_Prop_fillBackColor, COL_WHITE ), DFF_Prop_fillBackColor ), 0 ) );
1649 rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( rProperties.GetPropertyValue( DFF_Prop_fillColor, COL_WHITE ), DFF_Prop_fillColor ), 1 ) );
1651 rIn.Seek( nPos );
1654 struct QuantErr
1656 double fRed;
1657 double fGreen;
1658 double fBlue;
1660 QuantErr() : fRed( 0.0 ), fGreen( 0.0 ), fBlue( 0.0 ){};
1663 void ApplyRectangularGradientAsBitmap( const SvxMSDffManager& rManager, SvStream& rIn, SfxItemSet& rSet, const std::vector< ShadeColor >& rShadeColors, const DffObjData& rObjData, sal_Int32 nFix16Angle )
1665 Size aBitmapSizePixel( static_cast< sal_Int32 >( ( rObjData.aBoundRect.GetWidth() / 2540.0 ) * 90.0 ), // we will create a bitmap with 90 dpi
1666 static_cast< sal_Int32 >( ( rObjData.aBoundRect.GetHeight() / 2540.0 ) * 90.0 ) );
1667 if ( aBitmapSizePixel.Width() && aBitmapSizePixel.Height() && ( aBitmapSizePixel.Width() <= 1024 ) && ( aBitmapSizePixel.Height() <= 1024 ) )
1669 // std::vector< QuantErr > aQuantErrCurrScan( aBitmapSizePixel.Width() + 1 );
1670 // std::vector< QuantErr > aQuantErrNextScan( aBitmapSizePixel.Width() + 1 );
1672 double fFocusX = rManager.GetPropertyValue( DFF_Prop_fillToRight, 0 ) / 65536.0;
1673 double fFocusY = rManager.GetPropertyValue( DFF_Prop_fillToBottom, 0 ) / 65536.0;
1675 Bitmap aBitmap( aBitmapSizePixel, 24 );
1676 BitmapWriteAccess* pAcc = aBitmap.AcquireWriteAccess();
1677 if ( pAcc )
1679 sal_Int32 nX, nY;
1680 for ( nY = 0; nY < aBitmapSizePixel.Height(); nY++ )
1682 for ( nX = 0; nX < aBitmapSizePixel.Width(); nX++ )
1684 double fX = static_cast< double >( nX ) / aBitmapSizePixel.Width();
1685 double fY = static_cast< double >( nY ) / aBitmapSizePixel.Height();
1687 double fD, fDist;
1688 if ( fX < fFocusX )
1690 if ( fY < fFocusY )
1692 if ( fX > fY )
1693 fDist = fY, fD = fFocusY;
1694 else
1695 fDist = fX, fD = fFocusX;
1697 else
1699 if ( fX > ( 1 - fY ) )
1700 fDist = ( 1 - fY ), fD = 1 - fFocusY;
1701 else
1702 fDist = fX, fD = fFocusX;
1705 else
1707 if ( fY < fFocusY )
1709 if ( ( 1 - fX ) > fY )
1710 fDist = fY, fD = fFocusY;
1711 else
1712 fDist = ( 1 - fX ), fD = 1 - fFocusX;
1714 else
1716 if ( ( 1 - fX ) > ( 1 - fY ) )
1717 fDist = ( 1 - fY ), fD = 1 - fFocusY;
1718 else
1719 fDist = ( 1 - fX ), fD = 1 - fFocusX;
1722 if ( fD != 0.0 )
1723 fDist /= fD;
1725 std::vector< ShadeColor >::const_iterator aIter( rShadeColors.begin() );
1726 double fA = 0.0;
1727 Color aColorA = aIter->aColor;
1728 double fB = 1.0;
1729 Color aColorB( aColorA );
1730 while ( aIter != rShadeColors.end() )
1732 if ( aIter->fDist <= fDist )
1734 if ( aIter->fDist >= fA )
1736 fA = aIter->fDist;
1737 aColorA = aIter->aColor;
1740 if ( aIter->fDist > fDist )
1742 if ( aIter->fDist <= fB )
1744 fB = aIter->fDist;
1745 aColorB = aIter->aColor;
1748 aIter++;
1750 double fRed = aColorA.GetRed(), fGreen = aColorA.GetGreen(), fBlue = aColorA.GetBlue();
1751 double fD1 = fB - fA;
1752 if ( fD1 != 0.0 )
1754 fRed += ( ( ( fDist - fA ) * ( aColorB.GetRed() - aColorA.GetRed() ) ) / fD1 ); // + aQuantErrCurrScan[ nX ].fRed;
1755 fGreen += ( ( ( fDist - fA ) * ( aColorB.GetGreen() - aColorA.GetGreen() ) ) / fD1 ); // + aQuantErrCurrScan[ nX ].fGreen;
1756 fBlue += ( ( ( fDist - fA ) * ( aColorB.GetBlue() - aColorA.GetBlue() ) ) / fD1 ); // + aQuantErrCurrScan[ nX ].fBlue;
1758 sal_Int16 nRed = static_cast< sal_Int16 >( fRed + 0.5 );
1759 sal_Int16 nGreen = static_cast< sal_Int16 >( fGreen + 0.5 );
1760 sal_Int16 nBlue = static_cast< sal_Int16 >( fBlue + 0.5 );
1762 double fErr = fRed - nRed;
1763 aQuantErrCurrScan[ nX + 1 ].fRed += 7.0 * fErr / 16.0;
1764 if ( nX )
1765 aQuantErrNextScan[ nX - 1 ].fRed += 3.0 * fErr / 16.0;
1766 aQuantErrNextScan[ nX ].fRed += 5.0 * fErr / 16.0;
1767 aQuantErrNextScan[ nX + 1 ].fRed += 1.0 * fErr / 16.0;
1769 fErr = fGreen - nGreen;
1770 aQuantErrCurrScan[ nX + 1 ].fGreen += 7.0 * fErr / 16.0;
1771 if ( nX )
1772 aQuantErrNextScan[ nX - 1 ].fGreen += 3.0 * fErr / 16.0;
1773 aQuantErrNextScan[ nX ].fGreen += 5.0 * fErr / 16.0;
1774 aQuantErrNextScan[ nX + 1 ].fGreen += 1.0 * fErr / 16.0;
1776 fErr = fBlue - nBlue;
1777 aQuantErrCurrScan[ nX + 1 ].fBlue += 7.0 * fErr / 16.0;
1778 if ( nX )
1779 aQuantErrNextScan[ nX - 1 ].fBlue += 3.0 * fErr / 16.0;
1780 aQuantErrNextScan[ nX ].fBlue += 5.0 * fErr / 16.0;
1781 aQuantErrNextScan[ nX + 1 ].fBlue += 1.0 * fErr / 16.0;
1783 if ( nRed < 0 )
1784 nRed = 0;
1785 if ( nRed > 255 )
1786 nRed = 255;
1787 if ( nGreen < 0 )
1788 nGreen = 0;
1789 if ( nGreen > 255 )
1790 nGreen = 255;
1791 if ( nBlue < 0 )
1792 nBlue = 0;
1793 if ( nBlue > 255 )
1794 nBlue = 255;
1796 pAcc->SetPixel( nY, nX, BitmapColor( static_cast< sal_Int8 >( nRed ), static_cast< sal_Int8 >( nGreen ), static_cast< sal_Int8 >( nBlue ) ) );
1799 aQuantErrCurrScan.swap( aQuantErrNextScan );
1800 std::vector< QuantErr >::iterator aIter( aQuantErrNextScan.begin() );
1801 while( aIter != aQuantErrNextScan.end() )
1803 *aIter = QuantErr();
1804 aIter++;
1808 aBitmap.ReleaseAccess( pAcc );
1810 if ( nFix16Angle )
1812 sal_Bool bRotateWithShape = sal_True; // TRUE seems to be default
1813 sal_uInt32 nPos = rIn.Tell();
1814 if ( const_cast< SvxMSDffManager& >( rManager ).maShapeRecords.SeekToContent( rIn, DFF_msofbtUDefProp, SEEK_FROM_CURRENT_AND_RESTART ) )
1816 const_cast< SvxMSDffManager& >( rManager ).maShapeRecords.Current()->SeekToBegOfRecord( rIn );
1817 DffPropertyReader aSecPropSet( rManager );
1818 aSecPropSet.ReadPropSet( rIn, NULL );
1819 sal_Int32 nSecFillProperties = aSecPropSet.GetPropertyValue( DFF_Prop_fNoFillHitTest, 0x200020 );
1820 bRotateWithShape = ( nSecFillProperties & 0x0020 );
1822 rIn.Seek( nPos );
1823 if ( bRotateWithShape )
1825 aBitmap.Rotate( nFix16Angle / 10, rShadeColors[ 0 ].aColor );
1827 ULONG nMirrorFlags = BMP_MIRROR_NONE;
1828 if ( rObjData.nSpFlags & SP_FFLIPV )
1829 nMirrorFlags |= BMP_MIRROR_VERT;
1830 if ( rObjData.nSpFlags & SP_FFLIPH )
1831 nMirrorFlags |= BMP_MIRROR_HORZ;
1832 if ( nMirrorFlags != BMP_MIRROR_NONE )
1833 aBitmap.Mirror( nMirrorFlags );
1837 XOBitmap aXBmp( aBitmap, XBITMAP_STRETCH );
1838 rSet.Put( XFillBmpTileItem( sal_False ) );
1839 rSet.Put( XFillBitmapItem( String(), aXBmp ) );
1844 void DffPropertyReader::ApplyFillAttributes( SvStream& rIn, SfxItemSet& rSet, const DffObjData& rObjData ) const
1846 UINT32 nFillFlags(GetPropertyValue( DFF_Prop_fNoFillHitTest ));
1848 std::vector< ShadeColor > aShadeColors;
1849 GetShadeColors( rManager, *this, rIn, aShadeColors );
1851 if(!IsHardAttribute( DFF_Prop_fFilled ) && !IsCustomShapeFilledByDefault( rObjData.eShapeType ))
1853 nFillFlags &= ~0x10;
1856 if ( nFillFlags & 0x10 )
1858 MSO_FillType eMSO_FillType = (MSO_FillType)GetPropertyValue( DFF_Prop_fillType, mso_fillSolid );
1859 XFillStyle eXFill = XFILL_NONE;
1860 switch( eMSO_FillType )
1862 case mso_fillSolid : // Fill with a solid color
1863 eXFill = XFILL_SOLID;
1864 break;
1865 case mso_fillPattern : // Fill with a pattern (bitmap)
1866 case mso_fillTexture : // A texture (pattern with its own color map)
1867 case mso_fillPicture : // Center a picture in the shape
1868 eXFill = XFILL_BITMAP;
1869 break;
1870 case mso_fillShadeCenter : // Shade from bounding rectangle to end point
1872 if ( rObjData.aBoundRect.IsEmpty() )// size of object needed to be able
1873 eXFill = XFILL_GRADIENT; // to create a bitmap substitution
1874 else
1875 eXFill = XFILL_BITMAP;
1877 break;
1878 case mso_fillShade : // Shade from start to end points
1879 case mso_fillShadeShape : // Shade from shape outline to end point
1880 case mso_fillShadeScale : // Similar to mso_fillShade, but the fillAngle
1881 case mso_fillShadeTitle : // special type - shade to title --- for PP
1882 eXFill = XFILL_GRADIENT;
1883 break;
1884 // case mso_fillBackground : // Use the background fill color/pattern
1885 default: break;
1887 rSet.Put( XFillStyleItem( eXFill ) );
1889 if (IsProperty(DFF_Prop_fillOpacity))
1891 double nTrans = GetPropertyValue(DFF_Prop_fillOpacity);
1892 nTrans = (nTrans * 100) / 65536;
1893 rSet.Put(XFillTransparenceItem(
1894 sal_uInt16(100 - ::rtl::math::round(nTrans))));
1897 if ( ( eMSO_FillType == mso_fillShadeCenter ) && ( eXFill == XFILL_BITMAP ) )
1899 ApplyRectangularGradientAsBitmap( rManager, rIn, rSet, aShadeColors, rObjData, mnFix16Angle );
1901 else if ( eXFill == XFILL_GRADIENT )
1903 sal_Int32 nAngle = 3600 - ( ( Fix16ToAngle( GetPropertyValue( DFF_Prop_fillAngle, 0 ) ) + 5 ) / 10 );
1905 // Rotationswinkel in Bereich zwingen
1906 while ( nAngle >= 3600 )
1907 nAngle -= 3600;
1908 while ( nAngle < 0 )
1909 nAngle += 3600;
1911 sal_Int32 nFocus = GetPropertyValue( DFF_Prop_fillFocus, 0 );
1912 XGradientStyle eGrad = XGRAD_LINEAR;
1913 sal_Int32 nChgColors = 0;
1915 if ( nFocus < 0 ) // Bei negativem Focus sind die Farben zu tauschen
1917 nFocus =- nFocus;
1918 nChgColors ^= 1;
1920 if( nFocus > 40 && nFocus < 60 )
1922 eGrad = XGRAD_AXIAL; // Besser gehts leider nicht
1925 USHORT nFocusX = (USHORT)nFocus;
1926 USHORT nFocusY = (USHORT)nFocus;
1928 switch( eMSO_FillType )
1930 case mso_fillShadeShape :
1932 eGrad = XGRAD_RECT;
1933 nFocusY = nFocusX = 50;
1934 nChgColors ^= 1;
1936 break;
1937 case mso_fillShadeCenter :
1939 eGrad = XGRAD_RECT;
1940 nFocusX = ( IsProperty( DFF_Prop_fillToRight ) ) ? 100 : 0;
1941 nFocusY = ( IsProperty( DFF_Prop_fillToBottom ) ) ? 100 : 0;
1942 nChgColors ^= 1;
1944 break;
1945 default: break;
1947 Color aCol1( rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor, COL_WHITE ), DFF_Prop_fillColor ) );
1948 Color aCol2( rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillBackColor, COL_WHITE ), DFF_Prop_fillBackColor ) );
1950 if ( nChgColors )
1952 Color aZwi( aCol1 );
1953 aCol1 = aCol2;
1954 aCol2 = aZwi;
1956 XGradient aGrad( aCol2, aCol1, eGrad, nAngle, nFocusX, nFocusY );
1957 aGrad.SetStartIntens( 100 );
1958 aGrad.SetEndIntens( 100 );
1959 rSet.Put( XFillGradientItem( String(), aGrad ) );
1961 else if ( eXFill == XFILL_BITMAP )
1963 if( IsProperty( DFF_Prop_fillBlip ) )
1965 Graphic aGraf;
1966 // first try to get BLIP from cache
1967 BOOL bOK = rManager.GetBLIP( GetPropertyValue( DFF_Prop_fillBlip ), aGraf, NULL );
1968 // then try directly from stream (i.e. Excel chart hatches/bitmaps)
1969 if ( !bOK )
1970 bOK = SeekToContent( DFF_Prop_fillBlip, rIn ) && rManager.GetBLIPDirect( rIn, aGraf, NULL );
1971 if ( bOK )
1973 Bitmap aBmp( aGraf.GetBitmap() );
1975 if ( eMSO_FillType == mso_fillPattern )
1977 Color aCol1( COL_WHITE ), aCol2( COL_WHITE );
1978 if ( IsProperty( DFF_Prop_fillColor ) )
1979 aCol1 = rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor ), DFF_Prop_fillColor );
1980 if ( IsProperty( DFF_Prop_fillBackColor ) )
1981 aCol2 = rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillBackColor ), DFF_Prop_fillBackColor );
1983 XOBitmap aXOBitmap;
1985 // Bitmap einsetzen
1986 aXOBitmap.SetBitmap( aBmp );
1987 aXOBitmap.SetBitmapType( XBITMAP_IMPORT );
1989 if( aBmp.GetSizePixel().Width() == 8 && aBmp.GetSizePixel().Height() == 8 && aBmp.GetColorCount() == 2)
1991 aXOBitmap.Bitmap2Array();
1992 aXOBitmap.SetBitmapType( XBITMAP_8X8 );
1993 aXOBitmap.SetPixelSize( aBmp.GetSizePixel() );
1995 if( aXOBitmap.GetBackgroundColor() == COL_BLACK )
1997 aXOBitmap.SetPixelColor( aCol1 );
1998 aXOBitmap.SetBackgroundColor( aCol2 );
2000 else
2002 aXOBitmap.SetPixelColor( aCol2 );
2003 aXOBitmap.SetBackgroundColor( aCol1 );
2006 rSet.Put( XFillBitmapItem( String(), aXOBitmap ) );
2008 else if ( eMSO_FillType == mso_fillTexture )
2010 XOBitmap aXBmp( aBmp, XBITMAP_STRETCH );
2011 rSet.Put( XFillBmpTileItem( sal_True ) );
2012 rSet.Put( XFillBitmapItem( String(), aXBmp ) );
2013 rSet.Put( XFillBmpSizeXItem( GetPropertyValue( DFF_Prop_fillWidth, 0 ) / 360 ) );
2014 rSet.Put( XFillBmpSizeYItem( GetPropertyValue( DFF_Prop_fillHeight, 0 ) / 360 ) );
2015 rSet.Put( XFillBmpSizeLogItem( sal_True ) );
2017 else
2019 XOBitmap aXBmp( aBmp, XBITMAP_STRETCH );
2020 rSet.Put( XFillBitmapItem( String(), aXBmp ) );
2021 rSet.Put( XFillBmpTileItem( sal_False ) );
2027 else
2028 rSet.Put( XFillStyleItem( XFILL_NONE ) );
2031 void DffPropertyReader::ApplyCustomShapeTextAttributes( SfxItemSet& rSet ) const
2033 // sal_uInt32 nTextFlags = aTextObj.GetTextFlags();
2034 sal_Bool bVerticalText = sal_False;
2035 sal_Int32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 25 * 3600 ) / 360; // 0.25 cm (emu)
2036 sal_Int32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 25 * 3600 ) / 360; // 0.25 cm (emu)
2037 sal_Int32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 13 * 3600 ) / 360; // 0.13 cm (emu)
2038 sal_Int32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 13 * 3600 ) /360; // 0.13 cm (emu)
2040 SdrTextVertAdjust eTVA;
2041 SdrTextHorzAdjust eTHA;
2043 if ( IsProperty( DFF_Prop_txflTextFlow ) )
2045 MSO_TextFlow eTextFlow = (MSO_TextFlow)( GetPropertyValue( DFF_Prop_txflTextFlow ) & 0xFFFF );
2046 switch( eTextFlow )
2048 case mso_txflTtoBA : /* #68110# */ // Top to Bottom @-font, oben -> unten
2049 case mso_txflTtoBN : // Top to Bottom non-@, oben -> unten
2050 case mso_txflVertN : // Vertical, non-@, oben -> unten
2051 bVerticalText = sal_True; // nTextRotationAngle += 27000;
2052 break;
2053 default: break;
2056 sal_Int32 nFontDirection = GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 );
2057 if ( ( nFontDirection == 1 ) || ( nFontDirection == 3 ) )
2058 bVerticalText = !bVerticalText;
2060 if ( bVerticalText )
2062 eTVA = SDRTEXTVERTADJUST_BLOCK;
2063 eTHA = SDRTEXTHORZADJUST_CENTER;
2065 // Textverankerung lesen
2066 MSO_Anchor eTextAnchor = (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
2068 switch( eTextAnchor )
2070 case mso_anchorTop:
2071 case mso_anchorTopCentered:
2072 case mso_anchorTopBaseline:
2073 case mso_anchorTopCenteredBaseline:
2074 eTHA = SDRTEXTHORZADJUST_RIGHT;
2075 break;
2077 case mso_anchorMiddle :
2078 case mso_anchorMiddleCentered:
2079 eTHA = SDRTEXTHORZADJUST_CENTER;
2080 break;
2082 case mso_anchorBottom:
2083 case mso_anchorBottomCentered:
2084 case mso_anchorBottomBaseline:
2085 case mso_anchorBottomCenteredBaseline:
2086 eTHA = SDRTEXTHORZADJUST_LEFT;
2087 break;
2089 // if there is a 100% use of following attributes, the textbox can been aligned also in vertical direction
2090 switch ( eTextAnchor )
2092 case mso_anchorTopCentered :
2093 case mso_anchorMiddleCentered :
2094 case mso_anchorBottomCentered :
2095 case mso_anchorTopCenteredBaseline:
2096 case mso_anchorBottomCenteredBaseline:
2097 eTVA = SDRTEXTVERTADJUST_CENTER;
2098 break;
2100 default :
2101 eTVA = SDRTEXTVERTADJUST_TOP;
2102 break;
2105 else
2107 eTVA = SDRTEXTVERTADJUST_CENTER;
2108 eTHA = SDRTEXTHORZADJUST_BLOCK;
2110 // Textverankerung lesen
2111 MSO_Anchor eTextAnchor = (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
2113 switch( eTextAnchor )
2115 case mso_anchorTop:
2116 case mso_anchorTopCentered:
2117 case mso_anchorTopBaseline:
2118 case mso_anchorTopCenteredBaseline:
2119 eTVA = SDRTEXTVERTADJUST_TOP;
2120 break;
2122 case mso_anchorMiddle :
2123 case mso_anchorMiddleCentered:
2124 eTVA = SDRTEXTVERTADJUST_CENTER;
2125 break;
2127 case mso_anchorBottom:
2128 case mso_anchorBottomCentered:
2129 case mso_anchorBottomBaseline:
2130 case mso_anchorBottomCenteredBaseline:
2131 eTVA = SDRTEXTVERTADJUST_BOTTOM;
2132 break;
2134 // if there is a 100% usage of following attributes, the textbox can be aligned also in horizontal direction
2135 switch ( eTextAnchor )
2137 case mso_anchorTopCentered :
2138 case mso_anchorMiddleCentered :
2139 case mso_anchorBottomCentered :
2140 case mso_anchorTopCenteredBaseline:
2141 case mso_anchorBottomCenteredBaseline:
2142 eTHA = SDRTEXTHORZADJUST_CENTER; // the text has to be displayed using the full width;
2143 break;
2145 default :
2146 eTHA = SDRTEXTHORZADJUST_LEFT;
2147 break;
2150 rSet.Put( SvxFrameDirectionItem( bVerticalText ? FRMDIR_VERT_TOP_RIGHT : FRMDIR_HORI_LEFT_TOP, EE_PARA_WRITINGDIR ) );
2152 rSet.Put( SdrTextVertAdjustItem( eTVA ) );
2153 rSet.Put( SdrTextHorzAdjustItem( eTHA ) );
2155 rSet.Put( SdrTextLeftDistItem( nTextLeft ) );
2156 rSet.Put( SdrTextRightDistItem( nTextRight ) );
2157 rSet.Put( SdrTextUpperDistItem( nTextTop ) );
2158 rSet.Put( SdrTextLowerDistItem( nTextBottom ) );
2160 rSet.Put( SdrTextWordWrapItem( (MSO_WrapMode)GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) != mso_wrapNone ? sal_True : sal_False ) );
2161 rSet.Put( SdrTextAutoGrowHeightItem( ( GetPropertyValue( DFF_Prop_FitTextToShape ) & 2 ) != 0 ) );
2163 // rSet.Put( SdrTextAutoGrowWidthItem( (MSO_WrapMode)GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) != mso_wrapNone ? sal_False : sal_True ) );
2164 // rSet.Put( SdrTextAutoGrowHeightItem( ( GetPropertyValue( DFF_Prop_FitTextToShape ) & 2 ) != 0 ) );
2167 void DffPropertyReader::ApplyCustomShapeGeometryAttributes( SvStream& rIn, SfxItemSet& rSet, const DffObjData& rObjData ) const
2170 sal_uInt32 nAdjustmentsWhichNeedsToBeConverted = 0;
2172 ///////////////////////////////////////
2173 // creating SdrCustomShapeGeometryItem //
2174 ///////////////////////////////////////
2175 typedef uno::Sequence< beans::PropertyValue > PropSeq;
2176 typedef std::vector< beans::PropertyValue > PropVec;
2177 typedef PropVec::iterator PropVecIter;
2178 PropVecIter aIter;
2179 PropVecIter aEnd;
2182 // aPropVec will be filled with all PropertyValues
2183 PropVec aPropVec;
2184 PropertyValue aProp;
2186 /////////////////////////////////////////////////////////////////////
2187 // "Type" property, including the predefined CustomShape type name //
2188 /////////////////////////////////////////////////////////////////////
2189 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
2190 aProp.Name = sType;
2191 aProp.Value <<= EnhancedCustomShapeTypeNames::Get( rObjData.eShapeType );
2192 aPropVec.push_back( aProp );
2195 /////////////////
2196 // "MirroredX" //
2197 /////////////////
2198 if ( nShapeFlags & SP_FFLIPH )
2200 const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
2201 sal_Bool bMirroredX = sal_True;
2202 aProp.Name = sMirroredX;
2203 aProp.Value <<= bMirroredX;
2204 aPropVec.push_back( aProp );
2206 /////////////////
2207 // "MirroredY" //
2208 /////////////////
2209 if ( nShapeFlags & SP_FFLIPV )
2211 const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
2212 sal_Bool bMirroredY = sal_True;
2213 aProp.Name = sMirroredY;
2214 aProp.Value <<= bMirroredY;
2215 aPropVec.push_back( aProp );
2218 ///////////////
2219 // "ViewBox" //
2220 ///////////////
2222 sal_Int32 nCoordWidth = 21600; // needed to replace handle type center with absolute value
2223 sal_Int32 nCoordHeight= 21600;
2224 if ( IsProperty( DFF_Prop_geoLeft ) || IsProperty( DFF_Prop_geoTop ) || IsProperty( DFF_Prop_geoRight ) || IsProperty( DFF_Prop_geoBottom ) )
2226 com::sun::star::awt::Rectangle aViewBox;
2227 const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
2228 aViewBox.X = GetPropertyValue( DFF_Prop_geoLeft, 0 );
2229 aViewBox.Y = GetPropertyValue( DFF_Prop_geoTop, 0 );
2230 aViewBox.Width = nCoordWidth = ((sal_Int32)GetPropertyValue( DFF_Prop_geoRight, 21600 ) ) - aViewBox.X;
2231 aViewBox.Height = nCoordHeight = ((sal_Int32)GetPropertyValue( DFF_Prop_geoBottom, 21600 ) ) - aViewBox.Y;
2232 aProp.Name = sViewBox;
2233 aProp.Value <<= aViewBox;
2234 aPropVec.push_back( aProp );
2236 /////////////////////
2237 // TextRotateAngle //
2238 /////////////////////
2239 if ( IsProperty( DFF_Prop_txflTextFlow ) || IsProperty( DFF_Prop_cdirFont ) )
2241 sal_Int32 nTextRotateAngle = 0;
2242 MSO_TextFlow eTextFlow = (MSO_TextFlow)( GetPropertyValue( DFF_Prop_txflTextFlow ) & 0xFFFF );
2243 /* sal_Int32 nFontDirection = GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 ); */
2245 if ( eTextFlow == mso_txflBtoT ) // Bottom to Top non-@, unten -> oben
2246 nTextRotateAngle += 90;
2247 switch( GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 ) ) // SJ: mso_cdir90 and mso_cdir270 will be simulated by
2248 { // activating vertical writing for the text objects
2249 case mso_cdir90 :
2251 if ( eTextFlow == mso_txflTtoBA )
2252 nTextRotateAngle -= 180;
2254 break;
2255 case mso_cdir180: nTextRotateAngle -= 180; break;
2256 case mso_cdir270:
2258 if ( eTextFlow != mso_txflTtoBA )
2259 nTextRotateAngle -= 180;
2261 break;
2262 default: break;
2264 if ( nTextRotateAngle )
2266 double fTextRotateAngle = nTextRotateAngle;
2267 const rtl::OUString sTextRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) );
2268 aProp.Name = sTextRotateAngle;
2269 aProp.Value <<= fTextRotateAngle;
2270 aPropVec.push_back( aProp );
2273 //////////////////////////////////////////
2274 // "Extrusion" PropertySequence element //
2275 //////////////////////////////////////////
2276 sal_Bool bExtrusionOn = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 8 ) != 0;
2277 if ( bExtrusionOn )
2279 PropVec aExtrusionPropVec;
2281 // "Extrusion"
2282 const rtl::OUString sExtrusionOn( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
2283 aProp.Name = sExtrusionOn;
2284 aProp.Value <<= bExtrusionOn;
2285 aExtrusionPropVec.push_back( aProp );
2287 // "Brightness"
2288 if ( IsProperty( DFF_Prop_c3DAmbientIntensity ) )
2290 const rtl::OUString sExtrusionBrightness( RTL_CONSTASCII_USTRINGPARAM ( "Brightness" ) );
2291 double fBrightness = (sal_Int32)GetPropertyValue( DFF_Prop_c3DAmbientIntensity );
2292 fBrightness /= 655.36;
2293 aProp.Name = sExtrusionBrightness;
2294 aProp.Value <<= fBrightness;
2295 aExtrusionPropVec.push_back( aProp );
2297 // "Depth" in 1/100mm
2298 if ( IsProperty( DFF_Prop_c3DExtrudeBackward ) || IsProperty( DFF_Prop_c3DExtrudeForward ) )
2300 const rtl::OUString sDepth( RTL_CONSTASCII_USTRINGPARAM ( "Depth" ) );
2301 double fBackDepth = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DExtrudeBackward, 1270 * 360 )) / 360.0;
2302 double fForeDepth = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DExtrudeForward ), 0 ) / 360.0;
2303 double fDepth = fBackDepth + fForeDepth;
2304 double fFraction = fDepth != 0.0 ? fForeDepth / fDepth : 0;
2305 EnhancedCustomShapeParameterPair aDepthParaPair;
2306 aDepthParaPair.First.Value <<= fDepth;
2307 aDepthParaPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
2308 aDepthParaPair.Second.Value <<= fFraction;
2309 aDepthParaPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
2310 aProp.Name = sDepth;
2311 aProp.Value <<= aDepthParaPair;
2312 aExtrusionPropVec.push_back( aProp );
2314 // "Diffusion"
2315 if ( IsProperty( DFF_Prop_c3DDiffuseAmt ) )
2317 const rtl::OUString sExtrusionDiffusion( RTL_CONSTASCII_USTRINGPARAM ( "Diffusion" ) );
2318 double fDiffusion = (sal_Int32)GetPropertyValue( DFF_Prop_c3DDiffuseAmt );
2319 fDiffusion /= 655.36;
2320 aProp.Name = sExtrusionDiffusion;
2321 aProp.Value <<= fDiffusion;
2322 aExtrusionPropVec.push_back( aProp );
2324 // "NumberOfLineSegments"
2325 if ( IsProperty( DFF_Prop_c3DTolerance ) )
2327 const rtl::OUString sExtrusionNumberOfLineSegments( RTL_CONSTASCII_USTRINGPARAM ( "NumberOfLineSegments" ) );
2328 aProp.Name = sExtrusionNumberOfLineSegments;
2329 aProp.Value <<= (sal_Int32)GetPropertyValue( DFF_Prop_c3DTolerance );
2330 aExtrusionPropVec.push_back( aProp );
2332 // "LightFace"
2333 const rtl::OUString sExtrusionLightFace( RTL_CONSTASCII_USTRINGPARAM ( "LightFace" ) );
2334 sal_Bool bExtrusionLightFace = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 1 ) != 0;
2335 aProp.Name = sExtrusionLightFace;
2336 aProp.Value <<= bExtrusionLightFace;
2337 aExtrusionPropVec.push_back( aProp );
2338 // "FirstLightHarsh"
2339 const rtl::OUString sExtrusionFirstLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightHarsh" ) );
2340 sal_Bool bExtrusionFirstLightHarsh = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 2 ) != 0;
2341 aProp.Name = sExtrusionFirstLightHarsh;
2342 aProp.Value <<= bExtrusionFirstLightHarsh;
2343 aExtrusionPropVec.push_back( aProp );
2344 // "SecondLightHarsh"
2345 const rtl::OUString sExtrusionSecondLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightHarsh" ) );
2346 sal_Bool bExtrusionSecondLightHarsh = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 1 ) != 0;
2347 aProp.Name = sExtrusionSecondLightHarsh;
2348 aProp.Value <<= bExtrusionSecondLightHarsh;
2349 aExtrusionPropVec.push_back( aProp );
2350 // "FirstLightLevel"
2351 if ( IsProperty( DFF_Prop_c3DKeyIntensity ) )
2353 const rtl::OUString sExtrusionFirstLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightLevel" ) );
2354 double fFirstLightLevel = (sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyIntensity );
2355 fFirstLightLevel /= 655.36;
2356 aProp.Name = sExtrusionFirstLightLevel;
2357 aProp.Value <<= fFirstLightLevel;
2358 aExtrusionPropVec.push_back( aProp );
2360 // "SecondLightLevel"
2361 if ( IsProperty( DFF_Prop_c3DFillIntensity ) )
2363 const rtl::OUString sExtrusionSecondLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightLevel" ) );
2364 double fSecondLightLevel = (sal_Int32)GetPropertyValue( DFF_Prop_c3DFillIntensity );
2365 fSecondLightLevel /= 655.36;
2366 aProp.Name = sExtrusionSecondLightLevel;
2367 aProp.Value <<= fSecondLightLevel;
2368 aExtrusionPropVec.push_back( aProp );
2370 // "FirtstLightDirection"
2371 if ( IsProperty( DFF_Prop_c3DKeyX ) || IsProperty( DFF_Prop_c3DKeyY ) || IsProperty( DFF_Prop_c3DKeyZ ) )
2373 double fLightX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyX, 50000 ));
2374 double fLightY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyY, 0 ));
2375 double fLightZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyZ, 10000 ));
2376 ::com::sun::star::drawing::Direction3D aExtrusionFirstLightDirection( fLightX, fLightY, fLightZ );
2377 const rtl::OUString sExtrusionFirstLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightDirection" ) );
2378 aProp.Name = sExtrusionFirstLightDirection;
2379 aProp.Value <<= aExtrusionFirstLightDirection;
2380 aExtrusionPropVec.push_back( aProp );
2382 // "SecondLightDirection"
2383 if ( IsProperty( DFF_Prop_c3DFillX ) || IsProperty( DFF_Prop_c3DFillY ) || IsProperty( DFF_Prop_c3DFillZ ) )
2385 double fLight2X = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillX, (sal_uInt32)-50000 ));
2386 double fLight2Y = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillY, 0 ));
2387 double fLight2Z = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillZ, 10000 ));
2388 ::com::sun::star::drawing::Direction3D aExtrusionSecondLightDirection( fLight2X, fLight2Y, fLight2Z );
2389 const rtl::OUString sExtrusionSecondLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightDirection" ) );
2390 aProp.Name = sExtrusionSecondLightDirection;
2391 aProp.Value <<= aExtrusionSecondLightDirection;
2392 aExtrusionPropVec.push_back( aProp );
2395 /* LockRotationCenter, OrientationAngle and Orientation needs to be converted to use the properties AngleX, AngleY and RotationAngle instead.
2396 // "LockRotationCenter"
2397 const rtl::OUString sExtrusionLockRotationCenter( RTL_CONSTASCII_USTRINGPARAM ( "LockRotationCenter" ) );
2398 sal_Bool bExtrusionLockRotationCenter = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 16 ) != 0;
2399 aProp.Name = sExtrusionLockRotationCenter;
2400 aProp.Value <<= bExtrusionLockRotationCenter;
2401 aExtrusionPropVec.push_back( aProp );
2403 // "Orientation"
2404 if ( IsProperty( DFF_Prop_c3DRotationAxisX ) || IsProperty( DFF_Prop_c3DRotationAxisY ) || IsProperty( DFF_Prop_c3DRotationAxisZ ) )
2406 double fRotX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisX, 100 ));
2407 double fRotY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisY, 0 ));
2408 double fRotZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisZ, 0 ));
2409 ::com::sun::star::drawing::Direction3D aExtrusionDirection( fRotX, fRotY, fRotZ );
2410 const rtl::OUString sExtrusionDirection( RTL_CONSTASCII_USTRINGPARAM ( "Orientation" ) );
2411 aProp.Name = sExtrusionDirection;
2412 aProp.Value <<= aExtrusionDirection;
2413 aExtrusionPropVec.push_back( aProp );
2415 // "OrientationAngle" in Grad
2416 if ( IsProperty( DFF_Prop_c3DRotationAngle ) )
2418 const rtl::OUString sExtrusionOrientationAngle( RTL_CONSTASCII_USTRINGPARAM ( "OrientationAngle" ) );
2419 double fOrientationAngle = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAngle )) / 65536.0;
2420 aProp.Name = sExtrusionOrientationAngle;
2421 aProp.Value <<= fOrientationAngle;
2422 aExtrusionPropVec.push_back( aProp );
2426 // "Metal"
2427 const rtl::OUString sExtrusionMetal( RTL_CONSTASCII_USTRINGPARAM ( "Metal" ) );
2428 sal_Bool bExtrusionMetal = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 4 ) != 0;
2429 aProp.Name = sExtrusionMetal;
2430 aProp.Value <<= bExtrusionMetal;
2431 aExtrusionPropVec.push_back( aProp );
2432 // if ( IsProperty( DFF_Prop_c3DExtrudePlane ) )
2433 // {
2434 // UPS
2435 // }
2436 // "ShadeMode"
2437 if ( IsProperty( DFF_Prop_c3DRenderMode ) )
2439 const rtl::OUString sExtrusionShadeMode( RTL_CONSTASCII_USTRINGPARAM ( "ShadeMode" ) );
2440 sal_uInt32 nExtrusionRenderMode = GetPropertyValue( DFF_Prop_c3DRenderMode );
2441 com::sun::star::drawing::ShadeMode eExtrusionShadeMode( com::sun::star::drawing::ShadeMode_FLAT );
2442 if ( nExtrusionRenderMode == mso_Wireframe )
2443 eExtrusionShadeMode = com::sun::star::drawing::ShadeMode_DRAFT;
2445 aProp.Name = sExtrusionShadeMode;
2446 aProp.Value <<= eExtrusionShadeMode;
2447 aExtrusionPropVec.push_back( aProp );
2449 // "RotateAngle" in Grad
2450 if ( IsProperty( DFF_Prop_c3DXRotationAngle ) || IsProperty( DFF_Prop_c3DYRotationAngle ) )
2452 const rtl::OUString sExtrusionAngle( RTL_CONSTASCII_USTRINGPARAM ( "RotateAngle" ) );
2453 double fAngleX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DXRotationAngle, 0 )) / 65536.0;
2454 double fAngleY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DYRotationAngle, 0 )) / 65536.0;
2455 EnhancedCustomShapeParameterPair aRotateAnglePair;
2456 aRotateAnglePair.First.Value <<= fAngleX;
2457 aRotateAnglePair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
2458 aRotateAnglePair.Second.Value <<= fAngleY;
2459 aRotateAnglePair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
2460 aProp.Name = sExtrusionAngle;
2461 aProp.Value <<= aRotateAnglePair;
2462 aExtrusionPropVec.push_back( aProp );
2465 // "AutoRotationCenter"
2466 if ( ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 8 ) == 0 )
2468 // "RotationCenter"
2469 if ( IsProperty( DFF_Prop_c3DRotationCenterX ) || IsProperty( DFF_Prop_c3DRotationCenterY ) || IsProperty( DFF_Prop_c3DRotationCenterZ ) )
2471 ::com::sun::star::drawing::Direction3D aRotationCenter(
2472 (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterX, 0 )) / 360.0,
2473 (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterY, 0 )) / 360.0,
2474 (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterZ, 0 )) / 360.0 );
2476 const rtl::OUString sExtrusionRotationCenter( RTL_CONSTASCII_USTRINGPARAM ( "RotationCenter" ) );
2477 aProp.Name = sExtrusionRotationCenter;
2478 aProp.Value <<= aRotationCenter;
2479 aExtrusionPropVec.push_back( aProp );
2482 // "Shininess"
2483 if ( IsProperty( DFF_Prop_c3DShininess ) )
2485 const rtl::OUString sExtrusionShininess( RTL_CONSTASCII_USTRINGPARAM ( "Shininess" ) );
2486 double fShininess = (sal_Int32)GetPropertyValue( DFF_Prop_c3DShininess );
2487 fShininess /= 655.36;
2488 aProp.Name = sExtrusionShininess;
2489 aProp.Value <<= fShininess;
2490 aExtrusionPropVec.push_back( aProp );
2492 // "Skew"
2493 if ( IsProperty( DFF_Prop_c3DSkewAmount ) || IsProperty( DFF_Prop_c3DSkewAngle ) )
2495 const rtl::OUString sExtrusionSkew( RTL_CONSTASCII_USTRINGPARAM ( "Skew" ) );
2496 double fSkewAmount = (sal_Int32)GetPropertyValue( DFF_Prop_c3DSkewAmount, 50 );
2497 double fSkewAngle = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DSkewAngle, sal::static_int_cast< UINT32 >(-135 * 65536) )) / 65536.0;
2499 EnhancedCustomShapeParameterPair aSkewPair;
2500 aSkewPair.First.Value <<= fSkewAmount;
2501 aSkewPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
2502 aSkewPair.Second.Value <<= fSkewAngle;
2503 aSkewPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
2504 aProp.Name = sExtrusionSkew;
2505 aProp.Value <<= aSkewPair;
2506 aExtrusionPropVec.push_back( aProp );
2508 // "Specularity"
2509 if ( IsProperty( DFF_Prop_c3DSpecularAmt ) )
2511 const rtl::OUString sExtrusionSpecularity( RTL_CONSTASCII_USTRINGPARAM ( "Specularity" ) );
2512 double fSpecularity = (sal_Int32)GetPropertyValue( DFF_Prop_c3DSpecularAmt );
2513 fSpecularity /= 1333;
2514 aProp.Name = sExtrusionSpecularity;
2515 aProp.Value <<= fSpecularity;
2516 aExtrusionPropVec.push_back( aProp );
2518 // "ProjectionMode"
2519 const rtl::OUString sExtrusionProjectionMode( RTL_CONSTASCII_USTRINGPARAM ( "ProjectionMode" ) );
2520 ProjectionMode eProjectionMode = GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 4 ? ProjectionMode_PARALLEL : ProjectionMode_PERSPECTIVE;
2521 aProp.Name = sExtrusionProjectionMode;
2522 aProp.Value <<= eProjectionMode;
2523 aExtrusionPropVec.push_back( aProp );
2525 // "ViewPoint" in 1/100mm
2526 if ( IsProperty( DFF_Prop_c3DXViewpoint ) || IsProperty( DFF_Prop_c3DYViewpoint ) || IsProperty( DFF_Prop_c3DZViewpoint ) )
2528 double fViewX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DXViewpoint, 1249920 )) / 360.0;
2529 double fViewY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DYViewpoint, (sal_uInt32)-1249920 ))/ 360.0;
2530 double fViewZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DZViewpoint, 9000000 )) / 360.0;
2531 ::com::sun::star::drawing::Position3D aExtrusionViewPoint( fViewX, fViewY, fViewZ );
2532 const rtl::OUString sExtrusionViewPoint( RTL_CONSTASCII_USTRINGPARAM ( "ViewPoint" ) );
2533 aProp.Name = sExtrusionViewPoint;
2534 aProp.Value <<= aExtrusionViewPoint;
2535 aExtrusionPropVec.push_back( aProp );
2537 // "Origin"
2538 if ( IsProperty( DFF_Prop_c3DOriginX ) || IsProperty( DFF_Prop_c3DOriginY ) )
2540 const rtl::OUString sExtrusionOrigin( RTL_CONSTASCII_USTRINGPARAM ( "Origin" ) );
2541 double fOriginX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DOriginX, 0 ));
2542 double fOriginY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DOriginY, 0 ));
2543 fOriginX /= 65536;
2544 fOriginY /= 65536;
2545 EnhancedCustomShapeParameterPair aOriginPair;
2546 aOriginPair.First.Value <<= fOriginX;
2547 aOriginPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
2548 aOriginPair.Second.Value <<= fOriginY;
2549 aOriginPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
2550 aProp.Name = sExtrusionOrigin;
2551 aProp.Value <<= aOriginPair;
2552 aExtrusionPropVec.push_back( aProp );
2554 // "ExtrusionColor"
2555 const rtl::OUString sExtrusionColor( RTL_CONSTASCII_USTRINGPARAM ( "Color" ) );
2556 sal_Bool bExtrusionColor = IsProperty( DFF_Prop_c3DExtrusionColor ); // ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 2 ) != 0;
2557 aProp.Name = sExtrusionColor;
2558 aProp.Value <<= bExtrusionColor;
2559 aExtrusionPropVec.push_back( aProp );
2560 if ( IsProperty( DFF_Prop_c3DExtrusionColor ) )
2561 rSet.Put( XSecondaryFillColorItem( String(), rManager.MSO_CLR_ToColor(
2562 GetPropertyValue( DFF_Prop_c3DExtrusionColor ), DFF_Prop_c3DExtrusionColor ) ) );
2563 // pushing the whole Extrusion element
2564 const rtl::OUString sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
2565 PropSeq aExtrusionPropSeq( aExtrusionPropVec.size() );
2566 aIter = aExtrusionPropVec.begin();
2567 aEnd = aExtrusionPropVec.end();
2568 beans::PropertyValue* pExtrusionValues = aExtrusionPropSeq.getArray();
2569 while ( aIter != aEnd )
2570 *pExtrusionValues++ = *aIter++;
2571 aProp.Name = sExtrusion;
2572 aProp.Value <<= aExtrusionPropSeq;
2573 aPropVec.push_back( aProp );
2576 /////////////////////////////////////////
2577 // "Equations" PropertySequence element //
2578 /////////////////////////////////////////
2579 if ( IsProperty( DFF_Prop_pFormulas ) )
2581 sal_uInt16 i;
2582 sal_uInt16 nNumElem = 0;
2583 sal_uInt16 nNumElemMem = 0;
2584 sal_uInt16 nElemSize = 8;
2586 if ( SeekToContent( DFF_Prop_pFormulas, rIn ) )
2587 rIn >> nNumElem >> nNumElemMem >> nElemSize;
2589 sal_Int16 nP1, nP2, nP3;
2590 sal_uInt16 nFlags;
2592 uno::Sequence< rtl::OUString > aEquations( nNumElem );
2593 for ( i = 0; i < nNumElem; i++ )
2595 rIn >> nFlags >> nP1 >> nP2 >> nP3;
2596 aEquations[ i ] = EnhancedCustomShape2d::GetEquation( nFlags, nP1, nP2, nP3 );
2598 // pushing the whole Equations element
2599 const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM ( "Equations" ) );
2600 aProp.Name = sEquations;
2601 aProp.Value <<= aEquations;
2602 aPropVec.push_back( aProp );
2605 ////////////////////////////////////////
2606 // "Handles" PropertySequence element //
2607 ////////////////////////////////////////
2608 if ( IsProperty( DFF_Prop_Handles ) )
2610 sal_uInt16 i;
2611 sal_uInt16 nNumElem = 0;
2612 sal_uInt16 nNumElemMem = 0;
2613 sal_uInt16 nElemSize = 36;
2615 if ( SeekToContent( DFF_Prop_Handles, rIn ) )
2616 rIn >> nNumElem >> nNumElemMem >> nElemSize;
2617 if ( nElemSize == 36 )
2619 uno::Sequence< beans::PropertyValues > aHandles( nNumElem );
2620 for ( i = 0; i < nNumElem; i++ )
2622 PropVec aHandlePropVec;
2623 sal_uInt32 nFlags;
2624 sal_Int32 nPositionX, nPositionY, nCenterX, nCenterY, nRangeXMin, nRangeXMax, nRangeYMin, nRangeYMax;
2625 rIn >> nFlags
2626 >> nPositionX
2627 >> nPositionY
2628 >> nCenterX
2629 >> nCenterY
2630 >> nRangeXMin
2631 >> nRangeXMax
2632 >> nRangeYMin
2633 >> nRangeYMax;
2635 if ( nPositionX == 2 ) // replacing center position with absolute value
2636 nPositionX = nCoordWidth / 2;
2637 if ( nPositionY == 2 )
2638 nPositionY = nCoordHeight / 2;
2639 EnhancedCustomShapeParameterPair aPosition;
2640 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.First, nPositionX, sal_True, sal_True );
2641 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.Second, nPositionY, sal_True, sal_False );
2642 const rtl::OUString sHandlePosition( RTL_CONSTASCII_USTRINGPARAM ( "Position" ) );
2643 aProp.Name = sHandlePosition;
2644 aProp.Value <<= aPosition;
2645 aHandlePropVec.push_back( aProp );
2647 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
2649 sal_Bool bMirroredX = sal_True;
2650 const rtl::OUString sHandleMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
2651 aProp.Name = sHandleMirroredX;
2652 aProp.Value <<= bMirroredX;
2653 aHandlePropVec.push_back( aProp );
2655 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
2657 sal_Bool bMirroredY = sal_True;
2658 const rtl::OUString sHandleMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
2659 aProp.Name = sHandleMirroredY;
2660 aProp.Value <<= bMirroredY;
2661 aHandlePropVec.push_back( aProp );
2663 if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
2665 sal_Bool bSwitched = sal_True;
2666 const rtl::OUString sHandleSwitched( RTL_CONSTASCII_USTRINGPARAM ( "Switched" ) );
2667 aProp.Name = sHandleSwitched;
2668 aProp.Value <<= bSwitched;
2669 aHandlePropVec.push_back( aProp );
2671 if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
2673 if ( nCenterX == 2 )
2674 nCenterX = nCoordWidth / 2;
2675 if ( nCenterY == 2 )
2676 nCenterY = nCoordHeight / 2;
2677 if ( ( nPositionY >= 0x256 ) || ( nPositionY <= 0x107 ) ) // position y
2678 nAdjustmentsWhichNeedsToBeConverted |= ( 1 << i );
2679 EnhancedCustomShapeParameterPair aPolar;
2680 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPolar.First, nCenterX, ( nFlags & 0x800 ) != 0, sal_True );
2681 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPolar.Second, nCenterY, ( nFlags & 0x1000 ) != 0, sal_False );
2682 const rtl::OUString sHandlePolar( RTL_CONSTASCII_USTRINGPARAM ( "Polar" ) );
2683 aProp.Name = sHandlePolar;
2684 aProp.Value <<= aPolar;
2685 aHandlePropVec.push_back( aProp );
2687 if ( nFlags & MSDFF_HANDLE_FLAGS_MAP )
2689 if ( nCenterX == 2 )
2690 nCenterX = nCoordWidth / 2;
2691 if ( nCenterY == 2 )
2692 nCenterY = nCoordHeight / 2;
2693 EnhancedCustomShapeParameterPair aMap;
2694 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aMap.First, nCenterX, ( nFlags & 0x800 ) != 0, sal_True );
2695 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aMap.Second, nCenterY, ( nFlags & 0x1000 ) != 0, sal_False );
2696 const rtl::OUString sHandleMap( RTL_CONSTASCII_USTRINGPARAM ( "Map" ) );
2697 aProp.Name = sHandleMap;
2698 aProp.Value <<= aMap;
2699 aHandlePropVec.push_back( aProp );
2701 if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
2703 if ( (sal_uInt32)nRangeXMin != 0x80000000 )
2705 if ( nRangeXMin == 2 )
2706 nRangeXMin = nCoordWidth / 2;
2707 EnhancedCustomShapeParameter aRangeXMinimum;
2708 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMinimum, nRangeXMin,
2709 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
2710 const rtl::OUString sHandleRangeXMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMinimum" ) );
2711 aProp.Name = sHandleRangeXMinimum;
2712 aProp.Value <<= aRangeXMinimum;
2713 aHandlePropVec.push_back( aProp );
2715 if ( (sal_uInt32)nRangeXMax != 0x7fffffff )
2717 if ( nRangeXMax == 2 )
2718 nRangeXMax = nCoordWidth / 2;
2719 EnhancedCustomShapeParameter aRangeXMaximum;
2720 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMaximum, nRangeXMax,
2721 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
2722 const rtl::OUString sHandleRangeXMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMaximum" ) );
2723 aProp.Name = sHandleRangeXMaximum;
2724 aProp.Value <<= aRangeXMaximum;
2725 aHandlePropVec.push_back( aProp );
2727 if ( (sal_uInt32)nRangeYMin != 0x80000000 )
2729 if ( nRangeYMin == 2 )
2730 nRangeYMin = nCoordHeight / 2;
2731 EnhancedCustomShapeParameter aRangeYMinimum;
2732 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMinimum, nRangeYMin,
2733 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MIN_IS_SPECIAL ) != 0, sal_True );
2734 const rtl::OUString sHandleRangeYMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMinimum" ) );
2735 aProp.Name = sHandleRangeYMinimum;
2736 aProp.Value <<= aRangeYMinimum;
2737 aHandlePropVec.push_back( aProp );
2739 if ( (sal_uInt32)nRangeYMax != 0x7fffffff )
2741 if ( nRangeYMax == 2 )
2742 nRangeYMax = nCoordHeight / 2;
2743 EnhancedCustomShapeParameter aRangeYMaximum;
2744 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMaximum, nRangeYMax,
2745 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MAX_IS_SPECIAL ) != 0, sal_False );
2746 const rtl::OUString sHandleRangeYMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMaximum" ) );
2747 aProp.Name = sHandleRangeYMaximum;
2748 aProp.Value <<= aRangeYMaximum;
2749 aHandlePropVec.push_back( aProp );
2752 if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
2754 if ( (sal_uInt32)nRangeXMin != 0x7fffffff )
2756 if ( nRangeXMin == 2 )
2757 nRangeXMin = nCoordWidth / 2;
2758 EnhancedCustomShapeParameter aRadiusRangeMinimum;
2759 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMinimum, nRangeXMin,
2760 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
2761 const rtl::OUString sHandleRadiusRangeMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMinimum" ) );
2762 aProp.Name = sHandleRadiusRangeMinimum;
2763 aProp.Value <<= aRadiusRangeMinimum;
2764 aHandlePropVec.push_back( aProp );
2766 if ( (sal_uInt32)nRangeXMax != 0x80000000 )
2768 if ( nRangeXMax == 2 )
2769 nRangeXMax = nCoordWidth / 2;
2770 EnhancedCustomShapeParameter aRadiusRangeMaximum;
2771 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMaximum, nRangeXMax,
2772 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
2773 const rtl::OUString sHandleRadiusRangeMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMaximum" ) );
2774 aProp.Name = sHandleRadiusRangeMaximum;
2775 aProp.Value <<= aRadiusRangeMaximum;
2776 aHandlePropVec.push_back( aProp );
2779 if ( aHandlePropVec.size() )
2781 PropSeq aHandlePropSeq( aHandlePropVec.size() );
2782 aIter = aHandlePropVec.begin();
2783 aEnd = aHandlePropVec.end();
2784 beans::PropertyValue* pHandleValues = aHandlePropSeq.getArray();
2785 while ( aIter != aEnd )
2786 *pHandleValues++ = *aIter++;
2787 aHandles[ i ] = aHandlePropSeq;
2790 // pushing the whole Handles element
2791 const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM ( "Handles" ) );
2792 aProp.Name = sHandles;
2793 aProp.Value <<= aHandles;
2794 aPropVec.push_back( aProp );
2797 else
2799 const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( rObjData.eShapeType );
2800 if ( pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
2802 sal_Int32 i, nCnt = pDefCustomShape->nHandles;
2803 const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
2804 for ( i = 0; i < nCnt; i++, pData++ )
2806 if ( pData->nFlags & MSDFF_HANDLE_FLAGS_POLAR )
2808 if ( ( pData->nPositionY >= 0x256 ) || ( pData->nPositionY <= 0x107 ) )
2809 nAdjustmentsWhichNeedsToBeConverted |= ( 1 << i );
2814 /////////////////////////////////////
2815 // "Path" PropertySequence element //
2816 /////////////////////////////////////
2818 PropVec aPathPropVec;
2820 // "Path/ExtrusionAllowed"
2821 if ( IsHardAttribute( DFF_Prop_f3DOK ) )
2823 const rtl::OUString sExtrusionAllowed( RTL_CONSTASCII_USTRINGPARAM ( "ExtrusionAllowed" ) );
2824 sal_Bool bExtrusionAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 16 ) != 0;
2825 aProp.Name = sExtrusionAllowed;
2826 aProp.Value <<= bExtrusionAllowed;
2827 aPathPropVec.push_back( aProp );
2829 // "Path/ConcentricGradientFillAllowed"
2830 if ( IsHardAttribute( DFF_Prop_fFillShadeShapeOK ) )
2832 const rtl::OUString sConcentricGradientFillAllowed( RTL_CONSTASCII_USTRINGPARAM ( "ConcentricGradientFillAllowed" ) );
2833 sal_Bool bConcentricGradientFillAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 2 ) != 0;
2834 aProp.Name = sConcentricGradientFillAllowed;
2835 aProp.Value <<= bConcentricGradientFillAllowed;
2836 aPathPropVec.push_back( aProp );
2838 // "Path/TextPathAllowed"
2839 if ( IsHardAttribute( DFF_Prop_fGtextOK ) || ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x4000 ) )
2841 const rtl::OUString sTextPathAllowed( RTL_CONSTASCII_USTRINGPARAM ( "TextPathAllowed" ) );
2842 sal_Bool bTextPathAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 4 ) != 0;
2843 aProp.Name = sTextPathAllowed;
2844 aProp.Value <<= bTextPathAllowed;
2845 aPathPropVec.push_back( aProp );
2847 // Path/Coordinates
2848 if ( IsProperty( DFF_Prop_pVertices ) )
2850 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
2852 sal_uInt16 i;
2853 sal_uInt16 nNumElemVert = 0;
2854 sal_uInt16 nNumElemMemVert = 0;
2855 sal_uInt16 nElemSizeVert = 8;
2857 if ( SeekToContent( DFF_Prop_pVertices, rIn ) )
2858 rIn >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
2859 if ( nNumElemVert )
2861 sal_Int32 nX, nY;
2862 sal_Int16 nTmpA, nTmpB;
2863 aCoordinates.realloc( nNumElemVert );
2864 for ( i = 0; i < nNumElemVert; i++ )
2866 if ( nElemSizeVert == 8 )
2868 rIn >> nX
2869 >> nY;
2871 else
2873 rIn >> nTmpA
2874 >> nTmpB;
2876 nX = nTmpA;
2877 nY = nTmpB;
2879 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aCoordinates[ i ].First, nX );
2880 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aCoordinates[ i ].Second, nY );
2883 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
2884 aProp.Name = sCoordinates;
2885 aProp.Value <<= aCoordinates;
2886 aPathPropVec.push_back( aProp );
2888 // Path/Segments
2889 if ( IsProperty( DFF_Prop_pSegmentInfo ) )
2891 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments;
2893 sal_uInt16 i, nTmp;
2894 sal_uInt16 nNumElemSeg = 0;
2895 sal_uInt16 nNumElemMemSeg = 0;
2896 sal_uInt16 nElemSizeSeg = 2;
2898 if ( SeekToContent( DFF_Prop_pSegmentInfo, rIn ) )
2899 rIn >> nNumElemSeg >> nNumElemMemSeg >> nElemSizeSeg;
2900 if ( nNumElemSeg )
2902 sal_Int16 nCommand;
2903 sal_Int16 nCnt;
2904 aSegments.realloc( nNumElemSeg );
2905 for ( i = 0; i < nNumElemSeg; i++ )
2907 rIn >> nTmp;
2908 nCommand = EnhancedCustomShapeSegmentCommand::UNKNOWN;
2909 nCnt = (sal_Int16)( nTmp & 0xfff );
2910 switch( nTmp >> 12 )
2912 case 0x0: nCommand = EnhancedCustomShapeSegmentCommand::LINETO; if ( !nCnt ) nCnt = 1; break;
2913 case 0x1: nCommand = EnhancedCustomShapeSegmentCommand::LINETO; if ( !nCnt ) nCnt = 1; break; // seems to the relative lineto
2914 case 0x4: nCommand = EnhancedCustomShapeSegmentCommand::MOVETO; if ( !nCnt ) nCnt = 1; break;
2915 case 0x2: nCommand = EnhancedCustomShapeSegmentCommand::CURVETO; if ( !nCnt ) nCnt = 1; break;
2916 case 0x3: nCommand = EnhancedCustomShapeSegmentCommand::CURVETO; if ( !nCnt ) nCnt = 1; break; // seems to be the relative curveto
2917 case 0x8: nCommand = EnhancedCustomShapeSegmentCommand::ENDSUBPATH; nCnt = 0; break;
2918 case 0x6: nCommand = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH; nCnt = 0; break;
2919 case 0xa:
2920 case 0xb:
2922 switch ( ( nTmp >> 8 ) & 0xf )
2924 case 0x0:
2926 nCommand = EnhancedCustomShapeSegmentCommand::LINETO;
2927 if ( !nCnt )
2928 nCnt = 1;
2930 break;
2931 case 0x1:
2933 nCommand = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO;
2934 nCnt = ( nTmp & 0xff ) / 3;
2936 break;
2937 case 0x2:
2939 nCommand = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
2940 nCnt = ( nTmp & 0xff ) / 3;
2942 break;
2943 case 0x3:
2945 nCommand = EnhancedCustomShapeSegmentCommand::ARCTO;
2946 nCnt = ( nTmp & 0xff ) >> 2;
2948 break;
2949 case 0x4:
2951 nCommand = EnhancedCustomShapeSegmentCommand::ARC;
2952 nCnt = ( nTmp & 0xff ) >> 2;
2954 break;
2955 case 0x5:
2957 nCommand = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
2958 nCnt = ( nTmp & 0xff ) >> 2;
2960 break;
2961 case 0x6:
2963 nCommand = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
2964 nCnt = ( nTmp & 0xff ) >> 2;
2966 break;
2967 case 0x7:
2969 nCommand = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
2970 nCnt = nTmp & 0xff;
2972 break;
2973 case 0x8:
2975 nCommand = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
2976 nCnt = nTmp & 0xff;
2978 break;
2979 case 0xa: nCommand = EnhancedCustomShapeSegmentCommand::NOFILL; nCnt = 0; break;
2980 case 0xb: nCommand = EnhancedCustomShapeSegmentCommand::NOSTROKE; nCnt = 0; break;
2983 break;
2985 // if the command is unknown, we will store all the data in nCnt, so it will be possible to export without loss
2986 if ( nCommand == EnhancedCustomShapeSegmentCommand::UNKNOWN )
2987 nCnt = (sal_Int16)nTmp;
2988 aSegments[ i ].Command = nCommand;
2989 aSegments[ i ].Count = nCnt;
2992 const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
2993 aProp.Name = sSegments;
2994 aProp.Value <<= aSegments;
2995 aPathPropVec.push_back( aProp );
2997 // Path/StretchX
2998 if ( IsProperty( DFF_Prop_stretchPointX ) )
3000 const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) );
3001 sal_Int32 nStretchX = GetPropertyValue( DFF_Prop_stretchPointX, 0 );
3002 aProp.Name = sStretchX;
3003 aProp.Value <<= nStretchX;
3004 aPathPropVec.push_back( aProp );
3006 // Path/StretchX
3007 if ( IsProperty( DFF_Prop_stretchPointY ) )
3009 const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) );
3010 sal_Int32 nStretchY = GetPropertyValue( DFF_Prop_stretchPointY, 0 );
3011 aProp.Name = sStretchY;
3012 aProp.Value <<= nStretchY;
3013 aPathPropVec.push_back( aProp );
3015 // Path/TextFrames
3016 if ( IsProperty( DFF_Prop_textRectangles ) )
3018 sal_uInt16 i;
3019 sal_uInt16 nNumElem = 0;
3020 sal_uInt16 nNumElemMem = 0;
3021 sal_uInt16 nElemSize = 16;
3023 if ( SeekToContent( DFF_Prop_textRectangles, rIn ) )
3024 rIn >> nNumElem >> nNumElemMem >> nElemSize;
3025 if ( nElemSize == 16 )
3027 sal_Int32 nLeft, nTop, nRight, nBottom;
3028 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrames( nNumElem );
3029 for ( i = 0; i < nNumElem; i++ )
3031 rIn >> nLeft
3032 >> nTop
3033 >> nRight
3034 >> nBottom;
3036 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].TopLeft.First, nLeft );
3037 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].TopLeft.Second, nTop );
3038 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].BottomRight.First, nRight );
3039 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].BottomRight.Second, nBottom);
3041 const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
3042 aProp.Name = sTextFrames;
3043 aProp.Value <<= aTextFrames;
3044 aPathPropVec.push_back( aProp );
3047 //Path/GluePoints
3048 if ( IsProperty( DFF_Prop_connectorPoints ) )
3050 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aGluePoints;
3052 sal_uInt16 i;
3053 sal_uInt16 nNumElemVert = 0;
3054 sal_uInt16 nNumElemMemVert = 0;
3055 sal_uInt16 nElemSizeVert = 8;
3057 if ( SeekToContent( DFF_Prop_connectorPoints, rIn ) )
3058 rIn >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
3060 sal_Int32 nX, nY;
3061 sal_Int16 nTmpA, nTmpB;
3062 aGluePoints.realloc( nNumElemVert );
3063 for ( i = 0; i < nNumElemVert; i++ )
3065 if ( nElemSizeVert == 8 )
3067 rIn >> nX
3068 >> nY;
3070 else
3072 rIn >> nTmpA
3073 >> nTmpB;
3075 nX = nTmpA;
3076 nY = nTmpB;
3078 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].First, nX );
3079 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].Second, nY );
3081 const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
3082 aProp.Name = sGluePoints;
3083 aProp.Value <<= aGluePoints;
3084 aPathPropVec.push_back( aProp );
3086 if ( IsProperty( DFF_Prop_connectorType ) )
3088 sal_Int16 nGluePointType = (sal_uInt16)GetPropertyValue( DFF_Prop_connectorType );
3089 const rtl::OUString sGluePointType( RTL_CONSTASCII_USTRINGPARAM ( "GluePointType" ) );
3090 aProp.Name = sGluePointType;
3091 aProp.Value <<= nGluePointType;
3092 aPathPropVec.push_back( aProp );
3094 // pushing the whole Path element
3095 if ( aPathPropVec.size() )
3097 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
3098 PropSeq aPathPropSeq( aPathPropVec.size() );
3099 aIter = aPathPropVec.begin();
3100 aEnd = aPathPropVec.end();
3101 beans::PropertyValue* pPathValues = aPathPropSeq.getArray();
3102 while ( aIter != aEnd )
3103 *pPathValues++ = *aIter++;
3104 aProp.Name = sPath;
3105 aProp.Value <<= aPathPropSeq;
3106 aPropVec.push_back( aProp );
3109 /////////////////////////////////////////
3110 // "TextPath" PropertySequence element //
3111 /////////////////////////////////////////
3112 sal_Bool bTextPathOn = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x4000 ) != 0;
3113 if ( bTextPathOn )
3115 PropVec aTextPathPropVec;
3117 // TextPath
3118 const rtl::OUString sTextPathOn( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) );
3119 aProp.Name = sTextPathOn;
3120 aProp.Value <<= bTextPathOn;
3121 aTextPathPropVec.push_back( aProp );
3123 // TextPathMode
3124 const rtl::OUString sTextPathMode( RTL_CONSTASCII_USTRINGPARAM ( "TextPathMode" ) );
3125 sal_Bool bTextPathFitPath = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x100 ) != 0;
3127 sal_Bool bTextPathFitShape;
3128 if ( IsHardAttribute( DFF_Prop_gtextFStretch ) )
3129 bTextPathFitShape = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x400 ) != 0;
3130 else
3132 bTextPathFitShape = true;
3133 switch( rObjData.eShapeType )
3135 case mso_sptTextArchUpCurve :
3136 case mso_sptTextArchDownCurve :
3137 case mso_sptTextCircleCurve :
3138 case mso_sptTextButtonCurve :
3139 bTextPathFitShape = false;
3140 default : break;
3143 EnhancedCustomShapeTextPathMode eTextPathMode( EnhancedCustomShapeTextPathMode_NORMAL );
3144 if ( bTextPathFitShape )
3145 eTextPathMode = EnhancedCustomShapeTextPathMode_SHAPE;
3146 else if ( bTextPathFitPath )
3147 eTextPathMode = EnhancedCustomShapeTextPathMode_PATH;
3148 aProp.Name = sTextPathMode;
3149 aProp.Value <<= eTextPathMode;
3150 aTextPathPropVec.push_back( aProp );
3152 // ScaleX
3153 const rtl::OUString sTextPathScaleX( RTL_CONSTASCII_USTRINGPARAM ( "ScaleX" ) );
3154 sal_Bool bTextPathScaleX = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x40 ) != 0;
3155 aProp.Name = sTextPathScaleX;
3156 aProp.Value <<= bTextPathScaleX;
3157 aTextPathPropVec.push_back( aProp );
3158 // SameLetterHeights
3159 const rtl::OUString sSameLetterHeight( RTL_CONSTASCII_USTRINGPARAM ( "SameLetterHeights" ) );
3160 sal_Bool bSameLetterHeight = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x80 ) != 0;
3161 aProp.Name = sSameLetterHeight;
3162 aProp.Value <<= bSameLetterHeight;
3163 aTextPathPropVec.push_back( aProp );
3165 // pushing the whole TextPath element
3166 const rtl::OUString sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) );
3167 PropSeq aTextPathPropSeq( aTextPathPropVec.size() );
3168 aIter = aTextPathPropVec.begin();
3169 aEnd = aTextPathPropVec.end();
3170 beans::PropertyValue* pTextPathValues = aTextPathPropSeq.getArray();
3171 while ( aIter != aEnd )
3172 *pTextPathValues++ = *aIter++;
3173 aProp.Name = sTextPath;
3174 aProp.Value <<= aTextPathPropSeq;
3175 aPropVec.push_back( aProp );
3177 ////////////////////////
3178 // "AdjustmentValues" // The AdjustmentValues are imported at last, because depending to the type of the
3179 //////////////////////// handle (POLAR) we will convert the adjustment value from a fixed float to double
3181 // checking the last used adjustment handle, so we can determine how many handles are to allocate
3182 sal_Int32 i = DFF_Prop_adjust10Value;
3183 while ( ( i >= DFF_Prop_adjustValue ) && !IsProperty( i ) )
3184 i--;
3185 sal_Int32 nAdjustmentValues = ( i - DFF_Prop_adjustValue ) + 1;
3186 if ( nAdjustmentValues )
3188 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq( nAdjustmentValues );
3189 while( --nAdjustmentValues >= 0 )
3191 sal_Int32 nValue = 0;
3192 beans::PropertyState ePropertyState = beans::PropertyState_DEFAULT_VALUE;
3193 if ( IsProperty( i ) )
3195 nValue = GetPropertyValue( i );
3196 ePropertyState = beans::PropertyState_DIRECT_VALUE;
3198 if ( nAdjustmentsWhichNeedsToBeConverted & ( 1 << ( i - DFF_Prop_adjustValue ) ) )
3200 double fValue = nValue;
3201 fValue /= 65536;
3202 aAdjustmentSeq[ nAdjustmentValues ].Value <<= fValue;
3204 else
3205 aAdjustmentSeq[ nAdjustmentValues ].Value <<= nValue;
3206 aAdjustmentSeq[ nAdjustmentValues ].State = ePropertyState;
3207 i--;
3209 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
3210 aProp.Name = sAdjustmentValues;
3211 aProp.Value <<= aAdjustmentSeq;
3212 aPropVec.push_back( aProp );
3215 // creating the whole property set
3216 PropSeq aSeq( aPropVec.size() );
3217 beans::PropertyValue* pValues = aSeq.getArray();
3218 aIter = aPropVec.begin();
3219 aEnd = aPropVec.end();
3220 while ( aIter != aEnd )
3221 *pValues++ = *aIter++;
3222 rSet.Put( SdrCustomShapeGeometryItem( aSeq ) );
3225 void DffPropertyReader::ApplyAttributes( SvStream& rIn, SfxItemSet& rSet ) const
3227 Rectangle aEmptyRect;
3228 DffRecordHeader aHdTemp;
3229 DffObjData aDffObjTemp( aHdTemp, aEmptyRect, 0 );
3230 ApplyAttributes( rIn, rSet, aDffObjTemp );
3233 void DffPropertyReader::ApplyAttributes( SvStream& rIn, SfxItemSet& rSet, const DffObjData& rObjData ) const
3235 // MapUnit eMap( rManager.GetModel()->GetScaleUnit() );
3237 for ( void* pDummy = ((DffPropertyReader*)this)->First(); pDummy; pDummy = ((DffPropertyReader*)this)->Next() )
3239 UINT32 nRecType = GetCurKey();
3240 UINT32 nContent = mpContents[ nRecType ];
3241 switch ( nRecType )
3243 case DFF_Prop_gtextSize :
3244 rSet.Put( SvxFontHeightItem( rManager.ScalePt( nContent ), 100, EE_CHAR_FONTHEIGHT ) );
3245 break;
3246 // GeoText
3247 case DFF_Prop_gtextFStrikethrough :
3249 if ( nContent & 0x20 )
3250 rSet.Put( SvxWeightItem( nContent ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) );
3251 if ( nContent & 0x10 )
3252 rSet.Put( SvxPostureItem( nContent ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) );
3253 if ( nContent & 0x08 )
3254 rSet.Put( SvxUnderlineItem( nContent ? UNDERLINE_SINGLE : UNDERLINE_NONE, EE_CHAR_UNDERLINE ) );
3255 if ( nContent & 0x40 )
3256 rSet.Put(SvxShadowedItem( nContent != 0, EE_CHAR_SHADOW ) );
3257 // if ( nContent & 0x02 )
3258 // rSet.Put( SvxCaseMapItem( nContent ? SVX_CASEMAP_KAPITAELCHEN : SVX_CASEMAP_NOT_MAPPED ) );
3259 if ( nContent & 0x01 )
3260 rSet.Put( SvxCrossedOutItem( nContent ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, EE_CHAR_STRIKEOUT ) );
3262 break;
3264 case DFF_Prop_fillColor :
3265 rSet.Put( XFillColorItem( String(), rManager.MSO_CLR_ToColor( nContent, DFF_Prop_fillColor ) ) );
3266 break;
3268 // ShadowStyle
3269 case DFF_Prop_shadowType :
3271 MSO_ShadowType eShadowType = (MSO_ShadowType)nContent;
3272 if( eShadowType != mso_shadowOffset )
3274 // mso_shadowDouble
3275 // mso_shadowRich
3276 // mso_shadowEmbossOrEngrave
3277 // koennen wir nicht, kreiere Default-Schatten mit default-
3278 // Abstand
3279 rSet.Put( SdrShadowXDistItem( 35 ) ); // 0,35 mm Schattendistanz
3280 rSet.Put( SdrShadowYDistItem( 35 ) );
3283 break;
3284 case DFF_Prop_shadowColor :
3285 rSet.Put( SdrShadowColorItem( String(), rManager.MSO_CLR_ToColor( nContent, DFF_Prop_shadowColor ) ) );
3286 break;
3287 case DFF_Prop_shadowOpacity :
3288 rSet.Put( SdrShadowTransparenceItem( (sal_uInt16)( ( 0x10000 - nContent ) / 655 ) ) );
3289 break;
3290 case DFF_Prop_shadowOffsetX :
3292 INT32 nVal = (INT32)nContent;
3293 rManager.ScaleEmu( nVal );
3294 if ( nVal )
3295 rSet.Put( SdrShadowXDistItem( nVal ) );
3297 break;
3298 case DFF_Prop_shadowOffsetY :
3300 INT32 nVal = (INT32)nContent;
3301 rManager.ScaleEmu( nVal );
3302 if ( nVal )
3303 rSet.Put( SdrShadowYDistItem( nVal ) );
3305 break;
3306 case DFF_Prop_fshadowObscured :
3308 sal_Bool bHasShadow = ( nContent & 2 ) != 0;
3309 rSet.Put( SdrShadowItem( bHasShadow ) );
3310 if ( bHasShadow )
3312 if ( !IsProperty( DFF_Prop_shadowOffsetX ) )
3313 rSet.Put( SdrShadowXDistItem( 35 ) );
3314 if ( !IsProperty( DFF_Prop_shadowOffsetY ) )
3315 rSet.Put( SdrShadowYDistItem( 35 ) );
3318 break;
3322 ApplyLineAttributes( rSet, rObjData.eShapeType ); // #i28269#
3323 ApplyFillAttributes( rIn, rSet, rObjData );
3324 if ( rObjData.eShapeType != mso_sptNil )
3326 ApplyCustomShapeGeometryAttributes( rIn, rSet, rObjData );
3327 ApplyCustomShapeTextAttributes( rSet );
3331 //---------------------------------------------------------------------------
3332 //- Record Manager ----------------------------------------------------------
3333 //---------------------------------------------------------------------------
3335 DffRecordList::DffRecordList( DffRecordList* pList ) :
3336 nCount ( 0 ),
3337 nCurrent ( 0 ),
3338 pPrev ( pList ),
3339 pNext ( NULL )
3341 if ( pList )
3342 pList->pNext = this;
3345 DffRecordList::~DffRecordList()
3347 delete pNext;
3350 DffRecordManager::DffRecordManager() :
3351 DffRecordList ( NULL ),
3352 pCList ( (DffRecordList*)this )
3356 DffRecordManager::DffRecordManager( SvStream& rIn ) :
3357 DffRecordList ( NULL ),
3358 pCList ( (DffRecordList*)this )
3360 Consume( rIn );
3363 DffRecordManager::~DffRecordManager()
3368 void DffRecordManager::Consume( SvStream& rIn, BOOL bAppend, UINT32 nStOfs )
3370 if ( !bAppend )
3371 Clear();
3372 UINT32 nOldPos = rIn.Tell();
3373 if ( !nStOfs )
3375 DffRecordHeader aHd;
3376 rIn >> aHd;
3377 if ( aHd.nRecVer == DFF_PSFLAG_CONTAINER )
3378 nStOfs = aHd.GetRecEndFilePos();
3380 if ( nStOfs )
3382 pCList = (DffRecordList*)this;
3383 while ( pCList->pNext )
3384 pCList = pCList->pNext;
3385 while ( ( rIn.GetError() == 0 ) && ( ( rIn.Tell() + 8 ) <= nStOfs ) )
3387 if ( pCList->nCount == DFF_RECORD_MANAGER_BUF_SIZE )
3388 pCList = new DffRecordList( pCList );
3389 rIn >> pCList->mHd[ pCList->nCount ];
3390 pCList->mHd[ pCList->nCount++ ].SeekToEndOfRecord( rIn );
3392 rIn.Seek( nOldPos );
3396 void DffRecordManager::Clear()
3398 pCList = (DffRecordList*)this;
3399 delete pNext, pNext = NULL;
3400 nCurrent = 0;
3401 nCount = 0;
3404 DffRecordHeader* DffRecordManager::Current()
3406 DffRecordHeader* pRet = NULL;
3407 if ( pCList->nCurrent < pCList->nCount )
3408 pRet = &pCList->mHd[ pCList->nCurrent ];
3409 return pRet;
3412 DffRecordHeader* DffRecordManager::First()
3414 DffRecordHeader* pRet = NULL;
3415 pCList = (DffRecordList*)this;
3416 if ( pCList->nCount )
3418 pCList->nCurrent = 0;
3419 pRet = &pCList->mHd[ 0 ];
3421 return pRet;
3424 DffRecordHeader* DffRecordManager::Next()
3426 DffRecordHeader* pRet = NULL;
3427 UINT32 nC = pCList->nCurrent + 1;
3428 if ( nC < pCList->nCount )
3430 pCList->nCurrent++;
3431 pRet = &pCList->mHd[ nC ];
3433 else if ( pCList->pNext )
3435 pCList = pCList->pNext;
3436 pCList->nCurrent = 0;
3437 pRet = &pCList->mHd[ 0 ];
3439 return pRet;
3442 DffRecordHeader* DffRecordManager::Prev()
3444 DffRecordHeader* pRet = NULL;
3445 UINT32 nCur = pCList->nCurrent;
3446 if ( !nCur && pCList->pPrev )
3448 pCList = pCList->pPrev;
3449 nCur = pCList->nCount;
3451 if ( nCur-- )
3453 pCList->nCurrent = nCur;
3454 pRet = &pCList->mHd[ nCur ];
3456 return pRet;
3459 DffRecordHeader* DffRecordManager::Last()
3461 DffRecordHeader* pRet = NULL;
3462 while ( pCList->pNext )
3463 pCList = pCList->pNext;
3464 UINT32 nCnt = pCList->nCount;
3465 if ( nCnt-- )
3467 pCList->nCurrent = nCnt;
3468 pRet = &pCList->mHd[ nCnt ];
3470 return pRet;
3473 BOOL DffRecordManager::SeekToContent( SvStream& rIn, UINT16 nRecId, DffSeekToContentMode eMode )
3475 DffRecordHeader* pHd = GetRecordHeader( nRecId, eMode );
3476 if ( pHd )
3478 pHd->SeekToContent( rIn );
3479 return TRUE;
3481 else
3482 return FALSE;
3485 DffRecordHeader* DffRecordManager::GetRecordHeader( UINT16 nRecId, DffSeekToContentMode eMode )
3487 UINT32 nOldCurrent = pCList->nCurrent;
3488 DffRecordList* pOldList = pCList;
3489 DffRecordHeader* pHd;
3491 if ( eMode == SEEK_FROM_BEGINNING )
3492 pHd = First();
3493 else
3494 pHd = Next();
3496 while ( pHd )
3498 if ( pHd->nRecType == nRecId )
3499 break;
3500 pHd = Next();
3502 if ( !pHd && eMode == SEEK_FROM_CURRENT_AND_RESTART )
3504 DffRecordHeader* pBreak = &pOldList->mHd[ nOldCurrent ];
3505 pHd = First();
3506 if ( pHd )
3508 while ( pHd != pBreak )
3510 if ( pHd->nRecType == nRecId )
3511 break;
3512 pHd = Next();
3514 if ( pHd->nRecType != nRecId )
3515 pHd = NULL;
3518 if ( !pHd )
3520 pCList = pOldList;
3521 pOldList->nCurrent = nOldCurrent;
3523 return pHd;
3526 //---------------------------------------------------------------------------
3527 // private Methoden
3528 //---------------------------------------------------------------------------
3530 struct EscherBlipCacheEntry
3532 ByteString aUniqueID;
3533 sal_uInt32 nBlip;
3535 EscherBlipCacheEntry( sal_uInt32 nBlipId, const ByteString& rUniqueID ) :
3536 aUniqueID( rUniqueID ),
3537 nBlip( nBlipId ) {}
3540 void SvxMSDffManager::Scale( sal_Int32& rVal ) const
3542 if ( bNeedMap )
3543 rVal = BigMulDiv( rVal, nMapMul, nMapDiv );
3546 void SvxMSDffManager::Scale( Point& rPos ) const
3548 rPos.X() += nMapXOfs;
3549 rPos.Y() += nMapYOfs;
3550 if ( bNeedMap )
3552 rPos.X() = BigMulDiv( rPos.X(), nMapMul, nMapDiv );
3553 rPos.Y() = BigMulDiv( rPos.Y(), nMapMul, nMapDiv );
3557 void SvxMSDffManager::Scale( Size& rSiz ) const
3559 if ( bNeedMap )
3561 rSiz.Width() = BigMulDiv( rSiz.Width(), nMapMul, nMapDiv );
3562 rSiz.Height() = BigMulDiv( rSiz.Height(), nMapMul, nMapDiv );
3566 void SvxMSDffManager::Scale( Rectangle& rRect ) const
3568 rRect.Move( nMapXOfs, nMapYOfs );
3569 if ( bNeedMap )
3571 rRect.Left() =BigMulDiv( rRect.Left() , nMapMul, nMapDiv );
3572 rRect.Top() =BigMulDiv( rRect.Top() , nMapMul, nMapDiv );
3573 rRect.Right() =BigMulDiv( rRect.Right() , nMapMul, nMapDiv );
3574 rRect.Bottom()=BigMulDiv( rRect.Bottom(), nMapMul, nMapDiv );
3578 void SvxMSDffManager::Scale( Polygon& rPoly ) const
3580 if ( !bNeedMap )
3581 return;
3582 USHORT nPointAnz = rPoly.GetSize();
3583 for ( USHORT nPointNum = 0; nPointNum < nPointAnz; nPointNum++ )
3584 Scale( rPoly[ nPointNum ] );
3587 void SvxMSDffManager::Scale( PolyPolygon& rPoly ) const
3589 if ( !bNeedMap )
3590 return;
3591 USHORT nPolyAnz = rPoly.Count();
3592 for ( USHORT nPolyNum = 0; nPolyNum < nPolyAnz; nPolyNum++ )
3593 Scale( rPoly[ nPolyNum ] );
3596 void SvxMSDffManager::ScaleEmu( sal_Int32& rVal ) const
3598 rVal = BigMulDiv( rVal, nEmuMul, nEmuDiv );
3601 UINT32 SvxMSDffManager::ScalePt( UINT32 nVal ) const
3603 MapUnit eMap = pSdrModel->GetScaleUnit();
3604 Fraction aFact( GetMapFactor( MAP_POINT, eMap ).X() );
3605 long aMul = aFact.GetNumerator();
3606 long aDiv = aFact.GetDenominator() * 65536;
3607 aFact = Fraction( aMul, aDiv ); // nochmal versuchen zu kuerzen
3608 return BigMulDiv( nVal, aFact.GetNumerator(), aFact.GetDenominator() );
3611 INT32 SvxMSDffManager::ScalePoint( INT32 nVal ) const
3613 return BigMulDiv( nVal, nPntMul, nPntDiv );
3616 void SvxMSDffManager::SetModel(SdrModel* pModel, long nApplicationScale)
3618 pSdrModel = pModel;
3619 if( pModel && (0 < nApplicationScale) )
3621 // PPT arbeitet nur mit Einheiten zu 576DPI
3622 // WW hingegen verwendet twips, dh. 1440DPI.
3623 MapUnit eMap = pSdrModel->GetScaleUnit();
3624 Fraction aFact( GetMapFactor(MAP_INCH, eMap).X() );
3625 long nMul=aFact.GetNumerator();
3626 long nDiv=aFact.GetDenominator()*nApplicationScale;
3627 aFact=Fraction(nMul,nDiv); // nochmal versuchen zu kuerzen
3628 // Bei 100TH_MM -> 2540/576=635/144
3629 // Bei Twip -> 1440/576=5/2
3630 nMapMul = aFact.GetNumerator();
3631 nMapDiv = aFact.GetDenominator();
3632 bNeedMap = nMapMul!=nMapDiv;
3634 // MS-DFF-Properties sind grossteils in EMU (English Metric Units) angegeben
3635 // 1mm=36000emu, 1twip=635emu
3636 aFact=GetMapFactor(MAP_100TH_MM,eMap).X();
3637 nMul=aFact.GetNumerator();
3638 nDiv=aFact.GetDenominator()*360;
3639 aFact=Fraction(nMul,nDiv); // nochmal versuchen zu kuerzen
3640 // Bei 100TH_MM -> 1/360
3641 // Bei Twip -> 14,40/(25,4*360)=144/91440=1/635
3642 nEmuMul=aFact.GetNumerator();
3643 nEmuDiv=aFact.GetDenominator();
3645 // Und noch was fuer typografische Points
3646 aFact=GetMapFactor(MAP_POINT,eMap).X();
3647 nPntMul=aFact.GetNumerator();
3648 nPntDiv=aFact.GetDenominator();
3650 else
3652 pModel = 0;
3653 nMapMul = nMapDiv = nMapXOfs = nMapYOfs = nEmuMul = nEmuDiv = nPntMul = nPntDiv = 0;
3654 bNeedMap = FALSE;
3658 BOOL SvxMSDffManager::SeekToShape( SvStream& rSt, void* /* pClientData */, UINT32 nId ) const
3660 BOOL bRet = FALSE;
3661 if ( mpFidcls )
3663 UINT32 nMerk = rSt.Tell();
3664 UINT32 nShapeId, nSec = ( nId >> 10 ) - 1;
3665 if ( nSec < mnIdClusters )
3667 sal_IntPtr nOfs = (sal_IntPtr)maDgOffsetTable.Get( mpFidcls[ nSec ].dgid );
3668 if ( nOfs )
3670 rSt.Seek( nOfs );
3671 DffRecordHeader aEscherF002Hd;
3672 rSt >> aEscherF002Hd;
3673 ULONG nEscherF002End = aEscherF002Hd.GetRecEndFilePos();
3674 DffRecordHeader aEscherObjListHd;
3675 while ( rSt.Tell() < nEscherF002End )
3677 rSt >> aEscherObjListHd;
3678 if ( aEscherObjListHd.nRecVer != 0xf )
3679 aEscherObjListHd.SeekToEndOfRecord( rSt );
3680 else if ( aEscherObjListHd.nRecType == DFF_msofbtSpContainer )
3682 DffRecordHeader aShapeHd;
3683 if ( SeekToRec( rSt, DFF_msofbtSp, aEscherObjListHd.GetRecEndFilePos(), &aShapeHd ) )
3685 rSt >> nShapeId;
3686 if ( nId == nShapeId )
3688 aEscherObjListHd.SeekToBegOfRecord( rSt );
3689 bRet = TRUE;
3690 break;
3693 aEscherObjListHd.SeekToEndOfRecord( rSt );
3698 if ( !bRet )
3699 rSt.Seek( nMerk );
3701 return bRet;
3704 FASTBOOL SvxMSDffManager::SeekToRec( SvStream& rSt, USHORT nRecId, ULONG nMaxFilePos, DffRecordHeader* pRecHd, ULONG nSkipCount ) const
3706 FASTBOOL bRet = FALSE;
3707 ULONG nFPosMerk = rSt.Tell(); // FilePos merken fuer ggf. spaetere Restauration
3708 DffRecordHeader aHd;
3711 rSt >> aHd;
3712 if ( aHd.nRecType == nRecId )
3714 if ( nSkipCount )
3715 nSkipCount--;
3716 else
3718 bRet = TRUE;
3719 if ( pRecHd != NULL )
3720 *pRecHd = aHd;
3721 else
3722 aHd.SeekToBegOfRecord( rSt );
3725 if ( !bRet )
3726 aHd.SeekToEndOfRecord( rSt );
3728 while ( rSt.GetError() == 0 && rSt.Tell() < nMaxFilePos && !bRet );
3729 if ( !bRet )
3730 rSt.Seek( nFPosMerk ); // FilePos restaurieren
3731 return bRet;
3734 FASTBOOL SvxMSDffManager::SeekToRec2( USHORT nRecId1, USHORT nRecId2, ULONG nMaxFilePos, DffRecordHeader* pRecHd, ULONG nSkipCount ) const
3736 FASTBOOL bRet = FALSE;
3737 ULONG nFPosMerk = rStCtrl.Tell(); // FilePos merken fuer ggf. spaetere Restauration
3738 DffRecordHeader aHd;
3741 rStCtrl >> aHd;
3742 if ( aHd.nRecType == nRecId1 || aHd.nRecType == nRecId2 )
3744 if ( nSkipCount )
3745 nSkipCount--;
3746 else
3748 bRet = TRUE;
3749 if ( pRecHd )
3750 *pRecHd = aHd;
3751 else
3752 aHd.SeekToBegOfRecord( rStCtrl );
3755 if ( !bRet )
3756 aHd.SeekToEndOfRecord( rStCtrl );
3758 while ( rStCtrl.GetError() == 0 && rStCtrl.Tell() < nMaxFilePos && !bRet );
3759 if ( !bRet )
3760 rStCtrl.Seek( nFPosMerk ); // FilePos restaurieren
3761 return bRet;
3765 FASTBOOL SvxMSDffManager::GetColorFromPalette( USHORT /* nNum */, Color& rColor ) const
3767 // diese Methode ist in der zum Excel-Import
3768 // abgeleiteten Klasse zu ueberschreiben...
3769 rColor.SetColor( COL_WHITE );
3770 return TRUE;
3774 Color SvxMSDffManager::MSO_CLR_ToColor( sal_uInt32 nColorCode, sal_uInt16 nContentProperty ) const
3776 Color aColor( mnDefaultColor );
3778 // Fuer Textfarben: Header ist 0xfeRRGGBB
3779 if ( ( nColorCode & 0xfe000000 ) == 0xfe000000 )
3780 nColorCode &= 0x00ffffff;
3782 sal_uInt8 nUpper = (sal_uInt8)( nColorCode >> 24 );
3784 // sj: below change from 0x1b to 0x19 was done because of i84812 (0x02 -> rgb color),
3785 // now I have some problems to fix i104685 (there the color value is 0x02000000 whichs requires
3786 // a 0x2 scheme color to be displayed properly), the color docu seems to be incomplete
3787 if( nUpper & 0x19 ) // if( nUpper & 0x1f )
3789 if( ( nUpper & 0x08 ) || ( ( nUpper & 0x10 ) == 0 ) )
3791 // SCHEMECOLOR
3792 if ( !GetColorFromPalette( ( nUpper & 8 ) ? (sal_uInt16)nColorCode : nUpper, aColor ) )
3794 switch( nContentProperty )
3796 case DFF_Prop_pictureTransparent :
3797 case DFF_Prop_shadowColor :
3798 case DFF_Prop_fillBackColor :
3799 case DFF_Prop_fillColor :
3800 aColor = Color( COL_WHITE );
3801 break;
3802 case DFF_Prop_lineColor :
3804 aColor = Color( COL_BLACK );
3806 break;
3810 else // SYSCOLOR
3812 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
3814 // UINT16 nParameter = (BYTE)( nColorCode >> 16); // SJ: nice compiler optimization bug on windows, though downcasting
3815 UINT16 nParameter = sal_uInt16(( nColorCode >> 16 ) & 0x00ff); // the HiByte of nParameter is not zero, an exclusive AND is helping :o
3816 UINT16 nFunctionBits = (UINT16)( ( nColorCode & 0x00000f00 ) >> 8 );
3817 UINT16 nAdditionalFlags = (UINT16)( ( nColorCode & 0x0000f000) >> 8 );
3818 UINT16 nColorIndex = sal_uInt16(nColorCode & 0x00ff);
3819 UINT32 nPropColor = 0;
3821 sal_uInt16 nCProp = 0;
3823 switch ( nColorIndex )
3825 case mso_syscolorButtonFace : aColor = rStyleSettings.GetFaceColor(); break;
3826 case mso_syscolorWindowText : aColor = rStyleSettings.GetWindowTextColor(); break;
3827 case mso_syscolorMenu : aColor = rStyleSettings.GetMenuColor(); break;
3828 case mso_syscolor3DLight :
3829 case mso_syscolorButtonHighlight :
3830 case mso_syscolorHighlight : aColor = rStyleSettings.GetHighlightColor(); break;
3831 case mso_syscolorHighlightText : aColor = rStyleSettings.GetHighlightTextColor(); break;
3832 case mso_syscolorCaptionText : aColor = rStyleSettings.GetMenuTextColor(); break;
3833 case mso_syscolorActiveCaption : aColor = rStyleSettings.GetHighlightColor(); break;
3834 case mso_syscolorButtonShadow : aColor = rStyleSettings.GetShadowColor(); break;
3835 case mso_syscolorButtonText : aColor = rStyleSettings.GetButtonTextColor(); break;
3836 case mso_syscolorGrayText : aColor = rStyleSettings.GetDeactiveColor(); break;
3837 case mso_syscolorInactiveCaption : aColor = rStyleSettings.GetDeactiveColor(); break;
3838 case mso_syscolorInactiveCaptionText : aColor = rStyleSettings.GetDeactiveColor(); break;
3839 case mso_syscolorInfoBackground : aColor = rStyleSettings.GetFaceColor(); break;
3840 case mso_syscolorInfoText : aColor = rStyleSettings.GetInfoTextColor(); break;
3841 case mso_syscolorMenuText : aColor = rStyleSettings.GetMenuTextColor(); break;
3842 case mso_syscolorScrollbar : aColor = rStyleSettings.GetFaceColor(); break;
3843 case mso_syscolorWindow : aColor = rStyleSettings.GetWindowColor(); break;
3844 case mso_syscolorWindowFrame : aColor = rStyleSettings.GetWindowColor(); break;
3846 case mso_colorFillColor :
3848 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );
3849 nCProp = DFF_Prop_fillColor;
3851 break;
3852 case mso_colorLineOrFillColor : // ( use the line color only if there is a line )
3854 if ( GetPropertyValue( DFF_Prop_fNoLineDrawDash ) & 8 )
3856 nPropColor = GetPropertyValue( DFF_Prop_lineColor, 0 );
3857 nCProp = DFF_Prop_lineColor;
3859 else
3861 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );
3862 nCProp = DFF_Prop_fillColor;
3865 break;
3866 case mso_colorLineColor :
3868 nPropColor = GetPropertyValue( DFF_Prop_lineColor, 0 );
3869 nCProp = DFF_Prop_lineColor;
3871 break;
3872 case mso_colorShadowColor :
3874 nPropColor = GetPropertyValue( DFF_Prop_shadowColor, 0x808080 );
3875 nCProp = DFF_Prop_shadowColor;
3877 break;
3878 case mso_colorThis : // ( use this color ... )
3880 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //?????????????
3881 nCProp = DFF_Prop_fillColor;
3883 break;
3884 case mso_colorFillBackColor :
3886 nPropColor = GetPropertyValue( DFF_Prop_fillBackColor, 0xffffff );
3887 nCProp = DFF_Prop_fillBackColor;
3889 break;
3890 case mso_colorLineBackColor :
3892 nPropColor = GetPropertyValue( DFF_Prop_lineBackColor, 0xffffff );
3893 nCProp = DFF_Prop_lineBackColor;
3895 break;
3896 case mso_colorFillThenLine : // ( use the fillcolor unless no fill and line )
3898 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //?????????????
3899 nCProp = DFF_Prop_fillColor;
3901 break;
3902 case mso_colorIndexMask : // ( extract the color index ) ?
3904 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //?????????????
3905 nCProp = DFF_Prop_fillColor;
3907 break;
3909 if ( nCProp && ( nPropColor & 0x10000000 ) == 0 ) // beware of looping recursive
3910 aColor = MSO_CLR_ToColor( nPropColor, nCProp );
3912 if( nAdditionalFlags & 0x80 ) // make color gray
3914 UINT8 nZwi = aColor.GetLuminance();
3915 aColor = Color( nZwi, nZwi, nZwi );
3917 switch( nFunctionBits )
3919 case 0x01 : // darken color by parameter
3921 aColor.SetRed( sal::static_int_cast< UINT8 >( ( nParameter * aColor.GetRed() ) >> 8 ) );
3922 aColor.SetGreen( sal::static_int_cast< UINT8 >( ( nParameter * aColor.GetGreen() ) >> 8 ) );
3923 aColor.SetBlue( sal::static_int_cast< UINT8 >( ( nParameter * aColor.GetBlue() ) >> 8 ) );
3925 break;
3926 case 0x02 : // lighten color by parameter
3928 UINT16 nInvParameter = ( 0x00ff - nParameter ) * 0xff;
3929 aColor.SetRed( sal::static_int_cast< UINT8 >( ( nInvParameter + ( nParameter * aColor.GetRed() ) ) >> 8 ) );
3930 aColor.SetGreen( sal::static_int_cast< UINT8 >( ( nInvParameter + ( nParameter * aColor.GetGreen() ) ) >> 8 ) );
3931 aColor.SetBlue( sal::static_int_cast< UINT8 >( ( nInvParameter + ( nParameter * aColor.GetBlue() ) ) >> 8 ) );
3933 break;
3934 case 0x03 : // add grey level RGB(p,p,p)
3936 INT16 nR = (INT16)aColor.GetRed() + (INT16)nParameter;
3937 INT16 nG = (INT16)aColor.GetGreen() + (INT16)nParameter;
3938 INT16 nB = (INT16)aColor.GetBlue() + (INT16)nParameter;
3939 if ( nR > 0x00ff )
3940 nR = 0x00ff;
3941 if ( nG > 0x00ff )
3942 nG = 0x00ff;
3943 if ( nB > 0x00ff )
3944 nB = 0x00ff;
3945 aColor = Color( (UINT8)nR, (UINT8)nG, (UINT8)nB );
3947 break;
3948 case 0x04 : // substract grey level RGB(p,p,p)
3950 INT16 nR = (INT16)aColor.GetRed() - (INT16)nParameter;
3951 INT16 nG = (INT16)aColor.GetGreen() - (INT16)nParameter;
3952 INT16 nB = (INT16)aColor.GetBlue() - (INT16)nParameter;
3953 if ( nR < 0 )
3954 nR = 0;
3955 if ( nG < 0 )
3956 nG = 0;
3957 if ( nB < 0 )
3958 nB = 0;
3959 aColor = Color( (UINT8)nR, (UINT8)nG, (UINT8)nB );
3961 break;
3962 case 0x05 : // substract from grey level RGB(p,p,p)
3964 INT16 nR = (INT16)nParameter - (INT16)aColor.GetRed();
3965 INT16 nG = (INT16)nParameter - (INT16)aColor.GetGreen();
3966 INT16 nB = (INT16)nParameter - (INT16)aColor.GetBlue();
3967 if ( nR < 0 )
3968 nR = 0;
3969 if ( nG < 0 )
3970 nG = 0;
3971 if ( nB < 0 )
3972 nB = 0;
3973 aColor = Color( (UINT8)nR, (UINT8)nG, (UINT8)nB );
3975 break;
3976 case 0x06 : // per component: black if < p, white if >= p
3978 aColor.SetRed( aColor.GetRed() < nParameter ? 0x00 : 0xff );
3979 aColor.SetGreen( aColor.GetGreen() < nParameter ? 0x00 : 0xff );
3980 aColor.SetBlue( aColor.GetBlue() < nParameter ? 0x00 : 0xff );
3982 break;
3984 if ( nAdditionalFlags & 0x40 ) // top-bit invert
3985 aColor = Color( aColor.GetRed() ^ 0x80, aColor.GetGreen() ^ 0x80, aColor.GetBlue() ^ 0x80 );
3987 if ( nAdditionalFlags & 0x20 ) // invert color
3988 aColor = Color(0xff - aColor.GetRed(), 0xff - aColor.GetGreen(), 0xff - aColor.GetBlue());
3991 else if ( ( nUpper & 4 ) && ( ( nColorCode & 0xfffff8 ) == 0 ) )
3992 { // case of nUpper == 4 powerpoint takes this as agrument for a colorschemecolor
3993 GetColorFromPalette( nUpper, aColor );
3995 else // hart attributiert, eventuell mit Hinweis auf SYSTEMRGB
3996 aColor = Color( (BYTE)nColorCode, (BYTE)( nColorCode >> 8 ), (BYTE)( nColorCode >> 16 ) );
3997 return aColor;
4000 FASTBOOL SvxMSDffManager::ReadDffString(SvStream& rSt, String& rTxt) const
4002 FASTBOOL bRet=FALSE;
4003 DffRecordHeader aStrHd;
4004 if( !ReadCommonRecordHeader(aStrHd, rSt) )
4005 rSt.Seek( aStrHd.nFilePos );
4006 else if ( aStrHd.nRecType == DFF_PST_TextBytesAtom || aStrHd.nRecType == DFF_PST_TextCharsAtom )
4008 FASTBOOL bUniCode=aStrHd.nRecType==DFF_PST_TextCharsAtom;
4009 bRet=TRUE;
4010 ULONG nBytes = aStrHd.nRecLen;
4011 MSDFFReadZString( rSt, rTxt, nBytes, bUniCode );
4012 if( !bUniCode )
4014 for ( xub_StrLen n = 0; n < nBytes; n++ )
4016 if( rTxt.GetChar( n ) == 0x0B )
4017 rTxt.SetChar( n, ' ' ); // Weicher Umbruch
4018 // TODO: Zeilenumbruch im Absatz via Outliner setzen.
4021 aStrHd.SeekToEndOfRecord( rSt );
4023 else
4024 aStrHd.SeekToBegOfRecord( rSt );
4025 return bRet;
4028 // sj: I just want to set a string for a text object that may contain multiple
4029 // paragraphs. If I now take a look at the follwing code I get the impression that
4030 // our outliner is too complicate to be used properly,
4031 void SvxMSDffManager::ReadObjText( const String& rText, SdrObject* pObj ) const
4033 SdrTextObj* pText = PTR_CAST( SdrTextObj, pObj );
4034 if ( pText )
4036 SdrOutliner& rOutliner = pText->ImpGetDrawOutliner();
4037 rOutliner.Init( OUTLINERMODE_TEXTOBJECT );
4039 BOOL bOldUpdateMode = rOutliner.GetUpdateMode();
4040 rOutliner.SetUpdateMode( FALSE );
4041 rOutliner.SetVertical( pText->IsVerticalWriting() );
4043 sal_uInt16 nParaIndex = 0;
4044 sal_uInt32 nParaSize;
4045 const sal_Unicode* pCurrent, *pBuf = rText.GetBuffer();
4046 const sal_Unicode* pEnd = rText.GetBuffer() + rText.Len();
4048 while( pBuf < pEnd )
4050 pCurrent = pBuf;
4052 for ( nParaSize = 0; pBuf < pEnd; )
4054 sal_Unicode nChar = *pBuf++;
4055 if ( nChar == 0xa )
4057 if ( ( pBuf < pEnd ) && ( *pBuf == 0xd ) )
4058 pBuf++;
4059 break;
4061 else if ( nChar == 0xd )
4063 if ( ( pBuf < pEnd ) && ( *pBuf == 0xa ) )
4064 pBuf++;
4065 break;
4067 else
4068 nParaSize++;
4070 ESelection aSelection( nParaIndex, 0, nParaIndex, 0 );
4071 String aParagraph( pCurrent, (sal_uInt16)nParaSize );
4072 if ( !nParaIndex && !aParagraph.Len() ) // SJ: we are crashing if the first paragraph is empty ?
4073 aParagraph += (sal_Unicode)' '; // otherwise these two lines can be removed.
4074 rOutliner.Insert( aParagraph, nParaIndex, 0 );
4075 rOutliner.SetParaAttribs( nParaIndex, rOutliner.GetEmptyItemSet() );
4077 SfxItemSet aParagraphAttribs( rOutliner.GetEmptyItemSet() );
4078 if ( !aSelection.nStartPos )
4079 aParagraphAttribs.Put( SfxBoolItem( EE_PARA_BULLETSTATE, FALSE ) );
4080 aSelection.nStartPos = 0;
4081 rOutliner.QuickSetAttribs( aParagraphAttribs, aSelection );
4082 nParaIndex++;
4084 OutlinerParaObject* pNewText = rOutliner.CreateParaObject();
4085 rOutliner.Clear();
4086 rOutliner.SetUpdateMode( bOldUpdateMode );
4087 pText->SetOutlinerParaObject( pNewText );
4091 FASTBOOL SvxMSDffManager::ReadObjText(SvStream& rSt, SdrObject* pObj) const
4093 FASTBOOL bRet=FALSE;
4094 SdrTextObj* pText = PTR_CAST(SdrTextObj, pObj);
4095 if( pText )
4097 DffRecordHeader aTextHd;
4098 if( !ReadCommonRecordHeader(aTextHd, rSt) )
4099 rSt.Seek( aTextHd.nFilePos );
4100 else if ( aTextHd.nRecType==DFF_msofbtClientTextbox )
4102 bRet=TRUE;
4103 ULONG nRecEnd=aTextHd.GetRecEndFilePos();
4104 DffRecordHeader aHd;
4105 String aText;
4106 // UINT32 nInvent=pText->GetObjInventor();
4107 // UINT16 nIdent=pText->GetObjIdentifier();
4109 SdrOutliner& rOutliner=pText->ImpGetDrawOutliner();
4110 // sal_Int16 nMinDepth = rOutliner.GetMinDepth();
4111 USHORT nOutlMode = rOutliner.GetMode();
4113 { // Wohl 'nen kleiner Bug der EditEngine, das die
4114 // Absastzattribute bei Clear() nicht entfernt werden.
4115 FASTBOOL bClearParaAttribs = TRUE;
4116 rOutliner.SetStyleSheet( 0, NULL );
4117 SfxItemSet aSet(rOutliner.GetEmptyItemSet());
4118 aSet.Put(SvxColorItem( COL_BLACK ));
4119 rOutliner.SetParaAttribs(0,aSet);
4120 pText->SetMergedItemSet(aSet);
4122 bClearParaAttribs = FALSE;
4123 if( bClearParaAttribs )
4125 // Wohl 'nen kleiner Bug der EditEngine, dass die
4126 // Absastzattribute bei Clear() nicht entfernt werden.
4127 rOutliner.SetParaAttribs(0,rOutliner.GetEmptyItemSet());
4130 rOutliner.Init( OUTLINERMODE_TEXTOBJECT );
4132 // ULONG nFilePosMerker=rSt.Tell();
4133 ////////////////////////////////////
4134 // TextString und MetaChars lesen //
4135 ////////////////////////////////////
4138 if( !ReadCommonRecordHeader(aHd, rSt) )
4139 rSt.Seek( aHd.nFilePos );
4140 else
4142 switch (aHd.nRecType)
4144 //case TextHeaderAtom
4145 //case TextSpecInfoAtom
4146 case DFF_PST_TextBytesAtom:
4147 case DFF_PST_TextCharsAtom:
4149 aHd.SeekToBegOfRecord(rSt);
4150 ReadDffString(rSt, aText);
4152 break;
4153 case DFF_PST_TextRulerAtom :
4155 UINT16 nLen = (UINT16)aHd.nRecLen;
4156 if(nLen)
4158 UINT16 nVal1, nVal2, nVal3;
4159 UINT16 nDefaultTab = 2540; // PPT def: 1 Inch //rOutliner.GetDefTab();
4160 UINT16 nMostrightTab = 0;
4161 SfxItemSet aSet(rOutliner.GetEmptyItemSet());
4162 SvxTabStopItem aTabItem(0, 0, SVX_TAB_ADJUST_DEFAULT, EE_PARA_TABS);
4164 rSt >> nVal1;
4165 rSt >> nVal2;
4166 nLen -= 4;
4168 // Allg. TAB verstellt auf Wert in nVal3
4169 if(nLen && (nVal1 & 0x0001))
4171 rSt >> nVal3;
4172 nLen -= 2;
4173 nDefaultTab = (UINT16)(((UINT32)nVal3 * 1000) / 240);
4176 // Weitere, frei gesetzte TABs
4177 if(nLen && (nVal1 & 0x0004))
4179 rSt >> nVal1;
4180 nLen -= 2;
4182 // fest gesetzte TABs importieren
4183 while(nLen && nVal1--)
4185 rSt >> nVal2;
4186 rSt >> nVal3;
4187 nLen -= 4;
4189 UINT16 nNewTabPos = (UINT16)(((UINT32)nVal2 * 1000) / 240);
4190 if(nNewTabPos > nMostrightTab)
4191 nMostrightTab = nNewTabPos;
4193 SvxTabStop aTabStop(nNewTabPos);
4194 aTabItem.Insert(aTabStop);
4198 // evtl. noch default-TABs ergaenzen (immer)
4199 UINT16 nObjWidth = sal_uInt16(pObj->GetSnapRect().GetWidth() + 1);
4200 UINT16 nDefaultTabPos = nDefaultTab;
4202 while(nDefaultTabPos <= nObjWidth && nDefaultTabPos <= nMostrightTab)
4203 nDefaultTabPos =
4204 nDefaultTabPos + nDefaultTab;
4206 while(nDefaultTabPos <= nObjWidth)
4208 SvxTabStop aTabStop(nDefaultTabPos);
4209 aTabItem.Insert(aTabStop);
4210 nDefaultTabPos =
4211 nDefaultTabPos + nDefaultTab;
4214 // Falls TABs angelegt wurden, setze diese
4215 if(aTabItem.Count())
4217 aSet.Put(aTabItem);
4218 rOutliner.SetParaAttribs(0, aSet);
4222 break;
4224 aHd.SeekToEndOfRecord( rSt );
4227 while ( rSt.GetError() == 0 && rSt.Tell() < nRecEnd );
4229 ////////////////////////
4230 // SHIFT-Ret ersetzen //
4231 ////////////////////////
4232 if ( aText.Len() )
4234 aText += ' ';
4235 aText.SetChar( aText.Len()-1, 0x0D );
4236 rOutliner.SetText( aText, rOutliner.GetParagraph( 0 ) );
4238 // SHIFT-Ret ersetzen im Outliner
4239 if(aText.GetTokenCount(0x0B) > 1)
4241 UINT32 nParaCount = rOutliner.GetParagraphCount();
4242 for(UINT16 a=0;a<nParaCount;a++)
4244 Paragraph* pActPara = rOutliner.GetParagraph(a);
4245 String aParaText = rOutliner.GetText(pActPara);
4246 for(UINT16 b=0;b<aParaText.Len();b++)
4248 if( aParaText.GetChar( b ) == 0x0B)
4250 ESelection aSelection(a, b, a, b+1);
4251 rOutliner.QuickInsertLineBreak(aSelection);
4257 OutlinerParaObject* pNewText=rOutliner.CreateParaObject();
4258 rOutliner.Init( nOutlMode );
4259 pText->NbcSetOutlinerParaObject(pNewText);
4261 else
4262 aTextHd.SeekToBegOfRecord(rSt);
4265 return bRet;
4268 //static
4269 void SvxMSDffManager::MSDFFReadZString( SvStream& rIn, String& rStr,
4270 ULONG nRecLen, FASTBOOL bUniCode )
4272 sal_uInt16 nLen = (sal_uInt16)nRecLen;
4273 if( nLen )
4275 if ( bUniCode )
4276 nLen >>= 1;
4278 String sBuf;
4279 sal_Unicode* pBuf = sBuf.AllocBuffer( nLen );
4281 if( bUniCode )
4283 rIn.Read( (sal_Char*)pBuf, nLen << 1 );
4285 #ifdef OSL_BIGENDIAN
4286 for( sal_uInt16 n = 0; n < nLen; ++n, ++pBuf )
4287 *pBuf = SWAPSHORT( *pBuf );
4288 #endif // ifdef OSL_BIGENDIAN
4290 else
4292 // use the String-Data as buffer for the 8bit characters and
4293 // change then all to unicode
4294 sal_Char* pReadPos = ((sal_Char*)pBuf) + nLen;
4295 rIn.Read( (sal_Char*)pReadPos, nLen );
4296 for( sal_uInt16 n = 0; n < nLen; ++n, ++pBuf, ++pReadPos )
4297 *pBuf = ByteString::ConvertToUnicode( *pReadPos, RTL_TEXTENCODING_MS_1252 );
4300 rStr = sBuf.EraseTrailingChars( 0 );
4302 else
4303 rStr.Erase();
4306 SdrObject* SvxMSDffManager::ImportFontWork( SvStream& rStCt, SfxItemSet& rSet, Rectangle& rBoundRect ) const
4308 SdrObject* pRet = NULL;
4309 String aObjectText;
4310 String aFontName;
4311 BOOL bTextRotate = FALSE;
4313 ((SvxMSDffManager*)this)->mnFix16Angle = 0; // we don't want to use this property in future
4314 if ( SeekToContent( DFF_Prop_gtextUNICODE, rStCt ) )
4315 MSDFFReadZString( rStCt, aObjectText, GetPropertyValue( DFF_Prop_gtextUNICODE ), TRUE );
4316 if ( SeekToContent( DFF_Prop_gtextFont, rStCt ) )
4317 MSDFFReadZString( rStCt, aFontName, GetPropertyValue( DFF_Prop_gtextFont ), TRUE );
4318 if ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x2000 )
4320 // Text ist senkrecht formatiert, Box Kippen
4321 INT32 nHalfWidth = ( rBoundRect.GetWidth() + 1) >> 1;
4322 INT32 nHalfHeight = ( rBoundRect.GetHeight() + 1) >> 1;
4323 Point aTopLeft( rBoundRect.Left() + nHalfWidth - nHalfHeight,
4324 rBoundRect.Top() + nHalfHeight - nHalfWidth);
4325 Size aNewSize( rBoundRect.GetHeight(), rBoundRect.GetWidth() );
4326 Rectangle aNewRect( aTopLeft, aNewSize );
4327 rBoundRect = aNewRect;
4329 String aSrcText( aObjectText );
4330 aObjectText.Erase();
4331 for( UINT16 a = 0; a < aSrcText.Len(); a++ )
4333 aObjectText += aSrcText.GetChar( a );
4334 aObjectText += '\n';
4336 rSet.Put( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_CENTER ) );
4337 bTextRotate = TRUE;
4339 if ( aObjectText.Len() )
4340 { // FontWork-Objekt Mit dem Text in aObjectText erzeugen
4341 SdrObject* pNewObj = new SdrRectObj( OBJ_TEXT, rBoundRect );
4342 if( pNewObj )
4344 pNewObj->SetModel( pSdrModel );
4345 ((SdrRectObj*)pNewObj)->SetText( aObjectText );
4346 SdrFitToSizeType eFTS = SDRTEXTFIT_PROPORTIONAL;
4347 rSet.Put( SdrTextFitToSizeTypeItem( eFTS ) );
4348 rSet.Put( SdrTextAutoGrowHeightItem( FALSE ) );
4349 rSet.Put( SdrTextAutoGrowWidthItem( FALSE ) );
4350 rSet.Put( SvxFontItem( FAMILY_DONTKNOW, aFontName, String(),
4351 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO ));
4353 pNewObj->SetMergedItemSet(rSet);
4355 pRet = pNewObj->ConvertToPolyObj( FALSE, FALSE );
4356 if( !pRet )
4357 pRet = pNewObj;
4358 else
4360 pRet->NbcSetSnapRect( rBoundRect );
4361 SdrObject::Free( pNewObj );
4363 if( bTextRotate )
4365 double a = 9000 * nPi180;
4366 pRet->NbcRotate( rBoundRect.Center(), 9000, sin( a ), cos( a ) );
4370 return pRet;
4373 static Size lcl_GetPrefSize(const Graphic& rGraf, MapMode aWanted)
4375 MapMode aPrefMapMode(rGraf.GetPrefMapMode());
4376 if (aPrefMapMode == aWanted)
4377 return rGraf.GetPrefSize();
4378 Size aRetSize;
4379 if (aPrefMapMode == MAP_PIXEL)
4381 aRetSize = Application::GetDefaultDevice()->PixelToLogic(
4382 rGraf.GetPrefSize(), aWanted);
4384 else
4386 aRetSize = Application::GetDefaultDevice()->LogicToLogic(
4387 rGraf.GetPrefSize(), rGraf.GetPrefMapMode(), aWanted);
4389 return aRetSize;
4392 // sj: if the parameter pSet is null, then the resulting crop bitmap will be stored in rGraf,
4393 // otherwise rGraf is untouched and pSet is used to store the corresponding SdrGrafCropItem
4394 static void lcl_ApplyCropping( const DffPropSet& rPropSet, SfxItemSet* pSet, Graphic& rGraf )
4396 sal_Int32 nCropTop = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromTop, 0 );
4397 sal_Int32 nCropBottom = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromBottom, 0 );
4398 sal_Int32 nCropLeft = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromLeft, 0 );
4399 sal_Int32 nCropRight = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromRight, 0 );
4401 if( nCropTop || nCropBottom || nCropLeft || nCropRight )
4403 double fFactor;
4404 Size aCropSize;
4405 BitmapEx aCropBitmap;
4406 sal_uInt32 nTop( 0 ), nBottom( 0 ), nLeft( 0 ), nRight( 0 );
4408 if ( pSet ) // use crop attributes ?
4409 aCropSize = lcl_GetPrefSize( rGraf, MAP_100TH_MM );
4410 else
4412 aCropBitmap = rGraf.GetBitmapEx();
4413 aCropSize = aCropBitmap.GetSizePixel();
4415 if ( nCropTop )
4417 fFactor = (double)nCropTop / 65536.0;
4418 nTop = (sal_uInt32)( ( (double)( aCropSize.Height() + 1 ) * fFactor ) + 0.5 );
4420 if ( nCropBottom )
4422 fFactor = (double)nCropBottom / 65536.0;
4423 nBottom = (sal_uInt32)( ( (double)( aCropSize.Height() + 1 ) * fFactor ) + 0.5 );
4425 if ( nCropLeft )
4427 fFactor = (double)nCropLeft / 65536.0;
4428 nLeft = (sal_uInt32)( ( (double)( aCropSize.Width() + 1 ) * fFactor ) + 0.5 );
4430 if ( nCropRight )
4432 fFactor = (double)nCropRight / 65536.0;
4433 nRight = (sal_uInt32)( ( (double)( aCropSize.Width() + 1 ) * fFactor ) + 0.5 );
4435 if ( pSet ) // use crop attributes ?
4436 pSet->Put( SdrGrafCropItem( nLeft, nTop, nRight, nBottom ) );
4437 else
4439 Rectangle aCropRect( nLeft, nTop, aCropSize.Width() - nRight, aCropSize.Height() - nBottom );
4440 aCropBitmap.Crop( aCropRect );
4441 rGraf = aCropBitmap;
4446 SdrObject* SvxMSDffManager::ImportGraphic( SvStream& rSt, SfxItemSet& rSet, const DffObjData& rObjData ) const
4448 SdrObject* pRet = NULL;
4449 String aFilename;
4450 String aLinkFileName, aLinkFilterName;
4451 Rectangle aVisArea;
4453 MSO_BlipFlags eFlags = (MSO_BlipFlags)GetPropertyValue( DFF_Prop_pibFlags, mso_blipflagDefault );
4454 sal_uInt32 nBlipId = GetPropertyValue( DFF_Prop_pib, 0 );
4455 sal_Bool bGrfRead = sal_False,
4457 // Grafik verlinkt
4458 bLinkGrf = 0 != ( eFlags & mso_blipflagLinkToFile );
4460 Graphic aGraf; // be sure this graphic is deleted before swapping out
4461 if( SeekToContent( DFF_Prop_pibName, rSt ) )
4462 MSDFFReadZString( rSt, aFilename, GetPropertyValue( DFF_Prop_pibName ), TRUE );
4464 // UND, ODER folgendes:
4465 if( !( eFlags & mso_blipflagDoNotSave ) ) // Grafik embedded
4467 bGrfRead = GetBLIP( nBlipId, aGraf, &aVisArea );
4468 if ( !bGrfRead )
4471 Still no luck, lets look at the end of this record for a FBSE pool,
4472 this fallback is a specific case for how word does it sometimes
4474 rObjData.rSpHd.SeekToEndOfRecord( rSt );
4475 DffRecordHeader aHd;
4476 rSt >> aHd;
4477 if( DFF_msofbtBSE == aHd.nRecType )
4479 const ULONG nSkipBLIPLen = 20;
4480 const ULONG nSkipShapePos = 4;
4481 const ULONG nSkipBLIP = 4;
4482 const ULONG nSkip =
4483 nSkipBLIPLen + 4 + nSkipShapePos + 4 + nSkipBLIP;
4485 if (nSkip <= aHd.nRecLen)
4487 rSt.SeekRel(nSkip);
4488 if (0 == rSt.GetError())
4489 bGrfRead = GetBLIPDirect( rSt, aGraf, &aVisArea );
4494 if ( bGrfRead )
4496 // the writer is doing it's own cropping, so this part affects only impress and calc
4497 if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_CROP_BITMAPS )
4498 lcl_ApplyCropping( *this, ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 ? &rSet : NULL, aGraf );
4500 if ( IsProperty( DFF_Prop_pictureTransparent ) )
4502 UINT32 nTransColor = GetPropertyValue( DFF_Prop_pictureTransparent, 0 );
4504 if ( aGraf.GetType() == GRAPHIC_BITMAP )
4506 BitmapEx aBitmapEx( aGraf.GetBitmapEx() );
4507 Bitmap aBitmap( aBitmapEx.GetBitmap() );
4508 Bitmap aMask( aBitmap.CreateMask( MSO_CLR_ToColor( nTransColor, DFF_Prop_pictureTransparent ), 9 ) );
4509 if ( aBitmapEx.IsTransparent() )
4510 aMask.CombineSimple( aBitmapEx.GetMask(), BMP_COMBINE_OR );
4511 aGraf = BitmapEx( aBitmap, aMask );
4515 sal_Int32 nContrast = GetPropertyValue( DFF_Prop_pictureContrast, 0x10000 );
4517 0x10000 is msoffice 50%
4518 < 0x10000 is in units of 1/50th of 0x10000 per 1%
4519 > 0x10000 is in units where
4520 a msoffice x% is stored as 50/(100-x) * 0x10000
4522 plus, a (ui) microsoft % ranges from 0 to 100, OOO
4523 from -100 to 100, so also normalize into that range
4525 if ( nContrast > 0x10000 )
4527 double fX = nContrast;
4528 fX /= 0x10000;
4529 fX /= 51; // 50 + 1 to round
4530 fX = 1/fX;
4531 nContrast = static_cast<sal_Int32>(fX);
4532 nContrast -= 100;
4533 nContrast = -nContrast;
4534 nContrast = (nContrast-50)*2;
4536 else if ( nContrast == 0x10000 )
4537 nContrast = 0;
4538 else
4540 nContrast *= 101; //100 + 1 to round
4541 nContrast /= 0x10000;
4542 nContrast -= 100;
4544 sal_Int16 nBrightness = (sal_Int16)( (sal_Int32)GetPropertyValue( DFF_Prop_pictureBrightness, 0 ) / 327 );
4545 sal_Int32 nGamma = GetPropertyValue( DFF_Prop_pictureGamma, 0x10000 );
4546 GraphicDrawMode eDrawMode = GRAPHICDRAWMODE_STANDARD;
4547 switch ( GetPropertyValue( DFF_Prop_pictureActive ) & 6 )
4549 case 4 : eDrawMode = GRAPHICDRAWMODE_GREYS; break;
4550 case 6 : eDrawMode = GRAPHICDRAWMODE_MONO; break;
4551 case 0 :
4553 //office considers the converted values of (in OOo) 70 to be the
4554 //"watermark" values, which can vary slightly due to rounding from the
4555 //above values
4556 if (( nContrast == -70 ) && ( nBrightness == 70 ))
4558 nContrast = 0;
4559 nBrightness = 0;
4560 eDrawMode = GRAPHICDRAWMODE_WATERMARK;
4563 break;
4566 if ( nContrast || nBrightness || ( nGamma != 0x10000 ) || ( eDrawMode != GRAPHICDRAWMODE_STANDARD ) )
4568 if ( ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 )
4570 if ( nBrightness )
4571 rSet.Put( SdrGrafLuminanceItem( nBrightness ) );
4572 if ( nContrast )
4573 rSet.Put( SdrGrafContrastItem( (sal_Int16)nContrast ) );
4574 if ( nGamma != 0x10000 )
4575 rSet.Put( SdrGrafGamma100Item( nGamma / 655 ) );
4576 if ( eDrawMode != GRAPHICDRAWMODE_STANDARD )
4577 rSet.Put( SdrGrafModeItem( eDrawMode ) );
4579 else
4581 if ( eDrawMode == GRAPHICDRAWMODE_WATERMARK )
4583 nContrast = 60;
4584 nBrightness = 70;
4585 eDrawMode = GRAPHICDRAWMODE_STANDARD;
4587 switch ( aGraf.GetType() )
4589 case GRAPHIC_BITMAP :
4591 BitmapEx aBitmapEx( aGraf.GetBitmapEx() );
4592 if ( nBrightness || nContrast || ( nGamma != 0x10000 ) )
4593 aBitmapEx.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, FALSE );
4594 if ( eDrawMode == GRAPHICDRAWMODE_GREYS )
4595 aBitmapEx.Convert( BMP_CONVERSION_8BIT_GREYS );
4596 else if ( eDrawMode == GRAPHICDRAWMODE_MONO )
4597 aBitmapEx.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
4598 aGraf = aBitmapEx;
4601 break;
4603 case GRAPHIC_GDIMETAFILE :
4605 GDIMetaFile aGdiMetaFile( aGraf.GetGDIMetaFile() );
4606 if ( nBrightness || nContrast || ( nGamma != 0x10000 ) )
4607 aGdiMetaFile.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, FALSE );
4608 if ( eDrawMode == GRAPHICDRAWMODE_GREYS )
4609 aGdiMetaFile.Convert( MTF_CONVERSION_8BIT_GREYS );
4610 else if ( eDrawMode == GRAPHICDRAWMODE_MONO )
4611 aGdiMetaFile.Convert( MTF_CONVERSION_1BIT_THRESHOLD );
4612 aGraf = aGdiMetaFile;
4614 break;
4615 default: break;
4621 // sollte es ein OLE-Object sein?
4622 if( bGrfRead && !bLinkGrf && IsProperty( DFF_Prop_pictureId ) )
4624 // TODO/LATER: in future probably the correct aspect should be provided here
4625 sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
4626 // --> OD 2004-12-14 #i32596# - pass <nCalledByGroup> to method
4627 pRet = ImportOLE( GetPropertyValue( DFF_Prop_pictureId ), aGraf, rObjData.aBoundRect, aVisArea, rObjData.nCalledByGroup, nAspect );
4628 // <--
4630 if( !pRet )
4632 pRet = new SdrGrafObj;
4633 if( bGrfRead )
4634 ((SdrGrafObj*)pRet)->SetGraphic( aGraf );
4636 if( bLinkGrf && !bGrfRead ) // sj: #i55484# if the graphic was embedded ( bGrfRead == true ) then
4637 { // we do not need to set a link. TODO: not to lose the information where the graphic is linked from
4638 UniString aName( ::URIHelper::SmartRel2Abs( INetURLObject(maBaseURL), aFilename, URIHelper::GetMaybeFileHdl(), true, false,
4639 INetURLObject::WAS_ENCODED,
4640 INetURLObject::DECODE_UNAMBIGUOUS ) );
4642 String aFilterName;
4643 INetURLObject aURLObj( aName );
4645 if( aURLObj.GetProtocol() == INET_PROT_NOT_VALID )
4647 String aValidURL;
4649 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aValidURL ) )
4650 aURLObj = INetURLObject( aValidURL );
4653 if( aURLObj.GetProtocol() != INET_PROT_NOT_VALID )
4655 GraphicFilter* pGrfFilter = GetGrfFilter();
4656 aFilterName = pGrfFilter->GetImportFormatName(
4657 pGrfFilter->GetImportFormatNumberForShortName( aURLObj.getExtension() ) );
4660 aLinkFileName = aName;
4661 aLinkFilterName = aFilterName;
4665 // set the size from BLIP if there is one
4666 if ( pRet && bGrfRead && !aVisArea.IsEmpty() )
4667 pRet->SetBLIPSizeRectangle( aVisArea );
4669 if ( !pRet->GetName().Len() ) // SJ 22.02.00 : PPT OLE IMPORT:
4670 { // name is already set in ImportOLE !!
4671 // JP 01.12.99: SetName before SetModel - because in the other order the Bug 70098 is active
4672 if ( ( eFlags & mso_blipflagType ) != mso_blipflagComment )
4674 INetURLObject aURL;
4675 aURL.SetSmartURL( aFilename );
4676 pRet->SetName( aURL.getBase() );
4678 else
4679 pRet->SetName( aFilename );
4682 pRet->SetModel( pSdrModel ); // fuer GraphicLink erforderlich
4683 pRet->SetLogicRect( rObjData.aBoundRect );
4685 if ( pRet->ISA( SdrGrafObj ) )
4687 if( aLinkFileName.Len() )
4688 ((SdrGrafObj*)pRet)->SetGraphicLink( aLinkFileName, aLinkFilterName );
4690 if ( bLinkGrf && !bGrfRead )
4692 ((SdrGrafObj*)pRet)->ForceSwapIn();
4693 Graphic aGraf(((SdrGrafObj*)pRet)->GetGraphic());
4694 lcl_ApplyCropping( *this, &rSet, aGraf );
4696 ((SdrGrafObj*)pRet)->ForceSwapOut();
4699 return pRet;
4702 // PptSlidePersistEntry& rPersistEntry, SdPage* pPage
4703 SdrObject* SvxMSDffManager::ImportObj( SvStream& rSt, void* pClientData,
4704 Rectangle& rClientRect, const Rectangle& rGlobalChildRect, int nCalledByGroup, sal_Int32* pShapeId )
4706 SdrObject* pRet = NULL;
4707 DffRecordHeader aObjHd;
4708 rSt >> aObjHd;
4709 if ( aObjHd.nRecType == DFF_msofbtSpgrContainer )
4711 pRet = ImportGroup( aObjHd, rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup, pShapeId );
4713 else if ( aObjHd.nRecType == DFF_msofbtSpContainer )
4715 pRet = ImportShape( aObjHd, rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup, pShapeId );
4717 aObjHd.SeekToBegOfRecord( rSt ); // FilePos restaurieren
4718 return pRet;
4721 SdrObject* SvxMSDffManager::ImportGroup( const DffRecordHeader& rHd, SvStream& rSt, void* pClientData,
4722 Rectangle& rClientRect, const Rectangle& rGlobalChildRect,
4723 int nCalledByGroup, sal_Int32* pShapeId )
4725 SdrObject* pRet = NULL;
4727 if( pShapeId )
4728 *pShapeId = 0;
4730 rHd.SeekToContent( rSt );
4731 DffRecordHeader aRecHd; // the first atom has to be the SpContainer for the GroupObject
4732 rSt >> aRecHd;
4733 if ( aRecHd.nRecType == DFF_msofbtSpContainer )
4735 INT32 nGroupRotateAngle = 0;
4736 INT32 nSpFlags = 0;
4737 mnFix16Angle = 0;
4738 aRecHd.SeekToBegOfRecord( rSt );
4739 pRet = ImportObj( rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup + 1, pShapeId );
4740 if ( pRet )
4742 nSpFlags = nGroupShapeFlags;
4743 nGroupRotateAngle = mnFix16Angle;
4745 Rectangle aClientRect( rClientRect );
4747 Rectangle aGlobalChildRect;
4748 if ( !nCalledByGroup || rGlobalChildRect.IsEmpty() )
4749 aGlobalChildRect = GetGlobalChildAnchor( rHd, rSt, aClientRect );
4750 else
4751 aGlobalChildRect = rGlobalChildRect;
4753 if ( ( nGroupRotateAngle > 4500 && nGroupRotateAngle <= 13500 )
4754 || ( nGroupRotateAngle > 22500 && nGroupRotateAngle <= 31500 ) )
4756 sal_Int32 nHalfWidth = ( aClientRect.GetWidth() + 1 ) >> 1;
4757 sal_Int32 nHalfHeight = ( aClientRect.GetHeight() + 1 ) >> 1;
4758 Point aTopLeft( aClientRect.Left() + nHalfWidth - nHalfHeight,
4759 aClientRect.Top() + nHalfHeight - nHalfWidth );
4760 Size aNewSize( aClientRect.GetHeight(), aClientRect.GetWidth() );
4761 Rectangle aNewRect( aTopLeft, aNewSize );
4762 aClientRect = aNewRect;
4765 // now importing the inner objects of the group
4766 aRecHd.SeekToEndOfRecord( rSt );
4767 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
4769 DffRecordHeader aRecHd2;
4770 rSt >> aRecHd2;
4771 if ( aRecHd2.nRecType == DFF_msofbtSpgrContainer )
4773 Rectangle aGroupClientAnchor, aGroupChildAnchor;
4774 GetGroupAnchors( aRecHd2, rSt, aGroupClientAnchor, aGroupChildAnchor, aClientRect, aGlobalChildRect );
4775 aRecHd2.SeekToBegOfRecord( rSt );
4776 sal_Int32 nShapeId;
4777 SdrObject* pTmp = ImportGroup( aRecHd2, rSt, pClientData, aGroupClientAnchor, aGroupChildAnchor, nCalledByGroup + 1, &nShapeId );
4778 if ( pTmp )
4780 ((SdrObjGroup*)pRet)->GetSubList()->NbcInsertObject( pTmp );
4781 if( nShapeId )
4782 insertShapeId( nShapeId, pTmp );
4785 else if ( aRecHd2.nRecType == DFF_msofbtSpContainer )
4787 aRecHd2.SeekToBegOfRecord( rSt );
4788 sal_Int32 nShapeId;
4789 SdrObject* pTmp = ImportShape( aRecHd2, rSt, pClientData, aClientRect, aGlobalChildRect, nCalledByGroup + 1, &nShapeId );
4790 if ( pTmp )
4792 ((SdrObjGroup*)pRet)->GetSubList()->NbcInsertObject( pTmp );
4793 if( nShapeId )
4794 insertShapeId( nShapeId, pTmp );
4797 aRecHd2.SeekToEndOfRecord( rSt );
4800 // pRet->NbcSetSnapRect( aGroupBound );
4801 if ( nGroupRotateAngle )
4803 double a = nGroupRotateAngle * nPi180;
4804 pRet->NbcRotate( aClientRect.Center(), nGroupRotateAngle, sin( a ), cos( a ) );
4806 if ( nSpFlags & SP_FFLIPV ) // Vertikal gespiegelt?
4807 { // BoundRect in aBoundRect
4808 Point aLeft( aClientRect.Left(), ( aClientRect.Top() + aClientRect.Bottom() ) >> 1 );
4809 Point aRight( aLeft.X() + 1000, aLeft.Y() );
4810 pRet->NbcMirror( aLeft, aRight );
4812 if ( nSpFlags & SP_FFLIPH ) // Horizontal gespiegelt?
4813 { // BoundRect in aBoundRect
4814 Point aTop( ( aClientRect.Left() + aClientRect.Right() ) >> 1, aClientRect.Top() );
4815 Point aBottom( aTop.X(), aTop.Y() + 1000 );
4816 pRet->NbcMirror( aTop, aBottom );
4820 return pRet;
4823 SdrObject* SvxMSDffManager::ImportShape( const DffRecordHeader& rHd, SvStream& rSt, void* pClientData,
4824 Rectangle& rClientRect, const Rectangle& rGlobalChildRect,
4825 int nCalledByGroup, sal_Int32* pShapeId )
4827 SdrObject* pRet = NULL;
4829 if( pShapeId )
4830 *pShapeId = 0;
4832 rHd.SeekToBegOfRecord( rSt );
4833 DffObjData aObjData( rHd, rClientRect, nCalledByGroup );
4834 maShapeRecords.Consume( rSt, FALSE );
4835 aObjData.bShapeType = maShapeRecords.SeekToContent( rSt, DFF_msofbtSp, SEEK_FROM_BEGINNING );
4836 if ( aObjData.bShapeType )
4838 rSt >> aObjData.nShapeId
4839 >> aObjData.nSpFlags;
4840 aObjData.eShapeType = (MSO_SPT)maShapeRecords.Current()->nRecInstance;
4842 else
4844 aObjData.nShapeId = 0;
4845 aObjData.nSpFlags = 0;
4846 aObjData.eShapeType = mso_sptNil;
4849 if( pShapeId )
4850 *pShapeId = aObjData.nShapeId;
4852 if ( mbTracing )
4853 mpTracer->AddAttribute( aObjData.nSpFlags & SP_FGROUP
4854 ? rtl::OUString::createFromAscii( "GroupShape" )
4855 : rtl::OUString::createFromAscii( "Shape" ),
4856 rtl::OUString::valueOf( (sal_Int32)aObjData.nShapeId ) );
4857 aObjData.bOpt = maShapeRecords.SeekToContent( rSt, DFF_msofbtOPT, SEEK_FROM_CURRENT_AND_RESTART );
4858 if ( aObjData.bOpt )
4860 maShapeRecords.Current()->SeekToBegOfRecord( rSt );
4861 #ifdef DBG_AUTOSHAPE
4862 ReadPropSet( rSt, pClientData, (UINT32)aObjData.eShapeType );
4863 #else
4864 ReadPropSet( rSt, pClientData );
4865 #endif
4867 else
4869 InitializePropSet(); // get the default PropSet
4870 ( (DffPropertyReader*) this )->mnFix16Angle = 0;
4873 aObjData.bChildAnchor = maShapeRecords.SeekToContent( rSt, DFF_msofbtChildAnchor, SEEK_FROM_CURRENT_AND_RESTART );
4874 if ( aObjData.bChildAnchor )
4876 INT32 l, o, r, u;
4877 rSt >> l >> o >> r >> u;
4878 Scale( l );
4879 Scale( o );
4880 Scale( r );
4881 Scale( u );
4882 aObjData.aChildAnchor = Rectangle( l, o, r, u );
4883 if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() )
4885 double fl = l;
4886 double fo = o;
4887 double fWidth = r - l;
4888 double fHeight= u - o;
4889 double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth();
4890 double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight();
4891 fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left();
4892 fo = ( ( o - rGlobalChildRect.Top() ) * fYScale ) + rClientRect.Top();
4893 fWidth *= fXScale;
4894 fHeight *= fYScale;
4895 aObjData.aChildAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) );
4899 aObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt, DFF_msofbtClientAnchor, SEEK_FROM_CURRENT_AND_RESTART );
4900 if ( aObjData.bClientAnchor )
4901 ProcessClientAnchor2( rSt, *maShapeRecords.Current(), pClientData, aObjData );
4903 if ( aObjData.bChildAnchor )
4904 aObjData.aBoundRect = aObjData.aChildAnchor;
4906 if ( aObjData.nSpFlags & SP_FBACKGROUND )
4907 aObjData.aBoundRect = Rectangle( Point(), Size( 1, 1 ) );
4909 Rectangle aTextRect;
4910 if ( !aObjData.aBoundRect.IsEmpty() )
4911 { // Rotation auf BoundingBox anwenden, BEVOR ien Objekt generiert wurde
4912 if( mnFix16Angle )
4914 long nAngle = mnFix16Angle;
4915 if ( ( nAngle > 4500 && nAngle <= 13500 ) || ( nAngle > 22500 && nAngle <= 31500 ) )
4917 INT32 nHalfWidth = ( aObjData.aBoundRect.GetWidth() + 1 ) >> 1;
4918 INT32 nHalfHeight = ( aObjData.aBoundRect.GetHeight() + 1 ) >> 1;
4919 Point aTopLeft( aObjData.aBoundRect.Left() + nHalfWidth - nHalfHeight,
4920 aObjData.aBoundRect.Top() + nHalfHeight - nHalfWidth );
4921 Size aNewSize( aObjData.aBoundRect.GetHeight(), aObjData.aBoundRect.GetWidth() );
4922 Rectangle aNewRect( aTopLeft, aNewSize );
4923 aObjData.aBoundRect = aNewRect;
4926 aTextRect = aObjData.aBoundRect;
4927 FASTBOOL bGraphic = IsProperty( DFF_Prop_pib ) ||
4928 IsProperty( DFF_Prop_pibName ) ||
4929 IsProperty( DFF_Prop_pibFlags );
4931 if ( aObjData.nSpFlags & SP_FGROUP )
4933 pRet = new SdrObjGroup;
4934 /* After CWS aw033 has been integrated, an empty group object
4935 cannot store its resulting bounding rectangle anymore. We have
4936 to return this rectangle via rClientRect now, but only, if
4937 caller has not passed an own bounding ractangle. */
4938 if ( rClientRect.IsEmpty() )
4939 rClientRect = aObjData.aBoundRect;
4940 nGroupShapeFlags = aObjData.nSpFlags; // #73013#
4942 else if ( ( aObjData.eShapeType != mso_sptNil ) || IsProperty( DFF_Prop_pVertices ) || bGraphic )
4944 SfxItemSet aSet( pSdrModel->GetItemPool() );
4946 sal_Bool bIsConnector = ( ( aObjData.eShapeType >= mso_sptStraightConnector1 ) && ( aObjData.eShapeType <= mso_sptCurvedConnector5 ) );
4947 sal_Bool bIsCustomShape = sal_False;
4948 sal_Int32 nObjectRotation = mnFix16Angle;
4949 sal_uInt32 nSpFlags = aObjData.nSpFlags;
4951 if ( bGraphic )
4953 pRet = ImportGraphic( rSt, aSet, aObjData ); // SJ: #68396# is no longer true (fixed in ppt2000)
4954 ApplyAttributes( rSt, aSet, aObjData );
4955 pRet->SetMergedItemSet(aSet);
4957 else if ( aObjData.eShapeType == mso_sptLine )
4959 basegfx::B2DPolygon aPoly;
4960 aPoly.append(basegfx::B2DPoint(aObjData.aBoundRect.Left(), aObjData.aBoundRect.Top()));
4961 aPoly.append(basegfx::B2DPoint(aObjData.aBoundRect.Right(), aObjData.aBoundRect.Bottom()));
4962 pRet = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aPoly));
4963 pRet->SetModel( pSdrModel );
4964 ApplyAttributes( rSt, aSet, aObjData );
4965 pRet->SetMergedItemSet(aSet);
4967 else
4969 if ( GetCustomShapeContent( aObjData.eShapeType ) || IsProperty( DFF_Prop_pVertices ) )
4972 ApplyAttributes( rSt, aSet, aObjData );
4974 // the com.sun.star.drawing.EnhancedCustomShapeEngine is default, so we do not need to set a hard attribute
4975 // aSet.Put( SdrCustomShapeEngineItem( String::CreateFromAscii( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) ) );
4976 pRet = new SdrObjCustomShape();
4977 pRet->SetModel( pSdrModel );
4979 sal_Bool bIsFontwork = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x4000 ) != 0;
4981 // in case of a FontWork, the text is set by the escher import
4982 if ( bIsFontwork )
4984 String aObjectText;
4985 String aFontName;
4986 MSO_GeoTextAlign eGeoTextAlign;
4988 if ( SeekToContent( DFF_Prop_gtextFont, rSt ) )
4990 SvxFontItem aLatin(EE_CHAR_FONTINFO), aAsian(EE_CHAR_FONTINFO_CJK), aComplex(EE_CHAR_FONTINFO_CTL);
4991 GetDefaultFonts( aLatin, aAsian, aComplex );
4993 MSDFFReadZString( rSt, aFontName, GetPropertyValue( DFF_Prop_gtextFont ), TRUE );
4994 aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
4995 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO ));
4996 aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
4997 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO_CJK ) );
4998 aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
4999 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO_CTL ) );
5002 // SJ: applying fontattributes for Fontwork :
5003 if ( IsHardAttribute( DFF_Prop_gtextFItalic ) )
5004 aSet.Put( SvxPostureItem( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x0010 ) != 0 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) );
5006 if ( IsHardAttribute( DFF_Prop_gtextFBold ) )
5007 aSet.Put( SvxWeightItem( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x0020 ) != 0 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) );
5009 // SJ TODO: Vertical Writing is not correct, instead this should be
5010 // replaced through "CharacterRotation" by 90°, therefore a new Item has to be
5011 // supported by svx core, api and xml file format
5012 ((SdrObjCustomShape*)pRet)->SetVerticalWriting( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x2000 ) != 0 );
5014 if ( SeekToContent( DFF_Prop_gtextUNICODE, rSt ) )
5016 MSDFFReadZString( rSt, aObjectText, GetPropertyValue( DFF_Prop_gtextUNICODE ), TRUE );
5017 ReadObjText( aObjectText, pRet );
5020 eGeoTextAlign = ( (MSO_GeoTextAlign)GetPropertyValue( DFF_Prop_gtextAlign, mso_alignTextCenter ) );
5022 SdrTextHorzAdjust eHorzAdjust;
5023 switch( eGeoTextAlign )
5025 case mso_alignTextLetterJust :
5026 case mso_alignTextWordJust :
5027 case mso_alignTextStretch : eHorzAdjust = SDRTEXTHORZADJUST_BLOCK; break;
5028 default:
5029 case mso_alignTextInvalid :
5030 case mso_alignTextCenter : eHorzAdjust = SDRTEXTHORZADJUST_CENTER; break;
5031 case mso_alignTextLeft : eHorzAdjust = SDRTEXTHORZADJUST_LEFT; break;
5032 case mso_alignTextRight : eHorzAdjust = SDRTEXTHORZADJUST_RIGHT; break;
5034 aSet.Put( SdrTextHorzAdjustItem( eHorzAdjust ) );
5036 SdrFitToSizeType eFTS = SDRTEXTFIT_NONE;
5037 if ( eGeoTextAlign == mso_alignTextStretch )
5038 eFTS = SDRTEXTFIT_ALLLINES;
5039 aSet.Put( SdrTextFitToSizeTypeItem( eFTS ) );
5041 if ( IsProperty( DFF_Prop_gtextSpacing ) )
5043 sal_Int32 nTextWidth = GetPropertyValue( DFF_Prop_gtextSpacing, 100 < 16 ) / 655;
5044 if ( nTextWidth != 100 )
5045 aSet.Put( SvxCharScaleWidthItem( (sal_uInt16)nTextWidth, EE_CHAR_FONTWIDTH ) );
5047 if ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x1000 ) // SJ: Font Kerning On ?
5048 aSet.Put( SvxKerningItem( 1, EE_CHAR_KERNING ) );
5050 pRet->SetMergedItemSet( aSet );
5052 // sj: taking care of rtl, ltr. In case of fontwork mso. seems not to be able to set
5053 // proper text directions, instead the text default is depending to the string.
5054 // so we have to calculate the a text direction from string:
5055 if ( bIsFontwork )
5057 OutlinerParaObject* pParaObj = ((SdrObjCustomShape*)pRet)->GetOutlinerParaObject();
5058 if ( pParaObj )
5060 SdrOutliner& rOutliner = ((SdrObjCustomShape*)pRet)->ImpGetDrawOutliner();
5061 BOOL bOldUpdateMode = rOutliner.GetUpdateMode();
5062 SdrModel* pModel = pRet->GetModel();
5063 if ( pModel )
5064 rOutliner.SetStyleSheetPool( (SfxStyleSheetPool*)pModel->GetStyleSheetPool() );
5065 rOutliner.SetUpdateMode( FALSE );
5066 rOutliner.SetText( *pParaObj );
5067 VirtualDevice aVirDev( 1 );
5068 aVirDev.SetMapMode( MAP_100TH_MM );
5069 sal_uInt32 i, nParagraphs = rOutliner.GetParagraphCount();
5070 if ( nParagraphs )
5072 sal_Bool bCreateNewParaObject = sal_False;
5073 for ( i = 0; i < nParagraphs; i++ )
5075 BOOL bIsRTL = aVirDev.GetTextIsRTL( rOutliner.GetText( rOutliner.GetParagraph( i ) ), 0, STRING_LEN );
5076 if ( bIsRTL )
5078 SfxItemSet aSet2( rOutliner.GetParaAttribs( (USHORT)i ) );
5079 aSet2.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
5080 rOutliner.SetParaAttribs( (USHORT)i, aSet2 );
5081 bCreateNewParaObject = sal_True;
5084 if ( bCreateNewParaObject )
5086 OutlinerParaObject* pNewText = rOutliner.CreateParaObject();
5087 rOutliner.Init( OUTLINERMODE_TEXTOBJECT );
5088 ((SdrObjCustomShape*)pRet)->NbcSetOutlinerParaObject( pNewText );
5091 rOutliner.Clear();
5092 rOutliner.SetUpdateMode( bOldUpdateMode );
5096 // mso_sptArc special treating:
5097 // sj: since we actually can't render the arc because of its weird SnapRect settings,
5098 // we will create a new CustomShape, that can be saved/loaded without problems.
5099 // We will change the shape type, so this code applys only if importing arcs from msoffice.
5100 if ( aObjData.eShapeType == mso_sptArc )
5102 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
5103 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
5104 const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM ( "Handles" ) );
5105 const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM ( "Equations" ) );
5106 const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
5107 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
5108 const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
5109 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
5110 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates;
5111 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > seqAdjustmentValues;
5113 // before clearing the GeometryItem we have to store the current Coordinates
5114 const uno::Any* pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates );
5115 Rectangle aPolyBoundRect;
5116 if ( pAny && ( *pAny >>= seqCoordinates ) && ( seqCoordinates.getLength() >= 4 ) )
5118 sal_Int32 nPtNum, nNumElemVert = seqCoordinates.getLength();
5119 XPolygon aXP( (sal_uInt16)nNumElemVert );
5120 // const EnhancedCustomShapeParameterPair* pTmp = seqCoordinates.getArray();
5121 for ( nPtNum = 0; nPtNum < nNumElemVert; nPtNum++ )
5123 Point aP;
5124 sal_Int32 nX = 0, nY = 0;
5125 seqCoordinates[ nPtNum ].First.Value >>= nX;
5126 seqCoordinates[ nPtNum ].Second.Value >>= nY;
5127 aP.X() = nX;
5128 aP.Y() = nY;
5129 aXP[ (sal_uInt16)nPtNum ] = aP;
5131 aPolyBoundRect = Rectangle( aXP.GetBoundRect() );
5133 else
5134 aPolyBoundRect = Rectangle( -21600, 0, 21600, 43200 ); // defaulting
5136 // clearing items, so MergeDefaultAttributes will set the corresponding defaults from EnhancedCustomShapeGeometry
5137 aGeometryItem.ClearPropertyValue( sHandles );
5138 aGeometryItem.ClearPropertyValue( sEquations );
5139 aGeometryItem.ClearPropertyValue( sViewBox );
5140 aGeometryItem.ClearPropertyValue( sPath );
5142 sal_Int32 nEndAngle = 9000;
5143 sal_Int32 nStartAngle = 0;
5144 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sAdjustmentValues );
5145 if ( pAny && ( *pAny >>= seqAdjustmentValues ) && seqAdjustmentValues.getLength() > 1 )
5147 double fNumber;
5148 if ( seqAdjustmentValues[ 0 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE )
5150 seqAdjustmentValues[ 0 ].Value >>= fNumber;
5151 nEndAngle = NormAngle360( - (sal_Int32)fNumber * 100 );
5153 else
5155 fNumber = 270.0;
5156 seqAdjustmentValues[ 0 ].Value <<= fNumber;
5157 seqAdjustmentValues[ 0 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE; // so this value will properly be stored
5160 if ( seqAdjustmentValues[ 1 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE )
5162 seqAdjustmentValues[ 1 ].Value >>= fNumber;
5163 nStartAngle = NormAngle360( - (sal_Int32)fNumber * 100 );
5165 else
5167 fNumber = 0.0;
5168 seqAdjustmentValues[ 0 ].Value <<= fNumber;
5169 seqAdjustmentValues[ 1 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;
5172 PropertyValue aPropVal;
5173 aPropVal.Name = sAdjustmentValues;
5174 aPropVal.Value <<= seqAdjustmentValues;
5175 aGeometryItem.SetPropertyValue( aPropVal ); // storing the angle attribute
5177 if ( nStartAngle != nEndAngle )
5179 XPolygon aXPoly( aPolyBoundRect.Center(), aPolyBoundRect.GetWidth() / 2, aPolyBoundRect.GetHeight() / 2,
5180 (USHORT)nStartAngle / 10, (USHORT)nEndAngle / 10, TRUE );
5181 Rectangle aPolyPieRect( aXPoly.GetBoundRect() );
5183 double fYScale, fXScale;
5184 double fYOfs, fXOfs;
5186 Point aP( aObjData.aBoundRect.Center() );
5187 Size aS( aObjData.aBoundRect.GetSize() );
5188 aP.X() -= aS.Width() / 2;
5189 aP.Y() -= aS.Height() / 2;
5190 Rectangle aLogicRect( aP, aS );
5192 fYOfs = fXOfs = 0.0;
5194 if ( aPolyBoundRect.GetWidth() && aPolyPieRect.GetWidth() )
5196 fXScale = (double)aLogicRect.GetWidth() / (double)aPolyPieRect.GetWidth();
5197 if ( nSpFlags & SP_FFLIPH )
5198 fXOfs = ( (double)aPolyPieRect.Right() - (double)aPolyBoundRect.Right() ) * fXScale;
5199 else
5200 fXOfs = ( (double)aPolyBoundRect.Left() - (double)aPolyPieRect.Left() ) * fXScale;
5202 if ( aPolyBoundRect.GetHeight() && aPolyPieRect.GetHeight() )
5204 fYScale = (double)aLogicRect.GetHeight() / (double)aPolyPieRect.GetHeight();
5205 if ( nSpFlags & SP_FFLIPV )
5206 fYOfs = ( (double)aPolyPieRect.Bottom() - (double)aPolyBoundRect.Bottom() ) * fYScale;
5207 else
5208 fYOfs = ((double)aPolyBoundRect.Top() - (double)aPolyPieRect.Top() ) * fYScale;
5211 fXScale = (double)aPolyBoundRect.GetWidth() / (double)aPolyPieRect.GetWidth();
5212 fYScale = (double)aPolyBoundRect.GetHeight() / (double)aPolyPieRect.GetHeight();
5214 Rectangle aOldBoundRect( aObjData.aBoundRect );
5215 aObjData.aBoundRect = Rectangle( Point( aLogicRect.Left() + (sal_Int32)fXOfs, aLogicRect.Top() + (sal_Int32)fYOfs ),
5216 Size( (sal_Int32)( aLogicRect.GetWidth() * fXScale ), (sal_Int32)( aLogicRect.GetHeight() * fYScale ) ) );
5218 // creating the text frame -> scaling into (0,0),(21600,21600) destination coordinate system
5219 double fTextFrameScaleX = (double)21600 / (double)aPolyBoundRect.GetWidth();
5220 double fTextFrameScaleY = (double)21600 / (double)aPolyBoundRect.GetHeight();
5221 sal_Int32 nLeft = (sal_Int32)(( aPolyPieRect.Left() - aPolyBoundRect.Left() ) * fTextFrameScaleX );
5222 sal_Int32 nTop = (sal_Int32)(( aPolyPieRect.Top() - aPolyBoundRect.Top() ) * fTextFrameScaleY );
5223 sal_Int32 nRight = (sal_Int32)(( aPolyPieRect.Right() - aPolyBoundRect.Left() ) * fTextFrameScaleX );
5224 sal_Int32 nBottom= (sal_Int32)(( aPolyPieRect.Bottom()- aPolyBoundRect.Top() ) * fTextFrameScaleY );
5225 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrame( 1 );
5226 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.First, nLeft );
5227 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.Second, nTop );
5228 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.First, nRight );
5229 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.Second,nBottom );
5230 PropertyValue aProp;
5231 aProp.Name = sTextFrames;
5232 aProp.Value <<= aTextFrame;
5233 aGeometryItem.SetPropertyValue( sPath, aProp );
5235 // sj: taking care of the different rotation points, since the new arc is having a bigger snaprect
5236 if ( mnFix16Angle )
5238 sal_Int32 nAngle = mnFix16Angle;
5239 if ( nSpFlags & SP_FFLIPH )
5240 nAngle = 36000 - nAngle;
5241 if ( nSpFlags & SP_FFLIPV )
5242 nAngle = -nAngle;
5243 double a = nAngle * F_PI18000;
5244 double ss = sin( a );
5245 double cc = cos( a );
5246 Point aP1( aOldBoundRect.TopLeft() );
5247 Point aC1( aObjData.aBoundRect.Center() );
5248 Point aP2( aOldBoundRect.TopLeft() );
5249 Point aC2( aOldBoundRect.Center() );
5250 RotatePoint( aP1, aC1, ss, cc );
5251 RotatePoint( aP2, aC2, ss, cc );
5252 aObjData.aBoundRect.Move( aP2.X() - aP1.X(), aP2.Y() - aP1.Y() );
5255 ((SdrObjCustomShape*)pRet)->SetMergedItem( aGeometryItem );
5256 ((SdrObjCustomShape*)pRet)->MergeDefaultAttributes();
5258 // now setting a new name, so the above correction is only done once when importing from ms
5259 SdrCustomShapeGeometryItem aGeoName( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
5260 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
5261 const rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM ( "mso-spt100" ) );
5262 PropertyValue aPropVal;
5263 aPropVal.Name = sType;
5264 aPropVal.Value <<= sName;
5265 aGeoName.SetPropertyValue( aPropVal );
5266 ((SdrObjCustomShape*)pRet)->SetMergedItem( aGeoName );
5268 else
5269 ((SdrObjCustomShape*)pRet)->MergeDefaultAttributes();
5271 pRet->SetSnapRect( aObjData.aBoundRect );
5272 EnhancedCustomShape2d aCustomShape2d( pRet );
5273 aTextRect = aCustomShape2d.GetTextRect();
5275 bIsCustomShape = TRUE;
5277 if( bIsConnector )
5279 if( nObjectRotation )
5281 double a = nObjectRotation * nPi180;
5282 pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) );
5284 // Horizontal gespiegelt?
5285 if ( nSpFlags & SP_FFLIPH )
5287 Rectangle aBndRect( pRet->GetSnapRect() );
5288 Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() );
5289 Point aBottom( aTop.X(), aTop.Y() + 1000 );
5290 pRet->NbcMirror( aTop, aBottom );
5292 // Vertikal gespiegelt?
5293 if ( nSpFlags & SP_FFLIPV )
5295 Rectangle aBndRect( pRet->GetSnapRect() );
5296 Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 );
5297 Point aRight( aLeft.X() + 1000, aLeft.Y() );
5298 pRet->NbcMirror( aLeft, aRight );
5300 basegfx::B2DPolyPolygon aPoly( SdrObjCustomShape::GetLineGeometry( (SdrObjCustomShape*)pRet, sal_True ) );
5301 SdrObject::Free( pRet );
5303 pRet = new SdrEdgeObj();
5304 pRet->SetLogicRect( aObjData.aBoundRect );
5306 // Konnektoren
5307 MSO_ConnectorStyle eConnectorStyle = (MSO_ConnectorStyle)GetPropertyValue( DFF_Prop_cxstyle, mso_cxstyleStraight );
5309 ((SdrEdgeObj*)pRet)->ConnectToNode(TRUE, NULL);
5310 ((SdrEdgeObj*)pRet)->ConnectToNode(FALSE, NULL);
5312 Point aPoint1( aObjData.aBoundRect.TopLeft() );
5313 Point aPoint2( aObjData.aBoundRect.BottomRight() );
5315 // Rotationen beachten
5316 if ( nObjectRotation )
5318 double a = nObjectRotation * nPi180;
5319 Point aCenter( aObjData.aBoundRect.Center() );
5320 double ss = sin(a);
5321 double cc = cos(a);
5323 RotatePoint(aPoint1, aCenter, ss, cc);
5324 RotatePoint(aPoint2, aCenter, ss, cc);
5327 // Linie innerhalb des Bereiches zurechtdrehen/spiegeln
5328 if ( nSpFlags & SP_FFLIPH )
5330 INT32 n = aPoint1.X();
5331 aPoint1.X() = aPoint2.X();
5332 aPoint2.X() = n;
5334 if ( nSpFlags & SP_FFLIPV )
5336 INT32 n = aPoint1.Y();
5337 aPoint1.Y() = aPoint2.Y();
5338 aPoint2.Y() = n;
5340 nSpFlags &= ~( SP_FFLIPV | SP_FFLIPH );
5342 pRet->NbcSetPoint(aPoint1, 0L); // Startpunkt
5343 pRet->NbcSetPoint(aPoint2, 1L); // Endpunkt
5345 sal_Int32 n1HorzDist, n1VertDist, n2HorzDist, n2VertDist;
5346 n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 0;
5347 switch( eConnectorStyle )
5349 case mso_cxstyleBent:
5351 aSet.Put( SdrEdgeKindItem( SDREDGE_ORTHOLINES ) );
5352 n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 630;
5354 break;
5355 case mso_cxstyleCurved:
5356 aSet.Put( SdrEdgeKindItem( SDREDGE_BEZIER ) );
5357 break;
5358 default: // mso_cxstyleStraight || mso_cxstyleNone
5359 aSet.Put( SdrEdgeKindItem( SDREDGE_ONELINE ) );
5360 break;
5362 aSet.Put( SdrEdgeNode1HorzDistItem( n1HorzDist ) );
5363 aSet.Put( SdrEdgeNode1VertDistItem( n1VertDist ) );
5364 aSet.Put( SdrEdgeNode2HorzDistItem( n2HorzDist ) );
5365 aSet.Put( SdrEdgeNode2VertDistItem( n2VertDist ) );
5367 ((SdrEdgeObj*)pRet)->SetEdgeTrackPath( aPoly );
5372 if ( pRet )
5374 if( nObjectRotation )
5376 double a = nObjectRotation * nPi180;
5377 pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) );
5379 // Horizontal gespiegelt?
5380 if ( nSpFlags & SP_FFLIPH )
5382 Rectangle aBndRect( pRet->GetSnapRect() );
5383 Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() );
5384 Point aBottom( aTop.X(), aTop.Y() + 1000 );
5385 pRet->NbcMirror( aTop, aBottom );
5387 // Vertikal gespiegelt?
5388 if ( nSpFlags & SP_FFLIPV )
5390 Rectangle aBndRect( pRet->GetSnapRect() );
5391 Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 );
5392 Point aRight( aLeft.X() + 1000, aLeft.Y() );
5393 pRet->NbcMirror( aLeft, aRight );
5399 // #i51348# #118052# name of the shape
5400 if( pRet )
5402 ::rtl::OUString aObjName = GetPropertyString( DFF_Prop_wzName, rSt );
5403 if( aObjName.getLength() > 0 )
5404 pRet->SetName( aObjName );
5407 pRet =
5408 ProcessObj( rSt, aObjData, pClientData, aTextRect, pRet);
5410 if ( mbTracing )
5411 mpTracer->RemoveAttribute( aObjData.nSpFlags & SP_FGROUP
5412 ? rtl::OUString::createFromAscii( "GroupShape" )
5413 : rtl::OUString::createFromAscii( "Shape" ) );
5414 return pRet;
5417 Rectangle SvxMSDffManager::GetGlobalChildAnchor( const DffRecordHeader& rHd, SvStream& rSt, Rectangle& aClientRect )
5419 Rectangle aChildAnchor;
5420 rHd.SeekToContent( rSt );
5421 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
5423 DffRecordHeader aShapeHd;
5424 rSt >> aShapeHd;
5425 if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) ||
5426 ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) )
5428 DffRecordHeader aShapeHd2( aShapeHd );
5429 if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer )
5430 rSt >> aShapeHd2;
5431 while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) )
5433 DffRecordHeader aShapeAtom;
5434 rSt >> aShapeAtom;
5436 if ( aShapeAtom.nRecType == DFF_msofbtClientAnchor )
5438 if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_PPT )
5440 sal_Int32 l, t, r, b;
5441 if ( aShapeAtom.nRecLen == 16 )
5443 rSt >> l >> t >> r >> b;
5445 else
5447 INT16 ls, ts, rs, bs;
5448 rSt >> ts >> ls >> rs >> bs; // etwas seltsame Koordinatenreihenfolge ...
5449 l = ls, t = ts, r = rs, b = bs;
5451 Scale( l );
5452 Scale( t );
5453 Scale( r );
5454 Scale( b );
5455 aClientRect = Rectangle( l, t, r, b );
5457 break;
5459 else if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor )
5461 sal_Int32 l, o, r, u;
5462 rSt >> l >> o >> r >> u;
5463 Scale( l );
5464 Scale( o );
5465 Scale( r );
5466 Scale( u );
5467 Rectangle aChild( l, o, r, u );
5468 aChildAnchor.Union( aChild );
5469 break;
5471 aShapeAtom.SeekToEndOfRecord( rSt );
5474 aShapeHd.SeekToEndOfRecord( rSt );
5476 return aChildAnchor;
5479 void SvxMSDffManager::GetGroupAnchors( const DffRecordHeader& rHd, SvStream& rSt,
5480 Rectangle& rGroupClientAnchor, Rectangle& rGroupChildAnchor,
5481 const Rectangle& rClientRect, const Rectangle& rGlobalChildRect )
5483 sal_Bool bFirst = sal_True;
5484 rHd.SeekToContent( rSt );
5485 DffRecordHeader aShapeHd;
5486 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
5488 rSt >> aShapeHd;
5489 if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) ||
5490 ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) )
5492 DffRecordHeader aShapeHd2( aShapeHd );
5493 if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer )
5494 rSt >> aShapeHd2;
5495 while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) )
5497 DffRecordHeader aShapeAtom;
5498 rSt >> aShapeAtom;
5499 if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor )
5501 sal_Int32 l, o, r, u;
5502 rSt >> l >> o >> r >> u;
5503 Scale( l );
5504 Scale( o );
5505 Scale( r );
5506 Scale( u );
5507 Rectangle aChild( l, o, r, u );
5509 if ( bFirst )
5511 if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() )
5513 double fl = l;
5514 double fo = o;
5515 double fWidth = r - l;
5516 double fHeight= u - o;
5517 double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth();
5518 double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight();
5519 fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left();
5520 fo = ( ( o - rGlobalChildRect.Top() ) * fYScale ) + rClientRect.Top();
5521 fWidth *= fXScale;
5522 fHeight *= fYScale;
5523 rGroupClientAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) );
5525 bFirst = sal_False;
5527 else
5528 rGroupChildAnchor.Union( aChild );
5529 break;
5531 aShapeAtom.SeekToEndOfRecord( rSt );
5534 aShapeHd.SeekToEndOfRecord( rSt );
5538 SdrObject* SvxMSDffManager::ProcessObj(SvStream& rSt,
5539 DffObjData& rObjData,
5540 void* pData,
5541 Rectangle& rTextRect,
5542 SdrObject* pObj
5545 if( !rTextRect.IsEmpty() )
5547 SvxMSDffImportData& rImportData = *(SvxMSDffImportData*)pData;
5548 SvxMSDffImportRec* pImpRec = new SvxMSDffImportRec;
5549 SvxMSDffImportRec* pTextImpRec = pImpRec;
5551 // fill Import Record with data
5552 pImpRec->nShapeId = rObjData.nShapeId;
5553 pImpRec->eShapeType = rObjData.eShapeType;
5555 MSO_WrapMode eWrapMode( (MSO_WrapMode)GetPropertyValue(
5556 DFF_Prop_WrapText,
5557 mso_wrapSquare ) );
5558 rObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt,
5559 DFF_msofbtClientAnchor,
5560 SEEK_FROM_CURRENT_AND_RESTART );
5561 if( rObjData.bClientAnchor )
5562 ProcessClientAnchor( rSt,
5563 maShapeRecords.Current()->nRecLen,
5564 pImpRec->pClientAnchorBuffer, pImpRec->nClientAnchorLen );
5566 rObjData.bClientData = maShapeRecords.SeekToContent( rSt,
5567 DFF_msofbtClientData,
5568 SEEK_FROM_CURRENT_AND_RESTART );
5569 if( rObjData.bClientData )
5570 ProcessClientData( rSt,
5571 maShapeRecords.Current()->nRecLen,
5572 pImpRec->pClientDataBuffer, pImpRec->nClientDataLen );
5575 // process user (== Winword) defined parameters in 0xF122 record
5576 if( maShapeRecords.SeekToContent( rSt,
5577 DFF_msofbtUDefProp,
5578 SEEK_FROM_CURRENT_AND_RESTART )
5579 && maShapeRecords.Current()->nRecLen )
5581 UINT32 nBytesLeft = maShapeRecords.Current()->nRecLen;
5582 UINT32 nUDData;
5583 UINT16 nPID;
5584 while( 5 < nBytesLeft )
5586 rSt >> nPID;
5587 if ( rSt.GetError() != 0 )
5588 break;
5589 rSt >> nUDData;
5590 switch( nPID )
5592 case 0x038F: pImpRec->nXAlign = nUDData; break;
5593 case 0x0390: pImpRec->nXRelTo = nUDData; break;
5594 case 0x0391: pImpRec->nYAlign = nUDData; break;
5595 case 0x0392: pImpRec->nYRelTo = nUDData; break;
5596 case 0x03BF: pImpRec->nLayoutInTableCell = nUDData; break;
5598 if ( rSt.GetError() != 0 )
5599 break;
5600 pImpRec->bHasUDefProp = TRUE;
5601 nBytesLeft -= 6;
5605 // Textrahmen, auch Title oder Outline
5606 SdrObject* pOrgObj = pObj;
5607 SdrRectObj* pTextObj = 0;
5608 UINT32 nTextId = GetPropertyValue( DFF_Prop_lTxid, 0 );
5609 if( nTextId )
5611 SfxItemSet aSet( pSdrModel->GetItemPool() );
5613 //Originally anything that as a mso_sptTextBox was created as a
5614 //textbox, this was changed for #88277# to be created as a simple
5615 //rect to keep impress happy. For the rest of us we'd like to turn
5616 //it back into a textbox again.
5617 FASTBOOL bTextFrame = (pImpRec->eShapeType == mso_sptTextBox);
5618 if (!bTextFrame)
5620 //Either
5621 //a) its a simple text object or
5622 //b) its a rectangle with text and square wrapping.
5623 bTextFrame =
5625 (pImpRec->eShapeType == mso_sptTextSimple) ||
5627 (pImpRec->eShapeType == mso_sptRectangle)
5628 && (eWrapMode == mso_wrapSquare)
5629 && ShapeHasText(pImpRec->nShapeId, rObjData.rSpHd.GetRecBegFilePos() )
5634 if (bTextFrame)
5636 SdrObject::Free( pObj );
5637 pObj = pOrgObj = 0;
5640 // Distance of Textbox to it's surrounding Customshape
5641 INT32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 91440L);
5642 INT32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 91440L );
5643 INT32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 45720L );
5644 INT32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 45720L );
5646 ScaleEmu( nTextLeft );
5647 ScaleEmu( nTextRight );
5648 ScaleEmu( nTextTop );
5649 ScaleEmu( nTextBottom );
5651 INT32 nTextRotationAngle=0;
5652 bool bVerticalText = false;
5653 if ( IsProperty( DFF_Prop_txflTextFlow ) )
5655 MSO_TextFlow eTextFlow = (MSO_TextFlow)(GetPropertyValue(
5656 DFF_Prop_txflTextFlow) & 0xFFFF);
5657 switch( eTextFlow )
5659 case mso_txflBtoT:
5660 nTextRotationAngle = 9000;
5661 break;
5662 case mso_txflVertN:
5663 case mso_txflTtoBN:
5664 nTextRotationAngle = 27000;
5665 break;
5666 case mso_txflTtoBA:
5667 bVerticalText = true;
5668 break;
5669 case mso_txflHorzA:
5670 bVerticalText = true;
5671 nTextRotationAngle = 9000;
5672 case mso_txflHorzN:
5673 default :
5674 break;
5678 if (nTextRotationAngle)
5680 while (nTextRotationAngle > 360000)
5681 nTextRotationAngle-=9000;
5682 switch (nTextRotationAngle)
5684 case 9000:
5686 long nWidth = rTextRect.GetWidth();
5687 rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight();
5688 rTextRect.Bottom() = rTextRect.Top() + nWidth;
5690 INT32 nOldTextLeft = nTextLeft;
5691 INT32 nOldTextRight = nTextRight;
5692 INT32 nOldTextTop = nTextTop;
5693 INT32 nOldTextBottom = nTextBottom;
5695 nTextLeft = nOldTextBottom;
5696 nTextRight = nOldTextTop;
5697 nTextTop = nOldTextLeft;
5698 nTextBottom = nOldTextRight;
5700 break;
5701 case 27000:
5703 long nWidth = rTextRect.GetWidth();
5704 rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight();
5705 rTextRect.Bottom() = rTextRect.Top() + nWidth;
5707 INT32 nOldTextLeft = nTextLeft;
5708 INT32 nOldTextRight = nTextRight;
5709 INT32 nOldTextTop = nTextTop;
5710 INT32 nOldTextBottom = nTextBottom;
5712 nTextLeft = nOldTextTop;
5713 nTextRight = nOldTextBottom;
5714 nTextTop = nOldTextRight;
5715 nTextBottom = nOldTextLeft;
5717 break;
5718 default:
5719 break;
5723 pTextObj = new SdrRectObj(OBJ_TEXT, rTextRect);
5724 pTextImpRec = new SvxMSDffImportRec(*pImpRec);
5726 // Die vertikalen Absatzeinrueckungen sind im BoundRect mit drin,
5727 // hier rausrechnen
5728 Rectangle aNewRect(rTextRect);
5729 aNewRect.Bottom() -= nTextTop + nTextBottom;
5730 aNewRect.Right() -= nTextLeft + nTextRight;
5732 // Nur falls es eine einfache Textbox ist, darf der Writer
5733 // das Objekt durch einen Rahmen ersetzen, ansonsten
5734 if( bTextFrame )
5736 SvxMSDffShapeInfo aTmpRec( 0, pImpRec->nShapeId );
5737 aTmpRec.bSortByShapeId = TRUE;
5739 USHORT nFound;
5740 if( pShapeInfos->Seek_Entry( &aTmpRec, &nFound ) )
5742 SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject(nFound);
5743 pTextImpRec->bReplaceByFly = rInfo.bReplaceByFly;
5744 pTextImpRec->bLastBoxInChain = rInfo.bLastBoxInChain;
5748 if( !pObj )
5749 ApplyAttributes( rSt, aSet, rObjData );
5751 bool bFitText = false;
5752 if (GetPropertyValue(DFF_Prop_FitTextToShape) & 2)
5754 aSet.Put( SdrTextAutoGrowHeightItem( TRUE ) );
5755 aSet.Put( SdrTextMinFrameHeightItem(
5756 aNewRect.Bottom() - aNewRect.Top() ) );
5757 aSet.Put( SdrTextMinFrameWidthItem(
5758 aNewRect.Right() - aNewRect.Left() ) );
5759 bFitText = true;
5761 else
5763 aSet.Put( SdrTextAutoGrowHeightItem( FALSE ) );
5764 aSet.Put( SdrTextAutoGrowWidthItem( FALSE ) );
5767 switch ( (MSO_WrapMode)
5768 GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) )
5770 case mso_wrapNone :
5771 aSet.Put( SdrTextAutoGrowWidthItem( TRUE ) );
5772 if (bFitText)
5774 //can't do autowidth in flys #i107184#
5775 pTextImpRec->bReplaceByFly = false;
5777 break;
5778 case mso_wrapByPoints :
5779 aSet.Put( SdrTextContourFrameItem( TRUE ) );
5780 break;
5781 default: break;
5784 // Abstaende an den Raendern der Textbox setzen
5785 aSet.Put( SdrTextLeftDistItem( nTextLeft ) );
5786 aSet.Put( SdrTextRightDistItem( nTextRight ) );
5787 aSet.Put( SdrTextUpperDistItem( nTextTop ) );
5788 aSet.Put( SdrTextLowerDistItem( nTextBottom ) );
5789 pTextImpRec->nDxTextLeft = nTextLeft;
5790 pTextImpRec->nDyTextTop = nTextTop;
5791 pTextImpRec->nDxTextRight = nTextRight;
5792 pTextImpRec->nDyTextBottom = nTextBottom;
5794 // Textverankerung lesen
5795 if ( IsProperty( DFF_Prop_anchorText ) )
5797 MSO_Anchor eTextAnchor =
5798 (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText );
5800 SdrTextVertAdjust eTVA = SDRTEXTVERTADJUST_CENTER;
5801 BOOL bTVASet(FALSE);
5802 SdrTextHorzAdjust eTHA = SDRTEXTHORZADJUST_CENTER;
5803 BOOL bTHASet(FALSE);
5805 switch( eTextAnchor )
5807 case mso_anchorTop:
5809 eTVA = SDRTEXTVERTADJUST_TOP;
5810 bTVASet = TRUE;
5812 break;
5813 case mso_anchorTopCentered:
5815 eTVA = SDRTEXTVERTADJUST_TOP;
5816 bTVASet = TRUE;
5817 bTHASet = TRUE;
5819 break;
5821 case mso_anchorMiddle:
5822 bTVASet = TRUE;
5823 break;
5824 case mso_anchorMiddleCentered:
5826 bTVASet = TRUE;
5827 bTHASet = TRUE;
5829 break;
5830 case mso_anchorBottom:
5832 eTVA = SDRTEXTVERTADJUST_BOTTOM;
5833 bTVASet = TRUE;
5835 break;
5836 case mso_anchorBottomCentered:
5838 eTVA = SDRTEXTVERTADJUST_BOTTOM;
5839 bTVASet = TRUE;
5840 bTHASet = TRUE;
5842 break;
5844 case mso_anchorTopBaseline:
5845 case mso_anchorBottomBaseline:
5846 case mso_anchorTopCenteredBaseline:
5847 case mso_anchorBottomCenteredBaseline:
5848 break;
5850 default : break;
5852 // Einsetzen
5853 if ( bTVASet )
5854 aSet.Put( SdrTextVertAdjustItem( eTVA ) );
5855 if ( bTHASet )
5856 aSet.Put( SdrTextHorzAdjustItem( eTHA ) );
5859 pTextObj->SetMergedItemSet(aSet);
5860 pTextObj->SetModel(pSdrModel);
5862 if (bVerticalText)
5863 pTextObj->SetVerticalWriting(sal_True);
5865 if (nTextRotationAngle)
5867 long nMinWH = rTextRect.GetWidth() < rTextRect.GetHeight() ?
5868 rTextRect.GetWidth() : rTextRect.GetHeight();
5869 nMinWH /= 2;
5870 Point aPivot(rTextRect.TopLeft());
5871 aPivot.X() += nMinWH;
5872 aPivot.Y() += nMinWH;
5873 double a = nTextRotationAngle * nPi180;
5874 pTextObj->NbcRotate(aPivot, nTextRotationAngle, sin(a), cos(a));
5877 // rotate text with shape ?
5878 if ( mnFix16Angle )
5880 double a = mnFix16Angle * nPi180;
5881 pTextObj->NbcRotate( rObjData.aBoundRect.Center(), mnFix16Angle,
5882 sin( a ), cos( a ) );
5885 if( !pObj )
5887 pObj = pTextObj;
5889 else
5891 if( pTextObj != pObj )
5893 SdrObject* pGroup = new SdrObjGroup;
5894 pGroup->GetSubList()->NbcInsertObject( pObj );
5895 pGroup->GetSubList()->NbcInsertObject( pTextObj );
5896 if (pOrgObj == pObj)
5897 pOrgObj = pGroup;
5898 else
5899 pOrgObj = pObj;
5900 pObj = pGroup;
5904 else if( !pObj )
5906 // simple rectangular objects are ignored by ImportObj() :-(
5907 // this is OK for Draw but not for Calc and Writer
5908 // cause here these objects have a default border
5909 pObj = new SdrRectObj(rTextRect);
5910 pOrgObj = pObj;
5911 pObj->SetModel( pSdrModel );
5912 SfxItemSet aSet( pSdrModel->GetItemPool() );
5913 ApplyAttributes( rSt, aSet, rObjData );
5915 const SfxPoolItem* pPoolItem=NULL;
5916 SfxItemState eState = aSet.GetItemState( XATTR_FILLCOLOR,
5917 FALSE, &pPoolItem );
5918 if( SFX_ITEM_DEFAULT == eState )
5919 aSet.Put( XFillColorItem( String(),
5920 Color( mnDefaultColor ) ) );
5921 pObj->SetMergedItemSet(aSet);
5924 //Means that fBehindDocument is set
5925 if (GetPropertyValue(DFF_Prop_fPrint) & 0x20)
5926 pImpRec->bDrawHell = TRUE;
5927 else
5928 pImpRec->bDrawHell = FALSE;
5929 if (GetPropertyValue(DFF_Prop_fPrint) & 0x02)
5930 pImpRec->bHidden = TRUE;
5931 pTextImpRec->bDrawHell = pImpRec->bDrawHell;
5932 pTextImpRec->bHidden = pImpRec->bHidden;
5933 pImpRec->nNextShapeId = GetPropertyValue( DFF_Prop_hspNext, 0 );
5934 pTextImpRec->nNextShapeId=pImpRec->nNextShapeId;
5936 if ( nTextId )
5938 pTextImpRec->aTextId.nTxBxS = (UINT16)( nTextId >> 16 );
5939 pTextImpRec->aTextId.nSequence = (UINT16)nTextId;
5942 pTextImpRec->nDxWrapDistLeft = GetPropertyValue(
5943 DFF_Prop_dxWrapDistLeft, 114935L ) / 635L;
5944 pTextImpRec->nDyWrapDistTop = GetPropertyValue(
5945 DFF_Prop_dyWrapDistTop, 0 ) / 635L;
5946 pTextImpRec->nDxWrapDistRight = GetPropertyValue(
5947 DFF_Prop_dxWrapDistRight, 114935L ) / 635L;
5948 pTextImpRec->nDyWrapDistBottom = GetPropertyValue(
5949 DFF_Prop_dyWrapDistBottom, 0 ) / 635L;
5950 // 16.16 fraction times total image width or height, as appropriate.
5952 if (SeekToContent(DFF_Prop_pWrapPolygonVertices, rSt))
5954 delete pTextImpRec->pWrapPolygon;
5955 sal_uInt16 nNumElemVert, nNumElemMemVert, nElemSizeVert;
5956 rSt >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
5957 if (nNumElemVert && ((nElemSizeVert == 8) || (nElemSizeVert == 4)))
5959 pTextImpRec->pWrapPolygon = new Polygon(nNumElemVert);
5960 for (sal_uInt16 i = 0; i < nNumElemVert; ++i)
5962 sal_Int32 nX, nY;
5963 if (nElemSizeVert == 8)
5964 rSt >> nX >> nY;
5965 else
5967 sal_Int16 nSmallX, nSmallY;
5968 rSt >> nSmallX >> nSmallY;
5969 nX = nSmallX;
5970 nY = nSmallY;
5972 (*(pTextImpRec->pWrapPolygon))[i].X() = nX;
5973 (*(pTextImpRec->pWrapPolygon))[i].Y() = nY;
5978 pImpRec->nCropFromTop = GetPropertyValue(
5979 DFF_Prop_cropFromTop, 0 );
5980 pImpRec->nCropFromBottom = GetPropertyValue(
5981 DFF_Prop_cropFromBottom, 0 );
5982 pImpRec->nCropFromLeft = GetPropertyValue(
5983 DFF_Prop_cropFromLeft, 0 );
5984 pImpRec->nCropFromRight = GetPropertyValue(
5985 DFF_Prop_cropFromRight, 0 );
5987 pImpRec->bVFlip = (rObjData.nSpFlags & SP_FFLIPV) ? true : false;
5988 pImpRec->bHFlip = (rObjData.nSpFlags & SP_FFLIPH) ? true : false;
5990 UINT32 nLineFlags = GetPropertyValue( DFF_Prop_fNoLineDrawDash );
5991 pImpRec->eLineStyle = (nLineFlags & 8)
5992 ? (MSO_LineStyle)GetPropertyValue(
5993 DFF_Prop_lineStyle,
5994 mso_lineSimple )
5995 : (MSO_LineStyle)USHRT_MAX;
5996 pTextImpRec->eLineStyle = pImpRec->eLineStyle;
5998 if( pImpRec->nShapeId )
6000 // Import-Record-Liste ergaenzen
6001 if( pOrgObj )
6003 pImpRec->pObj = pOrgObj;
6004 rImportData.aRecords.Insert( pImpRec );
6007 if( pTextObj && (pOrgObj != pTextObj) )
6009 // Modify ShapeId (must be unique)
6010 pImpRec->nShapeId |= 0x8000000;
6011 pTextImpRec->pObj = pTextObj;
6012 rImportData.aRecords.Insert( pTextImpRec );
6015 // Eintrag in Z-Order-Liste um Zeiger auf dieses Objekt ergaenzen
6016 /*Only store objects which are not deep inside the tree*/
6017 if( ( rObjData.nCalledByGroup == 0 )
6019 ( (rObjData.nSpFlags & SP_FGROUP)
6020 && (rObjData.nCalledByGroup < 2) )
6022 StoreShapeOrder( pImpRec->nShapeId,
6023 ( ( (ULONG)pImpRec->aTextId.nTxBxS ) << 16 )
6024 + pImpRec->aTextId.nSequence, pObj );
6026 else
6027 delete pImpRec;
6030 return pObj;
6033 void SvxMSDffManager::StoreShapeOrder(ULONG nId,
6034 ULONG nTxBx,
6035 SdrObject* pObject,
6036 SwFlyFrmFmt* pFly,
6037 short nHdFtSection) const
6039 USHORT nShpCnt = pShapeOrders->Count();
6040 for (USHORT nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
6042 SvxMSDffShapeOrder& rOrder
6043 = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
6045 if( rOrder.nShapeId == nId )
6047 rOrder.nTxBxComp = nTxBx;
6048 rOrder.pObj = pObject;
6049 rOrder.pFly = pFly;
6050 rOrder.nHdFtSection = nHdFtSection;
6056 void SvxMSDffManager::ExchangeInShapeOrder( SdrObject* pOldObject,
6057 ULONG nTxBx,
6058 SwFlyFrmFmt* pFly,
6059 SdrObject* pObject) const
6061 USHORT nShpCnt = pShapeOrders->Count();
6062 for (USHORT nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
6064 SvxMSDffShapeOrder& rOrder
6065 = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
6067 if( rOrder.pObj == pOldObject )
6069 rOrder.pFly = pFly;
6070 rOrder.pObj = pObject;
6071 rOrder.nTxBxComp = nTxBx;
6077 void SvxMSDffManager::RemoveFromShapeOrder( SdrObject* pObject ) const
6079 USHORT nShpCnt = pShapeOrders->Count();
6080 for (USHORT nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
6082 SvxMSDffShapeOrder& rOrder
6083 = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
6085 if( rOrder.pObj == pObject )
6087 rOrder.pObj = 0;
6088 rOrder.pFly = 0;
6089 rOrder.nTxBxComp = 0;
6097 //---------------------------------------------------------------------------
6098 // Hilfs Deklarationen
6099 //---------------------------------------------------------------------------
6101 /*struct SvxMSDffBLIPInfo -> in's Header-File
6103 USHORT nBLIPType; // Art des BLIP: z.B. 6 fuer PNG
6104 ULONG nFilePos; // Offset des BLIP im Daten-Stream
6105 ULONG nBLIPSize; // Anzahl Bytes, die der BLIP im Stream einnimmt
6106 SvxMSDffBLIPInfo(USHORT nBType, ULONG nFPos, ULONG nBSize):
6107 nBLIPType( nBType ), nFilePos( nFPos ), nBLIPSize( nBSize ){}
6111 SV_IMPL_PTRARR( SvxMSDffBLIPInfos, SvxMSDffBLIPInfo_Ptr );
6113 SV_IMPL_PTRARR( SvxMSDffShapeOrders, SvxMSDffShapeOrder_Ptr );
6115 SV_IMPL_OP_PTRARR_SORT( SvxMSDffShapeInfos, SvxMSDffShapeInfo_Ptr );
6117 SV_IMPL_OP_PTRARR_SORT( SvxMSDffShapeTxBxSort, SvxMSDffShapeOrder_Ptr );
6120 // Liste aller SvxMSDffImportRec fuer eine Gruppe
6121 SV_IMPL_OP_PTRARR_SORT(MSDffImportRecords, MSDffImportRec_Ptr)
6123 //---------------------------------------------------------------------------
6124 // exportierte Klasse: oeffentliche Methoden
6125 //---------------------------------------------------------------------------
6127 SvxMSDffManager::SvxMSDffManager(SvStream& rStCtrl_,
6128 const String& rBaseURL,
6129 long nOffsDgg_,
6130 SvStream* pStData_,
6131 SdrModel* pSdrModel_,// s. unten: SetModel()
6132 long nApplicationScale,
6133 ColorData mnDefaultColor_,
6134 ULONG nDefaultFontHeight_,
6135 SvStream* pStData2_,
6136 MSFilterTracer* pTracer )
6137 :DffPropertyReader( *this ),
6138 pFormModel( NULL ),
6139 pBLIPInfos( new SvxMSDffBLIPInfos ),
6140 pShapeInfos( new SvxMSDffShapeInfos ),
6141 pShapeOrders( new SvxMSDffShapeOrders ),
6142 nDefaultFontHeight( nDefaultFontHeight_),
6143 nOffsDgg( nOffsDgg_ ),
6144 nBLIPCount( USHRT_MAX ), // mit Error initialisieren, da wir erst pruefen,
6145 nShapeCount( USHRT_MAX ), // ob Kontroll-Stream korrekte Daten enthaellt
6146 maBaseURL( rBaseURL ),
6147 mpFidcls( NULL ),
6148 rStCtrl( rStCtrl_ ),
6149 pStData( pStData_ ),
6150 pStData2( pStData2_ ),
6151 nSvxMSDffSettings( 0 ),
6152 nSvxMSDffOLEConvFlags( 0 ),
6153 pEscherBlipCache( NULL ),
6154 mnDefaultColor( mnDefaultColor_),
6155 mpTracer( pTracer ),
6156 mbTracing( sal_False )
6158 if ( mpTracer )
6160 uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) );
6161 aAny >>= mbTracing;
6163 SetModel( pSdrModel_, nApplicationScale );
6165 // FilePos des/der Stream(s) merken
6166 ULONG nOldPosCtrl = rStCtrl.Tell();
6167 ULONG nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
6169 // Falls kein Datenstream angegeben, gehen wir davon aus,
6170 // dass die BLIPs im Steuerstream stehen.
6171 if( !pStData )
6172 pStData = &rStCtrl;
6174 SetDefaultPropSet( rStCtrl, nOffsDgg );
6176 // Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen
6177 GetCtrlData( nOffsDgg );
6179 // Text-Box-Story-Ketten-Infos ueberpruefen
6180 CheckTxBxStoryChain();
6182 // alte FilePos des/der Stream(s) restaurieren
6183 rStCtrl.Seek( nOldPosCtrl );
6184 if( &rStCtrl != pStData )
6185 pStData->Seek( nOldPosData );
6188 SvxMSDffManager::SvxMSDffManager( SvStream& rStCtrl_, const String& rBaseURL, MSFilterTracer* pTracer )
6189 :DffPropertyReader( *this ),
6190 pFormModel( NULL ),
6191 pBLIPInfos( new SvxMSDffBLIPInfos ),
6192 pShapeInfos( new SvxMSDffShapeInfos ),
6193 pShapeOrders( new SvxMSDffShapeOrders ),
6194 nDefaultFontHeight( 24 ),
6195 nOffsDgg( 0 ),
6196 nBLIPCount( USHRT_MAX ), // mit Error initialisieren, da wir erst pruefen,
6197 nShapeCount( USHRT_MAX ), // ob Kontroll-Stream korrekte Daten enthaellt
6198 maBaseURL( rBaseURL ),
6199 mpFidcls( NULL ),
6200 rStCtrl( rStCtrl_ ),
6201 pStData( 0 ),
6202 pStData2( 0 ),
6203 nSvxMSDffSettings( 0 ),
6204 nSvxMSDffOLEConvFlags( 0 ),
6205 pEscherBlipCache( NULL ),
6206 mnDefaultColor( COL_DEFAULT ),
6207 mpTracer( pTracer ),
6208 mbTracing( sal_False )
6210 if ( mpTracer )
6212 uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) );
6213 aAny >>= mbTracing;
6215 SetModel( NULL, 0 );
6218 SvxMSDffManager::~SvxMSDffManager()
6220 if ( pEscherBlipCache )
6222 void* pPtr;
6223 for ( pPtr = pEscherBlipCache->First(); pPtr; pPtr = pEscherBlipCache->Next() )
6224 delete (EscherBlipCacheEntry*)pPtr;
6225 delete pEscherBlipCache;
6227 delete pBLIPInfos;
6228 delete pShapeInfos;
6229 delete pShapeOrders;
6230 delete pFormModel;
6231 delete[] mpFidcls;
6234 void SvxMSDffManager::InitSvxMSDffManager( long nOffsDgg_, SvStream* pStData_, sal_uInt32 nOleConvFlags )
6236 nOffsDgg = nOffsDgg_;
6237 pStData = pStData_;
6238 nSvxMSDffOLEConvFlags = nOleConvFlags;
6240 // FilePos des/der Stream(s) merken
6241 ULONG nOldPosCtrl = rStCtrl.Tell();
6243 SetDefaultPropSet( rStCtrl, nOffsDgg );
6245 // insert fidcl cluster table
6246 GetFidclData( nOffsDgg );
6248 // Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen
6249 GetCtrlData( nOffsDgg );
6251 // Text-Box-Story-Ketten-Infos ueberpruefen
6252 CheckTxBxStoryChain();
6254 // alte FilePos des/der Stream(s) restaurieren
6255 rStCtrl.Seek( nOldPosCtrl );
6258 void SvxMSDffManager::SetDgContainer( SvStream& rSt )
6260 UINT32 nFilePos = rSt.Tell();
6261 DffRecordHeader aDgContHd;
6262 rSt >> aDgContHd;
6263 // insert this container only if there is also a DgAtom
6264 if ( SeekToRec( rSt, DFF_msofbtDg, aDgContHd.GetRecEndFilePos() ) )
6266 DffRecordHeader aRecHd;
6267 rSt >> aRecHd;
6268 UINT32 nDrawingId = aRecHd.nRecInstance;
6269 maDgOffsetTable.Insert( nDrawingId, (void*)nFilePos );
6270 rSt.Seek( nFilePos );
6274 void SvxMSDffManager::GetFidclData( long nOffsDggL )
6276 if ( nOffsDggL )
6278 UINT32 nDummy, nMerk = rStCtrl.Tell();
6279 rStCtrl.Seek( nOffsDggL );
6281 DffRecordHeader aRecHd;
6282 rStCtrl >> aRecHd;
6284 DffRecordHeader aDggAtomHd;
6285 if ( SeekToRec( rStCtrl, DFF_msofbtDgg, aRecHd.GetRecEndFilePos(), &aDggAtomHd ) )
6287 aDggAtomHd.SeekToContent( rStCtrl );
6288 rStCtrl >> mnCurMaxShapeId
6289 >> mnIdClusters
6290 >> nDummy
6291 >> mnDrawingsSaved;
6293 if ( mnIdClusters-- > 2 )
6295 if ( aDggAtomHd.nRecLen == ( mnIdClusters * sizeof( FIDCL ) + 16 ) )
6297 mpFidcls = new FIDCL[ mnIdClusters ];
6298 for ( UINT32 i = 0; i < mnIdClusters; i++ )
6300 rStCtrl >> mpFidcls[ i ].dgid
6301 >> mpFidcls[ i ].cspidCur;
6306 rStCtrl.Seek( nMerk );
6310 void SvxMSDffManager::CheckTxBxStoryChain()
6312 SvxMSDffShapeInfos* pOld = pShapeInfos;
6313 USHORT nCnt = pOld->Count();
6314 pShapeInfos = new SvxMSDffShapeInfos( (nCnt < 255)
6315 ? nCnt
6316 : 255 );
6317 // altes Info-Array ueberarbeiten
6318 // (ist sortiert nach nTxBxComp)
6319 ULONG nChain = ULONG_MAX;
6320 USHORT nObjMark = 0;
6321 BOOL bSetReplaceFALSE = FALSE;
6322 USHORT nObj;
6323 for( nObj = 0; nObj < nCnt; ++nObj )
6325 SvxMSDffShapeInfo* pObj = pOld->GetObject( nObj );
6326 if( pObj->nTxBxComp )
6328 pObj->bLastBoxInChain = FALSE;
6329 // Gruppenwechsel ?
6330 // --> OD 2008-07-28 #156763#
6331 // the text id also contains an internal drawing container id
6332 // to distinguish between text id of drawing objects in different
6333 // drawing containers.
6334 // if( nChain != (pObj->nTxBxComp & 0xFFFF0000) )
6335 if( nChain != pObj->nTxBxComp )
6336 // <--
6338 // voriger war letzter seiner Gruppe
6339 if( nObj )
6340 pOld->GetObject( nObj-1 )->bLastBoxInChain = TRUE;
6341 // Merker und Hilfs-Flag zuruecksetzen
6342 nObjMark = nObj;
6343 // --> OD 2008-07-28 #156763#
6344 // nChain = pObj->nTxBxComp & 0xFFFF0000;
6345 nChain = pObj->nTxBxComp;
6346 // <--
6347 bSetReplaceFALSE = !pObj->bReplaceByFly;
6349 else
6350 if( !pObj->bReplaceByFly )
6352 // Objekt, das NICHT durch Rahmen ersetzt werden darf ?
6353 // Hilfs-Flag setzen
6354 bSetReplaceFALSE = TRUE;
6355 // ggfs Flag in Anfang der Gruppe austragen
6356 for( USHORT nObj2 = nObjMark; nObj2 < nObj; ++nObj2 )
6357 pOld->GetObject( nObj2 )->bReplaceByFly = FALSE;
6360 if( bSetReplaceFALSE )
6362 pObj->bReplaceByFly = FALSE;
6365 // alle Shape-Info-Objekte in pShapeInfos umkopieren
6366 // (aber nach nShapeId sortieren)
6367 pObj->bSortByShapeId = TRUE;
6368 // --> OD 2008-07-28 #156763#
6369 pObj->nTxBxComp = pObj->nTxBxComp & 0xFFFF0000;
6370 // <--
6371 pShapeInfos->Insert( pObj );
6373 // voriger war letzter seiner Gruppe
6374 if( nObj )
6375 pOld->GetObject( nObj-1 )->bLastBoxInChain = TRUE;
6376 // urspruengliches Array freigeben, ohne Objekte zu zerstoeren
6377 pOld->Remove((USHORT)0, nCnt);
6378 delete pOld;
6382 /*****************************************************************************
6384 Einlesen der Shape-Infos im Ctor:
6385 ---------------------------------
6386 merken der Shape-Ids und zugehoerigen Blip-Nummern und TextBox-Infos
6387 ========= ============ =============
6388 und merken des File-Offsets fuer jedes Blip
6389 ============
6390 ******************************************************************************/
6391 void SvxMSDffManager::GetCtrlData( long nOffsDgg_ )
6393 // Start Offset unbedingt merken, falls wir nochmal aufsetzen muessen
6394 long nOffsDggL = nOffsDgg_;
6396 // Kontroll Stream positionieren
6397 rStCtrl.Seek( nOffsDggL );
6399 BYTE nVer;
6400 USHORT nInst;
6401 USHORT nFbt;
6402 UINT32 nLength;
6403 if( !this->ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) ) return;
6405 BOOL bOk;
6406 ULONG nPos = nOffsDggL + DFF_COMMON_RECORD_HEADER_SIZE;
6408 // Fall A: erst Drawing Group Container, dann n Mal Drawing Container
6409 if( DFF_msofbtDggContainer == nFbt )
6411 GetDrawingGroupContainerData( rStCtrl, nLength );
6413 rStCtrl.Seek( STREAM_SEEK_TO_END );
6414 UINT32 nMaxStrPos = rStCtrl.Tell();
6416 nPos += nLength;
6417 // --> OD 2008-07-28 #156763#
6418 unsigned long nDrawingContainerId = 1;
6419 // <--
6422 rStCtrl.Seek( nPos );
6424 bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) && ( DFF_msofbtDgContainer == nFbt );
6426 if( !bOk )
6428 nPos++;
6429 rStCtrl.Seek( nPos );
6430 bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength )
6431 && ( DFF_msofbtDgContainer == nFbt );
6433 if( bOk )
6435 // --> OD 2008-07-28 #156763#
6436 GetDrawingContainerData( rStCtrl, nLength, nDrawingContainerId );
6437 // <--
6439 nPos += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
6440 // --> OD 2008-07-28 #156763#
6441 ++nDrawingContainerId;
6442 // <--
6444 while( nPos < nMaxStrPos && bOk );
6449 // ab hier: Drawing Group Container d.h. Dokument - weit gueltige Daten
6450 // ======================= ========
6452 void SvxMSDffManager::GetDrawingGroupContainerData( SvStream& rSt, ULONG nLenDgg )
6454 BYTE nVer;
6455 USHORT nInst;
6456 USHORT nFbt;
6457 UINT32 nLength;
6459 ULONG nLenBStoreCont = 0, nLenFBSE = 0, nRead = 0;
6461 // Nach einem BStore Container suchen
6464 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
6465 nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
6466 if( DFF_msofbtBstoreContainer == nFbt )
6468 nLenBStoreCont = nLength; break;
6470 rSt.SeekRel( nLength );
6472 while( nRead < nLenDgg );
6474 if( !nLenBStoreCont ) return;
6476 // Im BStore Container alle Header der Container und Atome auslesen und die
6477 // relevanten Daten aller enthaltenen FBSEs in unserem Pointer Array ablegen.
6478 // Dabei zaehlen wir die gefundenen FBSEs im Member nBLIPCount mit.
6480 const ULONG nSkipBLIPLen = 20; // bis zu nBLIPLen zu ueberspringende Bytes
6481 const ULONG nSkipBLIPPos = 4; // dahinter bis zu nBLIPPos zu skippen
6483 sal_uInt32 nBLIPLen = 0, nBLIPPos = 0;
6485 nRead = 0;
6488 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
6489 nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
6490 if( DFF_msofbtBSE == nFbt )
6492 nLenFBSE = nLength;
6493 // ist FBSE gross genug fuer unsere Daten
6494 BOOL bOk = ( nSkipBLIPLen + 4 + nSkipBLIPPos + 4 <= nLenFBSE );
6496 if( bOk )
6498 rSt.SeekRel( nSkipBLIPLen );
6499 rSt >> nBLIPLen;
6500 rSt.SeekRel( nSkipBLIPPos );
6501 rSt >> nBLIPPos;
6502 bOk = rSt.GetError() == 0;
6504 nLength -= nSkipBLIPLen+ 4 + nSkipBLIPPos + 4;
6507 if( bOk )
6509 // Besonderheit:
6510 // Falls nBLIPLen kleiner ist als nLenFBSE UND nBLIPPos Null ist,
6511 // nehmen wir an, dass das Bild IM FBSE drin steht!
6512 if( (!nBLIPPos) && (nBLIPLen < nLenFBSE) )
6513 nBLIPPos = rSt.Tell() + 4;
6515 // Das hat ja fein geklappt!
6516 // Wir merken uns, dass wir einen FBSE mehr im Pointer Array haben.
6517 nBLIPPos = Calc_nBLIPPos(nBLIPPos, rSt.Tell());
6519 if( USHRT_MAX == nBLIPCount )
6520 nBLIPCount = 1;
6521 else
6522 nBLIPCount++;
6524 // Jetzt die Infos fuer spaetere Zugriffe speichern
6525 pBLIPInfos->Insert( new SvxMSDffBLIPInfo( nInst, nBLIPPos, nBLIPLen ),
6526 pBLIPInfos->Count() );
6529 rSt.SeekRel( nLength );
6531 while( nRead < nLenBStoreCont );
6535 // ab hier: Drawing Container d.h. Seiten (Blatt, Dia) - weit gueltige Daten
6536 // ================= ======
6538 void SvxMSDffManager::GetDrawingContainerData( SvStream& rSt, ULONG nLenDg,
6539 const unsigned long nDrawingContainerId )
6541 BYTE nVer;USHORT nInst;USHORT nFbt;UINT32 nLength;
6543 ULONG nReadDg = 0;
6545 // Wir stehen in einem Drawing Container (je einer pro Seite)
6546 // und muessen nun
6547 // alle enthaltenen Shape Group Container abklappern
6550 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
6551 nReadDg += DFF_COMMON_RECORD_HEADER_SIZE;
6552 // Patriarch gefunden (der oberste Shape Group Container) ?
6553 if( DFF_msofbtSpgrContainer == nFbt )
6555 if(!this->GetShapeGroupContainerData( rSt, nLength, TRUE, nDrawingContainerId )) return;
6557 else
6558 // blanker Shape Container ? (ausserhalb vom Shape Group Container)
6559 if( DFF_msofbtSpContainer == nFbt )
6561 if(!this->GetShapeContainerData( rSt, nLength, ULONG_MAX, nDrawingContainerId )) return;
6563 else
6564 rSt.SeekRel( nLength );
6565 nReadDg += nLength;
6567 while( nReadDg < nLenDg );
6570 BOOL SvxMSDffManager::GetShapeGroupContainerData( SvStream& rSt,
6571 ULONG nLenShapeGroupCont,
6572 BOOL bPatriarch,
6573 const unsigned long nDrawingContainerId )
6575 BYTE nVer;USHORT nInst;USHORT nFbt;UINT32 nLength;
6576 long nStartShapeGroupCont = rSt.Tell();
6577 // Wir stehen in einem Shape Group Container (ggfs. mehrere pro Seite)
6578 // und muessen nun
6579 // alle enthaltenen Shape Container abklappern
6580 BOOL bFirst = !bPatriarch;
6581 ULONG nReadSpGrCont = 0;
6584 if( !this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength ) )
6585 return FALSE;
6586 nReadSpGrCont += DFF_COMMON_RECORD_HEADER_SIZE;
6587 // Shape Container ?
6588 if( DFF_msofbtSpContainer == nFbt )
6590 ULONG nGroupOffs = bFirst ? nStartShapeGroupCont - DFF_COMMON_RECORD_HEADER_SIZE : ULONG_MAX;
6591 if ( !this->GetShapeContainerData( rSt, nLength, nGroupOffs, nDrawingContainerId ) )
6592 return FALSE;
6593 bFirst = FALSE;
6595 else
6596 // eingeschachtelter Shape Group Container ?
6597 if( DFF_msofbtSpgrContainer == nFbt )
6599 if ( !this->GetShapeGroupContainerData( rSt, nLength, FALSE, nDrawingContainerId ) )
6600 return FALSE;
6602 else
6603 rSt.SeekRel( nLength );
6604 nReadSpGrCont += nLength;
6606 while( nReadSpGrCont < nLenShapeGroupCont );
6607 // den Stream wieder korrekt positionieren
6608 rSt.Seek( nStartShapeGroupCont + nLenShapeGroupCont );
6609 return TRUE;
6612 BOOL SvxMSDffManager::GetShapeContainerData( SvStream& rSt,
6613 ULONG nLenShapeCont,
6614 ULONG nPosGroup,
6615 const unsigned long nDrawingContainerId )
6617 BYTE nVer;USHORT nInst;USHORT nFbt;UINT32 nLength;
6618 long nStartShapeCont = rSt.Tell();
6619 // Wir stehen in einem Shape Container (ggfs. mehrere pro Sh. Group)
6620 // und muessen nun
6621 // die Shape Id und File-Pos (fuer spaetere, erneute Zugriffe)
6622 // und den ersten BStore Verweis (falls vorhanden) entnehmen
6623 ULONG nLenShapePropTbl = 0;
6624 ULONG nReadSpCont = 0;
6626 // File Offset des Shape-Containers bzw. der Gruppe(!) vermerken
6628 ULONG nStartOffs = (ULONG_MAX > nPosGroup) ?
6629 nPosGroup : nStartShapeCont - DFF_COMMON_RECORD_HEADER_SIZE;
6630 SvxMSDffShapeInfo aInfo( nStartOffs );
6632 // duerfte das Shape durch einen Rahmen ersetzt werden ?
6633 // (vorausgesetzt, es zeigt sich, dass es eine TextBox ist,
6634 // und der Text nicht gedreht ist)
6635 BOOL bCanBeReplaced = (ULONG_MAX > nPosGroup) ? FALSE : TRUE;
6637 // wir wissen noch nicht, ob es eine TextBox ist
6638 MSO_SPT eShapeType = mso_sptNil;
6639 MSO_WrapMode eWrapMode = mso_wrapSquare;
6640 // BOOL bIsTextBox = FALSE;
6642 // Shape analysieren
6646 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return FALSE;
6647 nReadSpCont += DFF_COMMON_RECORD_HEADER_SIZE;
6648 // FSP ?
6649 if( ( DFF_msofbtSp == nFbt ) && ( 4 <= nLength ) )
6651 // Wir haben den FSP gefunden: Shape Typ und Id vermerken!
6652 eShapeType = (MSO_SPT)nInst;
6653 rSt >> aInfo.nShapeId;
6654 rSt.SeekRel( nLength - 4 );
6655 nReadSpCont += nLength;
6657 else if( DFF_msofbtOPT == nFbt ) // Shape Property Table ?
6659 // Wir haben die Property Table gefunden:
6660 // nach der Blip Property suchen!
6661 ULONG nPropRead = 0;
6662 USHORT nPropId;
6663 sal_uInt32 nPropVal;
6664 nLenShapePropTbl = nLength;
6665 // UINT32 nPropCount = nInst;
6666 long nStartShapePropTbl = rSt.Tell();
6667 // UINT32 nComplexDataFilePos = nStartShapePropTbl + (nPropCount * 6);
6670 rSt >> nPropId
6671 >> nPropVal;
6672 nPropRead += 6;
6674 switch( nPropId )
6676 case DFF_Prop_txflTextFlow :
6677 //Writer can now handle vertical textflows in its
6678 //native frames, to only need to do this for the
6679 //other two formats
6681 //Writer will handle all textflow except BtoT
6682 if (GetSvxMSDffSettings() &
6683 (SVXMSDFF_SETTINGS_IMPORT_PPT |
6684 SVXMSDFF_SETTINGS_IMPORT_EXCEL))
6686 if( 0 != nPropVal )
6687 bCanBeReplaced = false;
6689 else if (
6690 (nPropVal != mso_txflHorzN) &&
6691 (nPropVal != mso_txflTtoBA)
6694 bCanBeReplaced = false;
6696 break;
6697 case DFF_Prop_cdirFont :
6698 //Writer can now handle right to left and left
6699 //to right in its native frames, so only do
6700 //this for the other two formats.
6701 if (GetSvxMSDffSettings() &
6702 (SVXMSDFF_SETTINGS_IMPORT_PPT |
6703 SVXMSDFF_SETTINGS_IMPORT_EXCEL))
6705 if( 0 != nPropVal )
6706 bCanBeReplaced = FALSE;
6708 break;
6709 case DFF_Prop_Rotation :
6710 if( 0 != nPropVal )
6711 bCanBeReplaced = FALSE;
6712 break;
6714 case DFF_Prop_gtextFStrikethrough :
6715 if( ( 0x20002000 & nPropVal ) == 0x20002000 )
6716 bCanBeReplaced = FALSE;
6717 break;
6719 case DFF_Prop_fc3DLightFace :
6720 if( ( 0x00080008 & nPropVal ) == 0x00080008 )
6721 bCanBeReplaced = FALSE;
6722 break;
6724 case DFF_Prop_WrapText :
6725 eWrapMode = (MSO_WrapMode)nPropVal;
6726 break;
6728 default:
6730 // Bit gesetzt und gueltig?
6731 if( 0x4000 == ( nPropId & 0xC000 ) )
6733 // Blip Property gefunden: BStore Idx vermerken!
6734 nPropRead = nLenShapePropTbl;
6736 else if( 0x8000 & nPropId )
6738 // komplexe Prop gefunden:
6739 // Laenge ist immer 6, nur die Laenge der nach der
6740 // eigentlichen Prop-Table anhaengenden Extra-Daten
6741 // ist unterschiedlich
6742 nPropVal = 6;
6745 break;
6749 //JP 21.04.99: Bug 64510
6750 // alte Version, die unter OS/2 zu Compilerfehlern fuehrt und damit arge
6751 // Performance einbussen hat.
6753 if( 0x4000 == ( nPropId & 0xC000 ) )// Bit gesetzt und gueltig?
6755 // Blip Property gefunden: BStore Idx vermerken!
6756 aInfo.nBStoreIdx = nPropVal; // Index im BStore Container
6757 break;
6759 else
6760 if( ( ( (DFF_Prop_txflTextFlow == nPropId)
6761 || (DFF_Prop_Rotation == nPropId)
6762 || (DFF_Prop_cdirFont == nPropId) )
6763 && (0 != nPropVal) )
6765 || ( (DFF_Prop_gtextFStrikethrough == nPropId)
6766 && ( (0x20002000 & nPropVal) == 0x20002000) ) // also DFF_Prop_gtextFVertical
6767 || ( (DFF_Prop_fc3DLightFace == nPropId)
6768 && ( (0x00080008 & nPropVal) == 0x00080008) ) // also DFF_Prop_f3D
6771 bCanBeReplaced = FALSE; // Mist: gedrehter Text oder 3D-Objekt!
6773 else
6774 if( DFF_Prop_WrapText == nPropId )
6776 eWrapMode = (MSO_WrapMode)nPropVal;
6778 ////////////////////////////////////////////////////////////////
6779 ////////////////////////////////////////////////////////////////
6780 // keine weitere Property-Auswertung: folge beim Shape-Import //
6781 ////////////////////////////////////////////////////////////////
6782 ////////////////////////////////////////////////////////////////
6783 else
6784 if( 0x8000 & nPropId )
6786 // komplexe Prop gefunden: Laenge lesen und ueberspringen
6787 if(!SkipBytes( rSt, nPropVal )) return FALSE;
6788 nPropRead += nPropVal;
6792 while( nPropRead < nLenShapePropTbl );
6793 rSt.Seek( nStartShapePropTbl + nLenShapePropTbl );
6794 nReadSpCont += nLenShapePropTbl;
6796 else if( ( DFF_msofbtClientTextbox == nFbt ) && ( 4 == nLength ) ) // Text-Box-Story-Eintrag gefunden
6798 rSt >> aInfo.nTxBxComp;
6799 // --> OD 2008-07-28 #156763#
6800 // Add internal drawing container id to text id.
6801 // Note: The text id uses the first two bytes, while the internal
6802 // drawing container id used the second two bytes.
6803 aInfo.nTxBxComp = ( aInfo.nTxBxComp & 0xFFFF0000 ) +
6804 nDrawingContainerId;
6805 DBG_ASSERT( (aInfo.nTxBxComp & 0x0000FFFF) == nDrawingContainerId,
6806 "<SvxMSDffManager::GetShapeContainerData(..)> - internal drawing container Id could not be correctly merged into DFF_msofbtClientTextbox value." );
6807 // <--
6809 else
6811 rSt.SeekRel( nLength );
6812 nReadSpCont += nLength;
6815 while( nReadSpCont < nLenShapeCont );
6818 // Jetzt ggfs. die Infos fuer spaetere Zugriffe auf das Shape speichern
6820 if( aInfo.nShapeId )
6822 // fuer Textboxen ggfs. ersetzen durch Rahmen erlauben
6823 if( bCanBeReplaced
6824 && aInfo.nTxBxComp
6825 && (
6826 ( eShapeType == mso_sptTextSimple )
6827 || ( eShapeType == mso_sptTextBox )
6828 || ( ( ( eShapeType == mso_sptRectangle )
6829 || ( eShapeType == mso_sptRoundRectangle )
6831 ) ) )
6833 aInfo.bReplaceByFly = TRUE;
6835 pShapeInfos->Insert( new SvxMSDffShapeInfo( aInfo ) );
6836 pShapeOrders->Insert( new SvxMSDffShapeOrder( aInfo.nShapeId ),
6837 pShapeOrders->Count() );
6840 // und den Stream wieder korrekt positionieren
6841 rSt.Seek( nStartShapeCont + nLenShapeCont );
6842 return TRUE;
6847 /*****************************************************************************
6849 Zugriff auf ein Shape zur Laufzeit (ueber die Shape-Id)
6850 ----------------------------------
6851 ******************************************************************************/
6852 BOOL SvxMSDffManager::GetShape(ULONG nId, SdrObject*& rpShape,
6853 SvxMSDffImportData& rData)
6855 SvxMSDffShapeInfo aTmpRec(0, nId);
6856 aTmpRec.bSortByShapeId = TRUE;
6858 USHORT nFound;
6859 if( pShapeInfos->Seek_Entry(&aTmpRec, &nFound) )
6861 SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject( nFound );
6863 // eventuell altes Errorflag loeschen
6864 if( rStCtrl.GetError() )
6865 rStCtrl.ResetError();
6866 // FilePos des/der Stream(s) merken
6867 ULONG nOldPosCtrl = rStCtrl.Tell();
6868 ULONG nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
6869 // das Shape im Steuer Stream anspringen
6870 rStCtrl.Seek( rInfo.nFilePos );
6872 // Falls missglueckt, den Fehlerstatus zuruecksetzen und Pech gehabt!
6873 if( rStCtrl.GetError() )
6874 rStCtrl.ResetError();
6875 else
6876 rpShape = ImportObj( rStCtrl, &rData, rData.aParentRect, rData.aParentRect );
6878 // alte FilePos des/der Stream(s) restaurieren
6879 rStCtrl.Seek( nOldPosCtrl );
6880 if( &rStCtrl != pStData )
6881 pStData->Seek( nOldPosData );
6882 return ( 0 != rpShape );
6884 return FALSE;
6889 /* Zugriff auf ein BLIP zur Laufzeit (bei bereits bekannter Blip-Nr)
6890 ---------------------------------
6891 ******************************************************************************/
6892 BOOL SvxMSDffManager::GetBLIP( ULONG nIdx_, Graphic& rData, Rectangle* pVisArea ) const
6894 BOOL bOk = FALSE; // Ergebnisvariable initialisieren
6895 if ( pStData )
6897 // check if a graphic for this blipId is already imported
6898 if ( nIdx_ && pEscherBlipCache )
6900 EscherBlipCacheEntry* pEntry;
6901 for ( pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->First(); pEntry;
6902 pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->Next() )
6904 if ( pEntry->nBlip == nIdx_ )
6905 { /* if this entry is available, then it should be possible
6906 to get the Graphic via GraphicObject */
6907 GraphicObject aGraphicObject( pEntry->aUniqueID );
6908 rData = aGraphicObject.GetGraphic();
6909 if ( rData.GetType() != GRAPHIC_NONE )
6910 bOk = sal_True;
6911 else
6912 delete (EscherBlipCacheEntry*)pEscherBlipCache->Remove();
6913 break;
6917 if ( !bOk )
6919 USHORT nIdx = USHORT( nIdx_ );
6920 if( !nIdx || (pBLIPInfos->Count() < nIdx) ) return FALSE;
6922 // eventuell alte(s) Errorflag(s) loeschen
6923 if( rStCtrl.GetError() )
6924 rStCtrl.ResetError();
6925 if( ( &rStCtrl != pStData )
6926 && pStData->GetError() )
6927 pStData->ResetError();
6929 // FilePos des/der Stream(s) merken
6930 ULONG nOldPosCtrl = rStCtrl.Tell();
6931 ULONG nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
6933 // passende Info-Struct aus unserem Pointer Array nehmen
6934 SvxMSDffBLIPInfo& rInfo = *(*pBLIPInfos)[ nIdx-1 ];
6936 // das BLIP Atom im Daten Stream anspringen
6937 pStData->Seek( rInfo.nFilePos );
6938 // ggfs. Fehlerstatus zuruecksetzen
6939 if( pStData->GetError() )
6940 pStData->ResetError();
6941 else
6942 bOk = GetBLIPDirect( *pStData, rData, pVisArea );
6943 if( pStData2 && !bOk )
6945 // Fehler, aber zweite Chance: es gibt noch einen zweiten
6946 // Datenstream, in dem die Grafik liegen koennte!
6947 if( pStData2->GetError() )
6948 pStData2->ResetError();
6949 ULONG nOldPosData2 = pStData2->Tell();
6950 // das BLIP Atom im zweiten Daten Stream anspringen
6951 pStData2->Seek( rInfo.nFilePos );
6952 // ggfs. Fehlerstatus zuruecksetzen
6953 if( pStData2->GetError() )
6954 pStData2->ResetError();
6955 else
6956 bOk = GetBLIPDirect( *pStData2, rData, pVisArea );
6957 // alte FilePos des zweiten Daten-Stream restaurieren
6958 pStData2->Seek( nOldPosData2 );
6960 // alte FilePos des/der Stream(s) restaurieren
6961 rStCtrl.Seek( nOldPosCtrl );
6962 if( &rStCtrl != pStData )
6963 pStData->Seek( nOldPosData );
6965 if ( bOk )
6967 // create new BlipCacheEntry for this graphic
6968 GraphicObject aGraphicObject( rData );
6969 if ( !pEscherBlipCache )
6970 const_cast <SvxMSDffManager*> (this)->pEscherBlipCache = new List();
6971 EscherBlipCacheEntry* pNewEntry = new EscherBlipCacheEntry( nIdx_, aGraphicObject.GetUniqueID() );
6972 pEscherBlipCache->Insert( pNewEntry, LIST_APPEND );
6976 return bOk;
6979 /* Zugriff auf ein BLIP zur Laufzeit (mit korrekt positioniertem Stream)
6980 ---------------------------------
6981 ******************************************************************************/
6982 BOOL SvxMSDffManager::GetBLIPDirect( SvStream& rBLIPStream, Graphic& rData, Rectangle* pVisArea ) const
6984 ULONG nOldPos = rBLIPStream.Tell();
6986 int nRes = GRFILTER_OPENERROR; // Fehlervariable initialisieren
6988 // nachschauen, ob es sich auch wirklich um ein BLIP handelt
6989 UINT32 nLength;
6990 USHORT nInst, nFbt( 0 );
6991 BYTE nVer;
6992 if( ReadCommonRecordHeader( rBLIPStream, nVer, nInst, nFbt, nLength) && ( 0xF018 <= nFbt ) && ( 0xF117 >= nFbt ) )
6994 Size aMtfSize100;
6995 BOOL bMtfBLIP = FALSE;
6996 BOOL bZCodecCompression = FALSE;
6997 // Nun exakt auf den Beginn der eingebetteten Grafik positionieren
6998 ULONG nSkip = ( nInst & 0x0001 ) ? 32 : 16;
7000 switch( nInst & 0xFFFE )
7002 case 0x216 : // Metafile header then compressed WMF
7003 case 0x3D4 : // Metafile header then compressed EMF
7004 case 0x542 : // Metafile hd. then compressed PICT
7006 rBLIPStream.SeekRel( nSkip + 20 );
7008 // read in size of metafile in EMUS
7009 rBLIPStream >> aMtfSize100.Width() >> aMtfSize100.Height();
7011 // scale to 1/100mm
7012 aMtfSize100.Width() /= 360, aMtfSize100.Height() /= 360;
7014 if ( pVisArea ) // seem that we currently are skipping the visarea position
7015 *pVisArea = Rectangle( Point(), aMtfSize100 );
7017 // skip rest of header
7018 nSkip = 6;
7019 bMtfBLIP = bZCodecCompression = TRUE;
7021 break;
7022 case 0x46A : // One byte tag then JPEG (= JFIF) data
7023 case 0x6E0 : // One byte tag then PNG data
7024 case 0x7A8 :
7025 nSkip += 1; // One byte tag then DIB data
7026 break;
7028 rBLIPStream.SeekRel( nSkip );
7030 SvStream* pGrStream = &rBLIPStream;
7031 SvMemoryStream* pOut = NULL;
7032 if( bZCodecCompression )
7034 pOut = new SvMemoryStream( 0x8000, 0x4000 );
7035 ZCodec aZCodec( 0x8000, 0x8000 );
7036 aZCodec.BeginCompression();
7037 aZCodec.Decompress( rBLIPStream, *pOut );
7038 aZCodec.EndCompression();
7039 pOut->Seek( STREAM_SEEK_TO_BEGIN );
7040 pGrStream = pOut;
7043 //#define DBG_EXTRACTGRAPHICS
7044 #ifdef DBG_EXTRACTGRAPHICS
7046 static sal_Int32 nCount;
7048 String aFileName( String( RTL_CONSTASCII_STRINGPARAM( "dbggfx" ) ) );
7049 aFileName.Append( String::CreateFromInt32( nCount++ ) );
7050 switch( nInst &~ 1 )
7052 case 0x216 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".wmf" ) ) ); break;
7053 case 0x3d4 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".emf" ) ) ); break;
7054 case 0x542 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".pct" ) ) ); break;
7055 case 0x46a : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".jpg" ) ) ); break;
7056 case 0x6e0 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".png" ) ) ); break;
7057 case 0x7a8 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".bmp" ) ) ); break;
7060 String aURLStr;
7062 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( Application::GetAppFileName(), aURLStr ) )
7064 INetURLObject aURL( aURLStr );
7066 aURL.removeSegment();
7067 aURL.removeFinalSlash();
7068 aURL.Append( aFileName );
7070 SvStream* pDbgOut = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_TRUNC | STREAM_WRITE );
7072 if( pDbgOut )
7074 if ( bZCodecCompression )
7076 pOut->Seek( STREAM_SEEK_TO_END );
7077 pDbgOut->Write( pOut->GetData(), pOut->Tell() );
7078 pOut->Seek( STREAM_SEEK_TO_BEGIN );
7080 else
7082 sal_Int32 nDbgLen = nLength - nSkip;
7083 if ( nDbgLen )
7085 sal_Char* pDat = new sal_Char[ nDbgLen ];
7086 pGrStream->Read( pDat, nDbgLen );
7087 pDbgOut->Write( pDat, nDbgLen );
7088 pGrStream->SeekRel( -nDbgLen );
7089 delete[] pDat;
7093 delete pDbgOut;
7096 #endif
7098 if( ( nInst & 0xFFFE ) == 0x7A8 )
7099 { // DIBs direkt holen
7100 Bitmap aNew;
7101 if( aNew.Read( *pGrStream, FALSE ) )
7103 rData = Graphic( aNew );
7104 nRes = GRFILTER_OK;
7107 else
7108 { // und unsere feinen Filter darauf loslassen
7109 GraphicFilter* pGF = GetGrfFilter();
7110 String aEmptyStr;
7111 nRes = pGF->ImportGraphic( rData, aEmptyStr, *pGrStream, GRFILTER_FORMAT_DONTKNOW );
7113 // SJ: I40472, sometimes the aspect ratio (aMtfSize100) does not match and we get scaling problems,
7114 // then it is better to use the prefsize that is stored within the metafile. Bug #72846# for what the
7115 // scaling has been implemented does not happen anymore.
7117 // For pict graphics we will furthermore scale the metafile, because font scaling leads to error if the
7118 // dxarray is empty (this has been solved in wmf/emf but not for pict)
7119 if( bMtfBLIP && ( GRFILTER_OK == nRes ) && ( rData.GetType() == GRAPHIC_GDIMETAFILE ) && ( ( nInst & 0xFFFE ) == 0x542 ) )
7121 if ( ( aMtfSize100.Width() >= 1000 ) && ( aMtfSize100.Height() >= 1000 ) )
7122 { // #75956#, scaling does not work properly, if the graphic is less than 1cm
7123 GDIMetaFile aMtf( rData.GetGDIMetaFile() );
7124 const Size aOldSize( aMtf.GetPrefSize() );
7126 if( aOldSize.Width() && ( aOldSize.Width() != aMtfSize100.Width() ) &&
7127 aOldSize.Height() && ( aOldSize.Height() != aMtfSize100.Height() ) )
7129 aMtf.Scale( (double) aMtfSize100.Width() / aOldSize.Width(),
7130 (double) aMtfSize100.Height() / aOldSize.Height() );
7131 aMtf.SetPrefSize( aMtfSize100 );
7132 aMtf.SetPrefMapMode( MAP_100TH_MM );
7133 rData = aMtf;
7138 // ggfs. Fehlerstatus zuruecksetzen
7139 if ( ERRCODE_IO_PENDING == pGrStream->GetError() )
7140 pGrStream->ResetError();
7141 delete pOut;
7143 rBLIPStream.Seek( nOldPos ); // alte FilePos des Streams restaurieren
7145 return ( GRFILTER_OK == nRes ); // Ergebniss melden
7148 /* static */
7149 BOOL SvxMSDffManager::ReadCommonRecordHeader(DffRecordHeader& rRec, SvStream& rIn)
7151 rRec.nFilePos = rIn.Tell();
7152 return SvxMSDffManager::ReadCommonRecordHeader( rIn,rRec.nRecVer,
7153 rRec.nRecInstance,
7154 rRec.nRecType,
7155 rRec.nRecLen );
7159 /* auch static */
7160 BOOL SvxMSDffManager::ReadCommonRecordHeader( SvStream& rSt,
7161 BYTE& rVer,
7162 USHORT& rInst,
7163 USHORT& rFbt,
7164 UINT32& rLength )
7166 sal_uInt16 nTmp;
7167 rSt >> nTmp >> rFbt >> rLength;
7168 rVer = sal::static_int_cast< BYTE >(nTmp & 15);
7169 rInst = nTmp >> 4;
7170 return rSt.GetError() == 0;
7176 BOOL SvxMSDffManager::ProcessClientAnchor(SvStream& rStData, ULONG nDatLen,
7177 char*& rpBuff, UINT32& rBuffLen ) const
7179 if( nDatLen )
7181 rpBuff = new char[ nDatLen ];
7182 rBuffLen = nDatLen;
7183 rStData.Read( rpBuff, nDatLen );
7185 return TRUE;
7188 BOOL SvxMSDffManager::ProcessClientData(SvStream& rStData, ULONG nDatLen,
7189 char*& rpBuff, UINT32& rBuffLen ) const
7191 if( nDatLen )
7193 rpBuff = new char[ nDatLen ];
7194 rBuffLen = nDatLen;
7195 rStData.Read( rpBuff, nDatLen );
7197 return TRUE;
7201 void SvxMSDffManager::ProcessClientAnchor2( SvStream& /* rSt */, DffRecordHeader& /* rHd */ , void* /* pData */, DffObjData& /* rObj */ )
7203 return; // wird von SJ im Draw ueberladen
7206 ULONG SvxMSDffManager::Calc_nBLIPPos( ULONG nOrgVal, ULONG /* nStreamPos */ ) const
7208 return nOrgVal;
7211 BOOL SvxMSDffManager::GetOLEStorageName( long /* nOLEId */, String&, SvStorageRef&, uno::Reference < embed::XStorage >& ) const
7213 return FALSE;
7216 BOOL SvxMSDffManager::ShapeHasText( ULONG /* nShapeId */, ULONG /* nFilePos */ ) const
7218 return TRUE;
7221 // --> OD 2004-12-14 #i32596# - add new parameter <_nCalledByGroup>
7222 SdrObject* SvxMSDffManager::ImportOLE( long nOLEId,
7223 const Graphic& rGrf,
7224 const Rectangle& rBoundRect,
7225 const Rectangle& rVisArea,
7226 const int /* _nCalledByGroup */,
7227 sal_Int64 nAspect ) const
7228 // <--
7230 SdrObject* pRet = 0;
7231 String sStorageName;
7232 SvStorageRef xSrcStg;
7233 ErrCode nError = ERRCODE_NONE;
7234 uno::Reference < embed::XStorage > xDstStg;
7235 if( GetOLEStorageName( nOLEId, sStorageName, xSrcStg, xDstStg ))
7236 pRet = CreateSdrOLEFromStorage( sStorageName, xSrcStg, xDstStg,
7237 rGrf, rBoundRect, rVisArea, pStData, nError,
7238 nSvxMSDffOLEConvFlags, nAspect );
7239 return pRet;
7242 const GDIMetaFile* SvxMSDffManager::lcl_GetMetaFileFromGrf_Impl( const Graphic& rGrf,
7243 GDIMetaFile& rMtf )
7245 const GDIMetaFile* pMtf;
7246 if( GRAPHIC_BITMAP == rGrf.GetType() )
7248 Point aPt;
7249 const Size aSz(lcl_GetPrefSize(rGrf, MAP_100TH_MM));
7251 VirtualDevice aVirtDev;
7252 aVirtDev.EnableOutput( FALSE );
7253 MapMode aMM(MAP_100TH_MM);
7254 aVirtDev.SetMapMode( aMM );
7256 rMtf.Record( &aVirtDev );
7257 rGrf.Draw( &aVirtDev, aPt, aSz );
7258 rMtf.Stop();
7259 rMtf.SetPrefMapMode(aMM);
7260 rMtf.SetPrefSize( aSz );
7262 pMtf = &rMtf;
7264 else
7265 pMtf = &rGrf.GetGDIMetaFile();
7266 return pMtf;
7269 BOOL SvxMSDffManager::MakeContentStream( SotStorage * pStor, const GDIMetaFile & rMtf )
7271 String aPersistStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( SVEXT_PERSIST_STREAM ) ) );
7272 SotStorageStreamRef xStm = pStor->OpenSotStream( aPersistStream );
7273 xStm->SetVersion( pStor->GetVersion() );
7274 xStm->SetBufferSize( 8192 );
7276 USHORT nAspect = ASPECT_CONTENT;
7277 ULONG nAdviseModes = 2;
7279 Impl_OlePres aEle( FORMAT_GDIMETAFILE );
7280 // Die Groesse in 1/100 mm umrechnen
7281 // Falls eine nicht anwendbare MapUnit (Device abhaengig) verwendet wird,
7282 // versucht SV einen BestMatchden richtigen Wert zu raten.
7283 Size aSize = rMtf.GetPrefSize();
7284 MapMode aMMSrc = rMtf.GetPrefMapMode();
7285 MapMode aMMDst( MAP_100TH_MM );
7286 aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
7287 aEle.SetSize( aSize );
7288 aEle.SetAspect( nAspect );
7289 aEle.SetAdviseFlags( nAdviseModes );
7290 aEle.SetMtf( rMtf );
7291 aEle.Write( *xStm );
7293 xStm->SetBufferSize( 0 );
7294 return xStm->GetError() == SVSTREAM_OK;
7297 struct ClsIDs {
7298 UINT32 nId;
7299 const sal_Char* pSvrName;
7300 const sal_Char* pDspName;
7302 static ClsIDs aClsIDs[] = {
7304 { 0x000212F0, "MSWordArt", "Microsoft Word Art" },
7305 { 0x000212F0, "MSWordArt.2", "Microsoft Word Art 2.0" },
7307 // MS Apps
7308 { 0x00030000, "ExcelWorksheet", "Microsoft Excel Worksheet" },
7309 { 0x00030001, "ExcelChart", "Microsoft Excel Chart" },
7310 { 0x00030002, "ExcelMacrosheet", "Microsoft Excel Macro" },
7311 { 0x00030003, "WordDocument", "Microsoft Word Document" },
7312 { 0x00030004, "MSPowerPoint", "Microsoft PowerPoint" },
7313 { 0x00030005, "MSPowerPointSho", "Microsoft PowerPoint Slide Show"},
7314 { 0x00030006, "MSGraph", "Microsoft Graph" },
7315 { 0x00030007, "MSDraw", "Microsoft Draw" },
7316 { 0x00030008, "Note-It", "Microsoft Note-It" },
7317 { 0x00030009, "WordArt", "Microsoft Word Art" },
7318 { 0x0003000a, "PBrush", "Microsoft PaintBrush Picture" },
7319 { 0x0003000b, "Equation", "Microsoft Equation Editor" },
7320 { 0x0003000c, "Package", "Package" },
7321 { 0x0003000d, "SoundRec", "Sound" },
7322 { 0x0003000e, "MPlayer", "Media Player" },
7323 // MS Demos
7324 { 0x0003000f, "ServerDemo", "OLE 1.0 Server Demo" },
7325 { 0x00030010, "Srtest", "OLE 1.0 Test Demo" },
7326 { 0x00030011, "SrtInv", "OLE 1.0 Inv Demo" },
7327 { 0x00030012, "OleDemo", "OLE 1.0 Demo" },
7329 // Coromandel / Dorai Swamy / 718-793-7963
7330 { 0x00030013, "CoromandelIntegra", "Coromandel Integra" },
7331 { 0x00030014, "CoromandelObjServer","Coromandel Object Server" },
7333 // 3-d Visions Corp / Peter Hirsch / 310-325-1339
7334 { 0x00030015, "StanfordGraphics", "Stanford Graphics" },
7336 // Deltapoint / Nigel Hearne / 408-648-4000
7337 { 0x00030016, "DGraphCHART", "DeltaPoint Graph Chart" },
7338 { 0x00030017, "DGraphDATA", "DeltaPoint Graph Data" },
7340 // Corel / Richard V. Woodend / 613-728-8200 x1153
7341 { 0x00030018, "PhotoPaint", "Corel PhotoPaint" },
7342 { 0x00030019, "CShow", "Corel Show" },
7343 { 0x0003001a, "CorelChart", "Corel Chart" },
7344 { 0x0003001b, "CDraw", "Corel Draw" },
7346 // Inset Systems / Mark Skiba / 203-740-2400
7347 { 0x0003001c, "HJWIN1.0", "Inset Systems" },
7349 // Mark V Systems / Mark McGraw / 818-995-7671
7350 { 0x0003001d, "ObjMakerOLE", "MarkV Systems Object Maker" },
7352 // IdentiTech / Mike Gilger / 407-951-9503
7353 { 0x0003001e, "FYI", "IdentiTech FYI" },
7354 { 0x0003001f, "FYIView", "IdentiTech FYI Viewer" },
7356 // Inventa Corporation / Balaji Varadarajan / 408-987-0220
7357 { 0x00030020, "Stickynote", "Inventa Sticky Note" },
7359 // ShapeWare Corp. / Lori Pearce / 206-467-6723
7360 { 0x00030021, "ShapewareVISIO10", "Shapeware Visio 1.0" },
7361 { 0x00030022, "ImportServer", "Spaheware Import Server" },
7363 // test app SrTest
7364 { 0x00030023, "SrvrTest", "OLE 1.0 Server Test" },
7366 // test app ClTest. Doesn't really work as a server but is in reg db
7367 { 0x00030025, "Cltest", "OLE 1.0 Client Test" },
7369 // Microsoft ClipArt Gallery Sherry Larsen-Holmes
7370 { 0x00030026, "MS_ClipArt_Gallery", "Microsoft ClipArt Gallery" },
7371 // Microsoft Project Cory Reina
7372 { 0x00030027, "MSProject", "Microsoft Project" },
7374 // Microsoft Works Chart
7375 { 0x00030028, "MSWorksChart", "Microsoft Works Chart" },
7377 // Microsoft Works Spreadsheet
7378 { 0x00030029, "MSWorksSpreadsheet", "Microsoft Works Spreadsheet" },
7380 // AFX apps - Dean McCrory
7381 { 0x0003002A, "MinSvr", "AFX Mini Server" },
7382 { 0x0003002B, "HierarchyList", "AFX Hierarchy List" },
7383 { 0x0003002C, "BibRef", "AFX BibRef" },
7384 { 0x0003002D, "MinSvrMI", "AFX Mini Server MI" },
7385 { 0x0003002E, "TestServ", "AFX Test Server" },
7387 // Ami Pro
7388 { 0x0003002F, "AmiProDocument", "Ami Pro Document" },
7390 // WordPerfect Presentations For Windows
7391 { 0x00030030, "WPGraphics", "WordPerfect Presentation" },
7392 { 0x00030031, "WPCharts", "WordPerfect Chart" },
7394 // MicroGrafx Charisma
7395 { 0x00030032, "Charisma", "MicroGrafx Charisma" },
7396 { 0x00030033, "Charisma_30", "MicroGrafx Charisma 3.0" },
7397 { 0x00030034, "CharPres_30", "MicroGrafx Charisma 3.0 Pres" },
7398 // MicroGrafx Draw
7399 { 0x00030035, "Draw", "MicroGrafx Draw" },
7400 // MicroGrafx Designer
7401 { 0x00030036, "Designer_40", "MicroGrafx Designer 4.0" },
7403 // STAR DIVISION
7404 // { 0x000424CA, "StarMath", "StarMath 1.0" },
7405 { 0x00043AD2, "FontWork", "Star FontWork" },
7406 // { 0x000456EE, "StarMath2", "StarMath 2.0" },
7408 { 0, "", "" } };
7411 BOOL SvxMSDffManager::ConvertToOle2( SvStream& rStm, UINT32 nReadLen,
7412 const GDIMetaFile * pMtf, const SotStorageRef& rDest )
7414 BOOL bMtfRead = FALSE;
7415 SotStorageStreamRef xOle10Stm = rDest->OpenSotStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ),
7416 STREAM_WRITE| STREAM_SHARE_DENYALL );
7417 if( xOle10Stm->GetError() )
7418 return FALSE;
7420 UINT32 nType;
7421 UINT32 nRecType;
7422 UINT32 nStrLen;
7423 String aSvrName;
7424 UINT32 nDummy0;
7425 UINT32 nDummy1;
7426 UINT32 nDataLen;
7427 BYTE * pData;
7428 UINT32 nBytesRead = 0;
7431 rStm >> nType;
7432 rStm >> nRecType;
7433 rStm >> nStrLen;
7434 if( nStrLen )
7436 if( 0x10000L > nStrLen )
7438 sal_Char * pBuf = new sal_Char[ nStrLen ];
7439 rStm.Read( pBuf, nStrLen );
7440 aSvrName.Assign( String( pBuf, (USHORT) nStrLen-1, gsl_getSystemTextEncoding() ) );
7441 delete[] pBuf;
7443 else
7444 break;
7446 rStm >> nDummy0;
7447 rStm >> nDummy1;
7448 rStm >> nDataLen;
7450 nBytesRead += 6 * sizeof( UINT32 ) + nStrLen + nDataLen;
7452 if( !rStm.IsEof() && nReadLen > nBytesRead && nDataLen )
7454 if( xOle10Stm.Is() )
7456 pData = new BYTE[ nDataLen ];
7457 if( !pData )
7458 return FALSE;
7460 rStm.Read( pData, nDataLen );
7462 // write to ole10 stream
7463 *xOle10Stm << nDataLen;
7464 xOle10Stm->Write( pData, nDataLen );
7465 xOle10Stm = SotStorageStreamRef();
7467 // set the compobj stream
7468 ClsIDs* pIds;
7469 for( pIds = aClsIDs; pIds->nId; pIds++ )
7471 if( COMPARE_EQUAL == aSvrName.CompareToAscii( pIds->pSvrName ) )
7472 break;
7474 // SvGlobalName* pClsId = NULL;
7475 String aShort, aFull;
7476 if( pIds->nId )
7478 // gefunden!
7479 ULONG nCbFmt = SotExchange::RegisterFormatName( aSvrName );
7480 rDest->SetClass( SvGlobalName( pIds->nId, 0, 0, 0xc0,0,0,0,0,0,0,0x46 ), nCbFmt,
7481 String( pIds->pDspName, RTL_TEXTENCODING_ASCII_US ) );
7483 else
7485 ULONG nCbFmt = SotExchange::RegisterFormatName( aSvrName );
7486 rDest->SetClass( SvGlobalName(), nCbFmt, aSvrName );
7489 delete[] pData;
7491 else if( nRecType == 5 && !pMtf )
7493 ULONG nPos = rStm.Tell();
7494 UINT16 sz[4];
7495 rStm.Read( sz, 8 );
7496 //rStm.SeekRel( 8 );
7497 Graphic aGraphic;
7498 if( ERRCODE_NONE == GraphicConverter::Import( rStm, aGraphic ) && aGraphic.GetType() )
7500 const GDIMetaFile& rMtf = aGraphic.GetGDIMetaFile();
7501 MakeContentStream( rDest, rMtf );
7502 bMtfRead = TRUE;
7504 // set behind the data
7505 rStm.Seek( nPos + nDataLen );
7507 else
7508 rStm.SeekRel( nDataLen );
7510 } while( !rStm.IsEof() && nReadLen >= nBytesRead );
7512 if( !bMtfRead && pMtf )
7514 MakeContentStream( rDest, *pMtf );
7515 return TRUE;
7518 return FALSE;
7521 const char* GetInternalServerName_Impl( const SvGlobalName& aGlobName )
7523 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 )
7524 || aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) )
7525 return "swriter";
7526 else if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 )
7527 || aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) )
7528 return "scalc";
7529 else if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 )
7530 || aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) )
7531 return "simpress";
7532 else if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 )
7533 || aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) )
7534 return "sdraw";
7535 else if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 )
7536 || aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) )
7537 return "smath";
7538 else if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 )
7539 || aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) )
7540 return "schart";
7541 return 0;
7544 ::rtl::OUString GetFilterNameFromClassID_Impl( const SvGlobalName& aGlobName )
7546 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 ) )
7547 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Writer)" ) );
7549 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) )
7550 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer8" ) );
7552 if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 ) )
7553 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Calc)" ) );
7555 if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) )
7556 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc8" ) );
7558 if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 ) )
7559 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Impress)" ) );
7561 if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) )
7562 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress8" ) );
7564 if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 ) )
7565 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Draw)" ) );
7567 if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) )
7568 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw8" ) );
7570 if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 ) )
7571 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Math)" ) );
7573 if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) )
7574 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "math8" ) );
7576 if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 ) )
7577 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Chart)" ) );
7579 if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) )
7580 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "chart8" ) );
7582 return ::rtl::OUString();
7585 com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject > SvxMSDffManager::CheckForConvertToSOObj( UINT32 nConvertFlags,
7586 SotStorage& rSrcStg, const uno::Reference < embed::XStorage >& rDestStorage,
7587 const Graphic& rGrf,
7588 const Rectangle& rVisArea )
7590 uno::Reference < embed::XEmbeddedObject > xObj;
7591 SvGlobalName aStgNm = rSrcStg.GetClassName();
7592 const char* pName = GetInternalServerName_Impl( aStgNm );
7593 String sStarName;
7594 if ( pName )
7595 sStarName = String::CreateFromAscii( pName );
7596 else if ( nConvertFlags )
7598 static struct _ObjImpType
7600 UINT32 nFlag;
7601 const char* pFactoryNm;
7602 // GlobalNameId
7603 UINT32 n1;
7604 USHORT n2, n3;
7605 BYTE b8, b9, b10, b11, b12, b13, b14, b15;
7606 } aArr[] = {
7607 { OLE_MATHTYPE_2_STARMATH, "smath",
7608 0x0002ce02L, 0x0000, 0x0000,
7609 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7610 { OLE_MATHTYPE_2_STARMATH, "smath",
7611 0x00021700L, 0x0000, 0x0000,
7612 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7613 { OLE_WINWORD_2_STARWRITER, "swriter",
7614 0x00020906L, 0x0000, 0x0000,
7615 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7616 { OLE_EXCEL_2_STARCALC, "scalc", // Excel table
7617 0x00020810L, 0x0000, 0x0000,
7618 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7619 { OLE_EXCEL_2_STARCALC, "scalc", // Excel chart
7620 0x00020820L, 0x0000, 0x0000,
7621 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7622 // 114465: additional Excel OLE chart classId to above.
7623 { OLE_EXCEL_2_STARCALC, "scalc",
7624 0x00020821L, 0x0000, 0x0000,
7625 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7626 { OLE_POWERPOINT_2_STARIMPRESS, "simpress", // PowerPoint presentation
7627 0x64818d10L, 0x4f9b, 0x11cf,
7628 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 },
7629 { OLE_POWERPOINT_2_STARIMPRESS, "simpress", // PowerPoint slide
7630 0x64818d11L, 0x4f9b, 0x11cf,
7631 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 },
7632 { 0, 0,
7633 0, 0, 0,
7634 0, 0, 0, 0, 0, 0, 0, 0 }
7637 for( const _ObjImpType* pArr = aArr; pArr->nFlag; ++pArr )
7639 if( nConvertFlags & pArr->nFlag )
7641 SvGlobalName aTypeName( pArr->n1, pArr->n2, pArr->n3,
7642 pArr->b8, pArr->b9, pArr->b10, pArr->b11,
7643 pArr->b12, pArr->b13, pArr->b14, pArr->b15 );
7645 if ( aStgNm == aTypeName )
7647 sStarName = String::CreateFromAscii( pArr->pFactoryNm );
7648 break;
7654 if ( sStarName.Len() )
7656 //TODO/MBA: check if (and when) storage and stream will be destroyed!
7657 const SfxFilter* pFilter = 0;
7658 SvMemoryStream* pStream = new SvMemoryStream;
7659 if ( pName )
7661 // TODO/LATER: perhaps we need to retrieve VisArea and Metafile from the storage also
7662 SotStorageStreamRef xStr = rSrcStg.OpenSotStream( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "package_stream" ) ), STREAM_STD_READ );
7663 *xStr >> *pStream;
7665 else
7667 SfxFilterMatcher aMatch( sStarName );
7668 SotStorageRef xStorage = new SotStorage( FALSE, *pStream );
7669 rSrcStg.CopyTo( xStorage );
7670 xStorage->Commit();
7671 xStorage.Clear();
7672 String aType = SfxFilter::GetTypeFromStorage( rSrcStg );
7673 if ( aType.Len() )
7674 pFilter = aMatch.GetFilter4EA( aType );
7677 //#define DBG_EXTRACTOLESTREAMS
7678 #ifdef DBG_EXTRACTOLESTREAMS
7679 static sal_Int32 nCount(0);
7680 String aTmpName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("/tmp/embedded_stream_")));
7681 aTmpName += String::CreateFromInt32(nCount++);
7682 aTmpName += String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(".bin"));
7683 SvFileStream aTmpStream(aTmpName,STREAM_READ|STREAM_WRITE|STREAM_TRUNC);
7684 pStream->Seek(0);
7685 *pStream >> aTmpStream;
7686 aTmpStream.Close();
7687 #endif
7689 if ( pName || pFilter )
7691 //Reuse current ole name
7692 String aDstStgName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj)));
7693 aDstStgName += String::CreateFromInt32(nMSOleObjCntr);
7695 ::rtl::OUString aFilterName;
7696 if ( pFilter )
7697 aFilterName = pFilter->GetName();
7698 else
7699 aFilterName = GetFilterNameFromClassID_Impl( aStgNm );
7701 uno::Sequence < beans::PropertyValue > aMedium( aFilterName.getLength() ? 3 : 2);
7702 aMedium[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) );
7703 uno::Reference < io::XInputStream > xStream = new ::utl::OSeekableInputStreamWrapper( *pStream );
7704 aMedium[0].Value <<= xStream;
7705 aMedium[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
7706 aMedium[1].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) );
7708 if ( aFilterName.getLength() )
7710 aMedium[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
7711 aMedium[2].Value <<= aFilterName;
7714 ::rtl::OUString aName( aDstStgName );
7715 comphelper::EmbeddedObjectContainer aCnt( rDestStorage );
7716 xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
7718 if ( !xObj.is() )
7720 if( aFilterName.getLength() )
7722 // throw the filter parameter away as workaround
7723 aMedium.realloc( 2 );
7724 xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
7727 if ( !xObj.is() )
7728 return xObj;
7731 // TODO/LATER: ViewAspect must be passed from outside!
7732 sal_Int64 nViewAspect = embed::Aspects::MSOLE_CONTENT;
7734 // JP 26.10.2001: Bug 93374 / 91928 the writer
7735 // objects need the correct visarea needs the
7736 // correct visarea, but this is not true for
7737 // PowerPoint (see bugdoc 94908b)
7738 // SJ: 19.11.2001 bug 94908, also chart objects
7739 // needs the correct visarea
7741 // If pName is set this is an own embedded object, it should have the correct size internally
7742 // TODO/LATER: it might make sence in future to set the size stored in internal object
7743 if( !pName && ( sStarName.EqualsAscii( "swriter" ) || sStarName.EqualsAscii( "scalc" ) ) )
7745 MapMode aMapMode( VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nViewAspect ) ) );
7746 Size aSz;
7747 if ( rVisArea.IsEmpty() )
7748 aSz = lcl_GetPrefSize(rGrf, aMapMode );
7749 else
7751 aSz = rVisArea.GetSize();
7752 aSz = OutputDevice::LogicToLogic( aSz, MapMode( MAP_100TH_MM ), aMapMode );
7755 // don't modify the object
7756 //TODO/LATER: remove those hacks, that needs to be done differently!
7757 //xIPObj->EnableSetModified( FALSE );
7758 awt::Size aSize;
7759 aSize.Width = aSz.Width();
7760 aSize.Height = aSz.Height();
7761 xObj->setVisualAreaSize( nViewAspect, aSize );
7762 //xIPObj->EnableSetModified( TRUE );
7764 else if ( sStarName.EqualsAscii( "smath" ) )
7765 { // SJ: force the object to recalc its visarea
7766 //TODO/LATER: wait for PrinterChangeNotification
7767 //xIPObj->OnDocumentPrinterChanged( NULL );
7772 return xObj;
7775 // TODO/MBA: code review and testing!
7776 SdrOle2Obj* SvxMSDffManager::CreateSdrOLEFromStorage(
7777 const String& rStorageName,
7778 SotStorageRef& rSrcStorage,
7779 const uno::Reference < embed::XStorage >& xDestStorage,
7780 const Graphic& rGrf,
7781 const Rectangle& rBoundRect,
7782 const Rectangle& rVisArea,
7783 SvStream* pDataStrm,
7784 ErrCode& rError,
7785 UINT32 nConvertFlags,
7786 sal_Int64 nReccomendedAspect )
7788 sal_Int64 nAspect = nReccomendedAspect;
7789 SdrOle2Obj* pRet = 0;
7790 if( rSrcStorage.Is() && xDestStorage.is() && rStorageName.Len() )
7792 comphelper::EmbeddedObjectContainer aCnt( xDestStorage );
7793 // Ist der 01Ole-Stream ueberhaupt vorhanden ?
7794 // ( ist er z.B. bei FontWork nicht )
7795 // Wenn nicht -> Einbindung als Grafik
7796 BOOL bValidStorage = FALSE;
7797 String aDstStgName( String::CreateFromAscii(
7798 RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj)));
7800 aDstStgName += String::CreateFromInt32( ++nMSOleObjCntr );
7803 SvStorageRef xObjStg = rSrcStorage->OpenSotStorage( rStorageName,
7804 STREAM_READWRITE| STREAM_SHARE_DENYALL );
7805 if( xObjStg.Is() )
7808 BYTE aTestA[10]; // exist the \1CompObj-Stream ?
7809 SvStorageStreamRef xSrcTst = xObjStg->OpenSotStream(
7810 String(RTL_CONSTASCII_STRINGPARAM("\1CompObj"),
7811 RTL_TEXTENCODING_MS_1252 ));
7812 bValidStorage = xSrcTst.Is() && sizeof( aTestA ) ==
7813 xSrcTst->Read( aTestA, sizeof( aTestA ) );
7814 if( !bValidStorage )
7816 // or the \1Ole-Stream ?
7817 xSrcTst = xObjStg->OpenSotStream(
7818 String(RTL_CONSTASCII_STRINGPARAM("\1Ole"),
7819 RTL_TEXTENCODING_MS_1252 ));
7820 bValidStorage = xSrcTst.Is() && sizeof(aTestA) ==
7821 xSrcTst->Read(aTestA, sizeof(aTestA));
7825 if( bValidStorage )
7827 if ( nAspect != embed::Aspects::MSOLE_ICON )
7829 // check whether the object is iconified one
7830 // usually this information is already known, the only exception
7831 // is a kind of embedded objects in Word documents
7832 // TODO/LATER: should the caller be notified if the aspect changes in future?
7834 SvStorageStreamRef xObjInfoSrc = xObjStg->OpenSotStream(
7835 String( RTL_CONSTASCII_STRINGPARAM( "\3ObjInfo" ) ),
7836 STREAM_STD_READ | STREAM_NOCREATE );
7837 if ( xObjInfoSrc.Is() && !xObjInfoSrc->GetError() )
7839 BYTE nByte = 0;
7840 *xObjInfoSrc >> nByte;
7841 if ( ( nByte >> 4 ) & embed::Aspects::MSOLE_ICON )
7842 nAspect = embed::Aspects::MSOLE_ICON;
7846 uno::Reference < embed::XEmbeddedObject > xObj( CheckForConvertToSOObj(
7847 nConvertFlags, *xObjStg, xDestStorage, rGrf, rVisArea ));
7848 if ( xObj.is() )
7850 svt::EmbeddedObjectRef aObj( xObj, nAspect );
7852 // TODO/LATER: need MediaType
7853 aObj.SetGraphic( rGrf, ::rtl::OUString() );
7855 // TODO/MBA: check setting of PersistName
7856 pRet = new SdrOle2Obj( aObj, String(), rBoundRect, false);
7857 // we have the Object, don't create another
7858 bValidStorage = false;
7864 if( bValidStorage )
7866 // object is not an own object
7867 SotStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName, STREAM_READWRITE );
7869 if ( xObjStor.Is() )
7871 SotStorageRef xSrcStor = rSrcStorage->OpenSotStorage( rStorageName, STREAM_READ );
7872 xSrcStor->CopyTo( xObjStor );
7874 if( !xObjStor->GetError() )
7875 xObjStor->Commit();
7877 if( xObjStor->GetError() )
7879 rError = xObjStor->GetError();
7880 bValidStorage = FALSE;
7882 else if( !xObjStor.Is() )
7883 bValidStorage = FALSE;
7886 else if( pDataStrm )
7888 UINT32 nLen, nDummy;
7889 *pDataStrm >> nLen >> nDummy;
7890 if( SVSTREAM_OK != pDataStrm->GetError() ||
7891 // Id in BugDoc - exist there other Ids?
7892 // The ConvertToOle2 - does not check for consistent
7893 0x30008 != nDummy )
7894 bValidStorage = FALSE;
7895 else
7897 // or is it an OLE-1 Stream in the DataStream?
7898 SvStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName );
7899 //TODO/MBA: remove metafile conversion from ConvertToOle2
7900 //when is this code used?!
7901 GDIMetaFile aMtf;
7902 bValidStorage = ConvertToOle2( *pDataStrm, nLen, &aMtf, xObjStor );
7903 xObjStor->Commit();
7907 if( bValidStorage )
7909 uno::Reference < embed::XEmbeddedObject > xObj = aCnt.GetEmbeddedObject( aDstStgName );
7910 if( xObj.is() )
7912 // the visual area must be retrieved from the metafile (object doesn't know it so far)
7914 if ( nAspect != embed::Aspects::MSOLE_ICON )
7916 // working with visual area can switch the object to running state
7917 awt::Size aAwtSz;
7920 // the provided visual area should be used, if there is any
7921 if ( rVisArea.IsEmpty() )
7923 MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
7924 Size aSz(lcl_GetPrefSize(rGrf, MapMode(aMapUnit)));
7925 aAwtSz.Width = aSz.Width();
7926 aAwtSz.Height = aSz.Height();
7928 else
7930 aAwtSz.Width = rVisArea.GetWidth();
7931 aAwtSz.Height = rVisArea.GetHeight();
7933 //xInplaceObj->EnableSetModified( FALSE );
7934 xObj->setVisualAreaSize( nAspect, aAwtSz );
7935 //xInplaceObj->EnableSetModified( TRUE );*/
7937 catch( uno::Exception& )
7939 OSL_ENSURE( sal_False, "Could not set visual area of the object!\n" );
7943 svt::EmbeddedObjectRef aObj( xObj, nAspect );
7945 // TODO/LATER: need MediaType
7946 aObj.SetGraphic( rGrf, ::rtl::OUString() );
7948 pRet = new SdrOle2Obj( aObj, aDstStgName, rBoundRect, false);
7953 return pRet;
7956 SdrObject* SvxMSDffManager::GetAutoForm( MSO_SPT eTyp ) const
7958 SdrObject* pRet = NULL;
7960 if(120 >= UINT16(eTyp))
7962 pRet = new SdrRectObj();
7965 DBG_ASSERT(pRet, "SvxMSDffManager::GetAutoForm -> UNKNOWN AUTOFORM");
7967 return pRet;
7970 sal_Bool SvxMSDffManager::SetPropValue( const uno::Any& rAny, const uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
7971 const String& rPropName, sal_Bool bTestPropertyAvailability )
7973 sal_Bool bRetValue = sal_True;
7974 if ( bTestPropertyAvailability )
7976 bRetValue = sal_False;
7979 uno::Reference< beans::XPropertySetInfo >
7980 aXPropSetInfo( rXPropSet->getPropertySetInfo() );
7981 if ( aXPropSetInfo.is() )
7982 bRetValue = aXPropSetInfo->hasPropertyByName( rPropName );
7984 catch( uno::Exception& )
7986 bRetValue = sal_False;
7989 if ( bRetValue )
7993 rXPropSet->setPropertyValue( rPropName, rAny );
7994 bRetValue = sal_True;
7996 catch( uno::Exception& )
7998 bRetValue = sal_False;
8001 return bRetValue;
8004 SvxMSDffImportRec::SvxMSDffImportRec()
8005 : pObj( 0 ),
8006 pWrapPolygon(0),
8007 pClientAnchorBuffer( 0 ),
8008 nClientAnchorLen( 0 ),
8009 pClientDataBuffer( 0 ),
8010 nClientDataLen( 0 ),
8011 nXAlign( 0 ), // position n cm from left
8012 nXRelTo( 2 ), // relative to column
8013 nYAlign( 0 ), // position n cm below
8014 nYRelTo( 2 ), // relative to paragraph
8015 nLayoutInTableCell( 0 ), // element is laid out in table cell
8016 nTextRotationAngle( 0 ),
8017 nDxTextLeft( 144 ),
8018 nDyTextTop( 72 ),
8019 nDxTextRight( 144 ),
8020 nDyTextBottom( 72 ),
8021 nDxWrapDistLeft( 0 ),
8022 nDyWrapDistTop( 0 ),
8023 nDxWrapDistRight( 0 ),
8024 nDyWrapDistBottom(0 ),
8025 nCropFromTop( 0 ),
8026 nCropFromBottom( 0 ),
8027 nCropFromLeft( 0 ),
8028 nCropFromRight( 0 ),
8029 aTextId( 0, 0 ),
8030 nNextShapeId( 0 ),
8031 nShapeId( 0 ),
8032 eShapeType( mso_sptNil )
8034 eLineStyle = mso_lineSimple; // GPF-Bug #66227#
8035 bDrawHell = FALSE;
8036 bHidden = FALSE;
8037 // bInGroup = FALSE;
8038 bReplaceByFly = FALSE;
8039 bLastBoxInChain = TRUE;
8040 bHasUDefProp = FALSE; // was the DFF_msofbtUDefProp record set?
8041 bVFlip = FALSE;
8042 bHFlip = FALSE;
8043 bAutoWidth = FALSE;
8046 SvxMSDffImportRec::SvxMSDffImportRec(const SvxMSDffImportRec& rCopy)
8047 : pObj( rCopy.pObj ),
8048 nXAlign( rCopy.nXAlign ),
8049 nXRelTo( rCopy.nXRelTo ),
8050 nYAlign( rCopy.nYAlign ),
8051 nYRelTo( rCopy.nYRelTo ),
8052 nLayoutInTableCell( rCopy.nLayoutInTableCell ),
8053 nTextRotationAngle( rCopy.nTextRotationAngle ),
8054 nDxTextLeft( rCopy.nDxTextLeft ),
8055 nDyTextTop( rCopy.nDyTextTop ),
8056 nDxTextRight( rCopy.nDxTextRight ),
8057 nDyTextBottom( rCopy.nDyTextBottom ),
8058 nDxWrapDistLeft( rCopy.nDxWrapDistLeft ),
8059 nDyWrapDistTop( rCopy.nDyWrapDistTop ),
8060 nDxWrapDistRight( rCopy.nDxWrapDistRight ),
8061 nDyWrapDistBottom(rCopy.nDyWrapDistBottom ),
8062 nCropFromTop( rCopy.nCropFromTop ),
8063 nCropFromBottom( rCopy.nCropFromBottom ),
8064 nCropFromLeft( rCopy.nCropFromLeft ),
8065 nCropFromRight( rCopy.nCropFromRight ),
8066 aTextId( rCopy.aTextId ),
8067 nNextShapeId( rCopy.nNextShapeId ),
8068 nShapeId( rCopy.nShapeId ),
8069 eShapeType( rCopy.eShapeType )
8071 eLineStyle = rCopy.eLineStyle; // GPF-Bug #66227#
8072 bDrawHell = rCopy.bDrawHell;
8073 bHidden = rCopy.bHidden;
8074 // bInGroup = rCopy.bInGroup;
8075 bReplaceByFly = rCopy.bReplaceByFly;
8076 bAutoWidth = rCopy.bAutoWidth;
8077 bLastBoxInChain = rCopy.bLastBoxInChain;
8078 bHasUDefProp = rCopy.bHasUDefProp;
8079 bVFlip = rCopy.bVFlip;
8080 bHFlip = rCopy.bHFlip;
8081 nClientAnchorLen = rCopy.nClientAnchorLen;
8082 if( rCopy.nClientAnchorLen )
8084 pClientAnchorBuffer = new char[ nClientAnchorLen ];
8085 memcpy( pClientAnchorBuffer,
8086 rCopy.pClientAnchorBuffer,
8087 nClientAnchorLen );
8089 else
8090 pClientAnchorBuffer = 0;
8092 nClientDataLen = rCopy.nClientDataLen;
8093 if( rCopy.nClientDataLen )
8095 pClientDataBuffer = new char[ nClientDataLen ];
8096 memcpy( pClientDataBuffer,
8097 rCopy.pClientDataBuffer,
8098 nClientDataLen );
8100 else
8101 pClientDataBuffer = 0;
8103 if (rCopy.pWrapPolygon)
8104 pWrapPolygon = new Polygon(*rCopy.pWrapPolygon);
8105 else
8106 pWrapPolygon = 0;
8109 SvxMSDffImportRec::~SvxMSDffImportRec()
8111 if (pClientAnchorBuffer)
8112 delete[] pClientAnchorBuffer;
8113 if (pClientDataBuffer)
8114 delete[] pClientDataBuffer;
8115 if (pWrapPolygon)
8116 delete pWrapPolygon;
8119 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
8121 void SvxMSDffManager::insertShapeId( sal_Int32 nShapeId, SdrObject* pShape )
8123 maShapeIdContainer[nShapeId] = pShape;
8126 void SvxMSDffManager::removeShapeId( SdrObject* pShape )
8128 SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.begin() );
8129 const SvxMSDffShapeIdContainer::iterator aEnd( maShapeIdContainer.end() );
8130 while( aIter != aEnd )
8132 if( (*aIter).second == pShape )
8134 maShapeIdContainer.erase( aIter );
8135 break;
8140 SdrObject* SvxMSDffManager::getShapeForId( sal_Int32 nShapeId )
8142 SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.find(nShapeId) );
8143 return aIter != maShapeIdContainer.end() ? (*aIter).second : 0;