xref: /aoo42x/main/oox/source/xls/drawingmanager.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include "oox/xls/drawingmanager.hxx"
29*cdf0e10cSrcweir 
30*cdf0e10cSrcweir #include <com/sun/star/awt/Rectangle.hpp>
31*cdf0e10cSrcweir #include <com/sun/star/drawing/CircleKind.hpp>
32*cdf0e10cSrcweir #include <com/sun/star/drawing/PointSequenceSequence.hpp>
33*cdf0e10cSrcweir #include <com/sun/star/drawing/PolygonKind.hpp>
34*cdf0e10cSrcweir #include <com/sun/star/drawing/XShapes.hpp>
35*cdf0e10cSrcweir #include "oox/core/filterbase.hxx"
36*cdf0e10cSrcweir #include "oox/drawingml/fillproperties.hxx"
37*cdf0e10cSrcweir #include "oox/drawingml/lineproperties.hxx"
38*cdf0e10cSrcweir #include "oox/drawingml/shapepropertymap.hxx"
39*cdf0e10cSrcweir #include "oox/helper/containerhelper.hxx"
40*cdf0e10cSrcweir #include "oox/token/tokens.hxx"
41*cdf0e10cSrcweir #include "oox/xls/biffinputstream.hxx"
42*cdf0e10cSrcweir #include "oox/xls/unitconverter.hxx"
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir namespace oox {
45*cdf0e10cSrcweir namespace xls {
46*cdf0e10cSrcweir 
47*cdf0e10cSrcweir // ============================================================================
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir using namespace ::com::sun::star::awt;
50*cdf0e10cSrcweir using namespace ::com::sun::star::drawing;
51*cdf0e10cSrcweir using namespace ::com::sun::star::lang;
52*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
53*cdf0e10cSrcweir using namespace ::oox::drawingml;
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir using ::rtl::OUString;
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir // ============================================================================
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir namespace {
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir // OBJ record -----------------------------------------------------------------
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_GROUP         = 0;
64*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_LINE          = 1;
65*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_RECTANGLE     = 2;
66*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_OVAL          = 3;
67*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_ARC           = 4;
68*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_CHART         = 5;
69*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_TEXT          = 6;
70*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_BUTTON        = 7;
71*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_PICTURE       = 8;
72*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_POLYGON       = 9;        // new in BIFF4
73*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_CHECKBOX      = 11;       // new in BIFF5
74*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_OPTIONBUTTON  = 12;
75*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_EDIT          = 13;
76*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_LABEL         = 14;
77*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_DIALOG        = 15;
78*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_SPIN          = 16;
79*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_SCROLLBAR     = 17;
80*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_LISTBOX       = 18;
81*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_GROUPBOX      = 19;
82*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_DROPDOWN      = 20;
83*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_NOTE          = 25;       // new in BIFF8
84*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_DRAWING       = 30;
85*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJTYPE_UNKNOWN       = 0xFFFF;   // for internal use only
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJ_HIDDEN            = 0x0100;
88*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJ_VISIBLE           = 0x0200;
89*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJ_PRINTABLE         = 0x0400;
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir // line formatting ------------------------------------------------------------
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_AUTOCOLOR     = 64;
94*cdf0e10cSrcweir 
95*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_SOLID         = 0;
96*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_DASH          = 1;
97*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_DOT           = 2;
98*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_DASHDOT       = 3;
99*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_DASHDOTDOT    = 4;
100*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_MEDTRANS      = 5;
101*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_DARKTRANS     = 6;
102*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_LIGHTTRANS    = 7;
103*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_NONE          = 255;
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_HAIR          = 0;
106*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_THIN          = 1;
107*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_MEDIUM        = 2;
108*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_THICK         = 3;
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_AUTO          = 0x01;
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_ARROW_NONE         = 0;
113*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_ARROW_OPEN         = 1;
114*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_ARROW_FILLED       = 2;
115*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_ARROW_OPENBOTH     = 3;
116*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_ARROW_FILLEDBOTH   = 4;
117*cdf0e10cSrcweir 
118*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_ARROW_NARROW       = 0;
119*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_ARROW_MEDIUM       = 1;
120*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_ARROW_WIDE         = 2;
121*cdf0e10cSrcweir 
122*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_TL            = 0;
123*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_TR            = 1;
124*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_BR            = 2;
125*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_LINE_BL            = 3;
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_ARC_TR             = 0;
128*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_ARC_TL             = 1;
129*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_ARC_BL             = 2;
130*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_ARC_BR             = 3;
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJ_POLY_CLOSED       = 0x0100;
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir // fill formatting ------------------------------------------------------------
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_FILL_AUTOCOLOR     = 65;
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_PATT_NONE          = 0;
139*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_PATT_SOLID         = 1;
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_FILL_AUTO          = 0x01;
142*cdf0e10cSrcweir 
143*cdf0e10cSrcweir // text formatting ------------------------------------------------------------
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_HOR_LEFT           = 1;
146*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_HOR_CENTER         = 2;
147*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_HOR_RIGHT          = 3;
148*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_HOR_JUSTIFY        = 4;
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_VER_TOP            = 1;
151*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_VER_CENTER         = 2;
152*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_VER_BOTTOM         = 3;
153*cdf0e10cSrcweir const sal_uInt8 BIFF_OBJ_VER_JUSTIFY        = 4;
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJ_ORIENT_NONE       = 0;
156*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJ_ORIENT_STACKED    = 1;        /// Stacked top to bottom.
157*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJ_ORIENT_90CCW      = 2;        /// 90 degr. counterclockwise.
158*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJ_ORIENT_90CW       = 3;        /// 90 degr. clockwise.
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJ_TEXT_AUTOSIZE     = 0x0080;
161*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJ_TEXT_LOCKED       = 0x0200;
162*cdf0e10cSrcweir 
163*cdf0e10cSrcweir const sal_Int32 BIFF_OBJ_TEXT_MARGIN        = 20000;    /// Automatic text margin (EMUs).
164*cdf0e10cSrcweir 
165*cdf0e10cSrcweir // BIFF8 OBJ sub records ------------------------------------------------------
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJCMO_PRINTABLE      = 0x0010;   /// Object printable.
168*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJCMO_AUTOLINE       = 0x2000;   /// Automatic line formatting.
169*cdf0e10cSrcweir const sal_uInt16 BIFF_OBJCMO_AUTOFILL       = 0x4000;   /// Automatic fill formatting.
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir // ----------------------------------------------------------------------------
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir inline BiffInputStream& operator>>( BiffInputStream& rStrm, ShapeAnchor& rAnchor )
174*cdf0e10cSrcweir {
175*cdf0e10cSrcweir     rAnchor.importBiffAnchor( rStrm );
176*cdf0e10cSrcweir     return rStrm;
177*cdf0e10cSrcweir }
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir } // namespace
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir // ============================================================================
182*cdf0e10cSrcweir // Model structures for BIFF OBJ record data
183*cdf0e10cSrcweir // ============================================================================
184*cdf0e10cSrcweir 
185*cdf0e10cSrcweir BiffObjLineModel::BiffObjLineModel() :
186*cdf0e10cSrcweir     mnColorIdx( BIFF_OBJ_LINE_AUTOCOLOR ),
187*cdf0e10cSrcweir     mnStyle( BIFF_OBJ_LINE_SOLID ),
188*cdf0e10cSrcweir     mnWidth( BIFF_OBJ_LINE_HAIR ),
189*cdf0e10cSrcweir     mbAuto( true )
190*cdf0e10cSrcweir {
191*cdf0e10cSrcweir }
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir bool BiffObjLineModel::isVisible() const
194*cdf0e10cSrcweir {
195*cdf0e10cSrcweir     return mbAuto || (mnStyle != BIFF_OBJ_LINE_NONE);
196*cdf0e10cSrcweir }
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir BiffInputStream& operator>>( BiffInputStream& rStrm, BiffObjLineModel& rModel )
199*cdf0e10cSrcweir {
200*cdf0e10cSrcweir     sal_uInt8 nFlags;
201*cdf0e10cSrcweir     rStrm >> rModel.mnColorIdx >> rModel.mnStyle >> rModel.mnWidth >> nFlags;
202*cdf0e10cSrcweir     rModel.mbAuto = getFlag( nFlags, BIFF_OBJ_LINE_AUTO );
203*cdf0e10cSrcweir     return rStrm;
204*cdf0e10cSrcweir }
205*cdf0e10cSrcweir 
206*cdf0e10cSrcweir // ============================================================================
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir BiffObjFillModel::BiffObjFillModel() :
209*cdf0e10cSrcweir     mnBackColorIdx( BIFF_OBJ_LINE_AUTOCOLOR ),
210*cdf0e10cSrcweir     mnPattColorIdx( BIFF_OBJ_FILL_AUTOCOLOR ),
211*cdf0e10cSrcweir     mnPattern( BIFF_OBJ_PATT_SOLID ),
212*cdf0e10cSrcweir     mbAuto( true )
213*cdf0e10cSrcweir {
214*cdf0e10cSrcweir }
215*cdf0e10cSrcweir 
216*cdf0e10cSrcweir bool BiffObjFillModel::isFilled() const
217*cdf0e10cSrcweir {
218*cdf0e10cSrcweir     return mbAuto || (mnPattern != BIFF_OBJ_PATT_NONE);
219*cdf0e10cSrcweir }
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir BiffInputStream& operator>>( BiffInputStream& rStrm, BiffObjFillModel& rModel )
222*cdf0e10cSrcweir {
223*cdf0e10cSrcweir     sal_uInt8 nFlags;
224*cdf0e10cSrcweir     rStrm >> rModel.mnBackColorIdx >> rModel.mnPattColorIdx >> rModel.mnPattern >> nFlags;
225*cdf0e10cSrcweir     rModel.mbAuto = getFlag( nFlags, BIFF_OBJ_FILL_AUTO );
226*cdf0e10cSrcweir     return rStrm;
227*cdf0e10cSrcweir }
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir // ============================================================================
230*cdf0e10cSrcweir 
231*cdf0e10cSrcweir BiffObjTextModel::BiffObjTextModel() :
232*cdf0e10cSrcweir     mnTextLen( 0 ),
233*cdf0e10cSrcweir     mnFormatSize( 0 ),
234*cdf0e10cSrcweir     mnLinkSize( 0 ),
235*cdf0e10cSrcweir     mnDefFontId( 0 ),
236*cdf0e10cSrcweir     mnFlags( 0 ),
237*cdf0e10cSrcweir     mnOrientation( BIFF_OBJ_ORIENT_NONE ),
238*cdf0e10cSrcweir     mnButtonFlags( 0 ),
239*cdf0e10cSrcweir     mnShortcut( 0 ),
240*cdf0e10cSrcweir     mnShortcutEA( 0 )
241*cdf0e10cSrcweir {
242*cdf0e10cSrcweir }
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir void BiffObjTextModel::readObj3( BiffInputStream& rStrm )
245*cdf0e10cSrcweir {
246*cdf0e10cSrcweir     rStrm >> mnTextLen;
247*cdf0e10cSrcweir     rStrm.skip( 2 );
248*cdf0e10cSrcweir     rStrm >> mnFormatSize >> mnDefFontId;
249*cdf0e10cSrcweir     rStrm.skip( 2 );
250*cdf0e10cSrcweir     rStrm >> mnFlags >> mnOrientation;
251*cdf0e10cSrcweir     rStrm.skip( 8 );
252*cdf0e10cSrcweir }
253*cdf0e10cSrcweir 
254*cdf0e10cSrcweir void BiffObjTextModel::readObj5( BiffInputStream& rStrm )
255*cdf0e10cSrcweir {
256*cdf0e10cSrcweir     rStrm >> mnTextLen;
257*cdf0e10cSrcweir     rStrm.skip( 2 );
258*cdf0e10cSrcweir     rStrm >> mnFormatSize >> mnDefFontId;
259*cdf0e10cSrcweir     rStrm.skip( 2 );
260*cdf0e10cSrcweir     rStrm >> mnFlags >> mnOrientation;
261*cdf0e10cSrcweir     rStrm.skip( 2 );
262*cdf0e10cSrcweir     rStrm >> mnLinkSize;
263*cdf0e10cSrcweir     rStrm.skip( 2 );
264*cdf0e10cSrcweir     rStrm >> mnButtonFlags >> mnShortcut >> mnShortcutEA;
265*cdf0e10cSrcweir }
266*cdf0e10cSrcweir 
267*cdf0e10cSrcweir void BiffObjTextModel::readTxo8( BiffInputStream& rStrm )
268*cdf0e10cSrcweir {
269*cdf0e10cSrcweir     rStrm >> mnFlags >> mnOrientation >> mnButtonFlags >> mnShortcut >> mnShortcutEA >> mnTextLen >> mnFormatSize;
270*cdf0e10cSrcweir }
271*cdf0e10cSrcweir 
272*cdf0e10cSrcweir sal_uInt8 BiffObjTextModel::getHorAlign() const
273*cdf0e10cSrcweir {
274*cdf0e10cSrcweir     return extractValue< sal_uInt8 >( mnFlags, 1, 3 );
275*cdf0e10cSrcweir }
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir sal_uInt8 BiffObjTextModel::getVerAlign() const
278*cdf0e10cSrcweir {
279*cdf0e10cSrcweir     return extractValue< sal_uInt8 >( mnFlags, 4, 3 );
280*cdf0e10cSrcweir }
281*cdf0e10cSrcweir 
282*cdf0e10cSrcweir // ============================================================================
283*cdf0e10cSrcweir // BIFF drawing objects
284*cdf0e10cSrcweir // ============================================================================
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir BiffDrawingObjectContainer::BiffDrawingObjectContainer()
287*cdf0e10cSrcweir {
288*cdf0e10cSrcweir }
289*cdf0e10cSrcweir 
290*cdf0e10cSrcweir void BiffDrawingObjectContainer::append( const BiffDrawingObjectRef& rxDrawingObj )
291*cdf0e10cSrcweir {
292*cdf0e10cSrcweir     maObjects.push_back( rxDrawingObj );
293*cdf0e10cSrcweir }
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir void BiffDrawingObjectContainer::insertGrouped( const BiffDrawingObjectRef& rxDrawingObj )
296*cdf0e10cSrcweir {
297*cdf0e10cSrcweir     if( !maObjects.empty() )
298*cdf0e10cSrcweir         if( BiffGroupObject* pGroupObj = dynamic_cast< BiffGroupObject* >( maObjects.back().get() ) )
299*cdf0e10cSrcweir             if( pGroupObj->tryInsert( rxDrawingObj ) )
300*cdf0e10cSrcweir                 return;
301*cdf0e10cSrcweir     maObjects.push_back( rxDrawingObj );
302*cdf0e10cSrcweir }
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir void BiffDrawingObjectContainer::convertAndInsert( BiffDrawingBase& rDrawing, const Reference< XShapes >& rxShapes, const Rectangle* pParentRect ) const
305*cdf0e10cSrcweir {
306*cdf0e10cSrcweir     maObjects.forEachMem( &BiffDrawingObjectBase::convertAndInsert, ::boost::ref( rDrawing ), ::boost::cref( rxShapes ), pParentRect );
307*cdf0e10cSrcweir }
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir // ============================================================================
310*cdf0e10cSrcweir 
311*cdf0e10cSrcweir BiffDrawingObjectBase::BiffDrawingObjectBase( const WorksheetHelper& rHelper ) :
312*cdf0e10cSrcweir     WorksheetHelper( rHelper ),
313*cdf0e10cSrcweir     maAnchor( rHelper ),
314*cdf0e10cSrcweir     mnDffShapeId( 0 ),
315*cdf0e10cSrcweir     mnDffFlags( 0 ),
316*cdf0e10cSrcweir     mnObjId( BIFF_OBJ_INVALID_ID ),
317*cdf0e10cSrcweir     mnObjType( BIFF_OBJTYPE_UNKNOWN ),
318*cdf0e10cSrcweir     mbHasAnchor( false ),
319*cdf0e10cSrcweir     mbHidden( false ),
320*cdf0e10cSrcweir     mbVisible( true ),
321*cdf0e10cSrcweir     mbPrintable( true ),
322*cdf0e10cSrcweir     mbAreaObj( false ),
323*cdf0e10cSrcweir     mbAutoMargin( true ),
324*cdf0e10cSrcweir     mbSimpleMacro( true ),
325*cdf0e10cSrcweir     mbProcessShape( true ),
326*cdf0e10cSrcweir     mbInsertShape( true ),
327*cdf0e10cSrcweir     mbCustomDff( false )
328*cdf0e10cSrcweir {
329*cdf0e10cSrcweir }
330*cdf0e10cSrcweir 
331*cdf0e10cSrcweir BiffDrawingObjectBase::~BiffDrawingObjectBase()
332*cdf0e10cSrcweir {
333*cdf0e10cSrcweir }
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir /*static*/ BiffDrawingObjectRef BiffDrawingObjectBase::importObjBiff3( const WorksheetHelper& rHelper, BiffInputStream& rStrm )
336*cdf0e10cSrcweir {
337*cdf0e10cSrcweir     BiffDrawingObjectRef xDrawingObj;
338*cdf0e10cSrcweir 
339*cdf0e10cSrcweir     if( rStrm.getRemaining() >= 30 )
340*cdf0e10cSrcweir     {
341*cdf0e10cSrcweir         sal_uInt16 nObjType;
342*cdf0e10cSrcweir         rStrm.skip( 4 );
343*cdf0e10cSrcweir         rStrm >> nObjType;
344*cdf0e10cSrcweir         switch( nObjType )
345*cdf0e10cSrcweir         {
346*cdf0e10cSrcweir             case BIFF_OBJTYPE_GROUP:        xDrawingObj.reset( new BiffGroupObject( rHelper ) );    break;
347*cdf0e10cSrcweir             case BIFF_OBJTYPE_LINE:         xDrawingObj.reset( new BiffLineObject( rHelper ) );     break;
348*cdf0e10cSrcweir             case BIFF_OBJTYPE_RECTANGLE:    xDrawingObj.reset( new BiffRectObject( rHelper ) );     break;
349*cdf0e10cSrcweir             case BIFF_OBJTYPE_OVAL:         xDrawingObj.reset( new BiffOvalObject( rHelper ) );     break;
350*cdf0e10cSrcweir             case BIFF_OBJTYPE_ARC:          xDrawingObj.reset( new BiffArcObject( rHelper ) );      break;
351*cdf0e10cSrcweir #if 0
352*cdf0e10cSrcweir             case BIFF_OBJTYPE_CHART:        xDrawingObj.reset( new XclImpChartObj( rHelper ) );     break;
353*cdf0e10cSrcweir             case BIFF_OBJTYPE_TEXT:         xDrawingObj.reset( new XclImpTextObj( rHelper ) );      break;
354*cdf0e10cSrcweir             case BIFF_OBJTYPE_BUTTON:       xDrawingObj.reset( new XclImpButtonObj( rHelper ) );    break;
355*cdf0e10cSrcweir             case BIFF_OBJTYPE_PICTURE:      xDrawingObj.reset( new XclImpPictureObj( rHelper ) );   break;
356*cdf0e10cSrcweir #endif
357*cdf0e10cSrcweir             default:
358*cdf0e10cSrcweir #if 0
359*cdf0e10cSrcweir                 OSL_ENSURE( false, "BiffDrawingObjectBase::importObjBiff3 - unknown object type" );
360*cdf0e10cSrcweir #endif
361*cdf0e10cSrcweir                 xDrawingObj.reset( new BiffPlaceholderObject( rHelper ) );
362*cdf0e10cSrcweir         }
363*cdf0e10cSrcweir     }
364*cdf0e10cSrcweir 
365*cdf0e10cSrcweir     xDrawingObj->importObjBiff3( rStrm );
366*cdf0e10cSrcweir     return xDrawingObj;
367*cdf0e10cSrcweir }
368*cdf0e10cSrcweir 
369*cdf0e10cSrcweir /*static*/ BiffDrawingObjectRef BiffDrawingObjectBase::importObjBiff4( const WorksheetHelper& rHelper, BiffInputStream& rStrm )
370*cdf0e10cSrcweir {
371*cdf0e10cSrcweir     BiffDrawingObjectRef xDrawingObj;
372*cdf0e10cSrcweir 
373*cdf0e10cSrcweir     if( rStrm.getRemaining() >= 30 )
374*cdf0e10cSrcweir     {
375*cdf0e10cSrcweir         sal_uInt16 nObjType;
376*cdf0e10cSrcweir         rStrm.skip( 4 );
377*cdf0e10cSrcweir         rStrm >> nObjType;
378*cdf0e10cSrcweir         switch( nObjType )
379*cdf0e10cSrcweir         {
380*cdf0e10cSrcweir             case BIFF_OBJTYPE_GROUP:        xDrawingObj.reset( new BiffGroupObject( rHelper ) );    break;
381*cdf0e10cSrcweir             case BIFF_OBJTYPE_LINE:         xDrawingObj.reset( new BiffLineObject( rHelper ) );     break;
382*cdf0e10cSrcweir             case BIFF_OBJTYPE_RECTANGLE:    xDrawingObj.reset( new BiffRectObject( rHelper ) );     break;
383*cdf0e10cSrcweir             case BIFF_OBJTYPE_OVAL:         xDrawingObj.reset( new BiffOvalObject( rHelper ) );     break;
384*cdf0e10cSrcweir             case BIFF_OBJTYPE_ARC:          xDrawingObj.reset( new BiffArcObject( rHelper ) );      break;
385*cdf0e10cSrcweir             case BIFF_OBJTYPE_POLYGON:      xDrawingObj.reset( new BiffPolygonObject( rHelper ) );  break;
386*cdf0e10cSrcweir #if 0
387*cdf0e10cSrcweir             case BIFF_OBJTYPE_CHART:        xDrawingObj.reset( new XclImpChartObj( rHelper ) );     break;
388*cdf0e10cSrcweir             case BIFF_OBJTYPE_TEXT:         xDrawingObj.reset( new XclImpTextObj( rHelper ) );      break;
389*cdf0e10cSrcweir             case BIFF_OBJTYPE_BUTTON:       xDrawingObj.reset( new XclImpButtonObj( rHelper ) );    break;
390*cdf0e10cSrcweir             case BIFF_OBJTYPE_PICTURE:      xDrawingObj.reset( new XclImpPictureObj( rHelper ) );   break;
391*cdf0e10cSrcweir #endif
392*cdf0e10cSrcweir             default:
393*cdf0e10cSrcweir #if 0
394*cdf0e10cSrcweir                 OSL_ENSURE( false, "BiffDrawingObjectBase::importObjBiff4 - unknown object type" );
395*cdf0e10cSrcweir #endif
396*cdf0e10cSrcweir                 xDrawingObj.reset( new BiffPlaceholderObject( rHelper ) );
397*cdf0e10cSrcweir         }
398*cdf0e10cSrcweir     }
399*cdf0e10cSrcweir 
400*cdf0e10cSrcweir     xDrawingObj->importObjBiff4( rStrm );
401*cdf0e10cSrcweir     return xDrawingObj;
402*cdf0e10cSrcweir }
403*cdf0e10cSrcweir 
404*cdf0e10cSrcweir /*static*/ BiffDrawingObjectRef BiffDrawingObjectBase::importObjBiff5( const WorksheetHelper& rHelper, BiffInputStream& rStrm )
405*cdf0e10cSrcweir {
406*cdf0e10cSrcweir     BiffDrawingObjectRef xDrawingObj;
407*cdf0e10cSrcweir 
408*cdf0e10cSrcweir     if( rStrm.getRemaining() >= 34 )
409*cdf0e10cSrcweir     {
410*cdf0e10cSrcweir         sal_uInt16 nObjType;
411*cdf0e10cSrcweir         rStrm.skip( 4 );
412*cdf0e10cSrcweir         rStrm >> nObjType;
413*cdf0e10cSrcweir         switch( nObjType )
414*cdf0e10cSrcweir         {
415*cdf0e10cSrcweir             case BIFF_OBJTYPE_GROUP:        xDrawingObj.reset( new BiffGroupObject( rHelper ) );        break;
416*cdf0e10cSrcweir             case BIFF_OBJTYPE_LINE:         xDrawingObj.reset( new BiffLineObject( rHelper ) );         break;
417*cdf0e10cSrcweir             case BIFF_OBJTYPE_RECTANGLE:    xDrawingObj.reset( new BiffRectObject( rHelper ) );         break;
418*cdf0e10cSrcweir             case BIFF_OBJTYPE_OVAL:         xDrawingObj.reset( new BiffOvalObject( rHelper ) );         break;
419*cdf0e10cSrcweir             case BIFF_OBJTYPE_ARC:          xDrawingObj.reset( new BiffArcObject( rHelper ) );           break;
420*cdf0e10cSrcweir             case BIFF_OBJTYPE_POLYGON:      xDrawingObj.reset( new BiffPolygonObject( rHelper ) );      break;
421*cdf0e10cSrcweir #if 0
422*cdf0e10cSrcweir             case BIFF_OBJTYPE_CHART:        xDrawingObj.reset( new XclImpChartObj( rHelper ) );         break;
423*cdf0e10cSrcweir             case BIFF_OBJTYPE_TEXT:         xDrawingObj.reset( new XclImpTextObj( rHelper ) );          break;
424*cdf0e10cSrcweir             case BIFF_OBJTYPE_BUTTON:       xDrawingObj.reset( new XclImpButtonObj( rHelper ) );        break;
425*cdf0e10cSrcweir             case BIFF_OBJTYPE_PICTURE:      xDrawingObj.reset( new XclImpPictureObj( rHelper ) );       break;
426*cdf0e10cSrcweir             case BIFF_OBJTYPE_CHECKBOX:     xDrawingObj.reset( new XclImpCheckBoxObj( rHelper ) );      break;
427*cdf0e10cSrcweir             case BIFF_OBJTYPE_OPTIONBUTTON: xDrawingObj.reset( new XclImpOptionButtonObj( rHelper ) );  break;
428*cdf0e10cSrcweir             case BIFF_OBJTYPE_EDIT:         xDrawingObj.reset( new XclImpEditObj( rHelper ) );          break;
429*cdf0e10cSrcweir             case BIFF_OBJTYPE_LABEL:        xDrawingObj.reset( new XclImpLabelObj( rHelper ) );         break;
430*cdf0e10cSrcweir             case BIFF_OBJTYPE_DIALOG:       xDrawingObj.reset( new XclImpDialogObj( rHelper ) );        break;
431*cdf0e10cSrcweir             case BIFF_OBJTYPE_SPIN:         xDrawingObj.reset( new XclImpSpinButtonObj( rHelper ) );    break;
432*cdf0e10cSrcweir             case BIFF_OBJTYPE_SCROLLBAR:    xDrawingObj.reset( new XclImpScrollBarObj( rHelper ) );     break;
433*cdf0e10cSrcweir             case BIFF_OBJTYPE_LISTBOX:      xDrawingObj.reset( new XclImpListBoxObj( rHelper ) );       break;
434*cdf0e10cSrcweir             case BIFF_OBJTYPE_GROUPBOX:     xDrawingObj.reset( new XclImpGroupBoxObj( rHelper ) );      break;
435*cdf0e10cSrcweir             case BIFF_OBJTYPE_DROPDOWN:     xDrawingObj.reset( new XclImpDropDownObj( rHelper ) );      break;
436*cdf0e10cSrcweir #endif
437*cdf0e10cSrcweir             default:
438*cdf0e10cSrcweir #if 0
439*cdf0e10cSrcweir                 OSL_ENSURE( false, "BiffDrawingObjectBase::importObjBiff5 - unknown object type" );
440*cdf0e10cSrcweir #endif
441*cdf0e10cSrcweir                 xDrawingObj.reset( new BiffPlaceholderObject( rHelper ) );
442*cdf0e10cSrcweir         }
443*cdf0e10cSrcweir     }
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir     xDrawingObj->importObjBiff5( rStrm );
446*cdf0e10cSrcweir     return xDrawingObj;
447*cdf0e10cSrcweir }
448*cdf0e10cSrcweir 
449*cdf0e10cSrcweir /*static*/ BiffDrawingObjectRef BiffDrawingObjectBase::importObjBiff8( const WorksheetHelper& rHelper, BiffInputStream& rStrm )
450*cdf0e10cSrcweir {
451*cdf0e10cSrcweir     BiffDrawingObjectRef xDrawingObj;
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir     if( rStrm.getRemaining() >= 10 )
454*cdf0e10cSrcweir     {
455*cdf0e10cSrcweir         sal_uInt16 nSubRecId, nSubRecSize, nObjType;
456*cdf0e10cSrcweir         rStrm >> nSubRecId >> nSubRecSize >> nObjType;
457*cdf0e10cSrcweir         OSL_ENSURE( nSubRecId == BIFF_ID_OBJCMO, "BiffDrawingObjectBase::importObjBiff8 - OBJCMO subrecord expected" );
458*cdf0e10cSrcweir         if( (nSubRecId == BIFF_ID_OBJCMO) && (nSubRecSize >= 6) )
459*cdf0e10cSrcweir         {
460*cdf0e10cSrcweir             switch( nObjType )
461*cdf0e10cSrcweir             {
462*cdf0e10cSrcweir #if 0
463*cdf0e10cSrcweir                 // in BIFF8, all simple objects support text
464*cdf0e10cSrcweir                 case BIFF_OBJTYPE_LINE:
465*cdf0e10cSrcweir                 case BIFF_OBJTYPE_ARC:
466*cdf0e10cSrcweir                     xDrawingObj.reset( new XclImpTextObj( rHelper ) );
467*cdf0e10cSrcweir                     // lines and arcs may be 2-dimensional
468*cdf0e10cSrcweir                     xDrawingObj->setAreaObj( false );
469*cdf0e10cSrcweir                 break;
470*cdf0e10cSrcweir 
471*cdf0e10cSrcweir                 // in BIFF8, all simple objects support text
472*cdf0e10cSrcweir                 case BIFF_OBJTYPE_RECTANGLE:
473*cdf0e10cSrcweir                 case BIFF_OBJTYPE_OVAL:
474*cdf0e10cSrcweir                 case BIFF_OBJTYPE_POLYGON:
475*cdf0e10cSrcweir                 case BIFF_OBJTYPE_DRAWING:
476*cdf0e10cSrcweir                 case BIFF_OBJTYPE_TEXT:
477*cdf0e10cSrcweir                     xDrawingObj.reset( new XclImpTextObj( rHelper ) );
478*cdf0e10cSrcweir                 break;
479*cdf0e10cSrcweir #endif
480*cdf0e10cSrcweir 
481*cdf0e10cSrcweir                 case BIFF_OBJTYPE_GROUP:        xDrawingObj.reset( new BiffGroupObject( rHelper ) );        break;
482*cdf0e10cSrcweir #if 0
483*cdf0e10cSrcweir                 case BIFF_OBJTYPE_CHART:        xDrawingObj.reset( new XclImpChartObj( rHelper ) );         break;
484*cdf0e10cSrcweir                 case BIFF_OBJTYPE_BUTTON:       xDrawingObj.reset( new XclImpButtonObj( rHelper ) );        break;
485*cdf0e10cSrcweir                 case BIFF_OBJTYPE_PICTURE:      xDrawingObj.reset( new XclImpPictureObj( rHelper ) );       break;
486*cdf0e10cSrcweir                 case BIFF_OBJTYPE_CHECKBOX:     xDrawingObj.reset( new XclImpCheckBoxObj( rHelper ) );      break;
487*cdf0e10cSrcweir                 case BIFF_OBJTYPE_OPTIONBUTTON: xDrawingObj.reset( new XclImpOptionButtonObj( rHelper ) );  break;
488*cdf0e10cSrcweir                 case BIFF_OBJTYPE_EDIT:         xDrawingObj.reset( new XclImpEditObj( rHelper ) );          break;
489*cdf0e10cSrcweir                 case BIFF_OBJTYPE_LABEL:        xDrawingObj.reset( new XclImpLabelObj( rHelper ) );         break;
490*cdf0e10cSrcweir                 case BIFF_OBJTYPE_DIALOG:       xDrawingObj.reset( new XclImpDialogObj( rHelper ) );        break;
491*cdf0e10cSrcweir                 case BIFF_OBJTYPE_SPIN:         xDrawingObj.reset( new XclImpSpinButtonObj( rHelper ) );    break;
492*cdf0e10cSrcweir                 case BIFF_OBJTYPE_SCROLLBAR:    xDrawingObj.reset( new XclImpScrollBarObj( rHelper ) );     break;
493*cdf0e10cSrcweir                 case BIFF_OBJTYPE_LISTBOX:      xDrawingObj.reset( new XclImpListBoxObj( rHelper ) );       break;
494*cdf0e10cSrcweir                 case BIFF_OBJTYPE_GROUPBOX:     xDrawingObj.reset( new XclImpGroupBoxObj( rHelper ) );      break;
495*cdf0e10cSrcweir                 case BIFF_OBJTYPE_DROPDOWN:     xDrawingObj.reset( new XclImpDropDownObj( rHelper ) );      break;
496*cdf0e10cSrcweir                 case BIFF_OBJTYPE_NOTE:         xDrawingObj.reset( new XclImpNoteObj( rHelper ) );          break;
497*cdf0e10cSrcweir #endif
498*cdf0e10cSrcweir 
499*cdf0e10cSrcweir                 default:
500*cdf0e10cSrcweir #if 0
501*cdf0e10cSrcweir                     OSL_ENSURE( false, "BiffDrawingObjectBase::importObjBiff8 - unknown object type" );
502*cdf0e10cSrcweir #endif
503*cdf0e10cSrcweir                     xDrawingObj.reset( new BiffPlaceholderObject( rHelper ) );
504*cdf0e10cSrcweir             }
505*cdf0e10cSrcweir         }
506*cdf0e10cSrcweir     }
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir     xDrawingObj->importObjBiff8( rStrm );
509*cdf0e10cSrcweir     return xDrawingObj;
510*cdf0e10cSrcweir }
511*cdf0e10cSrcweir 
512*cdf0e10cSrcweir Reference< XShape > BiffDrawingObjectBase::convertAndInsert( BiffDrawingBase& rDrawing,
513*cdf0e10cSrcweir         const Reference< XShapes >& rxShapes, const Rectangle* pParentRect ) const
514*cdf0e10cSrcweir {
515*cdf0e10cSrcweir     Reference< XShape > xShape;
516*cdf0e10cSrcweir     if( rxShapes.is() && mbProcessShape && !mbHidden )  // TODO: support for hidden objects?
517*cdf0e10cSrcweir     {
518*cdf0e10cSrcweir         // base class 'ShapeAnchor' calculates the shape rectangle in 1/100 mm
519*cdf0e10cSrcweir         // in BIFF3-BIFF5, all shapes have absolute anchor (also children of group shapes)
520*cdf0e10cSrcweir         Rectangle aShapeRect = maAnchor.calcAnchorRectHmm( getDrawPageSize() );
521*cdf0e10cSrcweir 
522*cdf0e10cSrcweir         // convert the shape, if the calculated rectangle is not empty
523*cdf0e10cSrcweir         bool bHasWidth = aShapeRect.Width > 0;
524*cdf0e10cSrcweir         bool bHasHeight = aShapeRect.Height > 0;
525*cdf0e10cSrcweir         if( mbAreaObj ? (bHasWidth && bHasHeight) : (bHasWidth || bHasHeight) )
526*cdf0e10cSrcweir         {
527*cdf0e10cSrcweir             xShape = implConvertAndInsert( rDrawing, rxShapes, aShapeRect );
528*cdf0e10cSrcweir             /*  Notify the drawing that a new shape has been inserted (but not
529*cdf0e10cSrcweir                 for children of group shapes). For convenience, pass the
530*cdf0e10cSrcweir                 rectangle that contains position and size of the shape. */
531*cdf0e10cSrcweir             if( !pParentRect && xShape.is() )
532*cdf0e10cSrcweir                 rDrawing.notifyShapeInserted( xShape, aShapeRect );
533*cdf0e10cSrcweir         }
534*cdf0e10cSrcweir     }
535*cdf0e10cSrcweir     return xShape;
536*cdf0e10cSrcweir }
537*cdf0e10cSrcweir 
538*cdf0e10cSrcweir // protected ------------------------------------------------------------------
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir void BiffDrawingObjectBase::readNameBiff5( BiffInputStream& rStrm, sal_uInt16 nNameLen )
541*cdf0e10cSrcweir {
542*cdf0e10cSrcweir     maObjName = OUString();
543*cdf0e10cSrcweir     if( nNameLen > 0 )
544*cdf0e10cSrcweir     {
545*cdf0e10cSrcweir         // name length field is repeated before the name
546*cdf0e10cSrcweir         maObjName = rStrm.readByteStringUC( false, getTextEncoding() );
547*cdf0e10cSrcweir         // skip padding byte for word boundaries
548*cdf0e10cSrcweir         rStrm.alignToBlock( 2 );
549*cdf0e10cSrcweir     }
550*cdf0e10cSrcweir }
551*cdf0e10cSrcweir 
552*cdf0e10cSrcweir void BiffDrawingObjectBase::readMacroBiff3( BiffInputStream& rStrm, sal_uInt16 nMacroSize )
553*cdf0e10cSrcweir {
554*cdf0e10cSrcweir     maMacroName = OUString();
555*cdf0e10cSrcweir     rStrm.skip( nMacroSize );
556*cdf0e10cSrcweir     // skip padding byte for word boundaries, not contained in nMacroSize
557*cdf0e10cSrcweir     rStrm.alignToBlock( 2 );
558*cdf0e10cSrcweir }
559*cdf0e10cSrcweir 
560*cdf0e10cSrcweir void BiffDrawingObjectBase::readMacroBiff4( BiffInputStream& rStrm, sal_uInt16 nMacroSize )
561*cdf0e10cSrcweir {
562*cdf0e10cSrcweir     maMacroName = OUString();
563*cdf0e10cSrcweir     rStrm.skip( nMacroSize );
564*cdf0e10cSrcweir }
565*cdf0e10cSrcweir 
566*cdf0e10cSrcweir void BiffDrawingObjectBase::readMacroBiff5( BiffInputStream& rStrm, sal_uInt16 nMacroSize )
567*cdf0e10cSrcweir {
568*cdf0e10cSrcweir     maMacroName = OUString();
569*cdf0e10cSrcweir     rStrm.skip( nMacroSize );
570*cdf0e10cSrcweir }
571*cdf0e10cSrcweir 
572*cdf0e10cSrcweir void BiffDrawingObjectBase::readMacroBiff8( BiffInputStream& rStrm )
573*cdf0e10cSrcweir {
574*cdf0e10cSrcweir     maMacroName = OUString();
575*cdf0e10cSrcweir     if( rStrm.getRemaining() > 6 )
576*cdf0e10cSrcweir     {
577*cdf0e10cSrcweir         // macro is stored in a tNameXR token containing a link to a defined name
578*cdf0e10cSrcweir         sal_uInt16 nFmlaSize;
579*cdf0e10cSrcweir         rStrm >> nFmlaSize;
580*cdf0e10cSrcweir         rStrm.skip( 4 );
581*cdf0e10cSrcweir         OSL_ENSURE( nFmlaSize == 7, "BiffDrawingObjectBase::readMacroBiff8 - unexpected formula size" );
582*cdf0e10cSrcweir         if( nFmlaSize == 7 )
583*cdf0e10cSrcweir         {
584*cdf0e10cSrcweir             sal_uInt8 nTokenId;
585*cdf0e10cSrcweir             sal_uInt16 nExtLinkId, nExtNameId;
586*cdf0e10cSrcweir             rStrm >> nTokenId >> nExtLinkId >> nExtNameId;
587*cdf0e10cSrcweir #if 0
588*cdf0e10cSrcweir             OSL_ENSURE( nTokenId == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ),
589*cdf0e10cSrcweir                 "BiffDrawingObjectBase::readMacroBiff8 - tNameXR token expected" );
590*cdf0e10cSrcweir             if( nTokenId == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ) )
591*cdf0e10cSrcweir                 maMacroName = GetLinkManager().GetMacroName( nExtLinkId, nExtNameId );
592*cdf0e10cSrcweir #endif
593*cdf0e10cSrcweir         }
594*cdf0e10cSrcweir     }
595*cdf0e10cSrcweir }
596*cdf0e10cSrcweir 
597*cdf0e10cSrcweir void BiffDrawingObjectBase::convertLineProperties( ShapePropertyMap& rPropMap, const BiffObjLineModel& rLineModel, sal_uInt16 nArrows ) const
598*cdf0e10cSrcweir {
599*cdf0e10cSrcweir     if( rLineModel.mbAuto )
600*cdf0e10cSrcweir     {
601*cdf0e10cSrcweir         BiffObjLineModel aAutoModel;
602*cdf0e10cSrcweir         aAutoModel.mbAuto = false;
603*cdf0e10cSrcweir         convertLineProperties( rPropMap, aAutoModel, nArrows );
604*cdf0e10cSrcweir         return;
605*cdf0e10cSrcweir     }
606*cdf0e10cSrcweir 
607*cdf0e10cSrcweir     /*  Convert line formatting to DrawingML line formatting and let the
608*cdf0e10cSrcweir         DrawingML code do the hard work. */
609*cdf0e10cSrcweir     LineProperties aLineProps;
610*cdf0e10cSrcweir 
611*cdf0e10cSrcweir     if( rLineModel.mnStyle == BIFF_OBJ_LINE_NONE )
612*cdf0e10cSrcweir     {
613*cdf0e10cSrcweir         aLineProps.maLineFill.moFillType = XML_noFill;
614*cdf0e10cSrcweir     }
615*cdf0e10cSrcweir     else
616*cdf0e10cSrcweir     {
617*cdf0e10cSrcweir         aLineProps.maLineFill.moFillType = XML_solidFill;
618*cdf0e10cSrcweir         aLineProps.maLineFill.maFillColor.setPaletteClr( rLineModel.mnColorIdx );
619*cdf0e10cSrcweir         aLineProps.moLineCompound = XML_sng;
620*cdf0e10cSrcweir         aLineProps.moLineCap = XML_flat;
621*cdf0e10cSrcweir         aLineProps.moLineJoint = XML_round;
622*cdf0e10cSrcweir 
623*cdf0e10cSrcweir         // line width: use 0.35 mm per BIFF line width step
624*cdf0e10cSrcweir         sal_Int32 nLineWidth = 0;
625*cdf0e10cSrcweir         switch( rLineModel.mnWidth )
626*cdf0e10cSrcweir         {
627*cdf0e10cSrcweir             default:
628*cdf0e10cSrcweir             case BIFF_OBJ_LINE_HAIR:    nLineWidth = 0;     break;
629*cdf0e10cSrcweir             case BIFF_OBJ_LINE_THIN:    nLineWidth = 20;    break;
630*cdf0e10cSrcweir             case BIFF_OBJ_LINE_MEDIUM:  nLineWidth = 40;    break;
631*cdf0e10cSrcweir             case BIFF_OBJ_LINE_THICK:   nLineWidth = 60;    break;
632*cdf0e10cSrcweir         }
633*cdf0e10cSrcweir         aLineProps.moLineWidth = getLimitedValue< sal_Int32, sal_Int64 >( convertHmmToEmu( nLineWidth ), 0, SAL_MAX_INT32 );
634*cdf0e10cSrcweir 
635*cdf0e10cSrcweir         // dash style and transparency
636*cdf0e10cSrcweir         switch( rLineModel.mnStyle )
637*cdf0e10cSrcweir         {
638*cdf0e10cSrcweir             default:
639*cdf0e10cSrcweir             case BIFF_OBJ_LINE_SOLID:
640*cdf0e10cSrcweir                 aLineProps.moPresetDash = XML_solid;
641*cdf0e10cSrcweir             break;
642*cdf0e10cSrcweir             case BIFF_OBJ_LINE_DASH:
643*cdf0e10cSrcweir                 aLineProps.moPresetDash = XML_lgDash;
644*cdf0e10cSrcweir             break;
645*cdf0e10cSrcweir             case BIFF_OBJ_LINE_DOT:
646*cdf0e10cSrcweir                 aLineProps.moPresetDash = XML_dot;
647*cdf0e10cSrcweir             break;
648*cdf0e10cSrcweir             case BIFF_OBJ_LINE_DASHDOT:
649*cdf0e10cSrcweir                 aLineProps.moPresetDash = XML_lgDashDot;
650*cdf0e10cSrcweir             break;
651*cdf0e10cSrcweir             case BIFF_OBJ_LINE_DASHDOTDOT:
652*cdf0e10cSrcweir                 aLineProps.moPresetDash = XML_lgDashDotDot;
653*cdf0e10cSrcweir             break;
654*cdf0e10cSrcweir             case BIFF_OBJ_LINE_MEDTRANS:
655*cdf0e10cSrcweir                 aLineProps.moPresetDash = XML_solid;
656*cdf0e10cSrcweir                 aLineProps.maLineFill.maFillColor.addTransformation( XML_alpha, 50 * PER_PERCENT );
657*cdf0e10cSrcweir             break;
658*cdf0e10cSrcweir             case BIFF_OBJ_LINE_DARKTRANS:
659*cdf0e10cSrcweir                 aLineProps.moPresetDash = XML_solid;
660*cdf0e10cSrcweir                 aLineProps.maLineFill.maFillColor.addTransformation( XML_alpha, 75 * PER_PERCENT );
661*cdf0e10cSrcweir             break;
662*cdf0e10cSrcweir             case BIFF_OBJ_LINE_LIGHTTRANS:
663*cdf0e10cSrcweir                 aLineProps.moPresetDash = XML_solid;
664*cdf0e10cSrcweir                 aLineProps.maLineFill.maFillColor.addTransformation( XML_alpha, 25 * PER_PERCENT );
665*cdf0e10cSrcweir             break;
666*cdf0e10cSrcweir         }
667*cdf0e10cSrcweir 
668*cdf0e10cSrcweir         // line ends
669*cdf0e10cSrcweir         bool bLineStart = false;
670*cdf0e10cSrcweir         bool bLineEnd = false;
671*cdf0e10cSrcweir         bool bFilled = false;
672*cdf0e10cSrcweir         switch( extractValue< sal_uInt8 >( nArrows, 0, 4 ) )
673*cdf0e10cSrcweir         {
674*cdf0e10cSrcweir             case BIFF_OBJ_ARROW_OPEN:       bLineStart = false; bLineEnd = true;  bFilled = false;  break;
675*cdf0e10cSrcweir             case BIFF_OBJ_ARROW_OPENBOTH:   bLineStart = true;  bLineEnd = true;  bFilled = false;  break;
676*cdf0e10cSrcweir             case BIFF_OBJ_ARROW_FILLED:     bLineStart = false; bLineEnd = true;  bFilled = true;   break;
677*cdf0e10cSrcweir             case BIFF_OBJ_ARROW_FILLEDBOTH: bLineStart = true;  bLineEnd = true;  bFilled = true;   break;
678*cdf0e10cSrcweir         }
679*cdf0e10cSrcweir         if( bLineStart || bLineEnd )
680*cdf0e10cSrcweir         {
681*cdf0e10cSrcweir             // arrow type (open or closed)
682*cdf0e10cSrcweir             sal_Int32 nArrowType = bFilled ? XML_triangle : XML_arrow;
683*cdf0e10cSrcweir             aLineProps.maStartArrow.moArrowType = bLineStart ? nArrowType : XML_none;
684*cdf0e10cSrcweir             aLineProps.maEndArrow.moArrowType   = bLineEnd   ? nArrowType : XML_none;
685*cdf0e10cSrcweir 
686*cdf0e10cSrcweir             // arrow width
687*cdf0e10cSrcweir             sal_Int32 nArrowWidth = XML_med;
688*cdf0e10cSrcweir             switch( extractValue< sal_uInt8 >( nArrows, 4, 4 ) )
689*cdf0e10cSrcweir             {
690*cdf0e10cSrcweir                 case BIFF_OBJ_ARROW_NARROW: nArrowWidth = XML_sm;   break;
691*cdf0e10cSrcweir                 case BIFF_OBJ_ARROW_MEDIUM: nArrowWidth = XML_med;  break;
692*cdf0e10cSrcweir                 case BIFF_OBJ_ARROW_WIDE:   nArrowWidth = XML_lg;   break;
693*cdf0e10cSrcweir             }
694*cdf0e10cSrcweir             aLineProps.maStartArrow.moArrowWidth = aLineProps.maEndArrow.moArrowWidth = nArrowWidth;
695*cdf0e10cSrcweir 
696*cdf0e10cSrcweir             // arrow length
697*cdf0e10cSrcweir             sal_Int32 nArrowLength = XML_med;
698*cdf0e10cSrcweir             switch( extractValue< sal_uInt8 >( nArrows, 8, 4 ) )
699*cdf0e10cSrcweir             {
700*cdf0e10cSrcweir                 case BIFF_OBJ_ARROW_NARROW: nArrowLength = XML_sm;  break;
701*cdf0e10cSrcweir                 case BIFF_OBJ_ARROW_MEDIUM: nArrowLength = XML_med; break;
702*cdf0e10cSrcweir                 case BIFF_OBJ_ARROW_WIDE:   nArrowLength = XML_lg;  break;
703*cdf0e10cSrcweir             }
704*cdf0e10cSrcweir             aLineProps.maStartArrow.moArrowLength = aLineProps.maEndArrow.moArrowLength = nArrowLength;
705*cdf0e10cSrcweir         }
706*cdf0e10cSrcweir     }
707*cdf0e10cSrcweir 
708*cdf0e10cSrcweir     aLineProps.pushToPropMap( rPropMap, getBaseFilter().getGraphicHelper() );
709*cdf0e10cSrcweir }
710*cdf0e10cSrcweir 
711*cdf0e10cSrcweir void BiffDrawingObjectBase::convertFillProperties( ShapePropertyMap& rPropMap, const BiffObjFillModel& rFillModel ) const
712*cdf0e10cSrcweir {
713*cdf0e10cSrcweir     if( rFillModel.mbAuto )
714*cdf0e10cSrcweir     {
715*cdf0e10cSrcweir         BiffObjFillModel aAutoModel;
716*cdf0e10cSrcweir         aAutoModel.mbAuto = false;
717*cdf0e10cSrcweir         convertFillProperties( rPropMap, aAutoModel );
718*cdf0e10cSrcweir         return;
719*cdf0e10cSrcweir     }
720*cdf0e10cSrcweir 
721*cdf0e10cSrcweir     /*  Convert fill formatting to DrawingML fill formatting and let the
722*cdf0e10cSrcweir         DrawingML code do the hard work. */
723*cdf0e10cSrcweir     FillProperties aFillProps;
724*cdf0e10cSrcweir 
725*cdf0e10cSrcweir     if( rFillModel.mnPattern == BIFF_OBJ_PATT_NONE )
726*cdf0e10cSrcweir     {
727*cdf0e10cSrcweir         aFillProps.moFillType = XML_noFill;
728*cdf0e10cSrcweir     }
729*cdf0e10cSrcweir     else
730*cdf0e10cSrcweir     {
731*cdf0e10cSrcweir         const sal_Int32 spnPatternPresets[] = {
732*cdf0e10cSrcweir             XML_TOKEN_INVALID, XML_TOKEN_INVALID, XML_pct50, XML_pct50, XML_pct25,
733*cdf0e10cSrcweir             XML_dkHorz, XML_dkVert, XML_dkDnDiag, XML_dkUpDiag, XML_smCheck, XML_trellis,
734*cdf0e10cSrcweir             XML_ltHorz, XML_ltVert, XML_ltDnDiag, XML_ltUpDiag, XML_smGrid, XML_diagCross,
735*cdf0e10cSrcweir             XML_pct20, XML_pct10 };
736*cdf0e10cSrcweir         sal_Int32 nPatternPreset = STATIC_ARRAY_SELECT( spnPatternPresets, rFillModel.mnPattern, XML_TOKEN_INVALID );
737*cdf0e10cSrcweir         if( nPatternPreset == XML_TOKEN_INVALID )
738*cdf0e10cSrcweir         {
739*cdf0e10cSrcweir             aFillProps.moFillType = XML_solidFill;
740*cdf0e10cSrcweir             aFillProps.maFillColor.setPaletteClr( rFillModel.mnPattColorIdx );
741*cdf0e10cSrcweir         }
742*cdf0e10cSrcweir         else
743*cdf0e10cSrcweir         {
744*cdf0e10cSrcweir             aFillProps.moFillType = XML_pattFill;
745*cdf0e10cSrcweir             aFillProps.maPatternProps.maPattFgColor.setPaletteClr( rFillModel.mnPattColorIdx );
746*cdf0e10cSrcweir             aFillProps.maPatternProps.maPattBgColor.setPaletteClr( rFillModel.mnBackColorIdx );
747*cdf0e10cSrcweir             aFillProps.maPatternProps.moPattPreset = nPatternPreset;
748*cdf0e10cSrcweir         }
749*cdf0e10cSrcweir #if 0
750*cdf0e10cSrcweir         static const sal_uInt8 sppnPatterns[][ 8 ] =
751*cdf0e10cSrcweir         {
752*cdf0e10cSrcweir             { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 },
753*cdf0e10cSrcweir             { 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD },
754*cdf0e10cSrcweir             { 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 },
755*cdf0e10cSrcweir             { 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00 },
756*cdf0e10cSrcweir             { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC },
757*cdf0e10cSrcweir             { 0x33, 0x66, 0xCC, 0x99, 0x33, 0x66, 0xCC, 0x99 },
758*cdf0e10cSrcweir             { 0xCC, 0x66, 0x33, 0x99, 0xCC, 0x66, 0x33, 0x99 },
759*cdf0e10cSrcweir             { 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33 },
760*cdf0e10cSrcweir             { 0xCC, 0xFF, 0x33, 0xFF, 0xCC, 0xFF, 0x33, 0xFF },
761*cdf0e10cSrcweir             { 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 },
762*cdf0e10cSrcweir             { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 },
763*cdf0e10cSrcweir             { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 },
764*cdf0e10cSrcweir             { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 },
765*cdf0e10cSrcweir             { 0xFF, 0x11, 0x11, 0x11, 0xFF, 0x11, 0x11, 0x11 },
766*cdf0e10cSrcweir             { 0xAA, 0x44, 0xAA, 0x11, 0xAA, 0x44, 0xAA, 0x11 },
767*cdf0e10cSrcweir             { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
768*cdf0e10cSrcweir             { 0x80, 0x00, 0x08, 0x00, 0x80, 0x00, 0x08, 0x00 }
769*cdf0e10cSrcweir         };
770*cdf0e10cSrcweir         const sal_uInt8* const pnPattern = sppnPatterns[ ::std::min< size_t >( rFillData.mnPattern - 2, STATIC_ARRAY_SIZE( sppnPatterns ) ) ];
771*cdf0e10cSrcweir         // create 2-colored 8x8 DIB
772*cdf0e10cSrcweir         SvMemoryStream aMemStrm;
773*cdf0e10cSrcweir //      { 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00 }
774*cdf0e10cSrcweir         aMemStrm << sal_uInt32( 12 ) << sal_Int16( 8 ) << sal_Int16( 8 ) << sal_uInt16( 1 ) << sal_uInt16( 1 );
775*cdf0e10cSrcweir         aMemStrm << sal_uInt8( 0xFF ) << sal_uInt8( 0xFF ) << sal_uInt8( 0xFF );
776*cdf0e10cSrcweir         aMemStrm << sal_uInt8( 0x00 ) << sal_uInt8( 0x00 ) << sal_uInt8( 0x00 );
777*cdf0e10cSrcweir         for( size_t nIdx = 0; nIdx < 8; ++nIdx )
778*cdf0e10cSrcweir             aMemStrm << sal_uInt32( pnPattern[ nIdx ] ); // 32-bit little-endian
779*cdf0e10cSrcweir         aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
780*cdf0e10cSrcweir         Bitmap aBitmap;
781*cdf0e10cSrcweir         aBitmap.Read( aMemStrm, FALSE );
782*cdf0e10cSrcweir         XOBitmap aXOBitmap( aBitmap );
783*cdf0e10cSrcweir         aXOBitmap.Bitmap2Array();
784*cdf0e10cSrcweir         aXOBitmap.SetBitmapType( XBITMAP_8X8 );
785*cdf0e10cSrcweir         if( aXOBitmap.GetBackgroundColor().GetColor() == COL_BLACK )
786*cdf0e10cSrcweir             ::std::swap( aPattColor, aBackColor );
787*cdf0e10cSrcweir         aXOBitmap.SetPixelColor( aPattColor );
788*cdf0e10cSrcweir         aXOBitmap.SetBackgroundColor( aBackColor );
789*cdf0e10cSrcweir         rSdrObj.SetMergedItem( XFillStyleItem( XFILL_BITMAP ) );
790*cdf0e10cSrcweir         rSdrObj.SetMergedItem( XFillBitmapItem( EMPTY_STRING, aXOBitmap ) );
791*cdf0e10cSrcweir #endif
792*cdf0e10cSrcweir     }
793*cdf0e10cSrcweir 
794*cdf0e10cSrcweir     aFillProps.pushToPropMap( rPropMap, getBaseFilter().getGraphicHelper() );
795*cdf0e10cSrcweir }
796*cdf0e10cSrcweir 
797*cdf0e10cSrcweir void BiffDrawingObjectBase::convertFrameProperties( ShapePropertyMap& /*rPropMap*/, sal_uInt16 /*nFrameFlags*/ ) const
798*cdf0e10cSrcweir {
799*cdf0e10cSrcweir }
800*cdf0e10cSrcweir 
801*cdf0e10cSrcweir void BiffDrawingObjectBase::implReadObjBiff3( BiffInputStream& /*rStrm*/, sal_uInt16 /*nMacroSize*/ )
802*cdf0e10cSrcweir {
803*cdf0e10cSrcweir }
804*cdf0e10cSrcweir 
805*cdf0e10cSrcweir void BiffDrawingObjectBase::implReadObjBiff4( BiffInputStream& /*rStrm*/, sal_uInt16 /*nMacroSize*/ )
806*cdf0e10cSrcweir {
807*cdf0e10cSrcweir }
808*cdf0e10cSrcweir 
809*cdf0e10cSrcweir void BiffDrawingObjectBase::implReadObjBiff5( BiffInputStream& /*rStrm*/, sal_uInt16 /*nNameLen*/, sal_uInt16 /*nMacroSize*/ )
810*cdf0e10cSrcweir {
811*cdf0e10cSrcweir }
812*cdf0e10cSrcweir 
813*cdf0e10cSrcweir void BiffDrawingObjectBase::implReadObjBiff8SubRec( BiffInputStream& /*rStrm*/, sal_uInt16 /*nSubRecId*/, sal_uInt16 /*nSubRecSize*/ )
814*cdf0e10cSrcweir {
815*cdf0e10cSrcweir }
816*cdf0e10cSrcweir 
817*cdf0e10cSrcweir // private --------------------------------------------------------------------
818*cdf0e10cSrcweir 
819*cdf0e10cSrcweir void BiffDrawingObjectBase::importObjBiff3( BiffInputStream& rStrm )
820*cdf0e10cSrcweir {
821*cdf0e10cSrcweir     // back to offset 4 (ignore object count field)
822*cdf0e10cSrcweir     rStrm.seek( 4 );
823*cdf0e10cSrcweir 
824*cdf0e10cSrcweir     sal_uInt16 nObjFlags, nMacroSize;
825*cdf0e10cSrcweir     rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize;
826*cdf0e10cSrcweir     rStrm.skip( 2 );
827*cdf0e10cSrcweir 
828*cdf0e10cSrcweir     mbHasAnchor = true;
829*cdf0e10cSrcweir     mbHidden = getFlag( nObjFlags, BIFF_OBJ_HIDDEN );
830*cdf0e10cSrcweir     mbVisible = getFlag( nObjFlags, BIFF_OBJ_VISIBLE );
831*cdf0e10cSrcweir     implReadObjBiff3( rStrm, nMacroSize );
832*cdf0e10cSrcweir }
833*cdf0e10cSrcweir 
834*cdf0e10cSrcweir void BiffDrawingObjectBase::importObjBiff4( BiffInputStream& rStrm )
835*cdf0e10cSrcweir {
836*cdf0e10cSrcweir     // back to offset 4 (ignore object count field)
837*cdf0e10cSrcweir     rStrm.seek( 4 );
838*cdf0e10cSrcweir 
839*cdf0e10cSrcweir     sal_uInt16 nObjFlags, nMacroSize;
840*cdf0e10cSrcweir     rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize;
841*cdf0e10cSrcweir     rStrm.skip( 2 );
842*cdf0e10cSrcweir 
843*cdf0e10cSrcweir     mbHasAnchor = true;
844*cdf0e10cSrcweir     mbHidden = getFlag( nObjFlags, BIFF_OBJ_HIDDEN );
845*cdf0e10cSrcweir     mbVisible = getFlag( nObjFlags, BIFF_OBJ_VISIBLE );
846*cdf0e10cSrcweir     mbPrintable = getFlag( nObjFlags, BIFF_OBJ_PRINTABLE );
847*cdf0e10cSrcweir     implReadObjBiff4( rStrm, nMacroSize );
848*cdf0e10cSrcweir }
849*cdf0e10cSrcweir 
850*cdf0e10cSrcweir void BiffDrawingObjectBase::importObjBiff5( BiffInputStream& rStrm )
851*cdf0e10cSrcweir {
852*cdf0e10cSrcweir     // back to offset 4 (ignore object count field)
853*cdf0e10cSrcweir     rStrm.seek( 4 );
854*cdf0e10cSrcweir 
855*cdf0e10cSrcweir     sal_uInt16 nObjFlags, nMacroSize, nNameLen;
856*cdf0e10cSrcweir     rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize;
857*cdf0e10cSrcweir     rStrm.skip( 2 );
858*cdf0e10cSrcweir     rStrm >> nNameLen;
859*cdf0e10cSrcweir     rStrm.skip( 2 );
860*cdf0e10cSrcweir 
861*cdf0e10cSrcweir     mbHasAnchor = true;
862*cdf0e10cSrcweir     mbHidden = getFlag( nObjFlags, BIFF_OBJ_HIDDEN );
863*cdf0e10cSrcweir     mbVisible = getFlag( nObjFlags, BIFF_OBJ_VISIBLE );
864*cdf0e10cSrcweir     mbPrintable = getFlag( nObjFlags, BIFF_OBJ_PRINTABLE );
865*cdf0e10cSrcweir     implReadObjBiff5( rStrm, nNameLen, nMacroSize );
866*cdf0e10cSrcweir }
867*cdf0e10cSrcweir 
868*cdf0e10cSrcweir void BiffDrawingObjectBase::importObjBiff8( BiffInputStream& rStrm )
869*cdf0e10cSrcweir {
870*cdf0e10cSrcweir     // back to beginning
871*cdf0e10cSrcweir     rStrm.seekToStart();
872*cdf0e10cSrcweir 
873*cdf0e10cSrcweir     bool bLoop = true;
874*cdf0e10cSrcweir     while( bLoop && (rStrm.getRemaining() >= 4) )
875*cdf0e10cSrcweir     {
876*cdf0e10cSrcweir         sal_uInt16 nSubRecId, nSubRecSize;
877*cdf0e10cSrcweir         rStrm >> nSubRecId >> nSubRecSize;
878*cdf0e10cSrcweir         sal_Int64 nStrmPos = rStrm.tell();
879*cdf0e10cSrcweir         // sometimes the last subrecord has an invalid length (OBJLBSDATA) -> min()
880*cdf0e10cSrcweir         nSubRecSize = static_cast< sal_uInt16 >( ::std::min< sal_Int64 >( nSubRecSize, rStrm.getRemaining() ) );
881*cdf0e10cSrcweir 
882*cdf0e10cSrcweir         switch( nSubRecId )
883*cdf0e10cSrcweir         {
884*cdf0e10cSrcweir             case BIFF_ID_OBJCMO:
885*cdf0e10cSrcweir                 OSL_ENSURE( rStrm.tell() == 4, "BiffDrawingObjectBase::importObjBiff8 - unexpected OBJCMO subrecord" );
886*cdf0e10cSrcweir                 if( (rStrm.tell() == 4) && (nSubRecSize >= 6) )
887*cdf0e10cSrcweir                 {
888*cdf0e10cSrcweir                     sal_uInt16 nObjFlags;
889*cdf0e10cSrcweir                     rStrm >> mnObjType >> mnObjId >> nObjFlags;
890*cdf0e10cSrcweir                     mbPrintable = getFlag( nObjFlags, BIFF_OBJCMO_PRINTABLE );
891*cdf0e10cSrcweir                 }
892*cdf0e10cSrcweir             break;
893*cdf0e10cSrcweir             case BIFF_ID_OBJMACRO:
894*cdf0e10cSrcweir                 readMacroBiff8( rStrm );
895*cdf0e10cSrcweir             break;
896*cdf0e10cSrcweir             case BIFF_ID_OBJEND:
897*cdf0e10cSrcweir                 bLoop = false;
898*cdf0e10cSrcweir             break;
899*cdf0e10cSrcweir             default:
900*cdf0e10cSrcweir                 implReadObjBiff8SubRec( rStrm, nSubRecId, nSubRecSize );
901*cdf0e10cSrcweir         }
902*cdf0e10cSrcweir 
903*cdf0e10cSrcweir         // seek to end of subrecord
904*cdf0e10cSrcweir         rStrm.seek( nStrmPos + nSubRecSize );
905*cdf0e10cSrcweir     }
906*cdf0e10cSrcweir 
907*cdf0e10cSrcweir     /*  Call doReadObj8SubRec() with BIFF_ID_OBJEND for further stream
908*cdf0e10cSrcweir         processing (e.g. charts), even if the OBJEND subrecord is missing. */
909*cdf0e10cSrcweir     implReadObjBiff8SubRec( rStrm, BIFF_ID_OBJEND, 0 );
910*cdf0e10cSrcweir 
911*cdf0e10cSrcweir     /*  Pictures that Excel reads from BIFF5 and writes to BIFF8 still have the
912*cdf0e10cSrcweir         IMGDATA record following the OBJ record (but they use the image data
913*cdf0e10cSrcweir         stored in DFF). The IMGDATA record may be continued by several CONTINUE
914*cdf0e10cSrcweir         records. But the last CONTINUE record may be in fact an MSODRAWING
915*cdf0e10cSrcweir         record that contains the DFF data of the next drawing object! So we
916*cdf0e10cSrcweir         have to skip just enough CONTINUE records to look at the next
917*cdf0e10cSrcweir         MSODRAWING/CONTINUE record. */
918*cdf0e10cSrcweir     if( (rStrm.getNextRecId() == BIFF3_ID_IMGDATA) && rStrm.startNextRecord() )
919*cdf0e10cSrcweir     {
920*cdf0e10cSrcweir         rStrm.skip( 4 );
921*cdf0e10cSrcweir         sal_Int64 nDataSize = rStrm.readuInt32();
922*cdf0e10cSrcweir         nDataSize -= rStrm.getRemaining();
923*cdf0e10cSrcweir         // skip following CONTINUE records until IMGDATA ends
924*cdf0e10cSrcweir         while( (nDataSize > 0) && (rStrm.getNextRecId() == BIFF_ID_CONT) && rStrm.startNextRecord() )
925*cdf0e10cSrcweir         {
926*cdf0e10cSrcweir             OSL_ENSURE( nDataSize >= rStrm.getRemaining(), "BiffDrawingObjectBase::importObjBiff8 - CONTINUE too long" );
927*cdf0e10cSrcweir             nDataSize -= ::std::min( rStrm.getRemaining(), nDataSize );
928*cdf0e10cSrcweir         }
929*cdf0e10cSrcweir         OSL_ENSURE( nDataSize == 0, "BiffDrawingObjectBase::importObjBiff8 - missing CONTINUE records" );
930*cdf0e10cSrcweir         // next record may be MSODRAWING or CONTINUE or anything else
931*cdf0e10cSrcweir     }
932*cdf0e10cSrcweir }
933*cdf0e10cSrcweir 
934*cdf0e10cSrcweir // ============================================================================
935*cdf0e10cSrcweir 
936*cdf0e10cSrcweir BiffPlaceholderObject::BiffPlaceholderObject( const WorksheetHelper& rHelper ) :
937*cdf0e10cSrcweir     BiffDrawingObjectBase( rHelper )
938*cdf0e10cSrcweir {
939*cdf0e10cSrcweir     setProcessShape( false );
940*cdf0e10cSrcweir }
941*cdf0e10cSrcweir 
942*cdf0e10cSrcweir Reference< XShape > BiffPlaceholderObject::implConvertAndInsert( BiffDrawingBase& /*rDrawing*/,
943*cdf0e10cSrcweir         const Reference< XShapes >& /*rxShapes*/, const Rectangle& /*rShapeRect*/ ) const
944*cdf0e10cSrcweir {
945*cdf0e10cSrcweir     return Reference< XShape >();
946*cdf0e10cSrcweir }
947*cdf0e10cSrcweir 
948*cdf0e10cSrcweir // ============================================================================
949*cdf0e10cSrcweir 
950*cdf0e10cSrcweir BiffGroupObject::BiffGroupObject( const WorksheetHelper& rHelper ) :
951*cdf0e10cSrcweir     BiffDrawingObjectBase( rHelper ),
952*cdf0e10cSrcweir     mnFirstUngrouped( BIFF_OBJ_INVALID_ID )
953*cdf0e10cSrcweir {
954*cdf0e10cSrcweir }
955*cdf0e10cSrcweir 
956*cdf0e10cSrcweir bool BiffGroupObject::tryInsert( const BiffDrawingObjectRef& rxDrawingObj )
957*cdf0e10cSrcweir {
958*cdf0e10cSrcweir     if( rxDrawingObj->getObjId() == mnFirstUngrouped )
959*cdf0e10cSrcweir         return false;
960*cdf0e10cSrcweir     // insert into own list or into nested group
961*cdf0e10cSrcweir     maChildren.insertGrouped( rxDrawingObj );
962*cdf0e10cSrcweir     return true;
963*cdf0e10cSrcweir }
964*cdf0e10cSrcweir 
965*cdf0e10cSrcweir void BiffGroupObject::implReadObjBiff3( BiffInputStream& rStrm, sal_uInt16 nMacroSize )
966*cdf0e10cSrcweir {
967*cdf0e10cSrcweir     rStrm.skip( 4 );
968*cdf0e10cSrcweir     rStrm >> mnFirstUngrouped;
969*cdf0e10cSrcweir     rStrm.skip( 16 );
970*cdf0e10cSrcweir     readMacroBiff3( rStrm, nMacroSize );
971*cdf0e10cSrcweir }
972*cdf0e10cSrcweir 
973*cdf0e10cSrcweir void BiffGroupObject::implReadObjBiff4( BiffInputStream& rStrm, sal_uInt16 nMacroSize )
974*cdf0e10cSrcweir {
975*cdf0e10cSrcweir     rStrm.skip( 4 );
976*cdf0e10cSrcweir     rStrm >> mnFirstUngrouped;
977*cdf0e10cSrcweir     rStrm.skip( 16 );
978*cdf0e10cSrcweir     readMacroBiff4( rStrm, nMacroSize );
979*cdf0e10cSrcweir }
980*cdf0e10cSrcweir 
981*cdf0e10cSrcweir void BiffGroupObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
982*cdf0e10cSrcweir {
983*cdf0e10cSrcweir     rStrm.skip( 4 );
984*cdf0e10cSrcweir     rStrm >> mnFirstUngrouped;
985*cdf0e10cSrcweir     rStrm.skip( 16 );
986*cdf0e10cSrcweir     readNameBiff5( rStrm, nNameLen );
987*cdf0e10cSrcweir     readMacroBiff5( rStrm, nMacroSize );
988*cdf0e10cSrcweir }
989*cdf0e10cSrcweir 
990*cdf0e10cSrcweir Reference< XShape > BiffGroupObject::implConvertAndInsert( BiffDrawingBase& rDrawing,
991*cdf0e10cSrcweir         const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
992*cdf0e10cSrcweir {
993*cdf0e10cSrcweir     Reference< XShape > xGroupShape;
994*cdf0e10cSrcweir     if( !maChildren.empty() ) try
995*cdf0e10cSrcweir     {
996*cdf0e10cSrcweir         xGroupShape = rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.GroupShape" ), rxShapes, rShapeRect );
997*cdf0e10cSrcweir         Reference< XShapes > xChildShapes( xGroupShape, UNO_QUERY_THROW );
998*cdf0e10cSrcweir         maChildren.convertAndInsert( rDrawing, xChildShapes, &rShapeRect );
999*cdf0e10cSrcweir         // no child shape has been created - delete the group shape
1000*cdf0e10cSrcweir         if( !xChildShapes->hasElements() )
1001*cdf0e10cSrcweir         {
1002*cdf0e10cSrcweir             rxShapes->remove( xGroupShape );
1003*cdf0e10cSrcweir             xGroupShape.clear();
1004*cdf0e10cSrcweir         }
1005*cdf0e10cSrcweir     }
1006*cdf0e10cSrcweir     catch( Exception& )
1007*cdf0e10cSrcweir     {
1008*cdf0e10cSrcweir     }
1009*cdf0e10cSrcweir     return xGroupShape;
1010*cdf0e10cSrcweir }
1011*cdf0e10cSrcweir 
1012*cdf0e10cSrcweir // ============================================================================
1013*cdf0e10cSrcweir 
1014*cdf0e10cSrcweir BiffLineObject::BiffLineObject( const WorksheetHelper& rHelper ) :
1015*cdf0e10cSrcweir     BiffDrawingObjectBase( rHelper ),
1016*cdf0e10cSrcweir     mnArrows( 0 ),
1017*cdf0e10cSrcweir     mnStartPoint( BIFF_OBJ_LINE_TL )
1018*cdf0e10cSrcweir {
1019*cdf0e10cSrcweir     setAreaObj( false );
1020*cdf0e10cSrcweir }
1021*cdf0e10cSrcweir 
1022*cdf0e10cSrcweir void BiffLineObject::implReadObjBiff3( BiffInputStream& rStrm, sal_uInt16 nMacroSize )
1023*cdf0e10cSrcweir {
1024*cdf0e10cSrcweir     rStrm >> maLineModel >> mnArrows >> mnStartPoint;
1025*cdf0e10cSrcweir     rStrm.skip( 1 );
1026*cdf0e10cSrcweir     readMacroBiff3( rStrm, nMacroSize );
1027*cdf0e10cSrcweir }
1028*cdf0e10cSrcweir 
1029*cdf0e10cSrcweir void BiffLineObject::implReadObjBiff4( BiffInputStream& rStrm, sal_uInt16 nMacroSize )
1030*cdf0e10cSrcweir {
1031*cdf0e10cSrcweir     rStrm >> maLineModel >> mnArrows >> mnStartPoint;
1032*cdf0e10cSrcweir     rStrm.skip( 1 );
1033*cdf0e10cSrcweir     readMacroBiff4( rStrm, nMacroSize );
1034*cdf0e10cSrcweir }
1035*cdf0e10cSrcweir 
1036*cdf0e10cSrcweir void BiffLineObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1037*cdf0e10cSrcweir {
1038*cdf0e10cSrcweir     rStrm >> maLineModel >> mnArrows >> mnStartPoint;
1039*cdf0e10cSrcweir     rStrm.skip( 1 );
1040*cdf0e10cSrcweir     readNameBiff5( rStrm, nNameLen );
1041*cdf0e10cSrcweir     readMacroBiff5( rStrm, nMacroSize );
1042*cdf0e10cSrcweir }
1043*cdf0e10cSrcweir 
1044*cdf0e10cSrcweir Reference< XShape > BiffLineObject::implConvertAndInsert( BiffDrawingBase& rDrawing,
1045*cdf0e10cSrcweir         const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
1046*cdf0e10cSrcweir {
1047*cdf0e10cSrcweir     ShapePropertyMap aPropMap( getBaseFilter().getModelObjectHelper() );
1048*cdf0e10cSrcweir     convertLineProperties( aPropMap, maLineModel, mnArrows );
1049*cdf0e10cSrcweir 
1050*cdf0e10cSrcweir     // create the line polygon
1051*cdf0e10cSrcweir     PointSequenceSequence aPoints( 1 );
1052*cdf0e10cSrcweir     aPoints[ 0 ].realloc( 2 );
1053*cdf0e10cSrcweir     Point& rBeg = aPoints[ 0 ][ 0 ];
1054*cdf0e10cSrcweir     Point& rEnd = aPoints[ 0 ][ 1 ];
1055*cdf0e10cSrcweir     sal_Int32 nL = rShapeRect.X;
1056*cdf0e10cSrcweir     sal_Int32 nT = rShapeRect.Y;
1057*cdf0e10cSrcweir     sal_Int32 nR = rShapeRect.X + ::std::max< sal_Int32 >( rShapeRect.Width - 1, 0 );
1058*cdf0e10cSrcweir     sal_Int32 nB = rShapeRect.Y + ::std::max< sal_Int32 >( rShapeRect.Height - 1, 0 );
1059*cdf0e10cSrcweir     switch( mnStartPoint )
1060*cdf0e10cSrcweir     {
1061*cdf0e10cSrcweir         default:
1062*cdf0e10cSrcweir         case BIFF_OBJ_LINE_TL: rBeg.X = nL; rBeg.Y = nT; rEnd.X = nR; rEnd.Y = nB; break;
1063*cdf0e10cSrcweir         case BIFF_OBJ_LINE_TR: rBeg.X = nR; rBeg.Y = nT; rEnd.X = nL; rEnd.Y = nB; break;
1064*cdf0e10cSrcweir         case BIFF_OBJ_LINE_BR: rBeg.X = nR; rBeg.Y = nB; rEnd.X = nL; rEnd.Y = nT; break;
1065*cdf0e10cSrcweir         case BIFF_OBJ_LINE_BL: rBeg.X = nL; rBeg.Y = nB; rEnd.X = nR; rEnd.Y = nT; break;
1066*cdf0e10cSrcweir     }
1067*cdf0e10cSrcweir     aPropMap.setProperty( PROP_PolyPolygon, aPoints );
1068*cdf0e10cSrcweir     aPropMap.setProperty( PROP_PolygonKind, PolygonKind_LINE );
1069*cdf0e10cSrcweir 
1070*cdf0e10cSrcweir     // create the shape
1071*cdf0e10cSrcweir     Reference< XShape > xShape = rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.LineShape" ), rxShapes, rShapeRect );
1072*cdf0e10cSrcweir     PropertySet( xShape ).setProperties( aPropMap );
1073*cdf0e10cSrcweir     return xShape;
1074*cdf0e10cSrcweir }
1075*cdf0e10cSrcweir 
1076*cdf0e10cSrcweir // ============================================================================
1077*cdf0e10cSrcweir 
1078*cdf0e10cSrcweir BiffRectObject::BiffRectObject( const WorksheetHelper& rHelper ) :
1079*cdf0e10cSrcweir     BiffDrawingObjectBase( rHelper ),
1080*cdf0e10cSrcweir     mnFrameFlags( 0 )
1081*cdf0e10cSrcweir {
1082*cdf0e10cSrcweir     setAreaObj( true );
1083*cdf0e10cSrcweir }
1084*cdf0e10cSrcweir 
1085*cdf0e10cSrcweir void BiffRectObject::readFrameData( BiffInputStream& rStrm )
1086*cdf0e10cSrcweir {
1087*cdf0e10cSrcweir     rStrm >> maFillModel >> maLineModel >> mnFrameFlags;
1088*cdf0e10cSrcweir }
1089*cdf0e10cSrcweir 
1090*cdf0e10cSrcweir void BiffRectObject::convertRectProperties( ShapePropertyMap& rPropMap ) const
1091*cdf0e10cSrcweir {
1092*cdf0e10cSrcweir     convertLineProperties( rPropMap, maLineModel );
1093*cdf0e10cSrcweir     convertFillProperties( rPropMap, maFillModel );
1094*cdf0e10cSrcweir     convertFrameProperties( rPropMap, mnFrameFlags );
1095*cdf0e10cSrcweir }
1096*cdf0e10cSrcweir 
1097*cdf0e10cSrcweir void BiffRectObject::implReadObjBiff3( BiffInputStream& rStrm, sal_uInt16 nMacroSize )
1098*cdf0e10cSrcweir {
1099*cdf0e10cSrcweir     readFrameData( rStrm );
1100*cdf0e10cSrcweir     readMacroBiff3( rStrm, nMacroSize );
1101*cdf0e10cSrcweir }
1102*cdf0e10cSrcweir 
1103*cdf0e10cSrcweir void BiffRectObject::implReadObjBiff4( BiffInputStream& rStrm, sal_uInt16 nMacroSize )
1104*cdf0e10cSrcweir {
1105*cdf0e10cSrcweir     readFrameData( rStrm );
1106*cdf0e10cSrcweir     readMacroBiff4( rStrm, nMacroSize );
1107*cdf0e10cSrcweir }
1108*cdf0e10cSrcweir 
1109*cdf0e10cSrcweir void BiffRectObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1110*cdf0e10cSrcweir {
1111*cdf0e10cSrcweir     readFrameData( rStrm );
1112*cdf0e10cSrcweir     readNameBiff5( rStrm, nNameLen );
1113*cdf0e10cSrcweir     readMacroBiff5( rStrm, nMacroSize );
1114*cdf0e10cSrcweir }
1115*cdf0e10cSrcweir 
1116*cdf0e10cSrcweir Reference< XShape > BiffRectObject::implConvertAndInsert( BiffDrawingBase& rDrawing,
1117*cdf0e10cSrcweir         const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
1118*cdf0e10cSrcweir {
1119*cdf0e10cSrcweir     ShapePropertyMap aPropMap( getBaseFilter().getModelObjectHelper() );
1120*cdf0e10cSrcweir     convertRectProperties( aPropMap );
1121*cdf0e10cSrcweir 
1122*cdf0e10cSrcweir     Reference< XShape > xShape = rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.RectangleShape" ), rxShapes, rShapeRect );
1123*cdf0e10cSrcweir     PropertySet( xShape ).setProperties( aPropMap );
1124*cdf0e10cSrcweir     return xShape;
1125*cdf0e10cSrcweir }
1126*cdf0e10cSrcweir 
1127*cdf0e10cSrcweir // ============================================================================
1128*cdf0e10cSrcweir 
1129*cdf0e10cSrcweir BiffOvalObject::BiffOvalObject( const WorksheetHelper& rHelper ) :
1130*cdf0e10cSrcweir     BiffRectObject( rHelper )
1131*cdf0e10cSrcweir {
1132*cdf0e10cSrcweir }
1133*cdf0e10cSrcweir 
1134*cdf0e10cSrcweir Reference< XShape > BiffOvalObject::implConvertAndInsert( BiffDrawingBase& rDrawing,
1135*cdf0e10cSrcweir         const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
1136*cdf0e10cSrcweir {
1137*cdf0e10cSrcweir     ShapePropertyMap aPropMap( getBaseFilter().getModelObjectHelper() );
1138*cdf0e10cSrcweir     convertRectProperties( aPropMap );
1139*cdf0e10cSrcweir 
1140*cdf0e10cSrcweir     Reference< XShape > xShape = rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.EllipseShape" ), rxShapes, rShapeRect );
1141*cdf0e10cSrcweir     PropertySet( xShape ).setProperties( aPropMap );
1142*cdf0e10cSrcweir     return xShape;
1143*cdf0e10cSrcweir }
1144*cdf0e10cSrcweir 
1145*cdf0e10cSrcweir // ============================================================================
1146*cdf0e10cSrcweir 
1147*cdf0e10cSrcweir BiffArcObject::BiffArcObject( const WorksheetHelper& rHelper ) :
1148*cdf0e10cSrcweir     BiffDrawingObjectBase( rHelper ),
1149*cdf0e10cSrcweir     mnQuadrant( BIFF_OBJ_ARC_TR )
1150*cdf0e10cSrcweir {
1151*cdf0e10cSrcweir     setAreaObj( false );    // arc may be 2-dimensional
1152*cdf0e10cSrcweir }
1153*cdf0e10cSrcweir 
1154*cdf0e10cSrcweir void BiffArcObject::implReadObjBiff3( BiffInputStream& rStrm, sal_uInt16 nMacroSize )
1155*cdf0e10cSrcweir {
1156*cdf0e10cSrcweir     rStrm >> maFillModel >> maLineModel >> mnQuadrant;
1157*cdf0e10cSrcweir     rStrm.skip( 1 );
1158*cdf0e10cSrcweir     readMacroBiff3( rStrm, nMacroSize );
1159*cdf0e10cSrcweir }
1160*cdf0e10cSrcweir 
1161*cdf0e10cSrcweir void BiffArcObject::implReadObjBiff4( BiffInputStream& rStrm, sal_uInt16 nMacroSize )
1162*cdf0e10cSrcweir {
1163*cdf0e10cSrcweir     rStrm >> maFillModel >> maLineModel >> mnQuadrant;
1164*cdf0e10cSrcweir     rStrm.skip( 1 );
1165*cdf0e10cSrcweir     readMacroBiff4( rStrm, nMacroSize );
1166*cdf0e10cSrcweir }
1167*cdf0e10cSrcweir 
1168*cdf0e10cSrcweir void BiffArcObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1169*cdf0e10cSrcweir {
1170*cdf0e10cSrcweir     rStrm >> maFillModel >> maLineModel >> mnQuadrant;
1171*cdf0e10cSrcweir     rStrm.skip( 1 );
1172*cdf0e10cSrcweir     readNameBiff5( rStrm, nNameLen );
1173*cdf0e10cSrcweir     readMacroBiff5( rStrm, nMacroSize );
1174*cdf0e10cSrcweir }
1175*cdf0e10cSrcweir 
1176*cdf0e10cSrcweir Reference< XShape > BiffArcObject::implConvertAndInsert( BiffDrawingBase& rDrawing,
1177*cdf0e10cSrcweir         const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
1178*cdf0e10cSrcweir {
1179*cdf0e10cSrcweir     ShapePropertyMap aPropMap( getBaseFilter().getModelObjectHelper() );
1180*cdf0e10cSrcweir     convertLineProperties( aPropMap, maLineModel );
1181*cdf0e10cSrcweir     convertFillProperties( aPropMap, maFillModel );
1182*cdf0e10cSrcweir 
1183*cdf0e10cSrcweir     /*  Simulate arc objects with ellipse sections. While the original arc
1184*cdf0e10cSrcweir         object uses the entire object rectangle, only one quarter of the
1185*cdf0e10cSrcweir         ellipse shape will be visible. Thus, the size of the ellipse shape
1186*cdf0e10cSrcweir         needs to be extended and its position adjusted according to the visible
1187*cdf0e10cSrcweir         quadrant. */
1188*cdf0e10cSrcweir     Rectangle aNewRect( rShapeRect.X, rShapeRect.Y, rShapeRect.Width * 2, rShapeRect.Height * 2 );
1189*cdf0e10cSrcweir     long nStartAngle = 0;
1190*cdf0e10cSrcweir     switch( mnQuadrant )
1191*cdf0e10cSrcweir     {
1192*cdf0e10cSrcweir         default:
1193*cdf0e10cSrcweir         case BIFF_OBJ_ARC_TR: nStartAngle =     0; aNewRect.X -= rShapeRect.Width;                                  break;
1194*cdf0e10cSrcweir         case BIFF_OBJ_ARC_TL: nStartAngle =  9000;                                                                  break;
1195*cdf0e10cSrcweir         case BIFF_OBJ_ARC_BL: nStartAngle = 18000;                                 aNewRect.Y -= rShapeRect.Height; break;
1196*cdf0e10cSrcweir         case BIFF_OBJ_ARC_BR: nStartAngle = 27000; aNewRect.X -= rShapeRect.Width; aNewRect.Y -= rShapeRect.Height; break;
1197*cdf0e10cSrcweir     }
1198*cdf0e10cSrcweir     long nEndAngle = (nStartAngle + 9000) % 36000;
1199*cdf0e10cSrcweir     aPropMap.setProperty( PROP_CircleKind, maFillModel.isFilled() ? CircleKind_SECTION : CircleKind_ARC );
1200*cdf0e10cSrcweir     aPropMap.setProperty( PROP_CircleStartAngle, nStartAngle );
1201*cdf0e10cSrcweir     aPropMap.setProperty( PROP_CircleEndAngle, nEndAngle );
1202*cdf0e10cSrcweir 
1203*cdf0e10cSrcweir     // create the shape
1204*cdf0e10cSrcweir     Reference< XShape > xShape = rDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.EllipseShape" ), rxShapes, aNewRect );
1205*cdf0e10cSrcweir     PropertySet( xShape ).setProperties( aPropMap );
1206*cdf0e10cSrcweir     return xShape;
1207*cdf0e10cSrcweir }
1208*cdf0e10cSrcweir 
1209*cdf0e10cSrcweir // ============================================================================
1210*cdf0e10cSrcweir 
1211*cdf0e10cSrcweir BiffPolygonObject::BiffPolygonObject( const WorksheetHelper& rHelper ) :
1212*cdf0e10cSrcweir     BiffRectObject( rHelper ),
1213*cdf0e10cSrcweir     mnPolyFlags( 0 ),
1214*cdf0e10cSrcweir     mnPointCount( 0 )
1215*cdf0e10cSrcweir {
1216*cdf0e10cSrcweir     setAreaObj( false );    // polygon may be 2-dimensional
1217*cdf0e10cSrcweir }
1218*cdf0e10cSrcweir 
1219*cdf0e10cSrcweir void BiffPolygonObject::implReadObjBiff4( BiffInputStream& rStrm, sal_uInt16 nMacroSize )
1220*cdf0e10cSrcweir {
1221*cdf0e10cSrcweir     readFrameData( rStrm );
1222*cdf0e10cSrcweir     rStrm >> mnPolyFlags;
1223*cdf0e10cSrcweir     rStrm.skip( 10 );
1224*cdf0e10cSrcweir     rStrm >> mnPointCount;
1225*cdf0e10cSrcweir     rStrm.skip( 8 );
1226*cdf0e10cSrcweir     readMacroBiff4( rStrm, nMacroSize );
1227*cdf0e10cSrcweir     importCoordList( rStrm );
1228*cdf0e10cSrcweir }
1229*cdf0e10cSrcweir 
1230*cdf0e10cSrcweir void BiffPolygonObject::implReadObjBiff5( BiffInputStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1231*cdf0e10cSrcweir {
1232*cdf0e10cSrcweir     readFrameData( rStrm );
1233*cdf0e10cSrcweir     rStrm >> mnPolyFlags;
1234*cdf0e10cSrcweir     rStrm.skip( 10 );
1235*cdf0e10cSrcweir     rStrm >> mnPointCount;
1236*cdf0e10cSrcweir     rStrm.skip( 8 );
1237*cdf0e10cSrcweir     readNameBiff5( rStrm, nNameLen );
1238*cdf0e10cSrcweir     readMacroBiff5( rStrm, nMacroSize );
1239*cdf0e10cSrcweir     importCoordList( rStrm );
1240*cdf0e10cSrcweir }
1241*cdf0e10cSrcweir 
1242*cdf0e10cSrcweir namespace {
1243*cdf0e10cSrcweir 
1244*cdf0e10cSrcweir Point lclGetPolyPoint( const Rectangle& rAnchorRect, const Point& rPoint )
1245*cdf0e10cSrcweir {
1246*cdf0e10cSrcweir     // polygon coordinates are given in 1/16384 of shape size
1247*cdf0e10cSrcweir     return Point(
1248*cdf0e10cSrcweir         rAnchorRect.X + static_cast< sal_Int32 >( rAnchorRect.Width * getLimitedValue< double >( static_cast< double >( rPoint.X ) / 16384.0, 0.0, 1.0 ) + 0.5 ),
1249*cdf0e10cSrcweir         rAnchorRect.Y + static_cast< sal_Int32 >( rAnchorRect.Height * getLimitedValue< double >( static_cast< double >( rPoint.Y ) / 16384.0, 0.0, 1.0 ) + 0.5 ) );
1250*cdf0e10cSrcweir }
1251*cdf0e10cSrcweir 
1252*cdf0e10cSrcweir } // namespace
1253*cdf0e10cSrcweir 
1254*cdf0e10cSrcweir Reference< XShape > BiffPolygonObject::implConvertAndInsert( BiffDrawingBase& rDrawing,
1255*cdf0e10cSrcweir         const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
1256*cdf0e10cSrcweir {
1257*cdf0e10cSrcweir     Reference< XShape > xShape;
1258*cdf0e10cSrcweir     if( maCoords.size() >= 2 )
1259*cdf0e10cSrcweir     {
1260*cdf0e10cSrcweir         ShapePropertyMap aPropMap( getBaseFilter().getModelObjectHelper() );
1261*cdf0e10cSrcweir         convertRectProperties( aPropMap );
1262*cdf0e10cSrcweir 
1263*cdf0e10cSrcweir         // create the polygon
1264*cdf0e10cSrcweir         PointVector aPolygon;
1265*cdf0e10cSrcweir         for( PointVector::const_iterator aIt = maCoords.begin(), aEnd = maCoords.end(); aIt != aEnd; ++aIt )
1266*cdf0e10cSrcweir             aPolygon.push_back( lclGetPolyPoint( rShapeRect, *aIt ) );
1267*cdf0e10cSrcweir         // close polygon if specified
1268*cdf0e10cSrcweir         if( getFlag( mnPolyFlags, BIFF_OBJ_POLY_CLOSED ) && ((maCoords.front().X != maCoords.back().X) || (maCoords.front().Y != maCoords.back().Y)) )
1269*cdf0e10cSrcweir             aPolygon.push_back( aPolygon.front() );
1270*cdf0e10cSrcweir         PointSequenceSequence aPoints( 1 );
1271*cdf0e10cSrcweir         aPoints[ 0 ] = ContainerHelper::vectorToSequence( aPolygon );
1272*cdf0e10cSrcweir         aPropMap.setProperty( PROP_PolyPolygon, aPoints );
1273*cdf0e10cSrcweir 
1274*cdf0e10cSrcweir         // create the shape
1275*cdf0e10cSrcweir         OUString aService = maFillModel.isFilled() ?
1276*cdf0e10cSrcweir             CREATE_OUSTRING( "com.sun.star.drawing.PolyPolygonShape" ) :
1277*cdf0e10cSrcweir             CREATE_OUSTRING( "com.sun.star.drawing.PolyLineShape" );
1278*cdf0e10cSrcweir         xShape = rDrawing.createAndInsertXShape( aService, rxShapes, rShapeRect );
1279*cdf0e10cSrcweir         PropertySet( xShape ).setProperties( aPropMap );
1280*cdf0e10cSrcweir     }
1281*cdf0e10cSrcweir     return xShape;
1282*cdf0e10cSrcweir }
1283*cdf0e10cSrcweir 
1284*cdf0e10cSrcweir void BiffPolygonObject::importCoordList( BiffInputStream& rStrm )
1285*cdf0e10cSrcweir {
1286*cdf0e10cSrcweir     if( (rStrm.getNextRecId() == BIFF_ID_COORDLIST) && rStrm.startNextRecord() )
1287*cdf0e10cSrcweir     {
1288*cdf0e10cSrcweir         OSL_ENSURE( rStrm.getRemaining() / 4 == mnPointCount, "BiffPolygonObject::importCoordList - wrong polygon point count" );
1289*cdf0e10cSrcweir         while( rStrm.getRemaining() >= 4 )
1290*cdf0e10cSrcweir         {
1291*cdf0e10cSrcweir             sal_uInt16 nX, nY;
1292*cdf0e10cSrcweir             rStrm >> nX >> nY;
1293*cdf0e10cSrcweir             maCoords.push_back( Point( nX, nY ) );
1294*cdf0e10cSrcweir         }
1295*cdf0e10cSrcweir     }
1296*cdf0e10cSrcweir }
1297*cdf0e10cSrcweir 
1298*cdf0e10cSrcweir // ============================================================================
1299*cdf0e10cSrcweir // BIFF drawing page
1300*cdf0e10cSrcweir // ============================================================================
1301*cdf0e10cSrcweir 
1302*cdf0e10cSrcweir BiffDrawingBase::BiffDrawingBase( const WorksheetHelper& rHelper, const Reference< XDrawPage >& rxDrawPage ) :
1303*cdf0e10cSrcweir     WorksheetHelper( rHelper ),
1304*cdf0e10cSrcweir     mxDrawPage( rxDrawPage )
1305*cdf0e10cSrcweir {
1306*cdf0e10cSrcweir }
1307*cdf0e10cSrcweir 
1308*cdf0e10cSrcweir void BiffDrawingBase::importObj( BiffInputStream& rStrm )
1309*cdf0e10cSrcweir {
1310*cdf0e10cSrcweir     BiffDrawingObjectRef xDrawingObj;
1311*cdf0e10cSrcweir 
1312*cdf0e10cSrcweir #if 0
1313*cdf0e10cSrcweir     /*  #i61786# In BIFF8 streams, OBJ records may occur without MSODRAWING
1314*cdf0e10cSrcweir         records. In this case, the OBJ records are in BIFF5 format. Do a sanity
1315*cdf0e10cSrcweir         check here that there is no DFF data loaded before. */
1316*cdf0e10cSrcweir     DBG_ASSERT( maDffStrm.Tell() == 0, "BiffDrawingBase::importObj - unexpected DFF stream data, OBJ will be ignored" );
1317*cdf0e10cSrcweir     if( maDffStrm.Tell() == 0 ) switch( GetBiff() )
1318*cdf0e10cSrcweir #else
1319*cdf0e10cSrcweir     switch( getBiff() )
1320*cdf0e10cSrcweir #endif
1321*cdf0e10cSrcweir     {
1322*cdf0e10cSrcweir         case BIFF3:
1323*cdf0e10cSrcweir             xDrawingObj = BiffDrawingObjectBase::importObjBiff3( *this, rStrm );
1324*cdf0e10cSrcweir         break;
1325*cdf0e10cSrcweir         case BIFF4:
1326*cdf0e10cSrcweir             xDrawingObj = BiffDrawingObjectBase::importObjBiff4( *this, rStrm );
1327*cdf0e10cSrcweir         break;
1328*cdf0e10cSrcweir         case BIFF5:
1329*cdf0e10cSrcweir // TODO: add BIFF8 when DFF is supported
1330*cdf0e10cSrcweir //        case BIFF8:
1331*cdf0e10cSrcweir             xDrawingObj = BiffDrawingObjectBase::importObjBiff5( *this, rStrm );
1332*cdf0e10cSrcweir         break;
1333*cdf0e10cSrcweir         default:;
1334*cdf0e10cSrcweir     }
1335*cdf0e10cSrcweir 
1336*cdf0e10cSrcweir     if( xDrawingObj.get() )
1337*cdf0e10cSrcweir     {
1338*cdf0e10cSrcweir         // insert into maRawObjs or into the last open group object
1339*cdf0e10cSrcweir         maRawObjs.insertGrouped( xDrawingObj );
1340*cdf0e10cSrcweir         // to be able to find objects by ID
1341*cdf0e10cSrcweir         maObjMapId[ xDrawingObj->getObjId() ] = xDrawingObj;
1342*cdf0e10cSrcweir     }
1343*cdf0e10cSrcweir }
1344*cdf0e10cSrcweir 
1345*cdf0e10cSrcweir void BiffDrawingBase::setSkipObj( sal_uInt16 nObjId )
1346*cdf0e10cSrcweir {
1347*cdf0e10cSrcweir     /*  Store identifiers of objects to be skipped in a separate list (the OBJ
1348*cdf0e10cSrcweir         record may not be read yet). In the finalization phase, all objects
1349*cdf0e10cSrcweir         registered here will be skipped. */
1350*cdf0e10cSrcweir     maSkipObjs.push_back( nObjId );
1351*cdf0e10cSrcweir }
1352*cdf0e10cSrcweir 
1353*cdf0e10cSrcweir void BiffDrawingBase::finalizeImport()
1354*cdf0e10cSrcweir {
1355*cdf0e10cSrcweir     Reference< XShapes > xShapes( mxDrawPage, UNO_QUERY );
1356*cdf0e10cSrcweir     OSL_ENSURE( xShapes.is(), "BiffDrawingBase::finalizeImport - no shapes container" );
1357*cdf0e10cSrcweir     if( !xShapes.is() )
1358*cdf0e10cSrcweir         return;
1359*cdf0e10cSrcweir 
1360*cdf0e10cSrcweir     // process list of objects to be skipped
1361*cdf0e10cSrcweir     for( BiffObjIdVector::const_iterator aIt = maSkipObjs.begin(), aEnd = maSkipObjs.end(); aIt != aEnd; ++aIt )
1362*cdf0e10cSrcweir         if( BiffDrawingObjectBase* pDrawingObj = maObjMapId.get( *aIt ).get() )
1363*cdf0e10cSrcweir             pDrawingObj->setProcessShape( false );
1364*cdf0e10cSrcweir 
1365*cdf0e10cSrcweir     // process drawing objects without DFF data
1366*cdf0e10cSrcweir     maRawObjs.convertAndInsert( *this, xShapes );
1367*cdf0e10cSrcweir }
1368*cdf0e10cSrcweir 
1369*cdf0e10cSrcweir Reference< XShape > BiffDrawingBase::createAndInsertXShape( const OUString& rService,
1370*cdf0e10cSrcweir         const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
1371*cdf0e10cSrcweir {
1372*cdf0e10cSrcweir     OSL_ENSURE( rService.getLength() > 0, "BiffDrawingBase::createAndInsertXShape - missing UNO shape service name" );
1373*cdf0e10cSrcweir     OSL_ENSURE( rxShapes.is(), "BiffDrawingBase::createAndInsertXShape - missing XShapes container" );
1374*cdf0e10cSrcweir     Reference< XShape > xShape;
1375*cdf0e10cSrcweir     if( (rService.getLength() > 0) && rxShapes.is() ) try
1376*cdf0e10cSrcweir     {
1377*cdf0e10cSrcweir         xShape.set( getBaseFilter().getModelFactory()->createInstance( rService ), UNO_QUERY_THROW );
1378*cdf0e10cSrcweir         // insert shape into passed shape collection (maybe drawpage or group shape)
1379*cdf0e10cSrcweir         rxShapes->add( xShape );
1380*cdf0e10cSrcweir         xShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) );
1381*cdf0e10cSrcweir         xShape->setSize( Size( rShapeRect.Width, rShapeRect.Height ) );
1382*cdf0e10cSrcweir     }
1383*cdf0e10cSrcweir     catch( Exception& )
1384*cdf0e10cSrcweir     {
1385*cdf0e10cSrcweir     }
1386*cdf0e10cSrcweir     OSL_ENSURE( xShape.is(), "BiffDrawingBase::createAndInsertXShape - cannot instanciate shape object" );
1387*cdf0e10cSrcweir     return xShape;
1388*cdf0e10cSrcweir }
1389*cdf0e10cSrcweir 
1390*cdf0e10cSrcweir // protected ------------------------------------------------------------------
1391*cdf0e10cSrcweir 
1392*cdf0e10cSrcweir void BiffDrawingBase::appendRawObject( const BiffDrawingObjectRef& rxDrawingObj )
1393*cdf0e10cSrcweir {
1394*cdf0e10cSrcweir     OSL_ENSURE( rxDrawingObj.get(), "BiffDrawingBase::appendRawObject - unexpected empty object reference" );
1395*cdf0e10cSrcweir     maRawObjs.append( rxDrawingObj );
1396*cdf0e10cSrcweir }
1397*cdf0e10cSrcweir 
1398*cdf0e10cSrcweir // ============================================================================
1399*cdf0e10cSrcweir 
1400*cdf0e10cSrcweir BiffSheetDrawing::BiffSheetDrawing( const WorksheetHelper& rHelper ) :
1401*cdf0e10cSrcweir     BiffDrawingBase( rHelper, rHelper.getDrawPage() )
1402*cdf0e10cSrcweir {
1403*cdf0e10cSrcweir }
1404*cdf0e10cSrcweir 
1405*cdf0e10cSrcweir void BiffSheetDrawing::notifyShapeInserted( const Reference< XShape >& /*rxShape*/, const Rectangle& rShapeRect )
1406*cdf0e10cSrcweir {
1407*cdf0e10cSrcweir     // collect all shape positions in the WorksheetHelper base class
1408*cdf0e10cSrcweir     extendShapeBoundingBox( rShapeRect );
1409*cdf0e10cSrcweir }
1410*cdf0e10cSrcweir 
1411*cdf0e10cSrcweir // ============================================================================
1412*cdf0e10cSrcweir 
1413*cdf0e10cSrcweir } // namespace xls
1414*cdf0e10cSrcweir } // namespace oox
1415