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